@@ -21,6 +21,7 @@ use crate::{
21
21
db:: DefDatabase ,
22
22
dyn_map:: { keys, DynMap } ,
23
23
expander:: Expander ,
24
+ item_tree:: { AttrOwner , ItemTree } ,
24
25
lower:: LowerCtx ,
25
26
nameres:: { DefMap , MacroSubNs } ,
26
27
src:: { HasChildSource , HasSource } ,
@@ -154,12 +155,58 @@ impl GenericParams {
154
155
def : GenericDefId ,
155
156
) -> Interned < GenericParams > {
156
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
+ } ;
157
204
macro_rules! id_to_generics {
158
205
( $id: ident) => { {
159
206
let id = $id. lookup( db) . id;
160
207
let tree = id. item_tree( db) ;
161
208
let item = & tree[ id. value] ;
162
- item. generic_params. clone ( )
209
+ enabled_params ( & item. generic_params, & tree )
163
210
} } ;
164
211
}
165
212
@@ -169,7 +216,8 @@ impl GenericParams {
169
216
let tree = loc. id . item_tree ( db) ;
170
217
let item = & tree[ loc. id . value ] ;
171
218
172
- 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) ;
173
221
174
222
let module = loc. container . module ( db) ;
175
223
let func_data = db. function_data ( id) ;
@@ -198,9 +246,14 @@ impl GenericParams {
198
246
}
199
247
}
200
248
201
- pub ( crate ) fn fill ( & mut self , lower_ctx : & LowerCtx < ' _ > , node : & dyn HasGenericParams ) {
249
+ pub ( crate ) fn fill (
250
+ & mut self ,
251
+ lower_ctx : & LowerCtx < ' _ > ,
252
+ node : & dyn HasGenericParams ,
253
+ add_param_attrs : impl FnMut ( AttrOwner , ast:: GenericParam ) ,
254
+ ) {
202
255
if let Some ( params) = node. generic_param_list ( ) {
203
- self . fill_params ( lower_ctx, params)
256
+ self . fill_params ( lower_ctx, params, add_param_attrs )
204
257
}
205
258
if let Some ( where_clause) = node. where_clause ( ) {
206
259
self . fill_where_predicates ( lower_ctx, where_clause) ;
@@ -218,7 +271,12 @@ impl GenericParams {
218
271
}
219
272
}
220
273
221
- fn fill_params ( & mut self , lower_ctx : & LowerCtx < ' _ > , params : ast:: GenericParamList ) {
274
+ fn fill_params (
275
+ & mut self ,
276
+ lower_ctx : & LowerCtx < ' _ > ,
277
+ params : ast:: GenericParamList ,
278
+ mut add_param_attrs : impl FnMut ( AttrOwner , ast:: GenericParam ) ,
279
+ ) {
222
280
for type_or_const_param in params. type_or_const_params ( ) {
223
281
match type_or_const_param {
224
282
ast:: TypeOrConstParam :: Type ( type_param) => {
@@ -232,13 +290,14 @@ impl GenericParams {
232
290
default,
233
291
provenance : TypeParamProvenance :: TypeParamList ,
234
292
} ;
235
- self . type_or_consts . alloc ( param. into ( ) ) ;
293
+ let idx = self . type_or_consts . alloc ( param. into ( ) ) ;
236
294
let type_ref = TypeRef :: Path ( name. into ( ) ) ;
237
295
self . fill_bounds (
238
296
lower_ctx,
239
297
type_param. type_bound_list ( ) ,
240
298
Either :: Left ( type_ref) ,
241
299
) ;
300
+ add_param_attrs ( idx. into ( ) , ast:: GenericParam :: TypeParam ( type_param) ) ;
242
301
}
243
302
ast:: TypeOrConstParam :: Const ( const_param) => {
244
303
let name = const_param. name ( ) . map_or_else ( Name :: missing, |it| it. as_name ( ) ) ;
@@ -250,21 +309,23 @@ impl GenericParams {
250
309
ty : Interned :: new ( ty) ,
251
310
has_default : const_param. default_val ( ) . is_some ( ) ,
252
311
} ;
253
- self . type_or_consts . alloc ( param. into ( ) ) ;
312
+ let idx = self . type_or_consts . alloc ( param. into ( ) ) ;
313
+ add_param_attrs ( idx. into ( ) , ast:: GenericParam :: ConstParam ( const_param) ) ;
254
314
}
255
315
}
256
316
}
257
317
for lifetime_param in params. lifetime_params ( ) {
258
318
let name =
259
319
lifetime_param. lifetime ( ) . map_or_else ( Name :: missing, |lt| Name :: new_lifetime ( & lt) ) ;
260
320
let param = LifetimeParamData { name : name. clone ( ) } ;
261
- self . lifetimes . alloc ( param) ;
321
+ let idx = self . lifetimes . alloc ( param) ;
262
322
let lifetime_ref = LifetimeRef :: new_name ( name) ;
263
323
self . fill_bounds (
264
324
lower_ctx,
265
325
lifetime_param. type_bound_list ( ) ,
266
326
Either :: Right ( lifetime_ref) ,
267
327
) ;
328
+ add_param_attrs ( idx. into ( ) , ast:: GenericParam :: LifetimeParam ( lifetime_param) ) ;
268
329
}
269
330
}
270
331
0 commit comments