Skip to content

Commit 7ed2da6

Browse files
bors[bot]matklad
andauthored
Merge #7805
7805: For unresolved macros, hightlight only the last segment r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents c412d5f + 05729fd commit 7ed2da6

File tree

8 files changed

+209
-109
lines changed

8 files changed

+209
-109
lines changed

crates/hir/src/diagnostics.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! FIXME: write short doc here
2-
pub use hir_def::diagnostics::{InactiveCode, UnresolvedModule, UnresolvedProcMacro};
2+
pub use hir_def::diagnostics::{
3+
InactiveCode, UnresolvedMacroCall, UnresolvedModule, UnresolvedProcMacro,
4+
};
35
pub use hir_expand::diagnostics::{
46
Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder,
57
};

crates/hir/src/semantics.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@ use rustc_hash::{FxHashMap, FxHashSet};
1616
use syntax::{
1717
algo::find_node_at_offset,
1818
ast::{self, GenericParamsOwner, LoopBodyOwner},
19-
match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize,
19+
match_ast, AstNode, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextSize,
2020
};
2121

2222
use crate::{
2323
code_model::Access,
2424
db::HirDatabase,
25-
diagnostics::Diagnostic,
2625
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
2726
source_analyzer::{resolve_hir_path, SourceAnalyzer},
2827
AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile, Label,
@@ -141,7 +140,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
141140
self.imp.original_range(node)
142141
}
143142

144-
pub fn diagnostics_display_range(&self, diagnostics: &dyn Diagnostic) -> FileRange {
143+
pub fn diagnostics_display_range(&self, diagnostics: InFile<SyntaxNodePtr>) -> FileRange {
145144
self.imp.diagnostics_display_range(diagnostics)
146145
}
147146

@@ -385,8 +384,7 @@ impl<'db> SemanticsImpl<'db> {
385384
node.as_ref().original_file_range(self.db.upcast())
386385
}
387386

388-
fn diagnostics_display_range(&self, diagnostics: &dyn Diagnostic) -> FileRange {
389-
let src = diagnostics.display_source();
387+
fn diagnostics_display_range(&self, src: InFile<SyntaxNodePtr>) -> FileRange {
390388
let root = self.db.parse_or_expand(src.file_id).unwrap();
391389
let node = src.value.to_node(&root);
392390
self.cache(root, src.file_id);

crates/hir_def/src/body.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl Expander {
123123
Some(it) => it,
124124
None => {
125125
if err.is_none() {
126-
eprintln!("no error despite `as_call_id_with_errors` returning `None`");
126+
log::warn!("no error despite `as_call_id_with_errors` returning `None`");
127127
}
128128
return ExpandResult { value: None, err };
129129
}

crates/hir_def/src/diagnostics.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,34 @@ impl Diagnostic for UnresolvedImport {
9595
}
9696
}
9797

98+
// Diagnostic: unresolved-macro-call
99+
//
100+
// This diagnostic is triggered if rust-analyzer is unable to resolove path to a
101+
// macro in a macro invocation.
102+
#[derive(Debug)]
103+
pub struct UnresolvedMacroCall {
104+
pub file: HirFileId,
105+
pub node: AstPtr<ast::MacroCall>,
106+
}
107+
108+
impl Diagnostic for UnresolvedMacroCall {
109+
fn code(&self) -> DiagnosticCode {
110+
DiagnosticCode("unresolved-macro-call")
111+
}
112+
fn message(&self) -> String {
113+
"unresolved macro call".to_string()
114+
}
115+
fn display_source(&self) -> InFile<SyntaxNodePtr> {
116+
InFile::new(self.file, self.node.clone().into())
117+
}
118+
fn as_any(&self) -> &(dyn Any + Send + 'static) {
119+
self
120+
}
121+
fn is_experimental(&self) -> bool {
122+
true
123+
}
124+
}
125+
98126
// Diagnostic: inactive-code
99127
//
100128
// This diagnostic is shown for code with inactive `#[cfg]` attributes.

crates/hir_def/src/lib.rs

Lines changed: 56 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ use std::{
5757

5858
use base_db::{impl_intern_key, salsa, CrateId};
5959
use hir_expand::{
60-
ast_id_map::FileAstId, eager::expand_eager_macro, hygiene::Hygiene, AstId, HirFileId, InFile,
61-
MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
60+
ast_id_map::FileAstId,
61+
eager::{expand_eager_macro, ErrorEmitted},
62+
hygiene::Hygiene,
63+
AstId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
6264
};
6365
use la_arena::Idx;
6466
use nameres::DefMap;
@@ -592,8 +594,15 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
592594
error_sink(mbe::ExpandError::Other("malformed macro invocation".into()));
593595
}
594596

595-
AstIdWithPath::new(ast_id.file_id, ast_id.value, path?)
596-
.as_call_id_with_errors(db, krate, resolver, error_sink)
597+
macro_call_as_call_id(
598+
&AstIdWithPath::new(ast_id.file_id, ast_id.value, path?),
599+
db,
600+
krate,
601+
resolver,
602+
error_sink,
603+
)
604+
.ok()?
605+
.ok()
597606
}
598607
}
599608

@@ -610,61 +619,50 @@ impl<T: ast::AstNode> AstIdWithPath<T> {
610619
}
611620
}
612621

613-
impl AsMacroCall for AstIdWithPath<ast::MacroCall> {
614-
fn as_call_id_with_errors(
615-
&self,
616-
db: &dyn db::DefDatabase,
617-
krate: CrateId,
618-
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
619-
error_sink: &mut dyn FnMut(mbe::ExpandError),
620-
) -> Option<MacroCallId> {
621-
let def: MacroDefId = resolver(self.path.clone()).or_else(|| {
622-
error_sink(mbe::ExpandError::Other(format!("could not resolve macro `{}`", self.path)));
623-
None
624-
})?;
625-
626-
if let MacroDefKind::BuiltInEager(_) = def.kind {
627-
let macro_call = InFile::new(self.ast_id.file_id, self.ast_id.to_node(db.upcast()));
628-
let hygiene = Hygiene::new(db.upcast(), self.ast_id.file_id);
629-
630-
Some(
631-
expand_eager_macro(
632-
db.upcast(),
633-
krate,
634-
macro_call,
635-
def,
636-
&|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?),
637-
error_sink,
638-
)
639-
.ok()?
640-
.into(),
641-
)
642-
} else {
643-
Some(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(self.ast_id)).into())
644-
}
645-
}
622+
struct UnresolvedMacro;
623+
624+
fn macro_call_as_call_id(
625+
call: &AstIdWithPath<ast::MacroCall>,
626+
db: &dyn db::DefDatabase,
627+
krate: CrateId,
628+
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
629+
error_sink: &mut dyn FnMut(mbe::ExpandError),
630+
) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
631+
let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?;
632+
633+
let res = if let MacroDefKind::BuiltInEager(_) = def.kind {
634+
let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
635+
let hygiene = Hygiene::new(db.upcast(), call.ast_id.file_id);
636+
637+
expand_eager_macro(
638+
db.upcast(),
639+
krate,
640+
macro_call,
641+
def,
642+
&|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?),
643+
error_sink,
644+
)
645+
.map(MacroCallId::from)
646+
} else {
647+
Ok(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(call.ast_id)).into())
648+
};
649+
Ok(res)
646650
}
647651

648-
impl AsMacroCall for AstIdWithPath<ast::Item> {
649-
fn as_call_id_with_errors(
650-
&self,
651-
db: &dyn db::DefDatabase,
652-
krate: CrateId,
653-
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
654-
error_sink: &mut dyn FnMut(mbe::ExpandError),
655-
) -> Option<MacroCallId> {
656-
let def: MacroDefId = resolver(self.path.clone()).or_else(|| {
657-
error_sink(mbe::ExpandError::Other(format!("could not resolve macro `{}`", self.path)));
658-
None
659-
})?;
660-
661-
Some(
662-
def.as_lazy_macro(
663-
db.upcast(),
664-
krate,
665-
MacroCallKind::Attr(self.ast_id, self.path.segments().last()?.to_string()),
666-
)
667-
.into(),
652+
fn item_attr_as_call_id(
653+
item_attr: &AstIdWithPath<ast::Item>,
654+
db: &dyn db::DefDatabase,
655+
krate: CrateId,
656+
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
657+
) -> Result<MacroCallId, UnresolvedMacro> {
658+
let def: MacroDefId = resolver(item_attr.path.clone()).ok_or(UnresolvedMacro)?;
659+
let last_segment = item_attr.path.segments().last().ok_or(UnresolvedMacro)?;
660+
let res = def
661+
.as_lazy_macro(
662+
db.upcast(),
663+
krate,
664+
MacroCallKind::Attr(item_attr.ast_id, last_segment.to_string()),
668665
)
669-
}
666+
.into();
667+
Ok(res)
670668
}

crates/hir_def/src/nameres.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ mod diagnostics {
417417

418418
UnresolvedProcMacro { ast: MacroCallKind },
419419

420+
UnresolvedMacroCall { ast: AstId<ast::MacroCall> },
421+
420422
MacroError { ast: MacroCallKind, message: String },
421423
}
422424

@@ -477,6 +479,13 @@ mod diagnostics {
477479
Self { in_module: container, kind: DiagnosticKind::MacroError { ast, message } }
478480
}
479481

482+
pub(super) fn unresolved_macro_call(
483+
container: LocalModuleId,
484+
ast: AstId<ast::MacroCall>,
485+
) -> Self {
486+
Self { in_module: container, kind: DiagnosticKind::UnresolvedMacroCall { ast } }
487+
}
488+
480489
pub(super) fn add_to(
481490
&self,
482491
db: &dyn DefDatabase,
@@ -589,6 +598,11 @@ mod diagnostics {
589598
});
590599
}
591600

601+
DiagnosticKind::UnresolvedMacroCall { ast } => {
602+
let node = ast.to_node(db.upcast());
603+
sink.push(UnresolvedMacroCall { file: ast.file_id, node: AstPtr::new(&node) });
604+
}
605+
592606
DiagnosticKind::MacroError { ast, message } => {
593607
let (file, ast) = match ast {
594608
MacroCallKind::FnLike(ast) => {

0 commit comments

Comments
 (0)