@@ -904,6 +904,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
904
904
// Keep track of which fields have already appeared in the pattern.
905
905
let mut used_fields = FxHashMap ( ) ;
906
906
907
+ let mut inexistent_fields = vec ! [ ] ;
907
908
// Typecheck each field.
908
909
for & Spanned { node : ref field, span } in fields {
909
910
let field_ty = match used_fields. entry ( field. name ) {
@@ -927,34 +928,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
927
928
self . field_ty ( span, f, substs)
928
929
} )
929
930
. unwrap_or_else ( || {
930
- let mut err = struct_span_err ! (
931
- tcx. sess,
932
- span,
933
- E0026 ,
934
- "{} `{}` does not have a field named `{}`" ,
935
- kind_name,
936
- tcx. item_path_str( variant. did) ,
937
- field. name
938
- ) ;
939
- err. span_label ( span,
940
- format ! ( "{} `{}` does not have field `{}`" ,
941
- kind_name,
942
- tcx. item_path_str( variant. did) ,
943
- field. name) ) ;
944
- if tcx. sess . teach ( & err. get_code ( ) . unwrap ( ) ) {
945
- err. note (
946
- "This error indicates that a struct pattern attempted to \
947
- extract a non-existent field from a struct. Struct fields \
948
- are identified by the name used before the colon : so struct \
949
- patterns should resemble the declaration of the struct type \
950
- being matched.\n \n \
951
- If you are using shorthand field patterns but want to refer \
952
- to the struct field by a different name, you should rename \
953
- it explicitly."
954
- ) ;
955
- }
956
- err. emit ( ) ;
957
-
931
+ inexistent_fields. push ( ( span, field. name ) ) ;
958
932
tcx. types . err
959
933
} )
960
934
}
@@ -963,6 +937,46 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
963
937
self . check_pat_walk ( & field. pat , field_ty, def_bm, true ) ;
964
938
}
965
939
940
+ if inexistent_fields. len ( ) > 0 {
941
+ let field_names = if inexistent_fields. len ( ) == 1 {
942
+ format ! ( "a field named `{}`" , inexistent_fields[ 0 ] . 1 )
943
+ } else {
944
+ format ! ( "fields named {}" ,
945
+ inexistent_fields. iter( )
946
+ . map( |( _, name) | format!( "`{}`" , name) )
947
+ . collect:: <Vec <String >>( )
948
+ . join( ", " ) )
949
+ } ;
950
+ let spans = inexistent_fields. iter ( ) . map ( |( span, _) | * span) . collect :: < Vec < _ > > ( ) ;
951
+ let mut err = struct_span_err ! ( tcx. sess,
952
+ spans,
953
+ E0026 ,
954
+ "{} `{}` does not have {}" ,
955
+ kind_name,
956
+ tcx. item_path_str( variant. did) ,
957
+ field_names) ;
958
+ for ( span, name) in & inexistent_fields {
959
+ err. span_label ( * span,
960
+ format ! ( "{} `{}` does not have field `{}`" ,
961
+ kind_name,
962
+ tcx. item_path_str( variant. did) ,
963
+ name) ) ;
964
+ }
965
+ if tcx. sess . teach ( & err. get_code ( ) . unwrap ( ) ) {
966
+ err. note (
967
+ "This error indicates that a struct pattern attempted to \
968
+ extract a non-existent field from a struct. Struct fields \
969
+ are identified by the name used before the colon : so struct \
970
+ patterns should resemble the declaration of the struct type \
971
+ being matched.\n \n \
972
+ If you are using shorthand field patterns but want to refer \
973
+ to the struct field by a different name, you should rename \
974
+ it explicitly."
975
+ ) ;
976
+ }
977
+ err. emit ( ) ;
978
+ }
979
+
966
980
// Require `..` if struct has non_exhaustive attribute.
967
981
if adt. is_struct ( ) && adt. is_non_exhaustive ( ) && !adt. did . is_local ( ) && !etc {
968
982
span_err ! ( tcx. sess, span, E0638 ,
0 commit comments