Feature flag for transitively freezing values
This PR adds a feature flag to model a potential new-in-practice rule in React: that freezing a function expression also freezes its closed-over values, transitively. For example, in the following code `data` is frozen when the lambda that captures it is is passed to useEffect: ```javascript const data = []; // useEffect freezes its argument (the function expr), which transitively freezes its captured value data useEffect(() => { foo(data); }, [data]); data.push(true); // ERROR: mutating a frozen value mutate(data); // we conservatively assume this doesn't mutate but could be wrong ``` Note that this rule has never been written down or enforced. It is theoretically equivalent to the rule (already implemented in Forget) that values captured by JSX are frozen: ```javascript const style = {...}; <div style={style}>...</div> style.width = 10; // ERROR: mutating a frozen value mutate(style); // we conservatively assume this doesn't mutate but could be wrong ``` However, JSX is typically constructed toward the very end of a render function. Thus in practice there isn't much subsequent code that could even modify such a captured value. But for the useEffect case (and other hooks that take closures as arguments), they tend to occur much earlier in a render function. There's more code that can run later and still modify the captured values, without causing issues in practice. The _practical_ rule today is that you can't modify values captured by frozen lambdas _after the component returns_: it's fine in practice to modify captured values between calling eg useEffect and returning from render. Thus this feature flag is fairly likely to break some percent of real product code. I'm adding this so that we can experiment and see how unsafe it actually is.