Skip to content

Commit bd15684

Browse files
committed
improve non-exhaustive struct pat error
1 parent 58fee52 commit bd15684

File tree

3 files changed

+49
-8
lines changed

3 files changed

+49
-8
lines changed

src/librustc_typeck/check/pat.rs

+24-8
Original file line numberDiff line numberDiff line change
@@ -1082,14 +1082,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10821082

10831083
// Require `..` if struct has non_exhaustive attribute.
10841084
if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
1085-
struct_span_err!(
1086-
tcx.sess,
1087-
pat.span,
1088-
E0638,
1089-
"`..` required with {} marked as non-exhaustive",
1090-
adt.variant_descr()
1091-
)
1092-
.emit();
1085+
self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty());
10931086
}
10941087

10951088
// Report an error if incorrect number of the fields were specified.
@@ -1108,6 +1101,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11081101
no_field_errors
11091102
}
11101103

1104+
fn error_foreign_non_exhaustive_spat(&self, pat: &Pat<'_>, descr: &str, no_fields: bool) {
1105+
let sess = self.tcx.sess;
1106+
let sm = sess.source_map();
1107+
let sp_brace = sm.end_point(pat.span);
1108+
let sp_comma = sm.end_point(pat.span.with_hi(sp_brace.hi()));
1109+
let sugg = if no_fields || sp_brace != sp_comma { ".. }" } else { ", .. }" };
1110+
1111+
let mut err = struct_span_err!(
1112+
sess,
1113+
pat.span,
1114+
E0638,
1115+
"`..` required with {} marked as non-exhaustive",
1116+
descr
1117+
);
1118+
err.span_suggestion_verbose(
1119+
sp_comma,
1120+
"add `..` at the end of the field list",
1121+
sugg.to_string(),
1122+
Applicability::MachineApplicable,
1123+
);
1124+
err.emit();
1125+
}
1126+
11111127
fn error_field_already_bound(&self, span: Span, ident: ast::Ident, other_field: Span) {
11121128
struct_span_err!(
11131129
self.tcx.sess,

src/test/ui/rfc-2008-non-exhaustive/struct.stderr

+15
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,33 @@ error[E0638]: `..` required with struct marked as non-exhaustive
6262
|
6363
LL | let NormalStruct { first_field, second_field } = ns;
6464
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
65+
|
66+
help: add `..` at the end of the field list
67+
|
68+
LL | let NormalStruct { first_field, second_field , .. } = ns;
69+
| ^^^^^^
6570

6671
error[E0638]: `..` required with struct marked as non-exhaustive
6772
--> $DIR/struct.rs:26:9
6873
|
6974
LL | let TupleStruct { 0: first_field, 1: second_field } = ts;
7075
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76+
|
77+
help: add `..` at the end of the field list
78+
|
79+
LL | let TupleStruct { 0: first_field, 1: second_field , .. } = ts;
80+
| ^^^^^^
7181

7282
error[E0638]: `..` required with struct marked as non-exhaustive
7383
--> $DIR/struct.rs:35:9
7484
|
7585
LL | let UnitStruct { } = us;
7686
| ^^^^^^^^^^^^^^
87+
|
88+
help: add `..` at the end of the field list
89+
|
90+
LL | let UnitStruct { .. } = us;
91+
| ^^^^
7792

7893
error: aborting due to 9 previous errors
7994

src/test/ui/rfc-2008-non-exhaustive/variant.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,22 @@ error[E0638]: `..` required with variant marked as non-exhaustive
6969
|
7070
LL | NonExhaustiveVariants::Struct { field } => ""
7171
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
72+
|
73+
help: add `..` at the end of the field list
74+
|
75+
LL | NonExhaustiveVariants::Struct { field , .. } => ""
76+
| ^^^^^^
7277

7378
error[E0638]: `..` required with variant marked as non-exhaustive
7479
--> $DIR/variant.rs:30:12
7580
|
7681
LL | if let NonExhaustiveVariants::Struct { field } = variant_struct {
7782
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
83+
|
84+
help: add `..` at the end of the field list
85+
|
86+
LL | if let NonExhaustiveVariants::Struct { field , .. } = variant_struct {
87+
| ^^^^^^
7888

7989
error: aborting due to 8 previous errors
8090

0 commit comments

Comments
 (0)