@@ -17,11 +17,11 @@ use itertools::Itertools;
17
17
use rustc_hash:: FxHashSet ;
18
18
19
19
use crate :: {
20
- Adt , AssocItem , Enum , GenericDef , GenericParam , HasVisibility , Impl , ModuleDef , ScopeDef , Type ,
21
- TypeParam , Variant ,
20
+ Adt , AssocItem , GenericDef , GenericParam , HasVisibility , Impl , ModuleDef , ScopeDef , Type ,
21
+ TypeParam ,
22
22
} ;
23
23
24
- use crate :: term_search:: { Expr , TermSearchConfig } ;
24
+ use crate :: term_search:: Expr ;
25
25
26
26
use super :: { LookupTable , NewTypesKey , TermSearchCtx } ;
27
27
@@ -151,212 +151,101 @@ pub(super) fn assoc_const<'a, DB: HirDatabase>(
151
151
/// * `should_continue` - Function that indicates when to stop iterating
152
152
pub ( super ) fn data_constructor < ' a , DB : HirDatabase > (
153
153
ctx : & ' a TermSearchCtx < ' a , DB > ,
154
- defs : & ' a FxHashSet < ScopeDef > ,
154
+ _defs : & ' a FxHashSet < ScopeDef > ,
155
155
lookup : & ' a mut LookupTable ,
156
156
should_continue : & ' a dyn std:: ops:: Fn ( ) -> bool ,
157
157
) -> impl Iterator < Item = Expr > + ' a {
158
158
let db = ctx. sema . db ;
159
159
let module = ctx. scope . module ( ) ;
160
- fn variant_helper (
161
- db : & dyn HirDatabase ,
162
- lookup : & mut LookupTable ,
163
- should_continue : & dyn std:: ops:: Fn ( ) -> bool ,
164
- parent_enum : Enum ,
165
- variant : Variant ,
166
- config : & TermSearchConfig ,
167
- ) -> Vec < ( Type , Vec < Expr > ) > {
168
- // Ignore unstable
169
- if variant. is_unstable ( db) {
170
- return Vec :: new ( ) ;
171
- }
172
-
173
- let generics = GenericDef :: from ( variant. parent_enum ( db) ) ;
174
- let Some ( type_params) = generics
175
- . type_or_const_params ( db)
176
- . into_iter ( )
177
- . map ( |it| it. as_type_param ( db) )
178
- . collect :: < Option < Vec < TypeParam > > > ( )
179
- else {
180
- // Ignore enums with const generics
181
- return Vec :: new ( ) ;
182
- } ;
183
-
184
- // We currently do not check lifetime bounds so ignore all types that have something to do
185
- // with them
186
- if !generics. lifetime_params ( db) . is_empty ( ) {
187
- return Vec :: new ( ) ;
188
- }
160
+ lookup
161
+ . types_wishlist ( )
162
+ . clone ( )
163
+ . into_iter ( )
164
+ . chain ( iter:: once ( ctx. goal . clone ( ) ) )
165
+ . filter_map ( |ty| ty. as_adt ( ) . map ( |adt| ( adt, ty) ) )
166
+ . filter ( |_| should_continue ( ) )
167
+ . filter_map ( move |( adt, ty) | match adt {
168
+ Adt :: Struct ( strukt) => {
169
+ // Ignore unstable or not visible
170
+ if strukt. is_unstable ( db) || !strukt. is_visible_from ( db, module) {
171
+ return None ;
172
+ }
189
173
190
- // Only account for stable type parameters for now, unstable params can be default
191
- // tho, for example in `Box<T, #[unstable] A: Allocator>`
192
- if type_params. iter ( ) . any ( |it| it. is_unstable ( db) && it. default ( db) . is_none ( ) ) {
193
- return Vec :: new ( ) ;
194
- }
174
+ let generics = GenericDef :: from ( strukt) ;
195
175
196
- let non_default_type_params_len =
197
- type_params. iter ( ) . filter ( |it| it. default ( db) . is_none ( ) ) . count ( ) ;
198
-
199
- let enum_ty_shallow = Adt :: from ( parent_enum) . ty ( db) ;
200
- let generic_params = lookup
201
- . types_wishlist ( )
202
- . clone ( )
203
- . into_iter ( )
204
- . filter ( |ty| ty. could_unify_with ( db, & enum_ty_shallow) )
205
- . map ( |it| it. type_arguments ( ) . collect :: < Vec < Type > > ( ) )
206
- . chain ( ( non_default_type_params_len == 0 ) . then_some ( Vec :: new ( ) ) ) ;
207
-
208
- generic_params
209
- . filter ( |_| should_continue ( ) )
210
- . filter_map ( move |generics| {
211
- // Insert default type params
212
- let mut g = generics. into_iter ( ) ;
213
- let generics: Vec < _ > = type_params
214
- . iter ( )
215
- . map ( |it| it. default ( db) . or_else ( || g. next ( ) ) )
216
- . collect :: < Option < _ > > ( ) ?;
176
+ // We currently do not check lifetime bounds so ignore all types that have something to do
177
+ // with them
178
+ if !generics. lifetime_params ( db) . is_empty ( ) {
179
+ return None ;
180
+ }
217
181
218
- let enum_ty = Adt :: from ( parent_enum) . ty_with_args ( db, generics. iter ( ) . cloned ( ) ) ;
182
+ if ty. contains_unknown ( ) {
183
+ return None ;
184
+ }
219
185
220
186
// Ignore types that have something to do with lifetimes
221
- if config. enable_borrowcheck && enum_ty . contains_reference ( db) {
187
+ if ctx . config . enable_borrowcheck && ty . contains_reference ( db) {
222
188
return None ;
223
189
}
190
+ let fields = strukt. fields ( db) ;
191
+ // Check if all fields are visible, otherwise we cannot fill them
192
+ if fields. iter ( ) . any ( |it| !it. is_visible_from ( db, module) ) {
193
+ return None ;
194
+ }
195
+
196
+ let generics: Vec < _ > = ty. type_arguments ( ) . collect ( ) ;
224
197
225
198
// Early exit if some param cannot be filled from lookup
226
- let param_exprs: Vec < Vec < Expr > > = variant
227
- . fields ( db)
199
+ let param_exprs: Vec < Vec < Expr > > = fields
228
200
. into_iter ( )
229
201
. map ( |field| lookup. find ( db, & field. ty_with_args ( db, generics. iter ( ) . cloned ( ) ) ) )
230
202
. collect :: < Option < _ > > ( ) ?;
231
203
232
204
// Note that we need special case for 0 param constructors because of multi cartesian
233
205
// product
234
- let variant_exprs : Vec < Expr > = if param_exprs. is_empty ( ) {
235
- vec ! [ Expr :: Variant { variant , generics, params: Vec :: new( ) } ]
206
+ let exprs : Vec < Expr > = if param_exprs. is_empty ( ) {
207
+ vec ! [ Expr :: Struct { strukt , generics, params: Vec :: new( ) } ]
236
208
} else {
237
209
param_exprs
238
210
. into_iter ( )
239
211
. multi_cartesian_product ( )
240
- . map ( |params| Expr :: Variant { variant , generics : generics. clone ( ) , params } )
212
+ . map ( |params| Expr :: Struct { strukt , generics : generics. clone ( ) , params } )
241
213
. collect ( )
242
214
} ;
243
- lookup. insert ( enum_ty. clone ( ) , variant_exprs. iter ( ) . cloned ( ) ) ;
244
-
245
- Some ( ( enum_ty, variant_exprs) )
246
- } )
247
- . collect ( )
248
- }
249
- defs. iter ( )
250
- . filter_map ( move |def| match def {
251
- ScopeDef :: ModuleDef ( ModuleDef :: Variant ( it) ) => {
252
- let variant_exprs = variant_helper (
253
- db,
254
- lookup,
255
- should_continue,
256
- it. parent_enum ( db) ,
257
- * it,
258
- & ctx. config ,
259
- ) ;
260
- if variant_exprs. is_empty ( ) {
261
- return None ;
262
- }
263
- if GenericDef :: from ( it. parent_enum ( db) )
264
- . type_or_const_params ( db)
265
- . into_iter ( )
266
- . filter_map ( |it| it. as_type_param ( db) )
267
- . all ( |it| it. default ( db) . is_some ( ) )
268
- {
269
- lookup. mark_fulfilled ( ScopeDef :: ModuleDef ( ModuleDef :: Variant ( * it) ) ) ;
270
- }
271
- Some ( variant_exprs)
272
- }
273
- ScopeDef :: ModuleDef ( ModuleDef :: Adt ( Adt :: Enum ( enum_) ) ) => {
274
- let exprs: Vec < ( Type , Vec < Expr > ) > = enum_
275
- . variants ( db)
276
- . into_iter ( )
277
- . flat_map ( |it| {
278
- variant_helper ( db, lookup, should_continue, * enum_, it, & ctx. config )
279
- } )
280
- . collect ( ) ;
281
-
282
- if exprs. is_empty ( ) {
283
- return None ;
284
- }
285
-
286
- if GenericDef :: from ( * enum_)
287
- . type_or_const_params ( db)
288
- . into_iter ( )
289
- . filter_map ( |it| it. as_type_param ( db) )
290
- . all ( |it| it. default ( db) . is_some ( ) )
291
- {
292
- lookup. mark_fulfilled ( ScopeDef :: ModuleDef ( ModuleDef :: Adt ( Adt :: Enum ( * enum_) ) ) ) ;
293
- }
294
215
295
- Some ( exprs)
216
+ lookup. insert ( ty. clone ( ) , exprs. iter ( ) . cloned ( ) ) ;
217
+ Some ( ( ty, exprs) )
296
218
}
297
- ScopeDef :: ModuleDef ( ModuleDef :: Adt ( Adt :: Struct ( it ) ) ) => {
298
- // Ignore unstable and not visible
299
- if it . is_unstable ( db) || !it . is_visible_from ( db, module) {
219
+ Adt :: Enum ( enum_ ) => {
220
+ // Ignore unstable or not visible
221
+ if enum_ . is_unstable ( db) || !enum_ . is_visible_from ( db, module) {
300
222
return None ;
301
223
}
302
224
303
- let generics = GenericDef :: from ( * it) ;
304
-
305
- // Ignore const params for now
306
- let type_params = generics
307
- . type_or_const_params ( db)
308
- . into_iter ( )
309
- . map ( |it| it. as_type_param ( db) )
310
- . collect :: < Option < Vec < TypeParam > > > ( ) ?;
311
-
225
+ let generics = GenericDef :: from ( enum_) ;
312
226
// We currently do not check lifetime bounds so ignore all types that have something to do
313
227
// with them
314
228
if !generics. lifetime_params ( db) . is_empty ( ) {
315
229
return None ;
316
230
}
317
231
318
- // Only account for stable type parameters for now, unstable params can be default
319
- // tho, for example in `Box<T, #[unstable] A: Allocator>`
320
- if type_params. iter ( ) . any ( |it| it. is_unstable ( db) && it. default ( db) . is_none ( ) ) {
232
+ if ty. contains_unknown ( ) {
321
233
return None ;
322
234
}
323
235
324
- let non_default_type_params_len =
325
- type_params. iter ( ) . filter ( |it| it. default ( db) . is_none ( ) ) . count ( ) ;
236
+ // Ignore types that have something to do with lifetimes
237
+ if ctx. config . enable_borrowcheck && ty. contains_reference ( db) {
238
+ return None ;
239
+ }
326
240
327
- let struct_ty_shallow = Adt :: from ( * it) . ty ( db) ;
328
- let generic_params = lookup
329
- . types_wishlist ( )
330
- . clone ( )
241
+ let generics: Vec < _ > = ty. type_arguments ( ) . collect ( ) ;
242
+ let exprs = enum_
243
+ . variants ( db)
331
244
. into_iter ( )
332
- . filter ( |ty| ty. could_unify_with ( db, & struct_ty_shallow) )
333
- . map ( |it| it. type_arguments ( ) . collect :: < Vec < Type > > ( ) )
334
- . chain ( ( non_default_type_params_len == 0 ) . then_some ( Vec :: new ( ) ) ) ;
335
-
336
- let exprs = generic_params
337
- . filter ( |_| should_continue ( ) )
338
- . filter_map ( |generics| {
339
- // Insert default type params
340
- let mut g = generics. into_iter ( ) ;
341
- let generics: Vec < _ > = type_params
342
- . iter ( )
343
- . map ( |it| it. default ( db) . or_else ( || g. next ( ) ) )
344
- . collect :: < Option < _ > > ( ) ?;
345
-
346
- let struct_ty = Adt :: from ( * it) . ty_with_args ( db, generics. iter ( ) . cloned ( ) ) ;
347
-
348
- // Ignore types that have something to do with lifetimes
349
- if ctx. config . enable_borrowcheck && struct_ty. contains_reference ( db) {
350
- return None ;
351
- }
352
- let fields = it. fields ( db) ;
353
- // Check if all fields are visible, otherwise we cannot fill them
354
- if fields. iter ( ) . any ( |it| !it. is_visible_from ( db, module) ) {
355
- return None ;
356
- }
357
-
245
+ . filter_map ( |variant| {
358
246
// Early exit if some param cannot be filled from lookup
359
- let param_exprs: Vec < Vec < Expr > > = fields
247
+ let param_exprs: Vec < Vec < Expr > > = variant
248
+ . fields ( db)
360
249
. into_iter ( )
361
250
. map ( |field| {
362
251
lookup. find ( db, & field. ty_with_args ( db, generics. iter ( ) . cloned ( ) ) )
@@ -365,36 +254,33 @@ pub(super) fn data_constructor<'a, DB: HirDatabase>(
365
254
366
255
// Note that we need special case for 0 param constructors because of multi cartesian
367
256
// product
368
- let struct_exprs: Vec < Expr > = if param_exprs. is_empty ( ) {
369
- vec ! [ Expr :: Struct { strukt: * it, generics, params: Vec :: new( ) } ]
257
+ let variant_exprs: Vec < Expr > = if param_exprs. is_empty ( ) {
258
+ vec ! [ Expr :: Variant {
259
+ variant,
260
+ generics: generics. clone( ) ,
261
+ params: Vec :: new( ) ,
262
+ } ]
370
263
} else {
371
264
param_exprs
372
265
. into_iter ( )
373
266
. multi_cartesian_product ( )
374
- . map ( |params| Expr :: Struct {
375
- strukt : * it ,
267
+ . map ( |params| Expr :: Variant {
268
+ variant ,
376
269
generics : generics. clone ( ) ,
377
270
params,
378
271
} )
379
272
. collect ( )
380
273
} ;
381
-
382
- if non_default_type_params_len == 0 {
383
- // Fulfilled only if there are no generic parameters
384
- lookup. mark_fulfilled ( ScopeDef :: ModuleDef ( ModuleDef :: Adt (
385
- Adt :: Struct ( * it) ,
386
- ) ) ) ;
387
- }
388
- lookup. insert ( struct_ty. clone ( ) , struct_exprs. iter ( ) . cloned ( ) ) ;
389
-
390
- Some ( ( struct_ty, struct_exprs) )
274
+ lookup. insert ( ty. clone ( ) , variant_exprs. iter ( ) . cloned ( ) ) ;
275
+ Some ( variant_exprs)
391
276
} )
277
+ . flatten ( )
392
278
. collect ( ) ;
393
- Some ( exprs)
279
+
280
+ Some ( ( ty, exprs) )
394
281
}
395
- _ => None ,
282
+ Adt :: Union ( _ ) => None ,
396
283
} )
397
- . flatten ( )
398
284
. filter_map ( |( ty, exprs) | ty. could_unify_with_deeply ( db, & ctx. goal ) . then_some ( exprs) )
399
285
. flatten ( )
400
286
}
0 commit comments