Next to the send/sync issues there’s also an issue that you cannot create an Fn like this with Box::new(|| f) since you can only move out of f once. But this works:
Sorry, still not get it. How? The commented code make a HookFunc first, then put it into a Box which is the HookBuilder, and the builder is consumed finally.
By writing Box::new(|| f) with a type hint of HookBuilder, you create a HookBuilder. Since a HookBuilder has a Send requirement, this requirement is imposed on what you put in the box.
Because captures are often by reference, the following general rules arise:
A closure is Sync if all captured variables are Sync.
A closure is Send if all variables captured by non-unique immutable reference are Sync, and all values captured by unique immutable or mutable reference, copy, or move are Send.
A closure is Clone or Copy if it does not capture any values by unique immutable or mutable reference, and if all values it captures by copy or move are Clone or Copy, respectively.
impl<T: ?Sized> Send for Box<T>
where
T: Send,
impl<T: ?Sized> Sync for Box<T>
where
T: Sync,
A trait object is an opaque value of another type that implements a set of traits. The set of traits is made up of an object safebase trait plus any number of auto traits.
Trait objects implement the base trait, its auto traits, and any supertraits of the base trait.