blob: d73b67dc0809abac56b92dd21628cd029235ddbf [file] [log] [blame]
// Test for fixed unsoundness in #126079.
// Enforces that the associated types that are dyn-compatible.
use std::marker::PhantomData;
fn transmute<T, U>(t: T) -> U {
(&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
//~^ ERROR the trait `Foo` is not dyn compatible
}
struct ActuallySuper;
struct NotActuallySuper;
trait Super<Q> {
type Assoc;
}
trait Dyn {
type Out;
}
impl<T, U> Dyn for dyn Foo<T, U> + '_ {
//~^ ERROR the trait `Foo` is not dyn compatible
type Out = U;
}
impl<S: Dyn<Out = U> + ?Sized, U> Super<NotActuallySuper> for S {
type Assoc = U;
}
trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
where
<Self as Mirror>::Assoc: Super<NotActuallySuper>
{
fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc;
}
trait Mirror {
type Assoc: ?Sized;
}
impl<T: ?Sized> Mirror for T {
type Assoc = T;
}
impl<T, U> Foo<T, U> for PhantomData<T> {
fn transmute(&self, t: T) -> T {
t
}
}
impl<T> Super<ActuallySuper> for PhantomData<T> {
type Assoc = T;
}
impl<T> Super<NotActuallySuper> for PhantomData<T> {
type Assoc = T;
}
fn main() {
let x = String::from("hello, world");
let s = transmute::<&str, &'static str>(x.as_str());
drop(x);
println!("> {s}");
}