@@ -11,12 +11,12 @@ use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
1111use crate :: ty:: print:: { FmtPrinter , Printer } ;
1212use crate :: ty:: subst:: { Subst , SubstsRef } ;
1313use crate :: ty:: { self , List , Ty , TyCtxt } ;
14- use crate :: ty:: { AdtDef , InstanceDef , Region , UserTypeAnnotationIndex } ;
14+ use crate :: ty:: { AdtDef , InstanceDef , Region , ScalarInt , UserTypeAnnotationIndex } ;
1515use rustc_hir as hir;
1616use rustc_hir:: def:: { CtorKind , Namespace } ;
1717use rustc_hir:: def_id:: { DefId , CRATE_DEF_INDEX } ;
1818use rustc_hir:: { self , GeneratorKind } ;
19- use rustc_target:: abi:: VariantIdx ;
19+ use rustc_target:: abi:: { Size , VariantIdx } ;
2020
2121use polonius_engine:: Atom ;
2222pub use rustc_ast:: Mutability ;
@@ -30,6 +30,7 @@ use rustc_span::symbol::Symbol;
3030use rustc_span:: { Span , DUMMY_SP } ;
3131use rustc_target:: asm:: InlineAsmRegOrRegClass ;
3232use std:: borrow:: Cow ;
33+ use std:: convert:: TryInto ;
3334use std:: fmt:: { self , Debug , Display , Formatter , Write } ;
3435use std:: ops:: { ControlFlow , Index , IndexMut } ;
3536use std:: slice;
@@ -2032,7 +2033,7 @@ impl<'tcx> Operand<'tcx> {
20322033 Operand :: Constant ( box Constant {
20332034 span,
20342035 user_ty : None ,
2035- literal : ty:: Const :: zero_sized ( tcx, ty) ,
2036+ literal : ConstantSource :: Ty ( ty:: Const :: zero_sized ( tcx, ty) ) ,
20362037 } )
20372038 }
20382039
@@ -2063,7 +2064,7 @@ impl<'tcx> Operand<'tcx> {
20632064 Operand :: Constant ( box Constant {
20642065 span,
20652066 user_ty : None ,
2066- literal : ty :: Const :: from_scalar ( tcx , val, ty) ,
2067+ literal : ConstantSource :: Val ( val. into ( ) , ty) ,
20672068 } )
20682069 }
20692070
@@ -2405,12 +2406,21 @@ pub struct Constant<'tcx> {
24052406 /// Needed for NLL to impose user-given type constraints.
24062407 pub user_ty : Option < UserTypeAnnotationIndex > ,
24072408
2408- pub literal : & ' tcx ty:: Const < ' tcx > ,
2409+ pub literal : ConstantSource < ' tcx > ,
2410+ }
2411+
2412+ #[ derive( Clone , Copy , PartialEq , PartialOrd , TyEncodable , TyDecodable , Hash , HashStable , Debug ) ]
2413+ pub enum ConstantSource < ' tcx > {
2414+ /// This constant came from the type system
2415+ Ty ( & ' tcx ty:: Const < ' tcx > ) ,
2416+ /// This constant cannot go back into the type system, as it represents
2417+ /// something the type system cannot handle (e.g. pointers).
2418+ Val ( interpret:: ConstValue < ' tcx > , Ty < ' tcx > ) ,
24092419}
24102420
24112421impl Constant < ' tcx > {
24122422 pub fn check_static_ptr ( & self , tcx : TyCtxt < ' _ > ) -> Option < DefId > {
2413- match self . literal . val . try_to_scalar ( ) {
2423+ match self . literal . const_for_ty ( ) ? . val . try_to_scalar ( ) {
24142424 Some ( Scalar :: Ptr ( ptr) ) => match tcx. global_alloc ( ptr. alloc_id ) {
24152425 GlobalAlloc :: Static ( def_id) => {
24162426 assert ! ( !tcx. is_thread_local_static( def_id) ) ;
@@ -2422,7 +2432,92 @@ impl Constant<'tcx> {
24222432 }
24232433 }
24242434 pub fn ty ( & self ) -> Ty < ' tcx > {
2425- self . literal . ty
2435+ self . literal . ty ( )
2436+ }
2437+ }
2438+
2439+ impl From < & ' tcx ty:: Const < ' tcx > > for ConstantSource < ' tcx > {
2440+ fn from ( ct : & ' tcx ty:: Const < ' tcx > ) -> Self {
2441+ Self :: Ty ( ct)
2442+ }
2443+ }
2444+
2445+ impl ConstantSource < ' tcx > {
2446+ /// Returns `None` if the constant is not trivially safe for use in the type system.
2447+ pub fn const_for_ty ( & self ) -> Option < & ' tcx ty:: Const < ' tcx > > {
2448+ match self {
2449+ ConstantSource :: Ty ( c) => Some ( c) ,
2450+ ConstantSource :: Val ( ..) => None ,
2451+ }
2452+ }
2453+
2454+ pub fn ty ( & self ) -> Ty < ' tcx > {
2455+ match self {
2456+ ConstantSource :: Ty ( c) => c. ty ,
2457+ ConstantSource :: Val ( _, ty) => ty,
2458+ }
2459+ }
2460+
2461+ #[ inline]
2462+ pub fn try_to_value ( self ) -> Option < interpret:: ConstValue < ' tcx > > {
2463+ match self {
2464+ ConstantSource :: Ty ( c) => c. val . try_to_value ( ) ,
2465+ ConstantSource :: Val ( val, _) => Some ( val) ,
2466+ }
2467+ }
2468+
2469+ #[ inline]
2470+ pub fn try_to_scalar ( self ) -> Option < Scalar > {
2471+ self . try_to_value ( ) ?. try_to_scalar ( )
2472+ }
2473+
2474+ #[ inline]
2475+ pub fn try_to_scalar_int ( self ) -> Option < ScalarInt > {
2476+ self . try_to_value ( ) ?. try_to_scalar ( ) ?. to_int ( ) . ok ( )
2477+ }
2478+
2479+ #[ inline]
2480+ pub fn try_to_bits ( self , size : Size ) -> Option < u128 > {
2481+ self . try_to_scalar_int ( ) ?. to_bits ( size) . ok ( )
2482+ }
2483+
2484+ #[ inline]
2485+ pub fn try_to_bool ( self ) -> Option < bool > {
2486+ self . try_to_scalar_int ( ) ?. try_into ( ) . ok ( )
2487+ }
2488+
2489+ #[ inline]
2490+ pub fn try_eval_bits (
2491+ & self ,
2492+ tcx : TyCtxt < ' tcx > ,
2493+ param_env : ty:: ParamEnv < ' tcx > ,
2494+ ty : Ty < ' tcx > ,
2495+ ) -> Option < u128 > {
2496+ match self {
2497+ Self :: Ty ( ct) => ct. try_eval_bits ( tcx, param_env, ty) ,
2498+ Self :: Val ( val, t) => {
2499+ assert_eq ! ( * t, ty) ;
2500+ let size =
2501+ tcx. layout_of ( param_env. with_reveal_all_normalized ( tcx) . and ( ty) ) . ok ( ) ?. size ;
2502+ val. try_to_bits ( size)
2503+ }
2504+ }
2505+ }
2506+
2507+ #[ inline]
2508+ pub fn try_eval_bool ( & self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> Option < bool > {
2509+ match self {
2510+ Self :: Ty ( ct) => ct. try_eval_bool ( tcx, param_env) ,
2511+ Self :: Val ( val, _) => val. try_to_bool ( ) ,
2512+ }
2513+ }
2514+
2515+ #[ inline]
2516+ pub fn try_eval_usize ( & self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> Option < u64 > {
2517+ match self {
2518+ Self :: Ty ( ct) => ct. try_eval_usize ( tcx, param_env) ,
2519+ Self :: Val ( val, _) => val. try_to_machine_usize ( tcx) ,
2520+ }
24262521 }
24272522}
24282523
@@ -2609,11 +2704,14 @@ impl<'tcx> Debug for Constant<'tcx> {
26092704
26102705impl < ' tcx > Display for Constant < ' tcx > {
26112706 fn fmt ( & self , fmt : & mut Formatter < ' _ > ) -> fmt:: Result {
2612- match self . literal . ty . kind ( ) {
2707+ match self . ty ( ) . kind ( ) {
26132708 ty:: FnDef ( ..) => { }
26142709 _ => write ! ( fmt, "const " ) ?,
26152710 }
2616- pretty_print_const ( self . literal , fmt, true )
2711+ match self . literal {
2712+ ConstantSource :: Ty ( c) => pretty_print_const ( c, fmt, true ) ,
2713+ ConstantSource :: Val ( val, ty) => pretty_print_const_value ( val, ty, fmt, true ) ,
2714+ }
26172715 }
26182716}
26192717
@@ -2632,6 +2730,23 @@ fn pretty_print_const(
26322730 } )
26332731}
26342732
2733+ fn pretty_print_const_value (
2734+ val : interpret:: ConstValue < ' tcx > ,
2735+ ty : Ty < ' tcx > ,
2736+ fmt : & mut Formatter < ' _ > ,
2737+ print_types : bool ,
2738+ ) -> fmt:: Result {
2739+ use crate :: ty:: print:: PrettyPrinter ;
2740+ ty:: tls:: with ( |tcx| {
2741+ let val = val. lift ( tcx) . unwrap ( ) ;
2742+ let ty = tcx. lift ( ty) . unwrap ( ) ;
2743+ let mut cx = FmtPrinter :: new ( tcx, fmt, Namespace :: ValueNS ) ;
2744+ cx. print_alloc_ids = true ;
2745+ cx. pretty_print_const_value ( val, ty, print_types) ?;
2746+ Ok ( ( ) )
2747+ } )
2748+ }
2749+
26352750impl < ' tcx > graph:: DirectedGraph for Body < ' tcx > {
26362751 type Node = BasicBlock ;
26372752}
0 commit comments