blob: 7de4aef422a083a23dcfc48499e7da8c365afbe9 [file] [log] [blame]
// Test that transmuting from `&dyn Trait<fn(&'static ())>` to `&dyn Trait<for<'a> fn(&'a ())>` is UB.
//
// The vtable of `() as Trait<fn(&'static ())>` and `() as Trait<for<'a> fn(&'a ())>` can have
// different entries and, because in the former the entry for `foo` is vacant, this test will
// segfault at runtime.
trait Trait<U> {
fn foo(&self)
where
U: HigherRanked,
{
}
}
impl<T, U> Trait<U> for T {}
trait HigherRanked {}
impl HigherRanked for for<'a> fn(&'a ()) {}
// 2nd candidate is required so that selecting `(): Trait<fn(&'static ())>` will
// evaluate the candidates and fail the leak check instead of returning the
// only applicable candidate.
trait Unsatisfied {}
impl<T: Unsatisfied> HigherRanked for T {}
fn main() {
let x: &dyn Trait<fn(&'static ())> = &();
let y: &dyn Trait<for<'a> fn(&'a ())> = unsafe { std::mem::transmute(x) };
//~^ ERROR: wrong trait in wide pointer vtable
y.foo();
}