Skip to content

add note when there's a type mismatch due to param_env shadowing #149910

@lcnr

Description

@lcnr
trait Trait {
    type Assoc;
}

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

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

results in the following error

error[E0308]: mismatched types
  --> src/lib.rs:10:5
   |
 9 | fn foo<T: Trait>(x: T) -> T::Assoc {
   |        -                  -------- expected `<T as Trait>::Assoc` because of return type
   |        |
   |        found this type parameter
10 |     x
   |     ^ expected associated type, found type parameter `T`
   |
   = note: expected associated type `<T as Trait>::Assoc`
               found type parameter `T`
help: consider further restricting this bound
   |
 9 | fn foo<T: Trait<Assoc = T>>(x: T) -> T::Assoc {
   |                +++++++++++

The reason this fails is that we do not normalize via impls if there is a where-bound in scope https://rustc-dev-guide.rust-lang.org/solve/candidate-preference.html#where-bounds-shadow-impls

If we get a type equality error and one side is an alias, we should check whether the alias would successfully normalize without param_env shadowing (using a ProofTreeVisitor in the new solver and maybe looking at all candidates and checking for impl ones in the old), and then add a note explaining why this error happens and suggesting ways to avoid it (mostly by dropping trivial where-clauses)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-trait-systemArea: Trait systemD-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions