use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::mir::RetagKind;
use rustc_middle::ty;
-use rustc_target::abi::{LayoutOf, Size};
+use rustc_target::abi::{Align, LayoutOf, Size};
use rustc_hir::Mutability;
use crate::*;
.size_and_align_of_mplace(place)?
.map(|(size, _)| size)
.unwrap_or_else(|| place.layout.size);
+ // `reborrow` relies on getting a `Pointer` and everything being in-bounds,
+ // so let's ensure that. However, we do not care about alignment.
// We can see dangling ptrs in here e.g. after a Box's `Unique` was
- // updated using "self.0 = ..." (can happen in Box::from_raw); see miri#1050.
- let place = this.mplace_access_checked(place)?;
+ // updated using "self.0 = ..." (can happen in Box::from_raw) so we cannot ICE; see miri#1050.
+ let place = this.mplace_access_checked(place, Some(Align::from_bytes(1).unwrap()))?;
+ // Nothing to do for ZSTs.
if size == Size::ZERO {
- // Nothing to do for ZSTs.
return Ok(val);
}
-#![feature(unsize, coerce_unsized)]
+#![feature(unsize, coerce_unsized, raw_ref_op)]
use std::collections::hash_map::DefaultHasher;
use std::hash::Hash;
fn test_basic() {
#[repr(packed)]
struct S {
+ fill: u8,
a: i32,
b: i64,
}
}
let mut x = S {
+ fill: 0,
a: 42,
b: 99,
};
let b = x.b;
assert_eq!(a, 42);
assert_eq!(b, 99);
+ assert_eq!(&x.fill, &0); // `fill` just requirs 1-byte-align, so this is fine
// can't do `assert_eq!(x.a, 42)`, because `assert_eq!` takes a reference
assert_eq!({x.a}, 42);
assert_eq!({x.b}, 99);
+ // but we *can* take a raw pointer!
+ assert_eq!(unsafe { (&raw const x.a).read_unaligned() }, 42);
+ assert_eq!(unsafe { (&raw const x.b).read_unaligned() }, 99);
x.b = 77;
assert_eq!({x.b}, 77);