Skip to content

where vs : in trait bounds #113195

Open
Open
@redshiftss

Description

@redshiftss

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-implied-boundsArea: Implied bounds / inferred outlives-boundsA-trait-systemArea: Trait systemC-discussionCategory: Discussion or questions that doesn't represent real issues.T-langRelevant to the language team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions