-
Notifications
You must be signed in to change notification settings - Fork 385
"constructing invalid value: wrong trait in wide pointer vtable" for seemingly identical traits #3541
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
let ocx = ObligationCtxt::new(infcx);
let param_env = ty::ParamEnv::reveal_all(); // in an empty environment post borrowck
ocx.eq(param_env, lhs, rhs)?; // equate the two trait refs
ocx.select_all_or_error().is_empty() // and check any potential nested constraints |
Thanks! We actually have a |
you can create a local one, given that the input should not refer to either placeholders or inference variables |
@lcnr any idea how to get a reproducible example for this? I tried this code but it doesn't trigger the error -- probably things get normalized earlier already so by the time we check the trait type, everything is already equal. #![feature(unboxed_closures)]
#![feature(ptr_metadata)]
type T1<'a> = &'a dyn for<'b> Fn(usize);
type T2<'a> = &'a dyn for<'b> Fn<(<[std::boxed::Box<i32>] as std::ptr::Pointee>::Metadata,), Output=()>;
fn main() {
let x: T1 = &|_| {};
let y: T2 = unsafe { std::mem::transmute(x) };
y(42);
} |
I get a build error instead:
|
unfortunately not, my idea was something like the following, as types from the HIR get normalized, but that didn't seem to do the trick 🤔 #![feature(ptr_metadata)]
type T1<'a> = &'a dyn for<'b> Fn(usize);
type T2<'a> = &'a dyn for<'b> Fn(<[std::boxed::Box<i32>] as std::ptr::Pointee>::Metadata);
#[repr(transparent)]
struct Foo<'a> {
x: &'a T2<'a>,
}
fn main() {
let foo = Foo { x: &((&|_| ()) as &dyn Fn(usize)) };
let x: T1<'_> = foo.x;
x(42);
} |
I got something by minimizing #![feature(ptr_metadata)]
// This test is the result of minimizing the `emplacable` crate to reproduce
// <https://github.com/rust-lang/miri/issues/3541>.
use std::{ops::FnMut, ptr::Pointee};
pub type EmplacerFn<'a, T> = dyn for<'b> FnMut(<T as Pointee>::Metadata) + 'a;
#[repr(transparent)]
pub struct Emplacer<'a, T>(EmplacerFn<'a, T>)
where
T: ?Sized;
impl<'a, T> Emplacer<'a, T>
where
T: ?Sized,
{
pub unsafe fn from_fn<'b>(emplacer_fn: &'b mut EmplacerFn<'a, T>) -> &'b mut Self {
unsafe { &mut *((emplacer_fn as *mut EmplacerFn<'a, T>) as *mut Self) }
}
}
pub fn box_new_with<T>()
where
T: ?Sized,
{
let emplacer_closure = &mut |_meta| {
unreachable!();
};
unsafe { Emplacer::<T>::from_fn(emplacer_closure) };
}
fn main() {
box_new_with::<[Box<i32>]>();
} @Jules-Bertholet thanks for making this a small self-contained crate, minimization would probably not have been feasible otherwise. :) |
Such is the way of nightly-only crates… It's fixed now |
Rollup merge of rust-lang#126232 - RalfJung:dyn-trait-equality, r=oli-obk interpret: dyn trait metadata check: equate traits in a proper way Hopefully fixes rust-lang/miri#3541... unfortunately we don't have a testcase. The first commit is just a refactor without functional change. r? `@oli-obk`
interpret: dyn trait metadata check: equate traits in a proper way Hopefully fixes #3541... unfortunately we don't have a testcase. The first commit is just a refactor without functional change. r? `@oli-obk`
Uh oh!
There was an error while loading. Please reload this page.
I don't have a minimal reduction atm, but the issue can be reproduced by cloning https://github.com/Jules-Bertholet/unsized-vec and running
cargo miri test -p emplacable
. This results in the following report of UB:But the two traits are the same!
<[std::boxed::Box<i32>] as std::ptr::Pointee>::Metadata
isusize
, andfor<'a> ...
vsfor<'b> ...
should not make a difference either.@rustbot label I-false-UB A-validation
The text was updated successfully, but these errors were encountered: