@@ -18,7 +18,6 @@ use triomphe::Arc;
1818use crate :: {
1919 builtin_type:: { BuiltinInt , BuiltinUint } ,
2020 db:: DefDatabase ,
21- expander:: CfgExpander ,
2221 item_tree:: { AttrOwner , Field , FieldAstId , Fields , ItemTree , ModItem , RawVisibilityId } ,
2322 lang_item:: LangItem ,
2423 lower:: LowerCtx ,
@@ -29,8 +28,8 @@ use crate::{
2928 tt:: { Delimiter , DelimiterKind , Leaf , Subtree , TokenTree } ,
3029 type_ref:: TypeRef ,
3130 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 ,
3433} ;
3534
3635/// Note that we use `StructData` for unions as well!
@@ -76,6 +75,7 @@ pub struct EnumData {
7675pub struct EnumVariantData {
7776 pub name : Name ,
7877 pub variant_data : Arc < VariantData > ,
78+ pub tree_id : la_arena:: Idx < crate :: item_tree:: Variant > ,
7979}
8080
8181#[ derive( Debug , Clone , PartialEq , Eq ) ]
@@ -326,6 +326,7 @@ impl EnumData {
326326 variants. alloc ( EnumVariantData {
327327 name : var. name . clone ( ) ,
328328 variant_data : Arc :: new ( var_data) ,
329+ tree_id,
329330 } ) ;
330331 } else {
331332 diagnostics. push ( DefDiagnostic :: unconfigured_code (
@@ -368,9 +369,10 @@ impl HasChildSource<LocalEnumVariantId> for EnumId {
368369 & self ,
369370 db : & dyn DefDatabase ,
370371 ) -> 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) ;
372374 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 ) ;
374376 src. with_value ( trace. into_map ( ) )
375377 }
376378}
@@ -379,31 +381,58 @@ fn lower_enum(
379381 db : & dyn DefDatabase ,
380382 trace : & mut Trace < EnumVariantData , ast:: Variant > ,
381383 ast : & InFile < ast:: Enum > ,
382- module_id : ModuleId ,
384+ loc : & EnumLoc ,
383385) {
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 ;
385392 let variants = ast
386393 . value
387394 . variant_list ( )
388395 . into_iter ( )
389396 . 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 {
392402 trace. alloc (
393403 || var. clone ( ) ,
394404 || EnumVariantData {
395405 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,
397414 } ,
398415 ) ;
399416 }
400417}
401418
402419impl 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 {
405427 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+ ) {
407436 StructKind :: Tuple => VariantData :: Tuple ( trace. into_arena ( ) ) ,
408437 StructKind :: Record => VariantData :: Record ( trace. into_arena ( ) ) ,
409438 StructKind :: Unit => VariantData :: Unit ,
@@ -435,28 +464,43 @@ impl HasChildSource<LocalFieldId> for VariantId {
435464 type Value = Either < ast:: TupleField , ast:: RecordField > ;
436465
437466 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 {
439469 VariantId :: EnumVariantId ( it) => {
440470 // I don't really like the fact that we call into parent source
441471 // here, this might add to more queries then necessary.
472+ let lookup = it. parent . lookup ( db) ;
473+ item_tree = lookup. id . item_tree ( db) ;
442474 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 )
444478 }
445479 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+ )
447500 }
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- ) ,
456501 } ;
457- let mut expander = CfgExpander :: new ( db, src. file_id , module_id. krate ) ;
458502 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 ) ;
460504 src. with_value ( trace. into_map ( ) )
461505 }
462506}
@@ -470,16 +514,19 @@ pub enum StructKind {
470514
471515fn lower_struct (
472516 db : & dyn DefDatabase ,
473- expander : & mut CfgExpander ,
474517 trace : & mut Trace < FieldData , Either < ast:: TupleField , ast:: RecordField > > ,
475518 ast : & InFile < ast:: StructKind > ,
519+ krate : CrateId ,
520+ item_tree : & ItemTree ,
521+ fields : & Fields ,
476522) -> StructKind {
477- let ctx = LowerCtx :: new ( db, & expander . hygiene ( ) , ast. file_id ) ;
523+ let ctx = LowerCtx :: with_file_id ( db, ast. file_id ) ;
478524
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) {
483530 continue ;
484531 }
485532
@@ -494,9 +541,10 @@ fn lower_struct(
494541 }
495542 StructKind :: Tuple
496543 }
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) {
500548 continue ;
501549 }
502550
@@ -511,7 +559,7 @@ fn lower_struct(
511559 }
512560 StructKind :: Record
513561 }
514- ast :: StructKind :: Unit => StructKind :: Unit ,
562+ _ => StructKind :: Unit ,
515563 }
516564}
517565
0 commit comments