4
4
use rustc_hir:: def:: Namespace ;
5
5
use rustc_middle:: ty:: layout:: { LayoutOf , PrimitiveExt , TyAndLayout } ;
6
6
use rustc_middle:: ty:: print:: { FmtPrinter , PrettyPrinter } ;
7
- use rustc_middle:: ty:: { ConstInt , Ty } ;
7
+ use rustc_middle:: ty:: { ConstInt , Ty , ValTree } ;
8
8
use rustc_middle:: { mir, ty} ;
9
+ use rustc_span:: Span ;
9
10
use rustc_target:: abi:: { self , Abi , Align , HasDataLayout , Size , TagEncoding } ;
10
11
use rustc_target:: abi:: { VariantIdx , Variants } ;
11
12
@@ -527,14 +528,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
527
528
Copy ( place) | Move ( place) => self . eval_place_to_op ( place, layout) ?,
528
529
529
530
Constant ( ref constant) => {
530
- let val =
531
+ let c =
531
532
self . subst_from_current_frame_and_normalize_erasing_regions ( constant. literal ) ?;
532
533
533
534
// This can still fail:
534
535
// * During ConstProp, with `TooGeneric` or since the `required_consts` were not all
535
536
// checked yet.
536
537
// * 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) ?
538
539
}
539
540
} ;
540
541
trace ! ( "{:?}: {:?}" , mir_op, * op) ;
@@ -549,9 +550,35 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
549
550
ops. iter ( ) . map ( |op| self . eval_operand ( op, None ) ) . collect ( )
550
551
}
551
552
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 (
553
579
& self ,
554
580
val : & mir:: ConstantKind < ' tcx > ,
581
+ span : Option < Span > ,
555
582
layout : Option < TyAndLayout < ' tcx > > ,
556
583
) -> InterpResult < ' tcx , OpTy < ' tcx , M :: Provenance > > {
557
584
// 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> {
563
590
let val = self . tcx . normalize_erasing_regions ( self . param_env , * val) ;
564
591
match val {
565
592
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)
594
597
}
595
598
mir:: ConstantKind :: Val ( val, ty) => self . const_val_to_op ( val, ty, layout) ,
596
599
mir:: ConstantKind :: Unevaluated ( uv, _) => {
597
600
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 ( ) )
599
602
}
600
603
}
601
604
}
602
605
603
- pub ( crate ) fn const_val_to_op (
606
+ pub ( super ) fn const_val_to_op (
604
607
& self ,
605
608
val_val : ConstValue < ' tcx > ,
606
609
ty : Ty < ' tcx > ,
0 commit comments