@@ -95,42 +95,35 @@ pub fn eval_body<'a, 'tcx>(
95
95
96
96
pub fn value_to_const_value < ' tcx > (
97
97
ecx : & EvalContext < ' _ , ' _ , ' tcx , CompileTimeEvaluator > ,
98
- mut val : Value ,
98
+ val : Value ,
99
99
ty : Ty < ' tcx > ,
100
100
) -> & ' tcx ty:: Const < ' tcx > {
101
- let layout = tcx. layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) ) . unwrap ( ) ;
101
+ let layout = ecx . tcx . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) ) . unwrap ( ) ;
102
102
match ( val, & layout. abi ) {
103
+ ( Value :: ByVal ( PrimVal :: Undef ) , _) if layout. is_zst ( ) => { } ,
103
104
( Value :: ByRef ( ..) , _) |
104
105
( Value :: ByVal ( _) , & layout:: Abi :: Scalar ( _) ) |
105
106
( Value :: ByValPair ( ..) , & layout:: Abi :: ScalarPair ( ..) ) => { } ,
106
107
_ => bug ! ( "bad value/layout combo: {:#?}, {:#?}" , val, layout) ,
107
108
}
108
109
let val = ( || {
109
- // Convert to ByVal or ByValPair if possible
110
- if let Value :: ByRef ( ptr, align) = val {
111
- if let Some ( read_val) = ecx. try_read_value ( ptr, align, ty) ? {
112
- val = read_val;
113
- }
114
- }
115
110
match val {
116
111
Value :: ByVal ( val) => Ok ( ConstValue :: ByVal ( val) ) ,
117
112
Value :: ByValPair ( a, b) => Ok ( ConstValue :: ByValPair ( a, b) ) ,
118
113
Value :: ByRef ( ptr, align) => {
119
114
let ptr = ptr. primval . to_ptr ( ) . unwrap ( ) ;
120
- assert_eq ! ( ptr. offset, 0 ) ;
121
115
let alloc = ecx. memory . get ( ptr. alloc_id ) ?;
122
- assert ! ( alloc. align. abi( ) >= layout . align. abi( ) ) ;
123
- assert ! ( alloc. bytes. len( ) as u64 = = layout. size. bytes( ) ) ;
116
+ assert ! ( alloc. align. abi( ) >= align. abi( ) ) ;
117
+ assert ! ( alloc. bytes. len( ) as u64 - ptr . offset > = layout. size. bytes( ) ) ;
124
118
let mut alloc = alloc. clone ( ) ;
125
- // The align field is meaningless for values, so just use the layout's align
126
- alloc. align = layout. align ;
119
+ alloc. align = align;
127
120
let alloc = ecx. tcx . intern_const_alloc ( alloc) ;
128
- Ok ( ConstValue :: ByRef ( alloc) )
121
+ Ok ( ConstValue :: ByRef ( alloc, ptr . offset ) )
129
122
}
130
123
}
131
124
} ) ( ) ;
132
- match result {
133
- Ok ( v ) => ty:: Const :: from_const_value ( tcx, val, ty) ,
125
+ match val {
126
+ Ok ( val ) => ty:: Const :: from_const_value ( ecx . tcx . tcx , val, ty) ,
134
127
Err ( mut err) => {
135
128
ecx. report ( & mut err, true , None ) ;
136
129
bug ! ( "miri error occured when converting Value to ConstValue" )
@@ -427,7 +420,7 @@ pub fn const_val_field<'a, 'tcx>(
427
420
Value :: ByRef ( ptr, align) => ( ptr, align) ,
428
421
Value :: ByValPair ( ..) | Value :: ByVal ( _) => {
429
422
let ptr = ecx. alloc_ptr ( ty) ?. into ( ) ;
430
- ecx. write_value_to_ptr ( value, ptr, ty) ?;
423
+ ecx. write_value_to_ptr ( value, ptr, layout . align , ty) ?;
431
424
( ptr, layout. align )
432
425
} ,
433
426
} ;
@@ -438,7 +431,21 @@ pub fn const_val_field<'a, 'tcx>(
438
431
} ;
439
432
let ( place, layout) = ecx. place_field ( place, field, layout) ?;
440
433
let ( ptr, align) = place. to_ptr_align ( ) ;
441
- Ok ( ( Value :: ByRef ( ptr, align) , layout. ty ) )
434
+ let mut new_value = Value :: ByRef ( ptr, align) ;
435
+ new_value = ecx. try_read_by_ref ( new_value, layout. ty ) ?;
436
+ use rustc_data_structures:: indexed_vec:: Idx ;
437
+ match ( value, new_value) {
438
+ ( Value :: ByVal ( _) , Value :: ByRef ( ..) ) |
439
+ ( Value :: ByValPair ( ..) , Value :: ByRef ( ..) ) |
440
+ ( Value :: ByVal ( _) , Value :: ByValPair ( ..) ) => bug ! (
441
+ "field {} of {:?} yielded {:?}" ,
442
+ field. index( ) ,
443
+ value,
444
+ new_value,
445
+ ) ,
446
+ _ => { } ,
447
+ }
448
+ Ok ( value_to_const_value ( & ecx, new_value, layout. ty ) )
442
449
} ) ( ) ;
443
450
result. map_err ( |err| {
444
451
let ( trace, span) = ecx. generate_stacktrace ( None ) ;
@@ -535,8 +542,11 @@ pub fn const_eval_provider<'a, 'tcx>(
535
542
} ;
536
543
537
544
let ( res, ecx) = eval_body_and_ecx ( tcx, cid, None , key. param_env ) ;
538
- res. map ( |( val, _, miri_ty) | {
539
- value_to_const_value ( & ecx, val, miri_ty)
545
+ res. and_then ( |( mut val, _, miri_ty) | {
546
+ if tcx. is_static ( def_id) . is_none ( ) {
547
+ val = ecx. try_read_by_ref ( val, miri_ty) ?;
548
+ }
549
+ Ok ( value_to_const_value ( & ecx, val, miri_ty) )
540
550
} ) . map_err ( |mut err| {
541
551
if tcx. is_static ( def_id) . is_some ( ) {
542
552
ecx. report ( & mut err, true , None ) ;
0 commit comments