aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres.rs
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-11-27 15:29:40 +0000
committerJonas Schievink <[email protected]>2020-11-27 15:29:40 +0000
commitd171838d63907d004ab935d6564bfeb4238d5540 (patch)
tree5c8d1a42cedda2027a6214727e4ad7cd4ffc4fa9 /crates/hir_def/src/nameres.rs
parent0432aa0ed7be3f41d41928499abc688a956214cf (diff)
More accurately place proc-macro diagnostic
Diffstat (limited to 'crates/hir_def/src/nameres.rs')
-rw-r--r--crates/hir_def/src/nameres.rs41
1 files changed, 38 insertions, 3 deletions
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 3d65a46bf..ffd0381d4 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -287,7 +287,8 @@ mod diagnostics {
287 use hir_expand::diagnostics::DiagnosticSink; 287 use hir_expand::diagnostics::DiagnosticSink;
288 use hir_expand::hygiene::Hygiene; 288 use hir_expand::hygiene::Hygiene;
289 use hir_expand::{InFile, MacroCallKind}; 289 use hir_expand::{InFile, MacroCallKind};
290 use syntax::{ast, AstPtr, SyntaxNodePtr}; 290 use syntax::ast::AttrsOwner;
291 use syntax::{ast, AstNode, AstPtr, SyntaxKind, SyntaxNodePtr};
291 292
292 use crate::path::ModPath; 293 use crate::path::ModPath;
293 use crate::{db::DefDatabase, diagnostics::*, nameres::LocalModuleId, AstId}; 294 use crate::{db::DefDatabase, diagnostics::*, nameres::LocalModuleId, AstId};
@@ -425,6 +426,7 @@ mod diagnostics {
425 } 426 }
426 427
427 DiagnosticKind::UnresolvedProcMacro { ast } => { 428 DiagnosticKind::UnresolvedProcMacro { ast } => {
429 let mut precise_location = None;
428 let (file, ast, name) = match ast { 430 let (file, ast, name) = match ast {
429 MacroCallKind::FnLike(ast) => { 431 MacroCallKind::FnLike(ast) => {
430 let node = ast.to_node(db.upcast()); 432 let node = ast.to_node(db.upcast());
@@ -432,14 +434,47 @@ mod diagnostics {
432 } 434 }
433 MacroCallKind::Attr(ast, name) => { 435 MacroCallKind::Attr(ast, name) => {
434 let node = ast.to_node(db.upcast()); 436 let node = ast.to_node(db.upcast());
437
438 // Compute the precise location of the macro name's token in the derive
439 // list.
440 // FIXME: This does not handle paths to the macro, but neither does the
441 // rest of r-a.
442 let derive_attrs =
443 node.attrs().filter_map(|attr| match attr.as_simple_call() {
444 Some((name, args)) if name == "derive" => Some(args),
445 _ => None,
446 });
447 'outer: for attr in derive_attrs {
448 let tokens =
449 attr.syntax().children_with_tokens().filter_map(|elem| {
450 match elem {
451 syntax::NodeOrToken::Node(_) => None,
452 syntax::NodeOrToken::Token(tok) => Some(tok),
453 }
454 });
455 for token in tokens {
456 if token.kind() == SyntaxKind::IDENT
457 && token.to_string() == *name
458 {
459 precise_location = Some(token.text_range());
460 break 'outer;
461 }
462 }
463 }
464
435 ( 465 (
436 ast.file_id, 466 ast.file_id,
437 SyntaxNodePtr::from(AstPtr::new(&node)), 467 SyntaxNodePtr::from(AstPtr::new(&node)),
438 Some(name.to_string()), 468 Some(name.clone()),
439 ) 469 )
440 } 470 }
441 }; 471 };
442 sink.push(UnresolvedProcMacro { file, node: ast, macro_name: name }); 472 sink.push(UnresolvedProcMacro {
473 file,
474 node: ast,
475 precise_location,
476 macro_name: name,
477 });
443 } 478 }
444 479
445 DiagnosticKind::MacroError { ast, message } => { 480 DiagnosticKind::MacroError { ast, message } => {