rust-lang / rust

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

Disambiguate method call for impl on dyn Trait #69161

Open haraldh opened 4 years ago

haraldh commented 4 years ago
pub trait Error: Debug + Display {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        None
    }

    fn chain(&self) -> Chain<'_> where Self: Sized + 'static {
        Chain {
            current: Some(self),
        }
    }
}

impl dyn Error + 'static {
    fn chain(&self) -> Chain<'_> {
        Chain {
            current: Some(self),
        }
    }
}

Seems like the compiler tries the trait method for an dyn Error + 'static even though it does not work, because of !Sized and does not consider taking the impl dyn Error + 'static.

Playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=a6845b426451f1d7a5105a9bd3a00499

error:

error[E0034]: multiple applicable items in scope
  --> src/main.rs:82:28
   |
82 |     let mut iter = dyn_err.chain();
   |                    --------^^^^^--
   |                    |       |
   |                    |       multiple `chain` found
   |                    help: disambiguate the method call for candidate #2: `Error::chain(&dyn_err)`
   |
note: candidate #1 is defined in an impl for the type `(dyn Error + 'static)`
  --> src/main.rs:16:5
   |
16 |     fn chain(&self) -> Chain<'_> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in the trait `Error`
  --> src/main.rs:8:5
   |
8  |     fn chain(&self) -> Chain<'_> where Self: Sized + 'static {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
haraldh commented 4 years ago

Introducing a new trait gets the job done, though and the compiler will pick the right thing. https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=682e14eddb0270a6787ab0259966f2d3

JelteF commented 4 years ago

I've been doing a bit of digging in the type checking code and I've found the core problem of this bug:

This piece of code that checks for illegal_sized_bound, should be checked somewhere in the consider_candidates (or one of the functions that it calls, such as consider_probe). It should be done before the Ambiguity error is returned.

I'm writing this down for two reasons:

  1. If someone with more experience or time to work on this wants to pick this up, then this might be useful to them. It also shows that the issue doesn't seem very complex to fix.
  2. If no-one does, then this way I don't have to figure it out next time I want to continue working on this.
haraldh commented 4 years ago

Any chance anybody looking into this?