Skip to content

Commit 861e474

Browse files
committed
update: make each trait_impl_reduntant_assoc_item into individual diagnostic
1 parent 5d84edd commit 861e474

File tree

5 files changed

+91
-75
lines changed

5 files changed

+91
-75
lines changed

crates/hir/src/diagnostics.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hir_def::path::ModPath;
1212
use hir_expand::{name::Name, HirFileId, InFile};
1313
use syntax::{ast, AstPtr, SyntaxError, SyntaxNodePtr, TextRange};
1414

15-
use crate::{AssocItem, Field, Local, MacroKind, Type};
15+
use crate::{AssocItem, Field, Local, MacroKind, Trait, Type};
1616

1717
macro_rules! diagnostics {
1818
($($diag:ident,)*) => {
@@ -55,7 +55,7 @@ diagnostics![
5555
ReplaceFilterMapNextWithFindMap,
5656
TraitImplIncorrectSafety,
5757
TraitImplMissingAssocItems,
58-
TraitImplReduntantAssocItems,
58+
TraitImplRedundantAssocItems,
5959
TraitImplOrphan,
6060
TypedHole,
6161
TypeMismatch,
@@ -313,8 +313,8 @@ pub struct TraitImplMissingAssocItems {
313313
}
314314

315315
#[derive(Debug, PartialEq, Eq)]
316-
pub struct TraitImplReduntantAssocItems {
316+
pub struct TraitImplRedundantAssocItems {
317317
pub file_id: HirFileId,
318-
pub impl_: AstPtr<ast::Impl>,
319-
pub reduntant: Vec<(Name, AssocItem)>,
320-
}
318+
pub trait_: Trait,
319+
pub assoc_item: (Name, AssocItem),
320+
}

crates/hir/src/lib.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -693,20 +693,20 @@ impl Module {
693693
},
694694
));
695695

696-
let reduntant: Vec<_> = impl_assoc_items_scratch.iter()
697-
.filter(|(id, name)| {
698-
!required_items.clone().any(|(impl_name, impl_item)| {
699-
discriminant(impl_item) == discriminant(id) && impl_name == name
696+
let redundant = impl_assoc_items_scratch
697+
.iter()
698+
.filter(|(id, name)| {
699+
!items.iter().any(|(impl_name, impl_item)| {
700+
discriminant(impl_item) == discriminant(id) && impl_name == name
701+
})
700702
})
701-
})
702-
.map(|(item, name)| (name.clone(), AssocItem::from(*item)))
703-
.collect();
704-
if !reduntant.is_empty() {
703+
.map(|(item, name)| (name.clone(), AssocItem::from(*item)));
704+
for (name, assoc_item) in redundant {
705705
acc.push(
706-
TraitImplReduntantAssocItems {
707-
impl_: ast_id_map.get(node.ast_id()),
706+
TraitImplRedundantAssocItems {
707+
trait_,
708708
file_id,
709-
reduntant,
709+
assoc_item: (name, assoc_item),
710710
}
711711
.into(),
712712
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use hir::{db::ExpandDatabase, Const, Function, HasSource, TypeAlias};
2+
3+
use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
4+
5+
// Diagnostic: trait-impl-redundant-assoc_item
6+
//
7+
// Diagnoses redundant trait items in a trait impl.
8+
pub(crate) fn trait_impl_redundant_assoc_item(
9+
ctx: &DiagnosticsContext<'_>,
10+
d: &hir::TraitImplRedundantAssocItems,
11+
) -> Diagnostic {
12+
let name = d.assoc_item.0.clone();
13+
let assoc_item = d.assoc_item.1;
14+
let db = ctx.sema.db;
15+
16+
let range = db.parse_or_expand(d.file_id).text_range();
17+
let trait_name = d.trait_.name(db).to_smol_str();
18+
19+
let (redundant_item_name, diagnostic_range) = match assoc_item {
20+
hir::AssocItem::Function(id) => (
21+
format!("`fn {}`", name.display(db)),
22+
Function::from(id).source(db).map(|it| it.syntax().value.text_range()).unwrap_or(range),
23+
),
24+
hir::AssocItem::Const(id) => (
25+
format!("`const {}`", name.display(db)),
26+
Const::from(id).source(db).map(|it| it.syntax().value.text_range()).unwrap_or(range),
27+
),
28+
hir::AssocItem::TypeAlias(id) => (
29+
format!("`type {}`", name.display(db)),
30+
TypeAlias::from(id)
31+
.source(db)
32+
.map(|it| it.syntax().value.text_range())
33+
.unwrap_or(range),
34+
),
35+
};
36+
37+
Diagnostic::new(
38+
DiagnosticCode::RustcHardError("E0407"),
39+
format!("{redundant_item_name} is not a member of trait `{trait_name}`"),
40+
diagnostic_range,
41+
)
42+
}
43+
44+
#[cfg(test)]
45+
mod tests {
46+
use crate::tests::check_diagnostics;
47+
48+
#[test]
49+
fn trait_with_default_value() {
50+
check_diagnostics(
51+
r#"
52+
trait Marker {
53+
const FLAG: bool = false;
54+
fn boo();
55+
fn foo () {}
56+
}
57+
struct Foo;
58+
impl Marker for Foo {
59+
type T = i32;
60+
//^^^^^^^^^^^^^ error: `type T` is not a member of trait `Marker`
61+
62+
const FLAG: bool = true;
63+
64+
fn bar() {}
65+
//^^^^^^^^^^^ error: `fn bar` is not a member of trait `Marker`
66+
67+
fn boo() {}
68+
}
69+
"#,
70+
)
71+
}
72+
}

crates/ide-diagnostics/src/handlers/trait_impl_reduntant_assoc_item.rs

-56
This file was deleted.

crates/ide-diagnostics/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ mod handlers {
4747
pub(crate) mod trait_impl_orphan;
4848
pub(crate) mod trait_impl_incorrect_safety;
4949
pub(crate) mod trait_impl_missing_assoc_item;
50-
pub(crate) mod trait_impl_reduntant_assoc_item;
50+
pub(crate) mod trait_impl_redundant_assoc_item;
5151
pub(crate) mod typed_hole;
5252
pub(crate) mod type_mismatch;
5353
pub(crate) mod unimplemented_builtin_macro;
@@ -365,7 +365,7 @@ pub fn diagnostics(
365365
AnyDiagnostic::ReplaceFilterMapNextWithFindMap(d) => handlers::replace_filter_map_next_with_find_map::replace_filter_map_next_with_find_map(&ctx, &d),
366366
AnyDiagnostic::TraitImplIncorrectSafety(d) => handlers::trait_impl_incorrect_safety::trait_impl_incorrect_safety(&ctx, &d),
367367
AnyDiagnostic::TraitImplMissingAssocItems(d) => handlers::trait_impl_missing_assoc_item::trait_impl_missing_assoc_item(&ctx, &d),
368-
AnyDiagnostic::TraitImplReduntantAssocItems(d) => handlers::trait_impl_reduntant_assoc_item::trait_impl_reduntant_assoc_item(&ctx, &d),
368+
AnyDiagnostic::TraitImplRedundantAssocItems(d) => handlers::trait_impl_redundant_assoc_item::trait_impl_redundant_assoc_item(&ctx, &d),
369369
AnyDiagnostic::TraitImplOrphan(d) => handlers::trait_impl_orphan::trait_impl_orphan(&ctx, &d),
370370
AnyDiagnostic::TypedHole(d) => handlers::typed_hole::typed_hole(&ctx, &d),
371371
AnyDiagnostic::TypeMismatch(d) => handlers::type_mismatch::type_mismatch(&ctx, &d),

0 commit comments

Comments
 (0)