@@ -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 > {
@@ -383,6 +384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
383384 Some ( self . resolve_pat_path ( * hir_id, * span, qpath) )
384385 }
385386 PatKind :: Struct ( ref qpath, ..) => Some ( self . resolve_pat_struct ( pat, qpath) ) ,
387+ PatKind :: TupleStruct ( ref qpath, ..) => Some ( self . resolve_pat_tuple_struct ( pat, qpath) ) ,
386388 _ => None ,
387389 } ;
388390 let opt_res_pat = opt_res_pat_or_err. map ( Result :: ok) . flatten ( ) ;
@@ -419,9 +421,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
419421 PatKind :: Binding ( ba, var_id, ident, sub) => {
420422 self . check_pat_ident ( pat, ba, var_id, ident, sub, expected, pat_info)
421423 }
422- PatKind :: TupleStruct ( ref qpath, subpats, ddpos) => {
423- self . check_pat_tuple_struct ( pat, qpath, subpats, ddpos, expected, pat_info)
424- }
424+ PatKind :: TupleStruct ( ref qpath, subpats, ddpos) => match opt_res_pat_or_err. unwrap ( ) {
425+ Ok ( ResolvedPat { ty, kind : ResolvedPatKind :: TupleStruct { res, variant } } ) => self
426+ . check_pat_tuple_struct (
427+ pat, qpath, subpats, ddpos, res, ty, variant, expected, pat_info,
428+ ) ,
429+ Err ( guar) => {
430+ let ty_err = Ty :: new_error ( self . tcx , guar) ;
431+ for subpat in subpats {
432+ self . check_pat ( subpat, ty_err, pat_info) ;
433+ }
434+ ty_err
435+ }
436+ Ok ( r) => span_bug ! ( pat. span, "tuple struct pattern resolved to {r:?}" ) ,
437+ } ,
425438 PatKind :: Struct ( _, fields, has_rest_pat) => match opt_res_pat_or_err. unwrap ( ) {
426439 Ok ( ResolvedPat { ty, kind : ResolvedPatKind :: Struct { variant } } ) => self
427440 . check_pat_struct ( pat, fields, has_rest_pat, ty, variant, expected, pat_info) ,
@@ -1469,26 +1482,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14691482 e. emit ( ) ;
14701483 }
14711484
1472- fn check_pat_tuple_struct (
1485+ fn resolve_pat_tuple_struct (
14731486 & self ,
14741487 pat : & ' tcx Pat < ' tcx > ,
14751488 qpath : & ' tcx hir:: QPath < ' tcx > ,
1476- subpats : & ' tcx [ Pat < ' tcx > ] ,
1477- ddpos : hir:: DotDotPos ,
1478- expected : Ty < ' tcx > ,
1479- pat_info : PatInfo < ' tcx > ,
1480- ) -> Ty < ' tcx > {
1489+ ) -> Result < ResolvedPat < ' tcx > , ErrorGuaranteed > {
14811490 let tcx = self . tcx ;
1482- let on_error = |e| {
1483- for pat in subpats {
1484- self . check_pat ( pat, Ty :: new_error ( tcx, e) , pat_info) ;
1485- }
1486- } ;
14871491 let report_unexpected_res = |res : Res | {
14881492 let expected = "tuple struct or tuple variant" ;
14891493 let e = report_unexpected_variant_res ( tcx, res, None , qpath, pat. span , E0164 , expected) ;
1490- on_error ( e) ;
1491- e
1494+ Err ( e)
14921495 } ;
14931496
14941497 // Resolve the path and check the definition for errors.
@@ -1497,25 +1500,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14971500 if res == Res :: Err {
14981501 let e = self . dcx ( ) . span_delayed_bug ( pat. span , "`Res::Err` but no error emitted" ) ;
14991502 self . set_tainted_by_errors ( e) ;
1500- on_error ( e) ;
1501- return Ty :: new_error ( tcx, e) ;
1503+ return Err ( e) ;
15021504 }
15031505
15041506 // Type-check the path.
15051507 let ( pat_ty, res) =
15061508 self . instantiate_value_path ( segments, opt_ty, res, pat. span , pat. span , pat. hir_id ) ;
15071509 if !pat_ty. is_fn ( ) {
1508- let e = report_unexpected_res ( res) ;
1509- return Ty :: new_error ( tcx, e) ;
1510+ return report_unexpected_res ( res) ;
15101511 }
15111512
15121513 let variant = match res {
15131514 Res :: Err => {
15141515 self . dcx ( ) . span_bug ( pat. span , "`Res::Err` but no error emitted" ) ;
15151516 }
15161517 Res :: Def ( DefKind :: AssocConst | DefKind :: AssocFn , _) => {
1517- let e = report_unexpected_res ( res) ;
1518- return Ty :: new_error ( tcx, e) ;
1518+ return report_unexpected_res ( res) ;
15191519 }
15201520 Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Fn ) , _) => tcx. expect_variant_res ( res) ,
15211521 _ => bug ! ( "unexpected pattern resolution: {:?}" , res) ,
@@ -1525,6 +1525,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15251525 let pat_ty = pat_ty. fn_sig ( tcx) . output ( ) ;
15261526 let pat_ty = pat_ty. no_bound_vars ( ) . expect ( "expected fn type" ) ;
15271527
1528+ Ok ( ResolvedPat { ty : pat_ty, kind : ResolvedPatKind :: TupleStruct { res, variant } } )
1529+ }
1530+
1531+ fn check_pat_tuple_struct (
1532+ & self ,
1533+ pat : & ' tcx Pat < ' tcx > ,
1534+ qpath : & ' tcx hir:: QPath < ' tcx > ,
1535+ subpats : & ' tcx [ Pat < ' tcx > ] ,
1536+ ddpos : hir:: DotDotPos ,
1537+ res : Res ,
1538+ pat_ty : Ty < ' tcx > ,
1539+ variant : & ' tcx VariantDef ,
1540+ expected : Ty < ' tcx > ,
1541+ pat_info : PatInfo < ' tcx > ,
1542+ ) -> Ty < ' tcx > {
1543+ let tcx = self . tcx ;
1544+ let on_error = |e| {
1545+ for pat in subpats {
1546+ self . check_pat ( pat, Ty :: new_error ( tcx, e) , pat_info) ;
1547+ }
1548+ } ;
1549+
15281550 // Type-check the tuple struct pattern against the expected type.
15291551 let diag = self . demand_eqtype_pat_diag ( pat. span , expected, pat_ty, & pat_info. top_info ) ;
15301552 let had_err = diag. map_err ( |diag| diag. emit ( ) ) ;
0 commit comments