performanceclosuresmonomorphization

Box<dyn Fn> as the default closure type

Heap-allocating every closure when a generic parameter would inline.

Why this looks tempting

Box<dyn Fn> has a fixed size and avoids generic noise in signatures.

Why wrong

Every call goes through a vtable and the heap allocation defeats inlining. The boxed closure can no longer be specialised by the optimiser — costly in a hot loop.

Fix

Take the closure as a generic: fn run<F: FnOnce()>(f: F). Use Box<dyn Fn> only when you genuinely need to store heterogeneous closures together.

Canonical alternative

trait-system/trait-objects