Skip to content

Supertrait elaboration causes unnecessary param-env shadowing #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
compiler-errors opened this issue Mar 13, 2024 · 1 comment
Open

Comments

@compiler-errors
Copy link
Member

compiler-errors commented Mar 13, 2024

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.

@lcnr
Copy link
Contributor

lcnr commented Jan 29, 2025

This now errors with the following error with both solver

error[E0308]: mismatched types
  --> <source>:19:18
   |
18 | fn process<T>() where Sql: Process<T> {
   |            - expected this type parameter
19 |     Sql::process((), ());
   |     ------------ ^^ expected type parameter `T`, found `()`
   |     |
   |     arguments to this function are incorrect
   |
   = note: expected type parameter `T`
                   found unit type `()`

The issue with <Rigid as OtherTrait>::Assoc has been fixed by lowering the priority of global where-clauses however. I think this issue can be closed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants