@@ -364,6 +364,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
364364 PatKind :: Struct ( ref qpath, fields, has_rest_pat) => {
365365 Some { 0 : & self . check_pat_struct ( pat, qpath, fields, has_rest_pat) }
366366 }
367+ PatKind :: TupleStruct ( ref qpath, subpats, ddpos) => {
368+ Some { 0 : & self . check_pat_tuple_struct ( pat, qpath, subpats, ddpos) }
369+ }
367370 _ => None ,
368371 } ;
369372 let adjust_mode = self . calc_adjust_mode ( pat, resolved_pat. and_then ( |r| r. path_res ) ) ;
@@ -393,9 +396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
393396 PatKind :: Binding ( ba, var_id, ident, sub) => {
394397 self . check_pat_ident ( pat, ba, var_id, ident, sub, expected, pat_info)
395398 }
396- PatKind :: TupleStruct ( ref qpath, subpats, ddpos) => {
397- self . check_pat_tuple_struct ( pat, qpath, subpats, ddpos, expected, pat_info)
398- }
399+ PatKind :: TupleStruct ( ..) => ( resolved_pat. unwrap ( ) . check ) ( expected, pat_info) ,
399400 PatKind :: Struct ( ..) => ( resolved_pat. unwrap ( ) . check ) ( expected, pat_info) ,
400401 PatKind :: Guard ( pat, cond) => {
401402 self . check_pat ( pat, expected, pat_info) ;
@@ -1446,97 +1447,107 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14461447 qpath : & ' tcx hir:: QPath < ' tcx > ,
14471448 subpats : & ' tcx [ Pat < ' tcx > ] ,
14481449 ddpos : hir:: DotDotPos ,
1449- expected : Ty < ' tcx > ,
1450- pat_info : PatInfo < ' tcx > ,
1451- ) -> Ty < ' tcx > {
1450+ ) -> ResolvedPat < impl Fn ( Ty < ' tcx > , PatInfo < ' tcx > ) -> Ty < ' tcx > > {
14521451 let tcx = self . tcx ;
1453- let on_error = |e| {
1454- for pat in subpats {
1455- self . check_pat ( pat, Ty :: new_error ( tcx, e) , pat_info) ;
1456- }
1457- } ;
14581452 let report_unexpected_res = |res : Res | {
14591453 let expected = "tuple struct or tuple variant" ;
1460- let e = report_unexpected_variant_res ( tcx, res, None , qpath, pat. span , E0164 , expected) ;
1461- on_error ( e) ;
1462- e
1454+ report_unexpected_variant_res ( tcx, res, None , qpath, pat. span , E0164 , expected)
14631455 } ;
14641456
1465- // Resolve the path and check the definition for errors.
1466- let ( res, opt_ty, segments) =
1467- self . resolve_ty_and_res_fully_qualified_call ( qpath, pat. hir_id , pat. span ) ;
1468- if res == Res :: Err {
1469- let e = self . dcx ( ) . span_delayed_bug ( pat. span , "`Res::Err` but no error emitted" ) ;
1470- self . set_tainted_by_errors ( e) ;
1471- on_error ( e) ;
1472- return Ty :: new_error ( tcx, e) ;
1473- }
1474-
1475- // Type-check the path.
1476- let ( pat_ty, res) =
1477- self . instantiate_value_path ( segments, opt_ty, res, pat. span , pat. span , pat. hir_id ) ;
1478- if !pat_ty. is_fn ( ) {
1479- let e = report_unexpected_res ( res) ;
1480- return Ty :: new_error ( tcx, e) ;
1481- }
1482-
1483- let variant = match res {
1484- Res :: Err => {
1485- self . dcx ( ) . span_bug ( pat. span , "`Res::Err` but no error emitted" ) ;
1457+ let pat_ty_and_res_and_variant = try {
1458+ // Resolve the path and check the definition for errors.
1459+ let ( res, opt_ty, segments) =
1460+ self . resolve_ty_and_res_fully_qualified_call ( qpath, pat. hir_id , pat. span ) ;
1461+ if res == Res :: Err {
1462+ let e = self . dcx ( ) . span_delayed_bug ( pat. span , "`Res::Err` but no error emitted" ) ;
1463+ self . set_tainted_by_errors ( e) ;
1464+ do yeet e;
14861465 }
1487- Res :: Def ( DefKind :: AssocConst | DefKind :: AssocFn , _) => {
1488- let e = report_unexpected_res ( res) ;
1489- return Ty :: new_error ( tcx, e) ;
1466+
1467+ // Type-check the path.
1468+ let ( pat_ty, res) =
1469+ self . instantiate_value_path ( segments, opt_ty, res, pat. span , pat. span , pat. hir_id ) ;
1470+ if !pat_ty. is_fn ( ) {
1471+ do yeet report_unexpected_res ( res) ;
14901472 }
1491- Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Fn ) , _) => tcx. expect_variant_res ( res) ,
1492- _ => bug ! ( "unexpected pattern resolution: {:?}" , res) ,
1493- } ;
14941473
1495- // Replace constructor type with constructed type for tuple struct patterns.
1496- let pat_ty = pat_ty. fn_sig ( tcx) . output ( ) ;
1497- let pat_ty = pat_ty. no_bound_vars ( ) . expect ( "expected fn type" ) ;
1474+ let variant = match res {
1475+ Res :: Err => {
1476+ self . dcx ( ) . span_bug ( pat. span , "`Res::Err` but no error emitted" ) ;
1477+ }
1478+ Res :: Def ( DefKind :: AssocConst | DefKind :: AssocFn , _) => {
1479+ do yeet report_unexpected_res ( res) ;
1480+ }
1481+ Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Fn ) , _) => tcx. expect_variant_res ( res) ,
1482+ _ => bug ! ( "unexpected pattern resolution: {:?}" , res) ,
1483+ } ;
14981484
1499- // Type-check the tuple struct pattern against the expected type .
1500- let diag = self . demand_eqtype_pat_diag ( pat . span , expected , pat_ty, & pat_info . top_info ) ;
1501- let had_err = diag . map_err ( |diag| diag . emit ( ) ) ;
1485+ // Replace constructor type with constructed type for tuple struct patterns .
1486+ let pat_ty = pat_ty . fn_sig ( tcx ) . output ( ) ;
1487+ let pat_ty = pat_ty . no_bound_vars ( ) . expect ( "expected fn type" ) ;
15021488
1503- // Type-check subpatterns.
1504- if subpats. len ( ) == variant. fields . len ( )
1505- || subpats. len ( ) < variant. fields . len ( ) && ddpos. as_opt_usize ( ) . is_some ( )
1506- {
1507- let ty:: Adt ( _, args) = pat_ty. kind ( ) else {
1508- bug ! ( "unexpected pattern type {:?}" , pat_ty) ;
1489+ ( pat_ty, res, variant)
1490+ } ;
1491+
1492+ let check = move |expected : Ty < ' tcx > , pat_info : PatInfo < ' tcx > | -> Ty < ' tcx > {
1493+ let on_error = |e| {
1494+ for pat in subpats {
1495+ self . check_pat ( pat, Ty :: new_error ( tcx, e) , pat_info) ;
1496+ }
15091497 } ;
1510- for ( i, subpat) in subpats. iter ( ) . enumerate_and_adjust ( variant. fields . len ( ) , ddpos) {
1511- let field = & variant. fields [ FieldIdx :: from_usize ( i) ] ;
1512- let field_ty = self . field_ty ( subpat. span , field, args) ;
1513- self . check_pat ( subpat, field_ty, pat_info) ;
1514-
1515- self . tcx . check_stability (
1516- variant. fields [ FieldIdx :: from_usize ( i) ] . did ,
1517- Some ( subpat. hir_id ) ,
1518- subpat. span ,
1519- None ,
1498+ let ( pat_ty, res, variant) = match pat_ty_and_res_and_variant {
1499+ Ok ( data) => data,
1500+ Err ( guar) => {
1501+ on_error ( guar) ;
1502+ return Ty :: new_error ( tcx, guar) ;
1503+ }
1504+ } ;
1505+
1506+ // Type-check the tuple struct pattern against the expected type.
1507+ let diag = self . demand_eqtype_pat_diag ( pat. span , expected, pat_ty, & pat_info. top_info ) ;
1508+ let had_err = diag. map_err ( |diag| diag. emit ( ) ) ;
1509+
1510+ // Type-check subpatterns.
1511+ if subpats. len ( ) == variant. fields . len ( )
1512+ || subpats. len ( ) < variant. fields . len ( ) && ddpos. as_opt_usize ( ) . is_some ( )
1513+ {
1514+ let ty:: Adt ( _, args) = pat_ty. kind ( ) else {
1515+ bug ! ( "unexpected pattern type {:?}" , pat_ty) ;
1516+ } ;
1517+ for ( i, subpat) in subpats. iter ( ) . enumerate_and_adjust ( variant. fields . len ( ) , ddpos)
1518+ {
1519+ let field = & variant. fields [ FieldIdx :: from_usize ( i) ] ;
1520+ let field_ty = self . field_ty ( subpat. span , field, args) ;
1521+ self . check_pat ( subpat, field_ty, pat_info) ;
1522+
1523+ self . tcx . check_stability (
1524+ variant. fields [ FieldIdx :: from_usize ( i) ] . did ,
1525+ Some ( subpat. hir_id ) ,
1526+ subpat. span ,
1527+ None ,
1528+ ) ;
1529+ }
1530+ if let Err ( e) = had_err {
1531+ on_error ( e) ;
1532+ return Ty :: new_error ( tcx, e) ;
1533+ }
1534+ } else {
1535+ let e = self . emit_err_pat_wrong_number_of_fields (
1536+ pat. span ,
1537+ res,
1538+ qpath,
1539+ subpats,
1540+ & variant. fields . raw ,
1541+ expected,
1542+ had_err,
15201543 ) ;
1521- }
1522- if let Err ( e) = had_err {
15231544 on_error ( e) ;
15241545 return Ty :: new_error ( tcx, e) ;
15251546 }
1526- } else {
1527- let e = self . emit_err_pat_wrong_number_of_fields (
1528- pat. span ,
1529- res,
1530- qpath,
1531- subpats,
1532- & variant. fields . raw ,
1533- expected,
1534- had_err,
1535- ) ;
1536- on_error ( e) ;
1537- return Ty :: new_error ( tcx, e) ;
1538- }
1539- pat_ty
1547+ pat_ty
1548+ } ;
1549+
1550+ ResolvedPat { path_res : None , check }
15401551 }
15411552
15421553 fn emit_err_pat_wrong_number_of_fields (
0 commit comments