diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 4f71bdaca1b13..95b33890d69ee 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -224,6 +224,8 @@ declare_features! ( (accepted, i128_type, "1.26.0", Some(35118)), /// Allows the use of `if let` expressions. (accepted, if_let, "1.0.0", None), + /// Rescoping temporaries in `if let` to align with Rust 2024. + (accepted, if_let_rescope, "CURRENT_RUSTC_VERSION", Some(124085)), /// Allows top level or-patterns (`p | q`) in `if let` and `while let`. (accepted, if_while_or_patterns, "1.33.0", Some(48215)), /// Allows lifetime elision in `impl` headers. For example: diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8f4c208f1fbb5..63c43c41ca699 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -482,8 +482,6 @@ declare_features! ( (unstable, half_open_range_patterns_in_slices, "1.66.0", Some(67264)), /// Allows `if let` guard in match arms. (unstable, if_let_guard, "1.47.0", Some(51114)), - /// Rescoping temporaries in `if let` to align with Rust 2024. - (unstable, if_let_rescope, "1.83.0", Some(124085)), /// Allows `impl Trait` to be used inside associated types (RFC 2515). (unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)), /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 312fb16c93aae..e37a7ed295245 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -466,8 +466,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h hir::ExprKind::If(cond, then, Some(otherwise)) => { let expr_cx = visitor.cx; - let data = if expr.span.at_least_rust_2024() && visitor.tcx.features().if_let_rescope() - { + let data = if expr.span.at_least_rust_2024() { ScopeData::IfThenRescope } else { ScopeData::IfThen @@ -482,8 +481,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h hir::ExprKind::If(cond, then, None) => { let expr_cx = visitor.cx; - let data = if expr.span.at_least_rust_2024() && visitor.tcx.features().if_let_rescope() - { + let data = if expr.span.at_least_rust_2024() { ScopeData::IfThenRescope } else { ScopeData::IfThen diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index bdfcc2c0a1006..afcfbebc14b31 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -24,7 +24,6 @@ declare_lint! { /// ### Example /// /// ```rust,edition2021 - /// #![feature(if_let_rescope)] /// #![warn(if_let_rescope)] /// #![allow(unused_variables)] /// @@ -243,7 +242,7 @@ impl_lint_pass!( impl<'tcx> LateLintPass<'tcx> for IfLetRescope { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { - if expr.span.edition().at_least_rust_2024() || !cx.tcx.features().if_let_rescope() { + if expr.span.edition().at_least_rust_2024() { return; } if let (Level::Allow, _) = cx.tcx.lint_level_at_node(IF_LET_RESCOPE, expr.hir_id) { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 5faefe2f25f41..24c914da77a0f 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -777,7 +777,7 @@ impl<'tcx> Cx<'tcx> { if_then_scope: region::Scope { id: then.hir_id.local_id, data: { - if expr.span.at_least_rust_2024() && tcx.features().if_let_rescope() { + if expr.span.at_least_rust_2024() { region::ScopeData::IfThenRescope } else { region::ScopeData::IfThen diff --git a/tests/ui/drop/drop_order.rs b/tests/ui/drop/drop_order.rs index cf06253800745..9706cb66b19df 100644 --- a/tests/ui/drop/drop_order.rs +++ b/tests/ui/drop/drop_order.rs @@ -4,8 +4,8 @@ //@ [edition2021] edition: 2021 //@ [edition2024] compile-flags: -Z unstable-options //@ [edition2024] edition: 2024 + #![feature(let_chains)] -#![cfg_attr(edition2024, feature(if_let_rescope))] use std::cell::RefCell; use std::convert::TryInto; diff --git a/tests/ui/drop/drop_order_if_let_rescope.rs b/tests/ui/drop/drop_order_if_let_rescope.rs index ae9f381820e16..cea84bbaa2b92 100644 --- a/tests/ui/drop/drop_order_if_let_rescope.rs +++ b/tests/ui/drop/drop_order_if_let_rescope.rs @@ -3,7 +3,6 @@ //@ compile-flags: -Z validate-mir -Zunstable-options #![feature(let_chains)] -#![feature(if_let_rescope)] use std::cell::RefCell; use std::convert::TryInto; diff --git a/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs b/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs index 2476f7cf2580a..e055c20d777bc 100644 --- a/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs +++ b/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs @@ -1,7 +1,6 @@ //@ edition: 2024 //@ compile-flags: -Z validate-mir -Zunstable-options -#![feature(if_let_rescope)] #![deny(if_let_rescope)] struct Droppy; diff --git a/tests/ui/drop/if-let-rescope-borrowck-suggestions.stderr b/tests/ui/drop/if-let-rescope-borrowck-suggestions.stderr index 0c6f1ea28d2ae..3c87e196af6e5 100644 --- a/tests/ui/drop/if-let-rescope-borrowck-suggestions.stderr +++ b/tests/ui/drop/if-let-rescope-borrowck-suggestions.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/if-let-rescope-borrowck-suggestions.rs:22:39 + --> $DIR/if-let-rescope-borrowck-suggestions.rs:21:39 | LL | do_something(if let Some(value) = Droppy.get_ref() { value } else { &0 }); | ^^^^^^ - temporary value is freed at the end of this statement @@ -7,7 +7,7 @@ LL | do_something(if let Some(value) = Droppy.get_ref() { value } else { &0 | creates a temporary value which is freed while still in use | note: lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead - --> $DIR/if-let-rescope-borrowck-suggestions.rs:22:64 + --> $DIR/if-let-rescope-borrowck-suggestions.rs:21:64 | LL | do_something(if let Some(value) = Droppy.get_ref() { value } else { &0 }); | ^ @@ -22,7 +22,7 @@ LL | do_something({ match Droppy.get_ref() { Some(value) => { value } _ => | ~~~~~~~ ++++++++++++++++ ~~~~ ++ error[E0716]: temporary value dropped while borrowed - --> $DIR/if-let-rescope-borrowck-suggestions.rs:24:39 + --> $DIR/if-let-rescope-borrowck-suggestions.rs:23:39 | LL | do_something(if let Some(value) = Droppy.get_ref() { | ^^^^^^ creates a temporary value which is freed while still in use @@ -31,7 +31,7 @@ LL | } else if let Some(value) = Droppy.get_ref() { | - temporary value is freed at the end of this statement | note: lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead - --> $DIR/if-let-rescope-borrowck-suggestions.rs:27:5 + --> $DIR/if-let-rescope-borrowck-suggestions.rs:26:5 | LL | } else if let Some(value) = Droppy.get_ref() { | ^ @@ -53,7 +53,7 @@ LL ~ }}}); | error[E0716]: temporary value dropped while borrowed - --> $DIR/if-let-rescope-borrowck-suggestions.rs:27:33 + --> $DIR/if-let-rescope-borrowck-suggestions.rs:26:33 | LL | } else if let Some(value) = Droppy.get_ref() { | ^^^^^^ creates a temporary value which is freed while still in use @@ -62,7 +62,7 @@ LL | } else { | - temporary value is freed at the end of this statement | note: lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead - --> $DIR/if-let-rescope-borrowck-suggestions.rs:30:5 + --> $DIR/if-let-rescope-borrowck-suggestions.rs:29:5 | LL | } else { | ^ diff --git a/tests/ui/drop/lint-if-let-rescope-gated.with_feature_gate.stderr b/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr similarity index 100% rename from tests/ui/drop/lint-if-let-rescope-gated.with_feature_gate.stderr rename to tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr diff --git a/tests/ui/drop/lint-if-let-rescope-gated.rs b/tests/ui/drop/lint-if-let-rescope-gated.rs index cef5de5a8fe56..ba0246573b406 100644 --- a/tests/ui/drop/lint-if-let-rescope-gated.rs +++ b/tests/ui/drop/lint-if-let-rescope-gated.rs @@ -1,13 +1,13 @@ // This test checks that the lint `if_let_rescope` only actions -// when the feature gate is enabled. -// Edition 2021 is used here because the lint should work especially -// when edition migration towards 2024 is run. +// when Edition 2021 or prior is targeted here because the lint should work especially +// when edition migration towards 2024 is executed. -//@ revisions: with_feature_gate without_feature_gate -//@ [without_feature_gate] check-pass -//@ edition: 2021 +//@ revisions: edition2021 edition2024 +//@ [edition2021] edition: 2021 +//@ [edition2024] edition: 2024 +//@ [edition2024] compile-flags: -Zunstable-options +//@ [edition2024] check-pass -#![cfg_attr(with_feature_gate, feature(if_let_rescope))] #![deny(if_let_rescope)] #![allow(irrefutable_let_patterns)] @@ -25,10 +25,10 @@ impl Droppy { fn main() { if let Some(_value) = Droppy.get() { - //[with_feature_gate]~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 - //[with_feature_gate]~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 - //[with_feature_gate]~| WARN: this changes meaning in Rust 2024 + //[edition2021]~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 + //[edition2021]~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 + //[edition2021]~| WARN: this changes meaning in Rust 2024 } else { - //[with_feature_gate]~^ HELP: the value is now dropped here in Edition 2024 + //[edition2021]~^ HELP: the value is now dropped here in Edition 2024 } } diff --git a/tests/ui/drop/lint-if-let-rescope-with-macro.rs b/tests/ui/drop/lint-if-let-rescope-with-macro.rs index 282b3320d3004..e7aeb81f4d1a5 100644 --- a/tests/ui/drop/lint-if-let-rescope-with-macro.rs +++ b/tests/ui/drop/lint-if-let-rescope-with-macro.rs @@ -4,7 +4,6 @@ //@ edition:2021 //@ compile-flags: -Z unstable-options -#![feature(if_let_rescope)] #![deny(if_let_rescope)] #![allow(irrefutable_let_patterns)] diff --git a/tests/ui/drop/lint-if-let-rescope-with-macro.stderr b/tests/ui/drop/lint-if-let-rescope-with-macro.stderr index 5fd0c61d17a57..de6cf6e8500ee 100644 --- a/tests/ui/drop/lint-if-let-rescope-with-macro.stderr +++ b/tests/ui/drop/lint-if-let-rescope-with-macro.stderr @@ -1,5 +1,5 @@ error: `if let` assigns a shorter lifetime since Edition 2024 - --> $DIR/lint-if-let-rescope-with-macro.rs:13:12 + --> $DIR/lint-if-let-rescope-with-macro.rs:12:12 | LL | if let $p = $e { $($conseq)* } else { $($alt)* } | ^^^ @@ -16,7 +16,7 @@ LL | | }; = warning: this changes meaning in Rust 2024 = note: for more information, see issue #124085 help: the value is now dropped here in Edition 2024 - --> $DIR/lint-if-let-rescope-with-macro.rs:13:38 + --> $DIR/lint-if-let-rescope-with-macro.rs:12:38 | LL | if let $p = $e { $($conseq)* } else { $($alt)* } | ^ @@ -29,7 +29,7 @@ LL | | {} LL | | }; | |_____- in this macro invocation note: the lint level is defined here - --> $DIR/lint-if-let-rescope-with-macro.rs:8:9 + --> $DIR/lint-if-let-rescope-with-macro.rs:7:9 | LL | #![deny(if_let_rescope)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/drop/lint-if-let-rescope.fixed b/tests/ui/drop/lint-if-let-rescope.fixed index 199068d0fd265..fec2e3b2ae705 100644 --- a/tests/ui/drop/lint-if-let-rescope.fixed +++ b/tests/ui/drop/lint-if-let-rescope.fixed @@ -1,7 +1,7 @@ //@ run-rustfix #![deny(if_let_rescope)] -#![feature(if_let_rescope, stmt_expr_attributes)] +#![feature(stmt_expr_attributes)] #![allow(irrefutable_let_patterns, unused_parens)] fn droppy() -> Droppy { diff --git a/tests/ui/drop/lint-if-let-rescope.rs b/tests/ui/drop/lint-if-let-rescope.rs index 4c043c0266cc4..ee184695b97ac 100644 --- a/tests/ui/drop/lint-if-let-rescope.rs +++ b/tests/ui/drop/lint-if-let-rescope.rs @@ -1,7 +1,7 @@ //@ run-rustfix #![deny(if_let_rescope)] -#![feature(if_let_rescope, stmt_expr_attributes)] +#![feature(stmt_expr_attributes)] #![allow(irrefutable_let_patterns, unused_parens)] fn droppy() -> Droppy { diff --git a/tests/ui/feature-gates/feature-gate-if-let-rescope.rs b/tests/ui/feature-gates/feature-gate-if-let-rescope.rs deleted file mode 100644 index bd1efd4fb7c1f..0000000000000 --- a/tests/ui/feature-gates/feature-gate-if-let-rescope.rs +++ /dev/null @@ -1,27 +0,0 @@ -// This test shows the code that could have been accepted by enabling #![feature(if_let_rescope)] - -struct A; -struct B<'a, T>(&'a mut T); - -impl A { - fn f(&mut self) -> Option> { - Some(B(self)) - } -} - -impl<'a, T> Drop for B<'a, T> { - fn drop(&mut self) { - // this is needed to keep NLL's hands off and to ensure - // the inner mutable borrow stays alive - } -} - -fn main() { - let mut a = A; - if let None = a.f().as_ref() { - unreachable!() - } else { - a.f().unwrap(); - //~^ ERROR cannot borrow `a` as mutable more than once at a time - }; -} diff --git a/tests/ui/feature-gates/feature-gate-if-let-rescope.stderr b/tests/ui/feature-gates/feature-gate-if-let-rescope.stderr deleted file mode 100644 index ff1846ae0b1f5..0000000000000 --- a/tests/ui/feature-gates/feature-gate-if-let-rescope.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0499]: cannot borrow `a` as mutable more than once at a time - --> $DIR/feature-gate-if-let-rescope.rs:24:9 - | -LL | if let None = a.f().as_ref() { - | ----- - | | - | first mutable borrow occurs here - | a temporary with access to the first borrow is created here ... -... -LL | a.f().unwrap(); - | ^ second mutable borrow occurs here -LL | -LL | }; - | - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `Option>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/mir/mir_let_chains_drop_order.rs b/tests/ui/mir/mir_let_chains_drop_order.rs index daf0a62fc85f3..92199625207e9 100644 --- a/tests/ui/mir/mir_let_chains_drop_order.rs +++ b/tests/ui/mir/mir_let_chains_drop_order.rs @@ -8,7 +8,6 @@ // See `mir_drop_order.rs` for more information #![feature(let_chains)] -#![cfg_attr(edition2024, feature(if_let_rescope))] #![allow(irrefutable_let_patterns)] use std::cell::RefCell; diff --git a/tests/ui/nll/issue-54556-niconii.edition2021.stderr b/tests/ui/nll/issue-54556-niconii.edition2021.stderr index 31a03abbc9826..abee09ed95037 100644 --- a/tests/ui/nll/issue-54556-niconii.edition2021.stderr +++ b/tests/ui/nll/issue-54556-niconii.edition2021.stderr @@ -1,5 +1,5 @@ error[E0597]: `counter` does not live long enough - --> $DIR/issue-54556-niconii.rs:30:20 + --> $DIR/issue-54556-niconii.rs:28:20 | LL | let counter = Mutex; | ------- binding `counter` declared here diff --git a/tests/ui/nll/issue-54556-niconii.rs b/tests/ui/nll/issue-54556-niconii.rs index 1a7ad17cc84c0..f01e0523cbf9d 100644 --- a/tests/ui/nll/issue-54556-niconii.rs +++ b/tests/ui/nll/issue-54556-niconii.rs @@ -12,8 +12,6 @@ //@ [edition2024] compile-flags: -Z unstable-options //@ [edition2024] check-pass -#![cfg_attr(edition2024, feature(if_let_rescope))] - struct Mutex; struct MutexGuard<'a>(&'a Mutex);