@samitouri / QOS-React-2 / commits / 19b08e67ad

[Bailout] When Inputs Detected In DepGraph Cycle

Inputs occured in depGraph cycle is dangenrous and should be treated as an invariant since Forget _may_ generate broken code in this case, despite that technically this is a stricter then what we needed for the particular case of #633 and #634 and there could be case that this is safe (like many `cfg-` tests that I have to mark as `bailout.`) I expect the next diff will fix them though. commit-id:0b13ed02

Xuan Huang (黄玄) committed Oct 5, 2022 at 18:42 UTC 19b08e67add524fa0c8c5e19b3b8da22f2528c46
2 files changed +27
compiler/forget/src/Diagnostic.ts
+8
@@ -126,6 +126,7 @@ export type ErrorCode =
126 | ParseCode<"E0018">
127 | ParseCode<"E0019">
128 | ParseCode<"E0020">
129 + | ParseCode<"E0021">
130 ;
131
132 // prettier-ignore
@@ -168,6 +169,7 @@ export type DiagnosticOpts =
169 | { code: "E0018"; path: NodePath; context: null }
170 | { code: "E0019"; path: NodePath; context: null }
171 | { code: "E0020"; path: NodePath; context: null }
172 + | { code: "E0021"; path: NodePath; context: { name: Name } }
173 ;
174
175 function getDiagnosticMessage(opts: DiagnosticOpts): DiagnosticMessage {
@@ -320,6 +322,12 @@ ${getSource(opts.path)}
322 body: "Forget does not support the use of the arguments object.",
323 suggestion: null,
324 };
325 + case "E0021":
326 + return {
327 + level: DiagnosticLevel.Error,
328 + body: `Input "${opts.context.name}" is detected in a DepGraph cycle. This is dangenrous since Forget may (though not always) generate broken code like accessing "c_input" before it is defined.`,
329 + suggestion: null,
330 + };
331 default:
332 assertExhaustive(opts, `Unhandled error code ${opts}`);
333 }
compiler/forget/src/MiddleEnd/DepGraphAnalysis.ts
+19
@@ -47,6 +47,7 @@ function run(
47 }
48
49 const sccGraph = valGraph.condense();
50 + checkSCCGraph(sccGraph, context);
51
52 if (outputKinds.includes(OutputKind.SCCGraph)) {
53 context.outputs[OutputKind.SCCGraph].push(sccGraph.snapshot());
@@ -184,6 +185,24 @@ function checkValGraph(valGraph: DepGraph.ValGraph) {
185 }
186 }
187
188 +function checkSCCGraph(sccGraph: DepGraph.SCCGraph, context: CompilerContext) {
189 + for (const scc of sccGraph.vertices) {
190 + if (scc.isInput()) continue;
191 +
192 + for (const valVertex of scc.members) {
193 + if (IR.isInputVal(valVertex.val)) {
194 + context.bailout("InputInDepGraphCycle", {
195 + code: "E0021",
196 + path: valVertex.val.ast.path,
197 + context: {
198 + name: valVertex.val.binding.identifier.name,
199 + },
200 + });
201 + }
202 + }
203 + }
204 +}
205 +
206 export function computeCfgControlDeps(
207 irFunc: IR.Func,
208 cfg: CFG