]> git.lizzy.rs Git - rust.git/commitdiff
Show proc-macro loading errors in unresolved-proc-macro diagnostics
authorLukas Wirth <lukastw97@gmail.com>
Wed, 15 Jun 2022 15:33:55 +0000 (17:33 +0200)
committerLukas Wirth <lukastw97@gmail.com>
Wed, 15 Jun 2022 15:34:01 +0000 (17:34 +0200)
14 files changed:
crates/base-db/src/fixture.rs
crates/base-db/src/input.rs
crates/base-db/src/lib.rs
crates/hir-def/src/nameres/collector.rs
crates/hir-def/src/nameres/diagnostics.rs
crates/hir-expand/src/proc_macro.rs
crates/hir/src/diagnostics.rs
crates/hir/src/lib.rs
crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs
crates/ide/src/lib.rs
crates/proc-macro-api/src/lib.rs
crates/project-model/src/tests.rs
crates/project-model/src/workspace.rs
crates/rust-analyzer/src/reload.rs

index 69585b44a1a1fb0d1929a37f6a5391242222de0a..8e6e6a11abda83b0cf2c3a92fc7207ede0704b0c 100644 (file)
@@ -159,7 +159,7 @@ pub fn parse_with_proc_macros(
                     meta.cfg.clone(),
                     meta.cfg,
                     meta.env,
-                    Default::default(),
+                    Ok(Vec::new()),
                     false,
                     origin,
                 );
@@ -194,7 +194,7 @@ pub fn parse_with_proc_macros(
                 default_cfg.clone(),
                 default_cfg,
                 Env::default(),
-                Default::default(),
+                Ok(Vec::new()),
                 false,
                 CrateOrigin::CratesIo { repo: None },
             );
@@ -231,7 +231,7 @@ pub fn parse_with_proc_macros(
                 CfgOptions::default(),
                 CfgOptions::default(),
                 Env::default(),
-                Vec::new(),
+                Ok(Vec::new()),
                 false,
                 CrateOrigin::Lang(LangCrateOrigin::Core),
             );
@@ -268,7 +268,7 @@ pub fn parse_with_proc_macros(
                 CfgOptions::default(),
                 CfgOptions::default(),
                 Env::default(),
-                proc_macro,
+                Ok(proc_macro),
                 true,
                 CrateOrigin::CratesIo { repo: None },
             );
index 9fcaa4b06dd998bd621a297839a30b611ce5ce82..4d0a3a301230a4a8bc2d7cd8bd827debed9d372b 100644 (file)
@@ -231,6 +231,8 @@ pub enum ProcMacroExpansionError {
     System(String),
 }
 
+pub type ProcMacroLoadResult = Result<Vec<ProcMacro>, String>;
+
 #[derive(Debug, Clone)]
 pub struct ProcMacro {
     pub name: SmolStr,
@@ -254,7 +256,7 @@ pub struct CrateData {
     pub potential_cfg_options: CfgOptions,
     pub env: Env,
     pub dependencies: Vec<Dependency>,
-    pub proc_macro: Vec<ProcMacro>,
+    pub proc_macro: ProcMacroLoadResult,
     pub origin: CrateOrigin,
     pub is_proc_macro: bool,
 }
@@ -300,19 +302,19 @@ pub fn is_prelude(&self) -> bool {
 impl CrateGraph {
     pub fn add_crate_root(
         &mut self,
-        file_id: FileId,
+        root_file_id: FileId,
         edition: Edition,
         display_name: Option<CrateDisplayName>,
         version: Option<String>,
         cfg_options: CfgOptions,
         potential_cfg_options: CfgOptions,
         env: Env,
-        proc_macro: Vec<ProcMacro>,
+        proc_macro: ProcMacroLoadResult,
         is_proc_macro: bool,
         origin: CrateOrigin,
     ) -> CrateId {
         let data = CrateData {
-            root_file_id: file_id,
+            root_file_id,
             edition,
             version,
             display_name,
@@ -628,7 +630,7 @@ fn detect_cyclic_dependency_indirect() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -640,7 +642,7 @@ fn detect_cyclic_dependency_indirect() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -652,7 +654,7 @@ fn detect_cyclic_dependency_indirect() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -678,7 +680,7 @@ fn detect_cyclic_dependency_direct() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -690,7 +692,7 @@ fn detect_cyclic_dependency_direct() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -713,7 +715,7 @@ fn it_works() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -725,7 +727,7 @@ fn it_works() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -737,7 +739,7 @@ fn it_works() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -760,7 +762,7 @@ fn dashes_are_normalized() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -772,7 +774,7 @@ fn dashes_are_normalized() {
             CfgOptions::default(),
             CfgOptions::default(),
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
index 2454698bb61c64c2babd1874be5ad4546a207cff..f5622ecf6070678b4bdb154f89943886bce9e3c2 100644 (file)
@@ -13,7 +13,7 @@
     input::{
         CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
         Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
-        ProcMacroId, ProcMacroKind, SourceRoot, SourceRootId,
+        ProcMacroId, ProcMacroKind, ProcMacroLoadResult, SourceRoot, SourceRootId,
     },
 };
 pub use salsa::{self, Cancelled};
index 7fea46bee3ca8f8cf6da77e8dc48ff85cef2c05a..1c276e0d6f75b97eed87a29ea7dbf74e8572a1b1 100644 (file)
@@ -74,19 +74,27 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
     }
 
     let cfg_options = &krate.cfg_options;
-    let proc_macros = krate
-        .proc_macro
-        .iter()
-        .enumerate()
-        .map(|(idx, it)| {
-            // FIXME: a hacky way to create a Name from string.
-            let name = tt::Ident { text: it.name.clone(), id: tt::TokenId::unspecified() };
+    let (proc_macros, proc_macro_err) = match &krate.proc_macro {
+        Ok(proc_macros) => {
             (
-                name.as_name(),
-                ProcMacroExpander::new(def_map.krate, base_db::ProcMacroId(idx as u32)),
+                proc_macros
+                    .iter()
+                    .enumerate()
+                    .map(|(idx, it)| {
+                        // FIXME: a hacky way to create a Name from string.
+                        let name =
+                            tt::Ident { text: it.name.clone(), id: tt::TokenId::unspecified() };
+                        (
+                            name.as_name(),
+                            ProcMacroExpander::new(def_map.krate, base_db::ProcMacroId(idx as u32)),
+                        )
+                    })
+                    .collect(),
+                None,
             )
-        })
-        .collect();
+        }
+        Err(e) => (Vec::new(), Some(e.clone())),
+    };
     let is_proc_macro = krate.is_proc_macro;
 
     let mut collector = DefCollector {
@@ -100,6 +108,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
         mod_dirs: FxHashMap::default(),
         cfg_options,
         proc_macros,
+        proc_macro_err,
         from_glob_import: Default::default(),
         skip_attrs: Default::default(),
         derive_helpers_in_scope: Default::default(),
@@ -241,6 +250,7 @@ struct DefCollector<'a> {
     /// empty when proc. macro support is disabled (in which case we still do name resolution for
     /// them).
     proc_macros: Vec<(Name, ProcMacroExpander)>,
+    proc_macro_err: Option<String>,
     is_proc_macro: bool,
     from_glob_import: PerNsGlobImports,
     /// If we fail to resolve an attribute on a `ModItem`, we fall back to ignoring the attribute.
@@ -1232,6 +1242,7 @@ fn resolve_macros(&mut self) -> ReachedFixedPoint {
                             self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
                                 directive.module_id,
                                 loc.kind,
+                                self.proc_macro_err.clone(),
                             ));
 
                             return recollect_without(self);
@@ -1283,7 +1294,11 @@ fn collect_macro_expansion(
             let diag = match err {
                 hir_expand::ExpandError::UnresolvedProcMacro => {
                     // Missing proc macros are non-fatal, so they are handled specially.
-                    DefDiagnostic::unresolved_proc_macro(module_id, loc.kind.clone())
+                    DefDiagnostic::unresolved_proc_macro(
+                        module_id,
+                        loc.kind.clone(),
+                        self.proc_macro_err.clone(),
+                    )
                 }
                 _ => DefDiagnostic::macro_error(module_id, loc.kind.clone(), err.to_string()),
             };
@@ -2097,6 +2112,7 @@ fn do_collect_defs(db: &dyn DefDatabase, def_map: DefMap) -> DefMap {
             mod_dirs: FxHashMap::default(),
             cfg_options: &CfgOptions::default(),
             proc_macros: Default::default(),
+            proc_macro_err: None,
             from_glob_import: Default::default(),
             skip_attrs: Default::default(),
             derive_helpers_in_scope: Default::default(),
index dd3ff92cb3b72dca00bab50e0836ae796ca05451..927237962d7e0e38b40f9d87c519f34f984892ac 100644 (file)
@@ -23,7 +23,7 @@ pub enum DefDiagnosticKind {
 
     UnconfiguredCode { ast: AstId<ast::Item>, cfg: CfgExpr, opts: CfgOptions },
 
-    UnresolvedProcMacro { ast: MacroCallKind },
+    UnresolvedProcMacro { ast: MacroCallKind, proc_macro_err: Option<String> },
 
     UnresolvedMacroCall { ast: MacroCallKind, path: ModPath },
 
@@ -81,8 +81,15 @@ pub(super) fn unconfigured_code(
         Self { in_module: container, kind: DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } }
     }
 
-    pub(super) fn unresolved_proc_macro(container: LocalModuleId, ast: MacroCallKind) -> Self {
-        Self { in_module: container, kind: DefDiagnosticKind::UnresolvedProcMacro { ast } }
+    pub(super) fn unresolved_proc_macro(
+        container: LocalModuleId,
+        ast: MacroCallKind,
+        proc_macro_err: Option<String>,
+    ) -> Self {
+        Self {
+            in_module: container,
+            kind: DefDiagnosticKind::UnresolvedProcMacro { ast, proc_macro_err },
+        }
     }
 
     pub(super) fn macro_error(
index df6c38761c39ba2e8ef7e06d4169f56150114020..b2686592a55267ef779c23ecc25eac66886d96de 100644 (file)
@@ -34,7 +34,15 @@ pub fn expand(
         match self.proc_macro_id {
             Some(id) => {
                 let krate_graph = db.crate_graph();
-                let proc_macro = match krate_graph[self.krate].proc_macro.get(id.0 as usize) {
+                let proc_macros = match &krate_graph[self.krate].proc_macro {
+                    Ok(proc_macros) => proc_macros,
+                    Err(e) => {
+                        return ExpandResult::only_err(ExpandError::Other(
+                            e.clone().into_boxed_str(),
+                        ))
+                    }
+                };
+                let proc_macro = match proc_macros.get(id.0 as usize) {
                     Some(proc_macro) => proc_macro,
                     None => {
                         return ExpandResult::only_err(ExpandError::Other(
index 0c88d15b089e05857c2ad38ae52f1e1d7cffa36a..4dd23dfa14a50f62855dec3c3b7ef222b5c8c045 100644 (file)
@@ -87,6 +87,7 @@ pub struct UnresolvedProcMacro {
     pub precise_location: Option<TextRange>,
     pub macro_name: Option<String>,
     pub kind: MacroKind,
+    pub proc_macro_err: Option<String>,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
index 4620d0c03acc4dfcfee4274ee0dad622184646a5..9f7a2d63fe56d6c51b030e13b2dcd8bcb695559f 100644 (file)
@@ -627,7 +627,7 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
             );
         }
 
-        DefDiagnosticKind::UnresolvedProcMacro { ast } => {
+        DefDiagnosticKind::UnresolvedProcMacro { ast, proc_macro_err } => {
             let (node, precise_location, macro_name, kind) = match ast {
                 MacroCallKind::FnLike { ast_id, .. } => {
                     let node = ast_id.to_node(db.upcast());
@@ -689,7 +689,16 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
                     )
                 }
             };
-            acc.push(UnresolvedProcMacro { node, precise_location, macro_name, kind }.into());
+            acc.push(
+                UnresolvedProcMacro {
+                    node,
+                    precise_location,
+                    macro_name,
+                    kind,
+                    proc_macro_err: proc_macro_err.clone(),
+                }
+                .into(),
+            );
         }
 
         DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
@@ -1163,6 +1172,7 @@ pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
                         precise_location: None,
                         macro_name: None,
                         kind: MacroKind::ProcMacro,
+                        proc_macro_err: None,
                     }
                     .into(),
                 ),
index 37350a7aaf17038e0a807dc4bc46d66096d5c964..5f905de4f17357285c94dbea69fc421fd008abfe 100644 (file)
@@ -29,19 +29,23 @@ pub(crate) fn unresolved_proc_macro(
         Some(name) => format!("proc macro `{}` not expanded", name),
         None => "proc macro not expanded".to_string(),
     };
-    let (message, severity) = if config_enabled {
-        (message, Severity::Error)
-    } else {
-        let message = match d.kind {
-            hir::MacroKind::Attr if proc_macros_enabled => {
-                format!("{message}{}", " (attribute macro expansion is disabled)")
+    let severity = if config_enabled { Severity::Error } else { Severity::WeakWarning };
+    let message = format!(
+        "{message}: {}",
+        if config_enabled {
+            match &d.proc_macro_err {
+                Some(e) => e,
+                None => "proc macro not found",
             }
-            _ => {
-                format!("{message}{}", " (proc-macro expansion is disabled)")
+        } else {
+            match d.kind {
+                hir::MacroKind::Attr if proc_macros_enabled => {
+                    "attribute macro expansion is disabled"
+                }
+                _ => "proc-macro expansion is disabled",
             }
-        };
-        (message, Severity::WeakWarning)
-    };
+        },
+    );
 
     Diagnostic::new("unresolved-proc-macro", message, display_range).severity(severity)
 }
index aab5ceda366e1d3ae8716b372eb05b4485738f67..07a7fbd7837c852148f95ac9f75c9f26180cda8b 100644 (file)
@@ -233,7 +233,7 @@ pub fn from_single_file(text: String) -> (Analysis, FileId) {
             cfg_options.clone(),
             cfg_options,
             Env::default(),
-            Default::default(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
index eb7a28b972b0ec08d1d253aab8590f45fcd53ad7..4a30168ca517b57f99113662608cc8d952c2fa06 100644 (file)
@@ -118,16 +118,13 @@ pub fn spawn(
         Ok(ProcMacroServer { process: Arc::new(Mutex::new(process)) })
     }
 
-    pub fn load_dylib(
-        &self,
-        dylib: MacroDylib,
-    ) -> Result<Result<Vec<ProcMacro>, String>, ServerError> {
+    pub fn load_dylib(&self, dylib: MacroDylib) -> Result<Vec<ProcMacro>, ServerError> {
         let _p = profile::span("ProcMacroClient::by_dylib_path");
         let macros =
             self.process.lock().unwrap_or_else(|e| e.into_inner()).find_proc_macros(&dylib.path)?;
 
-        let res = macros.map(|macros| {
-            macros
+        match macros {
+            Ok(macros) => Ok(macros
                 .into_iter()
                 .map(|(name, kind)| ProcMacro {
                     process: self.process.clone(),
@@ -135,10 +132,9 @@ pub fn load_dylib(
                     kind,
                     dylib_path: dylib.path.clone(),
                 })
-                .collect()
-        });
-
-        Ok(res)
+                .collect()),
+            Err(message) => Err(ServerError { message, io: None }),
+        }
     }
 }
 
index e72903e55fe8684e38bc94766bac69b11c229d4e..8eb8c40a220ee6dc7ded7353ec51990295bb4bff 100644 (file)
@@ -88,7 +88,7 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
 }
 
 fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph {
-    project_workspace.to_crate_graph(&mut |_, _| Vec::new(), &mut {
+    project_workspace.to_crate_graph(&mut |_, _| Ok(Vec::new()), &mut {
         let mut counter = 0;
         move |_path| {
             counter += 1;
index a94a38a17da73d226cc4b417f5f67b4bda560671..8982a9904ec1754d299631335efe176d681f28c0 100644 (file)
@@ -7,7 +7,7 @@
 use anyhow::{format_err, Context, Result};
 use base_db::{
     CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env,
-    FileId, LangCrateOrigin, ProcMacro,
+    FileId, LangCrateOrigin, ProcMacroLoadResult,
 };
 use cfg::{CfgDiff, CfgOptions};
 use paths::{AbsPath, AbsPathBuf};
@@ -389,7 +389,7 @@ pub fn n_packages(&self) -> usize {
 
     pub fn to_crate_graph(
         &self,
-        load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
+        load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
         load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
     ) -> CrateGraph {
         let _p = profile::span("ProjectWorkspace::to_crate_graph");
@@ -434,7 +434,7 @@ pub fn to_crate_graph(
 
 fn project_json_to_crate_graph(
     rustc_cfg: Vec<CfgFlag>,
-    load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
+    load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
     load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
     project: &ProjectJson,
     sysroot: &Option<Sysroot>,
@@ -454,12 +454,13 @@ fn project_json_to_crate_graph(
         })
         .map(|(crate_id, krate, file_id)| {
             let env = krate.env.clone().into_iter().collect();
-            let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| {
-                load_proc_macro(
+            let proc_macro = match krate.proc_macro_dylib_path.clone() {
+                Some(it) => load_proc_macro(
                     krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""),
                     &it,
-                )
-            });
+                ),
+                None => Ok(Vec::new()),
+            };
 
             let target_cfgs = match krate.target.as_deref() {
                 Some(target) => {
@@ -480,7 +481,7 @@ fn project_json_to_crate_graph(
                     cfg_options.clone(),
                     cfg_options,
                     env,
-                    proc_macro.unwrap_or_default(),
+                    proc_macro,
                     krate.is_proc_macro,
                     if krate.display_name.is_some() {
                         CrateOrigin::CratesIo { repo: krate.repository.clone() }
@@ -521,7 +522,7 @@ fn project_json_to_crate_graph(
 fn cargo_to_crate_graph(
     rustc_cfg: Vec<CfgFlag>,
     override_cfg: &CfgOverrides,
-    load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
+    load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
     load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
     cargo: &CargoWorkspace,
     build_scripts: &WorkspaceBuildScripts,
@@ -708,7 +709,7 @@ fn detached_files_to_crate_graph(
             cfg_options.clone(),
             cfg_options.clone(),
             Env::default(),
-            Vec::new(),
+            Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None },
         );
@@ -724,7 +725,7 @@ fn handle_rustc_crates(
     crate_graph: &mut CrateGraph,
     cfg_options: &CfgOptions,
     override_cfg: &CfgOverrides,
-    load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
+    load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
     pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>,
     public_deps: &SysrootPublicDeps,
     cargo: &CargoWorkspace,
@@ -840,7 +841,7 @@ fn add_target_crate_root(
     pkg: &PackageData,
     build_data: Option<&BuildScriptOutput>,
     cfg_options: &CfgOptions,
-    load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
+    load_proc_macro: &mut dyn FnMut(&AbsPath) -> ProcMacroLoadResult,
     file_id: FileId,
     cargo_name: &str,
     is_proc_macro: bool,
@@ -866,11 +867,10 @@ fn add_target_crate_root(
         }
     }
 
-    let proc_macro = build_data
-        .as_ref()
-        .and_then(|it| it.proc_macro_dylib_path.as_ref())
-        .map(|it| load_proc_macro(it))
-        .unwrap_or_default();
+    let proc_macro = match build_data.as_ref().and_then(|it| it.proc_macro_dylib_path.as_ref()) {
+        Some(it) => load_proc_macro(it),
+        None => Ok(Vec::new()),
+    };
 
     let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string());
     let mut potential_cfg_options = cfg_options.clone();
@@ -922,7 +922,6 @@ fn sysroot_to_crate_graph(
             let file_id = load(&sysroot[krate].root)?;
 
             let env = Env::default();
-            let proc_macro = vec![];
             let display_name = CrateDisplayName::from_canonical_name(sysroot[krate].name.clone());
             let crate_id = crate_graph.add_crate_root(
                 file_id,
@@ -932,7 +931,7 @@ fn sysroot_to_crate_graph(
                 cfg_options.clone(),
                 cfg_options.clone(),
                 env,
-                proc_macro,
+                Ok(Vec::new()),
                 false,
                 CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
             );
index 62a446ce2a68ef124eba8736f0f77a338f772e7f..3f129efd95b18c934a7a876968baea978f7654a4 100644 (file)
@@ -19,7 +19,7 @@
 use ide::Change;
 use ide_db::base_db::{
     CrateGraph, Env, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind,
-    SourceRoot, VfsPath,
+    ProcMacroLoadResult, SourceRoot, VfsPath,
 };
 use proc_macro_api::{MacroDylib, ProcMacroServer};
 use project_model::{ProjectWorkspace, WorkspaceBuildScripts};
@@ -536,45 +536,37 @@ pub(crate) fn partition(&self, vfs: &vfs::Vfs) -> Vec<SourceRoot> {
 /// Load the proc-macros for the given lib path, replacing all expanders whose names are in `dummy_replace`
 /// with an identity dummy expander.
 pub(crate) fn load_proc_macro(
-    client: Option<&ProcMacroServer>,
+    server: Option<&ProcMacroServer>,
     path: &AbsPath,
     dummy_replace: &[Box<str>],
-) -> Vec<ProcMacro> {
-    let dylib = match MacroDylib::new(path.to_path_buf()) {
-        Ok(it) => it,
-        Err(err) => {
-            // FIXME: that's not really right -- we store this error in a
-            // persistent status.
-            tracing::warn!("failed to load proc macro: {}", err);
-            return Vec::new();
+) -> ProcMacroLoadResult {
+    let res: Result<_, String> = (|| {
+        let dylib = MacroDylib::new(path.to_path_buf())
+            .map_err(|io| format!("Proc-macro dylib loading failed: {io}"))?;
+        Ok(if let Some(it) = server {
+            let vec = it.load_dylib(dylib).map_err(|e| format!("{e}"))?;
+            vec.into_iter()
+                .map(|expander| expander_to_proc_macro(expander, dummy_replace))
+                .collect()
+        } else {
+            Vec::new()
+        })
+    })();
+    return match res {
+        Ok(proc_macros) => {
+            tracing::info!(
+                "Loaded proc-macros for {}: {:?}",
+                path.display(),
+                proc_macros.iter().map(|it| it.name.clone()).collect::<Vec<_>>()
+            );
+            Ok(proc_macros)
+        }
+        Err(e) => {
+            tracing::warn!("proc-macro loading for {} failed: {e}", path.display());
+            Err(e)
         }
     };
 
-    let proc_macros: Vec<_> = client
-        .map(|it| it.load_dylib(dylib))
-        .into_iter()
-        .flat_map(|it| match it {
-            Ok(Ok(macros)) => macros,
-            Err(err) => {
-                tracing::error!("proc macro server crashed: {}", err);
-                Vec::new()
-            }
-            Ok(Err(err)) => {
-                // FIXME: that's not really right -- we store this error in a
-                // persistent status.
-                tracing::warn!("failed to load proc macro: {}", err);
-                Vec::new()
-            }
-        })
-        .map(|expander| expander_to_proc_macro(expander, dummy_replace))
-        .collect();
-    tracing::info!(
-        "Loaded proc-macros for {}: {:?}",
-        path.display(),
-        proc_macros.iter().map(|it| it.name.clone()).collect::<Vec<_>>()
-    );
-    return proc_macros;
-
     fn expander_to_proc_macro(
         expander: proc_macro_api::ProcMacro,
         dummy_replace: &[Box<str>],