Update base for Update on "[compiler] Improve handling of refs"

Summary:
This change expands our handling of refs to build an understanding of nested refs within objects and functions that may return refs. It builds a special-purpose type system within the ref analysis that gives a very lightweight structural type to objects and array expressions (merging the types of all their members), and then propagating those types throughout the analysis (e.g., if `ref` has type `Ref`, then `{ x: ref }` and `[ref]` have type `Structural(value=Ref)` and `{x: ref}.anything` and `[ref][anything]` have type `Ref`).

This allows us to support structures that contain refs, and functions that operate over them, being created and passed around during rendering without at runtime accessing a ref value.

The analysis here uses a fixpoint to allow types to be fully propagated through the system, and we defend against diverging by widening the type of a variable if it could grow infinitely: so, in something like
```
let x = ref;
while (condition) {
  x = [x]
}
```
we end up giving `x` the type `Structural(value=Ref)`.

[ghstack-poisoned]
This commit is contained in:
Mike Vitousek
2024-09-07 17:49:44 -07:00
parent 727b361528
commit cd1cb37dbd
@@ -107,7 +107,7 @@ function equation(left: Type, right: Type): TypeEquation {
function* generate(
func: HIRFunction,
): Generator<TypeEquation, void, undefined> {
if (func.env.fnType === 'Component') {
if (func.fnType === 'Component') {
const [props, ref] = func.params;
if (props && props.kind === 'Identifier') {
yield equation(props.identifier.type, {