@@ -703,7 +703,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
703
703
let pat_ty = pat_ty. fn_sig ( tcx) . output ( ) ;
704
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
711
// Type-check subpatterns.
709
712
if subpats. len ( ) == variant. fields . len ( )
@@ -721,7 +724,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
721
724
}
722
725
} else {
723
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
728
on_error ( ) ;
726
729
return tcx. types . err ;
727
730
}
@@ -734,8 +737,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
734
737
res : Res ,
735
738
qpath : & hir:: QPath ,
736
739
subpats : & ' tcx [ P < Pat > ] ,
737
- fields : & [ ty:: FieldDef ] ,
738
- expected : Ty < ' tcx >
740
+ fields : & ' tcx [ ty:: FieldDef ] ,
741
+ expected : Ty < ' tcx > ,
742
+ had_err : bool ,
739
743
) {
740
744
let subpats_ending = pluralize ! ( subpats. len( ) ) ;
741
745
let fields_ending = pluralize ! ( fields. len( ) ) ;
@@ -763,9 +767,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
763
767
// More generally, the expected type wants a tuple variant with one field of an
764
768
// N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern
765
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 {
767
- ty:: Adt ( _, substs) if fields. len ( ) == 1 => {
768
- let field_ty = fields[ 0 ] . ty ( self . tcx , substs) ;
770
+ let missing_parenthesis = match ( & expected. kind , fields, had_err) {
771
+ // #67037: only do this if we could sucessfully type-check the expected type against
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
776
match field_ty. kind {
770
777
ty:: Tuple ( _) => field_ty. tuple_fields ( ) . count ( ) == subpats. len ( ) ,
771
778
_ => false ,
0 commit comments