summaryrefslogtreecommitdiffstats
path: root/src/librustc_typeck/check/pat.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_typeck/check/pat.rs')
-rw-r--r--src/librustc_typeck/check/pat.rs21
1 files changed, 14 insertions, 7 deletions
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 9dd3bc6..71d1cd8 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -703,7 +703,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
703 let pat_ty = pat_ty.fn_sig(tcx).output(); 703 let pat_ty = pat_ty.fn_sig(tcx).output();
704 let pat_ty = pat_ty.no_bound_vars().expect("expected fn type"); 704 let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
705 705
706 self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span); 706 // Type-check the tuple struct pattern against the expected type.
707 let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, match_arm_pat_span);
708 let had_err = diag.is_some();
709 diag.map(|mut err| err.emit());
707 710
708 // Type-check subpatterns. 711 // Type-check subpatterns.
709 if subpats.len() == variant.fields.len() 712 if subpats.len() == variant.fields.len()
@@ -721,7 +724,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
721 } 724 }
722 } else { 725 } else {
723 // Pattern has wrong number of fields. 726 // Pattern has wrong number of fields.
724 self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected); 727 self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
725 on_error(); 728 on_error();
726 return tcx.types.err; 729 return tcx.types.err;
727 } 730 }
@@ -734,8 +737,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
734 res: Res, 737 res: Res,
735 qpath: &hir::QPath, 738 qpath: &hir::QPath,
736 subpats: &'tcx [P<Pat>], 739 subpats: &'tcx [P<Pat>],
737 fields: &[ty::FieldDef], 740 fields: &'tcx [ty::FieldDef],
738 expected: Ty<'tcx> 741 expected: Ty<'tcx>,
742 had_err: bool,
739 ) { 743 ) {
740 let subpats_ending = pluralize!(subpats.len()); 744 let subpats_ending = pluralize!(subpats.len());
741 let fields_ending = pluralize!(fields.len()); 745 let fields_ending = pluralize!(fields.len());
@@ -763,9 +767,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
763 // More generally, the expected type wants a tuple variant with one field of an 767 // More generally, the expected type wants a tuple variant with one field of an
764 // N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern 768 // N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern
765 // with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`. 769 // with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`.
766 let missing_parenthesis = match expected.kind { 770 let missing_parenthesis = match (&expected.kind, fields, had_err) {
767 ty::Adt(_, substs) if fields.len() == 1 => { 771 // #67037: only do this if we could sucessfully type-check the expected type against
768 let field_ty = fields[0].ty(self.tcx, substs); 772 // the tuple struct pattern. Otherwise the substs could get out of range on e.g.,
773 // `let P() = U;` where `P != U` with `struct P<T>(T);`.
774 (ty::Adt(_, substs), [field], false) => {
775 let field_ty = self.field_ty(pat_span, field, substs);
769 match field_ty.kind { 776 match field_ty.kind {
770 ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(), 777 ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(),
771 _ => false, 778 _ => false,