-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Open
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Code
struct A<'a>(&'a ());
impl<'a> A<'a> {
fn associated(a: &'a (), b: &()) {}
}
fn main() {
let works_not: for<'a> fn(&'a (), &()) = A::associated; // Error
let works_not: for<'a, 'b> fn(&'a (), &'b ()) = A::<'_>::associated; // Error
let works: for<'a> fn(&'a (), &()) = |a, b| A::associated(a, b); // Ok
let works: for<'a, 'b> fn(&'a (), &'b ()) = |a, b| A::associated(a, b); // Ok
}Current output
error[E0308]: mismatched types
--> src\main.rs:8:46
|
8 | let works_not: for<'a> fn(&'a (), &()) = A::associated; // Error
| ----------------------- ^^^^^^^^^^^^^ one type is more general than the other
| |
| expected due to this
|
= note: expected fn pointer `for<'a, 'b> fn(&'a (), &'b ())`
found fn item `for<'a> fn(&(), &'a ()) {A::<'_>::associated}`
error[E0308]: mismatched types
--> src\main.rs:9:53
|
9 | let works_not: for<'a, 'b> fn(&'a (), &'b ()) = A::<'_>::associated; // Error
| ------------------------------ ^^^^^^^^^^^^^^^^^^^ one type is more general than the other
| |
| expected due to this
|
= note: expected fn pointer `for<'a, 'b> fn(&'a (), &'b ())`
found fn item `for<'a> fn(&(), &'a ()) {A::<'_>::associated}`Desired output
error[E0308]: mismatched types
--> src/main.rs:8:46
|
10 | let no_works: for<'a> fn(&'a (), &()) = A::associated; // Error
| ----------------------- ^^^^^^^^^^^^^ one type is more general than the other
| |
| expected due to this
|
= note: expected fn pointer `for<'a, 'b> fn(&'a (), &'b ())`
found fn item `for<'b> fn(&'1 (), &'b ()) {A::<'1>::associated}`
help: you can convert a early bound lifetime to a late bound using a closure
--> src/main.rs:8:46
|
10 | let no_works: for<'a> fn(&'a (), &()) = |a, b| A::associated(a, b); // Error
| ++++++ ++++++Rationale and extra context
Proposed changes (ranked by importance):
- Introduce the concept of early/late bounds so that the problem becomes searchable.
- Explicitly name the early bound lifetimes ('1) since I didn't really parse the
{A::<'_>::associated}part of the fn type as linked/important. I thought that I might just need to add/remove lifetimes. - Suggest using a closure to convert from early bounds to late bounds. (I'm not sure if this always works?)
- Don't reuse
'aand'bin the diagnostic. Using the existing lifetime names instead of "shadowing" the definitions would be nice. This introduced more confusion since I commonly used'aand'bwhen writing lifetimes and it wasn't clear to me that these were different.
In my mind this is is an ideal output but some of these might not be feasible for one reason or another.
Other cases
Rust Version
$ cargo +stable -V -v
cargo 1.86.0 (adf9b6ad1 2025-02-28)
release: 1.86.0
commit-hash: adf9b6ad14cfa10ff680d5806741a144f7163698
commit-date: 2025-02-28
host: x86_64-pc-windows-msvc
libgit2: 1.9.0 (sys:0.20.0 vendored)
libcurl: 8.12.0-DEV (sys:0.4.79+curl-8.12.0 vendored ssl:Schannel)
os: Windows 10.0.26100 (Windows 11 Professional) [64-bit]Anything else?
You can see my initial confusion here: #140663.
I would be interested in trying to implement some of these changes.
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.