Key idea: Use a higher-ranked trait bound (HRTB) so that the closure
can borrow &mut workspace and &crate_name for the duration of the
async future without lifetime conflicts.
We define a new helper function that is basically the same pattern as
run_with_workspace_and_crate_name, but it takes two crate name strings.
This avoids the lifetime conflict by using a higher-ranked trait bound.