diff options
| author | bors <bors@rust-lang.org> | 2020-09-15 00:17:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-09-15 00:17:13 +0000 |
| commit | 255ceeb5ff9875b7f525aa101c8adc155f3e0ef8 (patch) | |
| tree | 37a3e1a5cd0ff5cb87c601e75234af92376a4303 | |
| parent | 9b4154193e8471f36b1a9e781f1ef7d492fc6a6c (diff) | |
| parent | 21f8326cec03848368e02936a032103aa24cf6d2 (diff) | |
| download | rust-255ceeb5ff9875b7f525aa101c8adc155f3e0ef8.tar.gz rust-255ceeb5ff9875b7f525aa101c8adc155f3e0ef8.zip | |
Auto merge of #76612 - estebank:pat-missing-fields-suggestion, r=davidtwco
Provide suggestion for missing fields in patterns
| -rw-r--r-- | compiler/rustc_typeck/src/check/pat.rs | 58 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0027-teach.rs | 15 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0027-teach.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0027.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0027.stderr | 26 | ||||
| -rw-r--r-- | src/test/ui/structs/struct-field-cfg.stderr | 9 | ||||
| -rw-r--r-- | src/test/ui/structs/struct-pat-derived-error.stderr | 9 |
7 files changed, 96 insertions, 38 deletions
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 171d5ee4ff2..6be2fdf9f19 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -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) { @@ -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) @@ -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 } diff --git a/src/test/ui/error-codes/E0027-teach.rs b/src/test/ui/error-codes/E0027-teach.rs deleted file mode 100644 index 11402f01484..00000000000 --- a/src/test/ui/error-codes/E0027-teach.rs +++ /dev/null @@ -1,15 +0,0 @@ -// compile-flags: -Z teach - -struct Dog { - name: String, - age: u32, -} - -fn main() { - let d = Dog { name: "Rusty".to_string(), age: 8 }; - - match d { - Dog { age: x } => {} - //~^ ERROR pattern does not mention field `name` - } -} diff --git a/src/test/ui/error-codes/E0027-teach.stderr b/src/test/ui/error-codes/E0027-teach.stderr deleted file mode 100644 index aa4cb9d4d18..00000000000 --- a/src/test/ui/error-codes/E0027-teach.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0027]: pattern does not mention field `name` - --> $DIR/E0027-teach.rs:12:9 - | -LL | Dog { age: x } => {} - | ^^^^^^^^^^^^^^ missing field `name` - | - = 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. - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0027`. diff --git a/src/test/ui/error-codes/E0027.rs b/src/test/ui/error-codes/E0027.rs index b8c6a2b7fcd..8d08e178934 100644 --- a/src/test/ui/error-codes/E0027.rs +++ b/src/test/ui/error-codes/E0027.rs @@ -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` } } diff --git a/src/test/ui/error-codes/E0027.stderr b/src/test/ui/error-codes/E0027.stderr index 4f17bba6477..c09f1ff1f2a 100644 --- a/src/test/ui/error-codes/E0027.stderr +++ b/src/test/ui/error-codes/E0027.stderr @@ -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`. diff --git a/src/test/ui/structs/struct-field-cfg.stderr b/src/test/ui/structs/struct-field-cfg.stderr index 29bad31ef96..b913b929079 100644 --- a/src/test/ui/structs/struct-field-cfg.stderr +++ b/src/test/ui/structs/struct-field-cfg.stderr @@ -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 diff --git a/src/test/ui/structs/struct-pat-derived-error.stderr b/src/test/ui/structs/struct-pat-derived-error.stderr index 6526ef58a44..f3e9ce76f1e 100644 --- a/src/test/ui/structs/struct-pat-derived-error.stderr +++ b/src/test/ui/structs/struct-pat-derived-error.stderr @@ -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 |
