@@ -107,11 +107,11 @@ impl TypeOrConstParamData {
107
107
impl_from ! ( TypeParamData , ConstParamData for TypeOrConstParamData ) ;
108
108
109
109
/// Data about the generic parameters of a function, struct, impl, etc.
110
- #[ derive( Clone , PartialEq , Eq , Debug , Default , Hash ) ]
110
+ #[ derive( Clone , PartialEq , Eq , Debug , Hash ) ]
111
111
pub struct GenericParams {
112
112
pub type_or_consts : Arena < TypeOrConstParamData > ,
113
113
pub lifetimes : Arena < LifetimeParamData > ,
114
- pub where_predicates : Vec < WherePredicate > ,
114
+ pub where_predicates : Box < [ WherePredicate ] > ,
115
115
}
116
116
117
117
/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
@@ -142,109 +142,14 @@ pub enum WherePredicateTypeTarget {
142
142
TypeOrConstParam ( LocalTypeOrConstParamId ) ,
143
143
}
144
144
145
- impl GenericParams {
146
- /// Iterator of type_or_consts field
147
- pub fn iter (
148
- & self ,
149
- ) -> impl DoubleEndedIterator < Item = ( Idx < TypeOrConstParamData > , & TypeOrConstParamData ) > {
150
- self . type_or_consts . iter ( )
151
- }
152
-
153
- pub ( crate ) fn generic_params_query (
154
- db : & dyn DefDatabase ,
155
- def : GenericDefId ,
156
- ) -> Interned < GenericParams > {
157
- let _p = profile:: span ( "generic_params_query" ) ;
158
-
159
- let krate = def. module ( db) . krate ;
160
- let cfg_options = db. crate_graph ( ) ;
161
- let cfg_options = & cfg_options[ krate] . cfg_options ;
162
-
163
- // Returns the generic parameters that are enabled under the current `#[cfg]` options
164
- let enabled_params = |params : & Interned < GenericParams > , item_tree : & ItemTree | {
165
- let enabled = |param| item_tree. attrs ( db, krate, param) . is_cfg_enabled ( cfg_options) ;
166
-
167
- // In the common case, no parameters will by disabled by `#[cfg]` attributes.
168
- // Therefore, make a first pass to check if all parameters are enabled and, if so,
169
- // clone the `Interned<GenericParams>` instead of recreating an identical copy.
170
- let all_type_or_consts_enabled =
171
- params. type_or_consts . iter ( ) . all ( |( idx, _) | enabled ( idx. into ( ) ) ) ;
172
- let all_lifetimes_enabled = params. lifetimes . iter ( ) . all ( |( idx, _) | enabled ( idx. into ( ) ) ) ;
173
-
174
- if all_type_or_consts_enabled && all_lifetimes_enabled {
175
- params. clone ( )
176
- } else {
177
- Interned :: new ( GenericParams {
178
- type_or_consts : all_type_or_consts_enabled
179
- . then ( || params. type_or_consts . clone ( ) )
180
- . unwrap_or_else ( || {
181
- params
182
- . type_or_consts
183
- . iter ( )
184
- . filter_map ( |( idx, param) | {
185
- enabled ( idx. into ( ) ) . then ( || param. clone ( ) )
186
- } )
187
- . collect ( )
188
- } ) ,
189
- lifetimes : all_lifetimes_enabled
190
- . then ( || params. lifetimes . clone ( ) )
191
- . unwrap_or_else ( || {
192
- params
193
- . lifetimes
194
- . iter ( )
195
- . filter_map ( |( idx, param) | {
196
- enabled ( idx. into ( ) ) . then ( || param. clone ( ) )
197
- } )
198
- . collect ( )
199
- } ) ,
200
- where_predicates : params. where_predicates . clone ( ) ,
201
- } )
202
- }
203
- } ;
204
- macro_rules! id_to_generics {
205
- ( $id: ident) => { {
206
- let id = $id. lookup( db) . id;
207
- let tree = id. item_tree( db) ;
208
- let item = & tree[ id. value] ;
209
- enabled_params( & item. generic_params, & tree)
210
- } } ;
211
- }
212
-
213
- match def {
214
- GenericDefId :: FunctionId ( id) => {
215
- let loc = id. lookup ( db) ;
216
- let tree = loc. id . item_tree ( db) ;
217
- let item = & tree[ loc. id . value ] ;
218
-
219
- let enabled_params = enabled_params ( & item. explicit_generic_params , & tree) ;
220
- let mut generic_params = GenericParams :: clone ( & enabled_params) ;
221
-
222
- let module = loc. container . module ( db) ;
223
- let func_data = db. function_data ( id) ;
224
-
225
- // Don't create an `Expander` if not needed since this
226
- // could cause a reparse after the `ItemTree` has been created due to the spanmap.
227
- let mut expander =
228
- Lazy :: new ( || ( module. def_map ( db) , Expander :: new ( db, loc. id . file_id ( ) , module) ) ) ;
229
- for param in func_data. params . iter ( ) {
230
- generic_params. fill_implicit_impl_trait_args ( db, & mut expander, param) ;
231
- }
232
-
233
- Interned :: new ( generic_params)
234
- }
235
- GenericDefId :: AdtId ( AdtId :: StructId ( id) ) => id_to_generics ! ( id) ,
236
- GenericDefId :: AdtId ( AdtId :: EnumId ( id) ) => id_to_generics ! ( id) ,
237
- GenericDefId :: AdtId ( AdtId :: UnionId ( id) ) => id_to_generics ! ( id) ,
238
- GenericDefId :: TraitId ( id) => id_to_generics ! ( id) ,
239
- GenericDefId :: TraitAliasId ( id) => id_to_generics ! ( id) ,
240
- GenericDefId :: TypeAliasId ( id) => id_to_generics ! ( id) ,
241
- GenericDefId :: ImplId ( id) => id_to_generics ! ( id) ,
242
- GenericDefId :: EnumVariantId ( _) | GenericDefId :: ConstId ( _) => {
243
- Interned :: new ( GenericParams :: default ( ) )
244
- }
245
- }
246
- }
145
+ #[ derive( Clone , Default ) ]
146
+ pub ( crate ) struct GenericParamsCollector {
147
+ pub ( crate ) type_or_consts : Arena < TypeOrConstParamData > ,
148
+ lifetimes : Arena < LifetimeParamData > ,
149
+ where_predicates : Vec < WherePredicate > ,
150
+ }
247
151
152
+ impl GenericParamsCollector {
248
153
pub ( crate ) fn fill (
249
154
& mut self ,
250
155
lower_ctx : & LowerCtx < ' _ > ,
@@ -444,11 +349,131 @@ impl GenericParams {
444
349
} ) ;
445
350
}
446
351
447
- pub ( crate ) fn shrink_to_fit ( & mut self ) {
448
- let Self { lifetimes, type_or_consts : types , where_predicates } = self ;
352
+ pub ( crate ) fn finish ( self ) -> GenericParams {
353
+ let Self { mut lifetimes, mut type_or_consts , where_predicates } = self ;
449
354
lifetimes. shrink_to_fit ( ) ;
450
- types. shrink_to_fit ( ) ;
451
- where_predicates. shrink_to_fit ( ) ;
355
+ type_or_consts. shrink_to_fit ( ) ;
356
+ GenericParams {
357
+ type_or_consts,
358
+ lifetimes,
359
+ where_predicates : where_predicates. into_boxed_slice ( ) ,
360
+ }
361
+ }
362
+ }
363
+
364
+ impl GenericParams {
365
+ /// Iterator of type_or_consts field
366
+ pub fn iter (
367
+ & self ,
368
+ ) -> impl DoubleEndedIterator < Item = ( Idx < TypeOrConstParamData > , & TypeOrConstParamData ) > {
369
+ self . type_or_consts . iter ( )
370
+ }
371
+
372
+ pub ( crate ) fn generic_params_query (
373
+ db : & dyn DefDatabase ,
374
+ def : GenericDefId ,
375
+ ) -> Interned < GenericParams > {
376
+ let _p = profile:: span ( "generic_params_query" ) ;
377
+
378
+ let krate = def. module ( db) . krate ;
379
+ let cfg_options = db. crate_graph ( ) ;
380
+ let cfg_options = & cfg_options[ krate] . cfg_options ;
381
+
382
+ // Returns the generic parameters that are enabled under the current `#[cfg]` options
383
+ let enabled_params = |params : & Interned < GenericParams > , item_tree : & ItemTree | {
384
+ let enabled = |param| item_tree. attrs ( db, krate, param) . is_cfg_enabled ( cfg_options) ;
385
+
386
+ // In the common case, no parameters will by disabled by `#[cfg]` attributes.
387
+ // Therefore, make a first pass to check if all parameters are enabled and, if so,
388
+ // clone the `Interned<GenericParams>` instead of recreating an identical copy.
389
+ let all_type_or_consts_enabled =
390
+ params. type_or_consts . iter ( ) . all ( |( idx, _) | enabled ( idx. into ( ) ) ) ;
391
+ let all_lifetimes_enabled = params. lifetimes . iter ( ) . all ( |( idx, _) | enabled ( idx. into ( ) ) ) ;
392
+
393
+ if all_type_or_consts_enabled && all_lifetimes_enabled {
394
+ params. clone ( )
395
+ } else {
396
+ Interned :: new ( GenericParams {
397
+ type_or_consts : all_type_or_consts_enabled
398
+ . then ( || params. type_or_consts . clone ( ) )
399
+ . unwrap_or_else ( || {
400
+ params
401
+ . type_or_consts
402
+ . iter ( )
403
+ . filter_map ( |( idx, param) | {
404
+ enabled ( idx. into ( ) ) . then ( || param. clone ( ) )
405
+ } )
406
+ . collect ( )
407
+ } ) ,
408
+ lifetimes : all_lifetimes_enabled
409
+ . then ( || params. lifetimes . clone ( ) )
410
+ . unwrap_or_else ( || {
411
+ params
412
+ . lifetimes
413
+ . iter ( )
414
+ . filter_map ( |( idx, param) | {
415
+ enabled ( idx. into ( ) ) . then ( || param. clone ( ) )
416
+ } )
417
+ . collect ( )
418
+ } ) ,
419
+ where_predicates : params. where_predicates . clone ( ) ,
420
+ } )
421
+ }
422
+ } ;
423
+ macro_rules! id_to_generics {
424
+ ( $id: ident) => { {
425
+ let id = $id. lookup( db) . id;
426
+ let tree = id. item_tree( db) ;
427
+ let item = & tree[ id. value] ;
428
+ enabled_params( & item. generic_params, & tree)
429
+ } } ;
430
+ }
431
+
432
+ match def {
433
+ GenericDefId :: FunctionId ( id) => {
434
+ let loc = id. lookup ( db) ;
435
+ let tree = loc. id . item_tree ( db) ;
436
+ let item = & tree[ loc. id . value ] ;
437
+
438
+ let enabled_params = enabled_params ( & item. explicit_generic_params , & tree) ;
439
+
440
+ let module = loc. container . module ( db) ;
441
+ let func_data = db. function_data ( id) ;
442
+ if func_data. params . is_empty ( ) {
443
+ enabled_params
444
+ } else {
445
+ let mut generic_params = GenericParamsCollector {
446
+ type_or_consts : enabled_params. type_or_consts . clone ( ) ,
447
+ lifetimes : enabled_params. lifetimes . clone ( ) ,
448
+ where_predicates : enabled_params. where_predicates . clone ( ) . into ( ) ,
449
+ } ;
450
+
451
+ // Don't create an `Expander` if not needed since this
452
+ // could cause a reparse after the `ItemTree` has been created due to the spanmap.
453
+ let mut expander = Lazy :: new ( || {
454
+ ( module. def_map ( db) , Expander :: new ( db, loc. id . file_id ( ) , module) )
455
+ } ) ;
456
+ for param in func_data. params . iter ( ) {
457
+ generic_params. fill_implicit_impl_trait_args ( db, & mut expander, param) ;
458
+ }
459
+ Interned :: new ( generic_params. finish ( ) )
460
+ }
461
+ }
462
+ GenericDefId :: AdtId ( AdtId :: StructId ( id) ) => id_to_generics ! ( id) ,
463
+ GenericDefId :: AdtId ( AdtId :: EnumId ( id) ) => id_to_generics ! ( id) ,
464
+ GenericDefId :: AdtId ( AdtId :: UnionId ( id) ) => id_to_generics ! ( id) ,
465
+ GenericDefId :: TraitId ( id) => id_to_generics ! ( id) ,
466
+ GenericDefId :: TraitAliasId ( id) => id_to_generics ! ( id) ,
467
+ GenericDefId :: TypeAliasId ( id) => id_to_generics ! ( id) ,
468
+ GenericDefId :: ImplId ( id) => id_to_generics ! ( id) ,
469
+ GenericDefId :: EnumVariantId ( _) | GenericDefId :: ConstId ( _) => {
470
+ Interned :: new ( GenericParams {
471
+ type_or_consts : Default :: default ( ) ,
472
+ lifetimes : Default :: default ( ) ,
473
+ where_predicates : Default :: default ( ) ,
474
+ } )
475
+ }
476
+ }
452
477
}
453
478
454
479
pub fn find_type_by_name ( & self , name : & Name , parent : GenericDefId ) -> Option < TypeParamId > {
0 commit comments