ide_diagnostics/handlers/
trait_impl_orphan.rs

1use hir::InFile;
2
3use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
4
5// Diagnostic: trait-impl-orphan
6//
7// Only traits defined in the current crate can be implemented for arbitrary types
8pub(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}