Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-diagnostics/src/handlers/incoherent_impl.rs')
-rw-r--r--crates/ide-diagnostics/src/handlers/incoherent_impl.rs77
1 files changed, 77 insertions, 0 deletions
diff --git a/crates/ide-diagnostics/src/handlers/incoherent_impl.rs b/crates/ide-diagnostics/src/handlers/incoherent_impl.rs
new file mode 100644
index 0000000000..72af9ebfcb
--- /dev/null
+++ b/crates/ide-diagnostics/src/handlers/incoherent_impl.rs
@@ -0,0 +1,77 @@
+use hir::InFile;
+
+use crate::{Diagnostic, DiagnosticsContext, Severity};
+
+// Diagnostic: incoherent-impl
+//
+// This diagnostic is triggered if the targe type of an impl is from a foreign crate.
+pub(crate) fn incoherent_impl(ctx: &DiagnosticsContext<'_>, d: &hir::IncoherentImpl) -> Diagnostic {
+ Diagnostic::new(
+ "incoherent-impl",
+ format!("cannot define inherent `impl` for foreign type"),
+ ctx.sema.diagnostics_display_range(InFile::new(d.file_id, d.impl_.clone().into())).range,
+ )
+ .severity(Severity::Error)
+}
+
+#[cfg(test)]
+mod change_case {
+ use crate::tests::check_diagnostics;
+
+ #[test]
+ fn primitive() {
+ check_diagnostics(
+ r#"
+ impl bool {}
+//^^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
+"#,
+ );
+ }
+
+ #[test]
+ fn primitive_rustc_allow_incoherent_impl() {
+ check_diagnostics(
+ r#"
+impl bool {
+ #[rustc_allow_incoherent_impl]
+ fn falsch(self) -> Self { false }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn rustc_allow_incoherent_impl() {
+ check_diagnostics(
+ r#"
+//- /lib.rs crate:foo
+#[rustc_has_incoherent_inherent_impls]
+pub struct S;
+//- /main.rs crate:main deps:foo
+impl foo::S {
+ #[rustc_allow_incoherent_impl]
+ fn func(self) {}
+}
+"#,
+ );
+ check_diagnostics(
+ r#"
+//- /lib.rs crate:foo
+pub struct S;
+//- /main.rs crate:main deps:foo
+ impl foo::S { #[rustc_allow_incoherent_impl] fn func(self) {} }
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
+"#,
+ );
+ check_diagnostics(
+ r#"
+//- /lib.rs crate:foo
+#[rustc_has_incoherent_inherent_impls]
+pub struct S;
+//- /main.rs crate:main deps:foo
+ impl foo::S { fn func(self) {} }
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
+"#,
+ );
+ }
+}