Fix issue #83

The problem was that inlining was hiding a bug in the implementation
of ifelse(), which would cause an index out of bounds exception when
the default case was reached. Inliners of conditional code would cause
the expressions that produced lambda arguments for conditionals (e.g.
the 2nd and 3rd args of a call to if(), 2nd arg to a when(), 3rd arg
to a guard(), etc.) to be evaluated lazily rather than eagerly. In
cases where the expression is immediate, such as a lambda literal or
a ref, the two are indistinguishable, but in cases where nontrivial
computation is involved (such as indexing into a list, the situation
in ifelse()) the difference is observable and lazy evaluation may
avoid errors incorrectly. Inliners are now properly conservative.

(Note: current code fails to inline certain cases that are possible,
because it's not clear that they pay their way w.r.t. complexity. If
desired, the template for such cases is ForInliner(), where a local
block is created that evaluates the lambda-producing expression and
stores it to a local before proceeding.)

Also fixed the implementation of ifelse() to avoid the error (now
correctly produced with the original implementation whether inlining
is on or not).
Merge remote-tracking branch 'upstream/master' into await
Await/awaits supplemental work/fixes

1. correct if() to while() around wait() calls

2. change awaits() args sig: was

    Tup(T | Box), Tup(T) -> Bool // single pred takes tuple of values

is now

    Tup(T | Box), Tup(T | Pred)  // tuple of preds, one per box

...this avoids the misunderstanding that predicate calls are in any
sense atomic on the aggregate of boxes.

3. remove legacy Types.unit()

4. add typedef Pred(T) = T -> Bool

5. tweak CG pipeline to use type.eval() where necessary.

Note: #5 is more ad-hoc than it should be. Reconciling type
reduction and evaluation remains a big TODO.