From 51de637a9f2980a11ffc8de7bf785d054dcb35fb Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Tue, 26 Mar 2024 01:23:26 -0400 Subject: [PATCH] Feature gate --- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_parse/src/parser/pat.rs | 4 ++ compiler/rustc_span/src/symbol.rs | 1 + .../ui/feature-gates/feature-gate-mut-ref.rs | 13 ++++++ .../feature-gates/feature-gate-mut-ref.stderr | 43 +++++++++++++++++++ tests/ui/match/mut-ref-mut-2021.rs | 1 + tests/ui/match/mut-ref-mut-2021.stderr | 16 +++---- tests/ui/mut/mut-ref.rs | 2 +- 9 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-mut-ref.rs create mode 100644 tests/ui/feature-gates/feature-gate-mut-ref.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index bb83f4c0f0ef8..5912dd3f931b2 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -565,6 +565,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented"); gate_all!(fn_delegation, "functions delegation is not yet fully implemented"); gate_all!(postfix_match, "postfix match is experimental"); + gate_all!(mut_ref, "mutable by-reference bindings are experimental"); if !visitor.features.never_patterns { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8d72f4924d63c..4c975c7b9e052 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -529,6 +529,8 @@ declare_features! ( (unstable, more_qualified_paths, "1.54.0", Some(86935)), /// Allows the `#[must_not_suspend]` attribute. (unstable, must_not_suspend, "1.57.0", Some(83310)), + /// Allows `mut ref` and `mut ref mut` identifier patterns. + (incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows using `#[naked]` on functions. (unstable, naked_functions, "1.9.0", Some(90957)), /// Allows specifying the as-needed link modifier diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index ead00c3f0d4c6..59e0cd92c4cb4 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -779,6 +779,10 @@ impl<'a> Parser<'a> { self.ban_mut_general_pat(mut_span, &pat, changed_any_binding); } + if matches!(pat.kind, PatKind::Ident(BindingAnnotation(ByRef::Yes(_), Mutability::Mut), ..)) + { + self.psess.gated_spans.gate(sym::mut_ref, pat.span); + } Ok(pat.into_inner().kind) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 891ddb7af5b0b..15fba5645e23e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1185,6 +1185,7 @@ symbols! { multiple_supertrait_upcastable, must_not_suspend, must_use, + mut_ref, naked, naked_functions, name, diff --git a/tests/ui/feature-gates/feature-gate-mut-ref.rs b/tests/ui/feature-gates/feature-gate-mut-ref.rs new file mode 100644 index 0000000000000..806b25de66ff2 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-mut-ref.rs @@ -0,0 +1,13 @@ +fn main() { + let mut ref x = 10; //~ ERROR [E0658] + x = &11; + let ref mut y = 12; + *y = 13; + let mut ref mut z = 14; //~ ERROR [E0658] + z = &mut 15; + + #[cfg(FALSE)] + let mut ref x = 10; //~ ERROR [E0658] + #[cfg(FALSE)] + let mut ref mut y = 10; //~ ERROR [E0658] +} diff --git a/tests/ui/feature-gates/feature-gate-mut-ref.stderr b/tests/ui/feature-gates/feature-gate-mut-ref.stderr new file mode 100644 index 0000000000000..d3eb674e92dec --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-mut-ref.stderr @@ -0,0 +1,43 @@ +error[E0658]: mutable by-reference bindings are experimental + --> $DIR/feature-gate-mut-ref.rs:2:17 + | +LL | let mut ref x = 10; + | ^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: mutable by-reference bindings are experimental + --> $DIR/feature-gate-mut-ref.rs:6:21 + | +LL | let mut ref mut z = 14; + | ^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: mutable by-reference bindings are experimental + --> $DIR/feature-gate-mut-ref.rs:10:17 + | +LL | let mut ref x = 10; + | ^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: mutable by-reference bindings are experimental + --> $DIR/feature-gate-mut-ref.rs:12:21 + | +LL | let mut ref mut y = 10; + | ^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/match/mut-ref-mut-2021.rs b/tests/ui/match/mut-ref-mut-2021.rs index 48516350d4d7f..699ccad49bcb8 100644 --- a/tests/ui/match/mut-ref-mut-2021.rs +++ b/tests/ui/match/mut-ref-mut-2021.rs @@ -1,4 +1,5 @@ //@ edition: 2021 +#![feature(mut_ref)] struct Foo(u8); diff --git a/tests/ui/match/mut-ref-mut-2021.stderr b/tests/ui/match/mut-ref-mut-2021.stderr index 9210ce23784f4..52ea8c580a564 100644 --- a/tests/ui/match/mut-ref-mut-2021.stderr +++ b/tests/ui/match/mut-ref-mut-2021.stderr @@ -1,5 +1,5 @@ error[E0384]: cannot assign twice to immutable variable `a` - --> $DIR/mut-ref-mut-2021.rs:7:5 + --> $DIR/mut-ref-mut-2021.rs:8:5 | LL | let Foo(a) = Foo(0); | - @@ -10,7 +10,7 @@ LL | a = 42; | ^^^^^^ cannot assign twice to immutable variable error[E0384]: cannot assign twice to immutable variable `a` - --> $DIR/mut-ref-mut-2021.rs:13:5 + --> $DIR/mut-ref-mut-2021.rs:14:5 | LL | let Foo(ref a) = Foo(0); | ----- first assignment to `a` @@ -18,7 +18,7 @@ LL | a = &42; | ^^^^^^^ cannot assign twice to immutable variable error[E0384]: cannot assign twice to immutable variable `a` - --> $DIR/mut-ref-mut-2021.rs:19:5 + --> $DIR/mut-ref-mut-2021.rs:20:5 | LL | let Foo(ref mut a) = Foo(0); | --------- first assignment to `a` @@ -26,7 +26,7 @@ LL | a = &mut 42; | ^^^^^^^^^^^ cannot assign twice to immutable variable error[E0384]: cannot assign twice to immutable variable `a` - --> $DIR/mut-ref-mut-2021.rs:25:5 + --> $DIR/mut-ref-mut-2021.rs:26:5 | LL | let Foo(a) = &Foo(0); | - first assignment to `a` @@ -34,7 +34,7 @@ LL | a = &42; | ^^^^^^^ cannot assign twice to immutable variable error[E0384]: cannot assign twice to immutable variable `a` - --> $DIR/mut-ref-mut-2021.rs:31:5 + --> $DIR/mut-ref-mut-2021.rs:32:5 | LL | let Foo(ref a) = &Foo(0); | ----- first assignment to `a` @@ -42,7 +42,7 @@ LL | a = &42; | ^^^^^^^ cannot assign twice to immutable variable error[E0384]: cannot assign twice to immutable variable `a` - --> $DIR/mut-ref-mut-2021.rs:37:5 + --> $DIR/mut-ref-mut-2021.rs:38:5 | LL | let Foo(a) = &mut Foo(0); | - first assignment to `a` @@ -50,7 +50,7 @@ LL | a = &mut 42; | ^^^^^^^^^^^ cannot assign twice to immutable variable error[E0384]: cannot assign twice to immutable variable `a` - --> $DIR/mut-ref-mut-2021.rs:43:5 + --> $DIR/mut-ref-mut-2021.rs:44:5 | LL | let Foo(ref a) = &mut Foo(0); | ----- first assignment to `a` @@ -58,7 +58,7 @@ LL | a = &42; | ^^^^^^^ cannot assign twice to immutable variable error[E0384]: cannot assign twice to immutable variable `a` - --> $DIR/mut-ref-mut-2021.rs:49:5 + --> $DIR/mut-ref-mut-2021.rs:50:5 | LL | let Foo(ref mut a) = &mut Foo(0); | --------- first assignment to `a` diff --git a/tests/ui/mut/mut-ref.rs b/tests/ui/mut/mut-ref.rs index 813c7f02df15b..01333c53f9fd7 100644 --- a/tests/ui/mut/mut-ref.rs +++ b/tests/ui/mut/mut-ref.rs @@ -1,5 +1,5 @@ //@ check-pass - +#![feature(mut_ref)] fn main() { let mut ref x = 10; x = &11;