I want to implement the std::io::Read
trait for my custom trait. This is my try:-
use std::io::Read;
trait Bar {
fn foo(&self);
}
impl<T: Bar> Read for T {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
Ok(0)
}
}
Error:-
Compiling playground v0.0.1 (/playground)
error[E0119]: conflicting implementations of trait `std::io::Read` for type `&mut _`:
--> src/lib.rs:7:1
|
7 | impl<T: Bar> Read for T {
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `std`:
- impl<R> std::io::Read for &mut R
where R: std::io::Read, R: ?Sized;
= note: downstream crates may implement trait `Bar` for type `&mut _`
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> src/lib.rs:7:6
|
7 | impl<T: Bar> Read for T {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors
This is currently not allowed, as explained in the note:
= note: downstream crates may implement trait `Bar` for type `&mut _`
You are trying to implement Read
for all types that implement Bar
, but you can't guarantee that all implementations of Bar
(present or future) don't - or won't - implement Read
already. For example, a user of your crate might implement Bar
for one of their own types.
Another problem is explained in the second error:
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
You are only allowed to implement a trait if either the trait is defined in your crate (Read
is not) or if the type that you are implementing it for is defined in your crate. That means you can't implement Read
for T
, because T
is literally any type, including arbitrary types from other crates.
A workaround for this would be to add a function that exposes a Read
implementation from an arbitrary T: Bar
:
use std::io::Read;
trait Bar {
fn foo(&self);
fn as_reader(&self) -> BarRead<&Self> {
BarRead(self)
}
}
pub struct BarRead<T>(T);
impl<T: Bar> Read for BarRead<T> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
Ok(0)
}
}