Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-diagnostics/src/lib.rs')
-rw-r--r--crates/ide-diagnostics/src/lib.rs45
1 files changed, 32 insertions, 13 deletions
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs
index 6744895f3c..6541bf6057 100644
--- a/crates/ide-diagnostics/src/lib.rs
+++ b/crates/ide-diagnostics/src/lib.rs
@@ -23,7 +23,7 @@
//! There are also a couple of ad-hoc diagnostics implemented directly here, we
//! don't yet have a great pattern for how to do them properly.
-#![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)]
+#![warn(rust_2018_idioms, unused_lifetimes)]
mod handlers {
pub(crate) mod break_outside_of_loop;
@@ -47,6 +47,7 @@ mod handlers {
pub(crate) mod trait_impl_orphan;
pub(crate) mod trait_impl_incorrect_safety;
pub(crate) mod trait_impl_missing_assoc_item;
+ pub(crate) mod trait_impl_redundant_assoc_item;
pub(crate) mod typed_hole;
pub(crate) mod type_mismatch;
pub(crate) mod unimplemented_builtin_macro;
@@ -89,7 +90,7 @@ use stdx::never;
use syntax::{
algo::find_node_at_range,
ast::{self, AstNode},
- SyntaxNode, SyntaxNodePtr, TextRange,
+ AstPtr, SyntaxNode, SyntaxNodePtr, TextRange,
};
// FIXME: Make this an enum
@@ -133,7 +134,7 @@ impl DiagnosticCode {
pub struct Diagnostic {
pub code: DiagnosticCode,
pub message: String,
- pub range: TextRange,
+ pub range: FileRange,
pub severity: Severity,
pub unused: bool,
pub experimental: bool,
@@ -143,7 +144,7 @@ pub struct Diagnostic {
}
impl Diagnostic {
- fn new(code: DiagnosticCode, message: impl Into<String>, range: TextRange) -> Diagnostic {
+ fn new(code: DiagnosticCode, message: impl Into<String>, range: FileRange) -> Diagnostic {
let message = message.into();
Diagnostic {
code,
@@ -172,7 +173,7 @@ impl Diagnostic {
node: InFile<SyntaxNodePtr>,
) -> Diagnostic {
let file_id = node.file_id;
- Diagnostic::new(code, message, ctx.sema.diagnostics_display_range(node.clone()).range)
+ Diagnostic::new(code, message, ctx.sema.diagnostics_display_range(node.clone()))
.with_main_node(node.map(|x| x.to_node(&ctx.sema.parse_or_expand(file_id))))
}
@@ -267,7 +268,7 @@ impl DiagnosticsContext<'_> {
&self,
node: &InFile<SyntaxNodePtr>,
precise_location: Option<TextRange>,
- ) -> TextRange {
+ ) -> FileRange {
let sema = &self.sema;
(|| {
let precise_location = precise_location?;
@@ -280,10 +281,11 @@ impl DiagnosticsContext<'_> {
}
})()
.unwrap_or_else(|| sema.diagnostics_display_range(node.clone()))
- .range
}
}
+/// Request diagnostics for the given [`FileId`]. The produced diagnostics may point to other files
+/// due to macros.
pub fn diagnostics(
db: &RootDatabase,
config: &DiagnosticsConfig,
@@ -300,7 +302,7 @@ pub fn diagnostics(
Diagnostic::new(
DiagnosticCode::RustcHardError("syntax-error"),
format!("Syntax Error: {err}"),
- err.range(),
+ FileRange { file_id, range: err.range() },
)
}));
@@ -363,6 +365,7 @@ pub fn diagnostics(
AnyDiagnostic::ReplaceFilterMapNextWithFindMap(d) => handlers::replace_filter_map_next_with_find_map::replace_filter_map_next_with_find_map(&ctx, &d),
AnyDiagnostic::TraitImplIncorrectSafety(d) => handlers::trait_impl_incorrect_safety::trait_impl_incorrect_safety(&ctx, &d),
AnyDiagnostic::TraitImplMissingAssocItems(d) => handlers::trait_impl_missing_assoc_item::trait_impl_missing_assoc_item(&ctx, &d),
+ AnyDiagnostic::TraitImplRedundantAssocItems(d) => handlers::trait_impl_redundant_assoc_item::trait_impl_redundant_assoc_item(&ctx, &d),
AnyDiagnostic::TraitImplOrphan(d) => handlers::trait_impl_orphan::trait_impl_orphan(&ctx, &d),
AnyDiagnostic::TypedHole(d) => handlers::typed_hole::typed_hole(&ctx, &d),
AnyDiagnostic::TypeMismatch(d) => handlers::type_mismatch::type_mismatch(&ctx, &d),
@@ -569,12 +572,28 @@ fn adjusted_display_range<N: AstNode>(
ctx: &DiagnosticsContext<'_>,
diag_ptr: InFile<SyntaxNodePtr>,
adj: &dyn Fn(N) -> Option<TextRange>,
-) -> TextRange {
+) -> FileRange {
let FileRange { file_id, range } = ctx.sema.diagnostics_display_range(diag_ptr);
let source_file = ctx.sema.db.parse(file_id);
- find_node_at_range::<N>(&source_file.syntax_node(), range)
- .filter(|it| it.syntax().text_range() == range)
- .and_then(adj)
- .unwrap_or(range)
+ FileRange {
+ file_id,
+ range: find_node_at_range::<N>(&source_file.syntax_node(), range)
+ .filter(|it| it.syntax().text_range() == range)
+ .and_then(adj)
+ .unwrap_or(range),
+ }
+}
+
+// FIXME Replace the one above with this one?
+fn adjusted_display_range_new<N: AstNode>(
+ ctx: &DiagnosticsContext<'_>,
+ diag_ptr: InFile<AstPtr<N>>,
+ adj: &dyn Fn(N) -> Option<TextRange>,
+) -> FileRange {
+ let source_file = ctx.sema.parse_or_expand(diag_ptr.file_id);
+ let node = diag_ptr.value.to_node(&source_file);
+ diag_ptr
+ .with_value(adj(node).unwrap_or_else(|| diag_ptr.value.text_range()))
+ .original_node_file_range_rooted(ctx.sema.db)
}