Dont count throw as an exit node (React semantics)

React will retry or abort components that throw (depending on a few conditions), 
so from React's perspective a `throw` statement is not a normal exit node. Thus 
the Rules of Hooks really have a caveat: the set of hooks that are called _in an 
execution that returns successfully_ must be consistent. Examples such as the 
following are therefore allowed: 

```javascript 

function Component(props) { 

if (props.cond) { 

throw new Error(...); 

} 

useHook(); 

} 

``` 

By modeling `throw` as an exit node, we rejected cases such as this. This diff 
changes to not model throws as exit nodes. #1584  changes this to make it an 
option, since some cases will want to consider throw as an exit node.
This commit is contained in:
Joe Savona
2023-05-08 13:58:46 -07:00
parent 7dedc6cc72
commit 8920fc0b2f
+4 -5
View File
@@ -113,10 +113,9 @@ class Dominator<T> {
*/
get(id: T): T | null {
const dominator = this.#nodes.get(id);
invariant(
dominator !== undefined,
`Called on invalid node identifier '${id}'`
);
if (dominator === undefined) {
return null;
}
return dominator === id ? null : dominator;
}
@@ -173,7 +172,7 @@ function computeReverseGraph(fn: HIRFunction): Graph<BlockId> {
preds: new Set(eachTerminalSuccessor(block.terminal)),
succs: new Set(block.preds),
};
if (block.terminal.kind === "return" || block.terminal.kind === "throw") {
if (block.terminal.kind === "return") {
node.preds.add(exitId);
exit.succs.add(id);
}