Error code E0794 for late-bound lifetime parameter error.

This commit is contained in:
Christopher Acosta 2023-01-27 22:23:01 +01:00 committed by Christopher Acossta
parent 1a521db67e
commit 75563cd725
9 changed files with 126 additions and 35 deletions

View File

@ -513,6 +513,7 @@
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.

View 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`).

View File

@ -618,7 +618,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
if position == GenericArgPosition::Value
&& args.num_lifetime_params() != param_counts.lifetimes
{
let mut err = tcx.sess.struct_span_err(span, msg);
let mut err = struct_span_err!(tcx.sess, span, E0794, "{}", msg);
err.span_note(span_late, note);
err.emit();
} else {

View File

@ -1,4 +1,4 @@
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:18:23
|
LL | let _: [u8; faz::<'a>(&())];
@ -10,7 +10,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:21:23
|
LL | let _: [u8; faz::<'b>(&())];
@ -22,7 +22,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:41:24
|
LL | let _: Foo<{ faz::<'a>(&()) }>;
@ -34,7 +34,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:44:24
|
LL | let _: Foo<{ faz::<'b>(&()) }>;
@ -94,7 +94,7 @@ LL | let _ = [0; bar::<N>()];
|
= help: try adding a `where` bound using this expression: `where [(); bar::<N>()]:`
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:30:23
|
LL | let _ = [0; faz::<'a>(&())];
@ -106,7 +106,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:33:23
|
LL | let _ = [0; faz::<'b>(&())];
@ -134,7 +134,7 @@ LL | let _ = Foo::<{ bar::<N>() }>;
|
= help: try adding a `where` bound using this expression: `where [(); { bar::<N>() }]:`
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:52:27
|
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
@ -146,7 +146,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:55:27
|
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
@ -160,3 +160,4 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
error: aborting due to 16 previous errors
For more information about this error, try `rustc --explain E0794`.

View File

@ -216,7 +216,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | let _: [u8; bar::<{ N }>()];
| + +
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:18:23
|
LL | let _: [u8; faz::<'a>(&())];
@ -228,7 +228,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:21:23
|
LL | let _: [u8; faz::<'b>(&())];
@ -251,7 +251,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | let _: Foo<{ bar::<{ N }>() }>;
| + +
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:41:24
|
LL | let _: Foo<{ faz::<'a>(&()) }>;
@ -263,7 +263,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:44:24
|
LL | let _: Foo<{ faz::<'b>(&()) }>;
@ -294,7 +294,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | let _ = [0; bar::<{ N }>()];
| + +
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:30:23
|
LL | let _ = [0; faz::<'a>(&())];
@ -306,7 +306,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:33:23
|
LL | let _ = [0; faz::<'b>(&())];
@ -329,7 +329,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | let _ = Foo::<{ bar::<{ N }>() }>;
| + +
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:52:27
|
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
@ -341,7 +341,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:55:27
|
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
@ -355,5 +355,5 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
error: aborting due to 36 previous errors
Some errors have detailed explanations: E0658, E0747.
Some errors have detailed explanations: E0658, E0747, E0794.
For more information about an error, try `rustc --explain E0658`.

View File

@ -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]
}

View File

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

View File

@ -30,7 +30,7 @@ note: method defined here, with 2 lifetime parameters: `'a`, `'b`
LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
| ^^^^^ -- --
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:27:15
|
LL | S::late::<'static>(S, &0, &0);
@ -42,7 +42,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:29:15
|
LL | S::late::<'static, 'static>(S, &0, &0);
@ -54,7 +54,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:31:15
|
LL | S::late::<'static, 'static, 'static>(S, &0, &0);
@ -66,7 +66,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:34:21
|
LL | S::late_early::<'static, 'static>(S, &0);
@ -78,7 +78,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:36:21
|
LL | S::late_early::<'static, 'static, 'static>(S, &0);
@ -90,7 +90,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:40:24
|
LL | S::late_implicit::<'static>(S, &0, &0);
@ -102,7 +102,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_implicit(self, _: &u8, _: &u8) {}
| ^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:42:24
|
LL | S::late_implicit::<'static, 'static>(S, &0, &0);
@ -114,7 +114,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_implicit(self, _: &u8, _: &u8) {}
| ^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:44:24
|
LL | S::late_implicit::<'static, 'static, 'static>(S, &0, &0);
@ -126,7 +126,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_implicit(self, _: &u8, _: &u8) {}
| ^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:47:30
|
LL | S::late_implicit_early::<'static, 'static>(S, &0);
@ -138,7 +138,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} }
| ^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:49:30
|
LL | S::late_implicit_early::<'static, 'static, 'static>(S, &0);
@ -150,7 +150,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} }
| ^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:52:35
|
LL | S::late_implicit_self_early::<'static, 'static>(&S);
@ -162,7 +162,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_implicit_self_early<'b>(&self) -> &'b u8 { loop {} }
| ^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:54:35
|
LL | S::late_implicit_self_early::<'static, 'static, 'static>(&S);
@ -174,7 +174,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_implicit_self_early<'b>(&self) -> &'b u8 { loop {} }
| ^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:57:28
|
LL | S::late_unused_early::<'static, 'static>(S);
@ -186,7 +186,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} }
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args-fail.rs:59:28
|
LL | S::late_unused_early::<'static, 'static, 'static>(S);
@ -232,4 +232,5 @@ LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
error: aborting due to 18 previous errors
For more information about this error, try `rustc --explain E0107`.
Some errors have detailed explanations: E0107, E0794.
For more information about an error, try `rustc --explain E0107`.

View File

@ -1,4 +1,4 @@
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args.rs:9:15
|
LL | S::late::<'static>(S, &0, &0);
@ -10,7 +10,7 @@ note: the late bound lifetime parameter is introduced here
LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
| ^^
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/method-call-lifetime-args.rs:11:24
|
LL | S::late_implicit::<'static>(S, &0, &0);
@ -24,3 +24,4 @@ LL | fn late_implicit(self, _: &u8, _: &u8) {}
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0794`.