@@ -31,8 +31,8 @@ use rustc::util::common::ErrorReported;
3131use syntax:: ast:: Mutability ;
3232use syntax:: source_map:: { Span , DUMMY_SP } ;
3333
34- use interpret:: { self ,
35- PlaceTy , MemPlace , OpTy , Operand , Immediate , Scalar , ConstValue , Pointer ,
34+ use crate :: interpret:: { self ,
35+ PlaceTy , MPlaceTy , MemPlace , OpTy , Operand , Immediate , Scalar , RawConst , ConstValue , Pointer ,
3636 EvalResult , EvalError , EvalErrorKind , GlobalId , EvalContext , StackPopCleanup ,
3737 Allocation , AllocId , MemoryKind ,
3838 snapshot, RefTracking ,
@@ -94,11 +94,13 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
9494 cid : GlobalId < ' tcx > ,
9595 mir : & ' mir mir:: Mir < ' tcx > ,
9696 param_env : ty:: ParamEnv < ' tcx > ,
97- ) -> EvalResult < ' tcx , OpTy < ' tcx > > {
97+ ) -> EvalResult < ' tcx , MPlaceTy < ' tcx > > {
9898 let mut ecx = mk_borrowck_eval_cx ( tcx, cid. instance , mir, DUMMY_SP ) . unwrap ( ) ;
9999 eval_body_using_ecx ( & mut ecx, cid, Some ( mir) , param_env)
100100}
101101
102+ // FIXME: This thing is a bad hack. We should get rid of it. Ideally constants are always
103+ // in an allocation.
102104pub fn op_to_const < ' tcx > (
103105 ecx : & CompileTimeEvalContext < ' _ , ' _ , ' tcx > ,
104106 op : OpTy < ' tcx > ,
@@ -150,7 +152,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
150152 cid : GlobalId < ' tcx > ,
151153 mir : Option < & ' mir mir:: Mir < ' tcx > > ,
152154 param_env : ty:: ParamEnv < ' tcx > ,
153- ) -> ( EvalResult < ' tcx , OpTy < ' tcx > > , CompileTimeEvalContext < ' a , ' mir , ' tcx > ) {
155+ ) -> ( EvalResult < ' tcx , MPlaceTy < ' tcx > > , CompileTimeEvalContext < ' a , ' mir , ' tcx > ) {
154156 // we start out with the best span we have
155157 // and try improving it down the road when more information is available
156158 let span = tcx. def_span ( cid. instance . def_id ( ) ) ;
@@ -166,7 +168,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
166168 cid : GlobalId < ' tcx > ,
167169 mir : Option < & ' mir mir:: Mir < ' tcx > > ,
168170 param_env : ty:: ParamEnv < ' tcx > ,
169- ) -> EvalResult < ' tcx , OpTy < ' tcx > > {
171+ ) -> EvalResult < ' tcx , MPlaceTy < ' tcx > > {
170172 debug ! ( "eval_body_using_ecx: {:?}, {:?}" , cid, param_env) ;
171173 let tcx = ecx. tcx . tcx ;
172174 let mut mir = match mir {
@@ -206,7 +208,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
206208 ecx. memory . intern_static ( ret. ptr . to_ptr ( ) ?. alloc_id , mutability) ?;
207209
208210 debug ! ( "eval_body_using_ecx done: {:?}" , * ret) ;
209- Ok ( ret. into ( ) )
211+ Ok ( ret)
210212}
211213
212214impl < ' tcx > Into < EvalError < ' tcx > > for ConstEvalError {
@@ -534,15 +536,17 @@ pub fn error_to_const_error<'a, 'mir, 'tcx>(
534536 ConstEvalErr { error : error. kind , stacktrace, span : ecx. tcx . span }
535537}
536538
537- fn validate_const < ' a , ' tcx > (
539+ fn validate_and_turn_into_const < ' a , ' tcx > (
538540 tcx : ty:: TyCtxt < ' a , ' tcx , ' tcx > ,
539- constant : & ' tcx ty :: Const < ' tcx > ,
541+ constant : RawConst < ' tcx > ,
540542 key : ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ,
541543) -> :: rustc:: mir:: interpret:: ConstEvalResult < ' tcx > {
542544 let cid = key. value ;
543545 let ecx = mk_eval_cx ( tcx, cid. instance , key. param_env ) . unwrap ( ) ;
544546 let val = ( || {
545- let op = ecx. const_to_op ( constant) ?;
547+ let op = ecx. raw_const_to_mplace ( constant) ?. into ( ) ;
548+ // FIXME: Once the visitor infrastructure landed, change validation to
549+ // work directly on `MPlaceTy`.
546550 let mut ref_tracking = RefTracking :: new ( op) ;
547551 while let Some ( ( op, path) ) = ref_tracking. todo . pop ( ) {
548552 ecx. validate_operand (
@@ -552,7 +556,10 @@ fn validate_const<'a, 'tcx>(
552556 /* const_mode */ true ,
553557 ) ?;
554558 }
555- Ok ( constant)
559+ // Now that we validated, turn this into a proper constant
560+ let def_id = cid. instance . def . def_id ( ) ;
561+ let normalize = tcx. is_static ( def_id) . is_none ( ) && cid. promoted . is_none ( ) ;
562+ op_to_const ( & ecx, op, normalize)
556563 } ) ( ) ;
557564
558565 val. map_err ( |error| {
@@ -591,14 +598,14 @@ pub fn const_eval_provider<'a, 'tcx>(
591598 }
592599 }
593600 tcx. const_eval_raw ( key) . and_then ( |val| {
594- validate_const ( tcx, val, key)
601+ validate_and_turn_into_const ( tcx, val, key)
595602 } )
596603}
597604
598605pub fn const_eval_raw_provider < ' a , ' tcx > (
599606 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
600607 key : ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ,
601- ) -> :: rustc:: mir:: interpret:: ConstEvalResult < ' tcx > {
608+ ) -> :: rustc:: mir:: interpret:: ConstEvalRawResult < ' tcx > {
602609 // Because the constant is computed twice (once per value of `Reveal`), we are at risk of
603610 // reporting the same error twice here. To resolve this, we check whether we can evaluate the
604611 // constant in the more restrictive `Reveal::UserFacing`, which most likely already was
@@ -648,16 +655,11 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
648655 } ;
649656
650657 let ( res, ecx) = eval_body_and_ecx ( tcx, cid, None , key. param_env ) ;
651- res. and_then ( |op| {
652- let normalize = tcx. is_static ( def_id) . is_none ( ) && cid. promoted . is_none ( ) ;
653- if !normalize {
654- // Sanity check: These must always be a MemPlace
655- match op. op {
656- Operand :: Indirect ( _) => { /* all is good */ } ,
657- Operand :: Immediate ( _) => bug ! ( "const eval gave us an Immediate" ) ,
658- }
659- }
660- op_to_const ( & ecx, op, normalize)
658+ res. and_then ( |place| {
659+ Ok ( RawConst {
660+ alloc_id : place. to_ptr ( ) . expect ( "we allocated this ptr!" ) . alloc_id ,
661+ ty : place. layout . ty
662+ } )
661663 } ) . map_err ( |error| {
662664 let err = error_to_const_error ( & ecx, error) ;
663665 // errors in statics are always emitted as fatal errors
0 commit comments