Skip to content

Commit c190214

Browse files
Don't reset binding mode on mut with edition >= 2024
1 parent 8ea4ea7 commit c190214

File tree

3 files changed

+137
-13
lines changed

3 files changed

+137
-13
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -605,23 +605,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
605605
expected: Ty<'tcx>,
606606
pat_info: PatInfo<'tcx, '_>,
607607
) -> Ty<'tcx> {
608-
let PatInfo { binding_mode: def_bm, top_info: ti, .. } = pat_info;
608+
let PatInfo { binding_mode: BindingAnnotation(def_br, _), top_info: ti, .. } = pat_info;
609609

610610
// Determine the binding mode...
611611
let bm = match ba {
612-
BindingAnnotation(ByRef::No, Mutability::Not) => def_bm,
613-
BindingAnnotation(ByRef::No, Mutability::Mut) => {
614-
if matches!(def_bm.0, ByRef::Yes(_)) {
615-
// `mut x` resets the binding mode.
616-
self.tcx.emit_node_span_lint(
617-
lint::builtin::DEREFERENCING_MUT_BINDING,
618-
pat.hir_id,
619-
pat.span,
620-
errors::DereferencingMutBinding { span: pat.span },
621-
);
622-
}
612+
BindingAnnotation(ByRef::No, Mutability::Mut)
613+
if !pat.span.at_least_rust_2024() && matches!(def_br, ByRef::Yes(_)) =>
614+
{
615+
// `mut x` resets the binding mode in edition <= 2021.
616+
self.tcx.emit_node_span_lint(
617+
lint::builtin::DEREFERENCING_MUT_BINDING,
618+
pat.hir_id,
619+
pat.span,
620+
errors::DereferencingMutBinding { span: pat.span },
621+
);
623622
BindingAnnotation(ByRef::No, Mutability::Mut)
624623
}
624+
BindingAnnotation(ByRef::No, mutbl) => BindingAnnotation(def_br, mutbl),
625625
BindingAnnotation(ByRef::Yes(_), _) => ba,
626626
};
627627
// ...and store it in a side table:
@@ -731,7 +731,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
731731
}
732732
}
733733

734-
// Precondition: pat is a Ref(_) pattern
734+
/// Precondition: pat is a `Ref(_)` pattern
735735
fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) {
736736
let tcx = self.tcx;
737737
if let PatKind::Ref(inner, mutbl) = pat.kind

tests/ui/match/mut-ref-mut-2024.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//@ edition: 2024
2+
//@ compile-flags: -Zunstable-options
3+
4+
struct Foo(u8);
5+
6+
fn main() {
7+
let Foo(a) = Foo(0);
8+
a = 42; //~ ERROR [E0384]
9+
10+
let Foo(mut a) = Foo(0);
11+
a = 42;
12+
13+
let Foo(ref a) = Foo(0);
14+
a = &42; //~ ERROR [E0384]
15+
16+
let Foo(mut ref a) = Foo(0);
17+
a = &42;
18+
19+
let Foo(ref mut a) = Foo(0);
20+
a = &mut 42; //~ ERROR [E0384]
21+
22+
let Foo(mut ref mut a) = Foo(0);
23+
a = &mut 42;
24+
25+
let Foo(a) = &Foo(0);
26+
a = &42; //~ ERROR [E0384]
27+
28+
let Foo(mut a) = &Foo(0);
29+
a = &42;
30+
31+
let Foo(ref a) = &Foo(0);
32+
a = &42; //~ ERROR [E0384]
33+
34+
let Foo(mut ref a) = &Foo(0);
35+
a = &42;
36+
37+
let Foo(a) = &mut Foo(0);
38+
a = &mut 42; //~ ERROR [E0384]
39+
40+
let Foo(mut a) = &mut Foo(0);
41+
a = &mut 42;
42+
43+
let Foo(ref a) = &mut Foo(0);
44+
a = &42; //~ ERROR [E0384]
45+
46+
let Foo(mut ref a) = &mut Foo(0);
47+
a = &42;
48+
49+
let Foo(ref mut a) = &mut Foo(0);
50+
a = &mut 42; //~ ERROR [E0384]
51+
52+
let Foo(mut ref mut a) = &mut Foo(0);
53+
a = &mut 42;
54+
}
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
error[E0384]: cannot assign twice to immutable variable `a`
2+
--> $DIR/mut-ref-mut-2024.rs:8:5
3+
|
4+
LL | let Foo(a) = Foo(0);
5+
| -
6+
| |
7+
| first assignment to `a`
8+
| help: consider making this binding mutable: `mut a`
9+
LL | a = 42;
10+
| ^^^^^^ cannot assign twice to immutable variable
11+
12+
error[E0384]: cannot assign twice to immutable variable `a`
13+
--> $DIR/mut-ref-mut-2024.rs:14:5
14+
|
15+
LL | let Foo(ref a) = Foo(0);
16+
| ----- first assignment to `a`
17+
LL | a = &42;
18+
| ^^^^^^^ cannot assign twice to immutable variable
19+
20+
error[E0384]: cannot assign twice to immutable variable `a`
21+
--> $DIR/mut-ref-mut-2024.rs:20:5
22+
|
23+
LL | let Foo(ref mut a) = Foo(0);
24+
| --------- first assignment to `a`
25+
LL | a = &mut 42;
26+
| ^^^^^^^^^^^ cannot assign twice to immutable variable
27+
28+
error[E0384]: cannot assign twice to immutable variable `a`
29+
--> $DIR/mut-ref-mut-2024.rs:26:5
30+
|
31+
LL | let Foo(a) = &Foo(0);
32+
| - first assignment to `a`
33+
LL | a = &42;
34+
| ^^^^^^^ cannot assign twice to immutable variable
35+
36+
error[E0384]: cannot assign twice to immutable variable `a`
37+
--> $DIR/mut-ref-mut-2024.rs:32:5
38+
|
39+
LL | let Foo(ref a) = &Foo(0);
40+
| ----- first assignment to `a`
41+
LL | a = &42;
42+
| ^^^^^^^ cannot assign twice to immutable variable
43+
44+
error[E0384]: cannot assign twice to immutable variable `a`
45+
--> $DIR/mut-ref-mut-2024.rs:38:5
46+
|
47+
LL | let Foo(a) = &mut Foo(0);
48+
| - first assignment to `a`
49+
LL | a = &mut 42;
50+
| ^^^^^^^^^^^ cannot assign twice to immutable variable
51+
52+
error[E0384]: cannot assign twice to immutable variable `a`
53+
--> $DIR/mut-ref-mut-2024.rs:44:5
54+
|
55+
LL | let Foo(ref a) = &mut Foo(0);
56+
| ----- first assignment to `a`
57+
LL | a = &42;
58+
| ^^^^^^^ cannot assign twice to immutable variable
59+
60+
error[E0384]: cannot assign twice to immutable variable `a`
61+
--> $DIR/mut-ref-mut-2024.rs:50:5
62+
|
63+
LL | let Foo(ref mut a) = &mut Foo(0);
64+
| --------- first assignment to `a`
65+
LL | a = &mut 42;
66+
| ^^^^^^^^^^^ cannot assign twice to immutable variable
67+
68+
error: aborting due to 8 previous errors
69+
70+
For more information about this error, try `rustc --explain E0384`.

0 commit comments

Comments
 (0)