internal: refactor unresolved proc macro diagnostic

This commit is contained in:
Aleksey Kladov 2021-06-13 17:51:44 +03:00
parent f85e383b94
commit 1e4aaee7bb
5 changed files with 59 additions and 61 deletions

View File

@ -36,6 +36,7 @@ diagnostics![
UnresolvedExternCrate,
UnresolvedImport,
UnresolvedMacroCall,
UnresolvedProcMacro,
MissingFields,
InactiveCode,
];
@ -69,46 +70,15 @@ pub struct InactiveCode {
pub opts: CfgOptions,
}
// Diagnostic: unresolved-proc-macro
//
// This diagnostic is shown when a procedural macro can not be found. This usually means that
// procedural macro support is simply disabled (and hence is only a weak hint instead of an error),
// but can also indicate project setup problems.
//
// 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`).
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct UnresolvedProcMacro {
pub file: HirFileId,
pub node: SyntaxNodePtr,
pub node: InFile<SyntaxNodePtr>,
/// If the diagnostic can be pinpointed more accurately than via `node`, this is the `TextRange`
/// to use instead.
pub precise_location: Option<TextRange>,
pub macro_name: Option<String>,
}
impl Diagnostic for UnresolvedProcMacro {
fn code(&self) -> DiagnosticCode {
DiagnosticCode("unresolved-proc-macro")
}
fn message(&self) -> String {
match &self.macro_name {
Some(name) => format!("proc macro `{}` not expanded", name),
None => "proc macro not expanded".to_string(),
}
}
fn display_source(&self) -> InFile<SyntaxNodePtr> {
InFile::new(self.file, self.node.clone())
}
fn as_any(&self) -> &(dyn Any + Send + 'static) {
self
}
}
// Diagnostic: macro-error
//
// This diagnostic is shown for macro expansion errors.

View File

@ -518,10 +518,10 @@ impl Module {
DefDiagnosticKind::UnresolvedProcMacro { ast } => {
let mut precise_location = None;
let (file, ast, name) = match ast {
let (node, name) = match ast {
MacroCallKind::FnLike { ast_id, .. } => {
let node = ast_id.to_node(db.upcast());
(ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node)), None)
(ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))), None)
}
MacroCallKind::Derive { ast_id, derive_name, .. } => {
let node = ast_id.to_node(db.upcast());
@ -554,8 +554,7 @@ impl Module {
}
(
ast_id.file_id,
SyntaxNodePtr::from(AstPtr::new(&node)),
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
Some(derive_name.clone()),
)
}
@ -566,18 +565,14 @@ impl Module {
|| panic!("cannot find attribute #{}", invoc_attr_index),
);
(
ast_id.file_id,
SyntaxNodePtr::from(AstPtr::new(&attr)),
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
Some(attr_name.clone()),
)
}
};
sink.push(UnresolvedProcMacro {
file,
node: ast,
precise_location,
macro_name: name,
});
acc.push(
UnresolvedProcMacro { node, precise_location, macro_name: name }.into(),
);
}
DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
@ -1056,12 +1051,14 @@ impl Function {
node: node.value.clone().into(),
message: message.to_string(),
}),
BodyDiagnostic::UnresolvedProcMacro { node } => sink.push(UnresolvedProcMacro {
file: node.file_id,
node: node.value.clone().into(),
precise_location: None,
macro_name: None,
}),
BodyDiagnostic::UnresolvedProcMacro { node } => acc.push(
UnresolvedProcMacro {
node: node.clone().map(|it| it.into()),
precise_location: None,
macro_name: None,
}
.into(),
),
BodyDiagnostic::UnresolvedMacroCall { node, path } => acc.push(
UnresolvedMacroCall { macro_call: node.clone(), path: path.clone() }.into(),
),

View File

@ -8,6 +8,7 @@ mod unresolved_module;
mod unresolved_extern_crate;
mod unresolved_import;
mod unresolved_macro_call;
mod unresolved_proc_macro;
mod inactive_code;
mod missing_fields;
@ -68,6 +69,11 @@ impl Diagnostic {
self
}
fn severity(mut self, severity: Severity) -> Diagnostic {
self.severity = severity;
self
}
fn error(range: TextRange, message: String) -> Self {
Self {
message,
@ -178,16 +184,6 @@ pub(crate) fn diagnostics(
.with_code(Some(d.code())),
);
})
.on::<hir::diagnostics::UnresolvedProcMacro, _>(|d| {
// Use more accurate position if available.
let display_range = d
.precise_location
.unwrap_or_else(|| sema.diagnostics_display_range(d.display_source()).range);
// FIXME: it would be nice to tell the user whether proc macros are currently disabled
res.borrow_mut()
.push(Diagnostic::hint(display_range, d.message()).with_code(Some(d.code())));
})
.on::<hir::diagnostics::UnimplementedBuiltinMacro, _>(|d| {
let display_range = sema.diagnostics_display_range(d.display_source()).range;
res.borrow_mut()
@ -231,6 +227,7 @@ pub(crate) fn diagnostics(
AnyDiagnostic::UnresolvedExternCrate(d) => unresolved_extern_crate::unresolved_extern_crate(&ctx, &d),
AnyDiagnostic::UnresolvedImport(d) => unresolved_import::unresolved_import(&ctx, &d),
AnyDiagnostic::UnresolvedMacroCall(d) => unresolved_macro_call::unresolved_macro_call(&ctx, &d),
AnyDiagnostic::UnresolvedProcMacro(d) => unresolved_proc_macro::unresolved_proc_macro(&ctx, &d),
AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d),
AnyDiagnostic::InactiveCode(d) => match inactive_code::inactive_code(&ctx, &d) {

View File

@ -1,7 +1,10 @@
use cfg::DnfExpr;
use stdx::format_to;
use crate::diagnostics::{Diagnostic, DiagnosticsContext};
use crate::{
diagnostics::{Diagnostic, DiagnosticsContext},
Severity,
};
// Diagnostic: inactive-code
//
@ -27,6 +30,7 @@ pub(super) fn inactive_code(
message,
ctx.sema.diagnostics_display_range(d.node.clone()).range,
)
.severity(Severity::WeakWarning)
.with_unused(true);
Some(res)
}

View File

@ -0,0 +1,30 @@
use crate::{
diagnostics::{Diagnostic, DiagnosticsContext},
Severity,
};
// Diagnostic: unresolved-proc-macro
//
// This diagnostic is shown when a procedural macro can not be found. This usually means that
// procedural macro support is simply disabled (and hence is only a weak hint instead of an error),
// but can also indicate project setup problems.
//
// 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`).
pub(super) fn unresolved_proc_macro(
ctx: &DiagnosticsContext<'_>,
d: &hir::UnresolvedProcMacro,
) -> 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(),
};
Diagnostic::new("unresolved-proc-macro", message, display_range).severity(Severity::WeakWarning)
}