Skip to content
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

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

Closed
cole-miller opened this issue Jan 2, 2021 · 13 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-error-codes Area: Explanation of an error code (--explain) A-lifetimes Area: Lifetimes / regions C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@cole-miller
Copy link

cole-miller commented Jan 2, 2021

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

@jonas-schievink jonas-schievink added A-diagnostics Area: Messages for errors, warnings, and lints A-lifetimes Area: Lifetimes / regions C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 2, 2021
@jyn514 jyn514 added the A-error-codes Area: Explanation of an error code (--explain) label Jan 2, 2021
@jyn514
Copy link
Member

jyn514 commented Jan 2, 2021

@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.

@jyn514 jyn514 added the E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. label Jan 2, 2021
@cole-miller
Copy link
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.

@jyn514
Copy link
Member

jyn514 commented Jan 2, 2021

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

@QuineDot
Copy link

QuineDot commented Jan 3, 2021

* 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;

@GroteGnoom
Copy link

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

@cole-miller
Copy link
Author

@rustbot claim

@Milo123459
Copy link
Contributor

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

@cole-miller
Copy link
Author

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

@rustbot release-assignment

@Milo123459
Copy link
Contributor

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

@sophrosyne97
Copy link

@rustbot claim

@czzrr
Copy link
Contributor

czzrr commented Jan 27, 2023

@rustbot claim

@rustbot rustbot assigned czzrr and unassigned sophrosyne97 Jan 27, 2023
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 17, 2023
Error code E0794 for late-bound lifetime parameter error.

This PR addresses [rust-lang#80618](rust-lang#80618).
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 18, 2023
Error code E0794 for late-bound lifetime parameter error.

This PR addresses [rust-lang#80618](rust-lang#80618).
saethlin pushed a commit to saethlin/miri that referenced this issue Mar 19, 2023
Error code E0794 for late-bound lifetime parameter error.

This PR addresses [#80618](rust-lang/rust#80618).
@wackbyte
Copy link
Contributor

I think this can be closed now?

@jieyouxu
Copy link
Member

Fixed by #107416.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-error-codes Area: Explanation of an error code (--explain) A-lifetimes Area: Lifetimes / regions C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

10 participants