about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-12-10 15:51:39 +0000
committerbors <bors@rust-lang.org>2023-12-10 15:51:39 +0000
commitb9068315db4812abbbef317447e47e0c62d3652f (patch)
treeb785d6c9b78c2ca7c139b5e1a1030deefc040047
parentbefd1eb4ec78e19f0c8628fa75241ea3ed6ec792 (diff)
parent803772e81d1245a4d1eebcea5484b1f78ba5aca6 (diff)
downloadrust-b9068315db4812abbbef317447e47e0c62d3652f.tar.gz
rust-b9068315db4812abbbef317447e47e0c62d3652f.zip
Auto merge of #116952 - compiler-errors:lifetime_capture_rules_2024, r=TaKO8Ki
Implement 2024-edition lifetime capture rules RFC

Implements rust-lang/rfcs#3498.
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs7
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.stderr18
-rw-r--r--tests/ui/impl-trait/implicit-capture-late.rs14
-rw-r--r--tests/ui/impl-trait/implicit-capture-late.stderr9
-rw-r--r--tests/ui/impl-trait/variance.e2024.stderr26
-rw-r--r--tests/ui/impl-trait/variance.new.stderr26
-rw-r--r--tests/ui/impl-trait/variance.old.stderr (renamed from tests/ui/impl-trait/variance.stderr)8
-rw-r--r--tests/ui/impl-trait/variance.rs16
11 files changed, 125 insertions, 8 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index a005a6e44ce..d9663d50c59 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1574,8 +1574,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 Vec::new()
             }
             hir::OpaqueTyOrigin::FnReturn(..) => {
-                if let FnDeclKind::Impl | FnDeclKind::Trait =
-                    fn_kind.expect("expected RPITs to be lowered with a FnKind")
+                if matches!(
+                    fn_kind.expect("expected RPITs to be lowered with a FnKind"),
+                    FnDeclKind::Impl | FnDeclKind::Trait
+                ) || self.tcx.features().lifetime_capture_rules_2024
+                    || span.at_least_rust_2024()
                 {
                     // return-position impl trait in trait was decided to capture all
                     // in-scope lifetimes, which we collect for all opaques during resolution.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index e68ab017380..365a16e6838 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -206,6 +206,8 @@ declare_features! (
     (internal, intrinsics, "1.0.0", None, None),
     /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
     (internal, lang_items, "1.0.0", None, None),
+    /// Changes `impl Trait` to capture all lifetimes in scope.
+    (unstable, lifetime_capture_rules_2024, "CURRENT_RUSTC_VERSION", None, None),
     /// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406
     (unstable, link_cfg, "1.14.0", None, None),
     /// Allows the `multiple_supertrait_upcastable` lint.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 485265e6889..9ad76b74c38 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -933,6 +933,7 @@ symbols! {
         lib,
         libc,
         lifetime,
+        lifetime_capture_rules_2024,
         lifetimes,
         likely,
         line,
diff --git a/tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.rs b/tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.rs
new file mode 100644
index 00000000000..c06107e66a7
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.rs
@@ -0,0 +1,6 @@
+fn foo(x: &Vec<i32>) -> impl Sized {
+    x
+    //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.stderr b/tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.stderr
new file mode 100644
index 00000000000..173e3dc02cc
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.stderr
@@ -0,0 +1,18 @@
+error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
+  --> $DIR/feature-gate-lifetime-capture-rules-2024.rs:2:5
+   |
+LL | fn foo(x: &Vec<i32>) -> impl Sized {
+   |           ---------     ---------- opaque type defined here
+   |           |
+   |           hidden type `&Vec<i32>` captures the anonymous lifetime defined here
+LL |     x
+   |     ^
+   |
+help: to declare that `impl Sized` captures `'_`, you can add an explicit `'_` lifetime bound
+   |
+LL | fn foo(x: &Vec<i32>) -> impl Sized + '_ {
+   |                                    ++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/impl-trait/implicit-capture-late.rs b/tests/ui/impl-trait/implicit-capture-late.rs
new file mode 100644
index 00000000000..8bfb16760c9
--- /dev/null
+++ b/tests/ui/impl-trait/implicit-capture-late.rs
@@ -0,0 +1,14 @@
+// known-bug: #117647
+
+#![feature(lifetime_capture_rules_2024)]
+#![feature(rustc_attrs)]
+#![allow(internal_features)]
+#![rustc_variance_of_opaques]
+
+use std::ops::Deref;
+
+fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
+    Box::new(x)
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/implicit-capture-late.stderr b/tests/ui/impl-trait/implicit-capture-late.stderr
new file mode 100644
index 00000000000..9b3a4ff5f42
--- /dev/null
+++ b/tests/ui/impl-trait/implicit-capture-late.stderr
@@ -0,0 +1,9 @@
+error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
+  --> $DIR/implicit-capture-late.rs:10:36
+   |
+LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
+   |                                    ^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0657`.
diff --git a/tests/ui/impl-trait/variance.e2024.stderr b/tests/ui/impl-trait/variance.e2024.stderr
new file mode 100644
index 00000000000..17245055744
--- /dev/null
+++ b/tests/ui/impl-trait/variance.e2024.stderr
@@ -0,0 +1,26 @@
+error: [*, o]
+  --> $DIR/variance.rs:14:36
+   |
+LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
+   |                                    ^^^^^^^^^^
+
+error: [*, o]
+  --> $DIR/variance.rs:19:32
+   |
+LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: [o]
+  --> $DIR/variance.rs:21:40
+   |
+LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
+   |                                        ^^^^^^^^^^
+
+error: [o]
+  --> $DIR/variance.rs:26:36
+   |
+LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/impl-trait/variance.new.stderr b/tests/ui/impl-trait/variance.new.stderr
new file mode 100644
index 00000000000..17245055744
--- /dev/null
+++ b/tests/ui/impl-trait/variance.new.stderr
@@ -0,0 +1,26 @@
+error: [*, o]
+  --> $DIR/variance.rs:14:36
+   |
+LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
+   |                                    ^^^^^^^^^^
+
+error: [*, o]
+  --> $DIR/variance.rs:19:32
+   |
+LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: [o]
+  --> $DIR/variance.rs:21:40
+   |
+LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
+   |                                        ^^^^^^^^^^
+
+error: [o]
+  --> $DIR/variance.rs:26:36
+   |
+LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/impl-trait/variance.stderr b/tests/ui/impl-trait/variance.old.stderr
index 64473675410..9410b54b491 100644
--- a/tests/ui/impl-trait/variance.stderr
+++ b/tests/ui/impl-trait/variance.old.stderr
@@ -1,23 +1,23 @@
 error: [*]
-  --> $DIR/variance.rs:8:36
+  --> $DIR/variance.rs:14:36
    |
 LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
    |                                    ^^^^^^^^^^
 
 error: [*, o]
-  --> $DIR/variance.rs:10:32
+  --> $DIR/variance.rs:19:32
    |
 LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: []
-  --> $DIR/variance.rs:12:40
+  --> $DIR/variance.rs:21:40
    |
 LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
    |                                        ^^^^^^^^^^
 
 error: [o]
-  --> $DIR/variance.rs:14:36
+  --> $DIR/variance.rs:26:36
    |
 LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/impl-trait/variance.rs b/tests/ui/impl-trait/variance.rs
index d6212f8f393..86da1908509 100644
--- a/tests/ui/impl-trait/variance.rs
+++ b/tests/ui/impl-trait/variance.rs
@@ -1,3 +1,9 @@
+// revisions: old new e2024
+//[e2024] edition: 2024
+//[e2024] compile-flags: -Z unstable-options
+
+#![cfg_attr(new, feature(lifetime_capture_rules_2024))]
+
 #![feature(rustc_attrs)]
 #![allow(internal_features)]
 #![rustc_variance_of_opaques]
@@ -5,11 +11,17 @@
 trait Captures<'a> {}
 impl<T> Captures<'_> for T {}
 
-fn not_captured_early<'a: 'a>() -> impl Sized {} //~ [*]
+fn not_captured_early<'a: 'a>() -> impl Sized {}
+//[old]~^ [*]
+//[new]~^^ [*, o]
+//[e2024]~^^^ [*, o]
 
 fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [*, o]
 
-fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} //~ []
+fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
+//[old]~^ []
+//[new]~^^ [o]
+//[e2024]~^^^ [o]
 
 fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o]