1
1
use rustc_data_structures:: fx:: FxHashMap ;
2
2
use rustc_hir:: lang_items:: LangItem ;
3
3
use rustc_middle:: mir:: interpret:: { AllocRange , Allocation , ConstAllocation , Scalar as MirScalar } ;
4
+ use rustc_middle:: mir:: Mutability ;
4
5
use rustc_middle:: ty:: layout:: LayoutCx ;
5
6
use rustc_middle:: ty:: { ParamEnv , ParamEnvAnd } ;
6
7
use rustc_middle:: ty:: { Ty , TyCtxt } ;
7
8
use rustc_target:: abi:: {
8
- Abi , FieldsShape , HasDataLayout , Integer , Primitive , Scalar , Size , TyAndLayout , WrappingRange ,
9
+ Abi , FieldsShape , HasDataLayout , Integer , Primitive , Scalar , Size , TyAndLayout , WrappingRange , Variants ,
9
10
} ;
10
11
11
12
#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
@@ -25,7 +26,12 @@ struct InvariantKey {
25
26
}
26
27
27
28
// FIXME: Don't add duplicate invariants (maybe use a HashMap?)
28
- fn add_invariants < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , invs : & mut FxHashMap < InvariantKey , WrappingRange > , offset : Size ) {
29
+ fn add_invariants < ' tcx > (
30
+ tcx : TyCtxt < ' tcx > ,
31
+ ty : Ty < ' tcx > ,
32
+ invs : & mut FxHashMap < InvariantKey , WrappingRange > ,
33
+ offset : Size ,
34
+ ) {
29
35
let x = tcx. layout_of ( ParamEnvAnd { param_env : ParamEnv :: reveal_all ( ) , value : ty } ) ;
30
36
31
37
if let Ok ( layout) = x {
@@ -46,8 +52,14 @@ fn add_invariants<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, invs: &mut FxHashMap<In
46
52
let _: Result < _ , _ > = invs. try_insert ( InvariantKey { offset, size } , valid_range) ;
47
53
}
48
54
55
+ //dbg!(&ty, &layout);
56
+ if !matches ! ( layout. layout. variants( ) , Variants :: Single { .. } ) {
57
+ // We *don't* want to look for fields inside enums.
58
+ return ;
59
+ }
60
+
49
61
let param_env = ParamEnv :: reveal_all ( ) ;
50
- let unwrap = LayoutCx { tcx, param_env } ;
62
+ let layout_cx = LayoutCx { tcx, param_env } ;
51
63
52
64
match layout. layout . fields ( ) {
53
65
FieldsShape :: Primitive => { }
@@ -57,13 +69,13 @@ fn add_invariants<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, invs: &mut FxHashMap<In
57
69
// That would lead to false negatives, though.
58
70
for idx in 0 ..* count {
59
71
let off = offset + * stride * idx;
60
- let f = layout. field ( & unwrap , idx as usize ) ;
72
+ let f = layout. field ( & layout_cx , idx as usize ) ;
61
73
add_invariants ( tcx, f. ty , invs, off) ;
62
74
}
63
75
}
64
76
FieldsShape :: Arbitrary { offsets, .. } => {
65
77
for ( idx, & field_offset) in offsets. iter ( ) . enumerate ( ) {
66
- let f = layout. field ( & unwrap , idx) ;
78
+ let f = layout. field ( & layout_cx , idx) ;
67
79
if f. ty == ty {
68
80
// Some types contain themselves as fields, such as
69
81
// &mut [T]
@@ -90,7 +102,7 @@ fn get_layout_of_invariant<'tcx>(tcx: TyCtxt<'tcx>) -> TyAndLayout<'tcx, Ty<'tcx
90
102
pub ( crate ) fn alloc_validity_invariants_of < ' tcx > (
91
103
tcx : TyCtxt < ' tcx > ,
92
104
ty : Ty < ' tcx > ,
93
- ) -> ConstAllocation < ' tcx > {
105
+ ) -> ( ConstAllocation < ' tcx > , usize ) {
94
106
let mut invs = FxHashMap :: default ( ) ;
95
107
96
108
let layout = tcx. data_layout ( ) ;
@@ -126,22 +138,17 @@ pub(crate) fn alloc_validity_invariants_of<'tcx>(
126
138
127
139
let offset_range = AllocRange { start : offset + start_off, size : Size :: from_bytes ( 16 ) } ;
128
140
alloc
129
- . write_scalar (
130
- & tcx,
131
- offset_range,
132
- MirScalar :: from_u128 ( invariant. 1 . start ) . into ( ) ,
133
- )
141
+ . write_scalar ( & tcx, offset_range, MirScalar :: from_u128 ( invariant. 1 . start ) . into ( ) )
134
142
. unwrap ( ) ;
135
143
136
144
let offset_range = AllocRange { start : offset + end_off, size : Size :: from_bytes ( 16 ) } ;
137
145
alloc
138
- . write_scalar (
139
- & tcx,
140
- offset_range,
141
- MirScalar :: from_u128 ( invariant. 1 . end ) . into ( ) ,
142
- )
146
+ . write_scalar ( & tcx, offset_range, MirScalar :: from_u128 ( invariant. 1 . end ) . into ( ) )
143
147
. unwrap ( ) ;
144
148
}
145
149
146
- tcx. intern_const_alloc ( alloc)
150
+ // The allocation is not mutable, we just needed write_scalar.
151
+ alloc. mutability = Mutability :: Not ;
152
+
153
+ ( tcx. intern_const_alloc ( alloc) , invs. len ( ) )
147
154
}
0 commit comments