Skip to main content

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