Skip to content

Coherence bypass using associated type to impl Trait for dyn Trait #152783

@theemathas

Description

@theemathas

This unsoundness is similar to #57893, but doesn't require a blanket impl.

the following code transmutes a Vec<u8> to a String.

type Src = Vec<u8>;
type Dst = String;

trait Trait<T> {
    type Assoc;
}

// Effectively: type Alias = dyn Trait<i32, Assoc = Src>
struct Dummy;
trait DummyTrait {
    type DummyAssoc: ?Sized;
}
impl DummyTrait for Dummy {
    type DummyAssoc = dyn Trait<i32, Assoc = Src>;
}
type Alias = <Dummy as DummyTrait>::DummyAssoc;

impl<T> Trait<T> for Alias {
    type Assoc = Dst;
}

fn foo<T>(x: <Alias as Trait<T>>::Assoc) -> Dst {
    x
}

fn bar(x: Src) -> Dst {
    foo::<i32>(x)
}

fn main() {
    let x: Vec<u8> = vec![102, 117, 110, 115, 111, 117, 110, 100];
    let y: String = bar(x);
    println!("{y}");
}

cc @lcnr

Meta

Reproducible on the playground with version 1.95.0-nightly (2026-02-17 8387095803f21a256a9a)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-coherenceArea: CoherenceA-dyn-traitArea: trait objects, vtable layoutA-trait-systemArea: Trait systemC-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-typesRelevant to the types team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions