@@ -107,11 +107,11 @@ impl TypeOrConstParamData {
107107impl_from ! ( TypeParamData , ConstParamData for TypeOrConstParamData ) ;
108108
109109/// 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 ) ]
111111pub struct GenericParams {
112112 pub type_or_consts : Arena < TypeOrConstParamData > ,
113113 pub lifetimes : Arena < LifetimeParamData > ,
114- pub where_predicates : Vec < WherePredicate > ,
114+ pub where_predicates : Box < [ WherePredicate ] > ,
115115}
116116
117117/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
@@ -142,109 +142,14 @@ pub enum WherePredicateTypeTarget {
142142 TypeOrConstParam ( LocalTypeOrConstParamId ) ,
143143}
144144
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 type_or_consts : Arena < TypeOrConstParamData > ,
148+ pub lifetimes : Arena < LifetimeParamData > ,
149+ pub where_predicates : Vec < WherePredicate > ,
150+ }
247151
152+ impl GenericParamsCollector {
248153 pub ( crate ) fn fill (
249154 & mut self ,
250155 lower_ctx : & LowerCtx < ' _ > ,
@@ -444,11 +349,131 @@ impl GenericParams {
444349 } ) ;
445350 }
446351
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 ;
449354 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+ }
452477 }
453478
454479 pub fn find_type_by_name ( & self , name : & Name , parent : GenericDefId ) -> Option < TypeParamId > {
0 commit comments