Question on std::convert::{From, Into} in generic bounds

The doc says users should only implement either From or Into, preferably From. And I assume how that works is if you implement one, the compiler will automatically do the other one for you behind the scene.

But the following testing code suggests that's not the case. So my question is, is it a bug with the compiler? Or is this behavior by design, and I misunderstood the doc.

Thanks in advance.

#[test]
fn generic_convert_from() {
    struct MyBool {
        inner: bool,
    }
    impl std::convert::From<u32> for MyBool {
        fn from(s: u32) -> Self {
            Self { inner: s > 0 }
        }
    }

    fn test_fn<T>(src: T) -> MyBool
    where
        // T: std::convert::Into<MyBool>,   // This does not work
        MyBool: std::convert::From<T>, // This works
    {
        MyBool::from(src)
    }

    test_fn(123u32);
}

Error message:

error[E0277]: the trait bound `feature_type::generic_convert_from::MyBool: std::convert::From<T>` is not satisfied
   --> src/feature_type/mod.rs:327:9
    |
327 |         MyBool::from(src)
    |         ^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `feature_type::generic_convert_from::MyBool`
    |
    = note: required by `std::convert::From::from`
$ rustc --version
rustc 1.43.0-nightly (564758c4c 2020-03-08)

Please use code blocks for code:

```
// your code
```

You misspelled MyBool as Bool.

I did. Thank you for pointing that out. I will fix that typo.

But even with that fixed it still does not work.

The From trait implies Into, but not the other way around, so if you only require Into, you can't use From. This is why the docs say you should prefer to implement From.

2 Likes

Thank you for the prompt reply. Learned something new.

Nothing magic going on here, it's just an ordinary blanket impl: https://doc.rust-lang.org/std/convert/trait.Into.html#impl-Into<U>

So you should implement From, but consume Into.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.