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

Diagnostics do not consider lifetime parameters to be "generics" #128583

Open
QuineDot opened this issue Aug 3, 2024 · 1 comment
Open

Diagnostics do not consider lifetime parameters to be "generics" #128583

QuineDot opened this issue Aug 3, 2024 · 1 comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@QuineDot
Copy link

QuineDot commented Aug 3, 2024

Code

fn example<'one: 'two, 'two, Three, const Four: usize, Five>() {}

fn main() {
    example::<()>();
}

Current output

error[E0107]: function takes 3 generic arguments but 1 generic argument was supplied
 --> src/main.rs:4:5
  |
4 |     example::<()>();
  |     ^^^^^^^   -- supplied 1 generic argument
  |     |
  |     expected 3 generic arguments
  |
note: function defined here, with 3 generic parameters: `Three`, `Four`, `Five`
 --> src/main.rs:1:4
  |
1 | fn example<'one: 'two, 'two, Three, const Four: usize, Five>() {}
  |    ^^^^^^^                   -----  -----------------  ----
help: add missing generic arguments
  |
4 |     example::<(), Four, Five>();
  |                 ++++++++++++

Desired output

error[E0107]: function takes 3 non-lifetime arguments but 1 non-lifetime argument was supplied
 --> src/main.rs:4:5
  |
4 |     example::<()>();
  |     ^^^^^^^   -- supplied 1 non-lifetime argument
  |     |
  |     expected 3 non-lifetime arguments
  |
note: function defined here, with 3 non-lifetime parameters: `Three`, `Four`, `Five`
 --> src/main.rs:1:4
  |
1 | fn example<'one: 'two, 'two, Three, const Four: usize, Five>() {}
  |    ^^^^^^^                   -----  -----------------  ----
help: add missing non-lifetime arguments
  |
4 |     example::<(), Four, Five>();
  |                 ++++++++++++

Rationale and extra context

Lifetimes parameters are also generic parameters, so the statement that the example has 3 generic arguments is counterfactual. For function items in particular, early-bound lifetimes are also generic parameters of the function item type.

See this URLO topic for an example of someone who understands the distinction between late and early lifetime parameters being confused by the current diagnostic (being mislead that a function's lifetime parameter was late bound because it "only had 2 generic parameters" based on the diagnostic).

Other cases

//! This version shows that the compiler currently outputs two
//! separate warnings, one for lifetime parameters and one for
//! non-lifetime parameters
fn example<'one: 'two, 'two, Three, const Four: usize, Five>() {}

fn main() {
    example::<'static, ()>();
}
/*

error[E0107]: function takes 2 lifetime arguments but 1 lifetime argument was supplied
 --> src/main.rs:4:5
  |
4 |     example::<'static, ()>();
  |     ^^^^^^^   ------- supplied 1 lifetime argument
  |     |
  |     expected 2 lifetime arguments
  |
note: function defined here, with 2 lifetime parameters: `'one`, `'two`
 --> src/main.rs:1:4
  |
1 | fn example<'one: 'two, 'two, Three, const Four: usize, Five>() {}
  |    ^^^^^^^ ----        ----
help: add missing lifetime argument
  |
4 |     example::<'static, 'static, ()>();
  |                      +++++++++

error[E0107]: function takes 3 generic arguments but 1 generic argument was supplied
 --> src/main.rs:4:5
  |
4 |     example::<'static, ()>();
  |     ^^^^^^^            -- supplied 1 generic argument
  |     |
  |     expected 3 generic arguments
  |
note: function defined here, with 3 generic parameters: `Three`, `Four`, `Five`
 --> src/main.rs:1:4
  |
1 | fn example<'one: 'two, 'two, Three, const Four: usize, Five>() {}
  |    ^^^^^^^                   -----  -----------------  ----
help: add missing generic arguments
  |
4 |     example::<'static, (), Four, Five>();
  |                          ++++++++++++
*/
*/

Rust Version

Rust playground

Stable channel
Build using the Stable version: 1.80.0

Beta channel
Build using the Beta version: 1.81.0-beta.2
(2024-07-25 08328a323ecd80b443a8)

Nightly channel
Build using the Nightly version: 1.82.0-nightly
(2024-08-02 fd8d6fbe505ecf913f5e)

Anything else?

No response

@QuineDot QuineDot added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 3, 2024
@QuineDot
Copy link
Author

QuineDot commented Aug 3, 2024

The error used to say "type arguments" instead of "generic arguments" which was accurate at the time. It presumably changed in 1.54 in anticipation of const generics and/or the ability to intermix generic const and types, which I believe both stabilized in 1.59. (Prior to that const parameters had to come after type parameters.)

This is the PR. Looks like before it was "lifetime", "type", "const" and after it was "lifetime", "generic".

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

1 participant