@@ -159,17 +159,47 @@ impl GenericParams {
159
159
let krate = def. module ( db) . krate ;
160
160
let cfg_options = db. crate_graph ( ) ;
161
161
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 | {
163
165
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
+ }
173
203
} ;
174
204
macro_rules! id_to_generics {
175
205
( $id: ident) => { {
@@ -186,7 +216,8 @@ impl GenericParams {
186
216
let tree = loc. id . item_tree ( db) ;
187
217
let item = & tree[ loc. id . value ] ;
188
218
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) ;
190
221
191
222
let module = loc. container . module ( db) ;
192
223
let func_data = db. function_data ( id) ;
0 commit comments