Skip to content

Migrate to GHC 9.2

Fredrik Wieczerkowski requested to merge ghc-9.2 into master

This branch migrates KiCS2 to GHC 9.2. Especially on ARM machines (such as Apple's M1 Macs) the new native ARM code generator in GHC brings massive improvements in compilation performance and removes the dependency on LLVM on this architecture.

Migration Changes

GHC Unique and UniqSupply Type

These modules used by the corresponding IDSupply implementation in the runtime have been moved to GHC.Types.Unique and GHC.Types.Unique.Supply, respectively.

Deep Skolemisation

Apart from changing the Stack resolver, an issue that prevented us from bootstrapping KiCS2 with GHC 9.2 was the removal of deep skolemisation causing error messages like the following:

kics2-libraries> .../kics2/lib/.curry/kics2-3.0.0/Curry_Prelude.hs:33028:6: error:
kics2-libraries>     • Couldn't match type: forall t2. Curry t2 => C_Apply t0 t2
kics2-libraries>                      with: t0 t1
kics2-libraries>       Expected: ConstStore -> C_Apply t0 t1
kics2-libraries>         Actual: ConstStore -> forall t1. Curry t1 => C_Apply t0 t1

In short, GHC 9.2 no longer allows implicit forall floating in higher-rank functions by default. To illustrate, this example compiles under GHC 8.10, but fails on GHC 9.2:

{-# LANGUAGE RankNTypes #-}
module ForallFloating where

inner :: String -> forall a. a -> String
inner x = const x

outer :: forall a. String -> a -> String
outer = inner

Since KiCS2's generated Curry constraints rely on such conversions, we need to generate eta-expansions manually:

outer :: forall a. String -> a -> String
outer = (\x -> inner x)

The GHC manual clarifies/discusses this practice and deep skolemisation in detail.

Removal of support for NondecreasingIndentation

See GHC 9.2.1's release notes. Implicit NondecreasingIndentation has been removed, thus breaking some code output by KiCS2. This mostly seems to include external implementations, e.g. the following implementation from the Prelude where the do block's contents are aligned with the parent case:

external_d_C_bindIO :: (Curry t0, Curry t1)
  => C_IO t0 -> (t0 -> Cover -> ConstStore -> C_IO t1)
  -> Cover -> ConstStore -> C_IO t1
external_d_C_bindIO m f cd cs = C_IO $ do
  res <- searchIO errSupply cd cs m
  case res of 
    Left err -> return (Left (traceFail ("Prelude.>>=") [show m, show f] err))
    Right x  -> do
    cs1 <- lookupGlobalCs
    let cs2 = combineCs cs cs1
    searchIO errSupply cd cs2 (f x cd cs2)
  where errSupply = internalError "Prelude.(>>=): ID supply used"
Edited by Fredrik Wieczerkowski

Merge request reports