Returning unboxed abstract types

New to Rust. Consider the below code.

trait X {
    const Y: Self;

impl X for i32 {
    const Y: Self = 10;

fn f1<T: X>() -> T {
    T::Y // okay

fn f2<T: X>() -> T {
    10i32 // error[E0308]: mismatched types expected type parameter `T` found type `i32`

I would like to know why f1 compiles and f2 doesn't compile. Both functions seem to return a concrete i32 value.

Yes, but in f1 your return type is T whereas in f2 it is i32. That both are the same in your example is just a coincidence. Imagine you implement X for f32 as well and your user calls f2::<f32>(). He won't get a value of f32, but of i32, which is not T in that case.

You could make f2 compile if you were to use an abstract return type instead. That way your user can't control T, but you, the person implementing f2, can choose it freely to be i32 (see here):

fn f2() -> impl X {
1 Like

The trick is what rustc can prove:
In the first example, it can prove that the type of T::Y is the same as T.

In the second example however, there is a problem: f2 promises that for any type T, it will return a value of T.
Yet what you return is a hard i32 value. What happens if we implement the trait for String as well and call f2::<String>()?

1 Like

Thank you :slight_smile:

Thank you !! :slightly_smiling_face:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.