better diagnostics for pattern matching tuple structs
Better diagnostic message when trying to pattern match a tuple struct with a struct pattern.
This commit is contained in:
parent
82bfda848e
commit
3b38dd9112
@ -36,6 +36,10 @@
|
||||
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!
|
||||
@ -1671,7 +1675,15 @@ fn error_tuple_variant_as_struct_pat(
|
||||
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)
|
||||
});
|
||||
@ -1893,7 +1905,14 @@ fn error_unmentioned_fields(
|
||||
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