@@ -203,6 +203,10 @@ struct DefCollector<'a> {
203
203
unexpanded_attribute_macros : Vec < DeriveDirective > ,
204
204
mod_dirs : FxHashMap < LocalModuleId , ModDir > ,
205
205
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).
206
210
proc_macros : Vec < ( Name , ProcMacroExpander ) > ,
207
211
exports_proc_macros : bool ,
208
212
from_glob_import : PerNsGlobImports ,
@@ -279,6 +283,22 @@ impl DefCollector<'_> {
279
283
}
280
284
}
281
285
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.
282
302
fn resolve_proc_macro ( & mut self , name : & Name ) {
283
303
self . exports_proc_macros = true ;
284
304
let macro_def = match self . proc_macros . iter ( ) . find ( |( n, _) | n == name) {
0 commit comments