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