After struggling for hours with writing a factory method which returns instances of a struct containing a field of a generic type (implementing a trait), I find that it compiles and runs only if I do not assign the result to a variable before returning it (see the bottom of the post for a complete working example):
This compiles and runs:
fn compiles() -> Parent<dyn IsAChild> {
    return match rand::thread_rng().gen_bool(1.0/2.0) {
        true => Parent { child: Box::new(Daughter{} ) },
        false => Parent { child: Box::new(Son{} ) },
    }
}
This does not compile:
fn does_not_compile() -> Parent<dyn IsAChild> {
    return match rand::thread_rng().gen_bool(1.0/2.0) {
        true => {
            let parent = Parent { child: Box::new(Daughter {}) };
            parent
        },
        false => {
            let parent = Parent { child: Box::new(Son {}) };
            parent
        },
    }
}
The does_not_compile() function results in the following error:
error[E0308]: mismatched types
  --> src\main.rs:39:13
   |
39 |             parent
   |             ^^^^^^ expected trait object `dyn IsAChild`, found struct `Daughter`
   |
   = note: expected struct `Parent<(dyn IsAChild + 'static)>`
              found struct `Parent<Daughter>`
This has me completely stumped. To me there is no semantic difference between the two, only the fact that the result is (temporarily) stored in a variable before it is returned. What is going on here?
Complete example (add rand = "*" to the dependencies):
use rand::Rng;
trait IsAChild {}
struct Parent<T: IsAChild + ?Sized> {
    child: Box<T>
}
struct Son;
impl IsAChild for Son {}
struct Daughter;
impl IsAChild for Daughter {}
fn compiles() -> Parent<dyn IsAChild> {
    return match rand::thread_rng().gen_bool(1.0/2.0) {
        true => Parent { child: Box::new(Daughter{} ) },
        false => Parent { child: Box::new(Son{} ) },
    }
}
fn compiles_too() -> Parent<dyn IsAChild> {
    return match rand::thread_rng().gen_bool(1.0/2.0) {
        true => {
            println!("It's a girl!");
            Parent { child: Box::new(Daughter{} ) }
        },
        false => {
            println!("It's a boy!");
            Parent { child: Box::new(Son{} ) }
        },
    }
}
/*
fn does_not_compile() -> Parent<dyn IsAChild> {
    return match rand::thread_rng().gen_bool(1.0/2.0) {
        true => {
            let parent = Parent { child: Box::new(Daughter {}) };
            parent
        },
        false => {
            let parent = Parent { child: Box::new(Son {}) };
            parent
        },
    }
}
*/
fn main() {
    compiles();
}    
 
     
    