@@ -32,7 +32,12 @@ fn add_invariants<'tcx>(
32
32
ty : Ty < ' tcx > ,
33
33
invs : & mut FxHashMap < InvariantKey , WrappingRange > ,
34
34
offset : Size ,
35
+ strictness : InvariantStrictness ,
35
36
) {
37
+ if strictness == InvariantStrictness :: Disable {
38
+ return ;
39
+ }
40
+
36
41
let x = tcx. layout_of ( ParamEnvAnd { param_env : ParamEnv :: reveal_all ( ) , value : ty } ) ;
37
42
38
43
if let Ok ( layout) = x {
@@ -48,9 +53,12 @@ fn add_invariants<'tcx>(
48
53
Primitive :: Pointer => InvariantSize :: Pointer ,
49
54
} ;
50
55
51
- // Pick the first scalar we see, this means NonZeroU8(u8) ends up with only one
52
- // invariant, the stricter one.
53
- let _: Result < _ , _ > = invs. try_insert ( InvariantKey { offset, size } , valid_range) ;
56
+ if !valid_range. is_full_for ( value. size ( & tcx) ) || strictness == InvariantStrictness :: All
57
+ {
58
+ // Pick the first scalar we see, this means NonZeroU8(u8) ends up with only one
59
+ // invariant, the stricter one.
60
+ let _: Result < _ , _ > = invs. try_insert ( InvariantKey { offset, size } , valid_range) ;
61
+ }
54
62
}
55
63
56
64
//dbg!(&ty, &layout);
@@ -71,7 +79,7 @@ fn add_invariants<'tcx>(
71
79
for idx in 0 ..* count {
72
80
let off = offset + * stride * idx;
73
81
let f = layout. field ( & layout_cx, idx as usize ) ;
74
- add_invariants ( tcx, f. ty , invs, off) ;
82
+ add_invariants ( tcx, f. ty , invs, off, strictness ) ;
75
83
}
76
84
}
77
85
FieldsShape :: Arbitrary { offsets, .. } => {
@@ -82,7 +90,7 @@ fn add_invariants<'tcx>(
82
90
// &mut [T]
83
91
// Easy solution is to just not recurse then.
84
92
} else {
85
- add_invariants ( tcx, f. ty , invs, offset + field_offset) ;
93
+ add_invariants ( tcx, f. ty , invs, offset + field_offset, strictness ) ;
86
94
}
87
95
}
88
96
}
@@ -99,17 +107,25 @@ fn get_layout_of_invariant<'tcx>(tcx: TyCtxt<'tcx>) -> TyAndLayout<'tcx, Ty<'tcx
99
107
layout
100
108
}
101
109
110
+ #[ derive( PartialEq , Clone , Copy , Eq ) ]
111
+ pub ( crate ) enum InvariantStrictness {
112
+ Disable ,
113
+ Normal ,
114
+ All ,
115
+ }
116
+
102
117
/// Directly returns a `ConstAllocation` containing a list of validity invariants of the given type.
103
118
pub ( crate ) fn alloc_validity_invariants_of < ' tcx > (
104
119
tcx : TyCtxt < ' tcx > ,
105
120
ty : Ty < ' tcx > ,
121
+ strictness : InvariantStrictness ,
106
122
) -> ( ConstAllocation < ' tcx > , usize ) {
107
123
let mut invs = FxHashMap :: default ( ) ;
108
124
109
125
let layout = tcx. data_layout ( ) ;
110
126
let validity_invariant = get_layout_of_invariant ( tcx) ;
111
127
112
- add_invariants ( tcx, ty, & mut invs, Size :: ZERO ) ;
128
+ add_invariants ( tcx, ty, & mut invs, Size :: ZERO , strictness ) ;
113
129
114
130
let allocation_size = validity_invariant. layout . size ( ) * invs. len ( ) as u64 ;
115
131
let mut alloc =
0 commit comments