rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.61k stars 12.74k forks source link

Implementing `From` for associated type results in confusing error #85576

Open oliver-giersch opened 3 years ago

oliver-giersch commented 3 years ago

Disclaimer: I am not sure if this an actual bug or rather a diagnostic issue.

The following simplified code

use std::str::FromStr;

type BoolErr = <bool as FromStr>::Err;

struct Error(BoolErr);

impl From<BoolErr> for Error {
    fn from(err: BoolErr) -> Self {
        Self(err)
    }
}

Playground

Produces the following incorrect/confusing error message on both stable and nigthly:

error[E0119]: conflicting implementations of trait `std::convert::From<Error>` for type `Error`:
 --> src/lib.rs:7:1
  |
7 | impl From<BoolErr> for Error {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `core`:
          - impl<T> From<T> for T;

I encountered this issue when I wanted to wrap the result returned by str::parse for a type from crate A which uses an error type from another crate B, which I did not want to depend on and import directly. I am aware that using an associated type here has implications for backwards compatibility, but in this case this is actually desirable I think, since I only want to forward the result into my custom error type, even if the concrete error type in crate A/B changes.

smmoosavi commented 1 year ago

This is a bug.

When it happens

When type is an associated type of a trait, and the trait is implemented in another crate. if the trait is implemented in the same crate, it works fine. Also if types are used directly, it works fine.

playground 1 use ParseBoolError directly and has no error playground 2 use type from trait and have the error

ParseBoolError and BoolErr are equal.

type BoolErr = <bool as FromStr>::Err;
assert_eq!(TypeId::of::<BoolErr>(), TypeId::of::<ParseBoolError>());

I have created a new repository that showcases another example of the same error.

type OtherDuration = <other::Systick as other::Monotonic>::Duration;
type OtherInstant = <other::Systick as other::Monotonic>::Instant;

impl FromTime for OtherDuration {}
impl FromTime for OtherInstant {}
QuineDot commented 7 months ago

Duplicates:

lcnr commented 6 months ago

FOr an explanation of the affected issue, see https://github.com/rust-lang/rust/issues/99940#issuecomment-1201595440

tbrezot commented 2 weeks ago

With the toolchain 1.82 and the following really similar code, rustc seems to end-up in an infinite loop:

use ml_kem::{KemCore, MlKem512};

type DK512 = <MlKem512 as KemCore>::DecapsulationKey;

struct DK(DK512);

impl From<DK512> for DK {
    fn from(value: DK512) -> Self {
        todo!()
    }
}

fn main() {
    println!("you will never print this line");
}

I am not sure how different it is from the bug reported in this issue. Using the nightly 1.84 toolchain, the compilation terminates with the same error.