From 7d1d79e0e6f3bd8351f6000e47b4272bd13db9b0 Mon Sep 17 00:00:00 2001 From: Mario Rogic Date: Fri, 3 May 2024 20:07:53 +1000 Subject: [PATCH] The LamderaCheckBoth harness generated in lamdera check also needs to support the unsafeCoerce trick --- extra/Lamdera/Evergreen/MigrationHarness.hs | 18 ++++++++ extra/Lamdera/Evergreen/ModifyAST.hs | 44 +++++++++++-------- .../Evergreen/TestMigrationGenerator.hs | 2 +- test/Test/Wire.hs | 2 +- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/extra/Lamdera/Evergreen/MigrationHarness.hs b/extra/Lamdera/Evergreen/MigrationHarness.hs index e52ff2cb..a15d24bf 100644 --- a/extra/Lamdera/Evergreen/MigrationHarness.hs +++ b/extra/Lamdera/Evergreen/MigrationHarness.hs @@ -534,6 +534,8 @@ genSupportingCode = do -- In development, we aren't building with the harnesses, so rather than an extra -- file dependency, just inject the additional helpers we need to type check our migrations pure [text| + import Lamdera exposing (sendToFrontend) + type UpgradeResult valueType msgType = AlreadyCurrent ( valueType, Cmd msgType ) @@ -579,6 +581,22 @@ genSupportingCode = do Upgraded ( unsafeCoerce model, Cmd.none ) + {-| + All local call-sites to this function will get replaced by the compiler + to point to Lamdera.Effect.unsafeCoerce instead, and this def will be removed + See lamdera-compiler/extra/Lamdera/Evergreen/ModifyAST.hs + -} + unsafeCoerce : a -> b + unsafeCoerce = + let + -- This is a hack to ensure the Lamdera.Effect module gets included + -- in overall compile scope given we cannot reference it directly + forceInclusion = + sendToFrontend + in + Debug.todo "unsafeCoerce" + + upgradeIsCurrent : Result String ( newModel, Cmd msg ) -> Result String (UpgradeResult newModel msg) upgradeIsCurrent priorResult = priorResult |> Result.map AlreadyCurrent diff --git a/extra/Lamdera/Evergreen/ModifyAST.hs b/extra/Lamdera/Evergreen/ModifyAST.hs index c30d9a21..7bdb5ce7 100644 --- a/extra/Lamdera/Evergreen/ModifyAST.hs +++ b/extra/Lamdera/Evergreen/ModifyAST.hs @@ -36,15 +36,15 @@ update :: Can.Module -> Can.Module update canonical = let moduleName :: Module.Canonical = (Can._name canonical) + decls :: Can.Decls = (Can._decls canonical) & removeUnsafeCoercePlaceholder + newDecls :: Can.Decls = updateDecls moduleName decls + newCanonical :: Can.Module = canonical { Can._decls = newDecls } in case moduleName of Module.Canonical (Name "author" "project") "LamderaHelpers" -> - let - decls :: Can.Decls = (Can._decls canonical) & removeUnsafeCoercePlaceholder - newDecls :: Can.Decls = updateDecls moduleName decls - in - canonical { Can._decls = newDecls } - + newCanonical + Module.Canonical (Name "author" "project") "LamderaCheckBoth" -> + newCanonical _ -> canonical @@ -77,23 +77,29 @@ updateDecls fileName decls = updateExpr :: Module.Canonical -> Name.Name -> Can.Expr -> Can.Expr updateExpr fileName functionName (Reporting.Annotation.At location_ expr_) = + let replaceCall location params = + Can.Call + (Reporting.Annotation.At location + (Can.VarForeign + (Module.Canonical (Name "lamdera" "core") "Lamdera.Effect") + "unsafeCoerce" + (Forall + (Map.fromList [("a", ()), ("b", ())]) + (TLambda (TVar "a") (TVar "b")) + ) + ) + ) params + in (case expr_ of Can.Call (Reporting.Annotation.At location (Can.VarTopLevel (Module.Canonical (Name "author" "project") "LamderaHelpers") "unsafeCoerce") ) params -> - Can.Call - (Reporting.Annotation.At - location - (Can.VarForeign - (Module.Canonical (Name "lamdera" "core") "Lamdera.Effect") - "unsafeCoerce" - (Forall - (Map.fromList [("a", ()), ("b", ())]) - (TLambda (TVar "a") (TVar "b")) - ) - ) - ) - params + replaceCall location params + + Can.Call (Reporting.Annotation.At location + (Can.VarTopLevel (Module.Canonical (Name "author" "project") "LamderaCheckBoth") "unsafeCoerce") + ) params -> + replaceCall location params -- The recursive rest. Might be worth looking at revisiting recursion schemes again, esp if error messages have improved Can.VarLocal name -> Can.VarLocal name diff --git a/test/Lamdera/Evergreen/TestMigrationGenerator.hs b/test/Lamdera/Evergreen/TestMigrationGenerator.hs index b6d0f5fe..1067d6a5 100644 --- a/test/Lamdera/Evergreen/TestMigrationGenerator.hs +++ b/test/Lamdera/Evergreen/TestMigrationGenerator.hs @@ -123,7 +123,7 @@ testExamples = withTestEnv $ do testFiles & mapM (\folder -> do scope folder $ do - io $ putStrLn $ "testing: " <> show folder + io $ atomicPutStrLn $ "testing: " <> show folder let oldVersion = 1 newVersion = 2 diff --git a/test/Test/Wire.hs b/test/Test/Wire.hs index 9840a8ac..a38402f1 100644 --- a/test/Test/Wire.hs +++ b/test/Test/Wire.hs @@ -139,7 +139,7 @@ wire = do testFiles & filter ((/=) "") & mapM (\filename -> do - putStrLn $ "testing: " <> show filename + atomicPutStrLn $ "testing: " <> show filename -- Bust Elm's caching with this one weird trick! touch $ project filename Lamdera.Compile.makeDev project [filename] `catch` catchTestException filename