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.rs162
1 files changed, 81 insertions, 81 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index cc4d14c12d..7a31a8a417 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -73,7 +73,7 @@ use rustc_hash::FxHashSet;
use stdx::{format_to, impl_from, never};
use syntax::{
ast::{self, HasAttrs as _, HasDocComments, HasName},
- AstNode, AstPtr, SmolStr, SyntaxNodePtr, T,
+ AstNode, AstPtr, SmolStr, SyntaxNodePtr, TextRange, T,
};
use crate::db::{DefDatabase, HirDatabase};
@@ -628,67 +628,7 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
}
DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
- let (node, precise_location, macro_name, kind) = match ast {
- MacroCallKind::FnLike { ast_id, .. } => {
- let node = ast_id.to_node(db.upcast());
- (
- ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
- node.path().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 } => {
- let node = ast_id.to_node(db.upcast());
- // Compute the precise location of the macro name's token in the derive
- // list.
- let token = (|| {
- let derive_attr = node
- .doc_comments_and_attrs()
- .nth(*derive_attr_index as usize)
- .and_then(Either::left)?;
- let token_tree = derive_attr.meta()?.token_tree()?;
- let group_by = token_tree
- .syntax()
- .children_with_tokens()
- .filter_map(|elem| match elem {
- syntax::NodeOrToken::Token(tok) => Some(tok),
- _ => None,
- })
- .group_by(|t| t.kind() == T![,]);
- let (_, mut group) = group_by
- .into_iter()
- .filter(|&(comma, _)| !comma)
- .nth(*derive_index as usize)?;
- group.find(|t| t.kind() == T![ident])
- })();
- (
- 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, .. } => {
- let node = ast_id.to_node(db.upcast());
- let attr = node
- .doc_comments_and_attrs()
- .nth((*invoc_attr_index) as usize)
- .and_then(Either::left)
- .unwrap_or_else(|| panic!("cannot find attribute #{}", invoc_attr_index));
-
- (
- 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,
- )
- }
- };
+ 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(),
@@ -696,10 +636,11 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
}
DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
- let node = ast.to_node(db.upcast());
+ let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
acc.push(
UnresolvedMacroCall {
- macro_call: InFile::new(node.file_id, SyntaxNodePtr::new(&node.value)),
+ macro_call: node,
+ precise_location,
path: path.clone(),
is_bang: matches!(ast, MacroCallKind::FnLike { .. }),
}
@@ -708,23 +649,8 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
}
DefDiagnosticKind::MacroError { ast, message } => {
- let node = match ast {
- MacroCallKind::FnLike { ast_id, .. } => {
- let node = ast_id.to_node(db.upcast());
- ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
- }
- MacroCallKind::Derive { ast_id, .. } => {
- // FIXME: point to the attribute instead, this creates very large diagnostics
- let node = ast_id.to_node(db.upcast());
- ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
- }
- MacroCallKind::Attr { ast_id, .. } => {
- // FIXME: point to the attribute instead, this creates very large diagnostics
- let node = ast_id.to_node(db.upcast());
- ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
- }
- };
- acc.push(MacroError { node, message: message.clone() }.into());
+ let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
+ acc.push(MacroError { node, precise_location, message: message.clone() }.into());
}
DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => {
@@ -771,6 +697,78 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
}
}
+fn precise_macro_call_location(
+ ast: &MacroCallKind,
+ db: &dyn HirDatabase,
+) -> (InFile<SyntaxNodePtr>, Option<TextRange>, Option<String>, MacroKind) {
+ // FIXME: maaybe 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 {
+ MacroCallKind::FnLike { ast_id, .. } => {
+ let node = ast_id.to_node(db.upcast());
+ (
+ ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
+ node.path()
+ .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 } => {
+ let node = ast_id.to_node(db.upcast());
+ // Compute the precise location of the macro name's token in the derive
+ // list.
+ let token = (|| {
+ let derive_attr = node
+ .doc_comments_and_attrs()
+ .nth(*derive_attr_index as usize)
+ .and_then(Either::left)?;
+ let token_tree = derive_attr.meta()?.token_tree()?;
+ let group_by = token_tree
+ .syntax()
+ .children_with_tokens()
+ .filter_map(|elem| match elem {
+ syntax::NodeOrToken::Token(tok) => Some(tok),
+ _ => None,
+ })
+ .group_by(|t| t.kind() == T![,]);
+ let (_, mut group) = group_by
+ .into_iter()
+ .filter(|&(comma, _)| !comma)
+ .nth(*derive_index as usize)?;
+ group.find(|t| t.kind() == T![ident])
+ })();
+ (
+ 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, .. } => {
+ let node = ast_id.to_node(db.upcast());
+ let attr = node
+ .doc_comments_and_attrs()
+ .nth((*invoc_attr_index) as usize)
+ .and_then(Either::left)
+ .unwrap_or_else(|| panic!("cannot find attribute #{}", invoc_attr_index));
+
+ (
+ 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,
+ )
+ }
+ }
+}
+
impl HasVisibility for Module {
fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
let def_map = self.id.def_map(db.upcast());
@@ -1156,6 +1154,7 @@ impl DefWithBody {
BodyDiagnostic::MacroError { node, message } => acc.push(
MacroError {
node: node.clone().map(|it| it.into()),
+ precise_location: None,
message: message.to_string(),
}
.into(),
@@ -1173,6 +1172,7 @@ impl DefWithBody {
BodyDiagnostic::UnresolvedMacroCall { node, path } => acc.push(
UnresolvedMacroCall {
macro_call: node.clone().map(|ast_ptr| ast_ptr.into()),
+ precise_location: None,
path: path.clone(),
is_bang: true,
}