Skip to content

Commit 4573bb8

Browse files
committed
Add special case for UnitVariant(..) patterns
1 parent 3574992 commit 4573bb8

File tree

4 files changed

+20
-13
lines changed

4 files changed

+20
-13
lines changed

src/librustc_typeck/check/_match.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
139139
if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
140140
if let hir::PatEnum(ref path, ref subpats) = pat.node {
141141
if !(subpats.is_some() && subpats.as_ref().unwrap().is_empty()) {
142-
bad_struct_kind_err(tcx.sess, pat.span, path);
142+
bad_struct_kind_err(tcx.sess, pat.span, path, false);
143143
return;
144144
}
145145
}
@@ -581,9 +581,9 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat,
581581
}
582582

583583
// This function exists due to the warning "diagnostic code E0164 already used"
584-
fn bad_struct_kind_err(sess: &Session, span: Span, path: &hir::Path) {
584+
fn bad_struct_kind_err(sess: &Session, span: Span, path: &hir::Path, is_warning: bool) {
585585
let name = pprust::path_to_string(path);
586-
span_err!(sess, span, E0164,
586+
span_err_or_warn!(is_warning, sess, span, E0164,
587587
"`{}` does not name a tuple variant or a tuple struct", name);
588588
}
589589

@@ -634,8 +634,8 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
634634
path_scheme, &ctor_predicates,
635635
opt_ty, def, pat.span, pat.id);
636636

637-
let report_bad_struct_kind = || {
638-
bad_struct_kind_err(tcx.sess, pat.span, path);
637+
let report_bad_struct_kind = |is_warning| {
638+
bad_struct_kind_err(tcx.sess, pat.span, path, is_warning);
639639
fcx.write_error(pat.id);
640640

641641
if let Some(subpats) = subpats {
@@ -650,7 +650,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
650650
// function uses checks specific to structs and enums.
651651
if path_res.depth != 0 {
652652
if is_tuple_struct_pat {
653-
report_bad_struct_kind();
653+
report_bad_struct_kind(false);
654654
} else {
655655
let pat_ty = fcx.node_ty(pat.id);
656656
demand::suptype(fcx, pat.span, expected, pat_ty);
@@ -668,8 +668,13 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
668668
{
669669
let variant = enum_def.variant_of_def(def);
670670
if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
671-
report_bad_struct_kind();
672-
return;
671+
// Matching unit variants with tuple variant patterns (`UnitVariant(..)`)
672+
// is allowed for backward compatibility.
673+
let is_special_case = variant.kind() == ty::VariantKind::Unit;
674+
report_bad_struct_kind(is_special_case);
675+
if !is_special_case {
676+
return
677+
}
673678
}
674679
(variant.fields
675680
.iter()
@@ -682,7 +687,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
682687
ty::TyStruct(struct_def, expected_substs) => {
683688
let variant = struct_def.struct_variant();
684689
if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
685-
report_bad_struct_kind();
690+
report_bad_struct_kind(false);
686691
return;
687692
}
688693
(variant.fields
@@ -694,7 +699,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
694699
"struct")
695700
}
696701
_ => {
697-
report_bad_struct_kind();
702+
report_bad_struct_kind(false);
698703
return;
699704
}
700705
};

src/test/compile-fail/empty-struct-unit-pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ fn main() {
3434
// E::Empty2() => () // ERROR `E::Empty2` does not name a tuple variant or a tuple struct
3535
// }
3636
match e2 {
37-
E::Empty2(..) => () //~ ERROR `E::Empty2` does not name a tuple variant or a tuple struct
37+
E::Empty2(..) => () //~ WARN `E::Empty2` does not name a tuple variant or a tuple struct
3838
}
3939
}

src/test/compile-fail/match-pattern-field-mismatch-2.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ fn main() {
2020
color::rgb(_, _, _) => { }
2121
color::cmyk(_, _, _, _) => { }
2222
color::no_color(_) => { }
23-
//~^ ERROR `color::no_color` does not name a tuple variant or a tuple struct
23+
//~^ ERROR this pattern has 1 field, but the corresponding variant has no fields
24+
//~^^ WARN `color::no_color` does not name a tuple variant or a tuple struct
2425
}
2526
}
2627
}

src/test/compile-fail/pattern-error-continue.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ fn f(_c: char) {}
2525
fn main() {
2626
match A::B(1, 2) {
2727
A::B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but
28-
A::D(_) => (), //~ ERROR `A::D` does not name a tuple variant or a tuple struct
28+
A::D(_) => (), //~ ERROR this pattern has 1 field, but
29+
//~^ WARN `A::D` does not name a tuple variant or a tuple struct
2930
_ => ()
3031
}
3132
match 'c' {

0 commit comments

Comments
 (0)