Description
I tried this code:
pub trait Reciever {
type Error where Self::Error: core::fmt::Debug + Sized;
fn recv(&mut self) -> Result<(), Self::Error> where Self::Error: core::fmt::Debug + Sized;
}
pub trait Transmitter {
type Error where Self::Error: core::fmt::Debug + Sized;
fn send(&mut self) -> Result<(), Self::Error> where Self::Error: core::fmt::Debug + Sized;
}
#[derive(Debug)]
pub struct Orchestrator<Rx : Reciever, Tx : Transmitter> {
rx : Rx,
tx : Tx,
}
impl<Rx: Reciever, Tx: Transmitter> Orchestrator<Rx, Tx> {
pub fn run(&mut self) {
let ev = self.rx.recv().unwrap();
}
}
I expected to see this happen: I expected this to compile.
Instead, this happened:
I got a (fairly undescriptive) error when compiling:
error[E0277]: `<Rx as Reciever>::Error` doesn't implement `Debug`
--> src/lib.rs:20:26
|
20 | let ev = self.rx.recv().unwrap();
| ^^^^ `<Rx as Reciever>::Error` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= help: the trait `Debug` is not implemented for `<Rx as Reciever>::Error`
note: required by a bound in `Reciever::recv`
--> src/lib.rs:3:71
|
3 | fn recv(&mut self) -> Result<(), Self::Error> where Self::Error: core::fmt::Debug + Sized;
| ^^^^^^^^^^^^^^^^ required by this bound in `Reciever::recv`
help: consider further restricting the associated type
|
19 | pub fn run(&mut self) where <Rx as Reciever>::Error: Debug {
| ++++++++++++++++++++++++++++++++++++
error[E0599]: the method `unwrap` exists for enum `Result<(), <Rx as Reciever>::Error>`, but its trait bounds were not satisfied
--> src/lib.rs:20:33
|
20 | let ev = self.rx.recv().unwrap();
| ^^^^^^ method cannot be called on `Result<(), <Rx as Reciever>::Error>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`<Rx as Reciever>::Error: Sized`
Changing the code to this:
pub trait Reciever {
type Error: core::fmt::Debug + Sized;
fn recv(&mut self) -> Result<(), Self::Error> where Self::Error: core::fmt::Debug + Sized;
}
pub trait Transmitter {
type Error: core::fmt::Debug + Sized;
fn send(&mut self) -> Result<(), Self::Error> where Self::Error: core::fmt::Debug + Sized;
}
#[derive(Debug)]
pub struct Orchestrator<Rx : Reciever, Tx : Transmitter> {
rx : Rx,
tx : Tx,
}
impl<Rx: Reciever, Tx: Transmitter> Orchestrator<Rx, Tx> {
pub fn run(&mut self) {
let ev = self.rx.recv().unwrap();
}
}
fixed the compilation error.
I expected the where:
clause and :
syntax to be functionally equivalent when defining bounds on associated types on traits. Not entirely sure if this is expected behavior or not, but I think a clearer error that guides the programmer towards the :
syntax is in any case good.
Here's a link to the rust playground I recreated the issue in: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b4bd9a0bc33f38cde593673ecabc50b1
Meta
rustc --version --verbose
:
rustc 1.72.0-nightly (330727467 2023-06-29)
binary: rustc
commit-hash: 330727467b8fdf2c43b95095a0efae7012c4f83b
commit-date: 2023-06-29
host: x86_64-unknown-linux-gnu
release: 1.72.0-nightly
LLVM version: 16.0.5
Although I've also seen the issue happen on stable
Backtrace isn't relevant as this is a compile-time issue.