Skip to content

Commit 23d76b8

Browse files
committed
Stabilize anonymous_lifetime_in_impl_trait
1 parent ffb7ed9 commit 23d76b8

18 files changed

+270
-266
lines changed

compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ declare_features! (
5454
(accepted, abi_thiscall, "1.73.0", None, None),
5555
/// Allows using ADX intrinsics from `core::arch::{x86, x86_64}`.
5656
(accepted, adx_target_feature, "1.61.0", Some(44839), None),
57+
/// Allows using anonymous lifetimes in argument-position impl-trait.
58+
(accepted, anonymous_lifetime_in_impl_trait, "CURRENT_RUSTC_VERSION", None, None),
5759
/// Allows explicit discriminants on non-unit enum variants.
5860
(accepted, arbitrary_enum_discriminant, "1.66.0", Some(60553), None),
5961
/// Allows using `sym` operands in inline assembly.

compiler/rustc_feature/src/unstable.rs

-2
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,6 @@ declare_features! (
175175
/// below (it has to be checked before expansion possibly makes
176176
/// macros disappear).
177177
(internal, allow_internal_unstable, "1.0.0", None, None),
178-
/// Allows using anonymous lifetimes in argument-position impl-trait.
179-
(unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None, None),
180178
/// Allows identifying the `compiler_builtins` crate.
181179
(internal, compiler_builtins, "1.13.0", None, None),
182180
/// Allows writing custom MIR

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+2-63
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_middle::query::Providers;
2121
use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
2222
use rustc_session::lint;
2323
use rustc_span::def_id::DefId;
24-
use rustc_span::symbol::{sym, Ident};
24+
use rustc_span::symbol::Ident;
2525
use rustc_span::{Span, DUMMY_SP};
2626
use std::fmt;
2727

@@ -1199,75 +1199,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11991199
break None;
12001200
}
12011201

1202-
Scope::Binder { ref bound_vars, scope_type, s, where_bound_origin, .. } => {
1202+
Scope::Binder { ref bound_vars, scope_type, s, .. } => {
12031203
if let Some(&def) = bound_vars.get(&region_def_id) {
12041204
break Some(def.shifted(late_depth));
12051205
}
12061206
match scope_type {
12071207
BinderScopeType::Normal => late_depth += 1,
12081208
BinderScopeType::Concatenating => {}
12091209
}
1210-
// Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
1211-
// regular fns.
1212-
if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
1213-
&& let hir::LifetimeName::Param(param_id) = lifetime_ref.res
1214-
&& let Some(generics) =
1215-
self.tcx.hir().get_generics(self.tcx.local_parent(param_id))
1216-
&& let Some(param) = generics.params.iter().find(|p| p.def_id == param_id)
1217-
&& param.is_elided_lifetime()
1218-
&& !self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id).is_async()
1219-
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
1220-
{
1221-
let mut diag = rustc_session::parse::feature_err(
1222-
&self.tcx.sess.parse_sess,
1223-
sym::anonymous_lifetime_in_impl_trait,
1224-
lifetime_ref.ident.span,
1225-
"anonymous lifetimes in `impl Trait` are unstable",
1226-
);
1227-
1228-
if let Some(generics) =
1229-
self.tcx.hir().get_generics(lifetime_ref.hir_id.owner.def_id)
1230-
{
1231-
let new_param_sugg =
1232-
if let Some(span) = generics.span_for_lifetime_suggestion() {
1233-
(span, "'a, ".to_owned())
1234-
} else {
1235-
(generics.span, "<'a>".to_owned())
1236-
};
1237-
1238-
let lifetime_sugg = match lifetime_ref.suggestion_position() {
1239-
(hir::LifetimeSuggestionPosition::Normal, span) => {
1240-
(span, "'a".to_owned())
1241-
}
1242-
(hir::LifetimeSuggestionPosition::Ampersand, span) => {
1243-
(span, "'a ".to_owned())
1244-
}
1245-
(hir::LifetimeSuggestionPosition::ElidedPath, span) => {
1246-
(span, "<'a>".to_owned())
1247-
}
1248-
(hir::LifetimeSuggestionPosition::ElidedPathArgument, span) => {
1249-
(span, "'a, ".to_owned())
1250-
}
1251-
(hir::LifetimeSuggestionPosition::ObjectDefault, span) => {
1252-
(span, "+ 'a".to_owned())
1253-
}
1254-
};
1255-
let suggestions = vec![lifetime_sugg, new_param_sugg];
1256-
1257-
diag.span_label(
1258-
lifetime_ref.ident.span,
1259-
"expected named lifetime parameter",
1260-
);
1261-
diag.multipart_suggestion(
1262-
"consider introducing a named lifetime parameter",
1263-
suggestions,
1264-
rustc_errors::Applicability::MaybeIncorrect,
1265-
);
1266-
}
1267-
1268-
diag.emit();
1269-
return;
1270-
}
12711210
scope = s;
12721211
}
12731212

tests/ui/associated-type-bounds/elision.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#![feature(associated_type_bounds)]
2-
#![feature(anonymous_lifetime_in_impl_trait)]
32

43
// The same thing should happen for constraints in dyn trait.
54
fn f(x: &mut dyn Iterator<Item: Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }

tests/ui/associated-type-bounds/elision.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0106]: missing lifetime specifier
2-
--> $DIR/elision.rs:5:70
2+
--> $DIR/elision.rs:4:70
33
|
44
LL | fn f(x: &mut dyn Iterator<Item: Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
55
| ------------------------------------------------ ^^ expected named lifetime parameter
@@ -11,7 +11,7 @@ LL | fn f<'a>(x: &'a mut dyn Iterator<Item: Iterator<Item = &'a ()>>) -> Option<
1111
| ++++ ++ ~~ ~~
1212

1313
error[E0308]: mismatched types
14-
--> $DIR/elision.rs:5:79
14+
--> $DIR/elision.rs:4:79
1515
|
1616
LL | fn f(x: &mut dyn Iterator<Item: Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
1717
| ----------------------------- -------------- ^^^^^^^^ expected `Option<&()>`, found `Option<impl Iterator<Item = &'_ ()>>`

tests/ui/borrowck/anonymous-region-in-apit.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(anonymous_lifetime_in_impl_trait)]
2-
31
trait Foo<T> {
42
fn bar(self, baz: T);
53
}

tests/ui/borrowck/anonymous-region-in-apit.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0521]: borrowed data escapes outside of closure
2-
--> $DIR/anonymous-region-in-apit.rs:8:17
2+
--> $DIR/anonymous-region-in-apit.rs:6:17
33
|
44
LL | fn qux(foo: impl Foo<&str>) {
55
| --- lifetime `'2` appears in the type of `foo`

tests/ui/generic-associated-types/issue-95305.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Forbid it for now but proper support might be added
33
// at some point in the future.
44

5-
#![feature(anonymous_lifetime_in_impl_trait)]
65
trait Foo {
76
type Item<'a>;
87
}

tests/ui/generic-associated-types/issue-95305.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0637]: `'_` cannot be used here
2-
--> $DIR/issue-95305.rs:10:26
2+
--> $DIR/issue-95305.rs:9:26
33
|
44
LL | fn foo(x: &impl Foo<Item<'_> = u32>) { }
55
| ^^ `'_` is a reserved lifetime name
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
trait FooBar<'a> {
2+
type Item;
3+
}
4+
5+
trait LendingIterator {
6+
type Item<'a>
7+
where
8+
Self: 'a;
9+
10+
fn iter(&mut self) -> Option<Self::Item<'_>>;
11+
}
12+
13+
fn main() {
14+
fn foo0(_: impl FooBar<_, Item = &u32>) {}
15+
//~^ the placeholder `_` is not allowed within types
16+
//~| trait takes 0 generic arguments but 1 generic
17+
fn foo1(_: impl LendingIterator<Item<'_> = &u32>) {}
18+
//~^ '_` cannot be used here [E0637]
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error[E0637]: `'_` cannot be used here
2+
--> $DIR/impl-trait-invalid-anon-lifetimes.rs:17:42
3+
|
4+
LL | fn foo1(_: impl LendingIterator<Item<'_> = &u32>) {}
5+
| ^^ `'_` is a reserved lifetime name
6+
7+
error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
8+
--> $DIR/impl-trait-invalid-anon-lifetimes.rs:14:21
9+
|
10+
LL | fn foo0(_: impl FooBar<_, Item = &u32>) {}
11+
| ^^^^^^ - help: remove this generic argument
12+
| |
13+
| expected 0 generic arguments
14+
|
15+
note: trait defined here, with 0 generic parameters
16+
--> $DIR/impl-trait-invalid-anon-lifetimes.rs:1:7
17+
|
18+
LL | trait FooBar<'a> {
19+
| ^^^^^^
20+
21+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
22+
--> $DIR/impl-trait-invalid-anon-lifetimes.rs:14:28
23+
|
24+
LL | fn foo0(_: impl FooBar<_, Item = &u32>) {}
25+
| ^ not allowed in type signatures
26+
|
27+
help: use type parameters instead
28+
|
29+
LL | fn foo0<T>(_: impl FooBar<T, Item = &u32>) {}
30+
| +++ ~
31+
32+
error: aborting due to 3 previous errors
33+
34+
Some errors have detailed explanations: E0107, E0121, E0637.
35+
For more information about an error, try `rustc --explain E0107`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
trait Foo<T> {
2+
fn foo(&self, _: T) { }
3+
}
4+
5+
trait FooBar<'a> {
6+
type Item;
7+
}
8+
9+
10+
mod foo {
11+
fn fun(t: impl crate::Foo<&u32>, n: u32) {
12+
t.foo(&n);
13+
//~^ ERROR `n` does not live long enough
14+
}
15+
}
16+
17+
mod fun {
18+
fn fun(t: impl Fn(&u32), n: u32) {
19+
t(&n);
20+
}
21+
}
22+
23+
mod iterator_fun {
24+
fn fun(t: impl Iterator<Item = impl Fn(&u32)>, n: u32) {
25+
for elem in t {
26+
elem(&n);
27+
}
28+
}
29+
}
30+
31+
mod iterator_foo {
32+
fn fun(t: impl Iterator<Item = impl crate::Foo<&u32>>, n: u32) {
33+
for elem in t {
34+
elem.foo(&n);
35+
//~^ ERROR `n` does not live long enough
36+
}
37+
}
38+
}
39+
40+
mod placeholder {
41+
trait Placeholder<'a> {
42+
fn foo(&self, _: &'a u32) {}
43+
}
44+
45+
fn fun(t: impl Placeholder<'_>, n: u32) {
46+
t.foo(&n);
47+
//~^ ERROR `n` does not live long enough
48+
}
49+
}
50+
51+
mod stabilized {
52+
trait InTrait {
53+
fn in_trait(&self) -> impl Iterator<Item = &u32>;
54+
}
55+
56+
fn foo1(_: impl Iterator<Item = &u32>) {}
57+
fn foo2<'b>(_: impl crate::FooBar<'b, Item = &u32>) {}
58+
}
59+
60+
fn main() {
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
error[E0597]: `n` does not live long enough
2+
--> $DIR/impl-trait-lifetimes.rs:12:15
3+
|
4+
LL | fn fun(t: impl crate::Foo<&u32>, n: u32) {
5+
| - has type `t` - binding `n` declared here
6+
LL | t.foo(&n);
7+
| ------^^-
8+
| | |
9+
| | borrowed value does not live long enough
10+
| argument requires that `n` is borrowed for `'1`
11+
LL |
12+
LL | }
13+
| - `n` dropped here while still borrowed
14+
15+
error[E0597]: `n` does not live long enough
16+
--> $DIR/impl-trait-lifetimes.rs:34:22
17+
|
18+
LL | fn fun(t: impl Iterator<Item = impl crate::Foo<&u32>>, n: u32) {
19+
| - binding `n` declared here
20+
LL | for elem in t {
21+
LL | elem.foo(&n);
22+
| ^^ borrowed value does not live long enough
23+
...
24+
LL | }
25+
| - `n` dropped here while still borrowed
26+
27+
error[E0597]: `n` does not live long enough
28+
--> $DIR/impl-trait-lifetimes.rs:46:15
29+
|
30+
LL | fn fun(t: impl Placeholder<'_>, n: u32) {
31+
| - has type `t` - binding `n` declared here
32+
LL | t.foo(&n);
33+
| ------^^-
34+
| | |
35+
| | borrowed value does not live long enough
36+
| argument requires that `n` is borrowed for `'1`
37+
LL |
38+
LL | }
39+
| - `n` dropped here while still borrowed
40+
41+
error: aborting due to 3 previous errors
42+
43+
For more information about this error, try `rustc --explain E0597`.

tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs tests/ui/impl-trait/impl-trait-missing-lifetime-gated.rs

+10-16
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44

55
mod elided {
66
fn f(_: impl Iterator<Item = &()>) {}
7-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
87

98
fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
10-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
11-
//~| ERROR missing lifetime specifier
9+
//~^ ERROR missing lifetime specifier
1210

1311
// Anonymous lifetimes in async fn are already allowed.
1412
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
@@ -17,16 +15,15 @@ mod elided {
1715
// Anonymous lifetimes in async fn are already allowed.
1816
// But that lifetime does not participate in resolution.
1917
async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
20-
//~^ ERROR missing lifetime specifier
18+
//~^ ERROR lifetime may not live long
19+
//~| ERROR missing lifetime specifier
2120
}
2221

2322
mod underscore {
2423
fn f(_: impl Iterator<Item = &'_ ()>) {}
25-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
2624

2725
fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
28-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
29-
//~| ERROR missing lifetime specifier
26+
//~^ ERROR missing lifetime specifier
3027

3128
// Anonymous lifetimes in async fn are already allowed.
3229
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
@@ -35,34 +32,31 @@ mod underscore {
3532
// Anonymous lifetimes in async fn are already allowed.
3633
// But that lifetime does not participate in resolution.
3734
async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
38-
//~^ ERROR missing lifetime specifier
35+
//~^ ERROR lifetime may not live long
36+
//~| ERROR missing lifetime specifier
3937
}
4038

4139
mod alone_in_path {
4240
trait Foo<'a> { fn next(&mut self) -> Option<&'a ()>; }
4341

4442
fn f(_: impl Foo) {}
45-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
4643

4744
fn g(mut x: impl Foo) -> Option<&()> { x.next() }
48-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
49-
//~| ERROR missing lifetime specifier
45+
//~^ ERROR missing lifetime specifier
5046
}
5147

5248
mod in_path {
5349
trait Foo<'a, T> { fn next(&mut self) -> Option<&'a T>; }
5450

5551
fn f(_: impl Foo<()>) {}
56-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
5752

5853
fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
59-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
60-
//~| ERROR missing lifetime specifier
54+
//~^ ERROR missing lifetime specifier
6155
}
6256

6357
// This must not err, as the `&` actually resolves to `'a`.
64-
fn resolved_anonymous<'a, T>(f: impl Fn(&'a str) -> &T) {
65-
f("f")
58+
fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) {
59+
f("f");
6660
}
6761

6862
fn main() {}

0 commit comments

Comments
 (0)