about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-06-12 17:27:41 +0000
committerbors <bors@rust-lang.org>2022-06-12 17:27:41 +0000
commit6c65edfd8ff171f7dfd43c2171eb2f8e07864406 (patch)
tree217be38032794efcde4a375ac82a5fbdd2817e9d
parent4f2a67b26feba72dd9ae0ad0d36a2b36652cc68c (diff)
parent0e4eb647f6f1794d1a77371b2bbb48d2401007b9 (diff)
downloadrust-6c65edfd8ff171f7dfd43c2171eb2f8e07864406.tar.gz
rust-6c65edfd8ff171f7dfd43c2171eb2f8e07864406.zip
Auto merge of #12514 - Veykril:proc-mac-err, r=Veykril
More precise proc-macro errors
-rw-r--r--crates/hir/src/lib.rs29
-rw-r--r--crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs11
-rw-r--r--crates/ide-diagnostics/src/lib.rs3
-rw-r--r--crates/rust-analyzer/src/config.rs3
4 files changed, 31 insertions, 15 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 3f62a2cd334..193ef904de9 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -628,35 +628,42 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
         }
 
         DefDiagnosticKind::UnresolvedProcMacro { ast } => {
-            let mut precise_location = None;
-            let (node, macro_name) = match ast {
+            let (node, precise_location, macro_name) = match ast {
                 MacroCallKind::FnLike { ast_id, .. } => {
                     let node = ast_id.to_node(db.upcast());
-                    (ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))), None)
+                    (
+                        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()),
+                    )
                 }
                 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.attrs().nth(*derive_attr_index as usize)?;
-                        derive_attr
+                        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![,])
+                            .group_by(|t| t.kind() == T![,]);
+                        let (_, mut group) = group_by
                             .into_iter()
                             .filter(|&(comma, _)| !comma)
-                            .nth(*derive_index as usize)
-                            .and_then(|(_, mut g)| g.find(|t| t.kind() == T![ident]))
+                            .nth(*derive_index as usize)?;
+                        group.find(|t| t.kind() == T![ident])
                     })();
-                    precise_location = token.as_ref().map(|tok| tok.text_range());
                     (
                         ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
+                        token.as_ref().map(|tok| tok.text_range()),
                         token.as_ref().map(ToString::to_string),
                     )
                 }
@@ -667,8 +674,10 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
                         .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())
diff --git a/crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs b/crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs
index fde1d1323f5..fea3a0e8323 100644
--- a/crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs
+++ b/crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs
@@ -8,20 +8,25 @@ use crate::{Diagnostic, DiagnosticsContext, Severity};
 //
 // If you are seeing a lot of "proc macro not expanded" warnings, you can add this option to the
 // `rust-analyzer.diagnostics.disabled` list to prevent them from showing. Alternatively you can
-// enable support for procedural macros (see `rust-analyzer.procMacro.enable`).
+// enable support for procedural macros (see `rust-analyzer.procMacro.attributes.enable`).
 pub(crate) fn unresolved_proc_macro(
     ctx: &DiagnosticsContext<'_>,
     d: &hir::UnresolvedProcMacro,
+    attr_proc_macros_enabled: bool,
 ) -> Diagnostic {
     // Use more accurate position if available.
     let display_range = d
         .precise_location
         .unwrap_or_else(|| ctx.sema.diagnostics_display_range(d.node.clone()).range);
-    // FIXME: it would be nice to tell the user whether proc macros are currently disabled
     let message = match &d.macro_name {
         Some(name) => format!("proc macro `{}` not expanded", name),
         None => "proc macro not expanded".to_string(),
     };
+    let message = format!(
+        "{message}{}",
+        if attr_proc_macros_enabled { "" } else { " (attribute macro expansion is disabled)" }
+    );
 
-    Diagnostic::new("unresolved-proc-macro", message, display_range).severity(Severity::WeakWarning)
+    Diagnostic::new("unresolved-proc-macro", message, display_range)
+        .severity(if attr_proc_macros_enabled { Severity::Error } else { Severity::WeakWarning })
 }
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs
index 1d4ea461d08..1cbe8ad72bb 100644
--- a/crates/ide-diagnostics/src/lib.rs
+++ b/crates/ide-diagnostics/src/lib.rs
@@ -139,6 +139,7 @@ impl Default for ExprFillDefaultMode {
 
 #[derive(Default, Debug, Clone)]
 pub struct DiagnosticsConfig {
+    pub attr_proc_macros_enabled: bool,
     pub disable_experimental: bool,
     pub disabled: FxHashSet<String>,
     pub expr_fill_default: ExprFillDefaultMode,
@@ -204,7 +205,7 @@ pub fn diagnostics(
             AnyDiagnostic::UnresolvedImport(d) => handlers::unresolved_import::unresolved_import(&ctx, &d),
             AnyDiagnostic::UnresolvedMacroCall(d) => handlers::unresolved_macro_call::unresolved_macro_call(&ctx, &d),
             AnyDiagnostic::UnresolvedModule(d) => handlers::unresolved_module::unresolved_module(&ctx, &d),
-            AnyDiagnostic::UnresolvedProcMacro(d) => handlers::unresolved_proc_macro::unresolved_proc_macro(&ctx, &d),
+            AnyDiagnostic::UnresolvedProcMacro(d) => handlers::unresolved_proc_macro::unresolved_proc_macro(&ctx, &d, config.attr_proc_macros_enabled),
             AnyDiagnostic::InvalidDeriveTarget(d) => handlers::invalid_derive_target::invalid_derive_target(&ctx, &d),
 
             AnyDiagnostic::InactiveCode(d) => match handlers::inactive_code::inactive_code(&ctx, &d) {
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 9fd19589999..fcc4cbebc5e 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -856,6 +856,7 @@ impl Config {
 
     pub fn diagnostics(&self) -> DiagnosticsConfig {
         DiagnosticsConfig {
+            attr_proc_macros_enabled: self.expand_proc_attr_macros(),
             disable_experimental: !self.data.diagnostics_experimental_enable,
             disabled: self.data.diagnostics_disabled.clone(),
             expr_fill_default: match self.data.assist_expressionFillDefault {
@@ -893,7 +894,7 @@ impl Config {
     }
 
     pub fn expand_proc_attr_macros(&self) -> bool {
-        self.data.procMacro_attributes_enable
+        self.data.procMacro_enable && self.data.procMacro_attributes_enable
     }
 
     pub fn files(&self) -> FilesConfig {