@@ -77,53 +77,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
77
77
}
78
78
}
79
79
PatKind :: Binding ( ba, var_id, _, ref sub) => {
80
- let bm = if ba == hir:: BindingAnnotation :: Unannotated {
81
- def_bm
82
- } else {
83
- ty:: BindingMode :: convert ( ba)
84
- } ;
85
- self . inh
86
- . tables
87
- . borrow_mut ( )
88
- . pat_binding_modes_mut ( )
89
- . insert ( pat. hir_id , bm) ;
90
- debug ! ( "check_pat_walk: pat.hir_id={:?} bm={:?}" , pat. hir_id, bm) ;
91
- let local_ty = self . local_ty ( pat. span , pat. hir_id ) . decl_ty ;
92
- match bm {
93
- ty:: BindByReference ( mutbl) => {
94
- // If the binding is like
95
- // ref x | ref const x | ref mut x
96
- // then `x` is assigned a value of type `&M T` where M is the mutability
97
- // and T is the expected type.
98
- let region_var = self . next_region_var ( infer:: PatternRegion ( pat. span ) ) ;
99
- let mt = ty:: TypeAndMut { ty : expected, mutbl : mutbl } ;
100
- let region_ty = tcx. mk_ref ( region_var, mt) ;
101
-
102
- // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
103
- // required. However, we use equality, which is stronger. See (*) for
104
- // an explanation.
105
- self . demand_eqtype_pat ( pat. span , region_ty, local_ty, discrim_span) ;
106
- }
107
- // Otherwise, the type of x is the expected type `T`.
108
- ty:: BindByValue ( _) => {
109
- // As above, `T <: typeof(x)` is required, but we
110
- // use equality, see (*) below.
111
- self . demand_eqtype_pat ( pat. span , expected, local_ty, discrim_span) ;
112
- }
113
- }
114
-
115
- // If there are multiple arms, make sure they all agree on
116
- // what the type of the binding `x` ought to be.
117
- if var_id != pat. hir_id {
118
- let vt = self . local_ty ( pat. span , var_id) . decl_ty ;
119
- self . demand_eqtype_pat ( pat. span , vt, local_ty, discrim_span) ;
120
- }
121
-
122
- if let Some ( ref p) = * sub {
123
- self . check_pat_walk ( & p, expected, def_bm, discrim_span) ;
124
- }
125
-
126
- local_ty
80
+ let sub = sub. as_deref ( ) ;
81
+ self . check_pat_ident ( pat, ba, var_id, sub, expected, def_bm, discrim_span)
127
82
}
128
83
PatKind :: TupleStruct ( ref qpath, ref subpats, ddpos) => {
129
84
self . check_pat_tuple_struct (
@@ -611,6 +566,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
611
566
Some ( common_type)
612
567
}
613
568
569
+ fn check_pat_ident (
570
+ & self ,
571
+ pat : & hir:: Pat ,
572
+ ba : hir:: BindingAnnotation ,
573
+ var_id : hir:: HirId ,
574
+ sub : Option < & ' tcx hir:: Pat > ,
575
+ expected : Ty < ' tcx > ,
576
+ def_bm : ty:: BindingMode ,
577
+ discrim_span : Option < Span > ,
578
+ ) -> Ty < ' tcx > {
579
+ // Determine the binding mode...
580
+ let bm = match ba {
581
+ hir:: BindingAnnotation :: Unannotated => def_bm,
582
+ _ => ty:: BindingMode :: convert ( ba) ,
583
+ } ;
584
+ // ...and store it in a side table:
585
+ self . inh
586
+ . tables
587
+ . borrow_mut ( )
588
+ . pat_binding_modes_mut ( )
589
+ . insert ( pat. hir_id , bm) ;
590
+
591
+ debug ! ( "check_pat_ident: pat.hir_id={:?} bm={:?}" , pat. hir_id, bm) ;
592
+
593
+ let local_ty = self . local_ty ( pat. span , pat. hir_id ) . decl_ty ;
594
+ let eq_ty = match bm {
595
+ ty:: BindByReference ( mutbl) => {
596
+ // If the binding is like `ref x | ref const x | ref mut x`
597
+ // then `x` is assigned a value of type `&M T` where M is the
598
+ // mutability and T is the expected type.
599
+ let region_var = self . next_region_var ( infer:: PatternRegion ( pat. span ) ) ;
600
+ let mt = ty:: TypeAndMut { ty : expected, mutbl } ;
601
+ let region_ty = self . tcx . mk_ref ( region_var, mt) ;
602
+
603
+ // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)`
604
+ // is required. However, we use equality, which is stronger.
605
+ // See (*) for an explanation.
606
+ region_ty
607
+ }
608
+ // Otherwise, the type of x is the expected type `T`.
609
+ ty:: BindByValue ( _) => {
610
+ // As above, `T <: typeof(x)` is required, but we use equality, see (*) below.
611
+ expected
612
+ }
613
+ } ;
614
+ self . demand_eqtype_pat ( pat. span , eq_ty, local_ty, discrim_span) ;
615
+
616
+ // If there are multiple arms, make sure they all agree on
617
+ // what the type of the binding `x` ought to be.
618
+ if var_id != pat. hir_id {
619
+ let vt = self . local_ty ( pat. span , var_id) . decl_ty ;
620
+ self . demand_eqtype_pat ( pat. span , vt, local_ty, discrim_span) ;
621
+ }
622
+
623
+ if let Some ( p) = sub {
624
+ self . check_pat_walk ( & p, expected, def_bm, discrim_span) ;
625
+ }
626
+
627
+ local_ty
628
+ }
629
+
614
630
fn borrow_pat_suggestion (
615
631
& self ,
616
632
err : & mut DiagnosticBuilder < ' _ > ,
0 commit comments