@@ -184,9 +184,9 @@ addGlobalHelp mode graph global state =
184184 Opt.Link linkedGlobal ->
185185 addGlobal mode graph state linkedGlobal
186186
187− Opt.Cycle values functions deps ->
187+ Opt.Cycle names values functions deps ->
188188 addStmt (addDeps deps state) (
189− generateCycle mode global values functions
189+ generateCycle mode global names values functions
190190 )
191191
192192 Opt.Manager effectsType ->
@@ -253,14 +253,28 @@ isDebugger (Opt.Global (ModuleName.Canonical _ home) _) =
253253-- GENERATE CYCLES
254254
255255
256−generateCycle :: Mode.Mode -> Opt.Global -> [(N.Name, Opt.Expr)] -> [Opt.Def] -> JS.Stmt
257−generateCycle mode (Opt.Global home _) values functions =
256+generateCycle :: Mode.Mode -> Opt.Global -> [N.Name] -> [(N.Name, Opt.Expr)] -> [Opt.Def] -> JS.Stmt
257+generateCycle mode (Opt.Global home _) names values functions =
258258 let
259− funcDefs = map (generateCycleFunc mode home) functions
260− safeDefs = map (generateSafeCycle mode home) values
261− realDefs = map (generateRealCycle home) values
259+ funcBlock = JS.Block $ map (generateCycleFunc mode home) functions
260+ safeBlock = JS.Block $ map (generateSafeCycle mode home) values
261+ realBlock = JS.Block $ map (generateRealCycle home) values
262262 in
263− JS.Block (funcDefs ++ safeDefs ++ realDefs)
263+ case mode of
264+ Mode.Prod _ _ ->
265+ JS.Block [ funcBlock, safeBlock, realBlock ]
266+
267+ Mode.Dev _ _ ->
268+ let
269+ tryRealBlock =
270+ JS.Try realBlock Name.dollar $ JS.Throw $ JS.String $
271+ "Some top-level definitions from `" <> N.toBuilder (ModuleName._module home) <> "` are causing infinite recursion:\\n"
272+ <> drawCycle names
273+ <> "\\n\\nThese errors are very tricky, so read "
274+ <> B.stringUtf8 (D.makeNakedLink "halting-problem")
275+ <> " to learn how to fix it!"
276+ in
277+ JS.Block [ funcBlock, safeBlock, tryRealBlock ]
264278
265279
266280generateCycleFunc :: Mode.Mode -> ModuleName.Canonical -> Opt.Def -> JS.Stmt
@@ -292,6 +306,17 @@ generateRealCycle home (name, _) =
292306 ]
293307
294308
309+drawCycle :: [N.Name] -> B.Builder
310+drawCycle names =
311+ let
312+ topLine = "\\n ┌─────┐"
313+ nameLine name = "\\n │ " <> N.toBuilder name
314+ midLine = "\\n │ ↓"
315+ bottomLine = "\\n └─────┘"
316+ in
317+ mconcat (topLine : List.intersperse midLine (map nameLine names) ++ [ bottomLine ])
318+
319+
295320
296321-- GENERATE KERNEL
297322