about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2022-06-22 22:19:02 +0200
committerCamille GILLOT <gillot.camille@gmail.com>2022-07-13 14:17:09 +0200
commit5a20834884f653e84485fb905785fdbca98b7e02 (patch)
tree8c4896f7859f481058b7b3708bae43a4a69d71fa
parent3b1b38d17f223378386f768204e4c5ad106b7c50 (diff)
downloadrust-5a20834884f653e84485fb905785fdbca98b7e02.tar.gz
rust-5a20834884f653e84485fb905785fdbca98b7e02.zip
Add feature gate.
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs17
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-95305.rs2
-rw-r--r--src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs21
-rw-r--r--src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr44
-rw-r--r--src/test/ui/suggestions/impl-trait-missing-lifetime.rs11
-rw-r--r--src/test/ui/suggestions/impl-trait-missing-lifetime.stderr16
8 files changed, 110 insertions, 4 deletions
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index b54f0ef361a..d210b9493d1 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -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
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 557dbecfabe..79688529082 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -1677,7 +1677,7 @@ 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));
                     }
@@ -1685,6 +1685,21 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                         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;
                 }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9b6967621f1..10a24a4c534 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -341,6 +341,7 @@ symbols! {
         always,
         and,
         and_then,
+        anonymous_lifetime_in_impl_trait,
         any,
         append_const_msg,
         arbitrary_enum_discriminant,
diff --git a/src/test/ui/generic-associated-types/issue-95305.rs b/src/test/ui/generic-associated-types/issue-95305.rs
index 78d4bb913b8..e2f1710fa28 100644
--- a/src/test/ui/generic-associated-types/issue-95305.rs
+++ b/src/test/ui/generic-associated-types/issue-95305.rs
@@ -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>;
 }
diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs
new file mode 100644
index 00000000000..fe291e021bc
--- /dev/null
+++ b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs
@@ -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() {}
diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
new file mode 100644
index 00000000000..9adc9679eee
--- /dev/null
+++ b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
@@ -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`.
diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime.rs b/src/test/ui/suggestions/impl-trait-missing-lifetime.rs
index 2ef0f5a4853..dcc716f56b7 100644
--- a/src/test/ui/suggestions/impl-trait-missing-lifetime.rs
+++ b/src/test/ui/suggestions/impl-trait-missing-lifetime.rs
@@ -1,3 +1,7 @@
+// edition:2021
+
+#![feature(anonymous_lifetime_in_impl_trait)]
+
 // This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
 fn f(_: impl Iterator<Item = &'_ ()>) {}
 
@@ -5,4 +9,11 @@ fn f(_: impl Iterator<Item = &'_ ()>) {}
 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() {}
diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr b/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr
index a09ef8121d7..d3c64cb466d 100644
--- a/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr
+++ b/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr
@@ -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
@@ -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`.