-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
(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 (6fdf1db aka 1.29.0-beta.15) and nightly (2224a42 aka 1.30.0-nightly).