ide_diagnostics/handlers/
trait_impl_orphan.rs1use hir::InFile;
2
3use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
4
5pub(crate) fn trait_impl_orphan(
9 ctx: &DiagnosticsContext<'_>,
10 d: &hir::TraitImplOrphan,
11) -> Diagnostic {
12 Diagnostic::new_with_syntax_node_ptr(
13 ctx,
14 DiagnosticCode::RustcHardError("E0117"),
15 "only traits defined in the current crate can be implemented for arbitrary types"
16 .to_owned(),
17 InFile::new(d.file_id, d.impl_.into()),
18 )
19}
20
21#[cfg(test)]
22mod tests {
23 use crate::tests::check_diagnostics;
24
25 #[test]
26 fn simple() {
27 check_diagnostics(
28 r#"
29//- /foo.rs crate:foo
30pub trait Foo {}
31//- /bar.rs crate:bar
32pub struct Bar;
33//- /main.rs crate:main deps:foo,bar
34struct LocalType;
35trait LocalTrait {}
36 impl foo::Foo for bar::Bar {}
37//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types
38impl foo::Foo for LocalType {}
39impl LocalTrait for bar::Bar {}
40"#,
41 );
42 }
43
44 #[test]
45 fn generics() {
46 check_diagnostics(
47 r#"
48//- /foo.rs crate:foo
49pub trait Foo<T> {}
50//- /bar.rs crate:bar
51pub struct Bar<T>(T);
52//- /main.rs crate:main deps:foo,bar
53struct LocalType<T>;
54trait LocalTrait<T> {}
55 impl<T> foo::Foo<T> for bar::Bar<T> {}
56//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types
57
58 impl<T> foo::Foo<T> for bar::Bar<LocalType<T>> {}
59//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types
60
61 impl<T> foo::Foo<LocalType<T>> for bar::Bar<T> {}
62
63 impl<T> foo::Foo<bar::Bar<LocalType<T>>> for bar::Bar<LocalType<T>> {}
64//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types
65"#,
66 );
67 }
68
69 #[test]
70 fn fundamental() {
71 check_diagnostics(
72 r#"
73//- /foo.rs crate:foo
74pub trait Foo<T> {}
75//- /bar.rs crate:bar
76pub struct Bar<T>(T);
77#[lang = "owned_box"]
78#[fundamental]
79pub struct Box<T>(T);
80//- /main.rs crate:main deps:foo,bar
81struct LocalType;
82 impl<T> foo::Foo<T> for bar::Box<T> {}
83//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types
84 impl<T> foo::Foo<T> for &LocalType {}
85 impl<T> foo::Foo<T> for bar::Box<LocalType> {}
86"#,
87 );
88 }
89
90 #[test]
91 fn dyn_object() {
92 check_diagnostics(
93 r#"
94//- /foo.rs crate:foo
95pub trait Foo<T> {}
96//- /bar.rs crate:bar
97pub struct Bar;
98//- /main.rs crate:main deps:foo,bar
99trait LocalTrait {}
100impl<T> foo::Foo<T> for dyn LocalTrait {}
101impl<T> foo::Foo<dyn LocalTrait> for Bar {}
102"#,
103 );
104 }
105
106 #[test]
107 fn twice_fundamental() {
108 check_diagnostics(
109 r#"
110//- /foo.rs crate:foo
111pub trait Trait {}
112//- /bar.rs crate:bar deps:foo
113struct Foo;
114impl foo::Trait for &&Foo {}
115 "#,
116 );
117 }
118}