@@ -159,17 +159,47 @@ impl GenericParams {
159159 let krate = def. module ( db) . krate ;
160160 let cfg_options = db. crate_graph ( ) ;
161161 let cfg_options = & cfg_options[ krate] . cfg_options ;
162- let enabled_params = |params : & GenericParams , item_tree : & ItemTree | {
162+
163+ // Returns the generic parameters that are enabled under the current `#[cfg]` options
164+ let enabled_params = |params : & Interned < GenericParams > , item_tree : & ItemTree | {
163165 let enabled = |param| item_tree. attrs ( db, krate, param) . is_cfg_enabled ( cfg_options) ;
164- Interned :: new ( GenericParams {
165- type_or_consts : ( params. type_or_consts . iter ( ) )
166- . filter_map ( |( idx, param) | enabled ( idx. into ( ) ) . then ( || param. clone ( ) ) )
167- . collect ( ) ,
168- lifetimes : ( params. lifetimes . iter ( ) )
169- . filter_map ( |( idx, param) | enabled ( idx. into ( ) ) . then ( || param. clone ( ) ) )
170- . collect ( ) ,
171- where_predicates : params. where_predicates . clone ( ) ,
172- } )
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+ }
173203 } ;
174204 macro_rules! id_to_generics {
175205 ( $id: ident) => { {
@@ -186,7 +216,8 @@ impl GenericParams {
186216 let tree = loc. id . item_tree ( db) ;
187217 let item = & tree[ loc. id . value ] ;
188218
189- let mut generic_params = GenericParams :: clone ( & item. explicit_generic_params ) ;
219+ let enabled_params = enabled_params ( & item. explicit_generic_params , & tree) ;
220+ let mut generic_params = GenericParams :: clone ( & enabled_params) ;
190221
191222 let module = loc. container . module ( db) ;
192223 let func_data = db. function_data ( id) ;
0 commit comments