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 {
|
impl MutblCap {
|
||||||
fn cap_mutbl_to_not(self, span: Option<Span>) -> Self {
|
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 {
|
fn as_mutbl(self) -> Mutability {
|
||||||
@ -744,9 +750,14 @@ fn check_pat_ident(
|
|||||||
self.tcx.dcx(),
|
self.tcx.dcx(),
|
||||||
ident.span,
|
ident.span,
|
||||||
E0596,
|
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();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2187,7 +2198,21 @@ fn check_pat_ref(
|
|||||||
// the bad interactions of the given hack detailed in (note_1).
|
// the bad interactions of the given hack detailed in (note_1).
|
||||||
debug!("check_pat_ref: expected={:?}", expected);
|
debug!("check_pat_ref: expected={:?}", expected);
|
||||||
match *expected.kind() {
|
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
|
// `&` pattern eats `&mut` reference
|
||||||
ty::Ref(_, r_ty, Mutability::Mut)
|
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_eat_one_layer_2024)
|
||||||
|| self.tcx.features().ref_pat_everywhere) =>
|
|| self.tcx.features().ref_pat_everywhere) =>
|
||||||
{
|
{
|
||||||
(
|
(expected, r_ty, pat_info)
|
||||||
expected,
|
|
||||||
r_ty,
|
|
||||||
PatInfo {
|
|
||||||
max_ref_mutbl: pat_info
|
|
||||||
.max_ref_mutbl
|
|
||||||
.cap_mutbl_to_not(Some(pat.span.until(inner.span))),
|
|
||||||
..pat_info
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere => {
|
_ if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere => {
|
||||||
|
@ -24,18 +24,24 @@ pub fn main() {
|
|||||||
//~^ ERROR: mismatched types
|
//~^ ERROR: mismatched types
|
||||||
}
|
}
|
||||||
if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
|
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)) {
|
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)) {
|
if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||||
//~^ ERROR: mismatched types
|
//~^ ERROR: mismatched types
|
||||||
}
|
}
|
||||||
|
|
||||||
let &mut _= &&0;
|
let &mut _ = &&0;
|
||||||
//~^ ERROR: mismatched types
|
//~^ ERROR: mismatched types
|
||||||
|
|
||||||
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||||
//~^ ERROR: mismatched types
|
//~^ 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}>`
|
= note: expected enum `Option<{integer}>`
|
||||||
found mutable reference `&mut _`
|
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
|
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:31
|
||||||
|
|
|
|
||||||
LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
|
LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
|
||||||
| ^
|
| - ^
|
||||||
|
|
| |
|
||||||
help: change this `&` pattern to an `&mut`
|
| help: replace this `&` with `&mut`: `&mut`
|
||||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17
|
|
||||||
|
|
|
||||||
LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
|
|
||||||
| ^
|
|
||||||
|
|
||||||
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
|
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:29:31
|
||||||
|
|
|
|
||||||
LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
|
LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
|
||||||
| ^
|
| - ^
|
||||||
|
|
| |
|
||||||
help: change this `&` pattern to an `&mut`
|
| help: replace this `&` with `&mut`: `&mut`
|
||||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:29:12
|
|
||||||
|
|
|
||||||
LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
|
|
||||||
| ^
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:17
|
--> $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
|
error[E0308]: mismatched types
|
||||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:9
|
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:9
|
||||||
|
|
|
|
||||||
LL | let &mut _= &&0;
|
LL | let &mut _ = &&0;
|
||||||
| ^^^^^^ --- this expression has type `&&{integer}`
|
| ^^^^^^ --- this expression has type `&&{integer}`
|
||||||
| |
|
| |
|
||||||
| expected integer, found `&mut _`
|
| expected integer, found `&mut _`
|
||||||
|
|
|
|
||||||
@ -121,7 +113,16 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
|||||||
= note: expected type `{integer}`
|
= note: expected type `{integer}`
|
||||||
found mutable reference `&mut _`
|
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.
|
Some errors have detailed explanations: E0308, E0596.
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
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]
|
//~^ ERROR: cannot move out of a shared reference [E0507]
|
||||||
let _: &u32 = x;
|
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)) {
|
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