Comments and fixes

This commit is contained in:
Jules Bertholet 2024-05-04 16:04:08 -04:00
parent 91bbbaa0f7
commit f57b970de8
No known key found for this signature in database
GPG Key ID: 32034DAFC38C1BFC
6 changed files with 132 additions and 55 deletions

View File

@ -137,8 +137,8 @@ enum AdjustMode {
/// with mutability matching the pattern, /// with mutability matching the pattern,
/// mark the pattern as having consumed this reference. /// mark the pattern as having consumed this reference.
/// ///
/// `Span` is that of the `&` or `&mut` itself /// `Span` is that of the `&` or `&mut` itself.
ResetAndConsumeRef(Mutability, Span), ResetAndConsumeRef(Mutability, Option<Span>),
/// Pass on the input binding mode and expected type. /// Pass on the input binding mode and expected type.
Pass, Pass,
} }
@ -154,15 +154,23 @@ enum AdjustMode {
/// this last case, so we need to throw an error ourselves. /// this last case, so we need to throw an error ourselves.
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum MutblCap { enum MutblCap {
/// Mutability restricted to immutable; /// Mutability restricted to immutable.
/// contained span, if present, should be shown in diagnostics as the reason. ///
Not(Option<Span>), /// The contained span, if present, points to an `&` pattern
/// that is the reason for the restriction,
/// and which will be reported in a diagnostic.
/// (Said diagnostic is shown only if
/// replacing the `&` pattern with `&mut` would allow the code to compile.)
///
/// (Outer [`Option`] is for whether to show the diagnostic,
/// inner [`Option`] is for whether we have a span we can report)
Not(Option<Option<Span>>),
/// No restriction on mutability /// No restriction on mutability
Mut, Mut,
} }
impl MutblCap { impl MutblCap {
fn cap_mutbl_to_not(self, span: Option<Span>) -> Self { fn cap_mutbl_to_not(self, span: Option<Option<Span>>) -> Self {
if let Some(s) = span if let Some(s) = span
&& self != MutblCap::Not(None) && self != MutblCap::Not(None)
{ {
@ -434,7 +442,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// ``` // ```
// //
// See issue #46688. // See issue #46688.
PatKind::Ref(inner, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl, pat.span.until(inner.span.find_ancestor_inside(pat.span).unwrap())), PatKind::Ref(inner, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl, inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end))),
// A `_` pattern works with any expected type, so there's no need to do anything. // A `_` pattern works with any expected type, so there's no need to do anything.
PatKind::Wild PatKind::Wild
// A malformed pattern doesn't have an expected type, so let's just accept any type. // A malformed pattern doesn't have an expected type, so let's just accept any type.
@ -752,12 +760,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
E0596, E0596,
"cannot borrow as mutable inside an `&` pattern" "cannot borrow as mutable inside an `&` pattern"
); );
err.span_suggestion(
and_pat_span, if let Some(span) = and_pat_span {
"replace this `&` with `&mut`", err.span_suggestion(
"&mut ", span,
Applicability::MachineApplicable, "replace this `&` with `&mut`",
); "&mut ",
Applicability::MachineApplicable,
);
}
err.emit(); err.emit();
} }

View File

@ -23,12 +23,6 @@ pub fn main() {
if let Some(&mut Some(x)) = &Some(Some(0)) { if let Some(&mut Some(x)) = &Some(Some(0)) {
//~^ ERROR: mismatched types //~^ ERROR: mismatched types
} }
if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
}
if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
//~^ 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
} }
@ -38,10 +32,4 @@ pub fn main() {
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
} }

View File

@ -64,24 +64,8 @@ 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 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: replace this `&` with `&mut`: `&mut`
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: replace this `&` with `&mut`: `&mut`
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:26:17
| |
LL | if let Some(&mut Some(x)) = &Some(Some(0)) { LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>` | ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
@ -92,7 +76,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
found mutable reference `&mut _` found mutable reference `&mut _`
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:30:9
| |
LL | let &mut _ = &&0; LL | let &mut _ = &&0;
| ^^^^^^ --- this expression has type `&&{integer}` | ^^^^^^ --- this expression has type `&&{integer}`
@ -103,7 +87,7 @@ LL | let &mut _ = &&0;
found mutable reference `&mut _` found mutable reference `&mut _`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:39:9 --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:33:9
| |
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
@ -113,15 +97,6 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
= note: expected type `{integer}` = note: expected type `{integer}`
found mutable reference `&mut _` found mutable reference `&mut _`
error[E0596]: cannot borrow as mutable inside an `&` pattern error: aborting due to 9 previous errors
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:15
|
LL | let &pat!(x) = &mut 0;
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`
error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0308, E0596.
For more information about an error, try `rustc --explain E0308`.

View File

@ -0,0 +1,30 @@
//@ edition: 2024
//@ compile-flags: -Zunstable-options
//@ run-rustfix
#![allow(incomplete_features)]
#![feature(ref_pat_eat_one_layer_2024)]
pub fn main() {
if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) {
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
}
if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) {
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
}
macro_rules! pat {
($var:ident) => { ref mut $var };
}
let &mut pat!(x) = &mut 0;
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
let &mut (ref mut a, ref mut b) = &mut (true, false);
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
//~| ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut bool = a;
let _: &mut bool = b;
}

View File

@ -0,0 +1,30 @@
//@ edition: 2024
//@ compile-flags: -Zunstable-options
//@ run-rustfix
#![allow(incomplete_features)]
#![feature(ref_pat_eat_one_layer_2024)]
pub fn main() {
if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
}
if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
}
macro_rules! pat {
($var:ident) => { ref mut $var };
}
let &pat!(x) = &mut 0;
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
let &(ref mut a, ref mut b) = &mut (true, false);
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
//~| ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut bool = a;
let _: &mut bool = b;
}

View File

@ -0,0 +1,43 @@
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:8:31
|
LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:13:31
|
LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:21:15
|
LL | let &pat!(x) = &mut 0;
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:19
|
LL | let &(ref mut a, ref mut b) = &mut (true, false);
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:30
|
LL | let &(ref mut a, ref mut b) = &mut (true, false);
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0596`.