Skip to content

Commit ca7dfb1

Browse files
authored
Rollup merge of #70386 - Centril:patty, r=estebank
typeck: minor pattern typing improvements r? @estebank
2 parents ef01fe6 + da10963 commit ca7dfb1

File tree

3 files changed

+52
-12
lines changed

3 files changed

+52
-12
lines changed

src/librustc_typeck/check/pat.rs

+27-12
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
835835
on_error();
836836
return tcx.types.err;
837837
}
838-
Res::Def(DefKind::AssocConst, _) | Res::Def(DefKind::AssocFn, _) => {
838+
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
839839
report_unexpected_res(res);
840840
return tcx.types.err;
841841
}
@@ -1020,7 +1020,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10201020
ty::Adt(adt, substs) => (substs, adt),
10211021
_ => span_bug!(pat.span, "struct pattern is not an ADT"),
10221022
};
1023-
let kind_name = adt.variant_descr();
10241023

10251024
// Index the struct fields' types.
10261025
let field_map = variant
@@ -1074,7 +1073,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10741073

10751074
if !inexistent_fields.is_empty() && !variant.recovered {
10761075
self.error_inexistent_fields(
1077-
kind_name,
1076+
adt.variant_descr(),
10781077
&inexistent_fields,
10791078
&mut unmentioned_fields,
10801079
variant,
@@ -1083,18 +1082,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10831082

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

10961088
// Report an error if incorrect number of the fields were specified.
1097-
if kind_name == "union" {
1089+
if adt.is_union() {
10981090
if fields.len() != 1 {
10991091
tcx.sess
11001092
.struct_span_err(pat.span, "union patterns should have exactly one field")
@@ -1109,6 +1101,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11091101
no_field_errors
11101102
}
11111103

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 to ignore all other fields",
1121+
sugg.to_string(),
1122+
Applicability::MachineApplicable,
1123+
);
1124+
err.emit();
1125+
}
1126+
11121127
fn error_field_already_bound(&self, span: Span, ident: ast::Ident, other_field: Span) {
11131128
struct_span_err!(
11141129
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 to ignore all other fields
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 to ignore all other fields
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 to ignore all other fields
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 to ignore all other fields
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 to ignore all other fields
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)