@@ -835,7 +835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
835
835
on_error ( ) ;
836
836
return tcx. types . err ;
837
837
}
838
- Res :: Def ( DefKind :: AssocConst , _ ) | Res :: Def ( DefKind :: AssocFn , _) => {
838
+ Res :: Def ( DefKind :: AssocConst | DefKind :: AssocFn , _) => {
839
839
report_unexpected_res ( res) ;
840
840
return tcx. types . err ;
841
841
}
@@ -1020,7 +1020,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1020
1020
ty:: Adt ( adt, substs) => ( substs, adt) ,
1021
1021
_ => span_bug ! ( pat. span, "struct pattern is not an ADT" ) ,
1022
1022
} ;
1023
- let kind_name = adt. variant_descr ( ) ;
1024
1023
1025
1024
// Index the struct fields' types.
1026
1025
let field_map = variant
@@ -1074,7 +1073,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1074
1073
1075
1074
if !inexistent_fields. is_empty ( ) && !variant. recovered {
1076
1075
self . error_inexistent_fields (
1077
- kind_name ,
1076
+ adt . variant_descr ( ) ,
1078
1077
& inexistent_fields,
1079
1078
& mut unmentioned_fields,
1080
1079
variant,
@@ -1083,18 +1082,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1083
1082
1084
1083
// Require `..` if struct has non_exhaustive attribute.
1085
1084
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 ( ) ) ;
1094
1086
}
1095
1087
1096
1088
// Report an error if incorrect number of the fields were specified.
1097
- if kind_name == "union" {
1089
+ if adt . is_union ( ) {
1098
1090
if fields. len ( ) != 1 {
1099
1091
tcx. sess
1100
1092
. struct_span_err ( pat. span , "union patterns should have exactly one field" )
@@ -1109,6 +1101,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1109
1101
no_field_errors
1110
1102
}
1111
1103
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
+
1112
1127
fn error_field_already_bound ( & self , span : Span , ident : ast:: Ident , other_field : Span ) {
1113
1128
struct_span_err ! (
1114
1129
self . tcx. sess,
0 commit comments