Various fixes:
- Only show error when move-check would not be triggered - Add structured suggestion
This commit is contained in:
parent
4f76f1069a
commit
ed96c655c6
@ -163,7 +163,13 @@ enum MutblCap {
|
||||
|
||||
impl MutblCap {
|
||||
fn cap_mutbl_to_not(self, span: Option<Span>) -> Self {
|
||||
if self == MutblCap::Mut { MutblCap::Not(span) } else { self }
|
||||
if let Some(s) = span
|
||||
&& self != MutblCap::Not(None)
|
||||
{
|
||||
MutblCap::Not(Some(s))
|
||||
} else {
|
||||
MutblCap::Not(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn as_mutbl(self) -> Mutability {
|
||||
@ -744,9 +750,14 @@ fn check_pat_ident(
|
||||
self.tcx.dcx(),
|
||||
ident.span,
|
||||
E0596,
|
||||
"cannot bind with `ref mut` behind an `&` pattern"
|
||||
"cannot borrow as mutable inside an `&` pattern"
|
||||
);
|
||||
err.span_suggestion(
|
||||
and_pat_span,
|
||||
"replace this `&` with `&mut`",
|
||||
"&mut ",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.span_help(and_pat_span, "change this `&` pattern to an `&mut`");
|
||||
err.emit();
|
||||
}
|
||||
|
||||
@ -2187,7 +2198,21 @@ fn check_pat_ref(
|
||||
// the bad interactions of the given hack detailed in (note_1).
|
||||
debug!("check_pat_ref: expected={:?}", expected);
|
||||
match *expected.kind() {
|
||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty, pat_info),
|
||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
|
||||
let pat_info = if r_mutbl == Mutability::Not
|
||||
&& ((pat.span.at_least_rust_2024()
|
||||
&& self.tcx.features().ref_pat_eat_one_layer_2024)
|
||||
|| self.tcx.features().ref_pat_everywhere)
|
||||
{
|
||||
PatInfo {
|
||||
max_ref_mutbl: pat_info.max_ref_mutbl.cap_mutbl_to_not(None),
|
||||
..pat_info
|
||||
}
|
||||
} else {
|
||||
pat_info
|
||||
};
|
||||
(expected, r_ty, pat_info)
|
||||
}
|
||||
|
||||
// `&` pattern eats `&mut` reference
|
||||
ty::Ref(_, r_ty, Mutability::Mut)
|
||||
@ -2196,16 +2221,7 @@ fn check_pat_ref(
|
||||
&& self.tcx.features().ref_pat_eat_one_layer_2024)
|
||||
|| self.tcx.features().ref_pat_everywhere) =>
|
||||
{
|
||||
(
|
||||
expected,
|
||||
r_ty,
|
||||
PatInfo {
|
||||
max_ref_mutbl: pat_info
|
||||
.max_ref_mutbl
|
||||
.cap_mutbl_to_not(Some(pat.span.until(inner.span))),
|
||||
..pat_info
|
||||
},
|
||||
)
|
||||
(expected, r_ty, pat_info)
|
||||
}
|
||||
|
||||
_ if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere => {
|
||||
|
@ -24,18 +24,24 @@ pub fn main() {
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
||||
if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
|
||||
//~^ ERROR: cannot bind with `ref mut` behind an `&` pattern
|
||||
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
|
||||
}
|
||||
if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
|
||||
//~^ ERROR: cannot bind with `ref mut` behind an `&` pattern
|
||||
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
|
||||
}
|
||||
if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
||||
|
||||
let &mut _= &&0;
|
||||
let &mut _ = &&0;
|
||||
//~^ ERROR: mismatched types
|
||||
|
||||
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||
//~^ ERROR: mismatched types
|
||||
|
||||
macro_rules! pat {
|
||||
($var:ident) => { ref mut $var };
|
||||
}
|
||||
let &pat!(x) = &mut 0;
|
||||
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
|
||||
}
|
||||
|
@ -64,29 +64,21 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
= note: expected enum `Option<{integer}>`
|
||||
found mutable reference `&mut _`
|
||||
|
||||
error[E0596]: cannot bind with `ref mut` behind an `&` pattern
|
||||
error[E0596]: cannot borrow as mutable inside an `&` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:31
|
||||
|
|
||||
LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
|
||||
| ^
|
||||
|
|
||||
help: change this `&` pattern to an `&mut`
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17
|
||||
|
|
||||
LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
|
||||
| ^
|
||||
| - ^
|
||||
| |
|
||||
| help: replace this `&` with `&mut`: `&mut`
|
||||
|
||||
error[E0596]: cannot bind with `ref mut` behind an `&` pattern
|
||||
error[E0596]: cannot borrow as mutable inside an `&` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:29:31
|
||||
|
|
||||
LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
|
||||
| ^
|
||||
|
|
||||
help: change this `&` pattern to an `&mut`
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:29:12
|
||||
|
|
||||
LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
|
||||
| ^
|
||||
| - ^
|
||||
| |
|
||||
| help: replace this `&` with `&mut`: `&mut`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:17
|
||||
@ -102,8 +94,8 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:9
|
||||
|
|
||||
LL | let &mut _= &&0;
|
||||
| ^^^^^^ --- this expression has type `&&{integer}`
|
||||
LL | let &mut _ = &&0;
|
||||
| ^^^^^^ --- this expression has type `&&{integer}`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
|
|
||||
@ -121,7 +113,16 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
error[E0596]: cannot borrow as mutable inside an `&` pattern
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:15
|
||||
|
|
||||
LL | ($var:ident) => { ref mut $var };
|
||||
| ------------ help: replace this `&` with `&mut`: `&mut`
|
||||
LL | }
|
||||
LL | let &pat!(x) = &mut 0;
|
||||
| ^
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0596.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
@ -8,4 +8,7 @@ pub fn main() {
|
||||
//~^ ERROR: cannot move out of a shared reference [E0507]
|
||||
let _: &u32 = x;
|
||||
}
|
||||
|
||||
let &ref mut x = &0;
|
||||
//~^ cannot borrow data in a `&` reference as mutable [E0596]
|
||||
}
|
||||
|
@ -12,6 +12,13 @@ help: consider borrowing the pattern binding
|
||||
LL | if let Some(&Some(ref x)) = Some(&Some(&mut 0)) {
|
||||
| +++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0596]: cannot borrow data in a `&` reference as mutable
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:12:10
|
||||
|
|
||||
LL | let &ref mut x = &0;
|
||||
| ^^^^^^^^^ cannot borrow as mutable
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0507, E0596.
|
||||
For more information about an error, try `rustc --explain E0507`.
|
||||
|
Loading…
Reference in New Issue
Block a user