@@ -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) ;
@@ -1446,97 +1447,107 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1446
1447
qpath : & ' tcx hir:: QPath < ' tcx > ,
1447
1448
subpats : & ' tcx [ Pat < ' tcx > ] ,
1448
1449
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 > > {
1452
1451
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
- } ;
1458
1452
let report_unexpected_res = |res : Res | {
1459
1453
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)
1463
1455
} ;
1464
1456
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;
1486
1465
}
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) ;
1490
1472
}
1491
- Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Fn ) , _) => tcx. expect_variant_res ( res) ,
1492
- _ => bug ! ( "unexpected pattern resolution: {:?}" , res) ,
1493
- } ;
1494
1473
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
+ } ;
1498
1484
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" ) ;
1502
1488
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
+ }
1509
1497
} ;
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,
1520
1543
) ;
1521
- }
1522
- if let Err ( e) = had_err {
1523
1544
on_error ( e) ;
1524
1545
return Ty :: new_error ( tcx, e) ;
1525
1546
}
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 }
1540
1551
}
1541
1552
1542
1553
fn emit_err_pat_wrong_number_of_fields (
0 commit comments