@@ -203,6 +203,10 @@ struct DefCollector<'a> {
203203 unexpanded_attribute_macros : Vec < DeriveDirective > ,
204204 mod_dirs : FxHashMap < LocalModuleId , ModDir > ,
205205 cfg_options : & ' a CfgOptions ,
206+ /// List of procedural macros defined by this crate. This is read from the dynamic library
207+ /// built by the build system, and is the list of proc. macros we can actually expand. It is
208+ /// empty when proc. macro support is disabled (in which case we still do name resolution for
209+ /// them).
206210 proc_macros : Vec < ( Name , ProcMacroExpander ) > ,
207211 exports_proc_macros : bool ,
208212 from_glob_import : PerNsGlobImports ,
@@ -279,6 +283,22 @@ impl DefCollector<'_> {
279283 }
280284 }
281285
286+ /// Adds a definition of procedural macro `name` to the root module.
287+ ///
288+ /// # Notes on procedural macro resolution
289+ ///
290+ /// Procedural macro functionality is provided by the build system: It has to build the proc
291+ /// macro and pass the resulting dynamic library to rust-analyzer.
292+ ///
293+ /// When procedural macro support is enabled, the list of proc macros exported by a crate is
294+ /// known before we resolve names in the crate. This list is stored in `self.proc_macros` and is
295+ /// derived from the dynamic library.
296+ ///
297+ /// However, we *also* would like to be able to at least *resolve* macros on our own, without
298+ /// help by the build system. So, when the macro isn't found in `self.proc_macros`, we instead
299+ /// use a dummy expander that always errors. This comes with the drawback of macros potentially
300+ /// going out of sync with what the build system sees (since we resolve using VFS state, but
301+ /// Cargo builds only on-disk files). We could and probably should add diagnostics for that.
282302 fn resolve_proc_macro ( & mut self , name : & Name ) {
283303 self . exports_proc_macros = true ;
284304 let macro_def = match self . proc_macros . iter ( ) . find ( |( n, _) | n == name) {
0 commit comments