From 4399299edc7200685703b4443cf92d670526d469 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 11 Jun 2019 10:56:41 +0200 Subject: [PATCH 1/8] mark_definedness cannot fail --- src/librustc/mir/interpret/allocation.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index d7caf950dcebd..8381125798a0d 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -247,7 +247,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`"); self.check_bounds(cx, ptr, size, CheckInAllocMsg::MemoryAccessTest)?; - self.mark_definedness(ptr, size, true)?; + self.mark_definedness(ptr, size, true); self.clear_relocations(cx, ptr, size)?; AllocationExtra::memory_written(self, ptr, size)?; @@ -406,7 +406,10 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { { let val = match val { ScalarMaybeUndef::Scalar(scalar) => scalar, - ScalarMaybeUndef::Undef => return self.mark_definedness(ptr, type_size, false), + ScalarMaybeUndef::Undef => { + self.mark_definedness(ptr, type_size, false); + return Ok(()); + }, }; let bytes = match val.to_bits_or_ptr(type_size, cx) { @@ -550,16 +553,15 @@ impl<'tcx, Tag, Extra> Allocation { ptr: Pointer, size: Size, new_state: bool, - ) -> InterpResult<'tcx> { + ) { if size.bytes() == 0 { - return Ok(()); + return; } self.undef_mask.set_range( ptr.offset, ptr.offset + size, new_state, ); - Ok(()) } } From e951d8ec0b9055c333485c0f68024b8371f4fa61 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 13 Jun 2019 16:52:37 +0200 Subject: [PATCH 2/8] Make `Allocation` stable hash robust --- src/librustc/ich/impls_ty.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 9b144b1ba3d2a..b2ad7e923b068 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -175,13 +175,17 @@ impl<'a> HashStable> for mir::interpret::Allocation { hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher, ) { - self.bytes.hash_stable(hcx, hasher); - for reloc in self.relocations.iter() { + let mir::interpret::Allocation { + bytes, relocations, undef_mask, align, mutability, + extra: _, + } = self; + bytes.hash_stable(hcx, hasher); + for reloc in relocations.iter() { reloc.hash_stable(hcx, hasher); } - self.undef_mask.hash_stable(hcx, hasher); - self.align.hash_stable(hcx, hasher); - self.mutability.hash_stable(hcx, hasher); + undef_mask.hash_stable(hcx, hasher); + align.hash_stable(hcx, hasher); + mutability.hash_stable(hcx, hasher); } } From 23a1ebb3fca8dc77340dd94400255722260991e9 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Jun 2019 15:58:51 +0200 Subject: [PATCH 3/8] Remove the `AllocId` from `ByRef` values `ByRef` const values have no identity beyond their value, we should not treat them as having identity. The `AllocId` often differed between equal constants, because of the way that the miri-engine evaluates constants. --- src/librustc/mir/interpret/value.rs | 5 ++--- src/librustc/ty/structural_impls.rs | 2 +- src/librustc_codegen_llvm/consts.rs | 2 +- src/librustc_codegen_ssa/mir/operand.rs | 4 ++-- src/librustc_codegen_ssa/mir/place.rs | 4 ++-- src/librustc_mir/const_eval.rs | 6 +++--- src/librustc_mir/hair/pattern/_match.rs | 9 +++++---- src/librustc_mir/interpret/operand.rs | 5 +++-- src/test/incremental/simd_intrinsic_ice.rs | 17 +++++++++++++++++ 9 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 src/test/incremental/simd_intrinsic_ice.rs diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 40e8111997361..0f08c40bff1b2 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -43,14 +43,13 @@ pub enum ConstValue<'tcx> { end: usize, }, - /// An allocation together with a pointer into the allocation. - /// Invariant: the pointer's `AllocId` resolves to the allocation. + /// An allocation together with an offset into the allocation. /// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive fields /// of `repr(packed)` structs. The alignment may be lower than the type of this constant. /// This permits reads with lower alignment than what the type would normally require. /// FIXME(RalfJ,oli-obk): The alignment checks are part of miri, but const eval doesn't really /// need them. Disabling them may be too hard though. - ByRef(Pointer, Align, &'tcx Allocation), + ByRef(Size, Align, &'tcx Allocation), /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 4cd0fd3e824f5..22c178b9cb04d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1335,7 +1335,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { match *self { - ConstValue::ByRef(ptr, align, alloc) => ConstValue::ByRef(ptr, align, alloc), + ConstValue::ByRef(offset, align, alloc) => ConstValue::ByRef(offset, align, alloc), ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)), ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)), ConstValue::Placeholder(p) => ConstValue::Placeholder(p), diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 4bf91bbed60ea..3f10773f85b41 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -71,7 +71,7 @@ pub fn codegen_static_initializer( let static_ = cx.tcx.const_eval(param_env.and(cid))?; let alloc = match static_.val { - ConstValue::ByRef(ptr, align, alloc) if ptr.offset.bytes() == 0 && align == alloc.align => { + ConstValue::ByRef(offset, align, alloc) if offset.bytes() == 0 && align == alloc.align => { alloc }, _ => bug!("static const eval returned {:#?}", static_), diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index c1626d31c7801..dc288c2f0f343 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -109,8 +109,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let b_llval = bx.const_usize((end - start) as u64); OperandValue::Pair(a_llval, b_llval) }, - ConstValue::ByRef(ptr, align, alloc) => { - return bx.load_operand(bx.from_const_alloc(layout, align, alloc, ptr.offset)); + ConstValue::ByRef(offset, align, alloc) => { + return bx.load_operand(bx.from_const_alloc(layout, align, alloc, offset)); }, }; diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 72aedb4812a21..4993f4559f777 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -424,8 +424,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = cx.layout_of(self.monomorphize(&ty)); match bx.tcx().const_eval(param_env.and(cid)) { Ok(val) => match val.val { - mir::interpret::ConstValue::ByRef(ptr, align, alloc) => { - bx.cx().from_const_alloc(layout, align, alloc, ptr.offset) + mir::interpret::ConstValue::ByRef(offset, align, alloc) => { + bx.cx().from_const_alloc(layout, align, alloc, offset) } _ => bug!("promoteds should have an allocation: {:?}", val), }, diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 284a8f40e1f35..126f1a12f399c 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -99,7 +99,7 @@ fn op_to_const<'tcx>( Ok(mplace) => { let ptr = mplace.ptr.to_ptr().unwrap(); let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef(ptr, mplace.align, alloc) + ConstValue::ByRef(ptr.offset, mplace.align, alloc) }, // see comment on `let try_as_immediate` above Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x { @@ -113,7 +113,7 @@ fn op_to_const<'tcx>( let mplace = op.to_mem_place(); let ptr = mplace.ptr.to_ptr().unwrap(); let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef(ptr, mplace.align, alloc) + ConstValue::ByRef(ptr.offset, mplace.align, alloc) }, }, Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => { @@ -542,7 +542,7 @@ fn validate_and_turn_into_const<'tcx>( let ptr = mplace.ptr.to_ptr()?; Ok(tcx.mk_const(ty::Const { val: ConstValue::ByRef( - ptr, + ptr.offset, mplace.align, ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), ), diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 974c863792eed..6e3f8da4807a1 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -218,7 +218,7 @@ impl LiteralExpander<'tcx> { (ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => { let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id); ConstValue::ByRef( - p, + p.offset, // FIXME(oli-obk): this should be the type's layout alloc.align, alloc, @@ -1436,9 +1436,10 @@ fn slice_pat_covered_by_const<'tcx>( suffix: &[Pattern<'tcx>], ) -> Result { let data: &[u8] = match (const_val.val, &const_val.ty.sty) { - (ConstValue::ByRef(ptr, _, alloc), ty::Array(t, n)) => { + (ConstValue::ByRef(offset, _, alloc), ty::Array(t, n)) => { assert_eq!(*t, tcx.types.u8); let n = n.assert_usize(tcx).unwrap(); + let ptr = Pointer::new(AllocId(0), offset); alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap() }, (ConstValue::Slice { data, start, end }, ty::Slice(t)) => { @@ -1758,9 +1759,9 @@ fn specialize<'p, 'a: 'p, 'tcx>( let (alloc, offset, n, ty) = match value.ty.sty { ty::Array(t, n) => { match value.val { - ConstValue::ByRef(ptr, _, alloc) => ( + ConstValue::ByRef(offset, _, alloc) => ( alloc, - ptr.offset, + offset, n.unwrap_usize(cx.tcx), t, ), diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 1b451e0b8f18f..96e9a416a72c7 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -538,10 +538,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.layout_of(self.monomorphize(val.ty)?) })?; let op = match val.val { - ConstValue::ByRef(ptr, align, _alloc) => { + ConstValue::ByRef(offset, align, alloc) => { + let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); // We rely on mutability being set correctly in that allocation to prevent writes // where none should happen. - let ptr = self.tag_static_base_pointer(ptr); + let ptr = self.tag_static_base_pointer(Pointer::new(id, offset)); Operand::Indirect(MemPlace::from_ptr(ptr, align)) }, ConstValue::Scalar(x) => diff --git a/src/test/incremental/simd_intrinsic_ice.rs b/src/test/incremental/simd_intrinsic_ice.rs new file mode 100644 index 0000000000000..06b2957ac62c9 --- /dev/null +++ b/src/test/incremental/simd_intrinsic_ice.rs @@ -0,0 +1,17 @@ +#![feature(repr_simd, platform_intrinsics)] + +// revisions:rpass1 rpass2 + +#[repr(simd)] +struct I32x2(i32, i32); + +extern "platform-intrinsic" { + fn simd_shuffle2(x: T, y: T, idx: [u32; 2]) -> U; +} + +fn main() { + unsafe { + let _: I32x2 = simd_shuffle2(I32x2(1, 2), I32x2(3, 4), [0, 0]); + let _: I32x2 = simd_shuffle2(I32x2(1, 2), I32x2(3, 4), [0, 0]); + } +} From 811b996e58e7bd5a6ce2495d26363e7c934887f1 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Jun 2019 19:43:13 +0200 Subject: [PATCH 4/8] Change `ByRef` to a struct variant to clarify its fields via names --- src/librustc/infer/freshen.rs | 2 +- src/librustc/mir/interpret/value.rs | 23 ++++++++++++++-------- src/librustc/ty/print/obsolete.rs | 2 +- src/librustc/ty/relate.rs | 2 +- src/librustc/ty/structural_impls.rs | 5 +++-- src/librustc_codegen_llvm/consts.rs | 2 +- src/librustc_codegen_ssa/mir/operand.rs | 2 +- src/librustc_codegen_ssa/mir/place.rs | 2 +- src/librustc_mir/const_eval.rs | 14 ++++++------- src/librustc_mir/hair/pattern/_match.rs | 14 ++++++------- src/librustc_mir/interpret/operand.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 2 +- src/librustc_typeck/check/mod.rs | 4 ++-- 13 files changed, 42 insertions(+), 34 deletions(-) diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 7f4a817faf182..400a538baa965 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -260,7 +260,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { ConstValue::Param(_) | ConstValue::Scalar(_) | ConstValue::Slice { .. } | - ConstValue::ByRef(..) | + ConstValue::ByRef { .. } | ConstValue::Unevaluated(..) => {} } diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 0f08c40bff1b2..d94e2c6c2e09e 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -43,13 +43,20 @@ pub enum ConstValue<'tcx> { end: usize, }, - /// An allocation together with an offset into the allocation. - /// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive fields - /// of `repr(packed)` structs. The alignment may be lower than the type of this constant. - /// This permits reads with lower alignment than what the type would normally require. - /// FIXME(RalfJ,oli-obk): The alignment checks are part of miri, but const eval doesn't really - /// need them. Disabling them may be too hard though. - ByRef(Size, Align, &'tcx Allocation), + /// An value not represented/representable by `Scalar` or `Slice` + ByRef { + /// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive fields + /// of `repr(packed)` structs. The alignment may be lower than the type of this constant. + /// This permits reads with lower alignment than what the type would normally require. + /// FIXME(RalfJ,oli-obk): The alignment checks are part of miri, but const eval doesn't really + /// need them. Disabling them may be too hard though. + align: Align, + /// Offset into `alloc` + offset: Size, + /// The backing memory of the value, may contain more memory than needed for just the value + /// in order to share `Allocation`s between values + alloc: &'tcx Allocation, + }, /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. @@ -66,7 +73,7 @@ impl<'tcx> ConstValue<'tcx> { ConstValue::Param(_) | ConstValue::Infer(_) | ConstValue::Placeholder(_) | - ConstValue::ByRef(..) | + ConstValue::ByRef{ .. } | ConstValue::Unevaluated(..) | ConstValue::Slice { .. } => None, ConstValue::Scalar(val) => Some(val), diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs index 16fb334803926..c12402a57cc3c 100644 --- a/src/librustc/ty/print/obsolete.rs +++ b/src/librustc/ty/print/obsolete.rs @@ -186,7 +186,7 @@ impl DefPathBasedNames<'tcx> { // as well as the unprintable types of constants (see `push_type_name` for more details). pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) { match c.val { - ConstValue::Scalar(..) | ConstValue::Slice { .. } | ConstValue::ByRef(..) => { + ConstValue::Scalar(..) | ConstValue::Slice { .. } | ConstValue::ByRef { .. } => { // FIXME(const_generics): we could probably do a better job here. write!(output, "{:?}", c).unwrap() } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 98fd5d1a9818d..46adb7eb2a476 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -594,7 +594,7 @@ pub fn super_relate_consts>( ty: a.ty, })) } - (ConstValue::ByRef(..), _) => { + (ConstValue::ByRef { .. }, _) => { bug!( "non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}", a, diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 22c178b9cb04d..ced2c8c465da4 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1335,7 +1335,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { match *self { - ConstValue::ByRef(offset, align, alloc) => ConstValue::ByRef(offset, align, alloc), + ConstValue::ByRef { offset, align, alloc } => + ConstValue::ByRef { offset, align, alloc }, ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)), ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)), ConstValue::Placeholder(p) => ConstValue::Placeholder(p), @@ -1348,7 +1349,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { match *self { - ConstValue::ByRef(..) => false, + ConstValue::ByRef { .. } => false, ConstValue::Infer(ic) => ic.visit_with(visitor), ConstValue::Param(p) => p.visit_with(visitor), ConstValue::Placeholder(_) => false, diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 3f10773f85b41..7f11df397961d 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -71,7 +71,7 @@ pub fn codegen_static_initializer( let static_ = cx.tcx.const_eval(param_env.and(cid))?; let alloc = match static_.val { - ConstValue::ByRef(offset, align, alloc) if offset.bytes() == 0 && align == alloc.align => { + ConstValue::ByRef { offset, align, alloc } if offset.bytes() == 0 && align == alloc.align => { alloc }, _ => bug!("static const eval returned {:#?}", static_), diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index dc288c2f0f343..4a6752fec3556 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -109,7 +109,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let b_llval = bx.const_usize((end - start) as u64); OperandValue::Pair(a_llval, b_llval) }, - ConstValue::ByRef(offset, align, alloc) => { + ConstValue::ByRef { offset, align, alloc } => { return bx.load_operand(bx.from_const_alloc(layout, align, alloc, offset)); }, }; diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 4993f4559f777..d56f39c6de204 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -424,7 +424,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = cx.layout_of(self.monomorphize(&ty)); match bx.tcx().const_eval(param_env.and(cid)) { Ok(val) => match val.val { - mir::interpret::ConstValue::ByRef(offset, align, alloc) => { + mir::interpret::ConstValue::ByRef { offset, align, alloc } => { bx.cx().from_const_alloc(layout, align, alloc, offset) } _ => bug!("promoteds should have an allocation: {:?}", val), diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 126f1a12f399c..64bc1929c9644 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -99,7 +99,7 @@ fn op_to_const<'tcx>( Ok(mplace) => { let ptr = mplace.ptr.to_ptr().unwrap(); let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef(ptr.offset, mplace.align, alloc) + ConstValue::ByRef { offset: ptr.offset, align: mplace.align, alloc } }, // see comment on `let try_as_immediate` above Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x { @@ -113,7 +113,7 @@ fn op_to_const<'tcx>( let mplace = op.to_mem_place(); let ptr = mplace.ptr.to_ptr().unwrap(); let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef(ptr.offset, mplace.align, alloc) + ConstValue::ByRef { offset: ptr.offset, align: mplace.align, alloc } }, }, Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => { @@ -541,11 +541,11 @@ fn validate_and_turn_into_const<'tcx>( if tcx.is_static(def_id) || cid.promoted.is_some() { let ptr = mplace.ptr.to_ptr()?; Ok(tcx.mk_const(ty::Const { - val: ConstValue::ByRef( - ptr.offset, - mplace.align, - ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), - ), + val: ConstValue::ByRef { + offset: ptr.offset, + align: mplace.align, + alloc: ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), + }, ty: mplace.layout.ty, })) } else { diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 6e3f8da4807a1..fc2951895f3fe 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -217,12 +217,12 @@ impl LiteralExpander<'tcx> { // the easy case, deref a reference (ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => { let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id); - ConstValue::ByRef( - p.offset, + ConstValue::ByRef { + offset: p.offset, // FIXME(oli-obk): this should be the type's layout - alloc.align, + align: alloc.align, alloc, - ) + } }, // unsize array to slice if pattern is array but match value or other patterns are slice (ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => { @@ -1436,7 +1436,7 @@ fn slice_pat_covered_by_const<'tcx>( suffix: &[Pattern<'tcx>], ) -> Result { let data: &[u8] = match (const_val.val, &const_val.ty.sty) { - (ConstValue::ByRef(offset, _, alloc), ty::Array(t, n)) => { + (ConstValue::ByRef { offset, alloc, .. }, ty::Array(t, n)) => { assert_eq!(*t, tcx.types.u8); let n = n.assert_usize(tcx).unwrap(); let ptr = Pointer::new(AllocId(0), offset); @@ -1759,7 +1759,7 @@ fn specialize<'p, 'a: 'p, 'tcx>( let (alloc, offset, n, ty) = match value.ty.sty { ty::Array(t, n) => { match value.val { - ConstValue::ByRef(offset, _, alloc) => ( + ConstValue::ByRef { offset, alloc, .. } => ( alloc, offset, n.unwrap_usize(cx.tcx), @@ -1779,7 +1779,7 @@ fn specialize<'p, 'a: 'p, 'tcx>( (end - start) as u64, t, ), - ConstValue::ByRef(..) => { + ConstValue::ByRef { .. } => { // FIXME(oli-obk): implement `deref` for `ConstValue` return None; }, diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 96e9a416a72c7..ec391b7bc5f02 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -538,7 +538,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.layout_of(self.monomorphize(val.ty)?) })?; let op = match val.val { - ConstValue::ByRef(offset, align, alloc) => { + ConstValue::ByRef { offset, align, alloc } => { let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); // We rely on mutability being set correctly in that allocation to prevent writes // where none should happen. diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index c64bb73802dc8..bb2738d5aa4a3 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1262,7 +1262,7 @@ fn collect_const<'tcx>( ConstValue::Scalar(Scalar::Ptr(ptr)) => collect_miri(tcx, ptr.alloc_id, output), ConstValue::Slice { data: alloc, start: _, end: _ } | - ConstValue::ByRef(_, _, alloc) => { + ConstValue::ByRef { alloc, .. } => { for &((), id) in alloc.relocations.values() { collect_miri(tcx, id, output); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fe742a74fffec..21acd67c03316 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1448,8 +1448,8 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) }; let param_env = ty::ParamEnv::reveal_all(); if let Ok(static_) = tcx.const_eval(param_env.and(cid)) { - let alloc = if let ConstValue::ByRef(_, _, allocation) = static_.val { - allocation + let alloc = if let ConstValue::ByRef { alloc, .. } = static_.val { + alloc } else { bug!("Matching on non-ByRef static") }; From cdf55965027b87a12800dca2dedd672fac618f5b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Jun 2019 19:48:03 +0200 Subject: [PATCH 5/8] Rename regression test to link it to the corresponding issue --- src/test/incremental/{simd_intrinsic_ice.rs => issue-61530.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/incremental/{simd_intrinsic_ice.rs => issue-61530.rs} (100%) diff --git a/src/test/incremental/simd_intrinsic_ice.rs b/src/test/incremental/issue-61530.rs similarity index 100% rename from src/test/incremental/simd_intrinsic_ice.rs rename to src/test/incremental/issue-61530.rs From 3dfe017dc3fccca64d67973be10e4bbd3e90c966 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Jun 2019 20:17:09 +0200 Subject: [PATCH 6/8] Pacify tidy --- src/librustc/mir/interpret/value.rs | 11 ++++++----- src/librustc_codegen_llvm/consts.rs | 4 +++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index d94e2c6c2e09e..efcba88fe2dd4 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -45,11 +45,12 @@ pub enum ConstValue<'tcx> { /// An value not represented/representable by `Scalar` or `Slice` ByRef { - /// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive fields - /// of `repr(packed)` structs. The alignment may be lower than the type of this constant. - /// This permits reads with lower alignment than what the type would normally require. - /// FIXME(RalfJ,oli-obk): The alignment checks are part of miri, but const eval doesn't really - /// need them. Disabling them may be too hard though. + /// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive + /// fields of `repr(packed)` structs. The alignment may be lower than the type of this + /// constant. This permits reads with lower alignment than what the type would normally + /// require. + /// FIXME(RalfJ,oli-obk): The alignment checks are part of miri, but const eval doesn't + /// really need them. Disabling them may be too hard though. align: Align, /// Offset into `alloc` offset: Size, diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 7f11df397961d..24167a2f88713 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -71,7 +71,9 @@ pub fn codegen_static_initializer( let static_ = cx.tcx.const_eval(param_env.and(cid))?; let alloc = match static_.val { - ConstValue::ByRef { offset, align, alloc } if offset.bytes() == 0 && align == alloc.align => { + ConstValue::ByRef { + offset, align, alloc, + } if offset.bytes() == 0 && align == alloc.align => { alloc }, _ => bug!("static const eval returned {:#?}", static_), From 0102942e8c4a7a7cfbefa6495f295a6b6a18ecbf Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 21 Jun 2019 09:54:11 +0200 Subject: [PATCH 7/8] Documentation typo --- src/librustc/mir/interpret/value.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index efcba88fe2dd4..388c549324268 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -43,7 +43,7 @@ pub enum ConstValue<'tcx> { end: usize, }, - /// An value not represented/representable by `Scalar` or `Slice` + /// A value not represented/representable by `Scalar` or `Slice` ByRef { /// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive /// fields of `repr(packed)` structs. The alignment may be lower than the type of this From d46a373b391cb546f5a737fd5009f7733c220531 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 21 Jun 2019 09:56:02 +0200 Subject: [PATCH 8/8] Further reduce the likelyhood of hash collisions --- src/librustc/ich/impls_ty.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index b2ad7e923b068..0ddc9211f9811 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -180,6 +180,7 @@ impl<'a> HashStable> for mir::interpret::Allocation { extra: _, } = self; bytes.hash_stable(hcx, hasher); + relocations.len().hash_stable(hcx, hasher); for reloc in relocations.iter() { reloc.hash_stable(hcx, hasher); }