Auto merge of #76612 - estebank:pat-missing-fields-suggestion, r=davidtwco
Provide suggestion for missing fields in patterns
This commit is contained in:
commit
255ceeb5ff
7 changed files with 96 additions and 38 deletions
|
@ -1150,7 +1150,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if no_accessible_unmentioned_fields {
|
if no_accessible_unmentioned_fields {
|
||||||
unmentioned_err = Some(self.error_no_accessible_fields(pat, &fields));
|
unmentioned_err = Some(self.error_no_accessible_fields(pat, &fields));
|
||||||
} else {
|
} 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) {
|
match (inexistent_fields_err, unmentioned_err) {
|
||||||
|
@ -1405,6 +1406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
pat: &Pat<'_>,
|
pat: &Pat<'_>,
|
||||||
unmentioned_fields: &[(&ty::FieldDef, Ident)],
|
unmentioned_fields: &[(&ty::FieldDef, Ident)],
|
||||||
|
fields: &'tcx [hir::FieldPat<'tcx>],
|
||||||
) -> DiagnosticBuilder<'tcx> {
|
) -> DiagnosticBuilder<'tcx> {
|
||||||
let field_names = if unmentioned_fields.len() == 1 {
|
let field_names = if unmentioned_fields.len() == 1 {
|
||||||
format!("field `{}`", unmentioned_fields[0].1)
|
format!("field `{}`", unmentioned_fields[0].1)
|
||||||
|
@ -1424,14 +1426,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
field_names
|
field_names
|
||||||
);
|
);
|
||||||
err.span_label(pat.span, format!("missing {}", field_names));
|
err.span_label(pat.span, format!("missing {}", field_names));
|
||||||
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
let len = unmentioned_fields.len();
|
||||||
err.note(
|
let (prefix, postfix, sp) = match fields {
|
||||||
"This error indicates that a pattern for a struct fails to specify a \
|
[] => match &pat.kind {
|
||||||
sub-pattern for every one of the struct's fields. Ensure that each field \
|
PatKind::Struct(path, [], false) => {
|
||||||
from the struct's definition is mentioned in the pattern, or use `..` to \
|
(" { ", " }", path.span().shrink_to_hi().until(pat.span.shrink_to_hi()))
|
||||||
ignore unwanted fields.",
|
}
|
||||||
);
|
_ => 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
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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`
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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`.
|
|
|
@ -7,7 +7,9 @@ fn main() {
|
||||||
let d = Dog { name: "Rusty".to_string(), age: 8 };
|
let d = Dog { name: "Rusty".to_string(), age: 8 };
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
Dog { age: x } => {}
|
Dog { age: x } => {} //~ ERROR pattern does not mention field `name`
|
||||||
//~^ ERROR pattern does not mention field `name`
|
}
|
||||||
|
match d {
|
||||||
|
Dog {} => {} //~ ERROR pattern does not mention fields `name`, `age`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,31 @@ error[E0027]: pattern does not mention field `name`
|
||||||
|
|
|
|
||||||
LL | Dog { age: x } => {}
|
LL | Dog { age: x } => {}
|
||||||
| ^^^^^^^^^^^^^^ missing field `name`
|
| ^^^^^^^^^^^^^^ 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: aborting due to previous error
|
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 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0027`.
|
For more information about this error, try `rustc --explain E0027`.
|
||||||
|
|
|
@ -17,6 +17,15 @@ error[E0027]: pattern does not mention field `present`
|
||||||
|
|
|
|
||||||
LL | let Foo { #[cfg(any())] present: () } = foo;
|
LL | let Foo { #[cfg(any())] present: () } = foo;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `present`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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`
|
error[E0026]: struct `Foo` does not have a field named `absent`
|
||||||
--> $DIR/struct-field-cfg.rs:16:42
|
--> $DIR/struct-field-cfg.rs:16:42
|
||||||
|
|
|
@ -15,6 +15,15 @@ error[E0027]: pattern does not mention fields `b`, `c`
|
||||||
|
|
|
|
||||||
LL | let A { x, y } = self.d;
|
LL | let A { x, y } = self.d;
|
||||||
| ^^^^^^^^^^ missing fields `b`, `c`
|
| ^^^^^^^^^^ 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
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue