We just copy the variables into the closure environment after it gets
allocated. This involves a decent chunk of stack traffic because we have
to increment their reference counts.
In the process, I figured out that the "ivy_app_mut" optimization for
later functions isn't sound in the presence of nested functions, because
one of the earlier applications can return a shared function which isn't
acceptable to mutate. (There are ways to make it sound if you know for
sure what functions are being called).