In general case, it is not possible to implement in crate C1 a trait defined in C2 for a Type defined in crate C3, being assumed that C1, C2, C3 are different
But is there a trick to designing a trait on purpose, so that such implementations are allowed?
Since Rust 1.41, it seems that Rust’s orphan rules have been a little bit more relaxed, as explained in Into doc.
The key is to make the trait dependent on a type parameter which is defined in the implementing crate. For example, the following, crate workspace "orphan", will actually work:
orphan/ | c1/ | src/lib.rs | pub trait MyTrait<T> {
| | | fn my_task(&self);
| | | }
| |
| | Cargo.toml | [package]
| | name = "c1"
| | version = "0.0.1"
| | edition = "2021"
| | [dependencies]
|
| c2/ | src/lib.rs | pub struct MyStruct;
| |
| | Cargo.toml | [package]
| | name = "c2"
| | version = "0.0.1"
| | edition = "2021"
| | [dependencies]
|
| c3/ | src/lib.rs | use c1::MyTrait; use c2::MyStruct;
| | | pub enum MyT {}
| | | impl MyTrait<MyT> for MyStruct {
| | | fn my_task(&self) { println!("hello!"); }
| | | }
| |
| | Cargo.toml | [package]
| | name = "c3"
| | version = "0.0.1"
| | edition = "2021"
| | [dependencies]
| | c1 = { path = "../c1", version = "0.0.1" }
| | c2 = { path = "../c2", version = "0.0.1" }
|
| c4/ | src/main.rs | fn main() {
| | | use c1::MyTrait; use c2::MyStruct;
| | | #[allow(unused_imports)] use c3;
| | | MyStruct.my_task();
| | | }
| |
| | Cargo.toml | [package]
| | name = "c4"
| | version = "0.0.1"
| | edition = "2021"
| | [dependencies]
| | c1 = { path = "../c1", version = "0.0.1" }
| | c2 = { path = "../c2", version = "0.0.1" }
| | c3 = { path = "../c3", version = "0.0.1" }
|
| Cargo.toml | [workspace]
| members = [ "c1", "c2", "c3", "c4", ]
with result:
cargo run --release
Compiling c4 v0.0.1 (XXX\orphan\c4)
Finished release [optimized] target(s) in 0.26s
Running `target\release\c4.exe`
hello!
In conclusion, there is a trick to design a trait in crate c1, so there is a way in some sense to implement this trait in crate c3 for a type defined in crate c2, assuming c1 , c2, c3 are different!