@@ -95,42 +95,35 @@ pub fn eval_body<'a, 'tcx>(
9595
9696pub fn value_to_const_value < ' tcx > (
9797 ecx : & EvalContext < ' _ , ' _ , ' tcx , CompileTimeEvaluator > ,
98- mut val : Value ,
98+ val : Value ,
9999 ty : Ty < ' tcx > ,
100100) -> & ' 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 ( ) ;
102102 match ( val, & layout. abi ) {
103+ ( Value :: ByVal ( PrimVal :: Undef ) , _) if layout. is_zst ( ) => { } ,
103104 ( Value :: ByRef ( ..) , _) |
104105 ( Value :: ByVal ( _) , & layout:: Abi :: Scalar ( _) ) |
105106 ( Value :: ByValPair ( ..) , & layout:: Abi :: ScalarPair ( ..) ) => { } ,
106107 _ => bug ! ( "bad value/layout combo: {:#?}, {:#?}" , val, layout) ,
107108 }
108109 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- }
115110 match val {
116111 Value :: ByVal ( val) => Ok ( ConstValue :: ByVal ( val) ) ,
117112 Value :: ByValPair ( a, b) => Ok ( ConstValue :: ByValPair ( a, b) ) ,
118113 Value :: ByRef ( ptr, align) => {
119114 let ptr = ptr. primval . to_ptr ( ) . unwrap ( ) ;
120- assert_eq ! ( ptr. offset, 0 ) ;
121115 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( ) ) ;
124118 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;
127120 let alloc = ecx. tcx . intern_const_alloc ( alloc) ;
128- Ok ( ConstValue :: ByRef ( alloc) )
121+ Ok ( ConstValue :: ByRef ( alloc, ptr . offset ) )
129122 }
130123 }
131124 } ) ( ) ;
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) ,
134127 Err ( mut err) => {
135128 ecx. report ( & mut err, true , None ) ;
136129 bug ! ( "miri error occured when converting Value to ConstValue" )
@@ -427,7 +420,7 @@ pub fn const_val_field<'a, 'tcx>(
427420 Value :: ByRef ( ptr, align) => ( ptr, align) ,
428421 Value :: ByValPair ( ..) | Value :: ByVal ( _) => {
429422 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) ?;
431424 ( ptr, layout. align )
432425 } ,
433426 } ;
@@ -438,7 +431,21 @@ pub fn const_val_field<'a, 'tcx>(
438431 } ;
439432 let ( place, layout) = ecx. place_field ( place, field, layout) ?;
440433 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 ) )
442449 } ) ( ) ;
443450 result. map_err ( |err| {
444451 let ( trace, span) = ecx. generate_stacktrace ( None ) ;
@@ -535,8 +542,11 @@ pub fn const_eval_provider<'a, 'tcx>(
535542 } ;
536543
537544 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) )
540550 } ) . map_err ( |mut err| {
541551 if tcx. is_static ( def_id) . is_some ( ) {
542552 ecx. report ( & mut err, true , None ) ;
0 commit comments