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,
/// mark the pattern as having consumed this reference.
///
/// `Span` is that of the `&` or `&mut` itself
ResetAndConsumeRef(Mutability, Span),
/// `Span` is that of the `&` or `&mut` itself.
ResetAndConsumeRef(Mutability, Option<Span>),
/// Pass on the input binding mode and expected type.
Pass,
}
@ -154,15 +154,23 @@ enum AdjustMode {
/// this last case, so we need to throw an error ourselves.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum MutblCap {
/// Mutability restricted to immutable;
/// contained span, if present, should be shown in diagnostics as the reason.
Not(Option<Span>),
/// Mutability restricted to immutable.
///
/// 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
Mut,
}
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
&& self != MutblCap::Not(None)
{
@ -434,7 +442,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// ```
//
// 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.
PatKind::Wild
// 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,
"cannot borrow as mutable inside an `&` pattern"
);
err.span_suggestion(
and_pat_span,
"replace this `&` with `&mut`",
"&mut ",
Applicability::MachineApplicable,
);
if let Some(span) = and_pat_span {
err.span_suggestion(
span,
"replace this `&` with `&mut`",
"&mut ",
Applicability::MachineApplicable,
);
}
err.emit();
}

View File

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

View File

@ -64,24 +64,8 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
= note: expected enum `Option<{integer}>`
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
--> $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)) {
| ^^^^^^^^^^^^ -------------- 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 _`
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;
| ^^^^^^ --- this expression has type `&&{integer}`
@ -103,7 +87,7 @@ LL | let &mut _ = &&0;
found mutable reference `&mut _`
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;
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
@ -113,15 +97,6 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
= note: expected type `{integer}`
found mutable reference `&mut _`
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $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 9 previous errors
error: aborting due to 12 previous errors
Some errors have detailed explanations: E0308, E0596.
For more information about an error, try `rustc --explain E0308`.
For more information about this 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`.