Why do I get an error when I try to implement a trait for a structure from the library? Why was it done this way? Wouldn't it be better to remove this restriction?
You haven't provided enough information to answer your question. You need to provide:
- What error you got (full output from terminal, not just the cut down error from an IDE).
- Example code that reproduces the error (linking a working example from play.rust-lang.org is preferred).
Additionally, it sounds like your question would fit better on users.rust-lang.org (the internals forum is for development of rustc itself, not for general support questions).
The structure and features are inside the library:
extern crate rust_tcp_sever;
pub use rust_tcp_sever::*;
fn main() { }
impl CleanControl for HttpServer {
#[inline]
// Function for working with Stream.
fn work(stream: &TcpStream) {
for _ in 0..3 {
println!("{}", CleanServer::read(stream).unwrap());
CleanServer::write(stream, "qwe");
}
}
}
And error:
error[E0117]: only traits defined in the current crate can be implemented for types defined outside
of the crate
--> src\main.rs:6:1
|
6 | impl CleanControl for HttpServer {
| ^^^^^^^^^^^^^^^^^^^^^^----------
| | |
| | `rust_tcp_sever::HttpServer` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
For more information about this error, try `rustc --explain E0117`.
That would be the orphan rule:
❯ rustc --explain E0117
Only traits defined in the current crate can be implemented for arbitrary types.
Erroneous code example:
impl Drop for u32 {}
This error indicates a violation of one of Rust's orphan rules for trait implementations. The rule prohibits any implementation of a
foreign trait (a trait defined in another crate) where
* the type that is implementing the trait is foreign
* all of the parameters being passed to the trait (if there are any) are also foreign.
To avoid this kind of error, ensure that at least one local type is referenced by the impl:
pub struct Foo; // you define your type in your crate
impl Drop for Foo { // and you can implement the trait on it!
// code of trait implementation here
}
impl From<Foo> for i32 { // or you use a type from your crate as
// a type parameter
fn from(i: Foo) -> i32 {
0
}
}
Alternatively, define a trait locally and implement that instead:
trait Bar {
fn get(&self) -> usize;
}
impl Bar for u32 {
fn get(&self) -> usize { 0 }
}
For information on the design of the orphan rules, see RFC 1023.
There are some soundness reasons for this (what if there are two colliding implementations of a trait for a type in two different crates? Which one should be used?). Though there have been discussions about possible ways to relax the rules (most recently only for binary crates) and possible ways around it. The easiest workaround is to use a wrapper type that you define in your own crate.
EDIT: The most recent discussion about this seems to be Limited Opt Out of Orphan Rule