From 0ad160a585672512303523c33e144092709459e6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 19 Oct 2023 19:00:18 +0000 Subject: [PATCH 1/3] Add lifetime_capture_rules_2024 --- compiler/rustc_ast_lowering/src/lib.rs | 6 +++-- compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + ...eature-gate-lifetime-capture-rules-2024.rs | 6 +++++ ...re-gate-lifetime-capture-rules-2024.stderr | 18 +++++++++++++ tests/ui/impl-trait/variance.new.stderr | 26 +++++++++++++++++++ .../{variance.stderr => variance.old.stderr} | 8 +++--- tests/ui/impl-trait/variance.rs | 12 +++++++-- 8 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.rs create mode 100644 tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.stderr create mode 100644 tests/ui/impl-trait/variance.new.stderr rename tests/ui/impl-trait/{variance.stderr => variance.old.stderr} (83%) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index aa8ad9784513d..241b47046fe41 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1571,8 +1571,10 @@ 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 { // 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 1d4fa9c75d9d1..2d70e112ed03e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -195,6 +195,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 d7e822382ef92..121d975409900 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -929,6 +929,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 0000000000000..c06107e66a76c --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-lifetime-capture-rules-2024.rs @@ -0,0 +1,6 @@ +fn foo(x: &Vec) -> 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 0000000000000..173e3dc02cc89 --- /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) -> impl Sized { + | --------- ---------- opaque type defined here + | | + | hidden type `&Vec` 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) -> 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/variance.new.stderr b/tests/ui/impl-trait/variance.new.stderr new file mode 100644 index 0000000000000..abf4b1ac2104e --- /dev/null +++ b/tests/ui/impl-trait/variance.new.stderr @@ -0,0 +1,26 @@ +error: [*, o] + --> $DIR/variance.rs:12:36 + | +LL | fn not_captured_early<'a: 'a>() -> impl Sized {} + | ^^^^^^^^^^ + +error: [*, o] + --> $DIR/variance.rs:16:32 + | +LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: [o] + --> $DIR/variance.rs:18:40 + | +LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} + | ^^^^^^^^^^ + +error: [o] + --> $DIR/variance.rs:22: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 similarity index 83% rename from tests/ui/impl-trait/variance.stderr rename to tests/ui/impl-trait/variance.old.stderr index 6447367541097..8b4d6314359e0 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:12:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: [*, o] - --> $DIR/variance.rs:10:32 + --> $DIR/variance.rs:16:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [] - --> $DIR/variance.rs:12:40 + --> $DIR/variance.rs:18:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:14:36 + --> $DIR/variance.rs:22: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 d6212f8f39372..e111d37761f4b 100644 --- a/tests/ui/impl-trait/variance.rs +++ b/tests/ui/impl-trait/variance.rs @@ -1,3 +1,7 @@ +// revisions: old new + +#![cfg_attr(new, feature(lifetime_capture_rules_2024))] + #![feature(rustc_attrs)] #![allow(internal_features)] #![rustc_variance_of_opaques] @@ -5,11 +9,15 @@ trait Captures<'a> {} impl Captures<'_> for T {} -fn not_captured_early<'a: 'a>() -> impl Sized {} //~ [*] +fn not_captured_early<'a: 'a>() -> impl Sized {} +//[old]~^ [*] +//[new]~^^ [*, 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] fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o] From acba7efe1ba688cac04810406ca27dbab60520fd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 19 Oct 2023 19:01:59 +0000 Subject: [PATCH 2/3] Add test for implicitly capturing late-bound var with new capture rules --- tests/ui/impl-trait/implicit-capture-late.rs | 14 ++++++++++++++ tests/ui/impl-trait/implicit-capture-late.stderr | 9 +++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/ui/impl-trait/implicit-capture-late.rs create mode 100644 tests/ui/impl-trait/implicit-capture-late.stderr 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 0000000000000..8bfb16760c918 --- /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) -> Box Deref> { + 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 0000000000000..9b3a4ff5f4250 --- /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) -> Box Deref> { + | ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0657`. From 803772e81d1245a4d1eebcea5484b1f78ba5aca6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 7 Nov 2023 00:07:57 +0000 Subject: [PATCH 3/3] Enable new capture rules by default on edition 2024 --- compiler/rustc_ast_lowering/src/lib.rs | 1 + tests/ui/impl-trait/variance.e2024.stderr | 26 +++++++++++++++++++++++ tests/ui/impl-trait/variance.new.stderr | 8 +++---- tests/ui/impl-trait/variance.old.stderr | 8 +++---- tests/ui/impl-trait/variance.rs | 6 +++++- 5 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 tests/ui/impl-trait/variance.e2024.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 241b47046fe41..72adcac679b8c 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1575,6 +1575,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { 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/tests/ui/impl-trait/variance.e2024.stderr b/tests/ui/impl-trait/variance.e2024.stderr new file mode 100644 index 0000000000000..1724505574413 --- /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 index abf4b1ac2104e..1724505574413 100644 --- a/tests/ui/impl-trait/variance.new.stderr +++ b/tests/ui/impl-trait/variance.new.stderr @@ -1,23 +1,23 @@ error: [*, o] - --> $DIR/variance.rs:12:36 + --> $DIR/variance.rs:14:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: [*, o] - --> $DIR/variance.rs:16:32 + --> $DIR/variance.rs:19:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:18:40 + --> $DIR/variance.rs:21:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:22:36 + --> $DIR/variance.rs:26:36 | LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/variance.old.stderr b/tests/ui/impl-trait/variance.old.stderr index 8b4d6314359e0..9410b54b491a8 100644 --- a/tests/ui/impl-trait/variance.old.stderr +++ b/tests/ui/impl-trait/variance.old.stderr @@ -1,23 +1,23 @@ error: [*] - --> $DIR/variance.rs:12:36 + --> $DIR/variance.rs:14:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: [*, o] - --> $DIR/variance.rs:16:32 + --> $DIR/variance.rs:19:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [] - --> $DIR/variance.rs:18:40 + --> $DIR/variance.rs:21:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:22: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 e111d37761f4b..86da1908509fd 100644 --- a/tests/ui/impl-trait/variance.rs +++ b/tests/ui/impl-trait/variance.rs @@ -1,4 +1,6 @@ -// revisions: old new +// revisions: old new e2024 +//[e2024] edition: 2024 +//[e2024] compile-flags: -Z unstable-options #![cfg_attr(new, feature(lifetime_capture_rules_2024))] @@ -12,12 +14,14 @@ impl Captures<'_> for T {} 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 {} //[old]~^ [] //[new]~^^ [o] +//[e2024]~^^^ [o] fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o]