55//!
66//! It is modeled on the rustc module `rustc_mir_build::thir::pattern`.
77
8- mod deconstruct_pat;
98mod pat_util;
109
10+ pub ( crate ) mod deconstruct_pat;
1111pub ( crate ) mod usefulness;
1212
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 ;
1515
16- use crate :: { db:: HirDatabase , InferenceResult , Interner , Substitution , Ty , TyKind } ;
16+ use crate :: {
17+ db:: HirDatabase , infer:: BindingMode , InferenceResult , Interner , Substitution , Ty , TyKind ,
18+ } ;
1719
1820use self :: pat_util:: EnumerateAndAdjustIterator ;
1921
2022pub ( crate ) use self :: usefulness:: MatchArm ;
2123
22- pub ( crate ) type PatId = Idx < Pat > ;
23-
2424#[ derive( Clone , Debug ) ]
2525pub ( crate ) enum PatternError {
2626 Unimplemented ,
27+ UnexpectedType ,
2728 UnresolvedVariant ,
2829 MissingField ,
2930 ExtraFields ,
@@ -41,12 +42,6 @@ pub(crate) struct Pat {
4142 pub ( crate ) kind : Box < PatKind > ,
4243}
4344
44- impl Pat {
45- pub ( crate ) fn wildcard_from_ty ( ty : Ty ) -> Self {
46- Pat { ty, kind : Box :: new ( PatKind :: Wild ) }
47- }
48- }
49-
5045/// Close relative to `rustc_mir_build::thir::pattern::PatKind`
5146#[ derive( Clone , Debug , PartialEq ) ]
5247pub ( crate ) enum PatKind {
@@ -100,7 +95,7 @@ impl<'a> PatCtxt<'a> {
10095 Self { db, infer, body, errors : Vec :: new ( ) }
10196 }
10297
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 {
10499 // XXX(iDawer): Collecting pattern adjustments feels imprecise to me.
105100 // When lowering of & and box patterns are implemented this should be tested
106101 // in a manner of `match_ergonomics_issue_9095` test.
@@ -116,7 +111,7 @@ impl<'a> PatCtxt<'a> {
116111 )
117112 }
118113
119- fn lower_pattern_unadjusted ( & mut self , pat : hir_def :: expr :: PatId ) -> Pat {
114+ fn lower_pattern_unadjusted ( & mut self , pat : PatId ) -> Pat {
120115 let mut ty = & self . infer [ pat] ;
121116 let variant = self . infer . variant_resolution_for_pat ( pat) ;
122117
@@ -138,9 +133,16 @@ impl<'a> PatCtxt<'a> {
138133 PatKind :: Leaf { subpatterns }
139134 }
140135
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+ _ => ( ) ,
144146 }
145147 PatKind :: Binding { subpattern : self . lower_opt_pattern ( subpat) }
146148 }
@@ -189,7 +191,7 @@ impl<'a> PatCtxt<'a> {
189191
190192 fn lower_tuple_subpats (
191193 & mut self ,
192- pats : & [ hir_def :: expr :: PatId ] ,
194+ pats : & [ PatId ] ,
193195 expected_len : usize ,
194196 ellipsis : Option < usize > ,
195197 ) -> Vec < FieldPat > {
@@ -207,17 +209,17 @@ impl<'a> PatCtxt<'a> {
207209 . collect ( )
208210 }
209211
210- fn lower_patterns ( & mut self , pats : & [ hir_def :: expr :: PatId ] ) -> Vec < Pat > {
212+ fn lower_patterns ( & mut self , pats : & [ PatId ] ) -> Vec < Pat > {
211213 pats. iter ( ) . map ( |& p| self . lower_pattern ( p) ) . collect ( )
212214 }
213215
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 > {
215217 pat. map ( |p| self . lower_pattern ( p) )
216218 }
217219
218220 fn lower_variant_or_leaf (
219221 & mut self ,
220- pat : hir_def :: expr :: PatId ,
222+ pat : PatId ,
221223 ty : & Ty ,
222224 subpatterns : Vec < FieldPat > ,
223225 ) -> PatKind {
@@ -244,7 +246,7 @@ impl<'a> PatCtxt<'a> {
244246 kind
245247 }
246248
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 {
248250 let ty = & self . infer [ pat] ;
249251
250252 let pat_from_kind = |kind| Pat { ty : ty. clone ( ) , kind : Box :: new ( kind) } ;
0 commit comments