Open nandesu-utils opened 1 year ago
I also have run into this behavior, notably the same does not occur with a user defined type that implements FromStr, only the builtin types. This code compiles without issue.
struct Error;
struct FromStringType;
struct FromStringTypeErr;
impl std::str::FromStr for FromStringType {
type Err = FromStringTypeErr;
fn from_str(_: &str) -> Result<Self, Self::Err> {
Ok(FromStringType)
}
}
impl From<<FromStringType as std::str::FromStr>::Err> for Error {
fn from(_: <FromStringType as std::str::FromStr>::Err) -> Self {
Self
}
}
rustc --version --verbose
:
rustc 1.68.2 (9eb3afe9e 2023-03-27)
binary: rustc
commit-hash: 9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0
commit-date: 2023-03-27
host: x86_64-unknown-linux-gnu
release: 1.68.2
LLVM version: 15.0.6
I can confirm this behavior.
Let's assume we have a library up
with the following contents:
pub trait Trait {
type Assoc;
}
pub struct Inner;
pub struct AssocInner;
impl Trait for AssocInner {
type Assoc = Inner;
}
In a dependent crate we want to implement the From trait for a wrapper:
use up::{AssocInner, Inner, Trait};
struct Outer(Inner);
impl From<<AssocInner as Trait>::Assoc> for Outer {
fn from(_: <AssocInner as Trait>::Assoc) -> Self {
Outer(Inner)
}
}
This does not compile:
cargo check
Checking down v0.1.0 (/home/jannis/s/o/projects/weird_bug_questionmark/down)
error[E0119]: conflicting implementations of trait `From<Outer>` for type `Outer`
--> src/lib.rs:5:1
|
5 | impl From<<AssocInner as Trait>::Assoc> for Outer {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> From<T> for T;
For more information about this error, try `rustc --explain E0119`.
error: could not compile `down` (lib) due to previous error
In the attached files (see below), I tried exactly examine where the problem is coming from. It seems to be definitely from Trait
, Inner
and AssocInner
being external and using the asssociated type for the generic type parameter in From<...>
in line 5. I don't understand it because the compiler seems to know what the type of the associated type is when used in other situations.
rustc --vesion --verbose
rustc 1.74.1 (a28077b28 2023-12-04)
binary: rustc
commit-hash: a28077b28a02b92985b3a3faecf92813155f1ea1
commit-date: 2023-12-04
host: x86_64-unknown-linux-gnu
release: 1.74.1
LLVM version: 17.0.4
closing this as a duplicate of https://github.com/rust-lang/rust/issues/85576#issuecomment-2058244779. Thanks for opening this issue
I tried this code:
I expected to see this happen: proper compilation and no errors
Instead, this happened: error about conflicting implementations,
So compiler thinks this associated
Err
might be locally definedError
type.Perhaps there are few issues from different perspectives:
The trait and implementing
Self
(which isu64
) type are both external (theu64
is a primitive though but it acts as if it was external here since you wouldn't be able to implement the external trait on it), and cyclic dependencies aren't possible so there is no way this associated type may be equal to localError
struct.And this seems to be trivially resolvable since the implementation that is getting selected is selected via concrete types so the associated type may be resolved right away and checked for equality and, hence, conflicts.
Meta
rustc --version --verbose
: