diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index bb83f4c0f0e..5912dd3f931 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -565,6 +565,7 @@ macro_rules! gate_all { 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 8d72f4924d6..4c975c7b9e0 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -529,6 +529,8 @@ pub fn internal(&self, feature: Symbol) -> bool { (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 ead00c3f0d4..59e0cd92c4c 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -779,6 +779,10 @@ fn parse_pat_ident_mut(&mut self) -> PResult<'a, PatKind> { 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 891ddb7af5b..15fba5645e2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1185,6 +1185,7 @@ 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 00000000000..806b25de66f --- /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 00000000000..d3eb674e92d --- /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/mut/mut-ref.rs b/tests/ui/mut/mut-ref.rs index 813c7f02df1..54630d95007 100644 --- a/tests/ui/mut/mut-ref.rs +++ b/tests/ui/mut/mut-ref.rs @@ -1,5 +1,6 @@ //@ check-pass - +#![allow(incomplete_features)] +#![feature(mut_ref)] fn main() { let mut ref x = 10; x = &11; diff --git a/tests/ui/match/mut-ref-mut-2021.rs b/tests/ui/pattern/mut-ref-mut-2021.rs similarity index 94% rename from tests/ui/match/mut-ref-mut-2021.rs rename to tests/ui/pattern/mut-ref-mut-2021.rs index 48516350d4d..a3be40faeff 100644 --- a/tests/ui/match/mut-ref-mut-2021.rs +++ b/tests/ui/pattern/mut-ref-mut-2021.rs @@ -1,4 +1,6 @@ //@ edition: 2021 +#![allow(incomplete_features)] +#![feature(mut_ref)] struct Foo(u8); diff --git a/tests/ui/match/mut-ref-mut-2021.stderr b/tests/ui/pattern/mut-ref-mut-2021.stderr similarity index 87% rename from tests/ui/match/mut-ref-mut-2021.stderr rename to tests/ui/pattern/mut-ref-mut-2021.stderr index 9210ce23784..eb31ffa0e30 100644 --- a/tests/ui/match/mut-ref-mut-2021.stderr +++ b/tests/ui/pattern/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:9: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:15: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:21: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:27: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:33: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:39: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:45: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:51:5 | LL | let Foo(ref mut a) = &mut Foo(0); | --------- first assignment to `a`