@@ -669,7 +669,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
669
669
let pat_ty = pat_ty. fn_sig ( tcx) . output ( ) ;
670
670
let pat_ty = pat_ty. no_bound_vars ( ) . expect ( "expected fn type" ) ;
671
671
672
- self . demand_eqtype_pat ( pat. span , expected, pat_ty, match_arm_pat_span) ;
672
+ // Type-check the tuple struct pattern against the expected type.
673
+ let diag = self . demand_eqtype_pat_diag ( pat. span , expected, pat_ty, match_arm_pat_span) ;
674
+ let had_err = diag. is_some ( ) ;
675
+ diag. map ( |mut err| err. emit ( ) ) ;
673
676
674
677
// Type-check subpatterns.
675
678
if subpats. len ( ) == variant. fields . len ( )
@@ -687,7 +690,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
687
690
}
688
691
} else {
689
692
// Pattern has wrong number of fields.
690
- self . e0023 ( pat. span , res, qpath, subpats, & variant. fields , expected) ;
693
+ self . e0023 ( pat. span , res, qpath, subpats, & variant. fields , expected, had_err ) ;
691
694
on_error ( ) ;
692
695
return tcx. types . err ;
693
696
}
@@ -700,8 +703,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
700
703
res : Res ,
701
704
qpath : & hir:: QPath ,
702
705
subpats : & ' tcx [ P < Pat > ] ,
703
- fields : & [ ty:: FieldDef ] ,
704
- expected : Ty < ' tcx >
706
+ fields : & ' tcx [ ty:: FieldDef ] ,
707
+ expected : Ty < ' tcx > ,
708
+ had_err : bool ,
705
709
) {
706
710
let subpats_ending = pluralise ! ( subpats. len( ) ) ;
707
711
let fields_ending = pluralise ! ( fields. len( ) ) ;
@@ -729,9 +733,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
729
733
// More generally, the expected type wants a tuple variant with one field of an
730
734
// N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern
731
735
// with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`.
732
- let missing_parenthesis = match expected. kind {
733
- ty:: Adt ( _, substs) if fields. len ( ) == 1 => {
734
- let field_ty = fields[ 0 ] . ty ( self . tcx , substs) ;
736
+ let missing_parenthesis = match ( & expected. kind , fields, had_err) {
737
+ // #67037: only do this if we could sucessfully type-check the expected type against
738
+ // the tuple struct pattern. Otherwise the substs could get out of range on e.g.,
739
+ // `let P() = U;` where `P != U` with `struct P<T>(T);`.
740
+ ( ty:: Adt ( _, substs) , [ field] , false ) => {
741
+ let field_ty = self . field_ty ( pat_span, field, substs) ;
735
742
match field_ty. kind {
736
743
ty:: Tuple ( _) => field_ty. tuple_fields ( ) . count ( ) == subpats. len ( ) ,
737
744
_ => false ,
0 commit comments