Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More precise proc-macro errors #12514

Merged
merged 1 commit into from
Jun 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
)
}
Expand All @@ -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())
Expand Down
11 changes: 8 additions & 3 deletions crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
}
3 changes: 2 additions & 1 deletion crates/ide-diagnostics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down