44use rustc_hir:: def:: Namespace ;
55use rustc_middle:: ty:: layout:: { LayoutOf , PrimitiveExt , TyAndLayout } ;
66use rustc_middle:: ty:: print:: { FmtPrinter , PrettyPrinter } ;
7- use rustc_middle:: ty:: { ConstInt , Ty } ;
7+ use rustc_middle:: ty:: { ConstInt , Ty , ValTree } ;
88use rustc_middle:: { mir, ty} ;
9+ use rustc_span:: Span ;
910use rustc_target:: abi:: { self , Abi , Align , HasDataLayout , Size , TagEncoding } ;
1011use rustc_target:: abi:: { VariantIdx , Variants } ;
1112
@@ -527,14 +528,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
527528 Copy ( place) | Move ( place) => self . eval_place_to_op ( place, layout) ?,
528529
529530 Constant ( ref constant) => {
530- let val =
531+ let c =
531532 self . subst_from_current_frame_and_normalize_erasing_regions ( constant. literal ) ?;
532533
533534 // This can still fail:
534535 // * During ConstProp, with `TooGeneric` or since the `required_consts` were not all
535536 // checked yet.
536537 // * During CTFE, since promoteds in `const`/`static` initializer bodies can fail.
537- self . const_to_op ( & val , layout) ?
538+ self . eval_mir_constant ( & c , Some ( constant . span ) , layout) ?
538539 }
539540 } ;
540541 trace ! ( "{:?}: {:?}" , mir_op, * op) ;
@@ -549,9 +550,35 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
549550 ops. iter ( ) . map ( |op| self . eval_operand ( op, None ) ) . collect ( )
550551 }
551552
552- pub fn const_to_op (
553+ fn eval_ty_constant (
554+ & self ,
555+ val : ty:: Const < ' tcx > ,
556+ span : Option < Span > ,
557+ ) -> InterpResult < ' tcx , ValTree < ' tcx > > {
558+ Ok ( match val. kind ( ) {
559+ ty:: ConstKind :: Param ( _) | ty:: ConstKind :: Placeholder ( ..) => {
560+ throw_inval ! ( TooGeneric )
561+ }
562+ ty:: ConstKind :: Error ( reported) => {
563+ throw_inval ! ( AlreadyReported ( reported) )
564+ }
565+ ty:: ConstKind :: Unevaluated ( uv) => {
566+ let instance = self . resolve ( uv. def , uv. substs ) ?;
567+ let cid = GlobalId { instance, promoted : None } ;
568+ self . ctfe_query ( span, |tcx| tcx. eval_to_valtree ( self . param_env . and ( cid) ) ) ?
569+ . unwrap_or_else ( || bug ! ( "unable to create ValTree for {uv:?}" ) )
570+ }
571+ ty:: ConstKind :: Bound ( ..) | ty:: ConstKind :: Infer ( ..) => {
572+ span_bug ! ( self . cur_span( ) , "unexpected ConstKind in ctfe: {val:?}" )
573+ }
574+ ty:: ConstKind :: Value ( valtree) => valtree,
575+ } )
576+ }
577+
578+ pub fn eval_mir_constant (
553579 & self ,
554580 val : & mir:: ConstantKind < ' tcx > ,
581+ span : Option < Span > ,
555582 layout : Option < TyAndLayout < ' tcx > > ,
556583 ) -> InterpResult < ' tcx , OpTy < ' tcx , M :: Provenance > > {
557584 // FIXME(const_prop): normalization needed b/c const prop lint in
@@ -563,44 +590,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
563590 let val = self . tcx . normalize_erasing_regions ( self . param_env , * val) ;
564591 match val {
565592 mir:: ConstantKind :: Ty ( ct) => {
566- match ct. kind ( ) {
567- ty:: ConstKind :: Param ( _) | ty:: ConstKind :: Placeholder ( ..) => {
568- throw_inval ! ( TooGeneric )
569- }
570- ty:: ConstKind :: Error ( reported) => {
571- throw_inval ! ( AlreadyReported ( reported) )
572- }
573- ty:: ConstKind :: Unevaluated ( uv) => {
574- // NOTE: We evaluate to a `ValTree` here as a check to ensure
575- // we're working with valid constants, even though we never need it.
576- let instance = self . resolve ( uv. def , uv. substs ) ?;
577- let cid = GlobalId { instance, promoted : None } ;
578- let _valtree = self
579- . tcx
580- . eval_to_valtree ( self . param_env . and ( cid) ) ?
581- . unwrap_or_else ( || bug ! ( "unable to create ValTree for {uv:?}" ) ) ;
582-
583- Ok ( self . eval_to_allocation ( cid) ?. into ( ) )
584- }
585- ty:: ConstKind :: Bound ( ..) | ty:: ConstKind :: Infer ( ..) => {
586- span_bug ! ( self . cur_span( ) , "unexpected ConstKind in ctfe: {ct:?}" )
587- }
588- ty:: ConstKind :: Value ( valtree) => {
589- let ty = ct. ty ( ) ;
590- let const_val = self . tcx . valtree_to_const_val ( ( ty, valtree) ) ;
591- self . const_val_to_op ( const_val, ty, layout)
592- }
593- }
593+ let ty = ct. ty ( ) ;
594+ let valtree = self . eval_ty_constant ( ct, span) ?;
595+ let const_val = self . tcx . valtree_to_const_val ( ( ty, valtree) ) ;
596+ self . const_val_to_op ( const_val, ty, layout)
594597 }
595598 mir:: ConstantKind :: Val ( val, ty) => self . const_val_to_op ( val, ty, layout) ,
596599 mir:: ConstantKind :: Unevaluated ( uv, _) => {
597600 let instance = self . resolve ( uv. def , uv. substs ) ?;
598- Ok ( self . eval_to_allocation ( GlobalId { instance, promoted : uv. promoted } ) ?. into ( ) )
601+ Ok ( self . eval_global ( GlobalId { instance, promoted : uv. promoted } , span ) ?. into ( ) )
599602 }
600603 }
601604 }
602605
603- pub ( crate ) fn const_val_to_op (
606+ pub ( super ) fn const_val_to_op (
604607 & self ,
605608 val_val : ConstValue < ' tcx > ,
606609 ty : Ty < ' tcx > ,
0 commit comments