Skip to content

Tracking issue for future-incompatibility lint coherence_leak_check #56105

Open

Description

@nikomatsakis

View all comments

This is the tracking issue for the "universe transition". The goal of this page is describe why this change was made and how you can fix code that is affected by it. It also provides a place to ask questions or register a complaint if you feel the change should not be made. For more information on the policy around bug fixes that affect existing code, see our breaking change policy guidelines.

What was the change and what code is affected?

This change (introduced in #55517) fixed a number of bugs (e.g., #32330) in how the Rust compiler handled higher-ranked types (e.g., fn(&u8) or -- more explicitly -- for<'a> fn(&'a u8)) and trait bounds (e.g., for<'a> T: Trait<'a>). One of these changes could however affect existing code. In particular, the compiler in the past would accept trait implementations for identical functions that differed only in where the lifetime binder appeared:

trait SomeTrait { }
impl SomeTrait for for<'a> fn(&'a u8) { }
impl<'a> SomeTrait for fn(&'a u8) { }

We no longer accept both of these impls. Code relying on this pattern would now have to introduce "newtypes", like struct Foo(for<'a> fn(&'a u8)).

History of this change

This change was first made in #55517 without a "warning period". This was done because (a) it would be challenging to issue precise warnings for affected code and (b) a crater run found zero regressions.

However, the change was subsequently backed out in #58592, owing to concerns about unintended side-effects.

The change was re-added in #65232, but this time with a warning period. We are currently completing the implementation and trying to figure out how to draw the line in terms of what should become a hard error.

Affected crates and patterns

This section is for collecting patterns and examples to look into or other related issues.

Activity

  1. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    on Nov 20, 2018
  2. changed the title [-]universe transition compatibility issue[/-] [+]tracking issue for "universe transition"[/+] on Nov 20, 2018
  3. SimonSapin commented on Jan 4, 2019

    @SimonSapin
    Contributor

    Oh hey, this one again.

    This breaking change is the exact opposite of another breaking change from August 2017 made in #43880 and discussed FCP’ed in #44224.

    Like before, Servo is affected. The fix is to remove the generic trait impl for fn(&A) -> B (keeping the one for fn(A) -> B) that we added in servo/servo#18327 to fix the other breaking change. I don’t know how much code outside of Servo is affected.

    In the abstract, the behavior now in Nightly makes more sense to be. fn(&A) -> B is a special case of fn(AA) -> B (with AA = &A), so it should be covered by a trait impl for the latter without a separate impl being needed.

    However, it doesn’t feel good that we pushed the ecosystem through a breakage (even if it might only affect a small fraction of the code out there) with lengthy technical arguments (that I don’t entirely understand) in #44224 to justify it, only to change our mind a couple years later and cause breakage again. Do those arguments no longer apply? Did something change, or were they not good arguments in the first place? What is the confidence that this time, reverting is the right decision?

    The goal of this page is describe why this change was made and how you can fix code that is affected by it.

    As far as I can find, the issue description says what the change is but not why it was made.

    a crater run found zero regressions

    I’m worried that we rely on Crater so much for this kind of decision. It can only test a sample of all the Rust code that exists in the world, and that sample likely has a heavy selection bias toward (relatively) small libraries rather than large applications.

    How much of https://www.rust-lang.org/production/users is tested by crater?

  4. added a commit that references this issue on Jan 4, 2019
  5. dtolnay commented on Jan 5, 2019

    @dtolnay
    Member

    I filed #57362 to follow up on a confusing sort of error message introduced in #55517.

    error[E0308]: mismatched types
      --> src/main.rs:13:7
       |
    13 |     a.f();
       |       ^ one type is more general than the other
       |
       = note: expected type `Trait`
                  found type `Trait`
  6. 40 remaining items

  7. added a commit that references this issue on Feb 5, 2024
  8. added a commit that references this issue on Jul 16, 2024
  9. added 2 commits that reference this issue on Jul 17, 2024
  10. added 4 commits that reference this issue on Jul 17, 2024
  11. changed the title [-]tracking issue for "universe transition"[/-] [+]Tracking issue for future-incompatibility lint `coherence_leak_check`[/+] on Sep 14, 2024
  12. added
    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.
    on Sep 14, 2024
  13. added
    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.
    and removed
    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.
    on Dec 21, 2024
  14. added
    A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)
    on Mar 3, 2026
  15. EFanZh commented on Sep 10, 2026

    @EFanZh
    Contributor

    I got this error with the following code using Rust 1.98.0:

    trait Foo {
        const VALUE: u32;
    }
    
    impl Foo for for<'a, 'b, 'c> fn(&'a (), &'b (), &'c ()) -> &'a () {
        const VALUE: u32 = 0;
    }
    
    impl Foo for for<'a, 'b, 'c> fn(&'a (), &'b (), &'c ()) -> &'b () {
        const VALUE: u32 = 1;
    }
    
    impl Foo for for<'a, 'b, 'c> fn(&'a (), &'b (), &'c ()) -> &'c () {
        const VALUE: u32 = 2;
    }

    Is this expected, or should this be considered a false positive?

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-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-lifetimesArea: Lifetimes / regionsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.C-future-incompatibilityCategory: Future-incompatibility lintsC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCS-tracking-impl-incompleteStatus: The implementation is incomplete.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

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions