ide_diagnostics/handlers/
incoherent_impl.rs

1use hir::InFile;
2use syntax::{AstNode, TextRange};
3
4use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_display_range};
5
6// Diagnostic: incoherent-impl
7//
8// This diagnostic is triggered if the targe type of an impl is from a foreign crate.
9pub(crate) fn incoherent_impl(ctx: &DiagnosticsContext<'_>, d: &hir::IncoherentImpl) -> Diagnostic {
10    let display_range = adjusted_display_range(ctx, InFile::new(d.file_id, d.impl_), &|node| {
11        Some(TextRange::new(
12            node.syntax().text_range().start(),
13            node.self_ty()?.syntax().text_range().end(),
14        ))
15    });
16
17    Diagnostic::new(
18        DiagnosticCode::RustcHardError("E0210"),
19        "cannot define inherent `impl` for foreign type".to_owned(),
20        display_range,
21    )
22    .stable()
23}
24
25#[cfg(test)]
26mod change_case {
27    use crate::tests::check_diagnostics;
28
29    #[test]
30    fn primitive() {
31        check_diagnostics(
32            r#"
33  impl bool {}
34//^^^^^^^^^ error: cannot define inherent `impl` for foreign type
35"#,
36        );
37    }
38
39    #[test]
40    fn primitive_rustc_allow_incoherent_impl() {
41        check_diagnostics(
42            r#"
43impl bool {
44    #[rustc_allow_incoherent_impl]
45    fn falsch(self) -> Self { false }
46}
47"#,
48        );
49    }
50
51    #[test]
52    fn rustc_allow_incoherent_impl() {
53        check_diagnostics(
54            r#"
55//- /lib.rs crate:foo
56#[rustc_has_incoherent_inherent_impls]
57pub struct S;
58//- /main.rs crate:main deps:foo
59impl foo::S {
60    #[rustc_allow_incoherent_impl]
61    fn func(self) {}
62}
63"#,
64        );
65        check_diagnostics(
66            r#"
67//- /lib.rs crate:foo
68pub struct S;
69//- /main.rs crate:main deps:foo
70  impl foo::S { #[rustc_allow_incoherent_impl] fn func(self) {} }
71//^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
72"#,
73        );
74        check_diagnostics(
75            r#"
76//- /lib.rs crate:foo
77#[rustc_has_incoherent_inherent_impls]
78pub struct S;
79//- /main.rs crate:main deps:foo
80  impl foo::S { fn func(self) {} }
81//^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
82"#,
83        );
84    }
85}