Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9599f3c

Browse files
Rollup merge of #107416 - czzrr:issue-80618, r=GuillaumeGomez
Error code E0794 for late-bound lifetime parameter error. This PR addresses [#80618](#80618).
2 parents df61fca + 75563cd commit 9599f3c

File tree

9 files changed

+126
-35
lines changed

9 files changed

+126
-35
lines changed

‎compiler/rustc_error_codes/src/error_codes.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ E0790: include_str!("./error_codes/E0790.md"),
513513
E0791: include_str!("./error_codes/E0791.md"),
514514
E0792: include_str!("./error_codes/E0792.md"),
515515
E0793: include_str!("./error_codes/E0793.md"),
516+
E0794: include_str!("./error_codes/E0794.md"),
516517
}
517518

518519
// Undocumented removed error codes. Note that many removed error codes are documented.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
A lifetime parameter of a function definition is called *late-bound* if it both:
2+
3+
1. appears in an argument type
4+
2. does not appear in a generic type constraint
5+
6+
You cannot specify lifetime arguments for late-bound lifetime parameters.
7+
8+
Erroneous code example:
9+
10+
```compile_fail,E0794
11+
fn foo<'a>(x: &'a str) -> &'a str { x }
12+
let _ = foo::<'static>;
13+
```
14+
15+
The type of a concrete instance of a generic function is universally quantified
16+
over late-bound lifetime parameters. This is because we want the function to
17+
work for any lifetime substituted for the late-bound lifetime parameter, no
18+
matter where the function is called. Consequently, it doesn't make sense to
19+
specify arguments for late-bound lifetime parameters, since they are not
20+
resolved until the function's call site(s).
21+
22+
To fix the issue, remove the specified lifetime:
23+
24+
```
25+
fn foo<'a>(x: &'a str) -> &'a str { x }
26+
let _ = foo;
27+
```
28+
29+
### Additional information
30+
31+
Lifetime parameters that are not late-bound are called *early-bound*.
32+
Confusion may arise from the fact that late-bound and early-bound
33+
lifetime parameters are declared the same way in function definitions.
34+
When referring to a function pointer type, universal quantification over
35+
late-bound lifetime parameters can be made explicit:
36+
37+
```
38+
trait BarTrait<'a> {}
39+
40+
struct Bar<'a> {
41+
s: &'a str
42+
}
43+
44+
impl<'a> BarTrait<'a> for Bar<'a> {}
45+
46+
fn bar<'a, 'b, T>(x: &'a str, _t: T) -> &'a str
47+
where T: BarTrait<'b>
48+
{
49+
x
50+
}
51+
52+
let bar_fn: for<'a> fn(&'a str, Bar<'static>) -> &'a str = bar; // OK
53+
let bar_fn2 = bar::<'static, Bar>; // Not allowed
54+
let bar_fn3 = bar::<Bar>; // OK
55+
```
56+
57+
In the definition of `bar`, the lifetime parameter `'a` is late-bound, while
58+
`'b` is early-bound. This is reflected in the type annotation for `bar_fn`,
59+
where `'a` is universally quantified and `'b` is substituted by a specific
60+
lifetime. It is not allowed to explicitly specify early-bound lifetime
61+
arguments when late-bound lifetime parameters are present (as for `bar_fn2`,
62+
see issue #42868: https://github.com/rust-lang/rust/issues/42868), although the
63+
types that are constrained by early-bound parameters can be specified (as for
64+
`bar_fn3`).

‎compiler/rustc_hir_analysis/src/astconv/generics.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
612612
if position == GenericArgPosition::Value
613613
&& args.num_lifetime_params() != param_counts.lifetimes
614614
{
615-
let mut err = tcx.sess.struct_span_err(span, msg);
615+
let mut err = struct_span_err!(tcx.sess,span,E0794,"{}", msg);
616616
err.span_note(span_late, note);
617617
err.emit();
618618
} else {

‎tests/ui/const-generics/const-arg-in-const-arg.full.stderr‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
1+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
22
--> $DIR/const-arg-in-const-arg.rs:18:23
33
|
44
LL | let _: [u8; faz::<'a>(&())];
@@ -10,7 +10,7 @@ note: the late bound lifetime parameter is introduced here
1010
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
1111
| ^^
1212

13-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
13+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
1414
--> $DIR/const-arg-in-const-arg.rs:21:23
1515
|
1616
LL | let _: [u8; faz::<'b>(&())];
@@ -22,7 +22,7 @@ note: the late bound lifetime parameter is introduced here
2222
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
2323
| ^^
2424

25-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
25+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
2626
--> $DIR/const-arg-in-const-arg.rs:41:24
2727
|
2828
LL | let _: Foo<{ faz::<'a>(&()) }>;
@@ -34,7 +34,7 @@ note: the late bound lifetime parameter is introduced here
3434
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
3535
| ^^
3636

37-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
37+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
3838
--> $DIR/const-arg-in-const-arg.rs:44:24
3939
|
4040
LL | let _: Foo<{ faz::<'b>(&()) }>;
@@ -94,7 +94,7 @@ LL | let _ = [0; bar::<N>()];
9494
|
9595
= help: try adding a `where` bound using this expression: `where [(); bar::<N>()]:`
9696

97-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
97+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
9898
--> $DIR/const-arg-in-const-arg.rs:30:23
9999
|
100100
LL | let _ = [0; faz::<'a>(&())];
@@ -106,7 +106,7 @@ note: the late bound lifetime parameter is introduced here
106106
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
107107
| ^^
108108

109-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
109+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
110110
--> $DIR/const-arg-in-const-arg.rs:33:23
111111
|
112112
LL | let _ = [0; faz::<'b>(&())];
@@ -134,7 +134,7 @@ LL | let _ = Foo::<{ bar::<N>() }>;
134134
|
135135
= help: try adding a `where` bound using this expression: `where [(); { bar::<N>() }]:`
136136

137-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
137+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
138138
--> $DIR/const-arg-in-const-arg.rs:52:27
139139
|
140140
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
@@ -146,7 +146,7 @@ note: the late bound lifetime parameter is introduced here
146146
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
147147
| ^^
148148

149-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
149+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
150150
--> $DIR/const-arg-in-const-arg.rs:55:27
151151
|
152152
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
@@ -160,3 +160,4 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
160160

161161
error: aborting due to 16 previous errors
162162

163+
For more information about this error, try `rustc --explain E0794`.

‎tests/ui/const-generics/const-arg-in-const-arg.min.stderr‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
216216
LL | let _: [u8; bar::<{ N }>()];
217217
| + +
218218

219-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
219+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
220220
--> $DIR/const-arg-in-const-arg.rs:18:23
221221
|
222222
LL | let _: [u8; faz::<'a>(&())];
@@ -228,7 +228,7 @@ note: the late bound lifetime parameter is introduced here
228228
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
229229
| ^^
230230

231-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
231+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
232232
--> $DIR/const-arg-in-const-arg.rs:21:23
233233
|
234234
LL | let _: [u8; faz::<'b>(&())];
@@ -251,7 +251,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
251251
LL | let _: Foo<{ bar::<{ N }>() }>;
252252
| + +
253253

254-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
254+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
255255
--> $DIR/const-arg-in-const-arg.rs:41:24
256256
|
257257
LL | let _: Foo<{ faz::<'a>(&()) }>;
@@ -263,7 +263,7 @@ note: the late bound lifetime parameter is introduced here
263263
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
264264
| ^^
265265

266-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
266+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
267267
--> $DIR/const-arg-in-const-arg.rs:44:24
268268
|
269269
LL | let _: Foo<{ faz::<'b>(&()) }>;
@@ -294,7 +294,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
294294
LL | let _ = [0; bar::<{ N }>()];
295295
| + +
296296

297-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
297+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
298298
--> $DIR/const-arg-in-const-arg.rs:30:23
299299
|
300300
LL | let _ = [0; faz::<'a>(&())];
@@ -306,7 +306,7 @@ note: the late bound lifetime parameter is introduced here
306306
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
307307
| ^^
308308

309-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
309+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
310310
--> $DIR/const-arg-in-const-arg.rs:33:23
311311
|
312312
LL | let _ = [0; faz::<'b>(&())];
@@ -329,7 +329,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
329329
LL | let _ = Foo::<{ bar::<{ N }>() }>;
330330
| + +
331331

332-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
332+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
333333
--> $DIR/const-arg-in-const-arg.rs:52:27
334334
|
335335
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
@@ -341,7 +341,7 @@ note: the late bound lifetime parameter is introduced here
341341
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
342342
| ^^
343343

344-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
344+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
345345
--> $DIR/const-arg-in-const-arg.rs:55:27
346346
|
347347
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
@@ -355,5 +355,5 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
355355

356356
error: aborting due to 36 previous errors
357357

358-
Some errors have detailed explanations: E0658, E0747.
358+
Some errors have detailed explanations: E0658, E0747, E0794.
359359
For more information about an error, try `rustc --explain E0658`.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn foo<'a>(x: &'a str) -> &'a str {
2+
x
3+
}
4+
5+
fn main() {
6+
let _ = foo::<'static>;
7+
//~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present [E0794]
8+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
2+
--> $DIR/issue-80618.rs:6:19
3+
|
4+
LL | let _ = foo::<'static>;
5+
| ^^^^^^^
6+
|
7+
note: the late bound lifetime parameter is introduced here
8+
--> $DIR/issue-80618.rs:1:8
9+
|
10+
LL | fn foo<'a>(x: &'a str) -> &'a str {
11+
| ^^
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0794`.

‎tests/ui/methods/method-call-lifetime-args-fail.stderr‎

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ note: method defined here, with 2 lifetime parameters: `'a`, `'b`
3030
LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
3131
| ^^^^^ -- --
3232

33-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
33+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
3434
--> $DIR/method-call-lifetime-args-fail.rs:27:15
3535
|
3636
LL | S::late::<'static>(S, &0, &0);
@@ -42,7 +42,7 @@ note: the late bound lifetime parameter is introduced here
4242
LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
4343
| ^^
4444

45-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
45+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
4646
--> $DIR/method-call-lifetime-args-fail.rs:29:15
4747
|
4848
LL | S::late::<'static, 'static>(S, &0, &0);
@@ -54,7 +54,7 @@ note: the late bound lifetime parameter is introduced here
5454
LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
5555
| ^^
5656

57-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
57+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
5858
--> $DIR/method-call-lifetime-args-fail.rs:31:15
5959
|
6060
LL | S::late::<'static, 'static, 'static>(S, &0, &0);
@@ -66,7 +66,7 @@ note: the late bound lifetime parameter is introduced here
6666
LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
6767
| ^^
6868

69-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
69+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
7070
--> $DIR/method-call-lifetime-args-fail.rs:34:21
7171
|
7272
LL | S::late_early::<'static, 'static>(S, &0);
@@ -78,7 +78,7 @@ note: the late bound lifetime parameter is introduced here
7878
LL | fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} }
7979
| ^^
8080

81-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
81+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
8282
--> $DIR/method-call-lifetime-args-fail.rs:36:21
8383
|
8484
LL | S::late_early::<'static, 'static, 'static>(S, &0);
@@ -90,7 +90,7 @@ note: the late bound lifetime parameter is introduced here
9090
LL | fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} }
9191
| ^^
9292

93-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
93+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
9494
--> $DIR/method-call-lifetime-args-fail.rs:40:24
9595
|
9696
LL | S::late_implicit::<'static>(S, &0, &0);
@@ -102,7 +102,7 @@ note: the late bound lifetime parameter is introduced here
102102
LL | fn late_implicit(self, _: &u8, _: &u8) {}
103103
| ^
104104

105-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
105+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
106106
--> $DIR/method-call-lifetime-args-fail.rs:42:24
107107
|
108108
LL | S::late_implicit::<'static, 'static>(S, &0, &0);
@@ -114,7 +114,7 @@ note: the late bound lifetime parameter is introduced here
114114
LL | fn late_implicit(self, _: &u8, _: &u8) {}
115115
| ^
116116

117-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
117+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
118118
--> $DIR/method-call-lifetime-args-fail.rs:44:24
119119
|
120120
LL | S::late_implicit::<'static, 'static, 'static>(S, &0, &0);
@@ -126,7 +126,7 @@ note: the late bound lifetime parameter is introduced here
126126
LL | fn late_implicit(self, _: &u8, _: &u8) {}
127127
| ^
128128

129-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
129+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
130130
--> $DIR/method-call-lifetime-args-fail.rs:47:30
131131
|
132132
LL | S::late_implicit_early::<'static, 'static>(S, &0);
@@ -138,7 +138,7 @@ note: the late bound lifetime parameter is introduced here
138138
LL | fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} }
139139
| ^
140140

141-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
141+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
142142
--> $DIR/method-call-lifetime-args-fail.rs:49:30
143143
|
144144
LL | S::late_implicit_early::<'static, 'static, 'static>(S, &0);
@@ -150,7 +150,7 @@ note: the late bound lifetime parameter is introduced here
150150
LL | fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} }
151151
| ^
152152

153-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
153+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
154154
--> $DIR/method-call-lifetime-args-fail.rs:52:35
155155
|
156156
LL | S::late_implicit_self_early::<'static, 'static>(&S);
@@ -162,7 +162,7 @@ note: the late bound lifetime parameter is introduced here
162162
LL | fn late_implicit_self_early<'b>(&self) -> &'b u8 { loop {} }
163163
| ^
164164

165-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
165+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
166166
--> $DIR/method-call-lifetime-args-fail.rs:54:35
167167
|
168168
LL | S::late_implicit_self_early::<'static, 'static, 'static>(&S);
@@ -174,7 +174,7 @@ note: the late bound lifetime parameter is introduced here
174174
LL | fn late_implicit_self_early<'b>(&self) -> &'b u8 { loop {} }
175175
| ^
176176

177-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
177+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
178178
--> $DIR/method-call-lifetime-args-fail.rs:57:28
179179
|
180180
LL | S::late_unused_early::<'static, 'static>(S);
@@ -186,7 +186,7 @@ note: the late bound lifetime parameter is introduced here
186186
LL | fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} }
187187
| ^^
188188

189-
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
189+
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
190190
--> $DIR/method-call-lifetime-args-fail.rs:59:28
191191
|
192192
LL | S::late_unused_early::<'static, 'static, 'static>(S);
@@ -232,4 +232,5 @@ LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
232232

233233
error: aborting due to 18 previous errors
234234

235-
For more information about this error, try `rustc --explain E0107`.
235+
Some errors have detailed explanations: E0107, E0794.
236+
For more information about an error, try `rustc --explain E0107`.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /