Repository: rust
Issue: Rust compiler not inferring the correct trait implementation
Labels: A-trait-system,T-compiler,A-inference,C-bug

(I've raised a question on [SO](https://stackoverflow.com/q/52153792/5099839), and the general answer is that it is due to a bug in rustc that should be reported here, so here I am :) I'm not sure about the report format you expect, so sorry if the following does not match)

I'm trying to implement a reader which could be able to extract values from different types from a file. There is a `File` struct which represents the file resource (and methods to access its content), and a `Reader` trait which makes it possible to extract values based on the resulting type. The (dummy) implementation looks like this ([playground](https://play.rust-lang.org/?gist=859160ad8016cafc2ce07c7e6b724fe7&version=stable&mode=debug&edition=2015)):
````rust
use std::io::Result;

mod file {
    use std::io::Result;

    pub struct File {/* ... */}

    pub trait Reader<T> {
        fn read(&mut self) -> Result<T>;
    }

    impl Reader<u32> for File {
        fn read(&mut self) -> Result<u32> {
            // Dummy implementation
            Ok(10)
        }
    }

    impl Reader<u8> for File {
        fn read(&mut self) -> Result<u8> {
            // Dummy implementation
            Ok(0)
        }
    }

    impl Reader<bool> for File {
        fn read(&mut self) -> Result<bool> {
            // Dummy implementation
            Ok(false)
        }
    }
}

use file::{File, Reader};

impl<T: Default> Reader<Vec<T>> for File
where
    File: Reader<T> + Reader<u32>,
{
    fn read(&mut self) -> Result<Vec<T>> {
        let count: u32 = self.read()?;
        let mut array: Vec<T> = Vec::with_capacity(count as usize);
        for _ in 0..count {
            let mut item: T = self.read()?;
            array.push(item);
        }

        Ok(array)
    }
}

fn main() {
    let mut file = File {};
    let _v: Vec<u8> = file.read().unwrap();
}
````

Everything worked until I added the `Reader<Vec<T>>` implementation. Vectors are stored in the file as a `u32` indicating the number of elements followed by the element's representation. The compiler gives the following error:

    error[E0308]: try expression alternatives have incompatible types
      --> src/main.rs:41:26
       |
    41 |         let count: u32 = self.read()?;
       |                          ^^^^^^^^^^^^
       |                          |
       |                          expected u32, found type parameter
       |                          help: try wrapping with a success variant: `Ok(self.read()?)`
       |
       = note: expected type `u32`
                  found type `T`

Even though I specified that `File` implements both `Reader<T>` and `Reader<u32>`, it seems to be stuck on `Reader<T>`.

What's even more strange is that if I only keep 2 implementations of the `Reader` trait (removing `Reader<bool>` for instance), the code compiles without any issue ([playground](https://play.rust-lang.org/?gist=0b4ead500802fcd4662413ac4ef340ea&version=stable&mode=debug&edition=2015)).

The current workaround is to explicitly tell the compiler it should use the `Reader<u32>` implementation:

````rust
let count: u32 = (self as &mut Reader<u32>).read()?;
````

**But the compiler should be able to detect this implicitly, as it does when only 2 implementations exist.**

Should Rust Playground be trusted, issue appears in stable (1.29.0), unstable (6fdf1dbb9a6d2fbd7894 aka 1.29.0-beta.15) and nightly (2224a42c353636db6ee5 aka 1.30.0-nightly).