mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Auto merge of #109760 - MaciejWas:struct-tuple-field-names-suggestion, r=jackh726
Better diagnostic when pattern matching tuple structs Fixes #108284 When trying to pattern match a tuple struct we might get a flawed error message if there are missing fields. E.g. ``` let x = Foo(100, 200); if let Foo { 0: bar } = x { ... } ``` Produces this error: ``` error[E0769]: tuple variant `Foo` written as struct variant --> hello.rs:5:12 | 5 | if let Foo { 0: foo } = x { | ^^^^^^^^^^^^^^ | help: use the tuple variant pattern syntax instead | 5 | if let Foo(_, _) = x { | ~~~~~~ ``` Which doesn't highlight that we can still use the struct syntax but we need to fill missing fields. This pr changes this error to: ``` error[E0027]: pattern does not mention field `1` --> hello.rs:5:12 | 5 | if let Foo { 0: foo } = x { | ^^^^^^^^^^^^^^ missing field `1` | help: include the missing field in the pattern | 5 | if let Foo { 0: foo, 1: _ } = x { | ~~~~~~~~ help: if you don't care about this missing field, you can explicitly ignore it | 5 | if let Foo { 0: foo, .. } = x { | ~~~~~~ ```
This commit is contained in:
commit
696aaad58c
@ -37,6 +37,10 @@ pointers. If you encounter this error you should try to avoid dereferencing the
|
||||
You can read more about trait objects in the Trait Objects section of the Reference: \
|
||||
https://doc.rust-lang.org/reference/types.html#trait-objects";
|
||||
|
||||
fn is_number(text: &str) -> bool {
|
||||
text.chars().all(|c: char| c.is_digit(10))
|
||||
}
|
||||
|
||||
/// Information about the expected type at the top level of type checking a pattern.
|
||||
///
|
||||
/// **NOTE:** This is only for use by diagnostics. Do NOT use for type checking logic!
|
||||
@ -1673,7 +1677,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
fields: &'tcx [hir::PatField<'tcx>],
|
||||
variant: &ty::VariantDef,
|
||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||
if let (Some(CtorKind::Fn), PatKind::Struct(qpath, ..)) = (variant.ctor_kind(), &pat.kind) {
|
||||
if let (Some(CtorKind::Fn), PatKind::Struct(qpath, pattern_fields, ..)) =
|
||||
(variant.ctor_kind(), &pat.kind)
|
||||
{
|
||||
let is_tuple_struct_match = !pattern_fields.is_empty()
|
||||
&& pattern_fields.iter().map(|field| field.ident.name.as_str()).all(is_number);
|
||||
if is_tuple_struct_match {
|
||||
return None;
|
||||
}
|
||||
|
||||
let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| {
|
||||
s.print_qpath(qpath, false)
|
||||
});
|
||||
@ -1895,7 +1907,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
prefix,
|
||||
unmentioned_fields
|
||||
.iter()
|
||||
.map(|(_, name)| name.to_string())
|
||||
.map(|(_, name)| {
|
||||
let field_name = name.to_string();
|
||||
if is_number(&field_name) {
|
||||
format!("{}: _", field_name)
|
||||
} else {
|
||||
field_name
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
if have_inaccessible_fields { ", .." } else { "" },
|
||||
|
@ -12,4 +12,7 @@ fn main() {
|
||||
match y {
|
||||
S { } => {} //~ ERROR: tuple variant `S` written as struct variant [E0769]
|
||||
}
|
||||
|
||||
if let E::S { 0: a } = x { //~ ERROR: pattern does not mention field `1`
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,22 @@ help: use the tuple variant pattern syntax instead
|
||||
LL | S(_, _) => {}
|
||||
| ~~~~~~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0027]: pattern does not mention field `1`
|
||||
--> $DIR/struct-tuple-field-names.rs:16:12
|
||||
|
|
||||
LL | if let E::S { 0: a } = x {
|
||||
| ^^^^^^^^^^^^^ missing field `1`
|
||||
|
|
||||
help: include the missing field in the pattern
|
||||
|
|
||||
LL | if let E::S { 0: a, 1: _ } = x {
|
||||
| ~~~~~~~~
|
||||
help: if you don't care about this missing field, you can explicitly ignore it
|
||||
|
|
||||
LL | if let E::S { 0: a, .. } = x {
|
||||
| ~~~~~~
|
||||
|
||||
For more information about this error, try `rustc --explain E0769`.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0027, E0769.
|
||||
For more information about an error, try `rustc --explain E0027`.
|
||||
|
Loading…
Reference in New Issue
Block a user