Skip to content

Commit 70abdc8

Browse files
committed
Stabilize anonymous_lifetime_in_impl_trait
1 parent f22a0c2 commit 70abdc8

15 files changed

+234
-131
lines changed

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -1168,9 +1168,16 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11681168
&& let hir::LifetimeName::Param(param_id) = lifetime_ref.res
11691169
&& let Some(generics) =
11701170
self.tcx.hir().get_generics(self.tcx.local_parent(param_id))
1171-
&& let Some(param) = generics.params.iter().find(|p| p.def_id == param_id)
1171+
&& let Some((param, pred)) = generics
1172+
.params
1173+
.iter()
1174+
.position(|param| param.def_id == param_id)
1175+
.and_then(|idx| {
1176+
Some((generics.params.get(idx)?, generics.predicates.get(idx)?))
1177+
})
11721178
&& param.is_elided_lifetime()
11731179
&& !self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id).is_async()
1180+
&& is_gat(pred)
11741181
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
11751182
{
11761183
let mut diag: rustc_errors::Diag<'_> = rustc_session::parse::feature_err(
@@ -2106,3 +2113,30 @@ pub fn deny_non_region_late_bound(
21062113
*arg = ResolvedArg::Error(guar);
21072114
}
21082115
}
2116+
2117+
fn is_gat(predicate: &hir::WherePredicate<'_>) -> bool {
2118+
let hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { bounds, .. }) = predicate
2119+
else {
2120+
return false;
2121+
};
2122+
for bound in *bounds {
2123+
let hir::GenericBound::Trait(poly_trait_ref, _) = bound else {
2124+
continue;
2125+
};
2126+
2127+
for segment in poly_trait_ref.trait_ref.path.segments {
2128+
let Some(generic_args) = segment.args else {
2129+
continue;
2130+
};
2131+
if !generic_args.args.is_empty() {
2132+
continue;
2133+
}
2134+
for binding in generic_args.bindings {
2135+
if !binding.gen_args.args.is_empty() {
2136+
return true;
2137+
}
2138+
}
2139+
}
2140+
}
2141+
false
2142+
}

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

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(anonymous_lifetime_in_impl_trait)]
2-
31
// The same thing should happen for constraints in dyn trait.
42
fn f(x: &mut dyn Iterator<Item: Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
53
//~^ ERROR associated type bounds are not allowed in `dyn` types

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:4:70
2+
--> $DIR/elision.rs:2: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: associated type bounds are not allowed in `dyn` types
14-
--> $DIR/elision.rs:4:27
14+
--> $DIR/elision.rs:2:27
1515
|
1616
LL | fn f(x: &mut dyn Iterator<Item: Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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,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

+9-12
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
//@ edition:2021
22
// gate-test-anonymous_lifetime_in_impl_trait
3+
34
// Verify the behaviour of `feature(anonymous_lifetime_in_impl_trait)`.
45

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

99
fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
10-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
10+
//~^ ERROR lifetime may not live long
1111
//~| ERROR missing lifetime specifier
1212

1313
// Anonymous lifetimes in async fn are already allowed.
@@ -17,16 +17,15 @@ mod elided {
1717
// Anonymous lifetimes in async fn are already allowed.
1818
// But that lifetime does not participate in resolution.
1919
async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
20-
//~^ ERROR missing lifetime specifier
21-
//~| ERROR lifetime may not live long enough
20+
//~^ ERROR lifetime may not live long
21+
//~| ERROR missing lifetime specifier
2222
}
2323

2424
mod underscore {
2525
fn f(_: impl Iterator<Item = &'_ ()>) {}
26-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
2726

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

3231
// Anonymous lifetimes in async fn are already allowed.
@@ -36,29 +35,27 @@ mod underscore {
3635
// Anonymous lifetimes in async fn are already allowed.
3736
// But that lifetime does not participate in resolution.
3837
async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
39-
//~^ ERROR missing lifetime specifier
40-
//~| ERROR lifetime may not live long enough
38+
//~^ ERROR lifetime may not live long
39+
//~| ERROR missing lifetime specifier
4140
}
4241

4342
mod alone_in_path {
4443
trait Foo<'a> { fn next(&mut self) -> Option<&'a ()>; }
4544

4645
fn f(_: impl Foo) {}
47-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
4846

4947
fn g(mut x: impl Foo) -> Option<&()> { x.next() }
50-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
48+
//~^ ERROR lifetime may not live long
5149
//~| ERROR missing lifetime specifier
5250
}
5351

5452
mod in_path {
5553
trait Foo<'a, T> { fn next(&mut self) -> Option<&'a T>; }
5654

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

6057
fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
61-
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
58+
//~^ ERROR lifetime may not live long
6259
//~| ERROR missing lifetime specifier
6360
}
6461

0 commit comments

Comments
 (0)