Skip to content

Commit 94b9b43

Browse files
Rollup merge of rust-lang#157766 - RalfJung:too-big, r=oli-obk
interpret: avoid computing layout of sized raw pointee This lets the [example](rust-lang#157654 (comment)) by @theemathas work in Miri.
2 parents 828fce6 + c9ecb9f commit 94b9b43

5 files changed

Lines changed: 23 additions & 12 deletions

File tree

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -925,16 +925,20 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
925925
}
926926
interp_ok(true)
927927
}
928-
ty::RawPtr(..) => {
928+
ty::RawPtr(pointee, ..) => {
929929
let ptr = self.read_immediate(value, ExpectedKind::RawPtr)?;
930930
if self.reset_provenance_and_padding {
931931
self.reset_pointer_provenance(value, &ptr)?;
932932
// There's no padding in a pointer.
933933
self.add_data_range_place(value);
934934
}
935935

936-
let place = self.ecx.imm_ptr_to_mplace(&ptr)?;
937-
if place.layout.is_unsized() {
936+
if !pointee.is_sized(*self.ecx.tcx, self.ecx.typing_env) {
937+
// Raw pointers to unsized types need to have their metadata checked.
938+
// We avoid creating this place for sized types to match codegen: those types
939+
// might actually be invalid (i.e., too big)!
940+
let place = self.ecx.imm_ptr_to_mplace(&ptr)?;
941+
assert!(place.layout.is_unsized());
938942
self.check_wide_ptr_meta(place.meta(), place.layout)?;
939943
}
940944
interp_ok(true)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/157654#issuecomment-4679655886>:
2+
//! the type behind a raw pointer should never have its layout computed.
3+
4+
//@compile-flags: -Zmiri-permissive-provenance
5+
6+
const PTR_BITS_MINUS_1: usize = std::mem::size_of::<*const ()>() * 8 - 1;
7+
8+
fn main() {
9+
std::hint::black_box(0 as *const [u64; 1 << PTR_BITS_MINUS_1]);
10+
}

tests/ui/layout/issue-unsized-tail-restatic-ice-122488.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::ops::Deref;
55
struct ArenaSet<U: Deref, V: ?Sized = <U as Deref>::Target>(V, U);
66
//~^ ERROR the size for values of type `V` cannot be known at compilation time
77

8-
const DATA: *const ArenaSet<Vec<u8>> = std::ptr::null_mut();
8+
const DATA: &ArenaSet<Vec<u8>> = unsafe { &* std::ptr::null_mut() };
99
//~^ ERROR the type `ArenaSet<Vec<u8>, [u8]>` has an unknown layout
1010

1111
pub fn main() {}

tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ LL | struct ArenaSet<U: Deref, V: ?Sized = <U as Deref>::Target>(Box<V>, U);
2323
| ++++ +
2424

2525
error[E0080]: the type `ArenaSet<Vec<u8>, [u8]>` has an unknown layout
26-
--> $DIR/issue-unsized-tail-restatic-ice-122488.rs:8:1
26+
--> $DIR/issue-unsized-tail-restatic-ice-122488.rs:8:43
2727
|
28-
LL | const DATA: *const ArenaSet<Vec<u8>> = std::ptr::null_mut();
29-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `DATA` failed here
28+
LL | const DATA: &ArenaSet<Vec<u8>> = unsafe { &* std::ptr::null_mut() };
29+
| ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `DATA` failed here
3030

3131
error: aborting due to 2 previous errors
3232

tests/ui/sized/stack-overflow-trait-infer-98842.stderr

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@ LL | struct Foo(<&'static Foo as ::core::ops::Deref>::Target);
77
note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`...
88
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL
99
= note: ...which again requires computing layout of `Foo`, completing the cycle
10-
note: cycle used when const-evaluating + checking `_`
11-
--> $DIR/stack-overflow-trait-infer-98842.rs:13:1
12-
|
13-
LL | const _: *const Foo = 0 as _;
14-
| ^^^^^^^^^^^^^^^^^^^
10+
note: cycle used when computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`
11+
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL
1512
= note: for more information, see <https://rustc-dev-guide.rust-lang.org/overview.html#queries> and <https://rustc-dev-guide.rust-lang.org/query.html>
1613

1714
error: aborting due to 1 previous error

0 commit comments

Comments
 (0)