Skip to content

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

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)

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Dec 12, 2025
  2. lcnr commented on Dec 12, 2025

    @lcnr
    ContributorAuthor

    example with worse error msg by @jdonszelmann

    pub trait Supertrait {
        type Assoc;
        fn decoder(self) -> Self::Assoc;
    }
    
    pub trait Trait: Supertrait {}
    
    impl<T: Trait> Supertrait for T {
        type Assoc = ();
        fn decoder(self) -> Self::Assoc {}
    }
    error[E0308]: mismatched types
      --> src/lib.rs:10:25
       |
    10 |     fn decoder(self) -> Self::Assoc {}
       |        -------          ^^^^^^^^^^^ expected associated type, found `()`
       |        |
       |        implicitly returns `()` as its body has no tail or `return` expression
       |
       = note: expected associated type `<T as Supertrait>::Assoc`
                        found unit type `()`
       = help: consider constraining the associated type `<T as Supertrait>::Assoc` to `()` or calling a method that returns `<T as Supertrait>::Assoc`
       = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
    
  3. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    A-diagnosticsArea: Messages for errors, warnings, and lints
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Dec 14, 2025
  4. xonx4l commented on Dec 20, 2025

    @xonx4l
    Contributor

    @lcnr like adding a check inside the error reporting function?

  5. lcnr commented on Dec 20, 2025

    @lcnr
    ContributorAuthor

    yes, when reporting type mismatch errors, check whether one side is an alias, if so, check whether the alias could have been normalized to another type via an impl, if so, check whether these types would be equal, in either case, add a note explaining that the alias is rigid due to a where-bound and could have otherwise been normalized

  6. xonx4l commented on Dec 20, 2025

    @xonx4l
    Contributor

    Great , makes so much sense now . Thanks

  7. added a commit that references this issue on Feb 15, 2026
  8. added a commit that references this issue on Feb 15, 2026
  9. lcnr commented on Mar 11, 2026

    @lcnr
    ContributorAuthor

    implemented in #150424 with tracking issue #152409

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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