Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why we need to repeat trait bounds that were specified in trait definitions?

I have a function like this:

pub fn foo<T: FromStr<Err = impl Display>>() -> T {
    T::from_str("123").map_err(|e| println!("{e}")).unwrap()
}

It has a trait bound on T and a trait bound on that trait’s associated type Err. I want to create an "alias" for these bounds. Here is my first trial:

pub trait AliasTrait: FromStr
where
    <Self as FromStr>::Err: Display,
{
}

impl<T: FromStr<Err = impl Display>> AliasTrait for T {}

pub fn foo<T: AliasTrait>() -> T {
    T::from_str("123").map_err(|e| println!("{e}")).unwrap()
}

However rustc complains that

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

error[E0277]: `<T as FromStr>::Err` doesn't implement `std::fmt::Display`
  --> src/main.rs:19:15
   |
19 | pub fn foo<T: AliasTrait>() -> T {
   |               ^^^^^^^^^^ `<T as FromStr>::Err` cannot be formatted with the default formatter
   |
   = help: the trait `std::fmt::Display` is not implemented for `<T as FromStr>::Err`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `AliasTrait`
  --> src/main.rs:13:29
   |
11 | pub trait AliasTrait: FromStr
   |           ---------- required by a bound in this
12 | where
13 |     <Self as FromStr>::Err: Display,
   |                             ^^^^^^^ required by this bound in `AliasTrait`
help: consider further restricting the associated type
   |
19 | pub fn foo<T: AliasTrait>() -> T where <T as FromStr>::Err: std::fmt::Display {
   |                                  ++++++++++++++++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.

But when I change the AliasTrait to

pub trait AliasTrait: FromStr<Err = <Self as AliasTrait>::Err> {
    type Err: Display;
}

impl<T: FromStr<Err = impl Display>> AliasTrait for T {
    type Err = T::Err;
}

Then it works.

Rust Playground

I do not quite understand why the first AliasTrait implementation needs to repeat the trait bounds specified in its definition. Because all types that implement AliasTrait should have satisfied these bounds. This is totally redundant.

>Solution :

This is a (very old) rustc bug: #20671.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading