Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r--crates/hir/src/lib.rs94
1 files changed, 53 insertions, 41 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 70f4a632fb..266ef2a55c 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -137,7 +137,7 @@ pub use {
hygiene::{marks_rev, SyntaxContextExt},
inert_attr_macro::AttributeTemplate,
name::Name,
- proc_macro::ProcMacros,
+ proc_macro::{ProcMacros, ProcMacrosBuilder},
tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt,
},
hir_ty::{
@@ -833,19 +833,27 @@ fn macro_call_diagnostics(
let ValueResult { value: parse_errors, err } = &*e;
if let Some(err) = err {
let loc = db.lookup_intern_macro_call(macro_call_id);
- let (node, precise_location, macro_name, kind) = precise_macro_call_location(&loc.kind, db);
- let diag = match err {
- &hir_expand::ExpandError::UnresolvedProcMacro(krate) => {
- UnresolvedProcMacro { node, precise_location, macro_name, kind, krate }.into()
- }
- err => MacroError { node, precise_location, message: err.to_string() }.into(),
+ let file_id = loc.kind.file_id();
+ let node =
+ InFile::new(file_id, db.ast_id_map(file_id).get_erased(loc.kind.erased_ast_id()));
+ let (message, error) = err.render_to_string(db.upcast());
+ let precise_location = if err.span().anchor.file_id == file_id {
+ Some(
+ err.span().range
+ + db.ast_id_map(err.span().anchor.file_id.into())
+ .get_erased(err.span().anchor.ast_id)
+ .text_range()
+ .start(),
+ )
+ } else {
+ None
};
- acc.push(diag);
+ acc.push(MacroError { node, precise_location, message, error }.into());
}
if !parse_errors.is_empty() {
let loc = db.lookup_intern_macro_call(macro_call_id);
- let (node, precise_location, _, _) = precise_macro_call_location(&loc.kind, db);
+ let (node, precise_location) = precise_macro_call_location(&loc.kind, db);
acc.push(
MacroExpansionParseError { node, precise_location, errors: parse_errors.clone() }
.into(),
@@ -895,6 +903,19 @@ fn emit_def_diagnostic_(
acc.push(UnresolvedExternCrate { decl: InFile::new(ast.file_id, item) }.into());
}
+ DefDiagnosticKind::MacroError { ast, path, err } => {
+ let item = ast.to_ptr(db.upcast());
+ let (message, error) = err.render_to_string(db.upcast());
+ acc.push(
+ MacroError {
+ node: InFile::new(ast.file_id, item.syntax_node_ptr()),
+ precise_location: None,
+ message: format!("{}: {message}", path.display(db.upcast())),
+ error,
+ }
+ .into(),
+ )
+ }
DefDiagnosticKind::UnresolvedImport { id, index } => {
let file_id = id.file_id();
let item_tree = id.item_tree(db.upcast());
@@ -991,15 +1012,8 @@ fn emit_def_diagnostic_(
Some(())
})();
}
- DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
- let (node, precise_location, macro_name, kind) = precise_macro_call_location(ast, db);
- acc.push(
- UnresolvedProcMacro { node, precise_location, macro_name, kind, krate: *krate }
- .into(),
- );
- }
DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
- let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
+ let (node, precise_location) = precise_macro_call_location(ast, db);
acc.push(
UnresolvedMacroCall {
macro_call: node,
@@ -1068,7 +1082,7 @@ fn emit_def_diagnostic_(
fn precise_macro_call_location(
ast: &MacroCallKind,
db: &dyn HirDatabase,
-) -> (InFile<SyntaxNodePtr>, Option<TextRange>, Option<String>, MacroKind) {
+) -> (InFile<SyntaxNodePtr>, Option<TextRange>) {
// FIXME: maybe we actually want slightly different ranges for the different macro diagnostics
// - e.g. the full attribute for macro errors, but only the name for name resolution
match ast {
@@ -1080,8 +1094,6 @@ fn precise_macro_call_location(
.and_then(|it| it.segment())
.and_then(|it| it.name_ref())
.map(|it| it.syntax().text_range()),
- node.path().and_then(|it| it.segment()).map(|it| it.to_string()),
- MacroKind::ProcMacro,
)
}
MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, .. } => {
@@ -1110,8 +1122,6 @@ fn precise_macro_call_location(
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
token.as_ref().map(|tok| tok.text_range()),
- token.as_ref().map(ToString::to_string),
- MacroKind::Derive,
)
}
MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => {
@@ -1126,12 +1136,6 @@ fn precise_macro_call_location(
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
Some(attr.syntax().text_range()),
- attr.path()
- .and_then(|path| path.segment())
- .and_then(|seg| seg.name_ref())
- .as_ref()
- .map(ToString::to_string),
- MacroKind::Attr,
)
}
}
@@ -1795,20 +1799,28 @@ impl DefWithBody {
BodyDiagnostic::InactiveCode { node, cfg, opts } => {
InactiveCode { node: *node, cfg: cfg.clone(), opts: opts.clone() }.into()
}
- BodyDiagnostic::MacroError { node, message } => MacroError {
- node: (*node).map(|it| it.into()),
- precise_location: None,
- message: message.to_string(),
- }
- .into(),
- BodyDiagnostic::UnresolvedProcMacro { node, krate } => UnresolvedProcMacro {
- node: (*node).map(|it| it.into()),
- precise_location: None,
- macro_name: None,
- kind: MacroKind::ProcMacro,
- krate: *krate,
+ BodyDiagnostic::MacroError { node, err } => {
+ let (message, error) = err.render_to_string(db.upcast());
+
+ let precise_location = if err.span().anchor.file_id == node.file_id {
+ Some(
+ err.span().range
+ + db.ast_id_map(err.span().anchor.file_id.into())
+ .get_erased(err.span().anchor.ast_id)
+ .text_range()
+ .start(),
+ )
+ } else {
+ None
+ };
+ MacroError {
+ node: (*node).map(|it| it.into()),
+ precise_location,
+ message,
+ error,
+ }
+ .into()
}
- .into(),
BodyDiagnostic::UnresolvedMacroCall { node, path } => UnresolvedMacroCall {
macro_call: (*node).map(|ast_ptr| ast_ptr.into()),
precise_location: None,