@@ -703,7 +703,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
703703 let pat_ty = pat_ty. fn_sig ( tcx) . output ( ) ;
704704 let pat_ty = pat_ty. no_bound_vars ( ) . expect ( "expected fn type" ) ;
705705
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 ( ) ) ;
707710
708711 // Type-check subpatterns.
709712 if subpats. len ( ) == variant. fields . len ( )
@@ -721,7 +724,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
721724 }
722725 } else {
723726 // 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 ) ;
725728 on_error ( ) ;
726729 return tcx. types . err ;
727730 }
@@ -734,8 +737,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
734737 res : Res ,
735738 qpath : & hir:: QPath ,
736739 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 ,
739743 ) {
740744 let subpats_ending = pluralize ! ( subpats. len( ) ) ;
741745 let fields_ending = pluralize ! ( fields. len( ) ) ;
@@ -763,9 +767,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
763767 // More generally, the expected type wants a tuple variant with one field of an
764768 // N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern
765769 // 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) ;
769776 match field_ty. kind {
770777 ty:: Tuple ( _) => field_ty. tuple_fields ( ) . count ( ) == subpats. len ( ) ,
771778 _ => false ,
0 commit comments