Skip to content

Commit 97ce1fb

Browse files
committed
Deduplicate invariants generated
1 parent 19e0f6f commit 97ce1fb

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics/validity_invariants_of.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_data_structures::fx::FxHashMap;
12
use rustc_hir::lang_items::LangItem;
23
use rustc_middle::mir::interpret::{AllocRange, Allocation, ConstAllocation, Scalar as MirScalar};
34
use rustc_middle::ty::layout::LayoutCx;
@@ -7,7 +8,7 @@ use rustc_target::abi::{
78
Abi, FieldsShape, HasDataLayout, Integer, Primitive, Scalar, Size, TyAndLayout, WrappingRange,
89
};
910

10-
#[derive(Debug, Clone, Copy)]
11+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1112
enum InvariantSize {
1213
U8,
1314
U16,
@@ -17,16 +18,14 @@ enum InvariantSize {
1718
Pointer,
1819
}
1920

20-
#[derive(Debug, Clone, Copy)]
21-
struct Invariant {
21+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22+
struct InvariantKey {
2223
offset: Size,
2324
size: InvariantSize,
24-
valid_range_start: u128,
25-
valid_range_end: u128,
2625
}
2726

2827
// FIXME: Don't add duplicate invariants (maybe use a HashMap?)
29-
fn add_invariants<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, invs: &mut Vec<Invariant>, offset: Size) {
28+
fn add_invariants<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, invs: &mut FxHashMap<InvariantKey, WrappingRange>, offset: Size) {
3029
let x = tcx.layout_of(ParamEnvAnd { param_env: ParamEnv::reveal_all(), value: ty });
3130

3231
if let Ok(layout) = x {
@@ -41,8 +40,10 @@ fn add_invariants<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, invs: &mut Vec<Invarian
4140
Primitive::F64 => InvariantSize::U64,
4241
Primitive::Pointer => InvariantSize::Pointer,
4342
};
44-
let WrappingRange { start, end } = valid_range;
45-
invs.push(Invariant { offset, size, valid_range_start: start, valid_range_end: end })
43+
44+
// Pick the first scalar we see, this means NonZeroU8(u8) ends up with only one
45+
// invariant, the stricter one.
46+
let _: Result<_, _> = invs.try_insert(InvariantKey { offset, size }, valid_range);
4647
}
4748

4849
let param_env = ParamEnv::reveal_all();
@@ -90,7 +91,7 @@ pub(crate) fn alloc_validity_invariants_of<'tcx>(
9091
tcx: TyCtxt<'tcx>,
9192
ty: Ty<'tcx>,
9293
) -> ConstAllocation<'tcx> {
93-
let mut invs: Vec<Invariant> = Vec::new();
94+
let mut invs = FxHashMap::default();
9495

9596
let layout = tcx.data_layout();
9697
let validity_invariant = get_layout_of_invariant(tcx);
@@ -114,21 +115,21 @@ pub(crate) fn alloc_validity_invariants_of<'tcx>(
114115
.write_scalar(
115116
&tcx,
116117
offset_range,
117-
MirScalar::from_machine_usize(invariant.offset.bytes(), &tcx).into(),
118+
MirScalar::from_machine_usize(invariant.0.offset.bytes(), &tcx).into(),
118119
)
119120
.unwrap();
120121

121122
let size_range = AllocRange { start: offset + size_off, size: Size::from_bytes(1) };
122123
alloc
123-
.write_scalar(&tcx, size_range, MirScalar::from_u8(invariant.size as u8).into())
124+
.write_scalar(&tcx, size_range, MirScalar::from_u8(invariant.0.size as u8).into())
124125
.unwrap();
125126

126127
let offset_range = AllocRange { start: offset + start_off, size: Size::from_bytes(16) };
127128
alloc
128129
.write_scalar(
129130
&tcx,
130131
offset_range,
131-
MirScalar::from_u128(invariant.valid_range_start).into(),
132+
MirScalar::from_u128(invariant.1.start).into(),
132133
)
133134
.unwrap();
134135

@@ -137,7 +138,7 @@ pub(crate) fn alloc_validity_invariants_of<'tcx>(
137138
.write_scalar(
138139
&tcx,
139140
offset_range,
140-
MirScalar::from_u128(invariant.valid_range_end).into(),
141+
MirScalar::from_u128(invariant.1.end).into(),
141142
)
142143
.unwrap();
143144
}

library/core/src/intrinsics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,6 +2140,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
21402140

21412141
#[derive(Debug, Clone, Copy)]
21422142
#[repr(u8)]
2143+
#[allow(dead_code)] // https://github.com/rust-lang/rust/issues/85677
21432144
enum InvariantSize {
21442145
U8 = 0,
21452146
U16 = 1,

0 commit comments

Comments
 (0)