Regarding mistake 1: return std::move(local_var), it is worth clarifying why this is technically a pessimization beyond just breaking NRVO. It comes down to the change in C++17 regarding prvalues.
> Pre-C++17, a prvalue was a temporary object.
> Post-C++17, a prvalue is an initializer. It has no identity and occupies no storage until it is materialized.