aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/lib.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-03-17 07:20:28 +0000
committerGitHub <[email protected]>2021-03-17 07:20:28 +0000
commit6fcb5d772f16af0d1f62dad55fbde75072fb9e89 (patch)
treee4ddd896f9ca8ca1f99c346a49104b04bc4ca04c /crates/hir_def/src/lib.rs
parent83e6940efb42675226adb8d2856c095b8dce36c5 (diff)
parenta79b5673e8f5d1f8d569bc7c984a293a972a7bb0 (diff)
Merge #8048
8048: Fix missing unresolved macro diagnostic in function body r=edwin0cheng a=brandondong This was an issue I found while working on https://github.com/rust-analyzer/rust-analyzer/pull/7970. **Reproduction:** 1. Call a non-existent macro in a function body. ``` fn main() { foo!(); } ``` 2. No diagnostics are raised. An unresolved-macro-call diagnostic is expected. 3. If the macro call is instead outside of the function body, this works as expected. I believe this worked previously and regressed in https://github.com/rust-analyzer/rust-analyzer/pull/7805. **Behavior prior to https://github.com/rust-analyzer/rust-analyzer/pull/7805:** - The unresolved-macro-call diagnostic did not exist. Instead, a macro-error diagnostic would be raised with the text "could not resolve macro [path]". - This was implemented by adding an error to the error sink (https://github.com/rust-analyzer/rust-analyzer/pull/7805/files#diff-50a326c5ae465bd9b31ee4310186380aa06e4fa1f6b41dbc0aed5bcc656a3cb8L657). - The error was propagated through https://github.com/rust-analyzer/rust-analyzer/blob/1a82af3527e476d52410ff4dfd2fb4c57466abcb/crates/hir_def/src/body.rs#L123 eventually reaching https://github.com/rust-analyzer/rust-analyzer/blob/1a82af3527e476d52410ff4dfd2fb4c57466abcb/crates/hir_def/src/body/lower.rs#L569. **Behavior after:** - Instead of writing to the error sink, an UnresolvedMacro error is now returned (https://github.com/rust-analyzer/rust-analyzer/pull/7805/files#diff-50a326c5ae465bd9b31ee4310186380aa06e4fa1f6b41dbc0aed5bcc656a3cb8R631). - The parent caller throws away the error as its function signature is `Option<MacroCallId>` (https://github.com/rust-analyzer/rust-analyzer/pull/7805/files#diff-50a326c5ae465bd9b31ee4310186380aa06e4fa1f6b41dbc0aed5bcc656a3cb8R604). - We instead now reach the warn condition (https://github.com/rust-analyzer/rust-analyzer/blob/1a82af3527e476d52410ff4dfd2fb4c57466abcb/crates/hir_def/src/body.rs#L124) and no diagnostics are created in https://github.com/rust-analyzer/rust-analyzer/blob/1a82af3527e476d52410ff4dfd2fb4c57466abcb/crates/hir_def/src/body/lower.rs#L575. **Fix:** - Make sure to propagate the UnresolvedMacro error. Report the error using the new unresolved-macro-call diagnostic. Co-authored-by: Brandon <[email protected]>
Diffstat (limited to 'crates/hir_def/src/lib.rs')
-rw-r--r--crates/hir_def/src/lib.rs27
1 files changed, 15 insertions, 12 deletions
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index c6655c5fb..6758411a0 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -58,7 +58,7 @@ use std::{
58use base_db::{impl_intern_key, salsa, CrateId}; 58use base_db::{impl_intern_key, salsa, CrateId};
59use hir_expand::{ 59use hir_expand::{
60 ast_id_map::FileAstId, 60 ast_id_map::FileAstId,
61 eager::{expand_eager_macro, ErrorEmitted}, 61 eager::{expand_eager_macro, ErrorEmitted, ErrorSink},
62 hygiene::Hygiene, 62 hygiene::Hygiene,
63 AstId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 63 AstId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
64}; 64};
@@ -583,7 +583,7 @@ pub trait AsMacroCall {
583 krate: CrateId, 583 krate: CrateId,
584 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 584 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
585 ) -> Option<MacroCallId> { 585 ) -> Option<MacroCallId> {
586 self.as_call_id_with_errors(db, krate, resolver, &mut |_| ()) 586 self.as_call_id_with_errors(db, krate, resolver, &mut |_| ()).ok()?.ok()
587 } 587 }
588 588
589 fn as_call_id_with_errors( 589 fn as_call_id_with_errors(
@@ -592,7 +592,7 @@ pub trait AsMacroCall {
592 krate: CrateId, 592 krate: CrateId,
593 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 593 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
594 error_sink: &mut dyn FnMut(mbe::ExpandError), 594 error_sink: &mut dyn FnMut(mbe::ExpandError),
595 ) -> Option<MacroCallId>; 595 ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro>;
596} 596}
597 597
598impl AsMacroCall for InFile<&ast::MacroCall> { 598impl AsMacroCall for InFile<&ast::MacroCall> {
@@ -601,25 +601,28 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
601 db: &dyn db::DefDatabase, 601 db: &dyn db::DefDatabase,
602 krate: CrateId, 602 krate: CrateId,
603 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 603 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
604 error_sink: &mut dyn FnMut(mbe::ExpandError), 604 mut error_sink: &mut dyn FnMut(mbe::ExpandError),
605 ) -> Option<MacroCallId> { 605 ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
606 let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value)); 606 let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
607 let h = Hygiene::new(db.upcast(), self.file_id); 607 let h = Hygiene::new(db.upcast(), self.file_id);
608 let path = self.value.path().and_then(|path| path::ModPath::from_src(path, &h)); 608 let path = self.value.path().and_then(|path| path::ModPath::from_src(path, &h));
609 609
610 if path.is_none() { 610 let path = match error_sink
611 error_sink(mbe::ExpandError::Other("malformed macro invocation".into())); 611 .option(path, || mbe::ExpandError::Other("malformed macro invocation".into()))
612 } 612 {
613 Ok(path) => path,
614 Err(error) => {
615 return Ok(Err(error));
616 }
617 };
613 618
614 macro_call_as_call_id( 619 macro_call_as_call_id(
615 &AstIdWithPath::new(ast_id.file_id, ast_id.value, path?), 620 &AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
616 db, 621 db,
617 krate, 622 krate,
618 resolver, 623 resolver,
619 error_sink, 624 error_sink,
620 ) 625 )
621 .ok()?
622 .ok()
623 } 626 }
624} 627}
625 628
@@ -636,7 +639,7 @@ impl<T: ast::AstNode> AstIdWithPath<T> {
636 } 639 }
637} 640}
638 641
639struct UnresolvedMacro; 642pub struct UnresolvedMacro;
640 643
641fn macro_call_as_call_id( 644fn macro_call_as_call_id(
642 call: &AstIdWithPath<ast::MacroCall>, 645 call: &AstIdWithPath<ast::MacroCall>,