(I've raised a question on SO, 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):
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).
The current workaround is to explicitly tell the compiler it should use the Reader<u32> implementation:
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).
(I've raised a question on SO, 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 aReader
trait which makes it possible to extract values based on the resulting type. The (dummy) implementation looks like this (playground):Everything worked until I added the
Reader<Vec<T>>
implementation. Vectors are stored in the file as au32
indicating the number of elements followed by the element's representation. The compiler gives the following error:Even though I specified that
File
implements bothReader<T>
andReader<u32>
, it seems to be stuck onReader<T>
.What's even more strange is that if I only keep 2 implementations of the
Reader
trait (removingReader<bool>
for instance), the code compiles without any issue (playground).The current workaround is to explicitly tell the compiler it should use the
Reader<u32>
implementation: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).