about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-06-21 10:16:14 +0000
committerbors <bors@rust-lang.org>2019-06-21 10:16:14 +0000
commit38cd9489f75f4a4387296ee304e2287f7c32c211 (patch)
treea5426f237dab435b99a07bd123e42ff45a49c457 /src
parent56a12b2ad058f22f1ef090713df15598525ba4a4 (diff)
parentd46a373b391cb546f5a737fd5009f7733c220531 (diff)
downloadrust-38cd9489f75f4a4387296ee304e2287f7c32c211.tar.gz
rust-38cd9489f75f4a4387296ee304e2287f7c32c211.zip
Auto merge of #61959 - oli-obk:const_field_ice, r=eddyb
Fix a hash collision issue on the `const_field` query

fixes #61530
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ich/impls_ty.rs15
-rw-r--r--src/librustc/infer/freshen.rs2
-rw-r--r--src/librustc/mir/interpret/allocation.rs12
-rw-r--r--src/librustc/mir/interpret/value.rs25
-rw-r--r--src/librustc/ty/print/obsolete.rs2
-rw-r--r--src/librustc/ty/relate.rs2
-rw-r--r--src/librustc/ty/structural_impls.rs5
-rw-r--r--src/librustc_codegen_llvm/consts.rs4
-rw-r--r--src/librustc_codegen_ssa/mir/operand.rs4
-rw-r--r--src/librustc_codegen_ssa/mir/place.rs4
-rw-r--r--src/librustc_mir/const_eval.rs14
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs17
-rw-r--r--src/librustc_mir/interpret/operand.rs5
-rw-r--r--src/librustc_mir/monomorphize/collector.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/test/incremental/issue-61530.rs17
16 files changed, 85 insertions, 49 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 9b144b1ba3d..0ddc9211f98 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -175,13 +175,18 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
         hcx: &mut StableHashingContext<'a>,
         hasher: &mut StableHasher<W>,
     ) {
-        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);
+        relocations.len().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);
     }
 }
 
diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs
index 7f4a817faf1..400a538baa9 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/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index d7caf950dce..8381125798a 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<Tag>> Allocation<Tag, Extra> {
         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<Tag>> Allocation<Tag, Extra> {
     {
         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<Tag, Extra> {
         ptr: Pointer<Tag>,
         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(())
     }
 }
 
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 40e81119973..388c5493242 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -43,14 +43,21 @@ pub enum ConstValue<'tcx> {
         end: usize,
     },
 
-    /// An allocation together with a pointer into the allocation.
-    /// Invariant: the pointer's `AllocId` resolves to 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),
+    /// 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
+        /// 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.
@@ -67,7 +74,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 16fb3348039..c12402a57cc 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 98fd5d1a981..46adb7eb2a4 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -594,7 +594,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
                 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 4cd0fd3e824..ced2c8c465d 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<F: TypeFolder<'tcx>>(&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),
@@ -1348,7 +1349,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
 
     fn super_visit_with<V: TypeVisitor<'tcx>>(&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 4bf91bbed60..24167a2f887 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(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 c1626d31c78..4a6752fec35 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 72aedb4812a..d56f39c6de2 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 3ad7b00a665..67bcd4943e7 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 { 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, 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,
-                    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 974c863792e..fc2951895f3 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,
+                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,9 +1436,10 @@ fn slice_pat_covered_by_const<'tcx>(
     suffix: &[Pattern<'tcx>],
 ) -> Result<bool, ErrorReported> {
     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,
                                 ),
@@ -1778,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 1b451e0b8f1..ec391b7bc5f 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/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index c64bb73802d..bb2738d5aa4 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 0e83db48284..bde4f804574 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")
         };
diff --git a/src/test/incremental/issue-61530.rs b/src/test/incremental/issue-61530.rs
new file mode 100644
index 00000000000..06b2957ac62
--- /dev/null
+++ b/src/test/incremental/issue-61530.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<T, U>(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]);
+    }
+}