-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Error code E0794 for late-bound lifetime parameter error.
- Loading branch information
Showing
9 changed files
with
126 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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`). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
fn foo<'a>(x: &'a str) -> &'a str { | ||
x | ||
} | ||
|
||
fn main() { | ||
let _ = foo::<'static>; | ||
//~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present [E0794] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present | ||
--> $DIR/issue-80618.rs:6:19 | ||
| | ||
LL | let _ = foo::<'static>; | ||
| ^^^^^^^ | ||
| | ||
note: the late bound lifetime parameter is introduced here | ||
--> $DIR/issue-80618.rs:1:8 | ||
| | ||
LL | fn foo<'a>(x: &'a str) -> &'a str { | ||
| ^^ | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0794`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.