@@ -278,6 +278,7 @@ struct ResolvedPat<'tcx> {
278278enum ResolvedPatKind < ' tcx > {
279279 Path { res : Res , pat_res : Res , segments : & ' tcx [ hir:: PathSegment < ' tcx > ] } ,
280280 Struct { variant : & ' tcx VariantDef } ,
281+ TupleStruct { res : Res , variant : & ' tcx VariantDef } ,
281282}
282283
283284impl < ' tcx > ResolvedPat < ' tcx > {
@@ -381,6 +382,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
381382 Some ( self . resolve_pat_path ( * hir_id, * span, qpath) )
382383 }
383384 PatKind :: Struct ( ref qpath, ..) => Some ( self . resolve_pat_struct ( pat, qpath) ) ,
385+ PatKind :: TupleStruct ( ref qpath, ..) => Some ( self . resolve_pat_tuple_struct ( pat, qpath) ) ,
384386 _ => None ,
385387 } ;
386388 let adjust_mode = self . calc_adjust_mode ( pat, opt_path_res) ;
@@ -575,9 +577,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
575577 PatKind :: Binding ( ba, var_id, ident, sub) => {
576578 self . check_pat_ident ( pat, ba, var_id, ident, sub, expected, pat_info)
577579 }
578- PatKind :: TupleStruct ( ref qpath, subpats, ddpos) => {
579- self . check_pat_tuple_struct ( pat, qpath, subpats, ddpos, expected, pat_info)
580- }
580+ PatKind :: TupleStruct ( ref qpath, subpats, ddpos) => match opt_path_res. unwrap ( ) {
581+ Ok ( ResolvedPat { ty, kind : ResolvedPatKind :: TupleStruct { res, variant } } ) => self
582+ . check_pat_tuple_struct (
583+ pat, qpath, subpats, ddpos, res, ty, variant, expected, pat_info,
584+ ) ,
585+ Err ( guar) => {
586+ let ty_err = Ty :: new_error ( self . tcx , guar) ;
587+ for subpat in subpats {
588+ self . check_pat ( subpat, ty_err, pat_info) ;
589+ }
590+ ty_err
591+ }
592+ Ok ( pr) => span_bug ! ( pat. span, "tuple struct pattern resolved to {pr:?}" ) ,
593+ } ,
581594 PatKind :: Struct ( _, fields, has_rest_pat) => match opt_path_res. unwrap ( ) {
582595 Ok ( ResolvedPat { ty, kind : ResolvedPatKind :: Struct { variant } } ) => self
583596 . check_pat_struct ( pat, fields, has_rest_pat, ty, variant, expected, pat_info) ,
@@ -1443,26 +1456,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14431456 e. emit ( ) ;
14441457 }
14451458
1446- fn check_pat_tuple_struct (
1459+ fn resolve_pat_tuple_struct (
14471460 & self ,
14481461 pat : & ' tcx Pat < ' tcx > ,
14491462 qpath : & ' tcx hir:: QPath < ' tcx > ,
1450- subpats : & ' tcx [ Pat < ' tcx > ] ,
1451- ddpos : hir:: DotDotPos ,
1452- expected : Ty < ' tcx > ,
1453- pat_info : PatInfo < ' tcx > ,
1454- ) -> Ty < ' tcx > {
1463+ ) -> Result < ResolvedPat < ' tcx > , ErrorGuaranteed > {
14551464 let tcx = self . tcx ;
1456- let on_error = |e| {
1457- for pat in subpats {
1458- self . check_pat ( pat, Ty :: new_error ( tcx, e) , pat_info) ;
1459- }
1460- } ;
14611465 let report_unexpected_res = |res : Res | {
14621466 let expected = "tuple struct or tuple variant" ;
14631467 let e = report_unexpected_variant_res ( tcx, res, None , qpath, pat. span , E0164 , expected) ;
1464- on_error ( e) ;
1465- e
1468+ Err ( e)
14661469 } ;
14671470
14681471 // Resolve the path and check the definition for errors.
@@ -1471,25 +1474,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14711474 if res == Res :: Err {
14721475 let e = self . dcx ( ) . span_delayed_bug ( pat. span , "`Res::Err` but no error emitted" ) ;
14731476 self . set_tainted_by_errors ( e) ;
1474- on_error ( e) ;
1475- return Ty :: new_error ( tcx, e) ;
1477+ return Err ( e) ;
14761478 }
14771479
14781480 // Type-check the path.
14791481 let ( pat_ty, res) =
14801482 self . instantiate_value_path ( segments, opt_ty, res, pat. span , pat. span , pat. hir_id ) ;
14811483 if !pat_ty. is_fn ( ) {
1482- let e = report_unexpected_res ( res) ;
1483- return Ty :: new_error ( tcx, e) ;
1484+ return report_unexpected_res ( res) ;
14841485 }
14851486
14861487 let variant = match res {
14871488 Res :: Err => {
14881489 self . dcx ( ) . span_bug ( pat. span , "`Res::Err` but no error emitted" ) ;
14891490 }
14901491 Res :: Def ( DefKind :: AssocConst | DefKind :: AssocFn , _) => {
1491- let e = report_unexpected_res ( res) ;
1492- return Ty :: new_error ( tcx, e) ;
1492+ return report_unexpected_res ( res) ;
14931493 }
14941494 Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Fn ) , _) => tcx. expect_variant_res ( res) ,
14951495 _ => bug ! ( "unexpected pattern resolution: {:?}" , res) ,
@@ -1499,6 +1499,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14991499 let pat_ty = pat_ty. fn_sig ( tcx) . output ( ) ;
15001500 let pat_ty = pat_ty. no_bound_vars ( ) . expect ( "expected fn type" ) ;
15011501
1502+ Ok ( ResolvedPat { ty : pat_ty, kind : ResolvedPatKind :: TupleStruct { res, variant } } )
1503+ }
1504+
1505+ fn check_pat_tuple_struct (
1506+ & self ,
1507+ pat : & ' tcx Pat < ' tcx > ,
1508+ qpath : & ' tcx hir:: QPath < ' tcx > ,
1509+ subpats : & ' tcx [ Pat < ' tcx > ] ,
1510+ ddpos : hir:: DotDotPos ,
1511+ res : Res ,
1512+ pat_ty : Ty < ' tcx > ,
1513+ variant : & ' tcx VariantDef ,
1514+ expected : Ty < ' tcx > ,
1515+ pat_info : PatInfo < ' tcx > ,
1516+ ) -> Ty < ' tcx > {
1517+ let tcx = self . tcx ;
1518+ let on_error = |e| {
1519+ for pat in subpats {
1520+ self . check_pat ( pat, Ty :: new_error ( tcx, e) , pat_info) ;
1521+ }
1522+ } ;
1523+
15021524 // Type-check the tuple struct pattern against the expected type.
15031525 let diag = self . demand_eqtype_pat_diag ( pat. span , expected, pat_ty, & pat_info. top_info ) ;
15041526 let had_err = diag. map_err ( |diag| diag. emit ( ) ) ;
0 commit comments