Skip to content

Commit

Permalink
Add feature gate.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Jul 13, 2022
1 parent 3b1b38d commit 5a20834
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 4 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ declare_features! (
/// below (it has to be checked before expansion possibly makes
/// macros disappear).
(active, allow_internal_unstable, "1.0.0", None, None),
/// Allows using anonymous lifetimes in argument-position impl-trait.
(active, anonymous_lifetime_in_impl_trait, "1.63.0", None, None),
/// Allows identifying the `compiler_builtins` crate.
(active, compiler_builtins, "1.13.0", None, None),
/// Outputs useful `assert!` messages
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_resolve/src/late/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1677,14 +1677,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
break None;
}

Scope::Binder { ref lifetimes, scope_type, s, .. } => {
Scope::Binder { ref lifetimes, scope_type, s, where_bound_origin, .. } => {
if let Some(&def) = lifetimes.get(&region_def_id) {
break Some(def.shifted(late_depth));
}
match scope_type {
BinderScopeType::Normal => late_depth += 1,
BinderScopeType::Concatenating => {}
}
// Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
// regular fns.
if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
&& let hir::LifetimeName::Param(_, hir::ParamName::Fresh) = lifetime_ref.name
&& let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner)
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
{
rustc_session::parse::feature_err(
&self.tcx.sess.parse_sess,
sym::anonymous_lifetime_in_impl_trait,
lifetime_ref.span,
"anonymous lifetimes in `impl Trait` are unstable",
).emit();
return;
}
scope = s;
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ symbols! {
always,
and,
and_then,
anonymous_lifetime_in_impl_trait,
any,
append_const_msg,
arbitrary_enum_discriminant,
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/generic-associated-types/issue-95305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// at some point in the future.

#![feature(generic_associated_types)]

#![feature(anonymous_lifetime_in_impl_trait)]
trait Foo {
type Item<'a>;
}
Expand Down
21 changes: 21 additions & 0 deletions src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// edition:2021
// gate-test-anonymous_lifetime_in_impl_trait
// Verify the behaviour of `feature(anonymous_lifetime_in_impl_trait)`.

fn f(_: impl Iterator<Item = &'_ ()>) {}
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable

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

// Anonymous lifetimes in async fn are already allowed.
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
async fn h(_: impl Iterator<Item = &'_ ()>) {}

// Anonymous lifetimes in async fn are already allowed.
// But that lifetime does not participate in resolution.
async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
//~^ ERROR missing lifetime specifier

fn main() {}
44 changes: 44 additions & 0 deletions src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
--> $DIR/impl-trait-missing-lifetime-gated.rs:5:31
|
LL | fn f(_: impl Iterator<Item = &'_ ()>) {}
| ^^
|
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable

error[E0106]: missing lifetime specifier
--> $DIR/impl-trait-missing-lifetime-gated.rs:8:50
|
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'static` lifetime
|
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
| ~~~~~~~

error[E0658]: anonymous lifetimes in `impl Trait` are unstable
--> $DIR/impl-trait-missing-lifetime-gated.rs:8:31
|
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
| ^^
|
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable

error[E0106]: missing lifetime specifier
--> $DIR/impl-trait-missing-lifetime-gated.rs:18:56
|
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'static` lifetime
|
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
| ~~~~~~~

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0106, E0658.
For more information about an error, try `rustc --explain E0106`.
11 changes: 11 additions & 0 deletions src/test/ui/suggestions/impl-trait-missing-lifetime.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
// edition:2021

#![feature(anonymous_lifetime_in_impl_trait)]

// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
fn f(_: impl Iterator<Item = &'_ ()>) {}

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

// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
async fn h(_: impl Iterator<Item = &'_ ()>) {}

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

fn main() {}
16 changes: 14 additions & 2 deletions src/test/ui/suggestions/impl-trait-missing-lifetime.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0106]: missing lifetime specifier
--> $DIR/impl-trait-missing-lifetime.rs:5:50
--> $DIR/impl-trait-missing-lifetime.rs:9:50
|
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
| ^^ expected named lifetime parameter
Expand All @@ -10,6 +10,18 @@ help: consider using the `'static` lifetime
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
| ~~~~~~~

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

error: aborting due to 2 previous errors

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

0 comments on commit 5a20834

Please sign in to comment.