Skip to content

Allow building with GHC 9.12 - #1828

Draft
sauclovian-g wants to merge 13 commits into
masterfrom
allow-ghc-9.12
Draft

Allow building with GHC 9.12#1828
sauclovian-g wants to merge 13 commits into
masterfrom
allow-ghc-9.12

Conversation

@sauclovian-g

Copy link
Copy Markdown
Contributor

This isn't working yet

@sauclovian-g
sauclovian-g marked this pull request as draft May 14, 2026 23:32
@RyanGlScott

Copy link
Copy Markdown
Contributor

There's a rather scary-looking error when compiling crucible-mir with GHC 9.12:

 <no location info>: error:
    compiler/GHC/Core/Opt/Simplify/Iteration.hs:3913:15-36: Non-exhaustive patterns in dmd : cont_dmds

This appears to be a GHC bug, and one that is exclusive to GHC 9.12. I've opened https://gitlab.haskell.org/ghc/ghc/-/issues/27261 to track this. Thus far, the only workaround that I've discovered is to ensure that the calls to error in mkTraitObject are only called in let bindings, not in <- bindings:

diff --git a/crucible-mir/src/Mir/Trans.hs b/crucible-mir/src/Mir/Trans.hs
index a0bb1125b..93748cb51 100644
--- a/crucible-mir/src/Mir/Trans.hs
+++ b/crucible-mir/src/Mir/Trans.hs
@@ -1300,8 +1300,8 @@ mkTraitObject :: forall h s ret.
     MirExp s ->
     MirGenerator h s ret (MirExp s)
 mkTraitObject traitName' vtableName e = do
-    handles <- Maybe.fromMaybe (error $ "missing vtable handles for " ++ show vtableName) <$>
-        use (cs . vtableMap . at vtableName)
+    mbHandles <- use (cs . vtableMap . at vtableName)
+    let handles = Maybe.fromMaybe (error $ "missing vtable handles for " ++ show vtableName) mbHandles

     col <- use $ cs . collection
     vtable <- case col ^. vtables . at vtableName of
@@ -1323,9 +1323,10 @@ mkTraitObject traitName' vtableName e = do
     -- trait.  A mismatch would cause runtime errors at calls to trait methods.
     trait <- Maybe.fromMaybe (error $ "unknown trait " ++ show traitName') <$>
         use (cs . collection . M.traits . at traitName')
-    Some vtableTy' <- case traitVtableType col trait of
-                        Left err -> error ("mkTraitObject: " ++ err)
-                        Right x -> return x
+    let someVtableTy' = case traitVtableType col trait of
+                          Left err -> error ("mkTraitObject: " ++ err)
+                          Right x -> x
+    Some vtableTy' <- pure someVtableTy'
     case testEquality vtableTy vtableTy' of
         Just _ -> return ()
         Nothing -> error $ unwords

Comment thread cabal.project
Comment on lines +39 to +42
-- there is no ring-buffer that permits GHC 9.12's base version
-- and boomerang doesn't permit GHC 9.12's template-haskell
allow-newer: ring-buffer:base
allow-newer: boomerang:template-haskell

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally like to file issues on the upstream repos and link to them in these comments to make it easier to track whether or not we can remove the allow-newers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good idea, I will make sure that gets done if we still need them by the time this gets merged.

@RyanGlScott

Copy link
Copy Markdown
Contributor

crucible-symio is failing to build on GHC 9.14 due to a rather funky-looking error message:

Details
src/Lang/Crucible/SymIO.hs:266:34: error: [GHC-05617]
Error:     • Could not deduce ‘(args <+> args''4) ~ (args <+> args'')’
      from the context: (IsSymInterface sym, 1 <= wptr)
        bound by the type signature for:
                   closeFileHandle :: forall sym (wptr :: Natural) p arch r
                                             (ret :: CrucibleType) a (args :: Ctx CrucibleType).
                                      (IsSymInterface sym, 1 <= wptr) =>
                                      GlobalVar (FileSystemType wptr)
                                      -> FileHandle sym wptr
                                      -> (forall (args' :: Ctx CrucibleType).
                                          Maybe FileHandleError
                                          -> C.OverrideSim p sym arch r args' ret a)
                                      -> C.OverrideSim p sym arch r args ret a
        at src/Lang/Crucible/SymIO.hs:(260,1)-(265,39)
      Expected: RegMap sym EmptyCtx
                -> FileHandle sym wptr
                -> FileM_ p arch r (args <+> args'') ret sym wptr ()
        Actual: RegMap sym EmptyCtx
                -> FileHandle sym wptr
                -> FileM_ p arch r (args <+> args''4) ret sym wptr ()
      Note: ‘<+>’ is a non-injective type family.
      The type variable ‘args''4’ is ambiguous
    • In the first argument of ‘($)’, namely
        ‘runFileMHandleCont
           fvar fhdl emptyRegMap (\ a -> cont (eitherToMaybeL a))’
      In the expression:
        runFileMHandleCont
          fvar fhdl emptyRegMap (\ a -> cont (eitherToMaybeL a))
          $ \ _ fhdl'
              -> do sz <- getPtrSz
                    sym <- getSym
                    ....
      In an equation for ‘closeFileHandle’:
          closeFileHandle fvar fhdl cont
            = runFileMHandleCont
                fvar fhdl emptyRegMap (\ a -> cont (eitherToMaybeL a))
                $ \ _ fhdl'
                    -> do sz <- getPtrSz
                          ....
    • Relevant bindings include
        closeFileHandle :: GlobalVar (FileSystemType wptr)
                           -> FileHandle sym wptr
                           -> (forall (args' :: Ctx CrucibleType).
                               Maybe FileHandleError -> C.OverrideSim p sym arch r args' ret a)
                           -> C.OverrideSim p sym arch r args ret a
          (bound at src/Lang/Crucible/SymIO.hs:266:1)
    |
266 | closeFileHandle fvar fhdl cont = runFileMHandleCont fvar fhdl emptyRegMap (\a -> cont (eitherToMaybeL a)) $ \_ fhdl' -> do
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

As far as I can tell, this is a regression in GHC's typechecker, which I have reported upstream at https://gitlab.haskell.org/ghc/ghc/-/issues/27262. A workaround is to enable {-# LANGUAGE NoDeepSubsumption #-} at the top of the file.

sauclovian-g added a commit that referenced this pull request Aug 28, 2026
sauclovian-g added a commit that referenced this pull request Aug 28, 2026
@sauclovian-g

Copy link
Copy Markdown
Contributor Author

ok, so it builds finally. I need to go check whether we still need allow-newer (and if so, file tickets upstream); then there are a couple questions to answer:

  1. What builds do we want to do going forward? My vote would be the same that we picked for Cryptol (9.6, 9.8, and 9.12 but skip 9.10).

  2. The 9.10 freeze file is for 10.1, but 10.3 is out; should we bump it? (I would vote yes)

@RyanGlScott

Copy link
Copy Markdown
Contributor

My vote would be the same that we picked for Cryptol (9.6, 9.8, and 9.12 but skip 9.10).

That sounds reasonable to me.

The 9.10 freeze file is for 10.1, but 10.3 is out; should we bump it? (I would vote yes)

I also vote yes, if that doesn't turn up any additional complications.

@sauclovian-g

Copy link
Copy Markdown
Contributor Author

That sounds reasonable to me.

Complication: the current default build is 9.10. I don't think we really want to roll that back to 9.8, and I don't think we want to roll it forward to 9.12 at the same time we first add 9.12 either.

We could drop either 9.6 or 9.8 (the latter doesn't seem entirely desirable, the former seems likely to result in periodically breaking the SAW build) or just build four versions until we are ready to drop 9.6 everywhere.

@sauclovian-g

sauclovian-g commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Ok, looks like 9.10.3 did not create complications. We just need to decide on the builds, and on Monday Tuesday I'll squash the squashable and rebase on head.

@RyanGlScott

Copy link
Copy Markdown
Contributor

I'm a bit confused: wasn't the proposal to use the same versions as in Cryptol's CI (9.6, 9.8, and 9.12 but skip 9.10)?

@sauclovian-g

Copy link
Copy Markdown
Contributor Author

It was, but currently what we build is:

  • ubuntu 24 with ghc 9.6
  • ubuntu 24 with ghc 9.8
  • ubuntu 24 with ghc 9.10
  • ubuntu 22 with ghc 9.10
  • macos 15 with ghc 9.10
  • windows 2022 with ghc 9.10

(some of the builds skip ubuntu 22, some skip windows, dunno how intentional that is)

Therefore under that plan we could do:

  • ubuntu 24 with ghc 9.6
  • ubuntu 24 with ghc 9.8
  • ubuntu 24 with ghc 9.12
  • ubuntu 22 with ghc 9.8
  • macos 15 with ghc 9.8
  • windows 2022 with ghc 9.8
  • ubuntu 24 with ghc 9.6
  • ubuntu 24 with ghc 9.8
  • ubuntu 24 with ghc 9.12
  • ubuntu 22 with ghc 9.12
  • macos 15 with ghc 9.12
  • windows 2022 with ghc 9.12

where the first winds back some of the versions (not necessarily desirable) and the second moves everything to 9.12 right away (also not necessarily desirable, especially right before a release).

Therefore I also suggested:

  • ubuntu 24 with ghc 9.6
  • ubuntu 24 with ghc 9.10
  • ubuntu 24 with ghc 9.12
  • ubuntu 22 with ghc 9.10
  • macos 15 with ghc 9.10
  • windows 2022 with ghc 9.10
    (drops 9.8)
  • ubuntu 24 with ghc 9.8
  • ubuntu 24 with ghc 9.10
  • ubuntu 24 with ghc 9.12
  • ubuntu 22 with ghc 9.10
  • macos 15 with ghc 9.10
  • windows 2022 with ghc 9.10
    (drops 9.6)
  • ubuntu 24 with ghc 9.6
  • ubuntu 24 with ghc 9.8
  • ubuntu 24 with ghc 9.10
  • ubuntu 24 with ghc 9.12
  • ubuntu 22 with ghc 9.10
  • macos 15 with ghc 9.10
  • windows 2022 with ghc 9.10
    (adds another build)

and another possible choice is

  • ubuntu 24 with ghc 9.6
  • ubuntu 24 with ghc 9.8
  • ubuntu 24 with ghc 9.12
  • ubuntu 22 with ghc 9.10
  • macos 15 with ghc 9.10
  • windows 2022 with ghc 9.10

Hopefully this is clearer...

@RyanGlScott

Copy link
Copy Markdown
Contributor

Ah, thanks for clarifying. The tension is that the current "default" GHC version in SAW's CI is one that Cryptol's CI doesn't test at all, then? I mainly suggested mirroring what Cryptol's CI does under the assumption that it would be simpler, but if it's not simpler, then we should feel free to deviate a bit.

I think option (4) would be my (slight) preference, as that picks three consecutive versions without needing to figure out the churn associated with a new default GHC version for CI.

@sauclovian-g

Copy link
Copy Markdown
Contributor Author

This is crucible :-)

(SAW's CI is currently on 9.4, 9.6, and 9.8, like Cryptol's had been before this round of changes)

The only problem with (4) is that there's some risk of accidentally introducing code that doesn't work in 9.6 and breaking the SAW build. I don't think that risk is all that high though.

I've added this to every CHANGELOG because grep suggests we've done a
very spotty job of randomly mentioning or not these changes in the
past, and there's no central place.
@sauclovian-g

Copy link
Copy Markdown
Contributor Author

I have rearranged the commits. It is still building 9.12 as well as everything else; will change that as soon as we're sure we've reached a decision.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants