Skip to content

Commit 860e50a

Browse files
committed
Lint resetting mut
1 parent 2b3d008 commit 860e50a

14 files changed

+149
-7
lines changed

compiler/rustc_hir_typeck/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private
4646
4747
hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty`
4848
49+
hir_typeck_dereferencing_mut_binding = dereferencing `mut` binding
50+
.label = `mut` dereferences the type of this binding
51+
.help = this will change in edition 2024
52+
4953
hir_typeck_expected_default_return_type = expected `()` because of default return type
5054
5155
hir_typeck_expected_return_type = expected `{$expected}` because of return type

compiler/rustc_hir_typeck/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,3 +630,11 @@ pub struct SuggestConvertViaMethod<'tcx> {
630630
pub expected: Ty<'tcx>,
631631
pub found: Ty<'tcx>,
632632
}
633+
634+
#[derive(LintDiagnostic)]
635+
#[diag(hir_typeck_dereferencing_mut_binding)]
636+
pub struct DereferencingMutBinding {
637+
#[label]
638+
#[help]
639+
pub span: Span,
640+
}

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_infer::infer;
1414
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1515
use rustc_middle::mir::interpret::ErrorHandled;
1616
use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeVisitableExt};
17-
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
17+
use rustc_session::lint;
1818
use rustc_span::edit_distance::find_best_match_for_name;
1919
use rustc_span::hygiene::DesugaringKind;
2020
use rustc_span::source_map::Spanned;
@@ -600,8 +600,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
600600

601601
// Determine the binding mode...
602602
let bm = match ba {
603-
hir::BindingAnnotation::NONE => def_bm,
604-
_ => BindingMode::convert(ba),
603+
hir::BindingAnnotation(ast::ByRef::No, hir::Mutability::Not) => def_bm,
604+
hir::BindingAnnotation(ast::ByRef::No, mutbl @ hir::Mutability::Mut) => {
605+
if let BindingMode::BindByReference(_) = def_bm {
606+
// `mut x` resets the binding mode.
607+
self.tcx.emit_spanned_lint(
608+
lint::builtin::DEREFERENCING_MUT_BINDING,
609+
pat.hir_id,
610+
pat.span,
611+
errors::DereferencingMutBinding { span: pat.span },
612+
);
613+
}
614+
BindingMode::BindByValue(mutbl)
615+
}
616+
hir::BindingAnnotation(ast::ByRef::Yes, mutbl) => BindingMode::BindByReference(mutbl),
605617
};
606618
// ...and store it in a side table:
607619
self.inh.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm);
@@ -1838,7 +1850,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18381850
&unmentioned_fields.iter().map(|(_, i)| i).collect::<Vec<_>>(),
18391851
);
18401852

1841-
self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| {
1853+
self.tcx.struct_span_lint_hir(lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| {
18421854
lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns));
18431855
lint.help(
18441856
"ensure that all fields are mentioned explicitly by adding the suggested fields",

tests/ui/or-patterns/or-patterns-default-binding-modes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![allow(irrefutable_let_patterns)]
66
#![allow(dropping_copy_types)]
77
#![allow(dropping_references)]
8+
#![allow(dereferencing_mut_binding)]
89

910
fn main() {
1011
// A regression test for a mistake we made at one point:

tests/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes-fixable.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ fn main() {
99
let mut p = (U, U);
1010
let (a, ref mut b) = &mut p;
1111
//~^ ERROR cannot move out of a mutable reference
12+
//~| WARN dereferencing `mut`
1213
}

tests/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes-fixable.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ fn main() {
99
let mut p = (U, U);
1010
let (a, mut b) = &mut p;
1111
//~^ ERROR cannot move out of a mutable reference
12+
//~| WARN dereferencing `mut`
1213
}

tests/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes-fixable.stderr

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
warning: dereferencing `mut` binding
2+
--> $DIR/move-ref-patterns-default-binding-modes-fixable.rs:10:13
3+
|
4+
LL | let (a, mut b) = &mut p;
5+
| ^^^^^ `mut` dereferences the type of this binding
6+
|
7+
help: this will change in edition 2024
8+
--> $DIR/move-ref-patterns-default-binding-modes-fixable.rs:10:13
9+
|
10+
LL | let (a, mut b) = &mut p;
11+
| ^^^^^
12+
= note: `#[warn(dereferencing_mut_binding)]` on by default
13+
114
error[E0507]: cannot move out of a mutable reference
215
--> $DIR/move-ref-patterns-default-binding-modes-fixable.rs:10:22
316
|
@@ -12,6 +25,6 @@ help: consider borrowing the pattern binding
1225
LL | let (a, ref mut b) = &mut p;
1326
| +++
1427

15-
error: aborting due to 1 previous error
28+
error: aborting due to 1 previous error; 1 warning emitted
1629

1730
For more information about this error, try `rustc --explain E0507`.

tests/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ fn main() {
77
let p = (U, U);
88
let (a, mut b) = &p;
99
//~^ ERROR cannot move out of a shared reference
10+
//~| WARN dereferencing `mut`
1011
}

tests/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
warning: dereferencing `mut` binding
2+
--> $DIR/move-ref-patterns-default-binding-modes.rs:8:13
3+
|
4+
LL | let (a, mut b) = &p;
5+
| ^^^^^ `mut` dereferences the type of this binding
6+
|
7+
help: this will change in edition 2024
8+
--> $DIR/move-ref-patterns-default-binding-modes.rs:8:13
9+
|
10+
LL | let (a, mut b) = &p;
11+
| ^^^^^
12+
= note: `#[warn(dereferencing_mut_binding)]` on by default
13+
114
error[E0507]: cannot move out of a shared reference
215
--> $DIR/move-ref-patterns-default-binding-modes.rs:8:22
316
|
@@ -12,6 +25,6 @@ help: consider borrowing the pattern binding
1225
LL | let (a, ref mut b) = &p;
1326
| +++
1427

15-
error: aborting due to 1 previous error
28+
error: aborting due to 1 previous error; 1 warning emitted
1629

1730
For more information about this error, try `rustc --explain E0507`.

tests/ui/rfcs/rfc-2005-default-binding-mode/for.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ pub fn main() {
55
// The below desugars to &(ref n, mut m).
66
for (n, mut m) in &tups {
77
//~^ ERROR cannot move out of a shared reference
8+
//~| WARN dereferencing `mut`
89
}
910
}

0 commit comments

Comments
 (0)