mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-22 20:03:37 +00:00
Account for ref
and mut
in the wrong place for pattern ident renaming
If the user writes `S { ref field: name }` instead of `S { field: ref name }`, we suggest the correct code. Fix #72298.
This commit is contained in:
parent
608e9682f0
commit
b589f47441
@ -967,11 +967,12 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
// check that a comma comes after every field
|
// check that a comma comes after every field
|
||||||
if !ate_comma {
|
if !ate_comma {
|
||||||
let err = ExpectedCommaAfterPatternField { span: self.token.span }
|
let mut err = ExpectedCommaAfterPatternField { span: self.token.span }
|
||||||
.into_diagnostic(&self.sess.span_diagnostic);
|
.into_diagnostic(&self.sess.span_diagnostic);
|
||||||
if let Some(mut delayed) = delayed_err {
|
if let Some(mut delayed) = delayed_err {
|
||||||
delayed.emit();
|
delayed.emit();
|
||||||
}
|
}
|
||||||
|
self.recover_misplaced_pattern_modifiers(&fields, &mut err);
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
ate_comma = false;
|
ate_comma = false;
|
||||||
@ -1109,6 +1110,37 @@ impl<'a> Parser<'a> {
|
|||||||
Ok((fields, etc))
|
Ok((fields, etc))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If the user writes `S { ref field: name }` instead of `S { field: ref name }`, we suggest
|
||||||
|
/// the correct code.
|
||||||
|
fn recover_misplaced_pattern_modifiers(
|
||||||
|
&self,
|
||||||
|
fields: &ThinVec<PatField>,
|
||||||
|
err: &mut DiagnosticBuilder<'a, ErrorGuaranteed>,
|
||||||
|
) {
|
||||||
|
if let Some(last) = fields.iter().last()
|
||||||
|
&& last.is_shorthand
|
||||||
|
&& let PatKind::Ident(binding, ident, None) = last.pat.kind
|
||||||
|
&& binding != BindingAnnotation::NONE
|
||||||
|
&& self.token == token::Colon
|
||||||
|
// We found `ref mut? ident:`, try to parse a `name,` or `name }`.
|
||||||
|
&& let Some(name_span) = self.look_ahead(1, |t| t.is_ident().then(|| t.span))
|
||||||
|
&& self.look_ahead(2, |t| {
|
||||||
|
t == &token::Comma || t == &token::CloseDelim(Delimiter::Brace)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
let span = last.pat.span.with_hi(ident.span.lo());
|
||||||
|
// We have `S { ref field: name }` instead of `S { field: ref name }`
|
||||||
|
err.multipart_suggestion(
|
||||||
|
"the pattern modifiers belong after the `:`",
|
||||||
|
vec![
|
||||||
|
(span, String::new()),
|
||||||
|
(name_span.shrink_to_lo(), binding.prefix_str().to_string()),
|
||||||
|
],
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Recover on `...` or `_` as if it were `..` to avoid further errors.
|
/// Recover on `...` or `_` as if it were `..` to avoid further errors.
|
||||||
/// See issue #46718.
|
/// See issue #46718.
|
||||||
fn recover_bad_dot_dot(&self) {
|
fn recover_bad_dot_dot(&self) {
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
// run-rustfix
|
||||||
|
struct S {
|
||||||
|
field_name: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match (S {field_name: ()}) {
|
||||||
|
S {field_name: ref _foo} => {} //~ ERROR expected `,`
|
||||||
|
}
|
||||||
|
match (S {field_name: ()}) {
|
||||||
|
S {field_name: mut _foo} => {} //~ ERROR expected `,`
|
||||||
|
}
|
||||||
|
match (S {field_name: ()}) {
|
||||||
|
S {field_name: ref mut _foo} => {} //~ ERROR expected `,`
|
||||||
|
}
|
||||||
|
// Verify that we recover enough to run typeck.
|
||||||
|
let _: usize = 3usize; //~ ERROR mismatched types
|
||||||
|
}
|
18
tests/ui/pattern/incorrect-placement-of-pattern-modifiers.rs
Normal file
18
tests/ui/pattern/incorrect-placement-of-pattern-modifiers.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// run-rustfix
|
||||||
|
struct S {
|
||||||
|
field_name: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match (S {field_name: ()}) {
|
||||||
|
S {ref field_name: _foo} => {} //~ ERROR expected `,`
|
||||||
|
}
|
||||||
|
match (S {field_name: ()}) {
|
||||||
|
S {mut field_name: _foo} => {} //~ ERROR expected `,`
|
||||||
|
}
|
||||||
|
match (S {field_name: ()}) {
|
||||||
|
S {ref mut field_name: _foo} => {} //~ ERROR expected `,`
|
||||||
|
}
|
||||||
|
// Verify that we recover enough to run typeck.
|
||||||
|
let _: usize = 3u8; //~ ERROR mismatched types
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
error: expected `,`
|
||||||
|
--> $DIR/incorrect-placement-of-pattern-modifiers.rs:8:26
|
||||||
|
|
|
||||||
|
LL | S {ref field_name: _foo} => {}
|
||||||
|
| - ^
|
||||||
|
| |
|
||||||
|
| while parsing the fields for this pattern
|
||||||
|
|
|
||||||
|
help: the pattern modifiers belong after the `:`
|
||||||
|
|
|
||||||
|
LL - S {ref field_name: _foo} => {}
|
||||||
|
LL + S {field_name: ref _foo} => {}
|
||||||
|
|
|
||||||
|
|
||||||
|
error: expected `,`
|
||||||
|
--> $DIR/incorrect-placement-of-pattern-modifiers.rs:11:26
|
||||||
|
|
|
||||||
|
LL | S {mut field_name: _foo} => {}
|
||||||
|
| - ^
|
||||||
|
| |
|
||||||
|
| while parsing the fields for this pattern
|
||||||
|
|
|
||||||
|
help: the pattern modifiers belong after the `:`
|
||||||
|
|
|
||||||
|
LL - S {mut field_name: _foo} => {}
|
||||||
|
LL + S {field_name: mut _foo} => {}
|
||||||
|
|
|
||||||
|
|
||||||
|
error: expected `,`
|
||||||
|
--> $DIR/incorrect-placement-of-pattern-modifiers.rs:14:30
|
||||||
|
|
|
||||||
|
LL | S {ref mut field_name: _foo} => {}
|
||||||
|
| - ^
|
||||||
|
| |
|
||||||
|
| while parsing the fields for this pattern
|
||||||
|
|
|
||||||
|
help: the pattern modifiers belong after the `:`
|
||||||
|
|
|
||||||
|
LL - S {ref mut field_name: _foo} => {}
|
||||||
|
LL + S {field_name: ref mut _foo} => {}
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/incorrect-placement-of-pattern-modifiers.rs:17:20
|
||||||
|
|
|
||||||
|
LL | let _: usize = 3u8;
|
||||||
|
| ----- ^^^ expected `usize`, found `u8`
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
help: change the type of the numeric literal from `u8` to `usize`
|
||||||
|
|
|
||||||
|
LL | let _: usize = 3usize;
|
||||||
|
| ~~~~~
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user