rust-lang / trait-system-refactor-initiative

The Rustc Trait System Refactor Initiative
21 stars 0 forks source link

Supertrait elaboration causes unnecessary param-env shadowing #100

Open compiler-errors opened 6 months ago

compiler-errors commented 6 months ago

I found this in diesel, but I expect to see it happen elsewhere.

trait HasMetadata {
    type Metadata;
}

struct Sql;
impl HasMetadata for Sql {
    type Metadata = ();
}

trait Process<T>: HasMetadata {
    fn process(t: T, metadata: Self::Metadata);
}

impl<T> Process<T> for Sql /* imagine `T` has some constraints that doesn't just make this an always-applicable blanket impl */ {
    fn process(t: T, metadata: Self::Metadata) {}
}

fn process<T>() where Sql: Process<T> {
    Sql::process((), ());
    //~^ ERROR because `<Sql as HasMetadata>::Metadata != ()`
}

Basically, a crate will have a meaningful param-env like Rigid: Trait<T> which elaborates into a trivial param-env candidate like Rigid: OtherTrait. That causes <Rigid as OtherTrait>::Assoc to no longer project.

This is hard to work around, because users can't just control the elaboration of their where clauses, and the where clause they wrote (i.e. Rigid: Trait<T>) does mention params and therefore is needed in the environment.