fake a base to suppress later extra error message

This commit is contained in:
yukang 2022-10-14 06:52:23 +08:00
parent 1e25882944
commit 4b77e730b5
4 changed files with 36 additions and 42 deletions

View File

@ -373,7 +373,7 @@ pub(crate) struct MissingSemicolonBeforeArray {
pub(crate) struct MissingDotDot { pub(crate) struct MissingDotDot {
#[primary_span] #[primary_span]
pub token_span: Span, pub token_span: Span,
#[suggestion_verbose(applicability = "maybe-incorrect", code = "..")] #[suggestion(applicability = "maybe-incorrect", code = "..", style = "verbose")]
pub sugg_span: Span, pub sugg_span: Span,
} }

View File

@ -2880,7 +2880,7 @@ impl<'a> Parser<'a> {
}; };
while self.token != token::CloseDelim(close_delim) { while self.token != token::CloseDelim(close_delim) {
if self.eat(&token::DotDot) { if self.eat(&token::DotDot) || self.recover_struct_fileds_dots(close_delim) {
let exp_span = self.prev_token.span; let exp_span = self.prev_token.span;
// We permit `.. }` on the left-hand side of a destructuring assignment. // We permit `.. }` on the left-hand side of a destructuring assignment.
if self.check(&token::CloseDelim(close_delim)) { if self.check(&token::CloseDelim(close_delim)) {
@ -2897,21 +2897,6 @@ impl<'a> Parser<'a> {
} }
self.recover_struct_comma_after_dotdot(exp_span); self.recover_struct_comma_after_dotdot(exp_span);
break; break;
} else if self.token == token::DotDotDot {
// suggest `..v` instead of `...v`
let snapshot = self.create_snapshot_for_diagnostic();
let span = self.token.span;
self.bump();
match self.parse_expr() {
Ok(_p) => {
self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span });
break;
}
Err(inner_err) => {
inner_err.cancel();
self.restore_snapshot(snapshot);
}
}
} }
let recovery_field = self.find_struct_error_after_field_looking_code(); let recovery_field = self.find_struct_error_after_field_looking_code();
@ -3042,6 +3027,18 @@ impl<'a> Parser<'a> {
self.recover_stmt(); self.recover_stmt();
} }
fn recover_struct_fileds_dots(&mut self, close_delim: Delimiter) -> bool {
if !self.look_ahead(1, |t| *t == token::CloseDelim(close_delim))
&& self.eat(&token::DotDotDot)
{
// recover from typo of `...`, suggest `..`
let span = self.prev_token.span;
self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span });
return true;
}
false
}
/// Parses `ident (COLON expr)?`. /// Parses `ident (COLON expr)?`.
fn parse_expr_field(&mut self) -> PResult<'a, ExprField> { fn parse_expr_field(&mut self) -> PResult<'a, ExprField> {
let attrs = self.parse_outer_attributes()?; let attrs = self.parse_outer_attributes()?;

View File

@ -1,5 +1,6 @@
#![allow(dead_code)] #![allow(dead_code)]
#[derive(Default)]
struct V3 { struct V3 {
x: f32, x: f32,
y: f32, y: f32,
@ -9,14 +10,16 @@ struct V3 {
fn pz(v: V3) { fn pz(v: V3) {
let _ = V3 { z: 0.0, ...v}; let _ = V3 { z: 0.0, ...v};
//~^ ERROR expected `..` //~^ ERROR expected `..`
//~| ERROR missing fields `x` and `y` in initializer of `V3`
let _ = V3 { z: 0.0, ...Default::default() };
//~^ ERROR expected `..`
let _ = V3 { z: 0.0, ... }; let _ = V3 { z: 0.0, ... };
//~^ expected identifier //~^ expected identifier
//~| ERROR missing fields `x` and `y` in initializer of `V3` //~| ERROR missing fields `x` and `y` in initializer of `V3`
let _ = V3 { z: 0.0, ...Default::default() }; let V3 { z: val, ... } = v;
//~^ ERROR expected `..` //~^ ERROR expected field pattern
//~| ERROR missing fields `x` and `y` in initializer of `V3`
} }
fn main() {} fn main() {}

View File

@ -1,5 +1,5 @@
error: expected `..`, found `...` error: expected `..`, found `...`
--> $DIR/issue-102806.rs:10:26 --> $DIR/issue-102806.rs:11:26
| |
LL | let _ = V3 { z: 0.0, ...v}; LL | let _ = V3 { z: 0.0, ...v};
| ^^^ | ^^^
@ -9,16 +9,8 @@ help: use `..` to fill in the rest of the fields
LL | let _ = V3 { z: 0.0, ..v}; LL | let _ = V3 { z: 0.0, ..v};
| ~~ | ~~
error: expected identifier, found `...`
--> $DIR/issue-102806.rs:13:26
|
LL | let _ = V3 { z: 0.0, ... };
| -- ^^^ expected identifier
| |
| while parsing this struct
error: expected `..`, found `...` error: expected `..`, found `...`
--> $DIR/issue-102806.rs:17:26 --> $DIR/issue-102806.rs:14:26
| |
LL | let _ = V3 { z: 0.0, ...Default::default() }; LL | let _ = V3 { z: 0.0, ...Default::default() };
| ^^^ | ^^^
@ -28,24 +20,26 @@ help: use `..` to fill in the rest of the fields
LL | let _ = V3 { z: 0.0, ..Default::default() }; LL | let _ = V3 { z: 0.0, ..Default::default() };
| ~~ | ~~
error[E0063]: missing fields `x` and `y` in initializer of `V3` error: expected identifier, found `...`
--> $DIR/issue-102806.rs:10:13 --> $DIR/issue-102806.rs:17:26
|
LL | let _ = V3 { z: 0.0, ...v};
| ^^ missing `x` and `y`
error[E0063]: missing fields `x` and `y` in initializer of `V3`
--> $DIR/issue-102806.rs:13:13
| |
LL | let _ = V3 { z: 0.0, ... }; LL | let _ = V3 { z: 0.0, ... };
| ^^ missing `x` and `y` | -- ^^^ expected identifier
| |
| while parsing this struct
error: expected field pattern, found `...`
--> $DIR/issue-102806.rs:21:22
|
LL | let V3 { z: val, ... } = v;
| ^^^ help: to omit remaining fields, use one fewer `.`: `..`
error[E0063]: missing fields `x` and `y` in initializer of `V3` error[E0063]: missing fields `x` and `y` in initializer of `V3`
--> $DIR/issue-102806.rs:17:13 --> $DIR/issue-102806.rs:17:13
| |
LL | let _ = V3 { z: 0.0, ...Default::default() }; LL | let _ = V3 { z: 0.0, ... };
| ^^ missing `x` and `y` | ^^ missing `x` and `y`
error: aborting due to 6 previous errors error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0063`. For more information about this error, try `rustc --explain E0063`.