@@ -18,7 +18,6 @@ use triomphe::Arc;
18
18
use crate :: {
19
19
builtin_type:: { BuiltinInt , BuiltinUint } ,
20
20
db:: DefDatabase ,
21
- expander:: CfgExpander ,
22
21
item_tree:: { AttrOwner , Field , FieldAstId , Fields , ItemTree , ModItem , RawVisibilityId } ,
23
22
lang_item:: LangItem ,
24
23
lower:: LowerCtx ,
@@ -29,8 +28,8 @@ use crate::{
29
28
tt:: { Delimiter , DelimiterKind , Leaf , Subtree , TokenTree } ,
30
29
type_ref:: TypeRef ,
31
30
visibility:: RawVisibility ,
32
- EnumId , LocalEnumVariantId , LocalFieldId , LocalModuleId , Lookup , ModuleId , StructId , UnionId ,
33
- VariantId ,
31
+ EnumId , EnumLoc , LocalEnumVariantId , LocalFieldId , LocalModuleId , Lookup , ModuleId , StructId ,
32
+ UnionId , VariantId ,
34
33
} ;
35
34
36
35
/// Note that we use `StructData` for unions as well!
@@ -76,6 +75,7 @@ pub struct EnumData {
76
75
pub struct EnumVariantData {
77
76
pub name : Name ,
78
77
pub variant_data : Arc < VariantData > ,
78
+ pub tree_id : la_arena:: Idx < crate :: item_tree:: Variant > ,
79
79
}
80
80
81
81
#[ derive( Debug , Clone , PartialEq , Eq ) ]
@@ -326,6 +326,7 @@ impl EnumData {
326
326
variants. alloc ( EnumVariantData {
327
327
name : var. name . clone ( ) ,
328
328
variant_data : Arc :: new ( var_data) ,
329
+ tree_id,
329
330
} ) ;
330
331
} else {
331
332
diagnostics. push ( DefDiagnostic :: unconfigured_code (
@@ -368,9 +369,10 @@ impl HasChildSource<LocalEnumVariantId> for EnumId {
368
369
& self ,
369
370
db : & dyn DefDatabase ,
370
371
) -> InFile < ArenaMap < LocalEnumVariantId , Self :: Value > > {
371
- let src = self . lookup ( db) . source ( db) ;
372
+ let loc = & self . lookup ( db) ;
373
+ let src = loc. source ( db) ;
372
374
let mut trace = Trace :: new_for_map ( ) ;
373
- lower_enum ( db, & mut trace, & src, self . lookup ( db ) . container ) ;
375
+ lower_enum ( db, & mut trace, & src, loc ) ;
374
376
src. with_value ( trace. into_map ( ) )
375
377
}
376
378
}
@@ -379,31 +381,58 @@ fn lower_enum(
379
381
db : & dyn DefDatabase ,
380
382
trace : & mut Trace < EnumVariantData , ast:: Variant > ,
381
383
ast : & InFile < ast:: Enum > ,
382
- module_id : ModuleId ,
384
+ loc : & EnumLoc ,
383
385
) {
384
- let expander = CfgExpander :: new ( db, ast. file_id , module_id. krate ) ;
386
+ let item_tree = loc. id . item_tree ( db) ;
387
+ let krate = loc. container . krate ;
388
+
389
+ let item_tree_variants = item_tree[ loc. id . value ] . variants . clone ( ) ;
390
+
391
+ let cfg_options = & db. crate_graph ( ) [ krate] . cfg_options ;
385
392
let variants = ast
386
393
. value
387
394
. variant_list ( )
388
395
. into_iter ( )
389
396
. flat_map ( |it| it. variants ( ) )
390
- . filter ( |var| expander. is_cfg_enabled ( db, var) ) ;
391
- for var in variants {
397
+ . zip ( item_tree_variants)
398
+ . filter ( |& ( _, item_tree_id) | {
399
+ item_tree. attrs ( db, krate, item_tree_id. into ( ) ) . is_cfg_enabled ( cfg_options)
400
+ } ) ;
401
+ for ( var, item_tree_id) in variants {
392
402
trace. alloc (
393
403
|| var. clone ( ) ,
394
404
|| EnumVariantData {
395
405
name : var. name ( ) . map_or_else ( Name :: missing, |it| it. as_name ( ) ) ,
396
- variant_data : Arc :: new ( VariantData :: new ( db, ast. with_value ( var. kind ( ) ) , module_id) ) ,
406
+ variant_data : Arc :: new ( VariantData :: new (
407
+ db,
408
+ ast. with_value ( var. kind ( ) ) ,
409
+ loc. container ,
410
+ & item_tree,
411
+ item_tree_id,
412
+ ) ) ,
413
+ tree_id : item_tree_id,
397
414
} ,
398
415
) ;
399
416
}
400
417
}
401
418
402
419
impl VariantData {
403
- fn new ( db : & dyn DefDatabase , flavor : InFile < ast:: StructKind > , module_id : ModuleId ) -> Self {
404
- let mut expander = CfgExpander :: new ( db, flavor. file_id , module_id. krate ) ;
420
+ fn new (
421
+ db : & dyn DefDatabase ,
422
+ flavor : InFile < ast:: StructKind > ,
423
+ module_id : ModuleId ,
424
+ item_tree : & ItemTree ,
425
+ variant : la_arena:: Idx < crate :: item_tree:: Variant > ,
426
+ ) -> Self {
405
427
let mut trace = Trace :: new_for_arena ( ) ;
406
- match lower_struct ( db, & mut expander, & mut trace, & flavor) {
428
+ match lower_struct (
429
+ db,
430
+ & mut trace,
431
+ & flavor,
432
+ module_id. krate ,
433
+ item_tree,
434
+ & item_tree[ variant] . fields ,
435
+ ) {
407
436
StructKind :: Tuple => VariantData :: Tuple ( trace. into_arena ( ) ) ,
408
437
StructKind :: Record => VariantData :: Record ( trace. into_arena ( ) ) ,
409
438
StructKind :: Unit => VariantData :: Unit ,
@@ -435,28 +464,43 @@ impl HasChildSource<LocalFieldId> for VariantId {
435
464
type Value = Either < ast:: TupleField , ast:: RecordField > ;
436
465
437
466
fn child_source ( & self , db : & dyn DefDatabase ) -> InFile < ArenaMap < LocalFieldId , Self :: Value > > {
438
- let ( src, module_id) = match self {
467
+ let item_tree;
468
+ let ( src, fields, container) = match * self {
439
469
VariantId :: EnumVariantId ( it) => {
440
470
// I don't really like the fact that we call into parent source
441
471
// here, this might add to more queries then necessary.
472
+ let lookup = it. parent . lookup ( db) ;
473
+ item_tree = lookup. id . item_tree ( db) ;
442
474
let src = it. parent . child_source ( db) ;
443
- ( src. map ( |map| map[ it. local_id ] . kind ( ) ) , it. parent . lookup ( db) . container )
475
+ let tree_id = db. enum_data ( it. parent ) . variants [ it. local_id ] . tree_id ;
476
+ let fields = & item_tree[ tree_id] . fields ;
477
+ ( src. map ( |map| map[ it. local_id ] . kind ( ) ) , fields, lookup. container )
444
478
}
445
479
VariantId :: StructId ( it) => {
446
- ( it. lookup ( db) . source ( db) . map ( |it| it. kind ( ) ) , it. lookup ( db) . container )
480
+ let lookup = it. lookup ( db) ;
481
+ item_tree = lookup. id . item_tree ( db) ;
482
+ (
483
+ lookup. source ( db) . map ( |it| it. kind ( ) ) ,
484
+ & item_tree[ lookup. id . value ] . fields ,
485
+ lookup. container ,
486
+ )
487
+ }
488
+ VariantId :: UnionId ( it) => {
489
+ let lookup = it. lookup ( db) ;
490
+ item_tree = lookup. id . item_tree ( db) ;
491
+ (
492
+ lookup. source ( db) . map ( |it| {
493
+ it. record_field_list ( )
494
+ . map ( ast:: StructKind :: Record )
495
+ . unwrap_or ( ast:: StructKind :: Unit )
496
+ } ) ,
497
+ & item_tree[ lookup. id . value ] . fields ,
498
+ lookup. container ,
499
+ )
447
500
}
448
- VariantId :: UnionId ( it) => (
449
- it. lookup ( db) . source ( db) . map ( |it| {
450
- it. record_field_list ( )
451
- . map ( ast:: StructKind :: Record )
452
- . unwrap_or ( ast:: StructKind :: Unit )
453
- } ) ,
454
- it. lookup ( db) . container ,
455
- ) ,
456
501
} ;
457
- let mut expander = CfgExpander :: new ( db, src. file_id , module_id. krate ) ;
458
502
let mut trace = Trace :: new_for_map ( ) ;
459
- lower_struct ( db, & mut expander , & mut trace , & src ) ;
503
+ lower_struct ( db, & mut trace , & src , container . krate , & item_tree , fields ) ;
460
504
src. with_value ( trace. into_map ( ) )
461
505
}
462
506
}
@@ -470,16 +514,19 @@ pub enum StructKind {
470
514
471
515
fn lower_struct (
472
516
db : & dyn DefDatabase ,
473
- expander : & mut CfgExpander ,
474
517
trace : & mut Trace < FieldData , Either < ast:: TupleField , ast:: RecordField > > ,
475
518
ast : & InFile < ast:: StructKind > ,
519
+ krate : CrateId ,
520
+ item_tree : & ItemTree ,
521
+ fields : & Fields ,
476
522
) -> StructKind {
477
- let ctx = LowerCtx :: new ( db, & expander . hygiene ( ) , ast. file_id ) ;
523
+ let ctx = LowerCtx :: with_file_id ( db, ast. file_id ) ;
478
524
479
- match & ast. value {
480
- ast:: StructKind :: Tuple ( fl) => {
481
- for ( i, fd) in fl. fields ( ) . enumerate ( ) {
482
- if !expander. is_cfg_enabled ( db, & fd) {
525
+ match ( & ast. value , fields) {
526
+ ( ast:: StructKind :: Tuple ( fl) , Fields :: Tuple ( fields) ) => {
527
+ let cfg_options = & db. crate_graph ( ) [ krate] . cfg_options ;
528
+ for ( ( i, fd) , item_tree_id) in fl. fields ( ) . enumerate ( ) . zip ( fields. clone ( ) ) {
529
+ if !item_tree. attrs ( db, krate, item_tree_id. into ( ) ) . is_cfg_enabled ( cfg_options) {
483
530
continue ;
484
531
}
485
532
@@ -494,9 +541,10 @@ fn lower_struct(
494
541
}
495
542
StructKind :: Tuple
496
543
}
497
- ast:: StructKind :: Record ( fl) => {
498
- for fd in fl. fields ( ) {
499
- if !expander. is_cfg_enabled ( db, & fd) {
544
+ ( ast:: StructKind :: Record ( fl) , Fields :: Record ( fields) ) => {
545
+ let cfg_options = & db. crate_graph ( ) [ krate] . cfg_options ;
546
+ for ( fd, item_tree_id) in fl. fields ( ) . zip ( fields. clone ( ) ) {
547
+ if !item_tree. attrs ( db, krate, item_tree_id. into ( ) ) . is_cfg_enabled ( cfg_options) {
500
548
continue ;
501
549
}
502
550
@@ -511,7 +559,7 @@ fn lower_struct(
511
559
}
512
560
StructKind :: Record
513
561
}
514
- ast :: StructKind :: Unit => StructKind :: Unit ,
562
+ _ => StructKind :: Unit ,
515
563
}
516
564
}
517
565
0 commit comments