Skip to content

Commit efad34f

Browse files
committed
Stabilize anonymous_lifetime_in_impl_trait
1 parent e3c631b commit efad34f

16 files changed

+202
-259
lines changed

compiler/rustc_feature/src/accepted.rs

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

compiler/rustc_feature/src/active.rs

-2
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,6 @@ declare_features! (
172172
/// below (it has to be checked before expansion possibly makes
173173
/// macros disappear).
174174
(internal, allow_internal_unstable, "1.0.0", None, None),
175-
/// Allows using anonymous lifetimes in argument-position impl-trait.
176-
(active, anonymous_lifetime_in_impl_trait, "1.63.0", None, None),
177175
/// Allows identifying the `compiler_builtins` crate.
178176
(internal, compiler_builtins, "1.13.0", None, None),
179177
/// Allows writing custom MIR

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+2-56
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

@@ -1197,68 +1197,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11971197
break None;
11981198
}
11991199

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

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,47 @@
1+
trait Foo<T> {
2+
fn foo(&self, _: T) { }
3+
}
4+
5+
mod foo {
6+
fn fun(t: impl crate::Foo<&u32>, n: u32) {
7+
t.foo(&n);
8+
//~^ ERROR `n` does not live long enough
9+
}
10+
}
11+
12+
mod fun {
13+
fn fun(t: impl Fn(&u32), n: u32) {
14+
t(&n);
15+
}
16+
}
17+
18+
mod iterator_fun {
19+
fn fun(t: impl Iterator<Item = impl Fn(&u32)>, n: u32) {
20+
for elem in t {
21+
elem(&n);
22+
}
23+
}
24+
}
25+
26+
mod iterator_foo {
27+
fn fun(t: impl Iterator<Item = impl crate::Foo<&u32>>, n: u32) {
28+
for elem in t {
29+
elem.foo(&n);
30+
//~^ ERROR `n` does not live long enough
31+
}
32+
}
33+
}
34+
35+
mod placeholder {
36+
trait Placeholder<'a> {
37+
fn foo(&self, _: &'a u32) {}
38+
}
39+
40+
fn fun(t: impl Placeholder<'_>, n: u32) {
41+
t.foo(&n);
42+
//~^ ERROR `n` does not live long enough
43+
}
44+
}
45+
46+
fn main() {
47+
}
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:7: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:29: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:41: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 renamed to 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)