Skip to content

Supertrait elaboration causes unnecessary param-env shadowing #100

Open
@compiler-errors

Description

@compiler-errors

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions