@@ -21,7 +21,7 @@ use syntax::ast::Mutability;
2121use syntax:: source_map:: { Span , DUMMY_SP } ;
2222
2323use crate :: interpret:: { self ,
24- PlaceTy , MPlaceTy , MemPlace , OpTy , ImmTy , Operand , Immediate , Scalar , Pointer ,
24+ PlaceTy , MPlaceTy , MemPlace , OpTy , ImmTy , Immediate , Scalar , Pointer ,
2525 RawConst , ConstValue ,
2626 EvalResult , EvalError , EvalErrorKind , GlobalId , EvalContext , StackPopCleanup ,
2727 Allocation , AllocId , MemoryKind ,
@@ -62,45 +62,46 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
6262 eval_body_using_ecx ( & mut ecx, cid, Some ( mir) , param_env)
6363}
6464
65- // FIXME: These two conversion functions are bad hacks. We should just always use allocations.
66- pub fn op_to_const < ' tcx > (
65+ fn mplace_to_const < ' tcx > (
66+ ecx : & CompileTimeEvalContext < ' _ , ' _ , ' tcx > ,
67+ mplace : MPlaceTy < ' tcx > ,
68+ ) -> EvalResult < ' tcx , ty:: Const < ' tcx > > {
69+ let MemPlace { ptr, align, meta } = * mplace;
70+ // extract alloc-offset pair
71+ assert ! ( meta. is_none( ) ) ;
72+ let ptr = ptr. to_ptr ( ) ?;
73+ let alloc = ecx. memory . get ( ptr. alloc_id ) ?;
74+ assert ! ( alloc. align >= align) ;
75+ assert ! ( alloc. bytes. len( ) as u64 - ptr. offset. bytes( ) >= mplace. layout. size. bytes( ) ) ;
76+ let mut alloc = alloc. clone ( ) ;
77+ alloc. align = align;
78+ // FIXME shouldn't it be the case that `mark_static_initialized` has already
79+ // interned this? I thought that is the entire point of that `FinishStatic` stuff?
80+ let alloc = ecx. tcx . intern_const_alloc ( alloc) ;
81+ let val = ConstValue :: ByRef ( ptr, alloc) ;
82+ Ok ( ty:: Const { val, ty : mplace. layout . ty } )
83+ }
84+
85+ fn op_to_const < ' tcx > (
6786 ecx : & CompileTimeEvalContext < ' _ , ' _ , ' tcx > ,
6887 op : OpTy < ' tcx > ,
69- may_normalize : bool ,
7088) -> EvalResult < ' tcx , ty:: Const < ' tcx > > {
7189 // We do not normalize just any data. Only scalar layout and slices.
72- let normalize = may_normalize
73- && match op. layout . abi {
74- layout:: Abi :: Scalar ( ..) => true ,
75- layout:: Abi :: ScalarPair ( ..) => op. layout . ty . is_slice ( ) ,
76- _ => false ,
77- } ;
90+ let normalize = match op. layout . abi {
91+ layout:: Abi :: Scalar ( ..) => true ,
92+ layout:: Abi :: ScalarPair ( ..) => op. layout . ty . is_slice ( ) ,
93+ _ => false ,
94+ } ;
7895 let normalized_op = if normalize {
79- Ok ( * ecx. read_immediate ( op) . expect ( "normalization works on validated constants" ) )
96+ Err ( * ecx. read_immediate ( op) . expect ( "normalization works on validated constants" ) )
8097 } else {
81- match * op {
82- Operand :: Indirect ( mplace) => Err ( mplace) ,
83- Operand :: Immediate ( val) => Ok ( val)
84- }
98+ op. try_as_mplace ( )
8599 } ;
86100 let val = match normalized_op {
87- Err ( MemPlace { ptr, align, meta } ) => {
88- // extract alloc-offset pair
89- assert ! ( meta. is_none( ) ) ;
90- let ptr = ptr. to_ptr ( ) ?;
91- let alloc = ecx. memory . get ( ptr. alloc_id ) ?;
92- assert ! ( alloc. align >= align) ;
93- assert ! ( alloc. bytes. len( ) as u64 - ptr. offset. bytes( ) >= op. layout. size. bytes( ) ) ;
94- let mut alloc = alloc. clone ( ) ;
95- alloc. align = align;
96- // FIXME shouldn't it be the case that `mark_static_initialized` has already
97- // interned this? I thought that is the entire point of that `FinishStatic` stuff?
98- let alloc = ecx. tcx . intern_const_alloc ( alloc) ;
99- ConstValue :: ByRef ( ptr, alloc)
100- } ,
101- Ok ( Immediate :: Scalar ( x) ) =>
101+ Ok ( mplace) => return mplace_to_const ( ecx, mplace) ,
102+ Err ( Immediate :: Scalar ( x) ) =>
102103 ConstValue :: Scalar ( x. not_undef ( ) ?) ,
103- Ok ( Immediate :: ScalarPair ( a, b) ) =>
104+ Err ( Immediate :: ScalarPair ( a, b) ) =>
104105 ConstValue :: Slice ( a. not_undef ( ) ?, b. to_usize ( ecx) ?) ,
105106 } ;
106107 Ok ( ty:: Const { val, ty : op. layout . ty } )
@@ -486,7 +487,7 @@ pub fn const_field<'a, 'tcx>(
486487 let field = ecx. operand_field ( down, field. index ( ) as u64 ) ?;
487488 // and finally move back to the const world, always normalizing because
488489 // this is not called for statics.
489- op_to_const ( & ecx, field, true )
490+ op_to_const ( & ecx, field)
490491 } ) ( ) ;
491492 result. map_err ( |error| {
492493 let err = error_to_const_error ( & ecx, error) ;
@@ -535,8 +536,11 @@ fn validate_and_turn_into_const<'a, 'tcx>(
535536 }
536537 // Now that we validated, turn this into a proper constant.
537538 let def_id = cid. instance . def . def_id ( ) ;
538- let normalize = tcx. is_static ( def_id) . is_none ( ) && cid. promoted . is_none ( ) ;
539- op_to_const ( & ecx, mplace. into ( ) , normalize)
539+ if tcx. is_static ( def_id) . is_some ( ) || cid. promoted . is_some ( ) {
540+ mplace_to_const ( & ecx, mplace)
541+ } else {
542+ op_to_const ( & ecx, mplace. into ( ) )
543+ }
540544 } ) ( ) ;
541545
542546 val. map_err ( |error| {
0 commit comments