mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 13:33:31 +00:00
fix: Report proc macro errors in expressions correctly as well
They didn't have a krate before, resulting in the generic "proc macro not found" error. Also improve error messages a bit more.
This commit is contained in:
parent
9eaf96c9ea
commit
8b3ec12aac
12 changed files with 69 additions and 69 deletions
|
@ -312,7 +312,7 @@ pub struct SyntheticSyntax;
|
|||
pub enum BodyDiagnostic {
|
||||
InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions },
|
||||
MacroError { node: InFile<AstPtr<ast::MacroCall>>, message: String },
|
||||
UnresolvedProcMacro { node: InFile<AstPtr<ast::MacroCall>> },
|
||||
UnresolvedProcMacro { node: InFile<AstPtr<ast::MacroCall>>, krate: CrateId },
|
||||
UnresolvedMacroCall { node: InFile<AstPtr<ast::MacroCall>>, path: ModPath },
|
||||
}
|
||||
|
||||
|
|
|
@ -572,9 +572,10 @@ impl ExprCollector<'_> {
|
|||
|
||||
if record_diagnostics {
|
||||
match &res.err {
|
||||
Some(ExpandError::UnresolvedProcMacro) => {
|
||||
Some(ExpandError::UnresolvedProcMacro(krate)) => {
|
||||
self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro {
|
||||
node: InFile::new(outer_file, syntax_ptr),
|
||||
krate: *krate,
|
||||
});
|
||||
}
|
||||
Some(err) => {
|
||||
|
|
|
@ -22,6 +22,7 @@ use itertools::Itertools;
|
|||
use la_arena::Idx;
|
||||
use limit::Limit;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use stdx::always;
|
||||
use syntax::{ast, SmolStr};
|
||||
|
||||
use crate::{
|
||||
|
@ -1234,7 +1235,7 @@ impl DefCollector<'_> {
|
|||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
|
||||
directive.module_id,
|
||||
loc.kind,
|
||||
Some(loc.def.krate),
|
||||
loc.def.krate,
|
||||
));
|
||||
return recollect_without(self);
|
||||
}
|
||||
|
@ -1258,7 +1259,7 @@ impl DefCollector<'_> {
|
|||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
|
||||
directive.module_id,
|
||||
loc.kind,
|
||||
Some(loc.def.krate),
|
||||
loc.def.krate,
|
||||
));
|
||||
|
||||
return recollect_without(self);
|
||||
|
@ -1308,13 +1309,10 @@ impl DefCollector<'_> {
|
|||
let err = self.db.macro_expand_error(macro_call_id);
|
||||
if let Some(err) = err {
|
||||
let diag = match err {
|
||||
hir_expand::ExpandError::UnresolvedProcMacro => {
|
||||
hir_expand::ExpandError::UnresolvedProcMacro(krate) => {
|
||||
always!(krate == loc.def.krate);
|
||||
// Missing proc macros are non-fatal, so they are handled specially.
|
||||
DefDiagnostic::unresolved_proc_macro(
|
||||
module_id,
|
||||
loc.kind.clone(),
|
||||
Some(loc.def.krate),
|
||||
)
|
||||
DefDiagnostic::unresolved_proc_macro(module_id, loc.kind.clone(), loc.def.krate)
|
||||
}
|
||||
_ => DefDiagnostic::macro_error(module_id, loc.kind.clone(), err.to_string()),
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@ pub enum DefDiagnosticKind {
|
|||
|
||||
UnconfiguredCode { ast: AstId<ast::Item>, cfg: CfgExpr, opts: CfgOptions },
|
||||
|
||||
UnresolvedProcMacro { ast: MacroCallKind, krate: Option<CrateId> },
|
||||
UnresolvedProcMacro { ast: MacroCallKind, krate: CrateId },
|
||||
|
||||
UnresolvedMacroCall { ast: MacroCallKind, path: ModPath },
|
||||
|
||||
|
@ -85,7 +85,7 @@ impl DefDiagnostic {
|
|||
pub(super) fn unresolved_proc_macro(
|
||||
container: LocalModuleId,
|
||||
ast: MacroCallKind,
|
||||
krate: Option<CrateId>,
|
||||
krate: CrateId,
|
||||
) -> Self {
|
||||
Self { in_module: container, kind: DefDiagnosticKind::UnresolvedProcMacro { ast, krate } }
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ pub type ExpandResult<T> = ValueResult<T, ExpandError>;
|
|||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum ExpandError {
|
||||
UnresolvedProcMacro,
|
||||
UnresolvedProcMacro(CrateId),
|
||||
Mbe(mbe::ExpandError),
|
||||
Other(Box<str>),
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ impl From<mbe::ExpandError> for ExpandError {
|
|||
impl fmt::Display for ExpandError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ExpandError::UnresolvedProcMacro => f.write_str("unresolved proc-macro"),
|
||||
ExpandError::UnresolvedProcMacro(_) => f.write_str("unresolved proc-macro"),
|
||||
ExpandError::Mbe(it) => it.fmt(f),
|
||||
ExpandError::Other(it) => f.write_str(it),
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ impl ProcMacroExpander {
|
|||
},
|
||||
}
|
||||
}
|
||||
None => ExpandResult::only_err(ExpandError::UnresolvedProcMacro),
|
||||
None => ExpandResult::only_err(ExpandError::UnresolvedProcMacro(self.krate)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ pub struct UnresolvedProcMacro {
|
|||
pub macro_name: Option<String>,
|
||||
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>,
|
||||
pub krate: CrateId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
|
|
|
@ -1159,13 +1159,13 @@ impl DefWithBody {
|
|||
}
|
||||
.into(),
|
||||
),
|
||||
BodyDiagnostic::UnresolvedProcMacro { node } => acc.push(
|
||||
BodyDiagnostic::UnresolvedProcMacro { node, krate } => acc.push(
|
||||
UnresolvedProcMacro {
|
||||
node: node.clone().map(|it| it.into()),
|
||||
precise_location: None,
|
||||
macro_name: None,
|
||||
kind: MacroKind::ProcMacro,
|
||||
krate: None,
|
||||
krate: *krate,
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
|
|
|
@ -32,13 +32,13 @@ pub(crate) fn unresolved_proc_macro(
|
|||
None => "proc macro not expanded".to_string(),
|
||||
};
|
||||
let severity = if config_enabled { Severity::Error } else { Severity::WeakWarning };
|
||||
let def_map = d.krate.map(|krate| ctx.sema.db.crate_def_map(krate));
|
||||
let def_map = ctx.sema.db.crate_def_map(d.krate);
|
||||
let message = format!(
|
||||
"{message}: {}",
|
||||
if config_enabled {
|
||||
match def_map.as_ref().and_then(|def_map| def_map.proc_macro_loading_error()) {
|
||||
match def_map.proc_macro_loading_error() {
|
||||
Some(e) => e,
|
||||
None => "proc macro not found",
|
||||
None => "proc macro not found in the built dylib",
|
||||
}
|
||||
} else {
|
||||
match d.kind {
|
||||
|
|
|
@ -173,7 +173,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -248,7 +248,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -313,7 +313,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||
},
|
||||
dependencies: [],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: Some(
|
||||
|
@ -390,7 +390,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -465,7 +465,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -555,7 +555,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -632,7 +632,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -697,7 +697,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||
},
|
||||
dependencies: [],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: Some(
|
||||
|
@ -776,7 +776,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -853,7 +853,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -934,7 +934,7 @@ fn cargo_hello_world_project_model() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -1011,7 +1011,7 @@ fn cargo_hello_world_project_model() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -1076,7 +1076,7 @@ fn cargo_hello_world_project_model() {
|
|||
},
|
||||
dependencies: [],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: Some(
|
||||
|
@ -1155,7 +1155,7 @@ fn cargo_hello_world_project_model() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -1232,7 +1232,7 @@ fn cargo_hello_world_project_model() {
|
|||
},
|
||||
],
|
||||
proc_macro: Err(
|
||||
"no build data",
|
||||
"crate has not (yet) been built",
|
||||
),
|
||||
origin: CratesIo {
|
||||
repo: None,
|
||||
|
@ -1288,8 +1288,8 @@ fn rust_project_hello_world_project_model() {
|
|||
prelude: true,
|
||||
},
|
||||
],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Alloc,
|
||||
|
@ -1322,8 +1322,8 @@ fn rust_project_hello_world_project_model() {
|
|||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Other,
|
||||
|
@ -1356,8 +1356,8 @@ fn rust_project_hello_world_project_model() {
|
|||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Other,
|
||||
|
@ -1400,8 +1400,8 @@ fn rust_project_hello_world_project_model() {
|
|||
prelude: true,
|
||||
},
|
||||
],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Other,
|
||||
|
@ -1434,8 +1434,8 @@ fn rust_project_hello_world_project_model() {
|
|||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Core,
|
||||
|
@ -1539,8 +1539,8 @@ fn rust_project_hello_world_project_model() {
|
|||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Other,
|
||||
|
@ -1573,8 +1573,8 @@ fn rust_project_hello_world_project_model() {
|
|||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Other,
|
||||
|
@ -1607,8 +1607,8 @@ fn rust_project_hello_world_project_model() {
|
|||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Other,
|
||||
|
@ -1641,8 +1641,8 @@ fn rust_project_hello_world_project_model() {
|
|||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Test,
|
||||
|
@ -1757,8 +1757,8 @@ fn rust_project_hello_world_project_model() {
|
|||
prelude: true,
|
||||
},
|
||||
],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Std,
|
||||
|
@ -1791,8 +1791,8 @@ fn rust_project_hello_world_project_model() {
|
|||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
proc_macro: Ok(
|
||||
[],
|
||||
proc_macro: Err(
|
||||
"no proc macro loaded for sysroot crate",
|
||||
),
|
||||
origin: Lang(
|
||||
Other,
|
||||
|
|
|
@ -873,7 +873,7 @@ fn add_target_crate_root(
|
|||
let proc_macro = match build_data.as_ref().map(|it| it.proc_macro_dylib_path.as_ref()) {
|
||||
Some(Some(it)) => load_proc_macro(it),
|
||||
Some(None) => Err("no proc macro dylib present".into()),
|
||||
None => Err("no build data".into()),
|
||||
None => Err("crate has not (yet) been built".into()),
|
||||
};
|
||||
|
||||
let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string());
|
||||
|
@ -929,7 +929,7 @@ fn sysroot_to_crate_graph(
|
|||
cfg_options.clone(),
|
||||
cfg_options.clone(),
|
||||
env,
|
||||
Ok(Vec::new()),
|
||||
Err("no proc macro loaded for sysroot crate".into()),
|
||||
false,
|
||||
CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
|
||||
);
|
||||
|
|
|
@ -540,17 +540,18 @@ pub(crate) fn load_proc_macro(
|
|||
path: &AbsPath,
|
||||
dummy_replace: &[Box<str>],
|
||||
) -> ProcMacroLoadResult {
|
||||
let res: Result<_, String> = (|| {
|
||||
let res: Result<Vec<_>, 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()
|
||||
})
|
||||
let server = server.ok_or_else(|| format!("Proc-macro server not started"))?;
|
||||
let vec = server.load_dylib(dylib).map_err(|e| format!("{e}"))?;
|
||||
if vec.is_empty() {
|
||||
return Err("proc macro library returned no proc macros".to_string());
|
||||
}
|
||||
Ok(vec
|
||||
.into_iter()
|
||||
.map(|expander| expander_to_proc_macro(expander, dummy_replace))
|
||||
.collect())
|
||||
})();
|
||||
return match res {
|
||||
Ok(proc_macros) => {
|
||||
|
|
Loading…
Reference in a new issue