@@ -21,7 +21,7 @@ use syntax::ast::Mutability;
21
21
use syntax:: source_map:: { Span , DUMMY_SP } ;
22
22
23
23
use crate :: interpret:: { self ,
24
- PlaceTy , MPlaceTy , MemPlace , OpTy , ImmTy , Operand , Immediate , Scalar , Pointer ,
24
+ PlaceTy , MPlaceTy , MemPlace , OpTy , ImmTy , Immediate , Scalar , Pointer ,
25
25
RawConst , ConstValue ,
26
26
EvalResult , EvalError , EvalErrorKind , GlobalId , EvalContext , StackPopCleanup ,
27
27
Allocation , AllocId , MemoryKind ,
@@ -62,45 +62,46 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
62
62
eval_body_using_ecx ( & mut ecx, cid, Some ( mir) , param_env)
63
63
}
64
64
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 > (
67
86
ecx : & CompileTimeEvalContext < ' _ , ' _ , ' tcx > ,
68
87
op : OpTy < ' tcx > ,
69
- may_normalize : bool ,
70
88
) -> EvalResult < ' tcx , ty:: Const < ' tcx > > {
71
89
// 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
+ } ;
78
95
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" ) )
80
97
} else {
81
- match * op {
82
- Operand :: Indirect ( mplace) => Err ( mplace) ,
83
- Operand :: Immediate ( val) => Ok ( val)
84
- }
98
+ op. try_as_mplace ( )
85
99
} ;
86
100
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) ) =>
102
103
ConstValue :: Scalar ( x. not_undef ( ) ?) ,
103
- Ok ( Immediate :: ScalarPair ( a, b) ) =>
104
+ Err ( Immediate :: ScalarPair ( a, b) ) =>
104
105
ConstValue :: Slice ( a. not_undef ( ) ?, b. to_usize ( ecx) ?) ,
105
106
} ;
106
107
Ok ( ty:: Const { val, ty : op. layout . ty } )
@@ -486,7 +487,7 @@ pub fn const_field<'a, 'tcx>(
486
487
let field = ecx. operand_field ( down, field. index ( ) as u64 ) ?;
487
488
// and finally move back to the const world, always normalizing because
488
489
// this is not called for statics.
489
- op_to_const ( & ecx, field, true )
490
+ op_to_const ( & ecx, field)
490
491
} ) ( ) ;
491
492
result. map_err ( |error| {
492
493
let err = error_to_const_error ( & ecx, error) ;
@@ -535,8 +536,11 @@ fn validate_and_turn_into_const<'a, 'tcx>(
535
536
}
536
537
// Now that we validated, turn this into a proper constant.
537
538
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
+ }
540
544
} ) ( ) ;
541
545
542
546
val. map_err ( |error| {
0 commit comments