Rollup merge of #109568 - RalfJung:miri-raw-ptr-dyn, r=oli-obk

miri: fix raw pointer dyn receivers

r? `@oli-obk`
Fixes https://github.com/rust-lang/miri/issues/2786
This commit is contained in:
Matthias Krüger 2023-03-25 03:37:12 +01:00 committed by GitHub
commit 31df7f1ecd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 1 deletions

View file

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

View file

@ -123,8 +123,35 @@ fn pointers_and_wrappers() {
assert_eq!(wpw.wrapper_ptr_wrapper(), 7);
}
fn raw_ptr_receiver() {
use std::ptr;
trait Foo {
fn foo(self: *const Self) -> &'static str;
}
impl Foo for i32 {
fn foo(self: *const Self) -> &'static str {
"I'm an i32!"
}
}
impl Foo for u32 {
fn foo(self: *const Self) -> &'static str {
"I'm a u32!"
}
}
let null_i32 = ptr::null::<i32>() as *const dyn Foo;
let null_u32 = ptr::null::<u32>() as *const dyn Foo;
assert_eq!("I'm an i32!", null_i32.foo());
assert_eq!("I'm a u32!", null_u32.foo());
}
fn main() {
pin_box_dyn();
stdlib_pointers();
pointers_and_wrappers();
raw_ptr_receiver();
}