Skip to content

"late bound lifetime parameters" error should have a number and help text #80618

Description

@cole-miller

Currently (tested on stable and nightly) if you try to compile this code

fn f<'a>() {}
fn main() { let _ = f::<'static>; }

you get this error message:

error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
 --> src/main.rs:4:17
  |
4 |     let _ = f::<'static>;
  |                 ^^^^^^^
  |
note: the late bound lifetime parameter is introduced here
 --> src/main.rs:1:6
  |
1 | fn f<'a>() {}
  |      ^^

There is no error number (like E0208) to pass to rustc --explain. There's also no mention that you can fix this error without changing the meaning of the code at all by putting a vacuous where clause in the signature of f, like this:

fn f<'a>() where 'a: 'a {}

See #42868 for background. (I'm not sure when that compatibility lint became a hard error; it seems to have happened without that tracking issue being updated. Maybe that has something to do with why the error has no number or help.)

I think:

  • this error should have a number and accompanying rustc --explain text that discusses the early- vs. late-bound lifetime distinction and why specifying late-bound lifetime parameters explicitly is not allowed
  • it should also have a help line that suggests adding where 'a: 'a

Here is the URLO thread that prompted this issue:

https://users.rust-lang.org/t/what-is-the-meaning-of-a-a-in-rust-lifetime-parameters/53570

cc @petrochenkov

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    A-lifetimesArea: Lifetimes / regions
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jan 2, 2021
  2. added
    A-error-codesArea: Explanation of an error code (--explain)
    on Jan 2, 2021
  3. jyn514 commented on Jan 2, 2021

    @jyn514
    Member

    @cole-miller are you interested in adding the --explain text? There's instructions at https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-codes.html?highlight=code#diagnostic-codes, it should be fairly simple.

  4. added
    E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
    on Jan 2, 2021
  5. cole-miller commented on Jan 2, 2021

    @cole-miller
    Author

    @jyn514 sure thing! While I'm waiting for ./x.py test tidy... how much harder would it be to add the help hint at the same time? I can always take a look at previous PRs to get a sense of what's required.

  6. jyn514 commented on Jan 2, 2021

    @jyn514
    Member

    Not too much harder I think :) See #76143 for an example of both.

  7. QuineDot commented on Jan 3, 2021

    @QuineDot
    * this error should have a number and accompanying `rustc --explain` text that discusses the early- vs. late-bound lifetime distinction and why specifying late-bound lifetime parameters explicitly is not allowed
    

    I agree this is needed no matter what.

    * it should also have a `help` line that suggests adding `where 'a: 'a`
    

    I'm not sure this is the best solution though.

    If there are no early bound lifetimes, just leaving off the lifetime specifier (as implied by the lint) also works:

    let _ = f; // just leave off the lifetime specifier
    let _: for<'a> fn() = f; // With type ascription

    In more complicated situations, the type ascription may be needed to specify the early bound lifetimes, but can sometimes still be used without forcing an early bound:

    struct Foo<'a, 'b> { a: &'a(), b: &'b () }
    // There is an implicit late bound parameter due to &Foo; 'a and 'b are early bound
    fn mixed<'a: 'a, 'b: 'b>(_: &Foo<'a, 'b>) -> Foo<'a, 'b> { todo!() }
    
    // This happens to work but no lifetimes can be specified without lint or error
    let _ = mixed;
    
    // For example, this triggers the lint as a warning; specifying 1 or 3+ lifetimes triggers an error:
    // let _ = mixed::<'static, 'static>;
    
    // type ascription allows specifying the lifetimes without warning or error
    let _: for<'a> fn(&'a Foo<'static, 'static>) -> Foo<'static, 'static> = mixed;

    However, it is sometimes necessary to force a lifetime to be early bound, as discussed in issue 42868 and friends. I don't know how tractable it is to detect when the force-early-bound workaround is or isn't required. On the third hand, if I understand the conversation in issue 42508, sometimes type ascription works where forcing an early bound does not.

    without changing the meaning of the code at all

    Not quite:

    // These compiled with `mixed` defined as above.  The first version fires the lint as a warning.
    let _ = mixed::<'static, 'static>;
    let _: for<'a> fn(&'a Foo<'static, 'static>) -> Foo<'static, 'static> = mixed;
    
    // Apply the suggested hint:
    fn mixed<'a: 'a, 'b: 'b, 'c: 'c>(_: &'c Foo<'a, 'b>) -> Foo<'a, 'b> { todo!() }
    
    // This now fails: expected 3 lifetime arguments
    let _ = mixed::<'static, 'static>;
    
    // This now fails: one type is more general than the other
    let _: for<'a> fn(&'a Foo<'static, 'static>) -> Foo<'static, 'static> = mixed;
  8. GroteGnoom commented on Jan 7, 2021

    @GroteGnoom

    Hi, @cole-miller could you claim this? Then it's easier to see which issues are not yet being worked on.

  9. cole-miller commented on Jan 7, 2021

    @cole-miller
    Author

    @rustbot claim

  10. Milo123459 commented on Sep 26, 2021

    @Milo123459
    Contributor

    Any work being done on this? I'd love to implement this as my first contribution.

  11. cole-miller commented on Sep 26, 2021

    @cole-miller
    Author

    I never got around to working on this, feel free to claim it!

    @rustbot release-assignment

  12. Milo123459 commented on Sep 26, 2021

    @Milo123459
    Contributor

    Alright cool! Can I have an example of what it should maybe look like?

  13. sophrosyne97 commented on Jan 1, 2022

    @sophrosyne97

    @rustbot claim

  14. czzrr commented on Jan 27, 2023

    @czzrr
    Contributor

    @rustbot claim

  15. added 2 commits that reference this issue on Mar 17, 2023
  16. wackbyte commented on Jan 28, 2024

    @wackbyte
    Contributor

    I think this can be closed now?

  17. jieyouxu commented on Oct 10, 2024

    @jieyouxu
    Member

    Fixed by #107416.

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-error-codesArea: Explanation of an error code (--explain)A-lifetimesArea: Lifetimes / regionsC-enhancementCategory: An issue proposing an enhancement or a PR with one.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.T-compilerRelevant to the compiler 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