ide_diagnostics/handlers/
incoherent_impl.rs1use hir::InFile;
2use syntax::{AstNode, TextRange};
3
4use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_display_range};
5
6pub(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}