mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-10 22:13:27 +00:00
Rollup merge of #98431 - WaffleLapkin:mut_pat_suggestions, r=compiler-errors
Suggest defining variable as mutable on `&mut _` type mismatch in pats Suggest writing `mut a` where `&mut a` was written but a non-ref type provided. Since we still don't have "apply either one of the suggestions but not both" kind of thing, the interaction with the suggestion of removing `&[mut]` or moving it to the type is weird, and idk how to make it better.. r? ``@compiler-errors``
This commit is contained in:
commit
1f923c2a41
@ -663,6 +663,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ast::Mutability::Not => "",
|
||||
};
|
||||
|
||||
let mut_var_suggestion = 'block: {
|
||||
if !matches!(mutbl, ast::Mutability::Mut) {
|
||||
break 'block None;
|
||||
}
|
||||
|
||||
let ident_kind = match binding_parent {
|
||||
hir::Node::Param(_) => "parameter",
|
||||
hir::Node::Local(_) => "variable",
|
||||
hir::Node::Arm(_) => "binding",
|
||||
|
||||
// Provide diagnostics only if the parent pattern is struct-like,
|
||||
// i.e. where `mut binding` makes sense
|
||||
hir::Node::Pat(Pat { kind, .. }) => match kind {
|
||||
PatKind::Struct(..)
|
||||
| PatKind::TupleStruct(..)
|
||||
| PatKind::Or(..)
|
||||
| PatKind::Tuple(..)
|
||||
| PatKind::Slice(..) => "binding",
|
||||
|
||||
PatKind::Wild
|
||||
| PatKind::Binding(..)
|
||||
| PatKind::Path(..)
|
||||
| PatKind::Box(..)
|
||||
| PatKind::Ref(..)
|
||||
| PatKind::Lit(..)
|
||||
| PatKind::Range(..) => break 'block None,
|
||||
},
|
||||
|
||||
// Don't provide suggestions in other cases
|
||||
_ => break 'block None,
|
||||
};
|
||||
|
||||
Some((
|
||||
pat.span,
|
||||
format!("to declare a mutable {ident_kind} use"),
|
||||
format!("mut {binding}"),
|
||||
))
|
||||
|
||||
};
|
||||
|
||||
match binding_parent {
|
||||
// Check that there is explicit type (ie this is not a closure param with inferred type)
|
||||
// so we don't suggest moving something to the type that does not exist
|
||||
@ -675,6 +715,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
],
|
||||
Applicability::MachineApplicable
|
||||
);
|
||||
|
||||
if let Some((sp, msg, sugg)) = mut_var_suggestion {
|
||||
err.span_note(sp, format!("{msg}: `{sugg}`"));
|
||||
}
|
||||
}
|
||||
hir::Node::Param(_) | hir::Node::Arm(_) | hir::Node::Pat(_) => {
|
||||
// rely on match ergonomics or it might be nested `&&pat`
|
||||
@ -684,6 +728,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
||||
if let Some((sp, msg, sugg)) = mut_var_suggestion {
|
||||
err.span_note(sp, format!("{msg}: `{sugg}`"));
|
||||
}
|
||||
}
|
||||
_ if let Some((sp, msg, sugg)) = mut_var_suggestion => {
|
||||
err.span_suggestion(sp, msg, sugg, Applicability::MachineApplicable);
|
||||
}
|
||||
_ => {} // don't provide suggestions in other cases #55175
|
||||
}
|
||||
|
@ -21,4 +21,17 @@ fn main() {
|
||||
let _ = |&mut _a: &mut u32| (); //~ ERROR mismatched types
|
||||
let _ = |&_a: &u32| (); //~ ERROR mismatched types
|
||||
let _ = |&mut _a: &mut u32| (); //~ ERROR mismatched types
|
||||
|
||||
#[allow(unused_mut)]
|
||||
{
|
||||
struct S(u8);
|
||||
|
||||
let mut _a = 0; //~ ERROR mismatched types
|
||||
let S(_b) = S(0); //~ ERROR mismatched types
|
||||
let (_c,) = (0,); //~ ERROR mismatched types
|
||||
|
||||
match 0 {
|
||||
_d => {} //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,4 +21,17 @@ fn main() {
|
||||
let _ = |&mut &_a: &mut u32| (); //~ ERROR mismatched types
|
||||
let _ = |&&mut _a: &u32| (); //~ ERROR mismatched types
|
||||
let _ = |&mut &mut _a: &mut u32| (); //~ ERROR mismatched types
|
||||
|
||||
#[allow(unused_mut)]
|
||||
{
|
||||
struct S(u8);
|
||||
|
||||
let &mut _a = 0; //~ ERROR mismatched types
|
||||
let S(&mut _b) = S(0); //~ ERROR mismatched types
|
||||
let (&mut _c,) = (0,); //~ ERROR mismatched types
|
||||
|
||||
match 0 {
|
||||
&mut _d => {} //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,11 @@ LL | fn _f1(&mut _a: u32) {}
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable parameter use: `mut _a`
|
||||
--> $DIR/ref-pat-suggestions.rs:4:8
|
||||
|
|
||||
LL | fn _f1(&mut _a: u32) {}
|
||||
| ^^^^^^^
|
||||
help: to take parameter `_a` by reference, move `&mut` to the type
|
||||
|
|
||||
LL - fn _f1(&mut _a: u32) {}
|
||||
@ -122,6 +127,11 @@ LL | let _: fn(u32) = |&mut _a| ();
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable parameter use: `mut _a`
|
||||
--> $DIR/ref-pat-suggestions.rs:12:23
|
||||
|
|
||||
LL | let _: fn(u32) = |&mut _a| ();
|
||||
| ^^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - let _: fn(u32) = |&mut _a| ();
|
||||
@ -222,6 +232,11 @@ LL | let _ = |&mut _a: u32| ();
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable parameter use: `mut _a`
|
||||
--> $DIR/ref-pat-suggestions.rs:19:14
|
||||
|
|
||||
LL | let _ = |&mut _a: u32| ();
|
||||
| ^^^^^^^
|
||||
help: to take parameter `_a` by reference, move `&mut` to the type
|
||||
|
|
||||
LL - let _ = |&mut _a: u32| ();
|
||||
@ -292,6 +307,81 @@ LL - let _ = |&mut &mut _a: &mut u32| ();
|
||||
LL + let _ = |&mut _a: &mut u32| ();
|
||||
|
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref-pat-suggestions.rs:29:13
|
||||
|
|
||||
LL | let &mut _a = 0;
|
||||
| ^^^^^^^ - this expression has type `{integer}`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| help: to declare a mutable variable use: `mut _a`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref-pat-suggestions.rs:30:15
|
||||
|
|
||||
LL | let S(&mut _b) = S(0);
|
||||
| ^^^^^^^ ---- this expression has type `S`
|
||||
| |
|
||||
| expected `u8`, found `&mut _`
|
||||
|
|
||||
= note: expected type `u8`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut _b`
|
||||
--> $DIR/ref-pat-suggestions.rs:30:15
|
||||
|
|
||||
LL | let S(&mut _b) = S(0);
|
||||
| ^^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - let S(&mut _b) = S(0);
|
||||
LL + let S(_b) = S(0);
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref-pat-suggestions.rs:31:14
|
||||
|
|
||||
LL | let (&mut _c,) = (0,);
|
||||
| ^^^^^^^ ---- this expression has type `({integer},)`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut _c`
|
||||
--> $DIR/ref-pat-suggestions.rs:31:14
|
||||
|
|
||||
LL | let (&mut _c,) = (0,);
|
||||
| ^^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - let (&mut _c,) = (0,);
|
||||
LL + let (_c,) = (0,);
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref-pat-suggestions.rs:34:13
|
||||
|
|
||||
LL | match 0 {
|
||||
| - this expression has type `{integer}`
|
||||
LL | &mut _d => {}
|
||||
| ^^^^^^^ expected integer, found `&mut _`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut _d`
|
||||
--> $DIR/ref-pat-suggestions.rs:34:13
|
||||
|
|
||||
LL | &mut _d => {}
|
||||
| ^^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - &mut _d => {}
|
||||
LL + _d => {}
|
||||
|
|
||||
|
||||
error: aborting due to 22 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -8,6 +8,11 @@ LL | for ((_, _), (&mut c, _)) in &mut map {
|
||||
|
|
||||
= note: expected type `char`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut c`
|
||||
--> $DIR/for-loop-bad-item.rs:7:19
|
||||
|
|
||||
LL | for ((_, _), (&mut c, _)) in &mut map {
|
||||
| ^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - for ((_, _), (&mut c, _)) in &mut map {
|
||||
|
Loading…
Reference in New Issue
Block a user