@@ -11,12 +11,12 @@ use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
11
11
use crate :: ty:: print:: { FmtPrinter , Printer } ;
12
12
use crate :: ty:: subst:: { Subst , SubstsRef } ;
13
13
use crate :: ty:: { self , List , Ty , TyCtxt } ;
14
- use crate :: ty:: { AdtDef , InstanceDef , Region , UserTypeAnnotationIndex } ;
14
+ use crate :: ty:: { AdtDef , InstanceDef , Region , ScalarInt , UserTypeAnnotationIndex } ;
15
15
use rustc_hir as hir;
16
16
use rustc_hir:: def:: { CtorKind , Namespace } ;
17
17
use rustc_hir:: def_id:: { DefId , CRATE_DEF_INDEX } ;
18
18
use rustc_hir:: { self , GeneratorKind } ;
19
- use rustc_target:: abi:: VariantIdx ;
19
+ use rustc_target:: abi:: { Size , VariantIdx } ;
20
20
21
21
use polonius_engine:: Atom ;
22
22
pub use rustc_ast:: Mutability ;
@@ -30,6 +30,7 @@ use rustc_span::symbol::Symbol;
30
30
use rustc_span:: { Span , DUMMY_SP } ;
31
31
use rustc_target:: asm:: InlineAsmRegOrRegClass ;
32
32
use std:: borrow:: Cow ;
33
+ use std:: convert:: TryInto ;
33
34
use std:: fmt:: { self , Debug , Display , Formatter , Write } ;
34
35
use std:: ops:: { ControlFlow , Index , IndexMut } ;
35
36
use std:: slice;
@@ -2032,7 +2033,7 @@ impl<'tcx> Operand<'tcx> {
2032
2033
Operand :: Constant ( box Constant {
2033
2034
span,
2034
2035
user_ty : None ,
2035
- literal : ty:: Const :: zero_sized ( tcx, ty) ,
2036
+ literal : ConstantSource :: Ty ( ty:: Const :: zero_sized ( tcx, ty) ) ,
2036
2037
} )
2037
2038
}
2038
2039
@@ -2063,7 +2064,7 @@ impl<'tcx> Operand<'tcx> {
2063
2064
Operand :: Constant ( box Constant {
2064
2065
span,
2065
2066
user_ty : None ,
2066
- literal : ty :: Const :: from_scalar ( tcx , val, ty) ,
2067
+ literal : ConstantSource :: Val ( val. into ( ) , ty) ,
2067
2068
} )
2068
2069
}
2069
2070
@@ -2405,12 +2406,21 @@ pub struct Constant<'tcx> {
2405
2406
/// Needed for NLL to impose user-given type constraints.
2406
2407
pub user_ty : Option < UserTypeAnnotationIndex > ,
2407
2408
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 > ) ,
2409
2419
}
2410
2420
2411
2421
impl Constant < ' tcx > {
2412
2422
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 ( ) {
2414
2424
Some ( Scalar :: Ptr ( ptr) ) => match tcx. global_alloc ( ptr. alloc_id ) {
2415
2425
GlobalAlloc :: Static ( def_id) => {
2416
2426
assert ! ( !tcx. is_thread_local_static( def_id) ) ;
@@ -2422,7 +2432,92 @@ impl Constant<'tcx> {
2422
2432
}
2423
2433
}
2424
2434
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
+ }
2426
2521
}
2427
2522
}
2428
2523
@@ -2609,11 +2704,14 @@ impl<'tcx> Debug for Constant<'tcx> {
2609
2704
2610
2705
impl < ' tcx > Display for Constant < ' tcx > {
2611
2706
fn fmt ( & self , fmt : & mut Formatter < ' _ > ) -> fmt:: Result {
2612
- match self . literal . ty . kind ( ) {
2707
+ match self . ty ( ) . kind ( ) {
2613
2708
ty:: FnDef ( ..) => { }
2614
2709
_ => write ! ( fmt, "const " ) ?,
2615
2710
}
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
+ }
2617
2715
}
2618
2716
}
2619
2717
@@ -2632,6 +2730,23 @@ fn pretty_print_const(
2632
2730
} )
2633
2731
}
2634
2732
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
+
2635
2750
impl < ' tcx > graph:: DirectedGraph for Body < ' tcx > {
2636
2751
type Node = BasicBlock ;
2637
2752
}
0 commit comments