0

I am trying to implement my custom trait for both impl std::io::Read and std::fs::DirEntry - the idea is to implement trait both for directores as well as files, buffers and so on.

use std::fs::DirEntry;
use std::io::Read;

trait MyTrait {}

impl<T> MyTrait for T
where
    T: Read,
{}

impl MyTrait for DirEntry {}

As a result I got error

error[E0119]: conflicting implementations of trait `MyTrait` for type `DirEntry`
  --> src/mytrait.rs:11:1
   |
6  | impl<T> MyTrait for T
   | --------------------- first implementation here
...
11 | impl MyTrait for DirEntry {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `DirEntry`
   |
   = note: upstream crates may add a new impl of trait `std::io::Read` for type `std::fs::DirEntry` in future versions

For more information about this error, try `rustc --explain E0119`.

As far as I understand I cannot implement MyTrait for both impl std::io::Read and std::fs::DirEntry because, somehow, std::fs::DirEntry already implements std::io::Read.

However I cannot find any information about this fact in the docs. I tried to find something in source code but my knowledge about Rust source code is none so mission failed.

I found the solution in which I should manually implement MyTrait for std::fs::File, buffers and so on with some helper macro (like impl_mytrait) but I want to know where I can find informations about possible upstream implementations - and if it's possible I want to find better solution than impl_mytrait macro.

E_net4
  • 27,810
  • 13
  • 101
  • 139
ventaquil
  • 2,780
  • 3
  • 23
  • 48

1 Answers1

1

If you read the note, the error is not because such an implementation already exists but because

= note: upstream crates may add a new impl of trait std::io::Read for type std::fs::DirEntry in future versions

'in future versions' here means currently there is no such implementation, but it's disallowed in Rust because adding such an implementation would be a breaking change (i.e. a major version bump required) for your crate, while it only requires a minor version bump from the upstream crate.

cafce25
  • 15,907
  • 4
  • 25
  • 31
  • I exactly understand the note - the question is _"where I can find information about this upstream new impl"_ and _"how can I impl `MyTrait` in bestway?"_. – ventaquil Feb 15 '23 at 02:57
  • At the time of this writing, `DirEntry` _does not implement_ `std::io::Read` and therefore you won't find information about this implementation in the documentation. If, at some point in the future, `std::io::Read` is implemented for `DirEntry`, you will find it mentioned in the doc for `DirEntry` and, quite possibly, also the doc for `std::io::Read` as it'll be an implementor from the same crate (i.e., `std`). – cadolphs Feb 15 '23 at 02:59
  • Okay, so basically `std::io::Read` is marked as _"it can be implemented to any other structs/types in the future"_? I assumed that there is hardcoded mapping somewhere that `std::io::Read` **could be** implemented to `std::fs::DirEntry`. – ventaquil Feb 15 '23 at 03:02
  • 1
    No that's a general rule you can't define a blanket impl and a foreign implementation at the same time, there is no special treatment for `std::io::Read` or `std::fs::DirEntry` happening here. – cafce25 Feb 15 '23 at 03:04