Skip to content

Commit 38cd948

Browse files
committed
Auto merge of #61959 - oli-obk:const_field_ice, r=eddyb
Fix a hash collision issue on the `const_field` query fixes #61530
2 parents 56a12b2 + d46a373 commit 38cd948

File tree

16 files changed

+85
-49
lines changed

16 files changed

+85
-49
lines changed

Diff for: src/librustc/ich/impls_ty.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,18 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
175175
hcx: &mut StableHashingContext<'a>,
176176
hasher: &mut StableHasher<W>,
177177
) {
178-
self.bytes.hash_stable(hcx, hasher);
179-
for reloc in self.relocations.iter() {
178+
let mir::interpret::Allocation {
179+
bytes, relocations, undef_mask, align, mutability,
180+
extra: _,
181+
} = self;
182+
bytes.hash_stable(hcx, hasher);
183+
relocations.len().hash_stable(hcx, hasher);
184+
for reloc in relocations.iter() {
180185
reloc.hash_stable(hcx, hasher);
181186
}
182-
self.undef_mask.hash_stable(hcx, hasher);
183-
self.align.hash_stable(hcx, hasher);
184-
self.mutability.hash_stable(hcx, hasher);
187+
undef_mask.hash_stable(hcx, hasher);
188+
align.hash_stable(hcx, hasher);
189+
mutability.hash_stable(hcx, hasher);
185190
}
186191
}
187192

Diff for: src/librustc/infer/freshen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
260260
ConstValue::Param(_) |
261261
ConstValue::Scalar(_) |
262262
ConstValue::Slice { .. } |
263-
ConstValue::ByRef(..) |
263+
ConstValue::ByRef { .. } |
264264
ConstValue::Unevaluated(..) => {}
265265
}
266266

Diff for: src/librustc/mir/interpret/allocation.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
247247
assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`");
248248
self.check_bounds(cx, ptr, size, CheckInAllocMsg::MemoryAccessTest)?;
249249

250-
self.mark_definedness(ptr, size, true)?;
250+
self.mark_definedness(ptr, size, true);
251251
self.clear_relocations(cx, ptr, size)?;
252252

253253
AllocationExtra::memory_written(self, ptr, size)?;
@@ -406,7 +406,10 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
406406
{
407407
let val = match val {
408408
ScalarMaybeUndef::Scalar(scalar) => scalar,
409-
ScalarMaybeUndef::Undef => return self.mark_definedness(ptr, type_size, false),
409+
ScalarMaybeUndef::Undef => {
410+
self.mark_definedness(ptr, type_size, false);
411+
return Ok(());
412+
},
410413
};
411414

412415
let bytes = match val.to_bits_or_ptr(type_size, cx) {
@@ -550,16 +553,15 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
550553
ptr: Pointer<Tag>,
551554
size: Size,
552555
new_state: bool,
553-
) -> InterpResult<'tcx> {
556+
) {
554557
if size.bytes() == 0 {
555-
return Ok(());
558+
return;
556559
}
557560
self.undef_mask.set_range(
558561
ptr.offset,
559562
ptr.offset + size,
560563
new_state,
561564
);
562-
Ok(())
563565
}
564566
}
565567

Diff for: src/librustc/mir/interpret/value.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,21 @@ pub enum ConstValue<'tcx> {
4343
end: usize,
4444
},
4545

46-
/// An allocation together with a pointer into the allocation.
47-
/// Invariant: the pointer's `AllocId` resolves to the allocation.
48-
/// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive fields
49-
/// of `repr(packed)` structs. The alignment may be lower than the type of this constant.
50-
/// This permits reads with lower alignment than what the type would normally require.
51-
/// FIXME(RalfJ,oli-obk): The alignment checks are part of miri, but const eval doesn't really
52-
/// need them. Disabling them may be too hard though.
53-
ByRef(Pointer, Align, &'tcx Allocation),
46+
/// A value not represented/representable by `Scalar` or `Slice`
47+
ByRef {
48+
/// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive
49+
/// fields of `repr(packed)` structs. The alignment may be lower than the type of this
50+
/// constant. This permits reads with lower alignment than what the type would normally
51+
/// require.
52+
/// FIXME(RalfJ,oli-obk): The alignment checks are part of miri, but const eval doesn't
53+
/// really need them. Disabling them may be too hard though.
54+
align: Align,
55+
/// Offset into `alloc`
56+
offset: Size,
57+
/// The backing memory of the value, may contain more memory than needed for just the value
58+
/// in order to share `Allocation`s between values
59+
alloc: &'tcx Allocation,
60+
},
5461

5562
/// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
5663
/// variants when the code is monomorphic enough for that.
@@ -67,7 +74,7 @@ impl<'tcx> ConstValue<'tcx> {
6774
ConstValue::Param(_) |
6875
ConstValue::Infer(_) |
6976
ConstValue::Placeholder(_) |
70-
ConstValue::ByRef(..) |
77+
ConstValue::ByRef{ .. } |
7178
ConstValue::Unevaluated(..) |
7279
ConstValue::Slice { .. } => None,
7380
ConstValue::Scalar(val) => Some(val),

Diff for: src/librustc/ty/print/obsolete.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl DefPathBasedNames<'tcx> {
186186
// as well as the unprintable types of constants (see `push_type_name` for more details).
187187
pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) {
188188
match c.val {
189-
ConstValue::Scalar(..) | ConstValue::Slice { .. } | ConstValue::ByRef(..) => {
189+
ConstValue::Scalar(..) | ConstValue::Slice { .. } | ConstValue::ByRef { .. } => {
190190
// FIXME(const_generics): we could probably do a better job here.
191191
write!(output, "{:?}", c).unwrap()
192192
}

Diff for: src/librustc/ty/relate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
594594
ty: a.ty,
595595
}))
596596
}
597-
(ConstValue::ByRef(..), _) => {
597+
(ConstValue::ByRef { .. }, _) => {
598598
bug!(
599599
"non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}",
600600
a,

Diff for: src/librustc/ty/structural_impls.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1335,7 +1335,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
13351335
impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
13361336
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
13371337
match *self {
1338-
ConstValue::ByRef(ptr, align, alloc) => ConstValue::ByRef(ptr, align, alloc),
1338+
ConstValue::ByRef { offset, align, alloc } =>
1339+
ConstValue::ByRef { offset, align, alloc },
13391340
ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)),
13401341
ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)),
13411342
ConstValue::Placeholder(p) => ConstValue::Placeholder(p),
@@ -1348,7 +1349,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
13481349

13491350
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
13501351
match *self {
1351-
ConstValue::ByRef(..) => false,
1352+
ConstValue::ByRef { .. } => false,
13521353
ConstValue::Infer(ic) => ic.visit_with(visitor),
13531354
ConstValue::Param(p) => p.visit_with(visitor),
13541355
ConstValue::Placeholder(_) => false,

Diff for: src/librustc_codegen_llvm/consts.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ pub fn codegen_static_initializer(
7171
let static_ = cx.tcx.const_eval(param_env.and(cid))?;
7272

7373
let alloc = match static_.val {
74-
ConstValue::ByRef(ptr, align, alloc) if ptr.offset.bytes() == 0 && align == alloc.align => {
74+
ConstValue::ByRef {
75+
offset, align, alloc,
76+
} if offset.bytes() == 0 && align == alloc.align => {
7577
alloc
7678
},
7779
_ => bug!("static const eval returned {:#?}", static_),

Diff for: src/librustc_codegen_ssa/mir/operand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
109109
let b_llval = bx.const_usize((end - start) as u64);
110110
OperandValue::Pair(a_llval, b_llval)
111111
},
112-
ConstValue::ByRef(ptr, align, alloc) => {
113-
return bx.load_operand(bx.from_const_alloc(layout, align, alloc, ptr.offset));
112+
ConstValue::ByRef { offset, align, alloc } => {
113+
return bx.load_operand(bx.from_const_alloc(layout, align, alloc, offset));
114114
},
115115
};
116116

Diff for: src/librustc_codegen_ssa/mir/place.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
424424
let layout = cx.layout_of(self.monomorphize(&ty));
425425
match bx.tcx().const_eval(param_env.and(cid)) {
426426
Ok(val) => match val.val {
427-
mir::interpret::ConstValue::ByRef(ptr, align, alloc) => {
428-
bx.cx().from_const_alloc(layout, align, alloc, ptr.offset)
427+
mir::interpret::ConstValue::ByRef { offset, align, alloc } => {
428+
bx.cx().from_const_alloc(layout, align, alloc, offset)
429429
}
430430
_ => bug!("promoteds should have an allocation: {:?}", val),
431431
},

Diff for: src/librustc_mir/const_eval.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ fn op_to_const<'tcx>(
9999
Ok(mplace) => {
100100
let ptr = mplace.ptr.to_ptr().unwrap();
101101
let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
102-
ConstValue::ByRef(ptr, mplace.align, alloc)
102+
ConstValue::ByRef { offset: ptr.offset, align: mplace.align, alloc }
103103
},
104104
// see comment on `let try_as_immediate` above
105105
Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x {
@@ -113,7 +113,7 @@ fn op_to_const<'tcx>(
113113
let mplace = op.to_mem_place();
114114
let ptr = mplace.ptr.to_ptr().unwrap();
115115
let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
116-
ConstValue::ByRef(ptr, mplace.align, alloc)
116+
ConstValue::ByRef { offset: ptr.offset, align: mplace.align, alloc }
117117
},
118118
},
119119
Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => {
@@ -541,11 +541,11 @@ fn validate_and_turn_into_const<'tcx>(
541541
if tcx.is_static(def_id) || cid.promoted.is_some() {
542542
let ptr = mplace.ptr.to_ptr()?;
543543
Ok(tcx.mk_const(ty::Const {
544-
val: ConstValue::ByRef(
545-
ptr,
546-
mplace.align,
547-
ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id),
548-
),
544+
val: ConstValue::ByRef {
545+
offset: ptr.offset,
546+
align: mplace.align,
547+
alloc: ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id),
548+
},
549549
ty: mplace.layout.ty,
550550
}))
551551
} else {

Diff for: src/librustc_mir/hair/pattern/_match.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,12 @@ impl LiteralExpander<'tcx> {
217217
// the easy case, deref a reference
218218
(ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => {
219219
let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id);
220-
ConstValue::ByRef(
221-
p,
220+
ConstValue::ByRef {
221+
offset: p.offset,
222222
// FIXME(oli-obk): this should be the type's layout
223-
alloc.align,
223+
align: alloc.align,
224224
alloc,
225-
)
225+
}
226226
},
227227
// unsize array to slice if pattern is array but match value or other patterns are slice
228228
(ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => {
@@ -1436,9 +1436,10 @@ fn slice_pat_covered_by_const<'tcx>(
14361436
suffix: &[Pattern<'tcx>],
14371437
) -> Result<bool, ErrorReported> {
14381438
let data: &[u8] = match (const_val.val, &const_val.ty.sty) {
1439-
(ConstValue::ByRef(ptr, _, alloc), ty::Array(t, n)) => {
1439+
(ConstValue::ByRef { offset, alloc, .. }, ty::Array(t, n)) => {
14401440
assert_eq!(*t, tcx.types.u8);
14411441
let n = n.assert_usize(tcx).unwrap();
1442+
let ptr = Pointer::new(AllocId(0), offset);
14421443
alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap()
14431444
},
14441445
(ConstValue::Slice { data, start, end }, ty::Slice(t)) => {
@@ -1758,9 +1759,9 @@ fn specialize<'p, 'a: 'p, 'tcx>(
17581759
let (alloc, offset, n, ty) = match value.ty.sty {
17591760
ty::Array(t, n) => {
17601761
match value.val {
1761-
ConstValue::ByRef(ptr, _, alloc) => (
1762+
ConstValue::ByRef { offset, alloc, .. } => (
17621763
alloc,
1763-
ptr.offset,
1764+
offset,
17641765
n.unwrap_usize(cx.tcx),
17651766
t,
17661767
),
@@ -1778,7 +1779,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
17781779
(end - start) as u64,
17791780
t,
17801781
),
1781-
ConstValue::ByRef(..) => {
1782+
ConstValue::ByRef { .. } => {
17821783
// FIXME(oli-obk): implement `deref` for `ConstValue`
17831784
return None;
17841785
},

Diff for: src/librustc_mir/interpret/operand.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -538,10 +538,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
538538
self.layout_of(self.monomorphize(val.ty)?)
539539
})?;
540540
let op = match val.val {
541-
ConstValue::ByRef(ptr, align, _alloc) => {
541+
ConstValue::ByRef { offset, align, alloc } => {
542+
let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
542543
// We rely on mutability being set correctly in that allocation to prevent writes
543544
// where none should happen.
544-
let ptr = self.tag_static_base_pointer(ptr);
545+
let ptr = self.tag_static_base_pointer(Pointer::new(id, offset));
545546
Operand::Indirect(MemPlace::from_ptr(ptr, align))
546547
},
547548
ConstValue::Scalar(x) =>

Diff for: src/librustc_mir/monomorphize/collector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ fn collect_const<'tcx>(
12621262
ConstValue::Scalar(Scalar::Ptr(ptr)) =>
12631263
collect_miri(tcx, ptr.alloc_id, output),
12641264
ConstValue::Slice { data: alloc, start: _, end: _ } |
1265-
ConstValue::ByRef(_, _, alloc) => {
1265+
ConstValue::ByRef { alloc, .. } => {
12661266
for &((), id) in alloc.relocations.values() {
12671267
collect_miri(tcx, id, output);
12681268
}

Diff for: src/librustc_typeck/check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1448,8 +1448,8 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span)
14481448
};
14491449
let param_env = ty::ParamEnv::reveal_all();
14501450
if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1451-
let alloc = if let ConstValue::ByRef(_, _, allocation) = static_.val {
1452-
allocation
1451+
let alloc = if let ConstValue::ByRef { alloc, .. } = static_.val {
1452+
alloc
14531453
} else {
14541454
bug!("Matching on non-ByRef static")
14551455
};

Diff for: src/test/incremental/issue-61530.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(repr_simd, platform_intrinsics)]
2+
3+
// revisions:rpass1 rpass2
4+
5+
#[repr(simd)]
6+
struct I32x2(i32, i32);
7+
8+
extern "platform-intrinsic" {
9+
fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
10+
}
11+
12+
fn main() {
13+
unsafe {
14+
let _: I32x2 = simd_shuffle2(I32x2(1, 2), I32x2(3, 4), [0, 0]);
15+
let _: I32x2 = simd_shuffle2(I32x2(1, 2), I32x2(3, 4), [0, 0]);
16+
}
17+
}

0 commit comments

Comments
 (0)