Skip to main content

ide_diagnostics/handlers/
trait_impl_missing_assoc_item.rs

1use hir::InFile;
2use itertools::Itertools;
3use syntax::{AstNode, ast};
4
5use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_display_range};
6
7// Diagnostic: trait-impl-missing-assoc_item
8//
9// Diagnoses missing trait items in a trait impl.
10pub(crate) fn trait_impl_missing_assoc_item(
11    ctx: &DiagnosticsContext<'_, '_>,
12    d: &hir::TraitImplMissingAssocItems,
13) -> Diagnostic {
14    let missing = d.missing.iter().format_with(", ", |(name, item), f| {
15        f(&match *item {
16            hir::AssocItem::Function(_) => "`fn ",
17            hir::AssocItem::Const(_) => "`const ",
18            hir::AssocItem::TypeAlias(_) => "`type ",
19        })?;
20        f(&name.display(ctx.sema.db, ctx.edition))?;
21        f(&"`")
22    });
23    Diagnostic::new(
24        DiagnosticCode::RustcHardError("E0046"),
25        format!("not all trait items implemented, missing: {missing}"),
26        adjusted_display_range::<ast::Impl>(
27            ctx,
28            InFile { file_id: d.file_id, value: d.impl_ },
29            &|impl_| impl_.trait_().map(|t| t.syntax().text_range()),
30        ),
31    )
32    .stable()
33}
34
35#[cfg(test)]
36mod tests {
37    use crate::tests::check_diagnostics;
38
39    #[test]
40    fn trait_with_default_value() {
41        check_diagnostics(
42            r#"
43trait Marker {
44    const FLAG: bool = false;
45}
46struct Foo;
47impl Marker for Foo {}
48            "#,
49        )
50    }
51
52    #[test]
53    fn simple() {
54        check_diagnostics(
55            r#"
56trait Trait {
57    const C: ();
58    type T;
59    fn f();
60}
61
62impl Trait for () {
63    const C: () = ();
64    type T = ();
65    fn f() {}
66}
67
68impl Trait for () {
69   //^^^^^ error: not all trait items implemented, missing: `const C`
70    type T = ();
71    fn f() {}
72}
73
74impl Trait for () {
75   //^^^^^ error: not all trait items implemented, missing: `const C`, `type T`, `fn f`
76}
77
78"#,
79        );
80    }
81
82    #[test]
83    fn default() {
84        check_diagnostics(
85            r#"
86trait Trait {
87    const C: ();
88    type T = ();
89    fn f() {}
90}
91
92impl Trait for () {
93    const C: () = ();
94    type T = ();
95    fn f() {}
96}
97
98impl Trait for () {
99   //^^^^^ error: not all trait items implemented, missing: `const C`
100    type T = ();
101    fn f() {}
102}
103
104impl Trait for () {
105   //^^^^^ error: not all trait items implemented, missing: `const C`
106     type T = ();
107 }
108
109impl Trait for () {
110   //^^^^^ error: not all trait items implemented, missing: `const C`
111}
112
113"#,
114        );
115    }
116
117    #[test]
118    fn negative_impl() {
119        check_diagnostics(
120            r#"
121trait Trait {
122    fn item();
123}
124
125// Negative impls don't require any items (in fact, the forbid providing any)
126impl !Trait for () {}
127"#,
128        )
129    }
130
131    #[test]
132    fn impl_sized_for_unsized() {
133        check_diagnostics(
134            r#"
135//- minicore: sized
136trait Trait {
137    type Item
138    where
139        Self: Sized;
140
141    fn item()
142    where
143        Self: Sized;
144}
145
146trait OtherTrait {}
147
148impl Trait for () {
149    type Item = ();
150    fn item() {}
151}
152impl Trait for Adt<i32> {}
153   //^^^^^ error: not all trait items implemented, missing: `type Item`, `fn item`
154
155// Items with Self: Sized bound not required to be implemented for unsized types.
156impl Trait for str {}
157impl Trait for dyn OtherTrait {}
158impl Trait for Adt<[i32]> {}
159impl Trait for Slice<i32> {}
160impl Trait for (str,) {}
161
162struct Adt<T>(i32, T);
163struct Slice<T>([T]);
164 "#,
165        )
166    }
167
168    #[test]
169    fn no_false_positive_on_specialization() {
170        check_diagnostics(
171            r#"
172#![feature(specialization)]
173
174pub trait Foo {
175    fn foo();
176}
177
178impl<T> Foo for T {
179    default fn foo() {}
180}
181impl Foo for bool {}
182"#,
183        );
184    }
185}