Skip to content

Commit 5a20834

Browse files
committed
Add feature gate.
1 parent 3b1b38d commit 5a20834

File tree

8 files changed

+110
-4
lines changed

8 files changed

+110
-4
lines changed

compiler/rustc_feature/src/active.rs

+2
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ declare_features! (
148148
/// below (it has to be checked before expansion possibly makes
149149
/// macros disappear).
150150
(active, allow_internal_unstable, "1.0.0", None, None),
151+
/// Allows using anonymous lifetimes in argument-position impl-trait.
152+
(active, anonymous_lifetime_in_impl_trait, "1.63.0", None, None),
151153
/// Allows identifying the `compiler_builtins` crate.
152154
(active, compiler_builtins, "1.13.0", None, None),
153155
/// Outputs useful `assert!` messages

compiler/rustc_resolve/src/late/lifetimes.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -1677,14 +1677,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
16771677
break None;
16781678
}
16791679

1680-
Scope::Binder { ref lifetimes, scope_type, s, .. } => {
1680+
Scope::Binder { ref lifetimes, scope_type, s, where_bound_origin, .. } => {
16811681
if let Some(&def) = lifetimes.get(&region_def_id) {
16821682
break Some(def.shifted(late_depth));
16831683
}
16841684
match scope_type {
16851685
BinderScopeType::Normal => late_depth += 1,
16861686
BinderScopeType::Concatenating => {}
16871687
}
1688+
// Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
1689+
// regular fns.
1690+
if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
1691+
&& let hir::LifetimeName::Param(_, hir::ParamName::Fresh) = lifetime_ref.name
1692+
&& let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner)
1693+
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
1694+
{
1695+
rustc_session::parse::feature_err(
1696+
&self.tcx.sess.parse_sess,
1697+
sym::anonymous_lifetime_in_impl_trait,
1698+
lifetime_ref.span,
1699+
"anonymous lifetimes in `impl Trait` are unstable",
1700+
).emit();
1701+
return;
1702+
}
16881703
scope = s;
16891704
}
16901705

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ symbols! {
341341
always,
342342
and,
343343
and_then,
344+
anonymous_lifetime_in_impl_trait,
344345
any,
345346
append_const_msg,
346347
arbitrary_enum_discriminant,

src/test/ui/generic-associated-types/issue-95305.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// at some point in the future.
44

55
#![feature(generic_associated_types)]
6-
6+
#![feature(anonymous_lifetime_in_impl_trait)]
77
trait Foo {
88
type Item<'a>;
99
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// edition:2021
2+
// gate-test-anonymous_lifetime_in_impl_trait
3+
// Verify the behaviour of `feature(anonymous_lifetime_in_impl_trait)`.
4+
5+
fn f(_: impl Iterator<Item = &'_ ()>) {}
6+
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
7+
8+
fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
9+
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
10+
//~| ERROR missing lifetime specifier
11+
12+
// Anonymous lifetimes in async fn are already allowed.
13+
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
14+
async fn h(_: impl Iterator<Item = &'_ ()>) {}
15+
16+
// Anonymous lifetimes in async fn are already allowed.
17+
// But that lifetime does not participate in resolution.
18+
async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
19+
//~^ ERROR missing lifetime specifier
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
2+
--> $DIR/impl-trait-missing-lifetime-gated.rs:5:31
3+
|
4+
LL | fn f(_: impl Iterator<Item = &'_ ()>) {}
5+
| ^^
6+
|
7+
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
8+
9+
error[E0106]: missing lifetime specifier
10+
--> $DIR/impl-trait-missing-lifetime-gated.rs:8:50
11+
|
12+
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
13+
| ^^ expected named lifetime parameter
14+
|
15+
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
16+
help: consider using the `'static` lifetime
17+
|
18+
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
19+
| ~~~~~~~
20+
21+
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
22+
--> $DIR/impl-trait-missing-lifetime-gated.rs:8:31
23+
|
24+
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
25+
| ^^
26+
|
27+
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
28+
29+
error[E0106]: missing lifetime specifier
30+
--> $DIR/impl-trait-missing-lifetime-gated.rs:18:56
31+
|
32+
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
33+
| ^^ expected named lifetime parameter
34+
|
35+
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
36+
help: consider using the `'static` lifetime
37+
|
38+
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
39+
| ~~~~~~~
40+
41+
error: aborting due to 4 previous errors
42+
43+
Some errors have detailed explanations: E0106, E0658.
44+
For more information about an error, try `rustc --explain E0106`.
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1+
// edition:2021
2+
3+
#![feature(anonymous_lifetime_in_impl_trait)]
4+
15
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
26
fn f(_: impl Iterator<Item = &'_ ()>) {}
37

48
// But that lifetime does not participate in resolution.
59
fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
610
//~^ ERROR missing lifetime specifier
711

12+
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
13+
async fn h(_: impl Iterator<Item = &'_ ()>) {}
14+
15+
// But that lifetime does not participate in resolution.
16+
async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
17+
//~^ ERROR missing lifetime specifier
18+
819
fn main() {}

src/test/ui/suggestions/impl-trait-missing-lifetime.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0106]: missing lifetime specifier
2-
--> $DIR/impl-trait-missing-lifetime.rs:5:50
2+
--> $DIR/impl-trait-missing-lifetime.rs:9:50
33
|
44
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
55
| ^^ expected named lifetime parameter
@@ -10,6 +10,18 @@ help: consider using the `'static` lifetime
1010
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
1111
| ~~~~~~~
1212

13-
error: aborting due to previous error
13+
error[E0106]: missing lifetime specifier
14+
--> $DIR/impl-trait-missing-lifetime.rs:16:56
15+
|
16+
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
17+
| ^^ expected named lifetime parameter
18+
|
19+
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
20+
help: consider using the `'static` lifetime
21+
|
22+
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
23+
| ~~~~~~~
24+
25+
error: aborting due to 2 previous errors
1426

1527
For more information about this error, try `rustc --explain E0106`.

0 commit comments

Comments
 (0)