@@ -489,39 +489,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
489
489
}
490
490
491
491
impl < ' a , ' gcx , ' tcx > FnCtxt < ' a , ' gcx , ' tcx > {
492
- pub fn check_pat_struct ( & self , pat : & ' gcx hir:: Pat ,
493
- path : & hir:: Path , fields : & ' gcx [ Spanned < hir:: FieldPat > ] ,
494
- etc : bool , expected : Ty < ' tcx > ) {
495
- let tcx = self . tcx ;
496
-
497
- let def = tcx. expect_def ( pat. id ) ;
498
- let variant = match self . def_struct_variant ( def, path. span ) {
499
- Some ( ( _, variant) ) => variant,
500
- None => {
501
- let name = pprust:: path_to_string ( path) ;
502
- span_err ! ( tcx. sess, pat. span, E0163 ,
503
- "`{}` does not name a struct or a struct variant" , name) ;
504
- self . write_error ( pat. id ) ;
505
-
506
- for field in fields {
507
- self . check_pat ( & field. node . pat , tcx. types . err ) ;
508
- }
509
- return ;
492
+ fn check_pat_struct ( & self ,
493
+ pat : & ' gcx hir:: Pat ,
494
+ path : & hir:: Path ,
495
+ fields : & ' gcx [ Spanned < hir:: FieldPat > ] ,
496
+ etc : bool ,
497
+ expected : Ty < ' tcx > )
498
+ {
499
+ // Resolve the path and check the definition for errors.
500
+ let def = self . finish_resolving_struct_path ( path, pat. id , pat. span ) ;
501
+ let variant = if let Some ( variant) = self . check_struct_path ( def, path, pat. span ) {
502
+ variant
503
+ } else {
504
+ self . write_error ( pat. id ) ;
505
+ for field in fields {
506
+ self . check_pat ( & field. node . pat , self . tcx . types . err ) ;
510
507
}
508
+ return ;
511
509
} ;
512
510
513
- let pat_ty = self . instantiate_type ( def. def_id ( ) , path) ;
514
- let item_substs = match pat_ty. sty {
511
+ // Type check the path.
512
+ let pat_ty = self . instantiate_type_path ( def. def_id ( ) , path, pat. id ) ;
513
+ self . demand_eqtype ( pat. span , expected, pat_ty) ;
514
+
515
+ // Type check subpatterns.
516
+ let substs = match pat_ty. sty {
515
517
ty:: TyStruct ( _, substs) | ty:: TyEnum ( _, substs) => substs,
516
518
_ => span_bug ! ( pat. span, "struct variant is not an ADT" )
517
519
} ;
518
- self . demand_eqtype ( pat. span , expected, pat_ty) ;
519
- self . check_struct_pat_fields ( pat. span , fields, variant, & item_substs, etc) ;
520
-
521
- self . write_ty ( pat. id , pat_ty) ;
522
- self . write_substs ( pat. id , ty:: ItemSubsts {
523
- substs : item_substs
524
- } ) ;
520
+ self . check_struct_pat_fields ( pat. span , fields, variant, substs, etc) ;
525
521
}
526
522
527
523
fn check_pat_path ( & self ,
@@ -539,8 +535,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
539
535
} ;
540
536
541
537
// Resolve the path and check the definition for errors.
542
- let ( def, opt_ty, segments) = self . resolve_ty_and_def_ufcs ( tcx . expect_resolution ( pat . id ) ,
543
- opt_self_ty , path , pat. span , pat. id ) ;
538
+ let ( def, opt_ty, segments) = self . resolve_ty_and_def_ufcs ( opt_self_ty , path ,
539
+ pat. id , pat. span ) ;
544
540
match def {
545
541
Def :: Err => {
546
542
self . set_tainted_by_errors ( ) ;
@@ -565,8 +561,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
565
561
// Type check the path.
566
562
let scheme = tcx. lookup_item_type ( def. def_id ( ) ) ;
567
563
let predicates = tcx. lookup_predicates ( def. def_id ( ) ) ;
568
- self . instantiate_path ( segments, scheme, & predicates, opt_ty , def , pat . span , pat . id ) ;
569
- let pat_ty = self . node_ty ( pat. id ) ;
564
+ let pat_ty = self . instantiate_value_path ( segments, scheme, & predicates,
565
+ opt_ty , def , pat . span , pat. id ) ;
570
566
self . demand_suptype ( pat. span , expected, pat_ty) ;
571
567
}
572
568
@@ -597,9 +593,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
597
593
} ;
598
594
599
595
// Resolve the path and check the definition for errors.
600
- let ( def, opt_ty, segments) = self . resolve_ty_and_def_ufcs ( tcx. expect_resolution ( pat. id ) ,
601
- None , path, pat. span , pat. id ) ;
602
- match def {
596
+ let ( def, opt_ty, segments) = self . resolve_ty_and_def_ufcs ( None , path, pat. id , pat. span ) ;
597
+ let variant = match def {
603
598
Def :: Err => {
604
599
self . set_tainted_by_errors ( ) ;
605
600
on_error ( ) ;
@@ -609,10 +604,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
609
604
report_unexpected_def ( false ) ;
610
605
return ;
611
606
}
612
- Def :: Variant ( ..) | Def :: Struct ( ..) => { } // OK
607
+ Def :: Variant ( ..) | Def :: Struct ( ..) => {
608
+ tcx. expect_variant_def ( def)
609
+ }
613
610
_ => bug ! ( "unexpected pattern definition {:?}" , def)
614
- }
615
- let variant = tcx. expect_variant_def ( def) ;
611
+ } ;
616
612
if variant. kind == VariantKind :: Unit && subpats. is_empty ( ) && ddpos. is_some ( ) {
617
613
// Matching unit structs with tuple variant patterns (`UnitVariant(..)`)
618
614
// is allowed for backward compatibility.
@@ -633,20 +629,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
633
629
scheme
634
630
} ;
635
631
let predicates = tcx. lookup_predicates ( def. def_id ( ) ) ;
636
- self . instantiate_path ( segments, scheme, & predicates, opt_ty , def , pat . span , pat . id ) ;
637
- let pat_ty = self . node_ty ( pat. id ) ;
632
+ let pat_ty = self . instantiate_value_path ( segments, scheme, & predicates,
633
+ opt_ty , def , pat . span , pat. id ) ;
638
634
self . demand_eqtype ( pat. span , expected, pat_ty) ;
639
635
640
636
// Type check subpatterns.
641
637
if subpats. len ( ) == variant. fields . len ( ) ||
642
638
subpats. len ( ) < variant. fields . len ( ) && ddpos. is_some ( ) {
643
- let expected_substs = match pat_ty. sty {
644
- ty:: TyEnum ( _, expected_substs) => expected_substs,
645
- ty:: TyStruct ( _, expected_substs) => expected_substs,
639
+ let substs = match pat_ty. sty {
640
+ ty:: TyStruct ( _, substs) | ty:: TyEnum ( _, substs) => substs,
646
641
ref ty => bug ! ( "unexpected pattern type {:?}" , ty) ,
647
642
} ;
648
643
for ( i, subpat) in subpats. iter ( ) . enumerate_and_adjust ( variant. fields . len ( ) , ddpos) {
649
- let field_ty = self . field_ty ( subpat. span , & variant. fields [ i] , expected_substs ) ;
644
+ let field_ty = self . field_ty ( subpat. span , & variant. fields [ i] , substs ) ;
650
645
self . check_pat ( & subpat, field_ty) ;
651
646
}
652
647
} else {
0 commit comments