@@ -8,7 +8,7 @@ use rustc_hash::FxHashMap;
88use rustc_pattern_analysis:: {
99 constructor:: { Constructor , ConstructorSet , VariantVisibility } ,
1010 index:: IdxContainer ,
11- Captures , PrivateUninhabitedField , TypeCx ,
11+ Captures , PatCx , PrivateUninhabitedField ,
1212} ;
1313use smallvec:: { smallvec, SmallVec } ;
1414use stdx:: never;
@@ -107,15 +107,17 @@ impl<'p> MatchCheckCtx<'p> {
107107 }
108108
109109 pub ( crate ) fn lower_pat ( & self , pat : & Pat ) -> DeconstructedPat < ' p > {
110- let singleton = |pat| vec ! [ pat] ;
110+ let singleton = |pat : DeconstructedPat < ' p > | vec ! [ pat. at_index ( 0 ) ] ;
111111 let ctor;
112- let fields: Vec < _ > ;
112+ let mut fields: Vec < _ > ;
113+ let arity;
113114
114115 match pat. kind . as_ref ( ) {
115116 PatKind :: Binding { subpattern : Some ( subpat) , .. } => return self . lower_pat ( subpat) ,
116117 PatKind :: Binding { subpattern : None , .. } | PatKind :: Wild => {
117118 ctor = Wildcard ;
118119 fields = Vec :: new ( ) ;
120+ arity = 0 ;
119121 }
120122 PatKind :: Deref { subpattern } => {
121123 ctor = match pat. ty . kind ( Interner ) {
@@ -128,23 +130,22 @@ impl<'p> MatchCheckCtx<'p> {
128130 }
129131 } ;
130132 fields = singleton ( self . lower_pat ( subpattern) ) ;
133+ arity = 1 ;
131134 }
132135 PatKind :: Leaf { subpatterns } | PatKind :: Variant { subpatterns, .. } => {
136+ fields = subpatterns
137+ . iter ( )
138+ . map ( |pat| {
139+ let idx: u32 = pat. field . into_raw ( ) . into ( ) ;
140+ self . lower_pat ( & pat. pattern ) . at_index ( idx as usize )
141+ } )
142+ . collect ( ) ;
133143 match pat. ty . kind ( Interner ) {
134144 TyKind :: Tuple ( _, substs) => {
135145 ctor = Struct ;
136- let mut wilds: Vec < _ > = substs
137- . iter ( Interner )
138- . map ( |arg| arg. assert_ty_ref ( Interner ) . clone ( ) )
139- . map ( DeconstructedPat :: wildcard)
140- . collect ( ) ;
141- for pat in subpatterns {
142- let idx: u32 = pat. field . into_raw ( ) . into ( ) ;
143- wilds[ idx as usize ] = self . lower_pat ( & pat. pattern ) ;
144- }
145- fields = wilds
146+ arity = substs. len ( Interner ) ;
146147 }
147- TyKind :: Adt ( adt, substs ) if is_box ( self . db , adt. 0 ) => {
148+ TyKind :: Adt ( adt, _ ) if is_box ( self . db , adt. 0 ) => {
148149 // The only legal patterns of type `Box` (outside `std`) are `_` and box
149150 // patterns. If we're here we can assume this is a box pattern.
150151 // FIXME(Nadrieril): A `Box` can in theory be matched either with `Box(_,
@@ -157,16 +158,9 @@ impl<'p> MatchCheckCtx<'p> {
157158 // normally or through box-patterns. We'll have to figure out a proper
158159 // solution when we introduce generalized deref patterns. Also need to
159160 // prevent mixing of those two options.
160- let pat =
161- subpatterns. iter ( ) . find ( |pat| pat. field . into_raw ( ) == 0u32 . into ( ) ) ;
162- let field = if let Some ( pat) = pat {
163- self . lower_pat ( & pat. pattern )
164- } else {
165- let ty = substs. at ( Interner , 0 ) . assert_ty_ref ( Interner ) . clone ( ) ;
166- DeconstructedPat :: wildcard ( ty)
167- } ;
161+ fields. retain ( |ipat| ipat. idx == 0 ) ;
168162 ctor = Struct ;
169- fields = singleton ( field ) ;
163+ arity = 1 ;
170164 }
171165 & TyKind :: Adt ( adt, _) => {
172166 ctor = match pat. kind . as_ref ( ) {
@@ -181,37 +175,33 @@ impl<'p> MatchCheckCtx<'p> {
181175 }
182176 } ;
183177 let variant = Self :: variant_id_for_adt ( & ctor, adt. 0 ) . unwrap ( ) ;
184- // Fill a vec with wildcards, then place the fields we have at the right
185- // index.
186- let mut wilds: Vec < _ > = self
187- . list_variant_fields ( & pat. ty , variant)
188- . map ( |( _, ty) | ty)
189- . map ( DeconstructedPat :: wildcard)
190- . collect ( ) ;
191- for pat in subpatterns {
192- let field_id: u32 = pat. field . into_raw ( ) . into ( ) ;
193- wilds[ field_id as usize ] = self . lower_pat ( & pat. pattern ) ;
194- }
195- fields = wilds;
178+ arity = variant. variant_data ( self . db . upcast ( ) ) . fields ( ) . len ( ) ;
196179 }
197180 _ => {
198181 never ! ( "pattern has unexpected type: pat: {:?}, ty: {:?}" , pat, & pat. ty) ;
199182 ctor = Wildcard ;
200- fields = Vec :: new ( ) ;
183+ fields. clear ( ) ;
184+ arity = 0 ;
201185 }
202186 }
203187 }
204188 & PatKind :: LiteralBool { value } => {
205189 ctor = Bool ( value) ;
206190 fields = Vec :: new ( ) ;
191+ arity = 0 ;
207192 }
208193 PatKind :: Or { pats } => {
209194 ctor = Or ;
210- fields = pats. iter ( ) . map ( |pat| self . lower_pat ( pat) ) . collect ( ) ;
195+ fields = pats
196+ . iter ( )
197+ . enumerate ( )
198+ . map ( |( i, pat) | self . lower_pat ( pat) . at_index ( i) )
199+ . collect ( ) ;
200+ arity = pats. len ( ) ;
211201 }
212202 }
213203 let data = PatData { db : self . db } ;
214- DeconstructedPat :: new ( ctor, fields, pat. ty . clone ( ) , data)
204+ DeconstructedPat :: new ( ctor, fields, arity , pat. ty . clone ( ) , data)
215205 }
216206
217207 pub ( crate ) fn hoist_witness_pat ( & self , pat : & WitnessPat < ' p > ) -> Pat {
@@ -271,7 +261,7 @@ impl<'p> MatchCheckCtx<'p> {
271261 }
272262}
273263
274- impl < ' p > TypeCx for MatchCheckCtx < ' p > {
264+ impl < ' p > PatCx for MatchCheckCtx < ' p > {
275265 type Error = ( ) ;
276266 type Ty = Ty ;
277267 type VariantIdx = EnumVariantId ;
@@ -453,7 +443,7 @@ impl<'p> TypeCx for MatchCheckCtx<'p> {
453443 let variant =
454444 pat. ty ( ) . as_adt ( ) . and_then ( |( adt, _) | Self :: variant_id_for_adt ( pat. ctor ( ) , adt) ) ;
455445
456- let db = pat. data ( ) . unwrap ( ) . db ;
446+ let db = pat. data ( ) . db ;
457447 if let Some ( variant) = variant {
458448 match variant {
459449 VariantId :: EnumVariantId ( v) => {
0 commit comments