The solution from How do I store a variable of type `impl Trait` in a struct? suggests creating a Future trait object. Doing that in my real code generates an error that the type is not Send, but the only difference between the working and non working version is the presence or absence of the cast to dyn Future.
Why does the compiler see these as different and how do I resolve the problem?
Here's a simplified version of the problem:
use std::future::Future;
fn uses_impl_trait() -> impl Future<Output = i32> {
    async { 42 }
}
fn uses_trait_object() -> Box<dyn Future<Output = i32>> {
    Box::new(async { 42 })
}
fn requires_send<T: Send>(_: T) {}
fn example() {
    requires_send(uses_impl_trait()); // Works
    requires_send(uses_trait_object()); // Fails
}
error[E0277]: `dyn std::future::Future<Output = i32>` cannot be sent between threads safely
  --> src/lib.rs:15:19
   |
11 | fn requires_send<T: Send>(_: T) {}
   |    -------------    ---- required by this bound in `requires_send`
...
15 |     requires_send(uses_trait_object());
   |                   ^^^^^^^^^^^^^^^^^^^ `dyn std::future::Future<Output = i32>` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `dyn std::future::Future<Output = i32>`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dyn std::future::Future<Output = i32>>`
   = note: required because it appears within the type `std::boxed::Box<dyn std::future::Future<Output = i32>>`
From Sending trait objects between threads in Rust, I already know that I can change the trait object to Box<dyn Future<Output = i32> + Send>, but why does this difference exist?