Skip to content

Commit 4b77e73

Browse files
committed
fake a base to suppress later extra error message
1 parent 1e25882 commit 4b77e73

File tree

4 files changed

+35
-41
lines changed

4 files changed

+35
-41
lines changed

compiler/rustc_parse/src/errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ pub(crate) struct MissingSemicolonBeforeArray {
373373
pub(crate) struct MissingDotDot {
374374
#[primary_span]
375375
pub token_span: Span,
376-
#[suggestion_verbose(applicability = "maybe-incorrect", code = "..")]
376+
#[suggestion(applicability = "maybe-incorrect", code = "..", style = "verbose")]
377377
pub sugg_span: Span,
378378
}
379379

compiler/rustc_parse/src/parser/expr.rs

+13-16
Original file line numberDiff line numberDiff line change
@@ -2880,7 +2880,7 @@ impl<'a> Parser<'a> {
28802880
};
28812881

28822882
while self.token != token::CloseDelim(close_delim) {
2883-
if self.eat(&token::DotDot) {
2883+
if self.eat(&token::DotDot) || self.recover_struct_fileds_dots(close_delim) {
28842884
let exp_span = self.prev_token.span;
28852885
// We permit `.. }` on the left-hand side of a destructuring assignment.
28862886
if self.check(&token::CloseDelim(close_delim)) {
@@ -2897,21 +2897,6 @@ impl<'a> Parser<'a> {
28972897
}
28982898
self.recover_struct_comma_after_dotdot(exp_span);
28992899
break;
2900-
} else if self.token == token::DotDotDot {
2901-
// suggest `..v` instead of `...v`
2902-
let snapshot = self.create_snapshot_for_diagnostic();
2903-
let span = self.token.span;
2904-
self.bump();
2905-
match self.parse_expr() {
2906-
Ok(_p) => {
2907-
self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span });
2908-
break;
2909-
}
2910-
Err(inner_err) => {
2911-
inner_err.cancel();
2912-
self.restore_snapshot(snapshot);
2913-
}
2914-
}
29152900
}
29162901

29172902
let recovery_field = self.find_struct_error_after_field_looking_code();
@@ -3042,6 +3027,18 @@ impl<'a> Parser<'a> {
30423027
self.recover_stmt();
30433028
}
30443029

3030+
fn recover_struct_fileds_dots(&mut self, close_delim: Delimiter) -> bool {
3031+
if !self.look_ahead(1, |t| *t == token::CloseDelim(close_delim))
3032+
&& self.eat(&token::DotDotDot)
3033+
{
3034+
// recover from typo of `...`, suggest `..`
3035+
let span = self.prev_token.span;
3036+
self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span });
3037+
return true;
3038+
}
3039+
false
3040+
}
3041+
30453042
/// Parses `ident (COLON expr)?`.
30463043
fn parse_expr_field(&mut self) -> PResult<'a, ExprField> {
30473044
let attrs = self.parse_outer_attributes()?;

src/test/ui/parser/issue-102806.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![allow(dead_code)]
22

3+
#[derive(Default)]
34
struct V3 {
45
x: f32,
56
y: f32,
@@ -9,14 +10,16 @@ struct V3 {
910
fn pz(v: V3) {
1011
let _ = V3 { z: 0.0, ...v};
1112
//~^ ERROR expected `..`
12-
//~| ERROR missing fields `x` and `y` in initializer of `V3`
13-
let _ = V3 { z: 0.0, ... };
14-
//~^ expected identifier
15-
//~| ERROR missing fields `x` and `y` in initializer of `V3`
1613

1714
let _ = V3 { z: 0.0, ...Default::default() };
1815
//~^ ERROR expected `..`
16+
17+
let _ = V3 { z: 0.0, ... };
18+
//~^ expected identifier
1919
//~| ERROR missing fields `x` and `y` in initializer of `V3`
20+
21+
let V3 { z: val, ... } = v;
22+
//~^ ERROR expected field pattern
2023
}
2124

2225
fn main() {}
+14-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: expected `..`, found `...`
2-
--> $DIR/issue-102806.rs:10:26
2+
--> $DIR/issue-102806.rs:11:26
33
|
44
LL | let _ = V3 { z: 0.0, ...v};
55
| ^^^
@@ -9,16 +9,8 @@ help: use `..` to fill in the rest of the fields
99
LL | let _ = V3 { z: 0.0, ..v};
1010
| ~~
1111

12-
error: expected identifier, found `...`
13-
--> $DIR/issue-102806.rs:13:26
14-
|
15-
LL | let _ = V3 { z: 0.0, ... };
16-
| -- ^^^ expected identifier
17-
| |
18-
| while parsing this struct
19-
2012
error: expected `..`, found `...`
21-
--> $DIR/issue-102806.rs:17:26
13+
--> $DIR/issue-102806.rs:14:26
2214
|
2315
LL | let _ = V3 { z: 0.0, ...Default::default() };
2416
| ^^^
@@ -28,24 +20,26 @@ help: use `..` to fill in the rest of the fields
2820
LL | let _ = V3 { z: 0.0, ..Default::default() };
2921
| ~~
3022

31-
error[E0063]: missing fields `x` and `y` in initializer of `V3`
32-
--> $DIR/issue-102806.rs:10:13
23+
error: expected identifier, found `...`
24+
--> $DIR/issue-102806.rs:17:26
3325
|
34-
LL | let _ = V3 { z: 0.0, ...v};
35-
| ^^ missing `x` and `y`
26+
LL | let _ = V3 { z: 0.0, ... };
27+
| -- ^^^ expected identifier
28+
| |
29+
| while parsing this struct
3630

37-
error[E0063]: missing fields `x` and `y` in initializer of `V3`
38-
--> $DIR/issue-102806.rs:13:13
31+
error: expected field pattern, found `...`
32+
--> $DIR/issue-102806.rs:21:22
3933
|
40-
LL | let _ = V3 { z: 0.0, ... };
41-
| ^^ missing `x` and `y`
34+
LL | let V3 { z: val, ... } = v;
35+
| ^^^ help: to omit remaining fields, use one fewer `.`: `..`
4236

4337
error[E0063]: missing fields `x` and `y` in initializer of `V3`
4438
--> $DIR/issue-102806.rs:17:13
4539
|
46-
LL | let _ = V3 { z: 0.0, ...Default::default() };
40+
LL | let _ = V3 { z: 0.0, ... };
4741
| ^^ missing `x` and `y`
4842

49-
error: aborting due to 6 previous errors
43+
error: aborting due to 5 previous errors
5044

5145
For more information about this error, try `rustc --explain E0063`.

0 commit comments

Comments
 (0)