Rollup merge of #107416 - czzrr:issue-80618, r=GuillaumeGomez
Error code E0794 for late-bound lifetime parameter error. This PR addresses [#80618](https://github.com/rust-lang/rust/issues/80618).
This commit is contained in:
commit
9599f3cc54
9 changed files with 126 additions and 35 deletions
|
@ -513,6 +513,7 @@ E0790: include_str!("./error_codes/E0790.md"),
|
|||
E0791: include_str!("./error_codes/E0791.md"),
|
||||
E0792: include_str!("./error_codes/E0792.md"),
|
||||
E0793: include_str!("./error_codes/E0793.md"),
|
||||
E0794: include_str!("./error_codes/E0794.md"),
|
||||
}
|
||||
|
||||
// Undocumented removed error codes. Note that many removed error codes are documented.
|
||||
|
|
64
compiler/rustc_error_codes/src/error_codes/E0794.md
Normal file
64
compiler/rustc_error_codes/src/error_codes/E0794.md
Normal file
|
@ -0,0 +1,64 @@
|
|||
A lifetime parameter of a function definition is called *late-bound* if it both:
|
||||
|
||||
1. appears in an argument type
|
||||
2. does not appear in a generic type constraint
|
||||
|
||||
You cannot specify lifetime arguments for late-bound lifetime parameters.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0794
|
||||
fn foo<'a>(x: &'a str) -> &'a str { x }
|
||||
let _ = foo::<'static>;
|
||||
```
|
||||
|
||||
The type of a concrete instance of a generic function is universally quantified
|
||||
over late-bound lifetime parameters. This is because we want the function to
|
||||
work for any lifetime substituted for the late-bound lifetime parameter, no
|
||||
matter where the function is called. Consequently, it doesn't make sense to
|
||||
specify arguments for late-bound lifetime parameters, since they are not
|
||||
resolved until the function's call site(s).
|
||||
|
||||
To fix the issue, remove the specified lifetime:
|
||||
|
||||
```
|
||||
fn foo<'a>(x: &'a str) -> &'a str { x }
|
||||
let _ = foo;
|
||||
```
|
||||
|
||||
### Additional information
|
||||
|
||||
Lifetime parameters that are not late-bound are called *early-bound*.
|
||||
Confusion may arise from the fact that late-bound and early-bound
|
||||
lifetime parameters are declared the same way in function definitions.
|
||||
When referring to a function pointer type, universal quantification over
|
||||
late-bound lifetime parameters can be made explicit:
|
||||
|
||||
```
|
||||
trait BarTrait<'a> {}
|
||||
|
||||
struct Bar<'a> {
|
||||
s: &'a str
|
||||
}
|
||||
|
||||
impl<'a> BarTrait<'a> for Bar<'a> {}
|
||||
|
||||
fn bar<'a, 'b, T>(x: &'a str, _t: T) -> &'a str
|
||||
where T: BarTrait<'b>
|
||||
{
|
||||
x
|
||||
}
|
||||
|
||||
let bar_fn: for<'a> fn(&'a str, Bar<'static>) -> &'a str = bar; // OK
|
||||
let bar_fn2 = bar::<'static, Bar>; // Not allowed
|
||||
let bar_fn3 = bar::<Bar>; // OK
|
||||
```
|
||||
|
||||
In the definition of `bar`, the lifetime parameter `'a` is late-bound, while
|
||||
`'b` is early-bound. This is reflected in the type annotation for `bar_fn`,
|
||||
where `'a` is universally quantified and `'b` is substituted by a specific
|
||||
lifetime. It is not allowed to explicitly specify early-bound lifetime
|
||||
arguments when late-bound lifetime parameters are present (as for `bar_fn2`,
|
||||
see issue #42868: https://github.com/rust-lang/rust/issues/42868), although the
|
||||
types that are constrained by early-bound parameters can be specified (as for
|
||||
`bar_fn3`).
|
Loading…
Add table
Add a link
Reference in a new issue