Skip to content

Associated types in object-safe method signatures don't always come from supertraits #126079

Closed
@compiler-errors

Description

@compiler-errors

One of the requirements for a trait to be object-safe is that the associated types that show up in signatures of methods come from the supertraits of the object. We don't currently implement this correctly -- we currently ignore the substitutions of the associated type 😿.

This is unsound:

use core::marker::PhantomData;

fn transmute<T, U>(t: T) -> U {
    (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
}

struct ActuallySuper;
struct NotActuallySuper;
trait Super<Q> {
    type Assoc;
}

trait Dyn {
    type Out;
}
impl<T, U> Dyn for dyn Foo<T, U> + '_ {
    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}");
}

Specifically, fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc; should only be sound if the return type was <Self as Super<ActuallySuper>>::Assoc, or if we added Super<NotActuallySuper> as a supertrait.

We should probably deeply normalize these supertraits and actually consider the associated types' substs match modulo regions.

Metadata

Metadata

Labels

A-dyn-traitArea: trait objects, vtable layoutC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type

Projects

Status

Completed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions