Error due to "Impl trait" while returning from a function

trait Common{
    fn setup(&self);
}

struct A{}
struct B{}

impl Common for A {
    fn setup(&self) {
        println!("A()");
    }
}

impl Common for B {
    fn setup(&self) {
        println!("B()");
    }
}

fn setup(k:bool)->impl Common{
match k{
    true => return A{},
    false => return B{},
}
}

for above code getting compilation error as below .

error[E0308]: mismatched types
  --> src/main.rs:25:21
   |
22 | fn setup(k:bool)->impl Common{
   |                   ----------- expected because this return type...
23 | match k{
24 |     true => return A{},
   |                    --- ...is found to be `A` here
25 |     false => return B{},
   |                     ^^^ expected struct `A`, found struct `B`
   |
   = note: to return `impl Trait`, all returned values must be of the same type

if I use Box<dyn Common> instead of impl Common code works as expected . So my question is using impl trait while returning from function is invalid ?

It's valid if everything you return has the same type. Return position impl Trait creates an opaque but otherwise shallow alias to the returned type. You can return the boxed dyn Trait because dyn Trait is its own concrete, singular type; the underlying type is erased.

In case you didn't see it, the error output you get from the compiler (e.g. if you ran cargo check on the command line) explains the situation quite well:

20 | fn setup(k:bool)->impl Common{
   |                   ----------- expected because this return type...
21 | match k{
22 |     true => return A{},
   |                    --- ...is found to be `A` here
23 |     false => return B{},
   |                     ^^^ expected struct `A`, found struct `B`
   |
   = note: to return `impl Trait`, all returned values must be of the same type
   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
   = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
   = help: you could instead create a new `enum` with a variant for each returned type
help: you could change the return type to be a boxed trait object
   |
20 | fn setup(k:bool)->Box<dyn Common>{
   |                   ~~~~~~~       +
help: if you change the return type to expect trait objects, box the returned expressions
   |
22 ~     true => return Box::new(A{}),
23 ~     false => return Box::new(B{}),
2 Likes

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.