use hir::InFile; use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext}; // Diagnostic: trait-impl-orphan // // Only traits defined in the current crate can be implemented for arbitrary types pub(crate) fn trait_impl_orphan( ctx: &DiagnosticsContext<'_>, d: &hir::TraitImplOrphan, ) -> Diagnostic { Diagnostic::new_with_syntax_node_ptr( ctx, DiagnosticCode::RustcHardError("E0117"), "only traits defined in the current crate can be implemented for arbitrary types" .to_owned(), InFile::new(d.file_id, d.impl_.into()), ) } #[cfg(test)] mod tests { use crate::tests::check_diagnostics; #[test] fn simple() { check_diagnostics( r#" //- /foo.rs crate:foo pub trait Foo {} //- /bar.rs crate:bar pub struct Bar; //- /main.rs crate:main deps:foo,bar struct LocalType; trait LocalTrait {} impl foo::Foo for bar::Bar {} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types impl foo::Foo for LocalType {} impl LocalTrait for bar::Bar {} "#, ); } #[test] fn generics() { check_diagnostics( r#" //- /foo.rs crate:foo pub trait Foo {} //- /bar.rs crate:bar pub struct Bar(T); //- /main.rs crate:main deps:foo,bar struct LocalType; trait LocalTrait {} impl foo::Foo for bar::Bar {} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types impl foo::Foo for bar::Bar> {} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types impl foo::Foo> for bar::Bar {} impl foo::Foo>> for bar::Bar> {} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types "#, ); } #[test] fn fundamental() { check_diagnostics( r#" //- /foo.rs crate:foo pub trait Foo {} //- /bar.rs crate:bar pub struct Bar(T); #[lang = "owned_box"] #[fundamental] pub struct Box(T); //- /main.rs crate:main deps:foo,bar struct LocalType; impl foo::Foo for bar::Box {} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only traits defined in the current crate can be implemented for arbitrary types impl foo::Foo for &LocalType {} impl foo::Foo for bar::Box {} "#, ); } #[test] fn dyn_object() { check_diagnostics( r#" //- /foo.rs crate:foo pub trait Foo {} //- /bar.rs crate:bar pub struct Bar; //- /main.rs crate:main deps:foo,bar trait LocalTrait {} impl foo::Foo for dyn LocalTrait {} impl foo::Foo for Bar {} "#, ); } #[test] fn twice_fundamental() { check_diagnostics( r#" //- /foo.rs crate:foo pub trait Trait {} //- /bar.rs crate:bar deps:foo struct Foo; impl foo::Trait for &&Foo {} "#, ); } }