ide_diagnostics/handlers/
trait_impl_missing_assoc_item.rs1use hir::InFile;
2use itertools::Itertools;
3use syntax::{AstNode, ast};
4
5use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_display_range};
6
7pub(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}
152
153// Items with Self: Sized bound not required to be implemented for unsized types.
154impl Trait for str {}
155impl Trait for dyn OtherTrait {}
156 "#,
157 )
158 }
159}