Can not implement io::Read for a custom trait - rust

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)
}
}
Playground
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)
}
}

Related

Implementing ToOwned ('a -> 'static) for an enum containing Cow<'a, str> causes unmet lifetime requirement

Context
Playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=de1286b8bce0dfb840a5fc0b50df25ad
I was reading this other SO post, which was saying you can convert a struct containing a Cow to have a 'static lifetime. Based on that post, I then tried the following:
use std::borrow::Cow;
enum S<'a> {
A(Cow<'a, str>),
B(i32)
}
impl ToOwned for S<'_> {
type Owned = S<'static>;
fn to_owned(&self) -> Self::Owned {
match *self {
S::A(s) => S::A(Cow::Owned(s.clone().into_owned())),
S::B(i) => S::B(i)
}
}
}
fn main() {
let s = S::A("a".into());
let s = s.to_owned();
}
and got the following error
error: incompatible lifetime on type
--> src/main.rs:9:18
|
9 | type Owned = S<'static>;
| ^^^^^^^^^^
|
note: because this has an unmet lifetime requirement
note: the lifetime `'_` as defined here...
--> src/main.rs:8:20
|
8 | impl ToOwned for S<'_> {
| ^^
note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
Questions
How exactly are lifetimes coming into play here if I'm converting the Cow into the owned version?
What's the right approach to getting this to work?
TL;DR: You cannot implement ToOwned for that; use an inherent method.
ToOwned::Owned has a bound:
type Owned: Borrow<Self>;
So we need S<'static> to impl Borrow<S<'a>> for any 'a.
...except this impl cannot be written:
error[E0119]: conflicting implementations of trait `std::borrow::Borrow<S<'static>>` for type `S<'static>`
--> src/main.rs:19:1
|
19 | impl<'a> Borrow<S<'a>> for S<'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> Borrow<T> for T
where T: ?Sized;
...because it conflicts with the blanket implementation Borrow<T> for T where 'a is 'static.
The compiler error without this impl is an outcome of the fact that the compiler sees that there is an impl<'a> Borrow<S<'a>> for S<'static> (the abovementioned blanket implementation), it is just that it constrains 'a: 'static. And so the compiler tries to prove 'a: 'static, and fails. This is an example of the compiler being over-smart, causing a confusing error message.

Rust: Struct generic type parameter for use in Fn member signature requires named lifetime

I have a struct with function member:
struct Foo<T> {
fun: Box<dyn Fn(T)>,
}
type FooI = Foo<&mut i32>;
This doesn't work:
error[E0106]: missing lifetime specifier
--> src/main.rs:5:17
|
5 | type FooI = Foo<&mut i32>;
| ^ expected named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
5 | type FooI<'a> = Foo<&'a mut i32>;
But I don't want FooI to be parameterised for the lifetime of T, I just want instances of T to outlive the call to Foo.fun. How would I encode that?
Unfortunately what you're trying to do won't currently work with Rust. When a struct is generic over a reference that reference will have to live for at least the life of the struct. So, if you listened to the compiler it wouldn't do what you wanted:
playground link
Because of this you either have to make fun be Box<dyn Fn(&mut T)> or change your struct to be generic over anything.
struct Foo<T> {
fun: Box<dyn Fn(&mut T)>
}
type FooI = Foo<i32>;
Playground Link
I haven't seen the code in context, but this might be a good chance to use traits.

Rust trait bound by supertrait with itself as generic parameter

When working with a trait hierarchy, I got into the following problem: A trait (that is used as a trait object) should define a function that returns its own type. Of course, Self cannot be used since it would be different for each subtype. Instead, the trait should return the type of the trait object, like:
trait MySpecialTrait {
fn clone(&self) -> Box<dyn MySpecialTrait>;
}
So far, this works. But now I want to extract this functionality in its own generic supertrait to be able to write generic code that only relies on the supertrait properties, like this:
trait Cloneable<Output: ?Sized> {
fn clone(&self) -> Box<Output>;
}
trait MySpecialTrait: Cloneable<dyn MySpecialTrait> {
fn something(&self);
}
fn clone_all<T>(data: &Vec<Box<T>>) -> Vec<Box<T>>
where T: ?Sized + Cloneable<T>
{
data.iter().map(|x|x.clone()).collect()
}
But this code yields the following error:
error[E0391]: cycle detected when computing the supertraits of `MySpecialTrait`
--> src\main.rs:28:1
|
28 | trait MySpecialTrait: Cloneable<dyn MySpecialTrait> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: ...which again requires computing the supertraits of `MySpecialTrait`, completing the cycle
note: cycle used when collecting item types in top-level module
--> src\main.rs:28:1
|
28 | trait MySpecialTrait: Cloneable<dyn MySpecialTrait> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Using associated types like this does not change anything:
trait Cloneable {
type Output;
fn clone(&self) -> Box<Self::Output>;
}
trait MySpecialTrait: Cloneable<Output = dyn MySpecialTrait> {
fn something(&self);
}
Can someone explain to me why there is a cycle? I understand that in the general case of trait A: B the supertraits of B have to be known to calculate the supertraits of A, so
trait A: B {}
trait B: A {}
cannot work. But in this case, MySpecialTrait is only referenced in the generic type arguments, so why is it required to compute the supertraits of Cloneable<dyn MySpecialTrait>?
Apart from that, is there are workaround for this problem?
Edit
I do not want clone_all to work only with all concrete subtypes of Cloneable<T>, but also with all trait types, e.g. I want to call clone_all with an argument of type Vec<Box<dyn MySpecialTrait>>.

How do I get around supertrait computation cycle? [duplicate]

I have a trait Trait with an associated type Trait::Associated. I am trying to bound the trait by requiring that it be indexable by its associated type, as shown here:
use std::ops::Index;
pub trait Trait: Index<Trait::Associated> {
type Associated;
}
However, the compiler complains that the associated type is ambiguous
error[E0223]: ambiguous associated type
--> src/main.rs:3:24
|
3 | pub trait Trait: Index<Trait::Associated> {
| ^^^^^^^^^^^^^^^^^ ambiguous associated type
|
= note: specify the type using the syntax `<Type as Trait>::Associated`
I also tried referring to the associated type as Self::Associated, but then the compiler protests about a cyclic reference between the type and the trait:
error[E0391]: cyclic dependency detected
--> src/main.rs:3:1
|
3 | pub trait Trait: Index<Self::Associated> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic reference
|
note: the cycle begins when computing the supertraits of `Trait`...
--> src/main.rs:3:1
|
3 | pub trait Trait: Index<Self::Associated> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which then again requires computing the supertraits of `Trait`, completing the cycle.
Finally, I also tried explicitly implementing Index for Trait:
pub trait Trait {
type Associated;
}
impl<T: Trait> Index<T::Associated> for T {
type Output = str;
fn index(&self, associated: T::Associated) -> &'static str {
"sup"
}
}
Unfortunately that fails too:
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
--> src/main.rs:7:1
|
7 | impl<T: Trait> Index<T::Associated> for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
|
= note: only traits defined in the current crate can be implemented for a type parameter
Am I trying to do something unreasonable here? Is there a way of achieving something similar, without having to use generics?
Playground.
You are close, very close.
The Trait does not assume that any reference to Trait in its definition refers to the current type. After all, you could wish to refer to other types also implementing Trait.
In order to specify that you want a specific type, you should heed the compilers note: use <Type as Trait>::Associated, where Type is the current type.
When defining the Trait, how do you refer to the concrete type for which it will be instantiated? You use Self!
The solution is:
pub trait Trait: Index<<Self as Trait>::Associated> {
type Associated;
}
I think the following provides the semantics you want, taking the approach of your second attempt.
pub trait Trait {
type Associated;
}
impl<T> Index<T> for Trait<Associated = T> {
type Output = str;
fn index(&self, associated: T) -> &'static str {
"sup"
}
}

When should I not implement a trait for references to implementors of that trait?

If I have a trait, and a function that accepts a generic type constrained to that type, everything works fine. If I try to pass in a reference to that type, I get a compilation error.
trait Trait {
fn hello(&self) -> u32;
}
struct Struct(u32);
impl Trait for Struct {
fn hello(&self) -> u32 {
self.0
}
}
fn runner<T: Trait>(t: T) {
println!("{}", t.hello())
}
fn main() {
let s = Struct(42);
// Works
runner(s);
// Doesn't work
runner(&s);
}
error[E0277]: the trait bound `&Struct: Trait` is not satisfied
--> src/main.rs:24:5
|
24 | runner(&s);
| ^^^^^^ the trait `Trait` is not implemented for `&Struct`
|
= help: the following implementations were found:
<Struct as Trait>
note: required by `runner`
--> src/main.rs:13:1
|
13 | fn runner<T: Trait>(t: T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
I can fix the issue by implementing the trait for any reference to a type that implements the trait:
impl<'a, T> Trait for &'a T
where
T: Trait,
{
fn hello(&self) -> u32 {
(*self).hello()
}
}
The piece of information that I'm missing is when shouldn't I implement this? Asked another way, why doesn't the compiler automatically implement this for me? Since it currently doesn't, I assume there must be cases where having this implementation would be disadvantageous.
when shouldn't I implement this? Asked another way, why doesn't the compiler automatically implement this for me? Since it currently doesn't, I assume there must be cases where having this implementation would be disadvantageous.
As an example, the Default trait immediately came to mind.
pub trait Default {
fn default() -> Self;
}
I could implement it for T, but there is no way to automatically implement it for &T.
The particular trait you are writing here only takes self by reference, and that is the only reason it is possible to write the additional implementation you did.
For this reason, taking the parameter to runner() by value is probably undesirable; you should instead be taking it by reference. This guideline can apply generally: if it is possible to implement the trait for a reference then rather than wondering “should I implement it?” you should wonder “why would I implement it?” for the only cases where you would use it should probably be altered to take the object by reference in the first place.

Resources