Skip to content

Commit a2a57bc

Browse files
committed
Fixes #63962. Hint about missing tuple parentheses in patterns
1 parent ed8b708 commit a2a57bc

File tree

3 files changed

+53
-11
lines changed

3 files changed

+53
-11
lines changed

src/librustc_typeck/check/pat.rs

+34-7
Original file line numberDiff line numberDiff line change
@@ -676,18 +676,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
676676
}
677677
} else {
678678
// Pattern has wrong number of fields.
679-
self.e0023(pat.span, res, &subpats, &variant.fields);
679+
self.e0023(pat.span, res, &subpats, &variant.fields, expected);
680680
on_error();
681681
return tcx.types.err;
682682
}
683683
pat_ty
684684
}
685685

686-
fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P<Pat>], fields: &[ty::FieldDef]) {
686+
fn e0023(
687+
&self,
688+
pat_span: Span,
689+
res: Res,
690+
subpats: &'tcx [P<Pat>],
691+
fields: &[ty::FieldDef],
692+
expected: Ty<'tcx>
693+
) {
687694
let subpats_ending = pluralise!(subpats.len());
688695
let fields_ending = pluralise!(fields.len());
696+
let missing_parenthesis = match expected.sty {
697+
ty::Adt(_, substs) if fields.len() == 1 => {
698+
let field_ty = fields[0].ty(self.tcx, substs);
699+
match field_ty.sty {
700+
ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(),
701+
_ => false,
702+
}
703+
}
704+
_ => false,
705+
};
689706
let res_span = self.tcx.def_span(res.def_id());
690-
struct_span_err!(
707+
let mut err = struct_span_err!(
691708
self.tcx.sess,
692709
pat_span,
693710
E0023,
@@ -697,15 +714,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
697714
res.descr(),
698715
fields.len(),
699716
fields_ending,
700-
)
701-
.span_label(pat_span, format!(
717+
);
718+
err.span_label(pat_span, format!(
702719
"expected {} field{}, found {}",
703720
fields.len(),
704721
fields_ending,
705722
subpats.len(),
706723
))
707-
.span_label(res_span, format!("{} defined here", res.descr()))
708-
.emit();
724+
.span_label(res_span, format!("{} defined here", res.descr()));
725+
726+
if missing_parenthesis {
727+
err.multipart_suggestion(
728+
"missing parenthesis",
729+
vec![(subpats[0].span.shrink_to_lo(), "(".to_string()),
730+
(subpats[subpats.len()-1].span.shrink_to_hi(), ")".to_string())],
731+
Applicability::MachineApplicable,
732+
);
733+
}
734+
735+
err.emit();
709736
}
710737

711738
fn check_pat_tuple(

src/test/ui/error-codes/E0023.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
enum Fruit {
22
Apple(String, String),
33
Pear(u32),
4+
Orange((String, String)),
45
}
56

67

@@ -10,5 +11,6 @@ fn main() {
1011
Fruit::Apple(a) => {}, //~ ERROR E0023
1112
Fruit::Apple(a, b, c) => {}, //~ ERROR E0023
1213
Fruit::Pear(1, 2) => {}, //~ ERROR E0023
14+
Fruit::Orange(a, b) => {}, //~ ERROR E0023
1315
}
1416
}

src/test/ui/error-codes/E0023.stderr

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
2-
--> $DIR/E0023.rs:10:9
2+
--> $DIR/E0023.rs:11:9
33
|
44
LL | Apple(String, String),
55
| --------------------- tuple variant defined here
@@ -8,7 +8,7 @@ LL | Fruit::Apple(a) => {},
88
| ^^^^^^^^^^^^^^^ expected 2 fields, found 1
99

1010
error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
11-
--> $DIR/E0023.rs:11:9
11+
--> $DIR/E0023.rs:12:9
1212
|
1313
LL | Apple(String, String),
1414
| --------------------- tuple variant defined here
@@ -17,14 +17,27 @@ LL | Fruit::Apple(a, b, c) => {},
1717
| ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
1818

1919
error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
20-
--> $DIR/E0023.rs:12:9
20+
--> $DIR/E0023.rs:13:9
2121
|
2222
LL | Pear(u32),
2323
| --------- tuple variant defined here
2424
...
2525
LL | Fruit::Pear(1, 2) => {},
2626
| ^^^^^^^^^^^^^^^^^ expected 1 field, found 2
2727

28-
error: aborting due to 3 previous errors
28+
error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
29+
--> $DIR/E0023.rs:14:9
30+
|
31+
LL | Orange((String, String)),
32+
| ------------------------ tuple variant defined here
33+
...
34+
LL | Fruit::Orange(a, b) => {},
35+
| ^^^^^^^^^^^^^^^^^^^ expected 1 field, found 2
36+
help: missing parenthesis
37+
|
38+
LL | Fruit::Orange((a, b)) => {},
39+
| ^ ^
40+
41+
error: aborting due to 4 previous errors
2942

3043
For more information about this error, try `rustc --explain E0023`.

0 commit comments

Comments
 (0)