Skip to content

Commit 31df7f1

Browse files
authored
Rollup merge of #109568 - RalfJung:miri-raw-ptr-dyn, r=oli-obk
miri: fix raw pointer dyn receivers r? `@oli-obk` Fixes rust-lang/miri#2786
2 parents 3b49ad3 + c2fddfd commit 31df7f1

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

Diff for: compiler/rustc_const_eval/src/interpret/terminator.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
539539
let mut receiver = args[0].clone();
540540
let receiver_place = loop {
541541
match receiver.layout.ty.kind() {
542-
ty::Ref(..) | ty::RawPtr(..) => break self.deref_operand(&receiver)?,
542+
ty::Ref(..) | ty::RawPtr(..) => {
543+
// We do *not* use `deref_operand` here: we don't want to conceptually
544+
// create a place that must be dereferenceable, since the receiver might
545+
// be a raw pointer and (for `*const dyn Trait`) we don't need to
546+
// actually access memory to resolve this method.
547+
// Also see <https://github.com/rust-lang/miri/issues/2786>.
548+
let val = self.read_immediate(&receiver)?;
549+
break self.ref_to_mplace(&val)?;
550+
}
543551
ty::Dynamic(.., ty::Dyn) => break receiver.assert_mem_place(), // no immediate unsized values
544552
ty::Dynamic(.., ty::DynStar) => {
545553
// Not clear how to handle this, so far we assume the receiver is always a pointer.

Diff for: src/tools/miri/tests/pass/dyn-arbitrary-self.rs

+27
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,35 @@ fn pointers_and_wrappers() {
123123
assert_eq!(wpw.wrapper_ptr_wrapper(), 7);
124124
}
125125

126+
fn raw_ptr_receiver() {
127+
use std::ptr;
128+
129+
trait Foo {
130+
fn foo(self: *const Self) -> &'static str;
131+
}
132+
133+
impl Foo for i32 {
134+
fn foo(self: *const Self) -> &'static str {
135+
"I'm an i32!"
136+
}
137+
}
138+
139+
impl Foo for u32 {
140+
fn foo(self: *const Self) -> &'static str {
141+
"I'm a u32!"
142+
}
143+
}
144+
145+
let null_i32 = ptr::null::<i32>() as *const dyn Foo;
146+
let null_u32 = ptr::null::<u32>() as *const dyn Foo;
147+
148+
assert_eq!("I'm an i32!", null_i32.foo());
149+
assert_eq!("I'm a u32!", null_u32.foo());
150+
}
151+
126152
fn main() {
127153
pin_box_dyn();
128154
stdlib_pointers();
129155
pointers_and_wrappers();
156+
raw_ptr_receiver();
130157
}

0 commit comments

Comments
 (0)