@@ -11,7 +11,7 @@ use cairo_lang_defs::db::DefsGroup;
1111use cairo_lang_defs:: diagnostic_utils:: StableLocation ;
1212use cairo_lang_defs:: ids:: {
1313 EnumLongId , ExternFunctionLongId , ExternTypeLongId , FreeFunctionLongId , ImplFunctionLongId ,
14- LocalVarId , LocalVarLongId , MemberLongId , ParamId , ParamLongId , StatementConstLongId ,
14+ LocalVarId , LocalVarLongId , MemberLongId , ModuleId , ParamId , ParamLongId , StatementConstLongId ,
1515 StatementItemId , StatementUseLongId , StructLongId , TraitConstantId , TraitConstantLongId ,
1616 TraitFunctionLongId , TraitImplId , TraitImplLongId , TraitLongId , TraitTypeId , TraitTypeLongId ,
1717 VarId , VariantLongId ,
@@ -29,7 +29,6 @@ use cairo_lang_syntax::node::ast::{
2929use cairo_lang_utils:: Intern ;
3030use cairo_lang_utils:: ordered_hash_map:: OrderedHashMap ;
3131use cairo_lang_utils:: smol_str:: SmolStr ;
32- use itertools:: chain;
3332use num_bigint:: BigInt ;
3433use salsa:: Database ;
3534use serde:: { Deserialize , Serialize } ;
@@ -47,7 +46,7 @@ use crate::items::imp::{
4746 NegativeImplId , NegativeImplLongId ,
4847} ;
4948use crate :: items:: impl_alias:: ImplAliasSemantic ;
50- use crate :: items:: macro_call:: module_macro_modules ;
49+ use crate :: items:: macro_call:: MacroCallSemantic ;
5150use crate :: items:: module:: { ModuleItemInfo , ModuleSemantic , ModuleSemanticData } ;
5251use crate :: items:: trt:: ConcreteTraitGenericFunctionLongId ;
5352use crate :: items:: visibility:: Visibility ;
@@ -125,19 +124,17 @@ pub fn generate_crate_def_cache<'db>(
125124 crate_id : cairo_lang_filesystem:: ids:: CrateId < ' db > ,
126125 ctx : & mut DefCacheSavingContext < ' db > ,
127126) -> Maybe < CrateDefCache < ' db > > {
128- let modules = db. crate_modules ( crate_id) ;
129-
130- let mut modules_data = Vec :: new ( ) ;
131- for module_id in modules. iter ( ) {
132- for module_id in chain ! ( [ module_id] , module_macro_modules( db, true , * module_id) ) {
133- let module_data = module_id. module_data ( db) ?;
134- modules_data. push ( (
135- ModuleIdCached :: new ( * module_id, ctx) ,
136- ModuleDataCached :: new ( db, module_data, ctx) ,
137- ) ) ;
138- }
139- }
140- Ok ( CrateDefCache :: new ( modules_data) )
127+ Ok ( CrateDefCache :: new (
128+ all_crate_modules_for_cache ( db, crate_id)
129+ . into_iter ( )
130+ . map ( |module_id| {
131+ Ok ( (
132+ ModuleIdCached :: new ( module_id, ctx) ,
133+ ModuleDataCached :: new ( db, module_id. module_data ( db) ?, ctx) ,
134+ ) )
135+ } )
136+ . collect :: < Maybe < _ > > ( ) ?,
137+ ) )
141138}
142139
143140/// Semantic items in the semantic cache.
@@ -154,22 +151,24 @@ pub fn generate_crate_semantic_cache<'db>(
154151 crate_id : CrateId < ' db > ,
155152 ctx : & mut SemanticCacheSavingContext < ' db > ,
156153) -> Maybe < CrateSemanticCache > {
157- let modules = ctx. db . crate_modules ( crate_id) ;
154+ let all_modules = all_crate_modules_for_cache ( ctx. db , crate_id) ;
158155
159- let mut modules_data = Vec :: new ( ) ;
160- for module_id in modules. iter ( ) {
161- for module_id in chain ! ( [ module_id] , module_macro_modules( ctx. db, true , * module_id) ) {
162- let module_data = ctx. db . priv_module_semantic_data ( * module_id) ?. clone ( ) ;
163- modules_data. push ( (
156+ let modules_data = all_modules
157+ . iter ( )
158+ . map ( |module_id| {
159+ Ok ( (
164160 ModuleIdCached :: new ( * module_id, & mut ctx. defs_ctx ) ,
165- ModuleSemanticDataCached :: new ( module_data, ctx) ,
166- ) ) ;
167- }
168- }
161+ ModuleSemanticDataCached :: new (
162+ ctx. db . priv_module_semantic_data ( * module_id) ?. clone ( ) ,
163+ ctx,
164+ ) ,
165+ ) )
166+ } )
167+ . collect :: < Maybe < _ > > ( ) ?;
169168
170169 Ok ( CrateSemanticCache {
171170 modules : modules_data,
172- impl_aliases : modules
171+ impl_aliases : all_modules
173172 . iter ( )
174173 . flat_map ( |id| match ctx. db . module_impl_aliases_ids ( * id) {
175174 Err ( err) => vec ! [ Err ( err) ] ,
@@ -2005,3 +2004,23 @@ impl ConcreteTraitCached {
20052004 long_id. intern ( db)
20062005 }
20072006}
2007+
2008+ /// Returns all modules reachable from the crate root, following both submodule and macro call
2009+ /// edges. This ensures that submodules nested inside MacroCall modules are included.
2010+ pub fn all_crate_modules_for_cache < ' db > (
2011+ db : & ' db dyn Database ,
2012+ crate_id : CrateId < ' db > ,
2013+ ) -> Vec < ModuleId < ' db > > {
2014+ let mut result = vec ! [ ModuleId :: CrateRoot ( crate_id) ] ;
2015+ let mut unprocessed = 0 ;
2016+ while let Some ( module_id) = result. get ( unprocessed) . copied ( ) {
2017+ unprocessed += 1 ;
2018+ if let Ok ( submodule_ids) = db. module_submodules_ids ( module_id) {
2019+ result. extend ( submodule_ids. iter ( ) . map ( |id| ModuleId :: Submodule ( * id) ) ) ;
2020+ }
2021+ if let Ok ( macro_calls) = db. module_macro_calls_ids ( module_id) {
2022+ result. extend ( macro_calls. iter ( ) . flat_map ( |id| db. macro_call_module_id ( * id) ) ) ;
2023+ }
2024+ }
2025+ result
2026+ }
0 commit comments