5
5
//!
6
6
//! It is modeled on the rustc module `rustc_mir_build::thir::pattern`.
7
7
8
- mod deconstruct_pat;
9
8
mod pat_util;
10
9
10
+ pub ( crate ) mod deconstruct_pat;
11
11
pub ( crate ) mod usefulness;
12
12
13
- use hir_def:: { body:: Body , EnumVariantId , LocalFieldId , VariantId } ;
14
- use la_arena :: Idx ;
13
+ use hir_def:: { body:: Body , expr :: PatId , EnumVariantId , LocalFieldId , VariantId } ;
14
+ use stdx :: never ;
15
15
16
- use crate :: { db:: HirDatabase , InferenceResult , Interner , Substitution , Ty , TyKind } ;
16
+ use crate :: {
17
+ db:: HirDatabase , infer:: BindingMode , InferenceResult , Interner , Substitution , Ty , TyKind ,
18
+ } ;
17
19
18
20
use self :: pat_util:: EnumerateAndAdjustIterator ;
19
21
20
22
pub ( crate ) use self :: usefulness:: MatchArm ;
21
23
22
- pub ( crate ) type PatId = Idx < Pat > ;
23
-
24
24
#[ derive( Clone , Debug ) ]
25
25
pub ( crate ) enum PatternError {
26
26
Unimplemented ,
27
+ UnexpectedType ,
27
28
UnresolvedVariant ,
28
29
MissingField ,
29
30
ExtraFields ,
@@ -41,12 +42,6 @@ pub(crate) struct Pat {
41
42
pub ( crate ) kind : Box < PatKind > ,
42
43
}
43
44
44
- impl Pat {
45
- pub ( crate ) fn wildcard_from_ty ( ty : Ty ) -> Self {
46
- Pat { ty, kind : Box :: new ( PatKind :: Wild ) }
47
- }
48
- }
49
-
50
45
/// Close relative to `rustc_mir_build::thir::pattern::PatKind`
51
46
#[ derive( Clone , Debug , PartialEq ) ]
52
47
pub ( crate ) enum PatKind {
@@ -100,7 +95,7 @@ impl<'a> PatCtxt<'a> {
100
95
Self { db, infer, body, errors : Vec :: new ( ) }
101
96
}
102
97
103
- pub ( crate ) fn lower_pattern ( & mut self , pat : hir_def :: expr :: PatId ) -> Pat {
98
+ pub ( crate ) fn lower_pattern ( & mut self , pat : PatId ) -> Pat {
104
99
// XXX(iDawer): Collecting pattern adjustments feels imprecise to me.
105
100
// When lowering of & and box patterns are implemented this should be tested
106
101
// in a manner of `match_ergonomics_issue_9095` test.
@@ -116,7 +111,7 @@ impl<'a> PatCtxt<'a> {
116
111
)
117
112
}
118
113
119
- fn lower_pattern_unadjusted ( & mut self , pat : hir_def :: expr :: PatId ) -> Pat {
114
+ fn lower_pattern_unadjusted ( & mut self , pat : PatId ) -> Pat {
120
115
let mut ty = & self . infer [ pat] ;
121
116
let variant = self . infer . variant_resolution_for_pat ( pat) ;
122
117
@@ -138,9 +133,16 @@ impl<'a> PatCtxt<'a> {
138
133
PatKind :: Leaf { subpatterns }
139
134
}
140
135
141
- hir_def:: expr:: Pat :: Bind { subpat, .. } => {
142
- if let TyKind :: Ref ( .., rty) = ty. kind ( Interner ) {
143
- ty = rty;
136
+ hir_def:: expr:: Pat :: Bind { ref name, subpat, .. } => {
137
+ let bm = self . infer . pat_binding_modes [ & pat] ;
138
+ match ( bm, ty. kind ( Interner ) ) {
139
+ ( BindingMode :: Ref ( _) , TyKind :: Ref ( .., rty) ) => ty = rty,
140
+ ( BindingMode :: Ref ( _) , _) => {
141
+ never ! ( "`ref {}` has wrong type {:?}" , name, ty) ;
142
+ self . errors . push ( PatternError :: UnexpectedType ) ;
143
+ return Pat { ty : ty. clone ( ) , kind : PatKind :: Wild . into ( ) } ;
144
+ }
145
+ _ => ( ) ,
144
146
}
145
147
PatKind :: Binding { subpattern : self . lower_opt_pattern ( subpat) }
146
148
}
@@ -189,7 +191,7 @@ impl<'a> PatCtxt<'a> {
189
191
190
192
fn lower_tuple_subpats (
191
193
& mut self ,
192
- pats : & [ hir_def :: expr :: PatId ] ,
194
+ pats : & [ PatId ] ,
193
195
expected_len : usize ,
194
196
ellipsis : Option < usize > ,
195
197
) -> Vec < FieldPat > {
@@ -207,17 +209,17 @@ impl<'a> PatCtxt<'a> {
207
209
. collect ( )
208
210
}
209
211
210
- fn lower_patterns ( & mut self , pats : & [ hir_def :: expr :: PatId ] ) -> Vec < Pat > {
212
+ fn lower_patterns ( & mut self , pats : & [ PatId ] ) -> Vec < Pat > {
211
213
pats. iter ( ) . map ( |& p| self . lower_pattern ( p) ) . collect ( )
212
214
}
213
215
214
- fn lower_opt_pattern ( & mut self , pat : Option < hir_def :: expr :: PatId > ) -> Option < Pat > {
216
+ fn lower_opt_pattern ( & mut self , pat : Option < PatId > ) -> Option < Pat > {
215
217
pat. map ( |p| self . lower_pattern ( p) )
216
218
}
217
219
218
220
fn lower_variant_or_leaf (
219
221
& mut self ,
220
- pat : hir_def :: expr :: PatId ,
222
+ pat : PatId ,
221
223
ty : & Ty ,
222
224
subpatterns : Vec < FieldPat > ,
223
225
) -> PatKind {
@@ -244,7 +246,7 @@ impl<'a> PatCtxt<'a> {
244
246
kind
245
247
}
246
248
247
- fn lower_path ( & mut self , pat : hir_def :: expr :: PatId , _path : & hir_def:: path:: Path ) -> Pat {
249
+ fn lower_path ( & mut self , pat : PatId , _path : & hir_def:: path:: Path ) -> Pat {
248
250
let ty = & self . infer [ pat] ;
249
251
250
252
let pat_from_kind = |kind| Pat { ty : ty. clone ( ) , kind : Box :: new ( kind) } ;
0 commit comments