Auto merge of #12544 - Veykril:proc-error, r=Veykril

Show proc-macro loading errors in unresolved-proc-macro diagnostics

This should help out people to potentially figure out the problem without having to check the logs
This commit is contained in:
bors 2022-06-15 16:21:21 +00:00
commit d39d520a21
15 changed files with 245 additions and 144 deletions

View file

@ -159,7 +159,7 @@ impl ChangeFixture {
meta.cfg.clone(), meta.cfg.clone(),
meta.cfg, meta.cfg,
meta.env, meta.env,
Default::default(), Ok(Vec::new()),
false, false,
origin, origin,
); );
@ -194,7 +194,7 @@ impl ChangeFixture {
default_cfg.clone(), default_cfg.clone(),
default_cfg, default_cfg,
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -231,7 +231,7 @@ impl ChangeFixture {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Vec::new(), Ok(Vec::new()),
false, false,
CrateOrigin::Lang(LangCrateOrigin::Core), CrateOrigin::Lang(LangCrateOrigin::Core),
); );
@ -268,7 +268,7 @@ impl ChangeFixture {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
proc_macro, Ok(proc_macro),
true, true,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );

View file

@ -231,6 +231,8 @@ pub enum ProcMacroExpansionError {
System(String), System(String),
} }
pub type ProcMacroLoadResult = Result<Vec<ProcMacro>, String>;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ProcMacro { pub struct ProcMacro {
pub name: SmolStr, pub name: SmolStr,
@ -254,7 +256,7 @@ pub struct CrateData {
pub potential_cfg_options: CfgOptions, pub potential_cfg_options: CfgOptions,
pub env: Env, pub env: Env,
pub dependencies: Vec<Dependency>, pub dependencies: Vec<Dependency>,
pub proc_macro: Vec<ProcMacro>, pub proc_macro: ProcMacroLoadResult,
pub origin: CrateOrigin, pub origin: CrateOrigin,
pub is_proc_macro: bool, pub is_proc_macro: bool,
} }
@ -300,19 +302,19 @@ impl Dependency {
impl CrateGraph { impl CrateGraph {
pub fn add_crate_root( pub fn add_crate_root(
&mut self, &mut self,
file_id: FileId, root_file_id: FileId,
edition: Edition, edition: Edition,
display_name: Option<CrateDisplayName>, display_name: Option<CrateDisplayName>,
version: Option<String>, version: Option<String>,
cfg_options: CfgOptions, cfg_options: CfgOptions,
potential_cfg_options: CfgOptions, potential_cfg_options: CfgOptions,
env: Env, env: Env,
proc_macro: Vec<ProcMacro>, proc_macro: ProcMacroLoadResult,
is_proc_macro: bool, is_proc_macro: bool,
origin: CrateOrigin, origin: CrateOrigin,
) -> CrateId { ) -> CrateId {
let data = CrateData { let data = CrateData {
root_file_id: file_id, root_file_id,
edition, edition,
version, version,
display_name, display_name,
@ -628,7 +630,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -640,7 +642,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -652,7 +654,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -678,7 +680,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -690,7 +692,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -713,7 +715,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -725,7 +727,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -737,7 +739,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -760,7 +762,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -772,7 +774,7 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );

View file

@ -13,7 +13,7 @@ pub use crate::{
input::{ input::{
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
ProcMacroId, ProcMacroKind, SourceRoot, SourceRootId, ProcMacroId, ProcMacroKind, ProcMacroLoadResult, SourceRoot, SourceRootId,
}, },
}; };
pub use salsa::{self, Cancelled}; pub use salsa::{self, Cancelled};

View file

@ -103,6 +103,8 @@ pub struct DefMap {
/// Side table for resolving derive helpers. /// Side table for resolving derive helpers.
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>, exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
fn_proc_macro_mapping: FxHashMap<FunctionId, ProcMacroId>, fn_proc_macro_mapping: FxHashMap<FunctionId, ProcMacroId>,
/// The error that occurred when failing to load the proc-macro dll.
proc_macro_loading_error: Option<Box<str>>,
/// Custom attributes registered with `#![register_attr]`. /// Custom attributes registered with `#![register_attr]`.
registered_attrs: Vec<SmolStr>, registered_attrs: Vec<SmolStr>,
@ -273,6 +275,7 @@ impl DefMap {
extern_prelude: FxHashMap::default(), extern_prelude: FxHashMap::default(),
exported_derives: FxHashMap::default(), exported_derives: FxHashMap::default(),
fn_proc_macro_mapping: FxHashMap::default(), fn_proc_macro_mapping: FxHashMap::default(),
proc_macro_loading_error: None,
prelude: None, prelude: None,
root, root,
modules, modules,
@ -305,6 +308,9 @@ impl DefMap {
pub fn fn_as_proc_macro(&self, id: FunctionId) -> Option<ProcMacroId> { pub fn fn_as_proc_macro(&self, id: FunctionId) -> Option<ProcMacroId> {
self.fn_proc_macro_mapping.get(&id).copied() self.fn_proc_macro_mapping.get(&id).copied()
} }
pub fn proc_macro_loading_error(&self) -> Option<&str> {
self.proc_macro_loading_error.as_deref()
}
pub(crate) fn krate(&self) -> CrateId { pub(crate) fn krate(&self) -> CrateId {
self.krate self.krate
@ -460,6 +466,7 @@ impl DefMap {
registered_attrs, registered_attrs,
registered_tools, registered_tools,
fn_proc_macro_mapping, fn_proc_macro_mapping,
proc_macro_loading_error: _,
block: _, block: _,
edition: _, edition: _,
recursion_limit: _, recursion_limit: _,

View file

@ -74,8 +74,9 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
} }
let cfg_options = &krate.cfg_options; let cfg_options = &krate.cfg_options;
let proc_macros = krate let proc_macros = match &krate.proc_macro {
.proc_macro Ok(proc_macros) => {
proc_macros
.iter() .iter()
.enumerate() .enumerate()
.map(|(idx, it)| { .map(|(idx, it)| {
@ -86,7 +87,13 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
ProcMacroExpander::new(def_map.krate, base_db::ProcMacroId(idx as u32)), ProcMacroExpander::new(def_map.krate, base_db::ProcMacroId(idx as u32)),
) )
}) })
.collect(); .collect()
}
Err(e) => {
def_map.proc_macro_loading_error = Some(e.clone().into_boxed_str());
Vec::new()
}
};
let is_proc_macro = krate.is_proc_macro; let is_proc_macro = krate.is_proc_macro;
let mut collector = DefCollector { let mut collector = DefCollector {
@ -1128,7 +1135,19 @@ impl DefCollector<'_> {
let def = match resolver(path.clone()) { let def = match resolver(path.clone()) {
Some(def) if def.is_attribute() => def, Some(def) if def.is_attribute() => def,
_ => return true, _ => {
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
directive.module_id,
MacroCallKind::Attr {
ast_id,
attr_args: Default::default(),
invoc_attr_index: attr.id.ast_index,
is_derive: false,
},
None,
));
return true;
}
}; };
if matches!( if matches!(
def, def,
@ -1232,6 +1251,7 @@ impl DefCollector<'_> {
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro( self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
directive.module_id, directive.module_id,
loc.kind, loc.kind,
Some(loc.def.krate),
)); ));
return recollect_without(self); return recollect_without(self);
@ -1283,7 +1303,11 @@ impl DefCollector<'_> {
let diag = match err { let diag = match err {
hir_expand::ExpandError::UnresolvedProcMacro => { hir_expand::ExpandError::UnresolvedProcMacro => {
// Missing proc macros are non-fatal, so they are handled specially. // 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(),
Some(loc.def.krate),
)
} }
_ => DefDiagnostic::macro_error(module_id, loc.kind.clone(), err.to_string()), _ => DefDiagnostic::macro_error(module_id, loc.kind.clone(), err.to_string()),
}; };

View file

@ -1,5 +1,6 @@
//! Diagnostics emitted during DefMap construction. //! Diagnostics emitted during DefMap construction.
use base_db::CrateId;
use cfg::{CfgExpr, CfgOptions}; use cfg::{CfgExpr, CfgOptions};
use hir_expand::MacroCallKind; use hir_expand::MacroCallKind;
use la_arena::Idx; use la_arena::Idx;
@ -23,7 +24,7 @@ pub enum DefDiagnosticKind {
UnconfiguredCode { ast: AstId<ast::Item>, cfg: CfgExpr, opts: CfgOptions }, UnconfiguredCode { ast: AstId<ast::Item>, cfg: CfgExpr, opts: CfgOptions },
UnresolvedProcMacro { ast: MacroCallKind }, UnresolvedProcMacro { ast: MacroCallKind, krate: Option<CrateId> },
UnresolvedMacroCall { ast: MacroCallKind, path: ModPath }, UnresolvedMacroCall { ast: MacroCallKind, path: ModPath },
@ -81,8 +82,12 @@ impl DefDiagnostic {
Self { in_module: container, kind: DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } } Self { in_module: container, kind: DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } }
} }
pub(super) fn unresolved_proc_macro(container: LocalModuleId, ast: MacroCallKind) -> Self { pub(super) fn unresolved_proc_macro(
Self { in_module: container, kind: DefDiagnosticKind::UnresolvedProcMacro { ast } } container: LocalModuleId,
ast: MacroCallKind,
krate: Option<CrateId>,
) -> Self {
Self { in_module: container, kind: DefDiagnosticKind::UnresolvedProcMacro { ast, krate } }
} }
pub(super) fn macro_error( pub(super) fn macro_error(

View file

@ -34,7 +34,15 @@ impl ProcMacroExpander {
match self.proc_macro_id { match self.proc_macro_id {
Some(id) => { Some(id) => {
let krate_graph = db.crate_graph(); 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, Some(proc_macro) => proc_macro,
None => { None => {
return ExpandResult::only_err(ExpandError::Other( return ExpandResult::only_err(ExpandError::Other(

View file

@ -3,6 +3,7 @@
//! //!
//! This probably isn't the best way to do this -- ideally, diagnistics should //! This probably isn't the best way to do this -- ideally, diagnistics should
//! be expressed in terms of hir types themselves. //! be expressed in terms of hir types themselves.
use base_db::CrateId;
use cfg::{CfgExpr, CfgOptions}; use cfg::{CfgExpr, CfgOptions};
use either::Either; use either::Either;
use hir_def::path::ModPath; use hir_def::path::ModPath;
@ -87,6 +88,8 @@ pub struct UnresolvedProcMacro {
pub precise_location: Option<TextRange>, pub precise_location: Option<TextRange>,
pub macro_name: Option<String>, pub macro_name: Option<String>,
pub kind: MacroKind, pub kind: MacroKind,
/// The crate id of the proc-macro this macro belongs to, or `None` if the proc-macro can't be found.
pub krate: Option<CrateId>,
} }
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]

View file

@ -627,7 +627,7 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
); );
} }
DefDiagnosticKind::UnresolvedProcMacro { ast } => { DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
let (node, precise_location, macro_name, kind) = match ast { let (node, precise_location, macro_name, kind) = match ast {
MacroCallKind::FnLike { ast_id, .. } => { MacroCallKind::FnLike { ast_id, .. } => {
let node = ast_id.to_node(db.upcast()); let node = ast_id.to_node(db.upcast());
@ -689,7 +689,10 @@ 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, krate: *krate }
.into(),
);
} }
DefDiagnosticKind::UnresolvedMacroCall { ast, path } => { DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
@ -1163,6 +1166,7 @@ impl DefWithBody {
precise_location: None, precise_location: None,
macro_name: None, macro_name: None,
kind: MacroKind::ProcMacro, kind: MacroKind::ProcMacro,
krate: None,
} }
.into(), .into(),
), ),

View file

@ -1,3 +1,5 @@
use hir::db::DefDatabase;
use crate::{Diagnostic, DiagnosticsContext, Severity}; use crate::{Diagnostic, DiagnosticsContext, Severity};
// Diagnostic: unresolved-proc-macro // Diagnostic: unresolved-proc-macro
@ -29,19 +31,24 @@ pub(crate) fn unresolved_proc_macro(
Some(name) => format!("proc macro `{}` not expanded", name), Some(name) => format!("proc macro `{}` not expanded", name),
None => "proc macro not expanded".to_string(), None => "proc macro not expanded".to_string(),
}; };
let (message, severity) = if config_enabled { let severity = if config_enabled { Severity::Error } else { Severity::WeakWarning };
(message, Severity::Error) let def_map = d.krate.map(|krate| ctx.sema.db.crate_def_map(krate));
let message = format!(
"{message}: {}",
if config_enabled {
match def_map.as_ref().and_then(|def_map| def_map.proc_macro_loading_error()) {
Some(e) => e,
None => "proc macro not found",
}
} else { } else {
let message = match d.kind { match d.kind {
hir::MacroKind::Attr if proc_macros_enabled => { hir::MacroKind::Attr if proc_macros_enabled => {
format!("{message}{}", " (attribute macro expansion is disabled)") "attribute macro expansion is disabled"
} }
_ => { _ => "proc-macro expansion is disabled",
format!("{message}{}", " (proc-macro expansion is disabled)")
} }
}; },
(message, Severity::WeakWarning) );
};
Diagnostic::new("unresolved-proc-macro", message, display_range).severity(severity) Diagnostic::new("unresolved-proc-macro", message, display_range).severity(severity)
} }

View file

@ -233,7 +233,7 @@ impl Analysis {
cfg_options.clone(), cfg_options.clone(),
cfg_options, cfg_options,
Env::default(), Env::default(),
Default::default(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );

View file

@ -118,16 +118,13 @@ impl ProcMacroServer {
Ok(ProcMacroServer { process: Arc::new(Mutex::new(process)) }) Ok(ProcMacroServer { process: Arc::new(Mutex::new(process)) })
} }
pub fn load_dylib( pub fn load_dylib(&self, dylib: MacroDylib) -> Result<Vec<ProcMacro>, ServerError> {
&self,
dylib: MacroDylib,
) -> Result<Result<Vec<ProcMacro>, String>, ServerError> {
let _p = profile::span("ProcMacroClient::by_dylib_path"); let _p = profile::span("ProcMacroClient::by_dylib_path");
let macros = let macros =
self.process.lock().unwrap_or_else(|e| e.into_inner()).find_proc_macros(&dylib.path)?; self.process.lock().unwrap_or_else(|e| e.into_inner()).find_proc_macros(&dylib.path)?;
let res = macros.map(|macros| { match macros {
macros Ok(macros) => Ok(macros
.into_iter() .into_iter()
.map(|(name, kind)| ProcMacro { .map(|(name, kind)| ProcMacro {
process: self.process.clone(), process: self.process.clone(),
@ -135,10 +132,9 @@ impl ProcMacroServer {
kind, kind,
dylib_path: dylib.path.clone(), dylib_path: dylib.path.clone(),
}) })
.collect() .collect()),
}); Err(message) => Err(ServerError { message, io: None }),
}
Ok(res)
} }
} }

View file

@ -88,7 +88,7 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
} }
fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph { 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; let mut counter = 0;
move |_path| { move |_path| {
counter += 1; counter += 1;
@ -172,7 +172,9 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -245,7 +247,9 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -308,7 +312,9 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
}, },
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: Some( repo: Some(
"https://github.com/rust-lang/libc", "https://github.com/rust-lang/libc",
@ -383,7 +389,9 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -456,7 +464,9 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -544,7 +554,9 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -619,7 +631,9 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -682,7 +696,9 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
}, },
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: Some( repo: Some(
"https://github.com/rust-lang/libc", "https://github.com/rust-lang/libc",
@ -759,7 +775,9 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -834,7 +852,9 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -913,7 +933,9 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -988,7 +1010,9 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -1053,7 +1077,9 @@ fn cargo_hello_world_project_model() {
}, },
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: Some( repo: Some(
"https://github.com/rust-lang/libc", "https://github.com/rust-lang/libc",
@ -1130,7 +1156,9 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -1205,7 +1233,9 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -1260,7 +1290,9 @@ fn rust_project_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Alloc, Alloc,
), ),
@ -1292,7 +1324,9 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1324,7 +1358,9 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1366,7 +1402,9 @@ fn rust_project_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1398,7 +1436,9 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Core, Core,
), ),
@ -1467,7 +1507,9 @@ fn rust_project_hello_world_project_model() {
prelude: false, prelude: false,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
}, },
@ -1499,7 +1541,9 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1531,7 +1575,9 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1563,7 +1609,9 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1595,7 +1643,9 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Test, Test,
), ),
@ -1709,7 +1759,9 @@ fn rust_project_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Std, Std,
), ),
@ -1741,7 +1793,9 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: [], proc_macro: Ok(
[],
),
origin: Lang( origin: Lang(
Other, Other,
), ),

View file

@ -7,7 +7,7 @@ use std::{collections::VecDeque, fmt, fs, process::Command};
use anyhow::{format_err, Context, Result}; use anyhow::{format_err, Context, Result};
use base_db::{ use base_db::{
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env,
FileId, LangCrateOrigin, ProcMacro, FileId, LangCrateOrigin, ProcMacroLoadResult,
}; };
use cfg::{CfgDiff, CfgOptions}; use cfg::{CfgDiff, CfgOptions};
use paths::{AbsPath, AbsPathBuf}; use paths::{AbsPath, AbsPathBuf};
@ -389,7 +389,7 @@ impl ProjectWorkspace {
pub fn to_crate_graph( pub fn to_crate_graph(
&self, &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>, load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
) -> CrateGraph { ) -> CrateGraph {
let _p = profile::span("ProjectWorkspace::to_crate_graph"); let _p = profile::span("ProjectWorkspace::to_crate_graph");
@ -434,7 +434,7 @@ impl ProjectWorkspace {
fn project_json_to_crate_graph( fn project_json_to_crate_graph(
rustc_cfg: Vec<CfgFlag>, 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>, load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
project: &ProjectJson, project: &ProjectJson,
sysroot: &Option<Sysroot>, sysroot: &Option<Sysroot>,
@ -454,12 +454,13 @@ fn project_json_to_crate_graph(
}) })
.map(|(crate_id, krate, file_id)| { .map(|(crate_id, krate, file_id)| {
let env = krate.env.clone().into_iter().collect(); let env = krate.env.clone().into_iter().collect();
let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| { let proc_macro = match krate.proc_macro_dylib_path.clone() {
load_proc_macro( Some(it) => load_proc_macro(
krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""), krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""),
&it, &it,
) ),
}); None => Ok(Vec::new()),
};
let target_cfgs = match krate.target.as_deref() { let target_cfgs = match krate.target.as_deref() {
Some(target) => { Some(target) => {
@ -480,7 +481,7 @@ fn project_json_to_crate_graph(
cfg_options.clone(), cfg_options.clone(),
cfg_options, cfg_options,
env, env,
proc_macro.unwrap_or_default(), proc_macro,
krate.is_proc_macro, krate.is_proc_macro,
if krate.display_name.is_some() { if krate.display_name.is_some() {
CrateOrigin::CratesIo { repo: krate.repository.clone() } CrateOrigin::CratesIo { repo: krate.repository.clone() }
@ -521,7 +522,7 @@ fn project_json_to_crate_graph(
fn cargo_to_crate_graph( fn cargo_to_crate_graph(
rustc_cfg: Vec<CfgFlag>, rustc_cfg: Vec<CfgFlag>,
override_cfg: &CfgOverrides, 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>, load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
cargo: &CargoWorkspace, cargo: &CargoWorkspace,
build_scripts: &WorkspaceBuildScripts, build_scripts: &WorkspaceBuildScripts,
@ -708,7 +709,7 @@ fn detached_files_to_crate_graph(
cfg_options.clone(), cfg_options.clone(),
cfg_options.clone(), cfg_options.clone(),
Env::default(), Env::default(),
Vec::new(), Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None }, CrateOrigin::CratesIo { repo: None },
); );
@ -724,7 +725,7 @@ fn handle_rustc_crates(
crate_graph: &mut CrateGraph, crate_graph: &mut CrateGraph,
cfg_options: &CfgOptions, cfg_options: &CfgOptions,
override_cfg: &CfgOverrides, 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>, pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>,
public_deps: &SysrootPublicDeps, public_deps: &SysrootPublicDeps,
cargo: &CargoWorkspace, cargo: &CargoWorkspace,
@ -840,7 +841,7 @@ fn add_target_crate_root(
pkg: &PackageData, pkg: &PackageData,
build_data: Option<&BuildScriptOutput>, build_data: Option<&BuildScriptOutput>,
cfg_options: &CfgOptions, cfg_options: &CfgOptions,
load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>, load_proc_macro: &mut dyn FnMut(&AbsPath) -> ProcMacroLoadResult,
file_id: FileId, file_id: FileId,
cargo_name: &str, cargo_name: &str,
is_proc_macro: bool, is_proc_macro: bool,
@ -866,11 +867,10 @@ fn add_target_crate_root(
} }
} }
let proc_macro = build_data let proc_macro = match build_data.as_ref().and_then(|it| it.proc_macro_dylib_path.as_ref()) {
.as_ref() Some(it) => load_proc_macro(it),
.and_then(|it| it.proc_macro_dylib_path.as_ref()) None => Ok(Vec::new()),
.map(|it| load_proc_macro(it)) };
.unwrap_or_default();
let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string()); let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string());
let mut potential_cfg_options = cfg_options.clone(); 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 file_id = load(&sysroot[krate].root)?;
let env = Env::default(); let env = Env::default();
let proc_macro = vec![];
let display_name = CrateDisplayName::from_canonical_name(sysroot[krate].name.clone()); let display_name = CrateDisplayName::from_canonical_name(sysroot[krate].name.clone());
let crate_id = crate_graph.add_crate_root( let crate_id = crate_graph.add_crate_root(
file_id, file_id,
@ -932,7 +931,7 @@ fn sysroot_to_crate_graph(
cfg_options.clone(), cfg_options.clone(),
cfg_options.clone(), cfg_options.clone(),
env, env,
proc_macro, Ok(Vec::new()),
false, false,
CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)), CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
); );

View file

@ -19,7 +19,7 @@ use hir::db::DefDatabase;
use ide::Change; use ide::Change;
use ide_db::base_db::{ use ide_db::base_db::{
CrateGraph, Env, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, CrateGraph, Env, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind,
SourceRoot, VfsPath, ProcMacroLoadResult, SourceRoot, VfsPath,
}; };
use proc_macro_api::{MacroDylib, ProcMacroServer}; use proc_macro_api::{MacroDylib, ProcMacroServer};
use project_model::{ProjectWorkspace, WorkspaceBuildScripts}; use project_model::{ProjectWorkspace, WorkspaceBuildScripts};
@ -536,44 +536,36 @@ impl SourceRootConfig {
/// Load the proc-macros for the given lib path, replacing all expanders whose names are in `dummy_replace` /// Load the proc-macros for the given lib path, replacing all expanders whose names are in `dummy_replace`
/// with an identity dummy expander. /// with an identity dummy expander.
pub(crate) fn load_proc_macro( pub(crate) fn load_proc_macro(
client: Option<&ProcMacroServer>, server: Option<&ProcMacroServer>,
path: &AbsPath, path: &AbsPath,
dummy_replace: &[Box<str>], dummy_replace: &[Box<str>],
) -> Vec<ProcMacro> { ) -> ProcMacroLoadResult {
let dylib = match MacroDylib::new(path.to_path_buf()) { let res: Result<_, String> = (|| {
Ok(it) => it, let dylib = MacroDylib::new(path.to_path_buf())
Err(err) => { .map_err(|io| format!("Proc-macro dylib loading failed: {io}"))?;
// FIXME: that's not really right -- we store this error in a Ok(if let Some(it) = server {
// persistent status. let vec = it.load_dylib(dylib).map_err(|e| format!("{e}"))?;
tracing::warn!("failed to load proc macro: {}", err); vec.into_iter()
return Vec::new();
}
};
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)) .map(|expander| expander_to_proc_macro(expander, dummy_replace))
.collect(); .collect()
} else {
Vec::new()
})
})();
return match res {
Ok(proc_macros) => {
tracing::info!( tracing::info!(
"Loaded proc-macros for {}: {:?}", "Loaded proc-macros for {}: {:?}",
path.display(), path.display(),
proc_macros.iter().map(|it| it.name.clone()).collect::<Vec<_>>() proc_macros.iter().map(|it| it.name.clone()).collect::<Vec<_>>()
); );
return proc_macros; Ok(proc_macros)
}
Err(e) => {
tracing::warn!("proc-macro loading for {} failed: {e}", path.display());
Err(e)
}
};
fn expander_to_proc_macro( fn expander_to_proc_macro(
expander: proc_macro_api::ProcMacro, expander: proc_macro_api::ProcMacro,