pub fn inline_apply(expr: &mut Expr) {
    expr.transform(&mut |ref mut expr| {
        if let Apply {
            ref func,
            params: ref args,
        } = expr.kind
        {
            if let Lambda {
                ref params,
                ref body,
            } = func.kind
            {
                let mut new = *body.clone();
                for (param, arg) in params.iter().zip(args) {
                    new.substitute(&param.name, &arg);
                }
                return Some(new);
            }
        }
        None
    });
}
Inlines Apply nodes whose argument is a Lambda expression. These often arise during macro
expansion but it's simpler to inline them before doing type inference.
Unlike many of the other transformations, we make this one independent of types so that
we can apply it before type inference.

Caveats:
- Functions that reuse a parameter twice have its expansion appear twice, instead of assigning
it to a temporary as would happen with function application.
- Does not complete inlining if some of the functions take functions as arguments (in that
case, the expressions after inlining may lead to more inlining).
weld/src/optimizer/transforms/inliner.rs