-
Notifications
You must be signed in to change notification settings - Fork 348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"constructing invalid value: wrong trait in wide pointer vtable" for seemingly identical traits #3541
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`
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: