Skip to content

Commit 5fbfcd8

Browse files
committed
typeck/pat.rs: extract error_inexistent_fields.
1 parent ba2a784 commit 5fbfcd8

File tree

1 file changed

+74
-56
lines changed
  • src/librustc_typeck/check

1 file changed

+74
-56
lines changed

src/librustc_typeck/check/pat.rs

Lines changed: 74 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -796,66 +796,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
796796

797797
self.check_pat(&field.pat, field_ty, def_bm, None);
798798
}
799+
799800
let mut unmentioned_fields = variant.fields
800801
.iter()
801802
.map(|field| field.ident.modern())
802803
.filter(|ident| !used_fields.contains_key(&ident))
803804
.collect::<Vec<_>>();
804-
if inexistent_fields.len() > 0 && !variant.recovered {
805-
let (field_names, t, plural) = if inexistent_fields.len() == 1 {
806-
(format!("a field named `{}`", inexistent_fields[0]), "this", "")
807-
} else {
808-
(format!("fields named {}",
809-
inexistent_fields.iter()
810-
.map(|ident| format!("`{}`", ident))
811-
.collect::<Vec<String>>()
812-
.join(", ")), "these", "s")
813-
};
814-
let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
815-
let mut err = struct_span_err!(tcx.sess,
816-
spans,
817-
E0026,
818-
"{} `{}` does not have {}",
819-
kind_name,
820-
tcx.def_path_str(variant.def_id),
821-
field_names);
822-
if let Some(ident) = inexistent_fields.last() {
823-
err.span_label(ident.span,
824-
format!("{} `{}` does not have {} field{}",
825-
kind_name,
826-
tcx.def_path_str(variant.def_id),
827-
t,
828-
plural));
829-
if plural == "" {
830-
let input = unmentioned_fields.iter().map(|field| &field.name);
831-
let suggested_name =
832-
find_best_match_for_name(input, &ident.as_str(), None);
833-
if let Some(suggested_name) = suggested_name {
834-
err.span_suggestion(
835-
ident.span,
836-
"a field with a similar name exists",
837-
suggested_name.to_string(),
838-
Applicability::MaybeIncorrect,
839-
);
840805

841-
// we don't want to throw `E0027` in case we have thrown `E0026` for them
842-
unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
843-
}
844-
}
845-
}
846-
if tcx.sess.teach(&err.get_code().unwrap()) {
847-
err.note(
848-
"This error indicates that a struct pattern attempted to \
849-
extract a non-existent field from a struct. Struct fields \
850-
are identified by the name used before the colon : so struct \
851-
patterns should resemble the declaration of the struct type \
852-
being matched.\n\n\
853-
If you are using shorthand field patterns but want to refer \
854-
to the struct field by a different name, you should rename \
855-
it explicitly."
856-
);
857-
}
858-
err.emit();
806+
if inexistent_fields.len() > 0 && !variant.recovered {
807+
self.error_inexistent_fields(
808+
kind_name,
809+
&inexistent_fields,
810+
&mut unmentioned_fields,
811+
variant
812+
);
859813
}
860814

861815
// Require `..` if struct has non_exhaustive attribute.
@@ -874,7 +828,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
874828
tcx.sess.span_err(span, "`..` cannot be used in union patterns");
875829
}
876830
} else if !etc && unmentioned_fields.len() > 0 {
877-
self.error_unmentioned_fields(span, unmentioned_fields, variant);
831+
self.error_unmentioned_fields(span, &unmentioned_fields, variant);
878832
}
879833
no_field_errors
880834
}
@@ -890,10 +844,74 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
890844
.emit();
891845
}
892846

847+
fn error_inexistent_fields(
848+
&self,
849+
kind_name: &str,
850+
inexistent_fields: &[ast::Ident],
851+
unmentioned_fields: &mut Vec<ast::Ident>,
852+
variant: &ty::VariantDef,
853+
) {
854+
let tcx = self.tcx;
855+
let (field_names, t, plural) = if inexistent_fields.len() == 1 {
856+
(format!("a field named `{}`", inexistent_fields[0]), "this", "")
857+
} else {
858+
(format!("fields named {}",
859+
inexistent_fields.iter()
860+
.map(|ident| format!("`{}`", ident))
861+
.collect::<Vec<String>>()
862+
.join(", ")), "these", "s")
863+
};
864+
let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
865+
let mut err = struct_span_err!(tcx.sess,
866+
spans,
867+
E0026,
868+
"{} `{}` does not have {}",
869+
kind_name,
870+
tcx.def_path_str(variant.def_id),
871+
field_names);
872+
if let Some(ident) = inexistent_fields.last() {
873+
err.span_label(ident.span,
874+
format!("{} `{}` does not have {} field{}",
875+
kind_name,
876+
tcx.def_path_str(variant.def_id),
877+
t,
878+
plural));
879+
if plural == "" {
880+
let input = unmentioned_fields.iter().map(|field| &field.name);
881+
let suggested_name =
882+
find_best_match_for_name(input, &ident.as_str(), None);
883+
if let Some(suggested_name) = suggested_name {
884+
err.span_suggestion(
885+
ident.span,
886+
"a field with a similar name exists",
887+
suggested_name.to_string(),
888+
Applicability::MaybeIncorrect,
889+
);
890+
891+
// we don't want to throw `E0027` in case we have thrown `E0026` for them
892+
unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
893+
}
894+
}
895+
}
896+
if tcx.sess.teach(&err.get_code().unwrap()) {
897+
err.note(
898+
"This error indicates that a struct pattern attempted to \
899+
extract a non-existent field from a struct. Struct fields \
900+
are identified by the name used before the colon : so struct \
901+
patterns should resemble the declaration of the struct type \
902+
being matched.\n\n\
903+
If you are using shorthand field patterns but want to refer \
904+
to the struct field by a different name, you should rename \
905+
it explicitly."
906+
);
907+
}
908+
err.emit();
909+
}
910+
893911
fn error_unmentioned_fields(
894912
&self,
895913
span: Span,
896-
unmentioned_fields: Vec<ast::Ident>,
914+
unmentioned_fields: &[ast::Ident],
897915
variant: &ty::VariantDef,
898916
) {
899917
let field_names = if unmentioned_fields.len() == 1 {

0 commit comments

Comments
 (0)