Skip to content

Commit dda28dc

Browse files
committed
interpret: dyn trait metadata check: equate traits in a proper way
1 parent aa8514d commit dda28dc

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#![feature(ptr_metadata)]
2+
// This test is the result of minimizing the `emplacable` crate to reproduce
3+
// <https://github.com/rust-lang/miri/issues/3541>.
4+
5+
use std::{ops::FnMut, ptr::Pointee};
6+
7+
pub type EmplacerFn<'a, T> = dyn for<'b> FnMut(<T as Pointee>::Metadata) + 'a;
8+
9+
#[repr(transparent)]
10+
pub struct Emplacer<'a, T>(EmplacerFn<'a, T>)
11+
where
12+
T: ?Sized;
13+
14+
impl<'a, T> Emplacer<'a, T>
15+
where
16+
T: ?Sized,
17+
{
18+
pub unsafe fn from_fn<'b>(emplacer_fn: &'b mut EmplacerFn<'a, T>) -> &'b mut Self {
19+
// This used to trigger:
20+
// constructing invalid value: wrong trait in wide pointer vtable: expected
21+
// `std::ops::FnMut(<[std::boxed::Box<i32>] as std::ptr::Pointee>::Metadata)`, but encountered
22+
// `std::ops::FnMut<(usize,)>`.
23+
unsafe { &mut *((emplacer_fn as *mut EmplacerFn<'a, T>) as *mut Self) }
24+
}
25+
}
26+
27+
pub fn box_new_with<T>()
28+
where
29+
T: ?Sized,
30+
{
31+
let emplacer_closure = &mut |_meta| {
32+
unreachable!();
33+
};
34+
35+
unsafe { Emplacer::<T>::from_fn(emplacer_closure) };
36+
}
37+
38+
fn main() {
39+
box_new_with::<[Box<i32>]>();
40+
}

0 commit comments

Comments
 (0)