Skip to content

Commit

Permalink
Auto merge of #76612 - estebank:pat-missing-fields-suggestion, r=davi…
Browse files Browse the repository at this point in the history
…dtwco

Provide suggestion for missing fields in patterns
  • Loading branch information
bors committed Sep 15, 2020
2 parents 9b41541 + 21f8326 commit 255ceeb
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 38 deletions.
58 changes: 49 additions & 9 deletions compiler/rustc_typeck/src/check/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if no_accessible_unmentioned_fields {
unmentioned_err = Some(self.error_no_accessible_fields(pat, &fields));
} else {
unmentioned_err = Some(self.error_unmentioned_fields(pat, &unmentioned_fields));
unmentioned_err =
Some(self.error_unmentioned_fields(pat, &unmentioned_fields, &fields));
}
}
match (inexistent_fields_err, unmentioned_err) {
Expand Down Expand Up @@ -1405,6 +1406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
pat: &Pat<'_>,
unmentioned_fields: &[(&ty::FieldDef, Ident)],
fields: &'tcx [hir::FieldPat<'tcx>],
) -> DiagnosticBuilder<'tcx> {
let field_names = if unmentioned_fields.len() == 1 {
format!("field `{}`", unmentioned_fields[0].1)
Expand All @@ -1424,14 +1426,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
field_names
);
err.span_label(pat.span, format!("missing {}", field_names));
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"This error indicates that a pattern for a struct fails to specify a \
sub-pattern for every one of the struct's fields. Ensure that each field \
from the struct's definition is mentioned in the pattern, or use `..` to \
ignore unwanted fields.",
);
}
let len = unmentioned_fields.len();
let (prefix, postfix, sp) = match fields {
[] => match &pat.kind {
PatKind::Struct(path, [], false) => {
(" { ", " }", path.span().shrink_to_hi().until(pat.span.shrink_to_hi()))
}
_ => return err,
},
[.., field] => (
match pat.kind {
PatKind::Struct(_, [_, ..], _) => ", ",
_ => "",
},
"",
field.span.shrink_to_hi(),
),
};
err.span_suggestion(
sp,
&format!(
"include the missing field{} in the pattern",
if len == 1 { "" } else { "s" },
),
format!(
"{}{}{}",
prefix,
unmentioned_fields
.iter()
.map(|(_, name)| name.to_string())
.collect::<Vec<_>>()
.join(", "),
postfix,
),
Applicability::MachineApplicable,
);
err.span_suggestion(
sp,
&format!(
"if you don't care about {} missing field{}, you can explicitely ignore {}",
if len == 1 { "this" } else { "these" },
if len == 1 { "" } else { "s" },
if len == 1 { "it" } else { "them" },
),
format!("{}..{}", prefix, postfix),
Applicability::MachineApplicable,
);
err
}

Expand Down
15 changes: 0 additions & 15 deletions src/test/ui/error-codes/E0027-teach.rs

This file was deleted.

11 changes: 0 additions & 11 deletions src/test/ui/error-codes/E0027-teach.stderr

This file was deleted.

6 changes: 4 additions & 2 deletions src/test/ui/error-codes/E0027.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ fn main() {
let d = Dog { name: "Rusty".to_string(), age: 8 };

match d {
Dog { age: x } => {}
//~^ ERROR pattern does not mention field `name`
Dog { age: x } => {} //~ ERROR pattern does not mention field `name`
}
match d {
Dog {} => {} //~ ERROR pattern does not mention fields `name`, `age`
}
}
26 changes: 25 additions & 1 deletion src/test/ui/error-codes/E0027.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,31 @@ error[E0027]: pattern does not mention field `name`
|
LL | Dog { age: x } => {}
| ^^^^^^^^^^^^^^ missing field `name`
|
help: include the missing field in the pattern
|
LL | Dog { age: x, name } => {}
| ^^^^^^
help: if you don't care about this missing field, you can explicitely ignore it
|
LL | Dog { age: x, .. } => {}
| ^^^^

error[E0027]: pattern does not mention fields `name`, `age`
--> $DIR/E0027.rs:13:9
|
LL | Dog {} => {}
| ^^^^^^ missing fields `name`, `age`
|
help: include the missing fields in the pattern
|
LL | Dog { name, age } => {}
| ^^^^^^^^^^^^^
help: if you don't care about these missing fields, you can explicitely ignore them
|
LL | Dog { .. } => {}
| ^^^^^^

error: aborting due to previous error
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0027`.
9 changes: 9 additions & 0 deletions src/test/ui/structs/struct-field-cfg.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ error[E0027]: pattern does not mention field `present`
|
LL | let Foo { #[cfg(any())] present: () } = foo;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `present`
|
help: include the missing field in the pattern
|
LL | let Foo { present } = foo;
| ^^^^^^^^^^^
help: if you don't care about this missing field, you can explicitely ignore it
|
LL | let Foo { .. } = foo;
| ^^^^^^

error[E0026]: struct `Foo` does not have a field named `absent`
--> $DIR/struct-field-cfg.rs:16:42
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/structs/struct-pat-derived-error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ error[E0027]: pattern does not mention fields `b`, `c`
|
LL | let A { x, y } = self.d;
| ^^^^^^^^^^ missing fields `b`, `c`
|
help: include the missing fields in the pattern
|
LL | let A { x, y, b, c } = self.d;
| ^^^^^^
help: if you don't care about these missing fields, you can explicitely ignore them
|
LL | let A { x, y, .. } = self.d;
| ^^^^

error: aborting due to 3 previous errors

Expand Down

0 comments on commit 255ceeb

Please sign in to comment.