Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir/src/diagnostics.rs | 3 | ||||
| -rw-r--r-- | crates/hir/src/lib.rs | 10 | ||||
| -rw-r--r-- | crates/hir_def/src/attr.rs | 7 | ||||
| -rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 17 | ||||
| -rw-r--r-- | crates/hir_def/src/nameres/diagnostics.rs | 4 | ||||
| -rw-r--r-- | crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs | 22 |
6 files changed, 44 insertions, 19 deletions
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index bc43fb15ee..08e239804c 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs @@ -67,8 +67,9 @@ pub struct UnresolvedImport { #[derive(Debug, Clone, Eq, PartialEq)] pub struct UnresolvedMacroCall { - pub macro_call: InFile<AstPtr<ast::MacroCall>>, + pub macro_call: InFile<SyntaxNodePtr>, pub path: ModPath, + pub is_bang: bool, } #[derive(Debug, Clone, Eq, PartialEq)] diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 382d1f9a54..2d73168727 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -701,8 +701,9 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag: let node = ast.to_node(db.upcast()); acc.push( UnresolvedMacroCall { - macro_call: InFile::new(ast.file_id, AstPtr::new(&node)), + macro_call: InFile::new(node.file_id, SyntaxNodePtr::new(&node.value)), path: path.clone(), + is_bang: matches!(ast, MacroCallKind::FnLike { .. }), } .into(), ); @@ -1170,7 +1171,12 @@ impl DefWithBody { .into(), ), BodyDiagnostic::UnresolvedMacroCall { node, path } => acc.push( - UnresolvedMacroCall { macro_call: node.clone(), path: path.clone() }.into(), + UnresolvedMacroCall { + macro_call: node.clone().map(|ast_ptr| ast_ptr.into()), + path: path.clone(), + is_bang: true, + } + .into(), ), } } diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 81054f83b0..11d3f48b94 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs @@ -813,12 +813,15 @@ impl Attr { let paths = args .token_trees .split(|tt| matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(Punct { char: ',', .. })))) - .map(|tts| { + .filter_map(|tts| { + if tts.is_empty() { + return None; + } let segments = tts.iter().filter_map(|tt| match tt { tt::TokenTree::Leaf(tt::Leaf::Ident(id)) => Some(id.as_name()), _ => None, }); - ModPath::from_segments(PathKind::Plain, segments) + Some(ModPath::from_segments(PathKind::Plain, segments)) }); Some(paths) diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 15e93f729a..a9705cf2dc 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -1359,13 +1359,24 @@ impl DefCollector<'_> { if let Err(UnresolvedMacro { path }) = macro_call_as_call_id { self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( directive.module_id, - ast_id.ast_id, + MacroCallKind::FnLike { ast_id: ast_id.ast_id, expand_to: *expand_to }, path, )); } } - MacroDirectiveKind::Derive { .. } | MacroDirectiveKind::Attr { .. } => { - // FIXME: we might want to diagnose this too + MacroDirectiveKind::Derive { ast_id, derive_attr, derive_pos } => { + self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( + directive.module_id, + MacroCallKind::Derive { + ast_id: ast_id.ast_id, + derive_attr_index: derive_attr.ast_index, + derive_index: *derive_pos as u32, + }, + ast_id.path.clone(), + )); + } + MacroDirectiveKind::Attr { .. } => { + // FIXME: these should get diagnosed by `reseed_with_unresolved_attribute` } } } diff --git a/crates/hir_def/src/nameres/diagnostics.rs b/crates/hir_def/src/nameres/diagnostics.rs index ab7a368268..dd3ff92cb3 100644 --- a/crates/hir_def/src/nameres/diagnostics.rs +++ b/crates/hir_def/src/nameres/diagnostics.rs @@ -25,7 +25,7 @@ pub enum DefDiagnosticKind { UnresolvedProcMacro { ast: MacroCallKind }, - UnresolvedMacroCall { ast: AstId<ast::MacroCall>, path: ModPath }, + UnresolvedMacroCall { ast: MacroCallKind, path: ModPath }, MacroError { ast: MacroCallKind, message: String }, @@ -95,7 +95,7 @@ impl DefDiagnostic { pub(super) fn unresolved_macro_call( container: LocalModuleId, - ast: AstId<ast::MacroCall>, + ast: MacroCallKind, path: ModPath, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnresolvedMacroCall { ast, path } } diff --git a/crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs b/crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs index ea0f35501b..831d082bc7 100644 --- a/crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs +++ b/crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs @@ -1,5 +1,5 @@ use hir::{db::AstDatabase, InFile}; -use syntax::{AstNode, SyntaxNodePtr}; +use syntax::{ast, AstNode, SyntaxNodePtr}; use crate::{Diagnostic, DiagnosticsContext}; @@ -12,19 +12,23 @@ pub(crate) fn unresolved_macro_call( d: &hir::UnresolvedMacroCall, ) -> Diagnostic { let last_path_segment = ctx.sema.db.parse_or_expand(d.macro_call.file_id).and_then(|root| { - d.macro_call - .value - .to_node(&root) - .path() - .and_then(|it| it.segment()) - .and_then(|it| it.name_ref()) - .map(|it| InFile::new(d.macro_call.file_id, SyntaxNodePtr::new(it.syntax()))) + let node = d.macro_call.value.to_node(&root); + if let Some(macro_call) = ast::MacroCall::cast(node) { + macro_call + .path() + .and_then(|it| it.segment()) + .and_then(|it| it.name_ref()) + .map(|it| InFile::new(d.macro_call.file_id, SyntaxNodePtr::new(it.syntax()))) + } else { + None + } }); let diagnostics = last_path_segment.unwrap_or_else(|| d.macro_call.clone().map(|it| it.into())); + let bang = if d.is_bang { "!" } else { "" }; Diagnostic::new( "unresolved-macro-call", - format!("unresolved macro `{}!`", d.path), + format!("unresolved macro `{}{}`", d.path, bang), ctx.sema.diagnostics_display_range(diagnostics).range, ) .experimental() |