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
3 changed files with 42 additions and 4 deletions
|
@ -36,6 +36,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: \
|
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";
|
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.
|
/// 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!
|
/// **NOTE:** This is only for use by diagnostics. Do NOT use for type checking logic!
|
||||||
|
@ -1671,7 +1675,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fields: &'tcx [hir::PatField<'tcx>],
|
fields: &'tcx [hir::PatField<'tcx>],
|
||||||
variant: &ty::VariantDef,
|
variant: &ty::VariantDef,
|
||||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
) -> 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| {
|
let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| {
|
||||||
s.print_qpath(qpath, false)
|
s.print_qpath(qpath, false)
|
||||||
});
|
});
|
||||||
|
@ -1893,7 +1905,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
prefix,
|
prefix,
|
||||||
unmentioned_fields
|
unmentioned_fields
|
||||||
.iter()
|
.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<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", "),
|
.join(", "),
|
||||||
if have_inaccessible_fields { ", .." } else { "" },
|
if have_inaccessible_fields { ", .." } else { "" },
|
||||||
|
|
|
@ -12,4 +12,7 @@ fn main() {
|
||||||
match y {
|
match y {
|
||||||
S { } => {} //~ ERROR: tuple variant `S` written as struct variant [E0769]
|
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(_, _) => {}
|
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…
Add table
Reference in a new issue