[Git][ghc/ghc][wip/sjakobi/upsert] Add `upsert` variants and replace uses of `alter`
by Simon Jakobi (@sjakobi2) 28 Mar '26
by Simon Jakobi (@sjakobi2) 28 Mar '26
28 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/upsert at Glasgow Haskell Compiler / GHC
Commits:
fe9764b8 by Simon Jakobi at 2026-03-28T02:28:34+01:00
Add `upsert` variants and replace uses of `alter`
- - - - -
18 changed files:
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/Cmm/Dataflow/Graph.hs
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/CmmToAsm/CFG.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/RoughMap.hs
- compiler/GHC/Core/TyCon/Env.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Data/FastString/Env.hs
- compiler/GHC/Data/Word64Map/Lazy.hs
- compiler/GHC/Data/Word64Map/Strict.hs
- compiler/GHC/Tc/Solver/Types.hs
- compiler/GHC/Types/Name/Env.hs
- compiler/GHC/Types/Name/Occurrence.hs
- compiler/GHC/Types/Unique/DFM.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Var/Env.hs
- compiler/GHC/Wasm/ControlFlow/FromCmm.hs
Changes:
=====================================
compiler/GHC/Cmm/CommonBlockElim.hs
=====================================
@@ -307,6 +307,6 @@ groupByInt :: (a -> Int) -> [a] -> [[a]]
groupByInt f xs = nonDetEltsUFM $ List.foldl' go emptyUFM xs
-- See Note [Unique Determinism and code generation]
where
- go m x = alterUFM addEntry m (f x)
+ go m x = upsertUFM addEntry m (f x)
where
- addEntry xs = Just $! maybe [x] (x:) xs
+ addEntry = maybe [x] (x:)
=====================================
compiler/GHC/Cmm/Dataflow/Graph.hs
=====================================
@@ -56,10 +56,10 @@ bodyToBlockList body = mapElems body
addBlock
:: (NonLocal block, HasDebugCallStack)
=> block C C -> LabelMap (block C C) -> LabelMap (block C C)
-addBlock block body = mapAlter add lbl body
+addBlock block body = mapUpsert add lbl body
where
lbl = entryLabel block
- add Nothing = Just block
+ add Nothing = block
add _ = error $ "duplicate label " ++ show lbl ++ " in graph"
=====================================
compiler/GHC/Cmm/Dataflow/Label.hs
=====================================
@@ -38,6 +38,7 @@ module GHC.Cmm.Dataflow.Label
, mapInsertWith
, mapDelete
, mapAlter
+ , mapUpsert
, mapAdjust
, mapUnion
, mapUnions
@@ -207,6 +208,9 @@ mapDelete (Label k) (LM m) = LM (M.delete k m)
mapAlter :: (Maybe v -> Maybe v) -> Label -> LabelMap v -> LabelMap v
mapAlter f (Label k) (LM m) = LM (M.alter f k m)
+mapUpsert :: (Maybe v -> v) -> Label -> LabelMap v -> LabelMap v
+mapUpsert f (Label k) (LM m) = LM (M.upsert f k m)
+
mapAdjust :: (v -> v) -> Label -> LabelMap v -> LabelMap v
mapAdjust f (Label k) (LM m) = LM (M.adjust f k m)
=====================================
compiler/GHC/CmmToAsm/CFG.hs
=====================================
@@ -357,15 +357,14 @@ addImmediateSuccessor weights node follower cfg
-- | Adds a new edge, overwrites existing edges if present
addEdge :: BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge from to info cfg =
- mapAlter addFromToEdge from $
- mapAlter addDestNode to cfg
+ mapUpsert addFromToEdge from $
+ mapUpsert addDestNode to cfg
where
-- Simply insert the edge into the edge list.
- addFromToEdge Nothing = Just $ mapSingleton to info
- addFromToEdge (Just wm) = Just $ mapInsert to info wm
+ addFromToEdge Nothing = mapSingleton to info
+ addFromToEdge (Just wm) = mapInsert to info wm
-- We must add the destination node explicitly
- addDestNode Nothing = Just $ mapEmpty
- addDestNode n@(Just _) = n
+ addDestNode = fromMaybe mapEmpty
-- | Adds a edge with the given weight to the cfg
@@ -610,11 +609,11 @@ getCfg platform weights graph =
edgelessCfg = mapFromList $ zip (map G.entryLabel blocks) (repeat mapEmpty)
insertEdge :: CFG -> ((BlockId,BlockId),EdgeInfo) -> CFG
insertEdge m ((from,to),weight) =
- mapAlter f from m
+ mapUpsert f from m
where
- f :: Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
- f Nothing = Just $ mapSingleton to weight
- f (Just destMap) = Just $ mapInsert to weight destMap
+ f :: Maybe (LabelMap EdgeInfo) -> LabelMap EdgeInfo
+ f Nothing = mapSingleton to weight
+ f (Just destMap) = mapInsert to weight destMap
getBlockEdges :: CmmBlock -> [((BlockId,BlockId),EdgeInfo)]
getBlockEdges block =
case branch of
=====================================
compiler/GHC/Core/Opt/Simplify/Iteration.hs
=====================================
@@ -4296,7 +4296,7 @@ unconditional-inlining for join points.
postInlineUnconditionally is primarily to push allocation into cold
branches; but a join point doesn't allocate, so that's a non-motivation.
-(DJ2) In mkDupableAlt and mkDupableStrictBind, generate an alterative for /all/
+(DJ2) In mkDupableAlt and mkDupableStrictBind, generate an alternative for /all/
alternatives, /except/ for ones that will definitely inline unconditionally
straight away. (In that case it's silly to make a join point in the first
place; it just takes an extra Simplifier iteration to undo.) This choice is
=====================================
compiler/GHC/Core/RoughMap.hs
=====================================
@@ -39,6 +39,7 @@ import GHC.Types.Name.Env
import Control.Monad (join)
import Data.Data (Data)
+import Data.Maybe (fromMaybe)
import GHC.Utils.Panic
{-
@@ -449,10 +450,9 @@ insertRM [] v rm@(RM {}) =
rm { rm_empty = v `consBag` rm_empty rm }
insertRM (RM_KnownTc k : ks) v rm@(RM {}) =
- rm { rm_known = alterDNameEnv f (rm_known rm) k }
+ rm { rm_known = upsertDNameEnv f (rm_known rm) k }
where
- f Nothing = Just $ (insertRM ks v emptyRM)
- f (Just m) = Just $ (insertRM ks v m)
+ f = insertRM ks v . fromMaybe emptyRM
insertRM (RM_WildCard : ks) v rm@(RM {}) =
rm { rm_wild = insertRM ks v (rm_wild rm) }
=====================================
compiler/GHC/Core/TyCon/Env.hs
=====================================
@@ -19,7 +19,7 @@ module GHC.Core.TyCon.Env (
extendTyConEnv_C, extendTyConEnv_Acc, extendTyConEnv,
extendTyConEnvList, extendTyConEnvList_C,
filterTyConEnv, anyTyConEnv,
- plusTyConEnv, plusTyConEnv_C, plusTyConEnv_CD, plusTyConEnv_CD2, alterTyConEnv,
+ plusTyConEnv, plusTyConEnv_C, plusTyConEnv_CD, plusTyConEnv_CD2, alterTyConEnv, upsertTyConEnv,
lookupTyConEnv, lookupTyConEnv_NF, delFromTyConEnv, delListFromTyConEnv,
elemTyConEnv, mapTyConEnv, disjointTyConEnv,
@@ -29,7 +29,7 @@ module GHC.Core.TyCon.Env (
lookupDTyConEnv,
delFromDTyConEnv, filterDTyConEnv,
mapDTyConEnv, mapMaybeDTyConEnv,
- adjustDTyConEnv, alterDTyConEnv, extendDTyConEnv, foldDTyConEnv
+ adjustDTyConEnv, alterDTyConEnv, upsertDTyConEnv, extendDTyConEnv, foldDTyConEnv
) where
import GHC.Prelude
@@ -57,6 +57,7 @@ mkTyConEnv :: [(TyCon,a)] -> TyConEnv a
mkTyConEnvWith :: (a -> TyCon) -> [a] -> TyConEnv a
nonDetTyConEnvElts :: TyConEnv a -> [a]
alterTyConEnv :: (Maybe a-> Maybe a) -> TyConEnv a -> TyCon -> TyConEnv a
+upsertTyConEnv :: (Maybe a -> a) -> TyConEnv a -> TyCon -> TyConEnv a
extendTyConEnv_C :: (a->a->a) -> TyConEnv a -> TyCon -> a -> TyConEnv a
extendTyConEnv_Acc :: (a->b->b) -> (a->b) -> TyConEnv b -> TyCon -> a -> TyConEnv b
extendTyConEnv :: TyConEnv a -> TyCon -> a -> TyConEnv a
@@ -85,6 +86,7 @@ extendTyConEnv x y z = addToUFM x y z
extendTyConEnvList x l = addListToUFM x l
lookupTyConEnv x y = lookupUFM x y
alterTyConEnv = alterUFM
+upsertTyConEnv = upsertUFM
mkTyConEnv l = listToUFM l
mkTyConEnvWith f = mkTyConEnv . map (\a -> (f a, a))
elemTyConEnv x y = elemUFM x y
@@ -137,6 +139,9 @@ adjustDTyConEnv = adjustUDFM
alterDTyConEnv :: (Maybe a -> Maybe a) -> DTyConEnv a -> TyCon -> DTyConEnv a
alterDTyConEnv = alterUDFM
+upsertDTyConEnv :: (Maybe a -> a) -> DTyConEnv a -> TyCon -> DTyConEnv a
+upsertDTyConEnv = upsertUDFM
+
extendDTyConEnv :: DTyConEnv a -> TyCon -> a -> DTyConEnv a
extendDTyConEnv = addToUDFM
=====================================
compiler/GHC/Core/Unify.hs
=====================================
@@ -2211,10 +2211,10 @@ extendFamEnv tc tys ty = UM $ \state ->
Unifiable (state { um_fam_env = extend (um_fam_env state) tc }, ())
where
extend :: FamSubstEnv -> TyCon -> FamSubstEnv
- extend = alterTyConEnv alter_tm
+ extend = upsertTyConEnv alter_tm
- alter_tm :: Maybe (ListMap TypeMap Type) -> Maybe (ListMap TypeMap Type)
- alter_tm m_elt = Just (alterTM tys (\_ -> Just ty) (m_elt `orElse` emptyTM))
+ alter_tm :: Maybe (ListMap TypeMap Type) -> ListMap TypeMap Type
+ alter_tm m_elt = alterTM tys (\_ -> Just ty) (m_elt `orElse` emptyTM)
umRnBndr2 :: UMEnv -> TyCoVar -> TyCoVar -> UMEnv
umRnBndr2 env v1 v2
=====================================
compiler/GHC/Data/FastString/Env.hs
=====================================
@@ -16,7 +16,7 @@ module GHC.Data.FastString.Env (
extendFsEnv_C, extendFsEnv_Acc, extendFsEnv,
extendFsEnvList, extendFsEnvList_C,
filterFsEnv,
- plusFsEnv, plusFsEnv_C, alterFsEnv,
+ plusFsEnv, plusFsEnv_C, alterFsEnv, upsertFsEnv,
lookupFsEnv, lookupFsEnv_NF, delFromFsEnv, delListFromFsEnv,
elemFsEnv, mapFsEnv, strictMapFsEnv, mapMaybeFsEnv,
nonDetFoldFsEnv,
@@ -46,6 +46,7 @@ type FastStringEnv a = UniqFM FastString a -- Domain is FastString
emptyFsEnv :: FastStringEnv a
mkFsEnv :: [(FastString,a)] -> FastStringEnv a
alterFsEnv :: (Maybe a-> Maybe a) -> FastStringEnv a -> FastString -> FastStringEnv a
+upsertFsEnv :: (Maybe a -> a) -> FastStringEnv a -> FastString -> FastStringEnv a
extendFsEnv_C :: (a->a->a) -> FastStringEnv a -> FastString -> a -> FastStringEnv a
extendFsEnv_Acc :: (a->b->b) -> (a->b) -> FastStringEnv b -> FastString -> a -> FastStringEnv b
extendFsEnv :: FastStringEnv a -> FastString -> a -> FastStringEnv a
@@ -69,6 +70,7 @@ extendFsEnv x y z = addToUFM x y z
extendFsEnvList x l = addListToUFM x l
lookupFsEnv x y = lookupUFM x y
alterFsEnv = alterUFM
+upsertFsEnv = upsertUFM
mkFsEnv l = listToUFM l
elemFsEnv x y = elemUFM x y
plusFsEnv x y = plusUFM x y
=====================================
compiler/GHC/Data/Word64Map/Lazy.hs
=====================================
@@ -91,6 +91,7 @@ module GHC.Data.Word64Map.Lazy (
, adjustWithKey
, update
, updateWithKey
+ , upsert
, updateLookupWithKey
, alter
, alterLookup
=====================================
compiler/GHC/Data/Word64Map/Strict.hs
=====================================
@@ -109,6 +109,7 @@ module GHC.Data.Word64Map.Strict (
, adjustWithKey
, update
, updateWithKey
+ , upsert
, updateLookupWithKey
, alter
, alterF
=====================================
compiler/GHC/Tc/Solver/Types.hs
=====================================
@@ -89,15 +89,15 @@ delTcApp :: TcAppMap a -> TyCon -> [Type] -> TcAppMap a
delTcApp m tc tys = adjustDTyConEnv (deleteTM tys) m tc
insertTcApp :: TcAppMap a -> TyCon -> [Type] -> a -> TcAppMap a
-insertTcApp m tc tys ct = alterDTyConEnv alter_tm m tc
+insertTcApp m tc tys ct = upsertDTyConEnv alter_tm m tc
where
- alter_tm mb_tm = Just (insertTM tys ct (mb_tm `orElse` emptyTM))
+ alter_tm mb_tm = insertTM tys ct (mb_tm `orElse` emptyTM)
alterTcApp :: forall a. TcAppMap a -> TyCon -> [Type] -> XT a -> TcAppMap a
-alterTcApp m tc tys upd = alterDTyConEnv alter_tm m tc
+alterTcApp m tc tys upd = upsertDTyConEnv alter_tm m tc
where
- alter_tm :: Maybe (ListMap LooseTypeMap a) -> Maybe (ListMap LooseTypeMap a)
- alter_tm m_elt = Just (alterTM tys upd (m_elt `orElse` emptyTM))
+ alter_tm :: Maybe (ListMap LooseTypeMap a) -> ListMap LooseTypeMap a
+ alter_tm m_elt = alterTM tys upd (m_elt `orElse` emptyTM)
filterTcAppMap :: forall a. (a -> Bool) -> TcAppMap a -> TcAppMap a
filterTcAppMap f m = mapMaybeDTyConEnv one_tycon m
=====================================
compiler/GHC/Types/Name/Env.hs
=====================================
@@ -19,7 +19,7 @@ module GHC.Types.Name.Env (
filterNameEnv, anyNameEnv,
mapMaybeNameEnv,
extendNameEnvListWith,
- plusNameEnv, plusNameEnv_C, plusNameEnv_CD, plusNameEnv_CD2, alterNameEnv,
+ plusNameEnv, plusNameEnv_C, plusNameEnv_CD, plusNameEnv_CD2, alterNameEnv, upsertNameEnv,
plusNameEnvList, plusNameEnvListWith,
lookupNameEnv, lookupNameEnv_NF, delFromNameEnv, delListFromNameEnv,
elemNameEnv, mapNameEnv, disjointNameEnv,
@@ -32,7 +32,7 @@ module GHC.Types.Name.Env (
lookupDNameEnv,
delFromDNameEnv, filterDNameEnv,
mapDNameEnv,
- adjustDNameEnv, alterDNameEnv, extendDNameEnv,
+ adjustDNameEnv, alterDNameEnv, upsertDNameEnv, extendDNameEnv,
eltsDNameEnv, extendDNameEnv_C,
plusDNameEnv_C,
foldDNameEnv,
@@ -107,6 +107,7 @@ mkNameEnvWith :: (a -> Name) -> [a] -> NameEnv a
fromUniqMap :: UniqMap Name a -> NameEnv a
nonDetNameEnvElts :: NameEnv a -> [a]
alterNameEnv :: (Maybe a-> Maybe a) -> NameEnv a -> Name -> NameEnv a
+upsertNameEnv :: (Maybe a -> a) -> NameEnv a -> Name -> NameEnv a
extendNameEnv_C :: (a->a->a) -> NameEnv a -> Name -> a -> NameEnv a
extendNameEnv_Acc :: (a->b->b) -> (a->b) -> NameEnv b -> Name -> a -> NameEnv b
extendNameEnv :: NameEnv a -> Name -> a -> NameEnv a
@@ -141,6 +142,7 @@ extendNameEnvList x l = addListToUFM x l
extendNameEnvListWith f x l = addListToUFM x (map (\a -> (f a, a)) l)
lookupNameEnv x y = lookupUFM x y
alterNameEnv = alterUFM
+upsertNameEnv = upsertUFM
mkNameEnv l = listToUFM l
mkNameEnvWith f = mkNameEnv . map (\a -> (f a, a))
fromUniqMap = mapUFM snd . getUniqMap
@@ -198,6 +200,9 @@ adjustDNameEnv = adjustUDFM
alterDNameEnv :: (Maybe a -> Maybe a) -> DNameEnv a -> Name -> DNameEnv a
alterDNameEnv = alterUDFM
+upsertDNameEnv :: (Maybe a -> a) -> DNameEnv a -> Name -> DNameEnv a
+upsertDNameEnv = upsertUDFM
+
extendDNameEnv :: DNameEnv a -> Name -> a -> DNameEnv a
extendDNameEnv = addToUDFM
=====================================
compiler/GHC/Types/Name/Occurrence.hs
=====================================
@@ -732,7 +732,7 @@ extendOccEnv_Acc f g (MkOccEnv env) (OccName ns s) =
MkOccEnv . extendFsEnv_Acc f' g' env s
where
f' :: a -> UniqFM NameSpace b -> UniqFM NameSpace b
- f' a bs = alterUFM (Just . \ case { Nothing -> g a ; Just b -> f a b }) bs ns
+ f' a bs = upsertUFM (\ case { Nothing -> g a ; Just b -> f a b }) bs ns
g' a = unitUFM ns (g a)
-- | Delete one element from an 'OccEnv'.
=====================================
compiler/GHC/Types/Unique/DFM.hs
=====================================
@@ -33,6 +33,7 @@ module GHC.Types.Unique.DFM (
adjustUDFM,
adjustUDFM_Directly,
alterUDFM,
+ upsertUDFM,
alterUDFM_L,
mapUDFM,
mapMaybeUDFM,
@@ -451,6 +452,23 @@ alterUDFM f (UDFM m i) k =
inject Nothing = Nothing
inject (Just v) = Just $ TaggedVal v i
+-- | The expression (@'upsertUDFM' f map k@) updates the value at @k@ or inserts
+-- a new value if @k@ is absent.
+--
+-- Like 'alterUDFM', updating an existing entry assigns it the current tag, so it
+-- becomes the newest element in deterministic iteration order.
+upsertUDFM
+ :: Uniquable key
+ => (Maybe elt -> elt) -- ^ How to adjust the element
+ -> UniqDFM key elt -- ^ Old 'UniqDFM'
+ -> key -- ^ @key@ of the element to adjust
+ -> UniqDFM key elt -- ^ New element at @key@ and modified 'UniqDFM'
+upsertUDFM f (UDFM m i) k =
+ UDFM (MS.upsert upsertf (getKey $ getUnique k) m) (i + 1)
+ where
+ upsertf Nothing = TaggedVal (f Nothing) i
+ upsertf (Just (TaggedVal v _)) = TaggedVal (f (Just v)) i
+
-- | The expression (@'alterUDFM_L' f map k@) alters value @x@ at @k@, or absence
-- thereof and returns the new element at @k@ if there is any.
-- 'alterUDFM_L' can be used to insert, delete, or update a value in
=====================================
compiler/GHC/Types/Unique/FM.hs
=====================================
@@ -42,7 +42,7 @@ module GHC.Types.Unique.FM (
addListToUFM,addListToUFM_C,
addToUFM_Directly,
addListToUFM_Directly,
- adjustUFM, alterUFM, alterUFM_L, alterUFM_Directly,
+ adjustUFM, alterUFM, upsertUFM, alterUFM_L, alterUFM_Directly,
adjustUFM_Directly,
delFromUFM,
delFromUFM_Directly,
@@ -226,6 +226,14 @@ alterUFM
-> UniqFM key elt -- ^ result
alterUFM f (UFM m) k = UFM (M.alter f (getKey $ getUnique k) m)
+upsertUFM
+ :: Uniquable key
+ => (Maybe elt -> elt) -- ^ How to adjust
+ -> UniqFM key elt -- ^ old
+ -> key -- ^ new
+ -> UniqFM key elt -- ^ result
+upsertUFM f (UFM m) k = UFM (M.upsert f (getKey $ getUnique k) m)
+
alterUFM_L
:: Uniquable key
=> (Maybe elt -> Maybe elt) -- ^ How to adjust
=====================================
compiler/GHC/Types/Var/Env.hs
=====================================
@@ -15,7 +15,7 @@ module GHC.Types.Var.Env (
strictPlusVarEnv, plusVarEnv, plusVarEnv_C,
strictPlusVarEnv_C, strictPlusVarEnv_C_Directly,
plusVarEnv_CD, plusMaybeVarEnv_C,
- plusVarEnvList, alterVarEnv,
+ plusVarEnvList, alterVarEnv, upsertVarEnv,
delVarEnvList, delVarEnv,
minusVarEnv,
lookupVarEnv, lookupVarEnv_NF, lookupWithDefaultVarEnv,
@@ -40,7 +40,7 @@ module GHC.Types.Var.Env (
isEmptyDVarEnv, foldDVarEnv, nonDetStrictFoldDVarEnv,
mapDVarEnv, filterDVarEnv,
modifyDVarEnv,
- alterDVarEnv,
+ alterDVarEnv, upsertDVarEnv,
plusDVarEnv, plusDVarEnv_C,
unitDVarEnv,
delDVarEnv,
@@ -509,6 +509,7 @@ mkVarEnv_Directly :: [(Unique, a)] -> VarEnv a
zipVarEnv :: [Var] -> [a] -> VarEnv a
unitVarEnv :: Var -> a -> VarEnv a
alterVarEnv :: (Maybe a -> Maybe a) -> VarEnv a -> Var -> VarEnv a
+upsertVarEnv :: (Maybe a -> a) -> VarEnv a -> Var -> VarEnv a
extendVarEnv :: VarEnv a -> Var -> a -> VarEnv a
extendVarEnv_C :: (a->a->a) -> VarEnv a -> Var -> a -> VarEnv a
extendVarEnv_Acc :: (a->b->b) -> (a->b) -> VarEnv b -> Var -> a -> VarEnv b
@@ -548,6 +549,7 @@ elemVarEnv = elemUFM
elemVarEnvByKey = elemUFM_Directly
disjointVarEnv = disjointUFM
alterVarEnv = alterUFM
+upsertVarEnv = upsertUFM
extendVarEnv = addToUFM
extendVarEnv_C = addToUFM_C
extendVarEnv_Acc = addToUFM_Acc
@@ -671,6 +673,9 @@ mapMaybeDVarEnv f = mapMaybeUDFM f
alterDVarEnv :: (Maybe a -> Maybe a) -> DVarEnv a -> Var -> DVarEnv a
alterDVarEnv = alterUDFM
+upsertDVarEnv :: (Maybe a -> a) -> DVarEnv a -> Var -> DVarEnv a
+upsertDVarEnv = upsertUDFM
+
plusDVarEnv :: DVarEnv a -> DVarEnv a -> DVarEnv a
plusDVarEnv = plusUDFM
=====================================
compiler/GHC/Wasm/ControlFlow/FromCmm.hs
=====================================
@@ -9,6 +9,7 @@ import GHC.Prelude hiding (succ)
import Data.Function
import Data.List (sortBy)
+import Data.Maybe (fromMaybe)
import qualified Data.Tree as Tree
import GHC.Cmm
@@ -330,9 +331,8 @@ smartPlus platform e k =
where width = cmmExprWidth platform e
addToList :: ([a] -> [a]) -> Label -> LabelMap [a] -> LabelMap [a]
-addToList consx = mapAlter add
- where add Nothing = Just (consx [])
- add (Just xs) = Just (consx xs)
+addToList consx = mapUpsert add
+ where add = consx . fromMaybe []
------------------------------------------------------------------
--- everything below here is for diagnostics in case of panic
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe9764b85a682a309411d02aa40a78a…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe9764b85a682a309411d02aa40a78a…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/elem-tests] Improve tests for `elem`
by Simon Jakobi (@sjakobi2) 28 Mar '26
by Simon Jakobi (@sjakobi2) 28 Mar '26
28 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/elem-tests at Glasgow Haskell Compiler / GHC
Commits:
595f5c40 by Simon Jakobi at 2026-03-28T01:05:08+01:00
Improve tests for `elem`
* Improve T17752 by including the Core output in golden files, checking
all of -O0, -O1 and -O2.
* Add tests for fusion and no-fusion cases.
Fixes #27101.
- - - - -
13 changed files:
- + libraries/base/tests/perf/ElemFusionUnknownList.hs
- + libraries/base/tests/perf/ElemFusionUnknownList_O1.stderr
- + libraries/base/tests/perf/ElemFusionUnknownList_O2.stderr
- + libraries/base/tests/perf/ElemNoFusion.hs
- + libraries/base/tests/perf/ElemNoFusion_O1.stderr
- + libraries/base/tests/perf/ElemNoFusion_O2.stderr
- − libraries/base/tests/perf/Makefile
- libraries/base/tests/perf/T17752.hs
- − libraries/base/tests/perf/T17752.stdout
- + libraries/base/tests/perf/T17752_O0.stderr
- + libraries/base/tests/perf/T17752_O1.stderr
- + libraries/base/tests/perf/T17752_O2.stderr
- libraries/base/tests/perf/all.T
Changes:
=====================================
libraries/base/tests/perf/ElemFusionUnknownList.hs
=====================================
@@ -0,0 +1,14 @@
+-- We expect `elem` to fuse with good producers such as `map` and `concatMap`.
+module ElemFusionUnknownList where
+
+fusionElemMap :: Int -> [Int] -> Bool
+fusionElemMap x = elem x . map (+1)
+
+fusionNotElemMap :: Int -> [Int] -> Bool
+fusionNotElemMap x = notElem x . map (+1)
+
+fusionElemConcatMap :: Int -> [Int] -> Bool
+fusionElemConcatMap x = elem x . concatMap (\y -> [y + 1, y + 2])
+
+fusionNotElemConcatMap :: Int -> [Int] -> Bool
+fusionNotElemConcatMap x = notElem x . concatMap (\y -> [y + 1, y + 2])
=====================================
libraries/base/tests/perf/ElemFusionUnknownList_O1.stderr
=====================================
@@ -0,0 +1,80 @@
+fusionNotElemConcatMap
+ = \ x x1 ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> True;
+ : y ys ->
+ case y of { I# x2 ->
+ case x of { I# x3 ->
+ case ==# x3 (+# x2 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x2 2#) of {
+ __DEFAULT -> jump go1 ys;
+ 1# -> False
+ };
+ 1# -> False
+ }
+ }
+ }
+ }; } in
+ jump go1 x1
+
+fusionElemConcatMap
+ = \ x x1 ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> False;
+ : y ys ->
+ case y of { I# x2 ->
+ case x of { I# x3 ->
+ case ==# x3 (+# x2 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x2 2#) of {
+ __DEFAULT -> jump go1 ys;
+ 1# -> True
+ };
+ 1# -> True
+ }
+ }
+ }
+ }; } in
+ jump go1 x1
+
+fusionNotElemMap
+ = \ x eta ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> True;
+ : y ys ->
+ case x of { I# x1 ->
+ case y of { I# x2 ->
+ case ==# x1 (+# x2 1#) of {
+ __DEFAULT -> jump go1 ys;
+ 1# -> False
+ }
+ }
+ }
+ }; } in
+ jump go1 eta
+
+fusionElemMap
+ = \ x eta ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> False;
+ : y ys ->
+ case x of { I# x1 ->
+ case y of { I# x2 ->
+ case ==# x1 (+# x2 1#) of {
+ __DEFAULT -> jump go1 ys;
+ 1# -> True
+ }
+ }
+ }
+ }; } in
+ jump go1 eta
+
=====================================
libraries/base/tests/perf/ElemFusionUnknownList_O2.stderr
=====================================
@@ -0,0 +1,128 @@
+fusionNotElemConcatMap
+ = \ x x1 ->
+ case x1 of {
+ [] -> True;
+ : y ys ->
+ case y of { I# x2 ->
+ case x of { I# x3 ->
+ case ==# x3 (+# x2 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x2 2#) of {
+ __DEFAULT ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> True;
+ : y1 ys1 ->
+ case y1 of { I# x4 ->
+ case ==# x3 (+# x4 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x4 2#) of {
+ __DEFAULT -> jump go1 ys1;
+ 1# -> False
+ };
+ 1# -> False
+ }
+ }
+ }; } in
+ jump go1 ys;
+ 1# -> False
+ };
+ 1# -> False
+ }
+ }
+ }
+ }
+
+fusionElemConcatMap
+ = \ x x1 ->
+ case x1 of {
+ [] -> False;
+ : y ys ->
+ case y of { I# x2 ->
+ case x of { I# x3 ->
+ case ==# x3 (+# x2 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x2 2#) of {
+ __DEFAULT ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> False;
+ : y1 ys1 ->
+ case y1 of { I# x4 ->
+ case ==# x3 (+# x4 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x4 2#) of {
+ __DEFAULT -> jump go1 ys1;
+ 1# -> True
+ };
+ 1# -> True
+ }
+ }
+ }; } in
+ jump go1 ys;
+ 1# -> True
+ };
+ 1# -> True
+ }
+ }
+ }
+ }
+
+fusionNotElemMap
+ = \ x eta ->
+ case eta of {
+ [] -> True;
+ : y ys ->
+ case x of { I# x1 ->
+ case y of { I# x2 ->
+ case ==# x1 (+# x2 1#) of {
+ __DEFAULT ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> True;
+ : y1 ys1 ->
+ case y1 of { I# x3 ->
+ case ==# x1 (+# x3 1#) of {
+ __DEFAULT -> jump go1 ys1;
+ 1# -> False
+ }
+ }
+ }; } in
+ jump go1 ys;
+ 1# -> False
+ }
+ }
+ }
+ }
+
+fusionElemMap
+ = \ x eta ->
+ case eta of {
+ [] -> False;
+ : y ys ->
+ case x of { I# x1 ->
+ case y of { I# x2 ->
+ case ==# x1 (+# x2 1#) of {
+ __DEFAULT ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> False;
+ : y1 ys1 ->
+ case y1 of { I# x3 ->
+ case ==# x1 (+# x3 1#) of {
+ __DEFAULT -> jump go1 ys1;
+ 1# -> True
+ }
+ }
+ }; } in
+ jump go1 ys;
+ 1# -> True
+ }
+ }
+ }
+ }
+
=====================================
libraries/base/tests/perf/ElemNoFusion.hs
=====================================
@@ -0,0 +1,14 @@
+-- As of March 2026, we don't expect `elem` to fuse with `sort` or `NonEmpty.toList`.
+-- `elem` isn't even specialized, and performs dictionary-passing, but that may
+-- change: #27096
+module ElemNoFusion where
+
+import Data.List (sort)
+import Data.List.NonEmpty (NonEmpty)
+import qualified Data.List.NonEmpty as NonEmpty
+
+noFusionElemNonEmptyToList :: Int -> NonEmpty Int -> Bool
+noFusionElemNonEmptyToList x = elem x . NonEmpty.toList
+
+noFusionElemSort :: Int -> [Int] -> Bool
+noFusionElemSort x = elem x . sort
=====================================
libraries/base/tests/perf/ElemNoFusion_O1.stderr
=====================================
@@ -0,0 +1,5 @@
+noFusionElemSort = \ x x1 -> elem $fEqInt x (actualSort gtInt x1)
+
+noFusionElemNonEmptyToList
+ = \ x x1 -> case x1 of { :| a1 as -> elem $fEqInt x (: a1 as) }
+
=====================================
libraries/base/tests/perf/ElemNoFusion_O2.stderr
=====================================
@@ -0,0 +1,5 @@
+noFusionElemSort = \ x x1 -> elem $fEqInt x (actualSort gtInt x1)
+
+noFusionElemNonEmptyToList
+ = \ x x1 -> case x1 of { :| a1 as -> elem $fEqInt x (: a1 as) }
+
=====================================
libraries/base/tests/perf/Makefile deleted
=====================================
@@ -1,15 +0,0 @@
-# This Makefile runs the tests using GHC's testsuite framework. It
-# assumes the package is part of a GHC build tree with the testsuite
-# installed in ../../../testsuite.
-
-TOP=../../../../testsuite
-include $(TOP)/mk/boilerplate.mk
-include $(TOP)/mk/test.mk
-
-
-T17752:
- '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques -dsuppress-all
- # All occurrences of elem should be optimized away.
- # For strings these should result in loops after inlining foldCString.
- # For lists it should result in a case expression.
- echo $$(grep -A4 "elem" T17752.dump-simpl)
=====================================
libraries/base/tests/perf/T17752.hs
=====================================
@@ -6,7 +6,7 @@ module T17752 where
-- Should compile to a pattern match if the rules fire
isElemList x = x `elem` ['a','b','c']
-isNotElemList x = x `elem` ['x','y','z']
+isNotElemList x = x `notElem` ['x','y','z']
isOneOfThese x = x `elem` [1,2,3,4,5::Int]
isNotOneOfThese x = x `notElem` [1,2,3,4,5::Int]
=====================================
libraries/base/tests/perf/T17752.stdout deleted
=====================================
@@ -1,2 +0,0 @@
-[1 of 1] Compiling T17752 ( T17752.hs, T17752.o )
-
=====================================
libraries/base/tests/perf/T17752_O0.stderr
=====================================
@@ -0,0 +1,47 @@
+isElemList
+ = \ x ->
+ elem
+ $fFoldableList
+ $fEqChar
+ x
+ (: (C# 'a'#) (: (C# 'b'#) (: (C# 'c'#) [])))
+
+isNotElemList
+ = \ x ->
+ notElem
+ $fFoldableList
+ $fEqChar
+ x
+ (: (C# 'x'#) (: (C# 'y'#) (: (C# 'z'#) [])))
+
+isOneOfThese
+ = \ x ->
+ elem
+ $fFoldableList
+ $fEqInt
+ x
+ (: (I# 1#) (: (I# 2#) (: (I# 3#) (: (I# 4#) (: (I# 5#) [])))))
+
+isNotOneOfThese
+ = \ x ->
+ notElem
+ $fFoldableList
+ $fEqInt
+ x
+ (: (I# 1#) (: (I# 2#) (: (I# 3#) (: (I# 4#) (: (I# 5#) [])))))
+
+isElemString
+ = \ x -> elem $fFoldableList $fEqChar x (unpackCString# "foo"#)
+
+isNotElemString
+ = \ x -> notElem $fFoldableList $fEqChar x (unpackCString# "bar"#)
+
+isElemStringUtf
+ = \ x ->
+ elem $fFoldableList $fEqChar x (unpackCStringUtf8# "fo\\195\\182"#)
+
+isNotElemStringUtf
+ = \ x ->
+ notElem
+ $fFoldableList $fEqChar x (unpackCStringUtf8# "b\\195\\164r"#)
+
=====================================
libraries/base/tests/perf/T17752_O1.stderr
=====================================
@@ -0,0 +1,118 @@
+isElemList
+ = \ x ->
+ case x of { C# x1 ->
+ case x1 of {
+ __DEFAULT -> False;
+ 'a'# -> True;
+ 'b'# -> True;
+ 'c'# -> True
+ }
+ }
+
+isNotElemList
+ = \ x ->
+ case x of { C# x1 ->
+ case x1 of {
+ __DEFAULT -> True;
+ 'x'# -> False;
+ 'y'# -> False;
+ 'z'# -> False
+ }
+ }
+
+isOneOfThese
+ = \ x ->
+ case x of { I# x1 ->
+ case x1 of {
+ __DEFAULT -> False;
+ 1# -> True;
+ 2# -> True;
+ 3# -> True;
+ 4# -> True;
+ 5# -> True
+ }
+ }
+
+isNotOneOfThese
+ = \ x ->
+ case x of { I# x1 ->
+ case x1 of {
+ __DEFAULT -> True;
+ 1# -> False;
+ 2# -> False;
+ 3# -> False;
+ 4# -> False;
+ 5# -> False
+ }
+ }
+
+isElemString
+ = \ x ->
+ joinrec {
+ go addr z
+ = case indexCharOffAddr# addr 0# of ch {
+ __DEFAULT ->
+ case x of { C# x1 ->
+ case eqChar# x1 ch of {
+ __DEFAULT -> jump go (plusAddr# addr 1#) z;
+ 1# -> True
+ }
+ };
+ '\NUL'# -> z
+ }; } in
+ jump go isElemString1 False
+
+isNotElemString
+ = \ x ->
+ joinrec {
+ go addr z
+ = case indexCharOffAddr# addr 0# of ch {
+ __DEFAULT ->
+ case x of { C# x1 ->
+ case eqChar# x1 ch of {
+ __DEFAULT -> jump go (plusAddr# addr 1#) z;
+ 1# -> False
+ }
+ };
+ '\NUL'# ->
+ case z of {
+ False -> True;
+ True -> False
+ }
+ }; } in
+ jump go isNotElemString1 False
+
+isElemStringUtf
+ = \ x ->
+ unpackFoldrCStringUtf8#
+ isElemStringUtf1
+ (\ y r ->
+ case x of { C# x1 ->
+ case y of { C# y1 ->
+ case eqChar# x1 y1 of {
+ __DEFAULT -> r;
+ 1# -> True
+ }
+ }
+ })
+ False
+
+isNotElemStringUtf
+ = \ x ->
+ case unpackFoldrCStringUtf8#
+ isNotElemStringUtf1
+ (\ y r ->
+ case x of { C# x1 ->
+ case y of { C# y1 ->
+ case eqChar# x1 y1 of {
+ __DEFAULT -> r;
+ 1# -> True
+ }
+ }
+ })
+ False
+ of {
+ False -> True;
+ True -> False
+ }
+
=====================================
libraries/base/tests/perf/T17752_O2.stderr
=====================================
@@ -0,0 +1,130 @@
+isElemList
+ = \ x ->
+ case x of { C# x1 ->
+ case x1 of {
+ __DEFAULT -> False;
+ 'a'# -> True;
+ 'b'# -> True;
+ 'c'# -> True
+ }
+ }
+
+isNotElemList
+ = \ x ->
+ case x of { C# x1 ->
+ case x1 of {
+ __DEFAULT -> True;
+ 'x'# -> False;
+ 'y'# -> False;
+ 'z'# -> False
+ }
+ }
+
+isOneOfThese
+ = \ x ->
+ case x of { I# x1 ->
+ case x1 of {
+ __DEFAULT -> False;
+ 1# -> True;
+ 2# -> True;
+ 3# -> True;
+ 4# -> True;
+ 5# -> True
+ }
+ }
+
+isNotOneOfThese
+ = \ x ->
+ case x of { I# x1 ->
+ case x1 of {
+ __DEFAULT -> True;
+ 1# -> False;
+ 2# -> False;
+ 3# -> False;
+ 4# -> False;
+ 5# -> False
+ }
+ }
+
+isElemString
+ = \ x ->
+ case indexCharOffAddr# isElemString1 0# of ch {
+ __DEFAULT ->
+ case x of { C# x1 ->
+ case eqChar# x1 ch of {
+ __DEFAULT ->
+ joinrec {
+ go addr z
+ = case indexCharOffAddr# addr 0# of ch1 {
+ __DEFAULT ->
+ case eqChar# x1 ch1 of {
+ __DEFAULT -> jump go (plusAddr# addr 1#) z;
+ 1# -> True
+ };
+ '\NUL'# -> z
+ }; } in
+ jump go (plusAddr# isElemString1 1#) False;
+ 1# -> True
+ }
+ };
+ '\NUL'# -> False
+ }
+
+isNotElemString
+ = \ x ->
+ case indexCharOffAddr# isNotElemString1 0# of ch {
+ __DEFAULT ->
+ case x of { C# x1 ->
+ case eqChar# x1 ch of {
+ __DEFAULT ->
+ joinrec {
+ $sgo sc
+ = case indexCharOffAddr# sc 0# of ch1 {
+ __DEFAULT ->
+ case eqChar# x1 ch1 of {
+ __DEFAULT -> jump $sgo (plusAddr# sc 1#);
+ 1# -> False
+ };
+ '\NUL'# -> True
+ }; } in
+ jump $sgo (plusAddr# isNotElemString1 1#);
+ 1# -> False
+ }
+ };
+ '\NUL'# -> True
+ }
+
+isElemStringUtf
+ = \ x ->
+ unpackFoldrCStringUtf8#
+ isElemStringUtf1
+ (\ y r ->
+ case x of { C# x1 ->
+ case y of { C# y1 ->
+ case eqChar# x1 y1 of {
+ __DEFAULT -> r;
+ 1# -> True
+ }
+ }
+ })
+ False
+
+isNotElemStringUtf
+ = \ x ->
+ case unpackFoldrCStringUtf8#
+ isNotElemStringUtf1
+ (\ y r ->
+ case x of { C# x1 ->
+ case y of { C# y1 ->
+ case eqChar# x1 y1 of {
+ __DEFAULT -> r;
+ 1# -> True
+ }
+ }
+ })
+ False
+ of {
+ False -> True;
+ True -> False
+ }
+
=====================================
libraries/base/tests/perf/all.T
=====================================
@@ -2,10 +2,26 @@
setTestOpts(js_skip)
#--------------------------------------
-# Check specialization of elem via rules
+# Check optimization of `elem`
#--------------------------------------
-test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752'])
+elemCoreFilter = "sed -En '/^(is|fusion|noFusion)[A-Za-z]*($| )/,/^$/p'"
+
+def elemCoreTest(test_name, module_name, opt):
+ test(test_name,
+ [only_ways(['normal']), extra_files([module_name + '.hs'])],
+ multimod_compile_filter,
+ [module_name,
+ f'{opt} -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
+ elemCoreFilter])
+
+elemCoreTest('T17752_O0', 'T17752', '-O0')
+elemCoreTest('T17752_O1', 'T17752', '-O1')
+elemCoreTest('T17752_O2', 'T17752', '-O2')
+elemCoreTest('ElemFusionUnknownList_O1', 'ElemFusionUnknownList', '-O1')
+elemCoreTest('ElemFusionUnknownList_O2', 'ElemFusionUnknownList', '-O2')
+elemCoreTest('ElemNoFusion_O1', 'ElemNoFusion', '-O1')
+elemCoreTest('ElemNoFusion_O2', 'ElemNoFusion', '-O2')
#--------------------------------------
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/595f5c40bc04ec75c5a9ec9c6de0583…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/595f5c40bc04ec75c5a9ec9c6de0583…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
27 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/elem-tests at Glasgow Haskell Compiler / GHC
Commits:
1c398cf8 by Simon Jakobi at 2026-03-28T00:28:13+01:00
Refactor all.T
- - - - -
1 changed file:
- libraries/base/tests/perf/all.T
Changes:
=====================================
libraries/base/tests/perf/all.T
=====================================
@@ -5,54 +5,23 @@ setTestOpts(js_skip)
# Check specialization of elem via rules
#--------------------------------------
-test('T17752_O0',
- [only_ways(['normal']), extra_files(['T17752.hs'])],
- multimod_compile_filter,
- ['T17752',
- '-O0 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
- "sed -n '/^is[A-Za-z]*$/,/^$/p'"])
-
-test('T17752_O1',
- [only_ways(['normal']), extra_files(['T17752.hs'])],
- multimod_compile_filter,
- ['T17752',
- '-O1 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
- "sed -n '/^is[A-Za-z]*$/,/^$/p'"])
-
-test('T17752_O2',
- [only_ways(['normal']), extra_files(['T17752.hs'])],
- multimod_compile_filter,
- ['T17752',
- '-O2 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
- "sed -n '/^is[A-Za-z]*$/,/^$/p'"])
-
-test('ElemFusionUnknownList_O1',
- [only_ways(['normal']), extra_files(['ElemFusionUnknownList.hs'])],
- multimod_compile_filter,
- ['ElemFusionUnknownList',
- '-O1 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
- "sed -n '/^fusion[A-Za-z]*$/,/^$/p'"])
-
-test('ElemFusionUnknownList_O2',
- [only_ways(['normal']), extra_files(['ElemFusionUnknownList.hs'])],
- multimod_compile_filter,
- ['ElemFusionUnknownList',
- '-O2 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
- "sed -n '/^fusion[A-Za-z]*$/,/^$/p'"])
-
-test('ElemNoFusion_O1',
- [only_ways(['normal']), extra_files(['ElemNoFusion.hs'])],
- multimod_compile_filter,
- ['ElemNoFusion',
- '-O1 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
- "sed -n '/^noFusion[A-Za-z]*/,/^$/p'"])
-
-test('ElemNoFusion_O2',
- [only_ways(['normal']), extra_files(['ElemNoFusion.hs'])],
- multimod_compile_filter,
- ['ElemNoFusion',
- '-O2 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
- "sed -n '/^noFusion[A-Za-z]*/,/^$/p'"])
+elemCoreFilter = "sed -En '/^(is|fusion|noFusion)[A-Za-z]*($| )/,/^$/p'"
+
+def elemCoreTest(test_name, module_name, opt):
+ test(test_name,
+ [only_ways(['normal']), extra_files([module_name + '.hs'])],
+ multimod_compile_filter,
+ [module_name,
+ f'{opt} -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
+ elemCoreFilter])
+
+elemCoreTest('T17752_O0', 'T17752', '-O0')
+elemCoreTest('T17752_O1', 'T17752', '-O1')
+elemCoreTest('T17752_O2', 'T17752', '-O2')
+elemCoreTest('ElemFusionUnknownList_O1', 'ElemFusionUnknownList', '-O1')
+elemCoreTest('ElemFusionUnknownList_O2', 'ElemFusionUnknownList', '-O2')
+elemCoreTest('ElemNoFusion_O1', 'ElemNoFusion', '-O1')
+elemCoreTest('ElemNoFusion_O2', 'ElemNoFusion', '-O2')
#--------------------------------------
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c398cf8508db140657d7a4ce4196ca…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c398cf8508db140657d7a4ce4196ca…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/int-index/unify-status] Status check for the HsType~HsExpr refactoring (#25121)
by Vladislav Zavialov (@int-index) 27 Mar '26
by Vladislav Zavialov (@int-index) 27 Mar '26
27 Mar '26
Vladislav Zavialov pushed to branch wip/int-index/unify-status at Glasgow Haskell Compiler / GHC
Commits:
13fdff31 by Vladislav Zavialov at 2026-03-28T01:44:57+03:00
Status check for the HsType~HsExpr refactoring (#25121)
Add a test case to track the status of a refactoring project within GHC
whose goal is to arrive at the following declaration:
type HsType = HsExpr
The rationale for this is to increase code reuse between the term- and
type-level code in the compiler front-end (AST, parser, renamer, type checker).
The status report is saved to testsuite/tests/ghc-api/T25121_status.stdout
and provides useful insights into what needs to happen to make progress on
the ticket.
- - - - -
3 changed files:
- + testsuite/tests/ghc-api/T25121_status.hs
- + testsuite/tests/ghc-api/T25121_status.stdout
- testsuite/tests/ghc-api/all.T
Changes:
=====================================
testsuite/tests/ghc-api/T25121_status.hs
=====================================
@@ -0,0 +1,127 @@
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE RequiredTypeArguments #-}
+{-# LANGUAGE TypeAbstractions #-}
+{-# LANGUAGE ExplicitNamespaces #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Main where
+
+import Type.Reflection
+import GHC.Hs
+
+main :: IO ()
+main = do
+ checkAllExtFields
+ checkAllDirectFields
+
+checkAllExtFields :: IO ()
+checkAllExtFields = do
+ -- No corresponding HsExpr: HsListTy HsTupleTy HsSumTy HsIParamTy HsDocTy
+
+ putStrLn "Extension fields @GhcPs\n-----------------------"
+ checkExtField "Var" (HsVar @GhcPs) (HsTyVar @GhcPs)
+ checkExtField "LitE" (HsLit @GhcPs) (HsTyLit @GhcPs)
+ checkExtField "Par" (HsPar @GhcPs) (HsParTy @GhcPs)
+ checkExtField "App" (HsApp @GhcPs) (HsAppTy @GhcPs)
+ checkExtField "AppTypeE" (HsAppType @GhcPs) (HsAppKindTy @GhcPs)
+ checkExtField "OpApp" (OpApp @GhcPs) (HsOpTy @GhcPs)
+ checkExtField "ForAll" (HsForAll @GhcPs) (HsForAllTy @GhcPs)
+ checkExtField "Qual" (HsQual @GhcPs) (HsQualTy @GhcPs)
+ checkExtField "Star" (HsStar @GhcPs) (HsStarTy @GhcPs)
+ checkExtField "FunArr" (HsFunArr @GhcPs) (HsFunTy @GhcPs)
+ checkExtField "ExprWithTySig" (ExprWithTySig @GhcPs) (HsKindSig @GhcPs)
+ checkExtField "UntypedSplice" (HsUntypedSplice @GhcPs) (HsSpliceTy @GhcPs)
+ checkExtField "ExplicitList" (ExplicitList @GhcPs) (HsExplicitListTy @GhcPs)
+ checkExtField "ExplicitTuple" (ExplicitTuple @GhcPs) (HsExplicitTupleTy @GhcPs)
+ checkExtField "Hole" (HsHole @GhcPs) (HsWildCardTy @GhcPs)
+
+ putStrLn "\nExtension fields @GhcRn\n-----------------------"
+ checkExtField "Var" (HsVar @GhcRn) (HsTyVar @GhcRn)
+ checkExtField "LitE" (HsLit @GhcRn) (HsTyLit @GhcRn)
+ checkExtField "Par" (HsPar @GhcRn) (HsParTy @GhcRn)
+ checkExtField "App" (HsApp @GhcRn) (HsAppTy @GhcRn)
+ checkExtField "AppTypeE" (HsAppType @GhcRn) (HsAppKindTy @GhcRn)
+ checkExtField "OpApp" (OpApp @GhcRn) (HsOpTy @GhcRn)
+ checkExtField "ForAll" (HsForAll @GhcRn) (HsForAllTy @GhcRn)
+ checkExtField "Qual" (HsQual @GhcRn) (HsQualTy @GhcRn)
+ checkExtField "Star" (HsStar @GhcRn) (HsStarTy @GhcRn)
+ checkExtField "FunArr" (HsFunArr @GhcRn) (HsFunTy @GhcRn)
+ checkExtField "ExprWithTySig" (ExprWithTySig @GhcRn) (HsKindSig @GhcRn)
+ checkExtField "UntypedSplice" (HsUntypedSplice @GhcRn) (HsSpliceTy @GhcRn)
+ checkExtField "ExplicitList" (ExplicitList @GhcRn) (HsExplicitListTy @GhcRn)
+ checkExtField "ExplicitTuple" (ExplicitTuple @GhcRn) (HsExplicitTupleTy @GhcRn)
+ checkExtField "Hole" (HsHole @GhcRn) (HsWildCardTy @GhcRn)
+
+ putStrLn "\nExtension fields @GhcTc\n-----------------------"
+ checkExtField "Var" (HsVar @GhcTc) (HsTyVar @GhcTc)
+ checkExtField "LitE" (HsLit @GhcTc) (HsTyLit @GhcTc)
+ checkExtField "Par" (HsPar @GhcTc) (HsParTy @GhcTc)
+ checkExtField "App" (HsApp @GhcTc) (HsAppTy @GhcTc)
+ checkExtField "AppTypeE" (HsAppType @GhcTc) (HsAppKindTy @GhcTc)
+ checkExtField "OpApp" (OpApp @GhcTc) (HsOpTy @GhcTc)
+ checkExtField "ForAll" (HsForAll @GhcTc) (HsForAllTy @GhcTc)
+ checkExtField "Qual" (HsQual @GhcTc) (HsQualTy @GhcTc)
+ checkExtField "Star" (HsStar @GhcTc) (HsStarTy @GhcTc)
+ checkExtField "FunArr" (HsFunArr @GhcTc) (HsFunTy @GhcTc)
+ checkExtField "ExprWithTySig" (ExprWithTySig @GhcTc) (HsKindSig @GhcTc)
+ checkExtField "UntypedSplice" (HsUntypedSplice @GhcTc) (HsSpliceTy @GhcTc)
+ checkExtField "ExplicitList" (ExplicitList @GhcTc) (HsExplicitListTy @GhcTc)
+ checkExtField "ExplicitTuple" (ExplicitTuple @GhcTc) (HsExplicitTupleTy @GhcTc)
+ checkExtField "Hole" (HsHole @GhcTc) (HsWildCardTy @GhcTc)
+
+checkAllDirectFields :: IO ()
+checkAllDirectFields = do
+ -- No corresponding HsExpr: HsListTy HsTupleTy HsSumTy HsIParamTy HsDocTy
+ putStrLn "\nDirect fields\n-------------"
+ checkDirectFields "Var" (HsVar @GhcPs) (HsTyVar @GhcPs)
+ checkDirectFields "LitE" (HsLit @GhcPs) (HsTyLit @GhcPs)
+ checkDirectFields "Par" (HsPar @GhcPs) (HsParTy @GhcPs)
+ checkDirectFields "App" (HsApp @GhcPs) (HsAppTy @GhcPs)
+ checkDirectFields "AppTypeE" (HsAppType @GhcPs) (HsAppKindTy @GhcPs)
+ checkDirectFields "OpApp" (OpApp @GhcPs) (HsOpTy @GhcPs)
+ checkDirectFields "ForAll" (HsForAll @GhcPs) (HsForAllTy @GhcPs)
+ checkDirectFields "Qual" (HsQual @GhcPs) (HsQualTy @GhcPs)
+ checkDirectFields "Star" (HsStar @GhcPs) (HsStarTy @GhcPs)
+ checkDirectFields "FunArr" (HsFunArr @GhcPs) (HsFunTy @GhcPs)
+ checkDirectFields "ExprWithTySig" (ExprWithTySig @GhcPs) (HsKindSig @GhcPs)
+ checkDirectFields "UntypedSplice" (HsUntypedSplice @GhcPs) (HsSpliceTy @GhcPs)
+ checkDirectFields "ExplicitList" (ExplicitList @GhcPs) (HsExplicitListTy @GhcPs)
+ checkDirectFields "ExplicitTuple" (ExplicitTuple @GhcPs) (HsExplicitTupleTy @GhcPs)
+ checkDirectFields "Hole" (HsHole @GhcPs) (HsWildCardTy @GhcPs)
+
+data P -- placeholder for the pass
+
+type Replace :: k -> k
+type family Replace t where
+ Replace (GhcPass _) = P
+ Replace HsType = HsExpr
+ Replace (f a) = Replace f (Replace a)
+ Replace t = t
+
+checkDirectFields :: forall r1 r2. String ->
+ forall x1 x2. forall (con1 :: x1 -> r1) (con2 :: x2 -> r2) ->
+ (Typeable (Replace r1), Typeable (Replace r2)) => IO ()
+checkDirectFields @r1 @r2 ctx _ _ =
+ let aRep = typeRep @(Replace r1)
+ bRep = typeRep @(Replace r2)
+ in case eqTypeRep aRep bRep of
+ Nothing -> do
+ putStrLn $ "T(" ++ ctx ++ ") mismatch"
+ putStrLn $ " >>> " ++ show aRep
+ putStrLn $ " <<< " ++ show bRep
+ Just HRefl -> do
+ putStrLn $ "T(" ++ ctx ++ ") match = " ++ show aRep
+
+checkExtField :: forall x1 x2. String ->
+ forall r1 r2. forall (con1 :: x1 -> r1) (con2 :: x2 -> r2) ->
+ (Typeable x1, Typeable x2) => IO ()
+checkExtField @x1 @x2 ctx _ _ =
+ let aRep = typeRep @x1
+ bRep = typeRep @x2
+ in case eqTypeRep aRep bRep of
+ Nothing -> do
+ putStrLn $ "X(" ++ ctx ++ ") mismatch"
+ putStrLn $ " >>> " ++ show aRep
+ putStrLn $ " <<< " ++ show bRep
+ Just HRefl -> do
+ putStrLn $ "X(" ++ ctx ++ ") match = " ++ show aRep
=====================================
testsuite/tests/ghc-api/T25121_status.stdout
=====================================
@@ -0,0 +1,125 @@
+Extension fields @GhcPs
+-----------------------
+X(Var) mismatch
+ >>> NoExtField
+ <<< EpToken "'"
+X(LitE) match = NoExtField
+X(Par) match = ((EpToken "("),(EpToken ")"))
+X(App) match = NoExtField
+X(AppTypeE) match = EpToken "@"
+X(OpApp) match = NoExtField
+X(ForAll) match = NoExtField
+X(Qual) match = NoExtField
+X(Star) match = EpUniToken "*" "\9733"
+X(FunArr) match = NoExtField
+X(ExprWithTySig) match = EpUniToken "::" "\8759"
+X(UntypedSplice) match = NoExtField
+X(ExplicitList) mismatch
+ >>> AnnList ()
+ <<< ((EpToken "'"),(EpToken "["),(EpToken "]"))
+X(ExplicitTuple) mismatch
+ >>> ((EpaLocation' [GenLocated (EpaLocation' NoComments) EpaComment]),(EpaLocation' [GenLocated (EpaLocation' NoComments) EpaComment]))
+ <<< ((EpToken "'"),(EpToken "("),(EpToken ")"))
+X(Hole) mismatch
+ >>> HoleKind
+ <<< EpToken "_"
+
+Extension fields @GhcRn
+-----------------------
+X(Var) mismatch
+ >>> NoExtField
+ <<< EpToken "'"
+X(LitE) match = NoExtField
+X(Par) mismatch
+ >>> NoExtField
+ <<< ((EpToken "("),(EpToken ")"))
+X(App) match = NoExtField
+X(AppTypeE) match = NoExtField
+X(OpApp) mismatch
+ >>> Fixity
+ <<< NoExtField
+X(ForAll) match = NoExtField
+X(Qual) match = NoExtField
+X(Star) match = EpUniToken "*" "\9733"
+X(FunArr) match = NoExtField
+X(ExprWithTySig) mismatch
+ >>> NoExtField
+ <<< EpUniToken "::" "\8759"
+X(UntypedSplice) mismatch
+ >>> HsUntypedSpliceResult (HsExpr (GhcPass 'Renamed))
+ <<< HsUntypedSpliceResult (GenLocated (EpAnn AnnListItem) (HsType (GhcPass 'Renamed)))
+X(ExplicitList) match = NoExtField
+X(ExplicitTuple) match = NoExtField
+X(Hole) mismatch
+ >>> HoleKind
+ <<< NoExtField
+
+Extension fields @GhcTc
+-----------------------
+X(Var) mismatch
+ >>> NoExtField
+ <<< EpToken "'"
+X(LitE) match = NoExtField
+X(Par) mismatch
+ >>> NoExtField
+ <<< ((EpToken "("),(EpToken ")"))
+X(App) match = NoExtField
+X(AppTypeE) mismatch
+ >>> Type
+ <<< NoExtField
+X(OpApp) mismatch
+ >>> DataConCantHappen
+ <<< NoExtField
+X(ForAll) mismatch
+ >>> DataConCantHappen
+ <<< NoExtField
+X(Qual) mismatch
+ >>> DataConCantHappen
+ <<< NoExtField
+X(Star) mismatch
+ >>> DataConCantHappen
+ <<< EpUniToken "*" "\9733"
+X(FunArr) mismatch
+ >>> DataConCantHappen
+ <<< NoExtField
+X(ExprWithTySig) mismatch
+ >>> NoExtField
+ <<< EpUniToken "::" "\8759"
+X(UntypedSplice) mismatch
+ >>> DataConCantHappen
+ <<< Type
+X(ExplicitList) match = Type
+X(ExplicitTuple) mismatch
+ >>> NoExtField
+ <<< [Type]
+X(Hole) mismatch
+ >>> (HoleKind,HoleExprRef)
+ <<< NoExtField
+
+Direct fields
+-------------
+T(Var) mismatch
+ >>> GenLocated (EpAnn NameAnn) RdrName -> HsExpr P
+ <<< PromotionFlag -> GenLocated (EpAnn NameAnn) RdrName -> HsExpr P
+T(LitE) match = HsLit P -> HsExpr P
+T(Par) match = GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsExpr P
+T(App) match = GenLocated (EpAnn AnnListItem) (HsExpr P) -> GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsExpr P
+T(AppTypeE) mismatch
+ >>> GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsWildCardBndrs P (GenLocated (EpAnn AnnListItem) (HsExpr P)) -> HsExpr P
+ <<< GenLocated (EpAnn AnnListItem) (HsExpr P) -> GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsExpr P
+T(OpApp) match = GenLocated (EpAnn AnnListItem) (HsExpr P) -> GenLocated (EpAnn AnnListItem) (HsExpr P) -> GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsExpr P
+T(ForAll) match = HsForAllTelescope P -> GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsExpr P
+T(Qual) match = GenLocated (EpAnn AnnContext) [GenLocated (EpAnn AnnListItem) (HsExpr P)] -> GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsExpr P
+T(Star) match = HsExpr P
+T(FunArr) match = HsMultAnnOf (GenLocated (EpAnn AnnListItem) (HsExpr P)) P -> GenLocated (EpAnn AnnListItem) (HsExpr P) -> GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsExpr P
+T(ExprWithTySig) mismatch
+ >>> GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsWildCardBndrs P (GenLocated (EpAnn AnnListItem) (HsSigType P)) -> HsExpr P
+ <<< GenLocated (EpAnn AnnListItem) (HsExpr P) -> GenLocated (EpAnn AnnListItem) (HsExpr P) -> HsExpr P
+T(UntypedSplice) match = HsUntypedSplice P -> HsExpr P
+T(ExplicitList) mismatch
+ >>> [GenLocated (EpAnn AnnListItem) (HsExpr P)] -> HsExpr P
+ <<< PromotionFlag -> [GenLocated (EpAnn AnnListItem) (HsExpr P)] -> HsExpr P
+T(ExplicitTuple) mismatch
+ >>> [HsTupArg P] -> Boxity -> HsExpr P
+ <<< PromotionFlag -> [GenLocated (EpAnn AnnListItem) (HsExpr P)] -> HsExpr P
+T(Hole) match = HsExpr P
=====================================
testsuite/tests/ghc-api/all.T
=====================================
@@ -79,3 +79,5 @@ test('T26910', [ extra_run_opts(f'"{config.libdir}"')
, when(arch('wasm32') or arch('javascript'), skip)
], compile_and_run, ['-package ghc -package template-haskell'])
test('TypeMapStringLiteral', normal, compile_and_run, ['-package ghc'])
+
+test('T25121_status', normal, compile_and_run, ['-package ghc'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13fdff31c0940cc0a13c843d18c4ee3…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13fdff31c0940cc0a13c843d18c4ee3…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/int-index/unify-status] 150 commits: Implement QualifiedStrings (#26503)
by Vladislav Zavialov (@int-index) 27 Mar '26
by Vladislav Zavialov (@int-index) 27 Mar '26
27 Mar '26
Vladislav Zavialov pushed to branch wip/int-index/unify-status at Glasgow Haskell Compiler / GHC
Commits:
ea4c2cbd by Brandon Chinn at 2026-02-27T16:22:38-08:00
Implement QualifiedStrings (#26503)
See Note [Implementation of QualifiedStrings]
- - - - -
08bc245b by sheaf at 2026-03-01T11:11:54-05:00
Clean up join points, casts & ticks
This commit shores up the logic dealing with casts and ticks occurring
in between a join point binding and a jump.
Fixes #26642 #26929 #26693
Makes progress on #14610 #26157 #26422
Changes:
- Remove 'GHC.Types.Tickish.TickishScoping' in favour of simpler
predicates 'tickishHasNoScope'/'tickishHasSoftScope', as things were
before commit 993975d3. This makes the code easier to read and
document (fewer indirections).
- Introduce 'canCollectArgsThroughTick' for consistent handling of
ticks around PrimOps and other 'Id's that cannot be eta-reduced.
See overhauled Note [Ticks and mandatory eta expansion].
- New Note [JoinId vs TailCallInfo] in GHC.Core.SimpleOpt that explains
robustness of JoinId vs fragility of TailCallInfo.
- Allow casts/non-soft-scoped ticks to occur in between a join point
binder and a jump, but only in Core Prep.
See Note [Join points, casts, and ticks] and
Note [Join points, casts, and ticks... in Core Prep]
in GHC.Core.Opt.Simplify.Iteration.
Also update Core Lint to account for this.
See Note [Linting join points with casts or ticks] in GHC.Core.Lint.
- Update 'GHC.Core.Utils.mergeCaseAlts' to avoid pushing a cast in
between a join point binding and its jumps. This fixes #26642.
See the new (MC5) and (MC6) in Note [Merge Nested Cases].
- Update float out to properly handle source note ticks. They are now
properly floated out instead of being discarded.
This increases the number of ticks in certain tests with -g.
Test cases: T26642 and TrickyJoins.
Metric increase due to more source note ticks with -g:
-------------------------
Metric Increase:
libdir
size_hello_artifact
size_hello_unicode
-------------------------
- - - - -
476c4cdf by Sean D. Gillespie at 2026-03-02T10:14:37-05:00
Add SIMD absolute value on x86 and LLVM
On x86, absolute value of 32 bits or less is implemented with
PABSB/PABSW/PABSD if SSSE3 is available. Otherwise, there is a fallback
for SSE2. For 64 bit integers it uses VPABSQ, required by AVX-512VL,
with fallbacks for SSE4.2 and SSE2.
There is no dedicated instruction for floating point absolute value on
x86, so it is simulated using bitwise AND.
Absolute value for signed integers and floats are implemented by the
"llvm.abs/llvm.fabs" standard library intrinsics. This implementation
uses MachOps constructors, unlike non-vector floating point absolute
value, which uses CallishMachOps.
- - - - -
709448c0 by Sean D. Gillespie at 2026-03-02T10:14:46-05:00
Add SIMD floating point square root
On x86, this is implemented with the SQRTPS and SQRTPD instructions. On
LLVM, it uses the sqrt library intrinstic.
- - - - -
0deadf66 by Sean D. Gillespie at 2026-03-02T10:14:47-05:00
Improve error message for SIMD on aarch64
When encountering vector literals on aarch64, previously it would
throw:
<no location info>: error:
panic! (the 'impossible' happened)
GHC version 9.15.20251219:
getRegister' (CmmLit:CmmVec):
Now it is more consistent with the other vector operations:
<no location info>: error:
sorry! (unimplemented feature or known bug)
GHC version 9.15.20251219:
SIMD operations on AArch64 currently require the LLVM backend
- - - - -
7d64031b by Vladislav Zavialov at 2026-03-03T11:09:28-05:00
Replace maybeAddSpace with spaceIfSingleQuote
Simplify pretty-printing of HsTypes by using spaceIfSingleQuote.
This allows us to drop the unwieldy lhsTypeHasLeadingPromotionQuote
helper function.
Follow-up to 178c1fd830c78377ef5d338406a41e1d8eb5f0da
- - - - -
598db847 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Correct `hIsReadable` and `hIsWritable` for duplex handles
This contribution implements CLC proposal #371. It changes `hIsReadable`
and `hIsWritable` such that they always throw a respective exception
when encountering a closed or semi-closed handle, not just in the case
of a file handle.
- - - - -
b90201e5 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Document `SemiClosedHandle`
- - - - -
c9df72b5 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Tell users what “semi-closed” means for duplex handles
- - - - -
a8aa1868 by Ilias Tsitsimpis at 2026-03-06T06:26:29-05:00
Fix determinism of linker arguments
The switch from Data.Map to UniqMap in 3b5be05ac29 introduced
non-determinism in the order of packages passed to the linker.
This resulted in non-reproducible builds where the DT_NEEDED entries in
dynamic libraries were ordered differently across builds.
Fix the regression by explicitly sorting the package list derived from
UniqMap.
Fixes #26838
- - - - -
9b64ad3a by Matthew Pickering at 2026-03-06T06:27:16-05:00
determinism: Use a deterministic renaming when writing bytecode files
Now when writing the bytecode file, a counter and substitution are used
to provide deterministic keys to local variables (rather than relying on
uniques). This change ensures that `.gbc` are produced
deterministically.
Fixes #26499
- - - - -
d29800e0 by Teo Camarasu at 2026-03-06T06:28:46-05:00
ghc-internal: delete Version hs-boot loop
Version has a Read instance which needs Unicode but part of the Unicode interface is the unicode version. This is easy to resolve. We simply don't re-export the version from the Unicode module.
Resolves #26940
- - - - -
ad25af90 by Sylvain Henry at 2026-03-06T06:30:33-05:00
Linker: implement support for COMMON symbols (#6107)
Add some support for COMMON symbols. We don't support common symbols
having different sizes where the larger one is allocated after the
smaller one. The linker will fail with an appropriate error message if
it happens.
- - - - -
3b59f158 by Cheng Shao at 2026-03-06T06:31:16-05:00
compiler: fix redundant import of GHC.Hs.Lit
This patch removes a redundant import of `GHC.Hs.Lit` which causes a
ghc build failure with validate flavours when bootstrapping from 9.14.
Fixes #26972.
- - - - -
148d36f3 by Cheng Shao at 2026-03-06T06:32:01-05:00
compiler: avoid unneeded traversals in GHC.Unit.State
Following !15591, this patch avoids unneeded traversals in
`reportCycles`/`reportUnusable` when log verbosity is below given
threshold. Also applies `logVerbAtLeast` when appropriate.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
7e31367c by Cheng Shao at 2026-03-06T06:32:46-05:00
ghc-internal: fix redundant import in GHC.Internal.Event.Windows.ManagedThreadPool
This patch fixes redundant import in
`GHC.Internal.Event.Windows.ManagedThreadPool` that causes a
compilation error when building windows target with validate flavours
and bootstrapping from 9.14. Fixes #26976.
- - - - -
fc8b8e27 by sheaf at 2026-03-06T06:33:28-05:00
System.Info.fullCompilerVersion: add 'since' annot
Fixes #26973
- - - - -
c8238375 by Sylvain Henry at 2026-03-06T06:34:23-05:00
Hadrian: deprecate --bignum and automatically enable +native_bignum for JS
Deprecate --bignum=... to select the bignum backend. It's only used to
select the native backend, and this can be done with the +native_bignum
flavour transformer.
Additionally, we automatically enable +native_bignum for the JS target
because the GMP backend isn't supported.
- - - - -
a3ac7074 by Sylvain Henry at 2026-03-06T06:35:17-05:00
JS: fix putEnum/fromEnum (#24593)
Don't go through Word16 when serializing Enums.
- - - - -
0b36e96c by Andreas Klebinger at 2026-03-06T06:35:58-05:00
Docs: Document -fworker-wrapper-cbv default setting.
Fixes #26841
- - - - -
eca445e7 by mangoiv at 2026-03-07T05:02:36-05:00
drop deb9/10 from CI, add deb13
debian 9 and 10 are end of life, hence we drop them
from our CI, but we do add debian 13. Jobs that were
previously run on 9 and 10 run on 13, too, jobs that
were run on 10, are run on 11 now. Jobs that were
previously run on debian 12 are run on debian 13 now.
This MR also updates hadrian's bootstrap plans for that
reason.
Metric Decrease:
T9872d
- - - - -
12f8b829 by Luite Stegeman at 2026-03-07T05:03:33-05:00
Fix GHC.Internal.Prim haddock
Haddock used to parse Haskell source to generate documentation,
but switched to using interface files instead. This broke documentation
of the GHC.Internal.Prim module, since it's a wired-in interface that
didn't provide a document structure.
This patch adds the missing document structure and updates genprimopcode
to make the section headers and descriptions available.
fixes #26954
- - - - -
f87e5e57 by Luite Stegeman at 2026-03-07T05:03:33-05:00
Remove obsolete --make-haskell-source from genprimopcode
Now that haddock uses the wired-in interface for GHC.Internal.Prim,
the generated Haskell source file is no longer needed. Remove the
--make-haskell-source code generator from genprimopcode and replace
the generated GHC/Internal/Prim.hs with a minimal static source file.
- - - - -
4a7ddc7b by Sylvain Henry at 2026-03-07T05:04:59-05:00
JS: fix linking of exposed but non-preload units (#24886)
Units exposed in the unit database but not explicitly passed on the
command-line were not considered by the JS linker. This isn't an issue
for cabal which passes every unit explicitly but it is an issue when
using GHC directly (cf T24886 test).
- - - - -
689aafcd by mangoiv at 2026-03-07T05:05:52-05:00
testsuite: double foundation timeout multiplier
The runtime timeout in the foundation test was regularly hit by code
generated by the wasm backend - we increase the timout since the high
runtime is expected on the wasm backend for this rather complex test.
Resolves #26938
- - - - -
a46a1bb1 by Cheng Shao at 2026-03-09T04:50:30-04:00
compiler: add myCapabilityExpr to GHC.Cmm.Utils
This commit adds `myCapabilityExpr` to `GHC.Cmm.Utils` which is
computed from `BaseReg`. It's convenient for codegen logic where one
needs to pass the current Capability's pointer.
- - - - -
4afc65b1 by Cheng Shao at 2026-03-09T04:50:30-04:00
compiler: lower tryPutMVar# into a ccall directly
This patch addresses an old TODO of `stg_tryPutMVarzh` by removing it
completely and making the compiler lower `tryPutMVar#` into a ccall to
`performTryPutMVar` directly, without landing into an intermediate C
or Cmm function. `performTryPutMVar` is promoted to a public RTS
function with default visibility, and the compiler lowering logic
takes into account the C ABI of `performTryPutMVar` and converts from
C Bool to primop's `Int#` result properly.
- - - - -
9e3d6a58 by Simon Hengel at 2026-03-09T04:51:15-04:00
Don't use #line in haddocks
This confuses the parser. Haddock output is unaffected by this change.
(read: this still produces the same documentation)
- - - - -
f4e8fec2 by Wolfgang Jeltsch at 2026-03-09T04:52:01-04:00
Remove in-package dependencies on `GHC.Internal.System.IO`
This contribution eliminates all dependencies on
`GHC.Internal.System.IO` from within `ghc-internal`. It comprises the
following changes:
* Make `GHC.Internal.Fingerprint` independent of I/O support
* Tighten the dependencies of `GHC.Internal.Data.Version`
* Tighten the dependencies of `GHC.Internal.TH.Monad`
* Tighten the dependencies of `GHCi.Helpers`
* Move some code that needs `System.IO` to `template-haskell`
* Move the `GHC.ResponseFile` implementation into `base`
* Move the `System.Exit` implementation into `base`
* Move the `System.IO.OS` implementation into `base`
Metric Decrease:
size_hello_artifact
size_hello_artifact_gzip
size_hello_unicode
size_hello_unicode_gzip
- - - - -
91df4c82 by Sylvain Henry at 2026-03-09T04:53:20-04:00
T18832: fix Windows CI failure by dropping removeDirectoryRecursive
On Windows, open file handles prevent deletion. After killThread, the
closer thread may not have called hClose yet, causing removeDirectoryRecursive
to fail with "permission denied". The test harness cleans up the run
directory anyway, so the call is redundant.
- - - - -
d7fe9671 by Cheng Shao at 2026-03-09T04:54:04-04:00
compiler: fix redundant import in GHC.StgToJS.Object
This patch fixes a redundant import in GHC.StgToJS.Object that causes
a build failure when compiling head from 9.14 with validate flavours.
Fixes #26991.
- - - - -
0bfd29c3 by Cheng Shao at 2026-03-09T04:54:46-04:00
wasm: fix `Illegal foreign declaration` failure when ghci loads modules with JSFFI exports
This patch fixes a wasm ghci error when loading modules with JSFFI
exports; the `backendValidityOfCExport` check in `tcCheckFEType`
should only makes sense and should be performed when not checking the
JavaScript calling convention; otherwise, when the calling convention
is JavaScript, the codegen logic should be trusted to backends that
actually make use of it. Fixes #26998.
- - - - -
e659610c by Duncan Coutts at 2026-03-09T12:08:35-04:00
Apply NOINLINE pragmas to generated Typeable bindings
For context, see the existing Note [Grand plan for Typeable]
and the Note [NOINLINE on generated Typeable bindings] added in the
subsequent commit.
This is about reducing the number of exported top level names and
unfoldings, which reduces interface file sizes and reduces the number of
global/dynamic linker symbols.
Also accept the changed test output and metric decreases.
Tests that record the phase output for type checking or for simplifier
end up with different output: the generated bindings now have an
Inline [~] annotation, and many top level names are now local rather
than module-prefixed for export.
Also accept the numerous metric decreases in compile_time/bytes
allocated, and a few in compile_time/max_bytes_used.
There's also one instance of a decrease in runtime/max_bytes_used but
it's a ghci-way test and so presumably the reason is that it loads
smaller .hi files and/or links fewer symbols.
-------------------------
Metric Decrease:
CoOpt_Singletons
MultiLayerModulesTH_OneShot
MultilineStringsPerf
T10421
T10547
T12150
T12227
T12234
T12425
T13035
T13056
T13253
T13253-spj
T15304
T15703
T16875
T17836b
T17977b
T18140
T18223
T18282
T18304
T18698a
T18698b
T18730
T18923
T20049
T21839c
T24471
T24582
T24984
T3064
T4029
T5030
T5642
T5837
T6048
T9020
T9198
T9961
TcPlugin_RewritePerf
WWRec
hard_hole_fits
mhu-perf
-------------------------
- - - - -
67df5161 by Duncan Coutts at 2026-03-09T12:08:35-04:00
Add documentation Note [NOINLINE on generated Typeable bindings]
and refer to it from the code and existing documentation.
- - - - -
c4ad6167 by Duncan Coutts at 2026-03-09T12:08:35-04:00
Switch existing note to "named wrinkle" style, (GPT1)..(GPT7)
GPT = Grand plan for Typeable
- - - - -
dc84f8e2 by Cheng Shao at 2026-03-09T12:09:21-04:00
ci: only build deb13 for validate pipeline aarch64-linux jobs
This patch drops the redundant aarch64-linux deb12 job from validate pipelines
and only keeps deb13; it's still built in nightly/release pipelines. Closes #27004.
- - - - -
23a50772 by Rajkumar Natarajan at 2026-03-10T14:11:37-04:00
chore: Merge GHC.Internal.TH.Quote into GHC.Internal.TH.Monad
Move the QuasiQuoter datatype from GHC.Internal.TH.Quote to
GHC.Internal.TH.Monad and delete the Quote module.
Update submodule template-haskell-quasiquoter to use the merged
upstream version that imports from the correct module.
Co-authored-by: Cursor <cursoragent(a)cursor.com>
- - - - -
a2bb6fc3 by Simon Jakobi at 2026-03-10T14:12:23-04:00
Add regression test for #16122
- - - - -
604e1180 by Cheng Shao at 2026-03-11T15:00:42-04:00
hadrian: remove the broken bench flavour
This patch removes the bench flavour from hadrian which has been
broken for years and not used for actual benchmarking (for which
`perf`/`release` is used instead). Closes #26825.
- - - - -
c3e64915 by Simon Jakobi at 2026-03-11T15:01:31-04:00
Add regression test for #18186
The original TypeInType language extension is replaced with
DataKinds+PolyKinds for compatibility.
Closes #18186.
- - - - -
664996c7 by Andreas Klebinger at 2026-03-11T15:02:16-04:00
Bump nofib submodule.
We accrued a number of nofib fixes we want to have here.
- - - - -
517cf64e by Simon Jakobi at 2026-03-11T15:03:03-04:00
Add regression test for #15907
Closes #15907.
- - - - -
fff362cf by Simon Jakobi at 2026-03-11T15:03:49-04:00
Ensure T14272 is run in optasm way
Closes #16539.
- - - - -
ec81ec2c by Simon Jakobi at 2026-03-11T15:03:49-04:00
Add regression test for #24632
Closes #24632.
- - - - -
cefec47b by Simon Jakobi at 2026-03-11T15:03:50-04:00
Fix module name of T9675: T6975 -> T9675
- - - - -
d3690ae8 by Andreas Klebinger at 2026-03-11T15:04:31-04:00
User guide: Clarify phase control on INLINEABLE[foo] pragmas.
Fixes #26851
- - - - -
e7054934 by Simon Jakobi at 2026-03-11T15:05:16-04:00
Add regression test for #12694
Closes #12694.
- - - - -
4756d9f6 by Simon Jakobi at 2026-03-11T15:05:16-04:00
Add regression test for #16275
Closes #16275.
- - - - -
34b7e2c1 by Simon Jakobi at 2026-03-11T15:05:16-04:00
Add regression test for #14908
Closes #14908.
- - - - -
4243db3d by Simon Jakobi at 2026-03-11T15:05:16-04:00
Add regression test for #14151
Closes #14151.
- - - - -
0e9f1453 by Simon Jakobi at 2026-03-11T15:05:16-04:00
Add regression test for #12640
Closes #12640.
- - - - -
ae606c7f by Simon Jakobi at 2026-03-11T15:05:16-04:00
Add regression test for #15588
Closes #15588.
- - - - -
5a38ce4e by Simon Jakobi at 2026-03-11T15:05:16-04:00
Add regression test for #9445
Closes #9445.
- - - - -
d054b467 by Cheng Shao at 2026-03-11T15:05:59-04:00
compiler: implement string interning logic for BCONPtrFS
This patch adds a `FastStringEnv`-based cache of `MallocStrings`
requests to `Interp`, so that when we load bytecode with many
breakpoints that share the same module names & unit ids, we reuse the
allocated remote pointers instead of issuing duplicte `MallocStrings`
requests and bloating the C heap. Closes #26995.
- - - - -
b85a0293 by Simon Jakobi at 2026-03-11T15:06:41-04:00
Add perf test for #1216
Closes #1216.
- - - - -
cd7f7420 by Sylvain Henry at 2026-03-11T15:07:58-04:00
JS: check that tuple constructors are linked (#23709)
Test js-mk_tup was failing before because tuple constructors weren't
linked in. It's no longer an issue after the linker fixes.
- - - - -
d57f01a4 by Matthew Pickering at 2026-03-11T15:08:40-04:00
testsuite: Add test for foreign import prim with unboxed tuple return
This commit just adds a test that foreign import prim works with unboxed
sums.
- - - - -
23d111ce by Matthew Pickering at 2026-03-11T15:08:41-04:00
Return a valid pointer in advanceStackFrameLocationzh
When there is no next stack chunk, `advanceStackFrameLocationzh` used to
return NULL in the pointer-typed StackSnapshot# result slot.
Even though the caller treats that case as "no next frame", the result is
still materialized in a GC-visible pointer slot. If a GC observes the raw
NULL there, stack decoding can crash.
Fix this by ensuring the dead pointer slot contains a valid closure
pointer. Also make the optional result explicit by returning an unboxed
sum instead of a tuple with a separate tag.
Fixes #27009
- - - - -
4c58a3ae by Cheng Shao at 2026-03-11T15:09:22-04:00
hadrian: build profiled dynamic objects with -dynamic-too
This patch enables hadrian to build profiled dynamic objects with
`-dynamic-too`, addressing a build parallelism bottleneck in release
pipelines. Closes #27010.
- - - - -
870243e4 by Zubin Duggal at 2026-03-12T17:33:28+05:30
DmdAnal: Take stable unfoldings into account when determining argument demands
Previously, demand analysis only looked at the RHS to compute argument demands.
If the optimised RHS discarded uses of an argument that the stable unfolding
still needed, it would be incorrectly marked absent. Worker/wrapper would then
replace it with LitRubbish, and inlining the stable unfolding would use the
rubbish value, causing a segfault.
To fix, we introduce addUnfoldingDemands which analyses the stable unfolding
with dmdAnal and combines its DmdType with the RHS's via the new `maxDmdType`
which combines the demands of the stable unfolding with the rhs, so we can avoid
any situation where we give an absent demand to something which is still used
by the stable unfolding.
Fixes #26416.
- - - - -
669d09f9 by Cheng Shao at 2026-03-13T15:06:07-04:00
hadrian: remove redundant library/rts ways definitions from stock flavours
This patch removes redundant library/rts ways definitions from stock
flavours in hadrian; they can be replaced by applying appropriate
filters on `defaultFlavour`.
- - - - -
a27dc081 by Teo Camarasu at 2026-03-13T15:06:51-04:00
ghc-internal: move bits Weak of finalizer interface to base
We move parts of the Weak finalizer interface to `base` only the parts
that the RTS needs to know about are kept in `ghc-internal`.
This lets us then prune our imports somewhat and get rid of some SOURCE imports.
Resolves #26985
- - - - -
6eef855b by Sylvain Henry at 2026-03-13T15:08:18-04:00
Stg/Unarise: constant-folding during unarisation (#25650)
When building an unboxed sum from a literal argument, mkUbxSum
previously emitted a runtime cast via `case primop [lit] of var -> ...`.
This wrapper prevented GHC from recognising the result as a static
StgRhsCon, causing top-level closures to be allocated as thunks instead
of being statically allocated.
Fix: try to perform the numeric literal cast at compile time using
mkLitNumberWrap (wrapping semantics). If successful, return the cast
literal directly with an identity wrapper (no case expression). The
runtime cast path is kept as fallback for non-literal arguments.
Test: codeGen/should_compile/T25650
- - - - -
905f8723 by Simon Jakobi at 2026-03-13T15:09:09-04:00
Add regression test for #2057
Test that GHC stops after an interface-file error instead of
continuing into the linker.
The test constructs a stale package dependency on purpose. `pkgB` is compiled
against one version of package `A`, then the same unit id is replaced by an
incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`,
finds an unfolding that still mentions the old `A`, and should fail while
loading interfaces.
Closes #2057.
Assisted-by: Codex
- - - - -
a13245a9 by Sylvain Henry at 2026-03-13T15:10:06-04:00
JS: fix recompilation avoidance (#23013)
- we were checking the mtime of the *.jsexe directory, not of a file
- we were not computing the PkgsLoaded at all
- - - - -
07442653 by Cheng Shao at 2026-03-13T15:10:51-04:00
hadrian: bump index state & bootstrap plans
This patch bumps hadrian index state & bootstrap plans:
- The updated index state allows bootstrapping from 9.14 without cabal
allow-newer hacks
- The updated bootstrap plans all contain shake-0.19.9 containing
important bugfix, allowing a subsequent patch to bump shake bound to
ensure the bugfix is included
- ghc 9.14.1 bootstrap plan is added
- - - - -
fdc1dbad by Cheng Shao at 2026-03-13T15:10:51-04:00
ci: add ghc 9.14.1 to bootstrap matrix
This patch adds ghc 9.14.1 to bootstrap matrix, so that we test
bootstrapping from ghc 9.14.1.
- - - - -
91916079 by Sylvain Henry at 2026-03-13T15:11:43-04:00
T17912: wait for opener thread to block before killing it (#24739)
Instead of a fixed 1000ms delay, poll threadStatus until the opener
thread is in BlockedOnForeignCall, ensuring killThread only fires once
the thread is provably inside the blocking open() syscall. This prevents
the test from accidentally passing on Windows due to scheduling races.
- - - - -
baa4ebb4 by Cheng Shao at 2026-03-13T15:12:26-04:00
template-haskell: fix redundant import in Language.Haskell.TH.Quote
This patch fixes a redundant import in `Language.Haskell.TH.Quote`
that causes a ghc build failure when bootstrapping from 9.14 with
validate flavours. Fixes #27014.
- - - - -
02e68a86 by Brandon Simmons at 2026-03-13T15:13:19-04:00
Add a cumulative gc_sync_elapsed_ns counter to GHC.Internal.Stats
This makes it possible to get an accurate view of time spent in sync
phase when using prometheus-style sampling. Previously this was only
available for the most recent GC.
This intentionally leaves GHC.Stats API unchanged since it is marked as
deprecated, and API changes there require CLC approval.
Fixes #26944
- - - - -
a18fa3c1 by Cheng Shao at 2026-03-14T05:12:14-04:00
configure: make $LLVMAS default to $CC when $CcLlvmBackend is YES
This patch changes the $LLVMAS detection logic in configure so that
when it's not manually specified by the user, it defaults to $CC if
$CcLlvmBackend is YES. It's a more sensible default than auto-detected
clang from the environment, especially when cross-compiling, $CC as
the cross target's LLVM assembler is more compatible with the use case
than the system-wide clang. Fixes #26769.
- - - - -
3774086e by Matthew Pickering at 2026-03-14T05:13:00-04:00
exceptions: annotate onException continuation with WhileHandling
Before this patch, an exception thrown in the `onException` handler
would loose track of where the original exception was thrown.
```
import Control.Exception
main :: IO ()
main = failingAction `onException` failingCleanup
where
failingAction = throwIO (ErrorCall "outer failure")
failingCleanup = throwIO (ErrorCall "cleanup failure")
```
would report
```
T28399: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
cleanup failure
HasCallStack backtrace:
throwIO, called at T28399.hs:<line>:<column> in <package-id>:Main
```
notice that the "outer failure" exception is not present in the error
message.
With this patch, any exception thrown is in the handler is annotated
with WhileHandling. The resulting message looks like
```
T28399: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
cleanup failure
While handling outer failure
HasCallStack backtrace:
throwIO, called at T28399.hs:7:22 in main:Main
```
CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/397
Fixes #26759
- - - - -
63ae8eb3 by Andreas Klebinger at 2026-03-14T05:13:43-04:00
Fix missing profiling header for origin_thunk frame.
Fixes #27007
- - - - -
213d2c0e by Cheng Shao at 2026-03-14T05:14:28-04:00
ci: fix ci-images revision
The current ci-images revision was a commit on the WIP branch of
https://gitlab.haskell.org/ghc/ci-images/-/merge_requests/183, and
it's not on the current ci-images master branch. This patch fixes the
image revision to use the current tip of ci-images master.
- - - - -
fc2b083f by Andreas Klebinger at 2026-03-14T05:15:14-04:00
Revert "hadrian/build-cabal: Better respect and utilize -j"
This reverts commit eab3dbba79650e6046efca79133b4c0a5257613d.
While it's neat this currently isn't well supported on all platforms.
It's time will come, but for now I'm reverting this to avoid issues for
users on slightly unconvential platforms.
This will be tracked at #26977.
- - - - -
12a706cf by Cheng Shao at 2026-03-14T16:37:54-04:00
base: fix redundant imports in GHC.Internal.Weak.Finalize
This patch fixes redundant imports in GHC.Internal.Weak.Finalize that
causes a regression in bootstrapping head from 9.14 with validate
flavours. Fixes #27026.
- - - - -
b5d39cad by Matthew Pickering at 2026-03-14T16:38:37-04:00
Use explicit syntax rather than pure
- - - - -
43638643 by Andreas Klebinger at 2026-03-15T18:15:48-04:00
Configure: Fix check for --target support in stage0 CC
The check FP_PROG_CC_LINKER_TARGET used $CC unconditionally to check for
--target support. However this fails for the stage0 config where the C
compiler used is not $CC but $CC_STAGE0.
Since we already pass the compiler under test into the macro I simply
changed it to use that instead.
Fixes #26999
- - - - -
18fd0df6 by Simon Hengel at 2026-03-15T18:16:33-04:00
Fix typo in recursive_do.rst
- - - - -
86bd9bfc by fendor at 2026-03-17T23:46:09-04:00
Introduce `-fimport-loaded-targets` GHCi flag
This new flag automatically adds all loaded targets to the GHCi session
by adding an `InteractiveImport` for the loaded targets.
By default, this flag is disabled, as it potentially increases memory-usage.
This interacts with the flag `-fno-load-initial-targets` as follows:
* If no module is loaded, no module is added as an interactive import.
* If a reload loads up to a module, all loaded modules are added as
interactive imports.
* Unloading modules removes them from the interactive context.
Fixes #26866 by rendering the use of a `-ghci-script` to achieve the
same thing redundant.
- - - - -
e3d4c1bb by mniip at 2026-03-17T23:47:03-04:00
ghc-internal: Remove GHC.Internal.Data.Eq
It served no purpose other than being a re-export.
- - - - -
6f4f6cf0 by mniip at 2026-03-17T23:47:03-04:00
ghc-internal: Refine GHC.Internal.Base imports
Removed re-exports from GHC.Internal.Base. This reveals some modules
that don't actually use anything *defined* in GHC.Internal.Base, and
that can be pushed down a little in the import graph.
Replaced most imports of GHC.Internal.Base with non-wildcard imports
from modules where the identifiers are actually defined.
Part of #26834
Metric Decrease:
T5321FD
- - - - -
7fb51f54 by mangoiv at 2026-03-17T23:48:00-04:00
ci: clone, don't copy when creating the cabal cache
Also removed WINDOWS_HOST variable detected via uname - we now just
check whether the CI job has windows in its name. This works because we
only ever care about it if the respective job is not a cross job. We
also statically detect darwin cross jobs in the same way. We only ever have
darwin -> darwin cross jobs so this is enough to detect the host
reliably.
- - - - -
f8817879 by mangoiv at 2026-03-17T23:48:44-04:00
ci: mark size_hello_artifact fragile on darwin x86
The size of the x86_64 hello artifact is not stable which results in flaky testruns.
Resolves #26814
- - - - -
e34cb6da by Adam Gundry at 2026-03-20T12:20:00-04:00
ghci: Mention active language edition in startup banner
Per GHC proposal 632, this makes the GHCi startup banner include
the active language edition, plus an indication of whether this
was the default (as opposed to being explicitly selected via an
option such as `-XGHC2024`). For example:
```
$ ghci
GHCi, version 9.14.1: https://www.haskell.org/ghc/ :? for help
Using default language edition: GHC2024
ghci>
```
Fixes #26037.
- - - - -
52c3e6ba by sheaf at 2026-03-20T12:21:09-04:00
Improve incomplete record selector warnings
This commit stops GHC from emitting spurious incomplete record selector
warnings for bare selectors/projections such as .fld
There are two places we currently emit incomplete record selector
warnings:
1. In the desugarer, when we see a record selector or an occurrence
of 'getField'. Here, we can use pattern matching information to
ensure we don't give false positives.
2. In the typechecker, which might sometimes give false positives but
can emit warnings in cases that the pattern match checker would
otherwise miss.
This is explained in Note [Detecting incomplete record selectors]
in GHC.HsToCore.Pmc.
Now, we obviously don't want to emit the same error twice, and generally
we prefer (1), as those messages contain fewer false positives. So we
suppress (2) when we are sure we are going to emit (1); the logic for
doing so is in GHC.Tc.Instance.Class.warnIncompleteRecSel,
and works by looking at the CtOrigin.
Now, the issue was that this logic handled explicit record selectors as
well as overloaded record field selectors such as "x.r" (which turns
into a simple GetFieldOrigin CtOrigin), but it didn't properly handle
record projectors like ".fld" or ".fld1.fld2" (which result in other
CtOrigins such as 'RecordFieldProjectionOrigin').
To solve this problem, we re-use the 'isHasFieldOrigin' introduced in
fbdc623a (slightly adjusted).
On the way, we also had to update the desugarer with special handling
for the 'ExpandedThingTc' case in 'ds_app', to make sure that
'ds_app_var' sees all the type arguments to 'getField' in order for it
to indeed emit warnings like in (1).
Fixes #26686
- - - - -
309d7e87 by Cheng Shao at 2026-03-20T12:21:53-04:00
rts: opportunistically grow the MutableByteArray# in-place in resizeMutableByteArray#
Following !15234, this patch improves `resizeMutableByteArray#` memory
efficiency by growing the `MutableByteArray#` in-place if possible,
addressing an old todo comment here. Also adds a new test case
`resizeMutableByteArrayInPlace` that stresses this behavior.
- - - - -
7d4ef162 by Matthew Craven at 2026-03-20T12:22:47-04:00
Change representation of floating point literals
This commit changes the representation of floating point literals
throughough the compiler, in particular in Core and Cmm.
The Rational type is deficient for this purpose, dealing poorly
with NaN, +/-Infinity, and negative zero. Instead, the new module
GHC.Types.Literal.Floating uses the host Float/Double type to represent
NaNs, infinities and negative zero. It also contains a Rational
constructor, for the benefit of -fexcess-precision.
Other changes:
- Remove Note [negative zero] and related code
This also removes the restrictions on constant-folding of division
by zero, and should make any problems with NaN/Infinity more obvious.
- Use -0.0 as the additive identity for Core constant folding rules
for floating-point addition, fixing #21227.
- Manual worker-wrapper for GHC.Float.rationalToDouble. This is
intended to prevent the compiler's WW on this function from
interfering with constant-folding. This change means that we now
avoid allocating a box for the result of a 'realToFrac' call in
T10359.
- Combine floatDecodeOp and doubleDecodeOp.
This change also fixes a bug in doubleDecodeOp wherein it
would incorrectly produce an Int# instead of an Int64#
literal for the mantissa component with 64-bit targets.
- Use Float/Double for assembly immediates, and update the X86 and
PowerPC backends to properly handle special values such as NaN and
infinity.
- Allow 'rational_to' to handle zero denominators, fixing a
TODO in GHC.Core.Opt.ConstantFold.
Fixes #8364 #9811 #18897 #21227
Progress towards #26919
Metric Decrease:
T10359
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
-------------------------
Metric Decrease:
T1969
T5321FD
-------------------------
- - - - -
80e2dd4f by Zubin Duggal at 2026-03-20T12:23:33-04:00
compiler/ffi: Collapse void pointer chains in capi wrappers
New gcc/clang treat -Wincompatible-pointer-types as an error by
default. Since C only allows implicit conversion from void*, not void**,
capi wrappers for functions taking e.g. abstract** would fail to compile
when the Haskell type Ptr (Ptr Abstract) was naively translated to void**.
Collapse nested void pointers to a single void* when the pointee type
has no known C representation.
Fixes #26852
- - - - -
1c50bd7b by Luite Stegeman at 2026-03-20T12:24:37-04:00
Move some functions related to pointer tagging to a separate module
- - - - -
bfd7aafd by Luite Stegeman at 2026-03-20T12:24:37-04:00
Branchless unpacking for enumeration types
Change unpacking for enumeration types to go to Word8#/Word16#/Word#
directly instead of going through an intermediate unboxed sum. This
allows us to do a branchless conversion using DataToTag and TagToEnum.
Fixes #26970
- - - - -
72b20fc0 by Luite Stegeman at 2026-03-20T12:25:30-04:00
bytecode: Carefully SLIDE off the end of a stack chunk
The SLIDE bytecode instruction was not checking for stack chunk
boundaries and could corrupt the stack underflow frame, leading
to crashes.
We add a check to use safe writes if we cross the chunk boundary
and also handle stack underflow if Sp is advanced past the underflow
frame.
fix #27001
- - - - -
2e22b43c by Cheng Shao at 2026-03-20T12:26:14-04:00
ghci: serialize BCOByteArray buffer directly when possible
This patch changes the `Binary` instances of `BCOByteArray` to
directly serialize the underlying buffer when possible, while also
taking into account the issue of host-dependent `Word` width. See
added comments and amended `Note [BCOByteArray serialization]` for
detailed explanation. Closes #27020.
- - - - -
89d9ba37 by Sylvain Henry at 2026-03-20T12:27:34-04:00
JS: replace BigInt with Number arithmetic for 32/64-bit quot/rem (#23597)
Replace BigInt-based implementations of quotWord32, remWord32,
quotRemWord32, quotRem2Word32, quotWord64, remWord64, quotInt64, and
remInt64 with pure Number (double/integer) arithmetic to avoid the
overhead of BigInt promotion.
- - - - -
ae4ddd60 by Sylvain Henry at 2026-03-20T12:28:28-04:00
Core: add constant-folding rules for Addr# eq/ne (#18032)
- - - - -
3e767f98 by Matthew Pickering at 2026-03-20T12:29:11-04:00
Use OsPath rather than FilePath in Downsweep cache
This gets us one step closure to uniformly using `OsPath` in the
compiler.
- - - - -
2c57de29 by Cheng Shao at 2026-03-20T12:29:55-04:00
hadrian: fix ghc-in-ghci flavour stage0 shared libraries
This patch fixes missing stage0 shared libraries in hadrian
ghc-in-ghci flavour, which was accidentally dropped in
669d09f950a6e88b903d9fd8a7571531774d4d5d and resulted in a regression
in HLS support on linux/macos. Fixes #27057.
- - - - -
5b1be555 by Sylvain Henry at 2026-03-20T12:30:48-04:00
JS: install rts/Types.h header file (#27033)
It was an omission, making HsFFI.h not usable with GHC using the JS
backend.
- - - - -
b883f08f by Cheng Shao at 2026-03-20T12:31:33-04:00
hadrian: don't compile RTS with -Winline
This patch removes `-Winline` from cflags when compiling the RTS,
given that:
1. It generates a huge pile of spam and hurts developer experience
2. Whether inlining happens is highly dependent on toolchains,
flavours, etc, and it's not really an issue to fix if inlining
doesn't happen; it's a hint to the C compiler anyway.
Fixes #27060.
- - - - -
333387d6 by Cheng Shao at 2026-03-20T12:31:33-04:00
hadrian: compile libffi-clib with -Wno-deprecated-declarations
This patch adds `-Wno-deprecated-declarations` to cflags of
`libffi-clib`, given that it produces noise at compile-time that
aren't really our issue to fix anyway, it's from vendored libffi
source code.
- - - - -
67c47771 by Rodrigo Mesquita at 2026-03-20T12:32:17-04:00
Expose decodeStackWithIpe from ghc-experimental
This decoding is useful to the debugger and it wasn't originally
exported as an oversight.
- - - - -
18513365 by Matthew Pickering at 2026-03-21T04:43:26-04:00
Add support for custom external interpreter commands
It can be useful for GHC API clients to implement their own external
interpreter commands.
For example, the debugger may want an efficient way to inspect the
stacks of the running threads in the external interpreter.
- - - - -
4636d906 by mangoiv at 2026-03-21T04:44:10-04:00
ci: remove obsolete fallback for old debian and ubuntu versions
- - - - -
2e3a2805 by mangoiv at 2026-03-21T04:44:10-04:00
ci: drop ubuntu 18 and 20
Ubuntu 18 EOL: May 2023
Ubuntu 20 EOL: May 2025
We should probably not make another major release supporting these platforms.
Also updates the generator script.
Resolves #25876
- - - - -
de54e264 by Cheng Shao at 2026-03-21T17:52:08+01:00
rts: fix -Wcompare-distinct-pointer-types errors
This commit fixes `-Wcompare-distinct-pointer-types` errors in the RTS
which should have been caught by the `validate` flavour but was
warnings in CI due to the recent `+werror` regression.
- - - - -
b9bd73de by Cheng Shao at 2026-03-21T17:52:08+01:00
ghc-internal: fix unused imports
This commit fixes unused imports in `ghc-internal` which should have
been caught by the `validate` flavour but was warnings in CI due to
the recent `+werror` regression. Fixes #26987 #27059.
- - - - -
da946a16 by Cheng Shao at 2026-03-21T17:03:51+00:00
ghci: fix unused imports
This commit fixes unused imports in `ghci` which should have been
caught by the `validate` flavour but was warnings in CI due to the
recent `+werror` regression. Fixes #26987 #27059.
- - - - -
955b1cf8 by Cheng Shao at 2026-03-21T17:03:51+00:00
compiler: fix unused imports in GHC.Tc.Types.Origin
This commit fixes unused imports in `GHC.Tc.Types.Origin` which should
have been caught by the `validate` flavour but was warnings in CI due
to the recent `+werror` regression. Fixes #27059.
- - - - -
3b1aeb50 by Cheng Shao at 2026-03-21T17:03:51+00:00
hadrian: fix missing +werror in validate flavour
This patch fixes missing `+werror` in validate flavour, which was an
oversight in bb3a2ba1eefadf0b2ef4f39b31337a23eec67f29. Fixes #27066.
- - - - -
44f118f0 by Cheng Shao at 2026-03-22T04:54:01-04:00
ci: bump CACHE_REV and add the missing reminder
This patch bumps `CACHE_REV` to address recent `[Cabal-7159]` CI
errors due to stale cabal cache on some runners, and also adds a
reminder to remind future maintainers. Fixes #27075.
- - - - -
2a218737 by ARATA Mizuki at 2026-03-23T11:11:39-04:00
Add 128-bit SIMD support to AArch64 NCG
Changes:
- Add `Format` field to vector-capable instructions.
These instructions will emit `vN.4s` (for example) as a operand.
- Additional constructors for `Operand`:
`OpVecLane` represents a vector lane and will be emitted as `vN.<width>[<index>]` (`vN.s[3]` for example).
`OpScalarAsVec` represents a scalar, but printed as a vector lane like `vN.<width>[0]` (`vN.s[0]` for example).
- Integer quot/rem are implemented in C, like x86.
Closes #26536
Metric Increase:
T3294
- - - - -
5d6e2be9 by ARATA Mizuki at 2026-03-23T11:11:39-04:00
AArch64 NCG: Improve code generation for floating-point and vector constants
Some floating-point constants can be directly encoded using the FMOV instruction.
Similarly, a class of vectors with same values can be encoded using FMOV, MOVI, or MVNI.
- - - - -
c6d262aa by Simon Jakobi at 2026-03-23T11:12:22-04:00
Add regression test for #13729
Closes #13729.
- - - - -
aa5dfe67 by Sylvain Henry at 2026-03-26T03:48:56-04:00
Check that shift values are valid
In GHC's codebase in non-DEBUG builds we silently substitute shiftL/R
with unsafeShiftL/R for performance reasons. However we were not
checking that the shift value was valid for unsafeShiftL/R, leading to
wrong computations, but only in non-DEBUG builds.
This patch adds the necessary checks and reports an error when a wrong
shift value is passed.
- - - - -
c8a7b588 by Sylvain Henry at 2026-03-26T03:48:56-04:00
Implement basic value range analysis (#25718)
Perform basic value range analysis to try to determine at compile time
the result of the application of some comparison primops (ltWord#, etc.).
This subsumes the built-in rewrite rules used previously to check if one
of the comparison argument was a bound (e.g. (x :: Word8) <= 255 is
always True). Our analysis is more powerful and handles type
conversions: e.g. word8ToWord x <= 255 is now detected as always True too.
We also use value range analysis to filter unreachable alternatives in
case-expressions. To support this, we had to allow case-expressions for
primitive types to not have a DEFAULT alternative (as was assumed before
and checked in Core lint).
- - - - -
a5ec467e by ARATA Mizuki at 2026-03-26T03:49:49-04:00
rts: Align stack to 64-byte boundary in StgRun on x86
When LLVM spills AVX/AVX-512 vector registers to the stack, it requires
32-byte (__m256) or 64-byte (__m512) alignment. If the stack is not
sufficiently aligned, LLVM inserts a realignment prologue that reserves
%rbp as a frame pointer, conflicting with GHC's use of %rbp as an STG
callee-saved register and breaking the tail-call-based calling convention.
Previously, GHC worked around this by lying to LLVM about the stack
alignment and rewriting aligned vector loads/stores (VMOVDQA, VMOVAPS)
to unaligned ones (VMOVDQU, VMOVUPS) in the LLVM Mangler. This had two
problems:
- It did not extend to AVX-512, which requires 64-byte alignment. (#26595)
- When Haskell calls a C function that takes __m256/__m512 arguments on
the stack, the callee requires genuine alignment, which could cause a
segfault. (#26822)
This patch genuinely aligns the stack to 64 bytes in StgRun by saving
the original stack pointer before alignment and restoring it in
StgReturn. We now unconditionally advertise 64-byte stack alignment to
LLVM for all x86 targets, making rewriteAVX in the LLVM Mangler
unnecessary. STG_RUN_STACK_FRAME_SIZE is increased from 48 to 56 bytes
on non-Windows x86-64 to store the saved stack pointer.
Closes #26595 and #26822
Co-Authored-By: Claude Opus 4.5 <noreply(a)anthropic.com>
- - - - -
661da815 by Teo Camarasu at 2026-03-26T03:50:33-04:00
ghc-internal: Float Generics to near top of module graph
We remove GHC.Internal.Generics from the critical path of the
`ghc-internal` module graph. GHC.Internal.Generics used to be in the
middle of the module graph, but now it is nearer the top (built later).
This change thins out the module graph and allows us to get rid of the
ByteOrder hs-boot file.
We implement this by moving Generics instances from the module where the
datatype is defined to the GHC.Internal.Generics module. This trades off
increasing the compiled size of GHC.Internal.Generics with reducing the
dependency footprint of datatype modules.
Not all instances are moved to GHC.Internal.Generics. For instance,
`GHC.Internal.Control.Monad.Fix` keeps its instance as it is one of the
very last modules compiled in `ghc-internal` and so inverting the
relationship here would risk adding GHC.Internal.Generics back onto the
critical path.
We also don't change modules that are re-exported from the `template-haskell` or `ghc-heap`.
This is done to make it easy to eventually move `Generics` to `base`
once something like #26657 is implemented.
Resolves #26930
Metric Decrease:
T21839c
- - - - -
45428f88 by sheaf at 2026-03-26T03:51:31-04:00
Avoid infinite loop in deep subsumption
This commit ensures we only unify after we recur in the deep subsumption
code in the FunTy vs non-FunTy case of GHC.Tc.Utils.Unify.tc_sub_type_deep,
to avoid falling into an infinite loop.
See the new Wrinkle [Avoiding a loop in tc_sub_type_deep] in
Note [FunTy vs non-FunTy case in tc_sub_type_deep] in GHC.Tc.Utils.Unify.
Fixes #26823
Co-authored-by: simonpj <simon.peytonjones(a)gmail.com>
- - - - -
2823b039 by Ian Duncan at 2026-03-26T03:52:21-04:00
AArch64: fix MOVK regUsageOfInstr to mark dst as both read and written
MOVK (move with keep) modifies only a 16-bit slice of the destination
register, so the destination is both read and written. The register
allocator must know this to avoid clobbering live values. Update
regUsageOfInstr to list the destination in both src and dst sets.
No regression test: triggering the misallocation requires specific
register pressure around a MOVK sequence, which is difficult to
reliably provoke from Haskell source.
- - - - -
57b7878d by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #12002
Closes #12002.
- - - - -
c8f9df2d by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #12046
Closes #12046.
Co-authored-by: Andreas Klebinger <klebinger.andreas(a)gmx.at>
- - - - -
615d72ac by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #13180
Closes #13180.
- - - - -
423eebcf by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #11141
Closes #11141.
- - - - -
286849a4 by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #11505
Closes #11505.
- - - - -
7db149d9 by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression perf test for #13820
Closes #13820.
- - - - -
e73c4adb by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #10381
Closes #10381.
- - - - -
5ebcfb57 by Benjamin Maurer at 2026-03-26T03:54:02-04:00
Generate assembly on x86 for word2float (#22252)
We used to emit C function call for MO_UF_Conv primitive.
Now emits direct assembly instead.
Co-Authored-By: Sylvain Henry <sylvain(a)haskus.fr>
Co-Authored-By: Claude Sonnet 4.6 <noreply(a)anthropic.com>
- - - - -
5b550754 by Matthew Pickering at 2026-03-26T03:54:51-04:00
rts: forward clone-stack messages after TSO migration
MSG_CLONE_STACK assumed that the target TSO was still owned by the
capability that received the message. This is not always true: the TSO
can migrate before the inbox entry is handled.
When that happened, handleCloneStackMessage could clone a live stack from
the wrong capability and use the wrong capability for allocation and
performTryPutMVar, leading to stack sanity failures such as
checkStackFrame: weird activation record found on stack.
Fix this by passing the current capability into
handleCloneStackMessage, rechecking msg->tso->cap at handling time, and
forwarding the message if the TSO has migrated. Once ownership matches,
use the executing capability consistently for cloneStack, rts_apply, and
performTryPutMVar.
Fixes #27008
- - - - -
ef0a1bd2 by mangoiv at 2026-03-26T03:55:34-04:00
release tracking: adopt release tracking ticket from #16816
- - - - -
a7f40fd9 by mangoiv at 2026-03-26T03:55:34-04:00
release tracking: add a release tracking ticket
Brings the information in the release tracking ticket up to date with
https://gitlab.haskell.org/ghc/ghc-hq/-/blob/main/release-management.mkd
Resolves #26691
- - - - -
161d3285 by Teo Camarasu at 2026-03-26T03:56:18-04:00
Revert "Set default eventlog-flush-interval to 5s"
Flushing the eventlog forces a synchronisation of all the capabilities
and there was a worry that this might lead to a performance cost for
some highly parallel workloads.
This reverts commit 66b96e2a591d8e3d60e74af3671344dfe4061cf2.
- - - - -
36eed985 by Cheng Shao at 2026-03-26T03:57:03-04:00
ghc-boot: move GHC.Data.SmallArray to ghc-boot
This commit moves `GHC.Data.SmallArray` from the `ghc` library to
`ghc-boot`, so that it can be used by `ghci` as well:
- The `Binary` (from `ghc`) instance of `SmallArray` is moved to
`GHC.Utils.Binary`
- Util functions `replicateSmallArrayIO`, `mapSmallArrayIO`,
`mapSmallArrayM_`, `imapSmallArrayM_` , `smallArrayFromList` and
`smallArrayToList` are added
- The `Show` instance is added
- The `Binary` (from `binary`) instance is added
- - - - -
fdf828ae by Cheng Shao at 2026-03-26T03:57:03-04:00
compiler: use `Binary` instance of `BCOByteArray` for bytecode objects
This commit defines `Binary` (from `compiler`) instance of
`BCOByteArray` which serializes the underlying buffer directly, and
uses it directly in bytecode object serialization. Previously we reuse
the `Binary` (from `binary`) instance, and this change allows us to
avoid double-copying via an intermediate `ByteString` when using
`put`/`get` in `binnary`. Also see added comment for explanation.
- - - - -
3bf62d0a by Cheng Shao at 2026-03-26T03:57:03-04:00
ghci: use SmallArray directly in ResolvedBCO
This patch makes ghci use `SmallArray` directly in `ResolvedBCO` when
applicable, making the memory representation more compact and reducing
marshaling overhead. Closes #27058.
- - - - -
3d6492ce by Wen Kokke at 2026-03-26T03:57:53-04:00
Fix race condition between flushEventLog and start/endEventLogging.
This commit changes `flushEventLog` to acquire/release the `state_change` mutex to prevent interleaving with `startEventLogging` and `endEventLogging`. In the current RTS, `flushEventLog` _does not_ acquire this mutex, which may lead to eventlog corruption on the following interleaving:
- `startEventLogging` writes the new `EventLogWriter` to `event_log_writer`.
- `flushEventLog` flushes some events to `event_log_writer`.
- `startEventLogging` writes the eventlog header to `event_log_writer`.
This causes the eventlog to be written out in an unreadable state, with one or more events preceding the eventlog header.
This commit renames the old function to `flushEventLog_` and defines `flushEventLog` simply as:
```c
void flushEventLog(Capability **cap USED_IF_THREADS)
{
ACQUIRE_LOCK(&state_change_mutex);
flushEventLog_(cap);
RELEASE_LOCK(&state_change_mutex);
}
```
The old function is still needed internally within the compilation unit, where it is used in `endEventLogging` in a context where the `state_change` mutex has already been acquired. I've chosen to mark `flushEventLog_` as static and let other uses of `flushEventLog` within the RTS refer to the new version. There is one use in `hs_init_ghc` via `flushTrace`, where the new locking behaviour should be harmless, and one use in `handle_tick`, which I believe was likely vulnerable to the same race condition, so the new locking behaviour is desirable.
I have not added a test. The behaviour is highly non-deterministic and requires a program that concurrently calls `flushEventLog` and `startEventLogging`/`endEventLogging`. I encountered the issue while developing `eventlog-socket` and within that context have verified that my patch likely addresses the issue: a test that used to fail within the first dozen or so runs now has been running on repeat for several hours.
- - - - -
7b9a75f0 by Phil Hazelden at 2026-03-26T03:58:37-04:00
Fix build with werror on glibc 2.43.
We've been defining `_XOPEN_SOURCE` and `_POSIX_C_SOURCE` to the same
values as defined in glibc prior to 2.43. But in 2.43, glibc changes
them to new values, which means we get a warning when redefining them.
By `#undef`ing them first, we no longer get a warning.
Closes #27076.
- - - - -
fe6e76c5 by Tobias Haslop at 2026-03-26T03:59:30-04:00
Fix broken Haddock link to Bifunctor class in description of Functor class
- - - - -
404b71c1 by Luite Stegeman at 2026-03-27T04:40:49-04:00
Fix assert in Interpreter.c
If we skip exactly the number of words on the stack we end up on
the first word in the next chunk.
- - - - -
a85bd503 by Luite Stegeman at 2026-03-27T04:40:49-04:00
Support arbitrary size unboxed tuples in bytecode
This stores the size (number of words on the stack) of the next
expected tuple in the TSO, ctoi_spill_size field, eliminating
the need of stg_ctoi_tN frames for each size.
Note: On 32 bit platform there is still a bytecode tuple size
limit of 255 words on the stack.
Fixes #26946
- - - - -
e2209031 by Luite Stegeman at 2026-03-27T04:40:49-04:00
Add specialized frames for small tuples
Small tuples are now returned more efficiently to the interpreter.
They use one less word of stack space and don't need manipulation
of the TSO anymore.
- - - - -
b26bb2ea by VeryMilkyJoe at 2026-03-27T04:41:38-04:00
Remove backwards compatibility pattern synonym `ModLocation`
Fixes #24932
- - - - -
66e5e324 by Vladislav Zavialov at 2026-03-27T04:42:25-04:00
Extend HsExpr with the StarIsType syntax (#26587, #26967)
This patch allows kinds of the form `k -> *` and `* -> k` to occur in
expression syntax, i.e. to be used as required type arguments.
For example:
{-# LANGUAGE RequiredTypeArguments, StarIsType #-}
x1 = f (* -> * -> *)
x2 = f (forall k. k -> *)
x3 = f ((* -> *) -> Constraint)
Summary of the changes:
* Introduce the HsStar constructor of HsExpr and its extension field XStar.
It is analogous to HsStarTy in HsType.
* Refactor HsStarTy to store the unicode flag as TokStar, defined as
type TokStar = EpUniToken "*" "★" -- similar to TokForall, TokRArrow, etc.
The token is stored in the extension field and replaces the Bool field.
* Extend the `infixexp2` nonterminal to parse `*` as a direct argument of `->`.
This is more limited than the full StarIsType syntax, but has the nice
property of not conflicting with the multiplication operator `a * b`.
Test case: T26967 T26967_tyop
- - - - -
f8de456f by Sylvain Henry at 2026-03-27T04:43:22-04:00
STM: don't create a transaction in the rhs of catchRetry# (#26028)
We don't need to create a transaction for the rhs of (catchRetry#)
because contrary to the lhs we don't need to abort it on retry. Moreover
it is particularly harmful if we have code such as (#26028):
let cN = readTVar vN >> retry
tree = c1 `orElse` (c2 `orElse` (c3 `orElse` ...))
atomically tree
Because it will stack transactions for the rhss and the read-sets of all
the transactions will be iteratively merged in O(n^2) after the
execution of the most nested retry.
This is the second attempt at implementing this. The first attempt
triggered segfaults (#26291) and has been reverted.
Co-Authored-By: Claude Sonnet 4.6 <noreply(a)anthropic.com>
- - - - -
fcf092dd by Luite Stegeman at 2026-03-27T04:44:17-04:00
Windows: remove StgAsyncIOResult and fix crash/leaks
In stg_block_async{_void}, a stack slot was reserved for
an StgAsyncIOResult. This slot would be filled by the IO
manager upon completion of the async call.
However, if the blocked thread was interrupted by an async
exception, we would end up in an invalid state:
- If the blocked computation was never re-entered, the
StgAsyncIOResult would never be freed.
- If the blocked computation was re-entered, the thread would
find an unitialized stack slot for the StgAsyncIOResult,
leading to a crash reading its fields, or freeing the pointer.
We fix this by removing the StgAsyncIOResult altogether and writing
the result directly to the stack.
Fixes #26341
- - - - -
05094993 by Luite Stegeman at 2026-03-27T04:45:12-04:00
Don't refine DEFAULT alt for unary typeclasses
A non-DEFAULT data alt for a unary typeclass dictionary would
interfere with Unary Class Magic, leading to segfaults.
fixes #27071
- - - - -
4ee260cf by sheaf at 2026-03-27T04:46:06-04:00
Fix several oversights in hsExprType
This commit fixes several oversights in GHC.Hs.Syn.Type.hsExprType:
- The 'RecordCon' case was returning the type of the constructor,
instead of the constructor application. This is fixed by using
'splitFunTys'.
- The 'ExplicitTuple' case failed to take into account tuple sections,
and was also incorrectly handling 1-tuples (e.g. 'Solo') which can
be constructed using Template Haskell.
- The 'NegApp' case was returning the type of the negation operator,
again failing to apply it to the argument. Fixed by using
'funResultTy'.
- The 'HsProc' case was computing the result type of the arrow proc
block, without taking into account the argument type. Fix that by
adding a new field to 'CmdTopTc' that stores the arrow type, so that
we can construct the correct result type `arr a b` for
`proc (pat :: a) -> (cmd :: b)`.
- The 'ArithSeq' and 'NegApp' cases were failing to take into account
the result 'HsWrapper', which could e.g. silently drop casts.
This is fixed by introducing 'syntaxExpr_wrappedFunResTy' which, on
top of taking the result type, applies the result 'HsWrapper'.
These fixes are validated by the new GHC API test T26910.
Fixes #26910
- - - - -
e97232ce by Hai at 2026-03-27T04:47:04-04:00
Parser.y: avoid looking at token with QualifiedDo
This changes the behavior of 'hintQualifiedDo' so that the supplied
token is not inspected when the QualifiedDo language extension bit is
set.
- - - - -
9831385b by Vladislav Zavialov at 2026-03-27T17:22:30-04:00
Infix holes in types (#11107)
This patch introduces several improvements that follow naturally from
refactoring HsOpTy to represent the operator as an HsType, aligning it
with the approach taken by OpApp and HsExpr.
User-facing changes:
1. Infix holes (t1 `_` t2) are now permitted in types, following the
precedent set by term-level expressions.
Test case: T11107
2. Error messages for illegal promotion ticks are now reported at more
precise source locations.
Test case: T17865
Internal changes:
* The definition of HsOpTy now mirrors that of OpApp:
| HsOpTy (XOpTy p) (LHsType p) (LHsType p) (LHsType p)
| OpApp (XOpApp p) (LHsExpr p) (LHsExpr p) (LHsExpr p)
This moves us one step closer to unifying HsType and HsExpr.
* Ignoring locations,
the old pattern match (HsOpTy x prom lhs op rhs)
is now written as (HsOpTy x lhs (HsTyVar x' prom op) rhs)
but we also handle (HsOpTy x lhs (HsWildCardTy x') rhs)
Constructors other than HsTyVar and HsWildCardTy never appear
in the operator position.
* The various definitions across the compiler have been updated to work
with the new representation, drawing inspiration from the term-level
pipeline where appropriate. For example,
ppr_infix_ty <=> ppr_infix_expr
get_tyop <=> get_op
lookupTypeFixityRn <=> lookupExprFixityRn
(the latter is factored out from rnExpr)
Test cases: T11107 T17865
- - - - -
5b6757d7 by mangoiv at 2026-03-27T17:23:19-04:00
ci: build i386 non-validate for deb12
This is a small fix that will unlock ghcup metadata to run, i386 debian
12 was missing as a job.
- - - - -
57157cbc by Vladislav Zavialov at 2026-03-28T01:33:59+03:00
Status check for the HsType~HsExpr refactoring (#25121)
Add a test case to track the status of a refactoring project within GHC,
whose goal is to arrive at the following declaration:
type HsType = HsExpr
The rationale for this is to increase code reuse between the term- and
type-level code in the compiler front-end (AST, parser, renamer, type checker).
- - - - -
931 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/flake.lock
- .gitlab/generate-ci/gen_ci.hs
- + .gitlab/issue_templates/release_tracking.md
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- compiler/CodeGen.Platform.h
- compiler/GHC.hs
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Builtin/Names/TH.hs
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Builtin/Utils.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/Cmm/Expr.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/Cmm/Node.hs
- compiler/GHC/Cmm/Opt.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Cmm/Type.hs
- compiler/GHC/Cmm/Utils.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/CmmToAsm/AArch64/Regs.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/LA64/Ppr.hs
- compiler/GHC/CmmToAsm/LA64/Regs.hs
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/CmmToAsm/PPC/Ppr.hs
- compiler/GHC/CmmToAsm/PPC/Regs.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
- compiler/GHC/CmmToAsm/RV64/Regs.hs
- compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs
- compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToAsm/X86/Regs.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/CmmToLlvm/Config.hs
- compiler/GHC/CmmToLlvm/Data.hs
- compiler/GHC/CmmToLlvm/Mangler.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/Core/Opt/DmdAnal.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/FloatOut.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- + compiler/GHC/Core/Opt/Range.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/AddImplicitBinds.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Config/CmmToLlvm.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Arrows.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Foreign/C.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Ext/Utils.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/String.hs
- + compiler/GHC/Platform/Tag.hs
- compiler/GHC/Prelude/Basic.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Fixity.hs
- compiler/GHC/Rename/HsType.hs
- + compiler/GHC/Rename/Lit.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Runtime/Interpreter/Init.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Stg/Pipeline.hs
- compiler/GHC/Stg/Unarise.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/Closure.hs
- compiler/GHC/StgToCmm/Expr.hs
- compiler/GHC/StgToCmm/Lit.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToCmm/Utils.hs
- compiler/GHC/StgToJS/Literal.hs
- compiler/GHC/StgToJS/Object.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Arrow.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Foreign.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Instance/Typeable.hs
- compiler/GHC/Tc/TyCl/Build.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Demand.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Literal.hs
- + compiler/GHC/Types/Literal/Floating.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Unit/Module/Location.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Error.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/Language/Haskell/Syntax/Expr.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/Language/Haskell/Syntax/Pat.hs
- compiler/Language/Haskell/Syntax/Type.hs
- compiler/ghc.cabal.in
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/exts/pragmas.rst
- + docs/users_guide/exts/qualified_strings.rst
- docs/users_guide/exts/recursive_do.rst
- docs/users_guide/exts/required_type_arguments.rst
- docs/users_guide/exts/rewrite_rules.rst
- docs/users_guide/ghci.rst
- docs/users_guide/using-optimisation.rst
- docs/users_guide/utils.py
- ghc/GHCi/UI.hs
- ghc/Main.hs
- hadrian/README.md
- hadrian/bootstrap/generate_bootstrap_plans
- hadrian/bootstrap/plan-9_10_1.json
- hadrian/bootstrap/plan-9_10_2.json
- + hadrian/bootstrap/plan-9_10_3.json
- hadrian/bootstrap/plan-9_12_1.json
- hadrian/bootstrap/plan-9_12_2.json
- + hadrian/bootstrap/plan-9_14_1.json
- hadrian/bootstrap/plan-bootstrap-9_10_1.json
- hadrian/bootstrap/plan-bootstrap-9_10_2.json
- + hadrian/bootstrap/plan-bootstrap-9_10_3.json
- hadrian/bootstrap/plan-bootstrap-9_12_1.json
- hadrian/bootstrap/plan-bootstrap-9_12_2.json
- + hadrian/bootstrap/plan-bootstrap-9_14_1.json
- hadrian/build-cabal
- hadrian/cabal.project
- hadrian/doc/flavours.md
- hadrian/hadrian.cabal
- hadrian/src/CommandLine.hs
- hadrian/src/Main.hs
- hadrian/src/Rules/Compile.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/GenPrimopCode.hs
- hadrian/src/Settings/Builders/Ghc.hs
- − hadrian/src/Settings/Flavours/Benchmark.hs
- hadrian/src/Settings/Flavours/Development.hs
- hadrian/src/Settings/Flavours/GhcInGhci.hs
- hadrian/src/Settings/Flavours/Quick.hs
- hadrian/src/Settings/Flavours/QuickCross.hs
- hadrian/src/Settings/Flavours/Quickest.hs
- hadrian/src/Settings/Flavours/Validate.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/changelog.md
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Data/Char.hs
- libraries/base/src/Data/Eq.hs
- libraries/base/src/Data/Semigroup.hs
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Fingerprint.hs
- libraries/base/src/GHC/ResponseFile.hs
- libraries/base/src/GHC/Stats.hs
- libraries/base/src/GHC/Unicode.hs
- libraries/base/src/GHC/Weak.hs
- libraries/base/src/GHC/Weak/Finalize.hs
- − libraries/base/src/GHC/Weak/Finalizehs
- libraries/base/src/Prelude.hs
- libraries/base/src/System/Exit.hs
- libraries/base/src/System/IO/OS.hs
- libraries/base/src/System/Info.hs
- libraries/base/src/System/Mem/Weak.hs
- libraries/base/tests/IO/T17912.hs
- libraries/base/tests/IO/T18832.hs
- libraries/base/tests/IO/all.T
- libraries/ghc-boot-th/GHC/Boot/TH/Quote.hs
- compiler/GHC/Data/SmallArray.hs → libraries/ghc-boot/GHC/Data/SmallArray.hs
- libraries/ghc-boot/ghc-boot.cabal.in
- libraries/ghc-experimental/CHANGELOG.md
- libraries/ghc-experimental/ghc-experimental.cabal.in
- libraries/ghc-experimental/src/GHC/Profiling/Eras.hs
- + libraries/ghc-experimental/src/GHC/Stack/Decode/Experimental.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- libraries/ghc-internal/CHANGELOG.md
- libraries/ghc-internal/cbits/Stack.cmm
- libraries/ghc-internal/codepages/MakeTable.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/AllocationLimitHandler.hs
- libraries/ghc-internal/src/GHC/Internal/Arr.hs
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/Bits.hs
- libraries/ghc-internal/src/GHC/Internal/ByteOrder.hs
- − libraries/ghc-internal/src/GHC/Internal/ByteOrder.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Char.hs
- libraries/ghc-internal/src/GHC/Internal/Clock.hsc
- libraries/ghc-internal/src/GHC/Internal/ClosureTypes.hs
- libraries/ghc-internal/src/GHC/Internal/Conc/Bound.hs
- libraries/ghc-internal/src/GHC/Internal/Conc/IO.hs
- libraries/ghc-internal/src/GHC/Internal/Conc/POSIX.hs
- libraries/ghc-internal/src/GHC/Internal/Conc/Signal.hs
- libraries/ghc-internal/src/GHC/Internal/Conc/Sync.hs
- − libraries/ghc-internal/src/GHC/Internal/Conc/Sync.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Conc/Windows.hs
- libraries/ghc-internal/src/GHC/Internal/ConsoleHandler.hsc
- libraries/ghc-internal/src/GHC/Internal/Control/Arrow.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Concurrent/MVar.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Exception/Base.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fail.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/IO/Class.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/ST/Imp.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/ST/Lazy/Imp.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Bits.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Dynamic.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Either.hs
- − libraries/ghc-internal/src/GHC/Internal/Data/Eq.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Function.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Functor/Const.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Functor/Identity.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Functor/Utils.hs
- libraries/ghc-internal/src/GHC/Internal/Data/IORef.hs
- libraries/ghc-internal/src/GHC/Internal/Data/List.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Maybe.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Monoid.hs
- libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Ord.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Proxy.hs
- libraries/ghc-internal/src/GHC/Internal/Data/STRef.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Semigroup/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/Data/String.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Traversable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Coercion.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Equality.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Ord.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Typeable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Typeable/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Unique.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- − libraries/ghc-internal/src/GHC/Internal/Data/Version.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Debug/Trace.hs
- libraries/ghc-internal/src/GHC/Internal/Debug/Trace.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Encoding/UTF8.hs
- libraries/ghc-internal/src/GHC/Internal/Enum.hs
- libraries/ghc-internal/src/GHC/Internal/Environment.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Array.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Control.hs
- libraries/ghc-internal/src/GHC/Internal/Event/EPoll.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/IntVar.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Internal/Types.hs
- libraries/ghc-internal/src/GHC/Internal/Event/KQueue.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/Manager.hs
- libraries/ghc-internal/src/GHC/Internal/Event/PSQ.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Poll.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/Thread.hs
- libraries/ghc-internal/src/GHC/Internal/Event/TimeOut.hs
- libraries/ghc-internal/src/GHC/Internal/Event/TimerManager.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Unique.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/Clock.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/ConsoleEvent.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/FFI.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/ManagedThreadPool.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/Thread.hs
- libraries/ghc-internal/src/GHC/Internal/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Exception/Context.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- libraries/ghc-internal/src/GHC/Internal/ExecutionStack.hs
- libraries/ghc-internal/src/GHC/Internal/ExecutionStack/Internal.hsc
- libraries/ghc-internal/src/GHC/Internal/Exts.hs
- libraries/ghc-internal/src/GHC/Internal/Fingerprint.hs
- libraries/ghc-internal/src/GHC/Internal/Fingerprint.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Fingerprint/Type.hs
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- libraries/ghc-internal/src/GHC/Internal/Float/ConversionUtils.hs
- libraries/ghc-internal/src/GHC/Internal/Float/RealFracMethods.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/C/ConstPtr.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/C/Error.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/C/String.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/C/String/Encoding.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/C/Types.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/ForeignPtr/Imp.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Alloc.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Array.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Error.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Pool.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Utils.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/Ptr.hs
- libraries/ghc-internal/src/GHC/Internal/Foreign/Storable.hs
- libraries/ghc-internal/src/GHC/Internal/ForeignPtr.hs
- libraries/ghc-internal/src/GHC/Internal/ForeignSrcLang.hs
- libraries/ghc-internal/src/GHC/Internal/Functor/ZipList.hs
- libraries/ghc-internal/src/GHC/Internal/GHCi.hs
- libraries/ghc-internal/src/GHC/Internal/GHCi/Helpers.hs
- libraries/ghc-internal/src/GHC/Internal/Generics.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable.hsc
- libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable/Types.hsc
- libraries/ghc-internal/src/GHC/Internal/Heap/InfoTableProf.hsc
- libraries/ghc-internal/src/GHC/Internal/Heap/ProfInfo/Types.hs
- libraries/ghc-internal/src/GHC/Internal/IO.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Buffer.hs
- libraries/ghc-internal/src/GHC/Internal/IO/BufferedIO.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Device.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/CodePage.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/CodePage/API.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/CodePage/Table.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/Failure.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/Iconv.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/Latin1.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/Types.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/UTF16.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/UTF32.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/UTF8.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Exception.hs-boot
- libraries/ghc-internal/src/GHC/Internal/IO/FD.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/FD.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Internals.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Lock.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Lock/Flock.hsc
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Lock/LinuxOFD.hsc
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Lock/NoOp.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Lock/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Text.hs
- − libraries/ghc-internal/src/GHC/Internal/IO/Handle/Text.hs-boot
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Windows.hs
- libraries/ghc-internal/src/GHC/Internal/IO/IOMode.hs
- libraries/ghc-internal/src/GHC/Internal/IO/SubSystem.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Unsafe.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Windows/Encoding.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Windows/Handle.hsc
- libraries/ghc-internal/src/GHC/Internal/IOArray.hs
- libraries/ghc-internal/src/GHC/Internal/IORef.hs
- libraries/ghc-internal/src/GHC/Internal/InfoProv.hs
- libraries/ghc-internal/src/GHC/Internal/InfoProv/Types.hsc
- libraries/ghc-internal/src/GHC/Internal/Int.hs
- libraries/ghc-internal/src/GHC/Internal/IsList.hs
- libraries/ghc-internal/src/GHC/Internal/Ix.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Foreign/Callback.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim/Internal/Build.hs
- libraries/ghc-internal/src/GHC/Internal/LanguageExtensions.hs
- libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
- libraries/ghc-internal/src/GHC/Internal/List.hs
- libraries/ghc-internal/src/GHC/Internal/MVar.hs
- libraries/ghc-internal/src/GHC/Internal/Num.hs
- libraries/ghc-internal/src/GHC/Internal/Numeric.hs
- libraries/ghc-internal/src/GHC/Internal/OverloadedLabels.hs
- libraries/ghc-internal/src/GHC/Internal/Pack.hs
- + libraries/ghc-internal/src/GHC/Internal/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/Profiling.hs
- libraries/ghc-internal/src/GHC/Internal/Ptr.hs
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags/Test.hsc
- libraries/ghc-internal/src/GHC/Internal/Read.hs
- libraries/ghc-internal/src/GHC/Internal/Real.hs
- − libraries/ghc-internal/src/GHC/Internal/ResponseFile.hs
- libraries/ghc-internal/src/GHC/Internal/ST.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- libraries/ghc-internal/src/GHC/Internal/STRef.hs
- libraries/ghc-internal/src/GHC/Internal/Show.hs
- libraries/ghc-internal/src/GHC/Internal/Stable.hs
- libraries/ghc-internal/src/GHC/Internal/StableName.hs
- libraries/ghc-internal/src/GHC/Internal/Stack.hs
- libraries/ghc-internal/src/GHC/Internal/Stack.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Stack/Annotation.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc
- libraries/ghc-internal/src/GHC/Internal/Stack/CloneStack.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/Constants.hsc
- libraries/ghc-internal/src/GHC/Internal/Stack/ConstantsProf.hsc
- libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/StaticPtr.hs
- libraries/ghc-internal/src/GHC/Internal/StaticPtr/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/Stats.hsc
- libraries/ghc-internal/src/GHC/Internal/Storable.hs
- libraries/ghc-internal/src/GHC/Internal/System/Environment.hs
- libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc
- libraries/ghc-internal/src/GHC/Internal/System/Environment/ExecutablePath.hsc
- − libraries/ghc-internal/src/GHC/Internal/System/Exit.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO/Error.hs
- − libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/src/GHC/Internal/System/Mem.hs
- libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs
- libraries/ghc-internal/src/GHC/Internal/System/Posix/Types.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- − libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/ghc-internal/src/GHC/Internal/Text/ParserCombinators/ReadP.hs
- libraries/ghc-internal/src/GHC/Internal/Text/ParserCombinators/ReadPrec.hs
- libraries/ghc-internal/src/GHC/Internal/Text/Read.hs
- libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs
- libraries/ghc-internal/src/GHC/Internal/TopHandler.hs
- libraries/ghc-internal/src/GHC/Internal/TypeLits.hs
- libraries/ghc-internal/src/GHC/Internal/TypeLits/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/TypeNats.hs
- libraries/ghc-internal/src/GHC/Internal/TypeNats/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Bits.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/DerivedCoreProperties.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/GeneralCategory.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleLowerCaseMapping.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleTitleCaseMapping.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleUpperCaseMapping.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Unsafe/Coerce.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Conc.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Conc/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Exports.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Flag.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Imports.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Types.hs
- libraries/ghc-internal/src/GHC/Internal/Weak.hs
- libraries/ghc-internal/src/GHC/Internal/Weak/Finalize.hs
- libraries/ghc-internal/src/GHC/Internal/Windows.hs
- libraries/ghc-internal/src/GHC/Internal/Word.hs
- libraries/ghc-internal/tools/ucd2haskell/exe/UCD2Haskell/ModuleGenerators.hs
- libraries/ghci/GHCi/CreateBCO.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/ResolvedBCO.hs
- libraries/ghci/GHCi/Run.hs
- libraries/ghci/GHCi/Server.hs
- libraries/template-haskell-quasiquoter
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- m4/fp_prog_cc_linker_target.m4
- nofib
- rts/Apply.cmm
- rts/CloneStack.c
- rts/CloneStack.h
- rts/Continuation.c
- rts/ContinuationOps.cmm
- rts/HeapStackCheck.cmm
- rts/IOManager.c
- rts/Interpreter.c
- rts/Linker.c
- rts/LinkerInternals.h
- rts/Messages.c
- rts/PrimOps.cmm
- rts/Printer.c
- rts/RaiseAsync.c
- rts/RtsFlags.c
- rts/RtsSymbols.c
- rts/STM.c
- rts/STM.h
- rts/Schedule.c
- rts/Stats.c
- rts/StgCRun.c
- rts/StgMiscClosures.cmm
- rts/Threads.c
- rts/Threads.h
- rts/eventlog/EventLog.c
- rts/include/RtsAPI.h
- rts/include/rts/Bytecodes.h
- rts/include/rts/Constants.h
- rts/include/rts/PosixSource.h
- rts/include/rts/Threads.h
- rts/include/rts/storage/TSO.h
- rts/include/stg/MiscClosures.h
- rts/include/stg/Prim.h
- rts/js/arith.js
- rts/linker/Elf.c
- rts/linker/MachO.c
- rts/linker/PEi386.c
- rts/prim/vectorQuotRem.c
- rts/rts.cabal
- rts/win32/AsyncMIO.c
- rts/win32/AsyncMIO.h
- testsuite/.gitignore
- testsuite/driver/perf_notes.py
- testsuite/tests/annotations/should_run/all.T
- + testsuite/tests/bytecode/T27001.hs
- + testsuite/tests/bytecode/T27001.stdout
- testsuite/tests/bytecode/all.T
- + testsuite/tests/bytecode/tuplestress/ByteCode.hs
- + testsuite/tests/bytecode/tuplestress/Common.hs-incl
- + testsuite/tests/bytecode/tuplestress/Obj.hs
- + testsuite/tests/bytecode/tuplestress/TupleStress.hs
- + testsuite/tests/bytecode/tuplestress/TupleStress.stdout
- + testsuite/tests/bytecode/tuplestress/all.T
- testsuite/tests/codeGen/should_compile/Makefile
- + testsuite/tests/codeGen/should_compile/T25650.hs
- + testsuite/tests/codeGen/should_compile/T25650.stdout-ws-32
- + testsuite/tests/codeGen/should_compile/T25650.stdout-ws-64
- testsuite/tests/codeGen/should_compile/all.T
- testsuite/tests/codeGen/should_compile/debug.stdout
- + testsuite/tests/codeGen/should_run/T21227.hs
- + testsuite/tests/codeGen/should_run/T21227.stdout
- + testsuite/tests/codeGen/should_run/T9811.hs
- + testsuite/tests/codeGen/should_run/T9811.stdout
- testsuite/tests/codeGen/should_run/Word2Float32.hs
- testsuite/tests/codeGen/should_run/Word2Float32.stdout
- testsuite/tests/codeGen/should_run/Word2Float64.hs
- testsuite/tests/codeGen/should_run/Word2Float64.stdout
- testsuite/tests/codeGen/should_run/all.T
- + testsuite/tests/concurrent/should_run/T26341.hs
- + testsuite/tests/concurrent/should_run/T26341.stdout
- + testsuite/tests/concurrent/should_run/T26341a.hs
- + testsuite/tests/concurrent/should_run/T26341a.stdout
- + testsuite/tests/concurrent/should_run/T26341b.hs
- + testsuite/tests/concurrent/should_run/T26341b.stdout
- testsuite/tests/concurrent/should_run/all.T
- + testsuite/tests/corelint/T15907.hs
- + testsuite/tests/corelint/T15907A.hs
- testsuite/tests/corelint/all.T
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/deSugar/should_compile/T16615.stderr
- testsuite/tests/deSugar/should_compile/T2431.stderr
- + testsuite/tests/dependent/should_fail/T15588.hs
- + testsuite/tests/dependent/should_fail/T15588.stderr
- testsuite/tests/dependent/should_fail/all.T
- testsuite/tests/dmdanal/should_compile/T16029.stdout
- testsuite/tests/dmdanal/should_compile/T18894.stderr
- + testsuite/tests/dmdanal/should_run/M1.hs
- + testsuite/tests/dmdanal/should_run/T26416.hs
- + testsuite/tests/dmdanal/should_run/T26416.stdout
- testsuite/tests/dmdanal/should_run/all.T
- testsuite/tests/dmdanal/sigs/T21081.stderr
- − testsuite/tests/driver/OneShotTH.stdout-javascript-unknown-ghcjs
- + testsuite/tests/driver/T13729/A/A.cabal
- + testsuite/tests/driver/T13729/A/Setup.hs
- + testsuite/tests/driver/T13729/A/TH.hs
- + testsuite/tests/driver/T13729/A/Types1.hs
- + testsuite/tests/driver/T13729/A/Types2.hs
- + testsuite/tests/driver/T13729/B/B.cabal
- + testsuite/tests/driver/T13729/B/Main.hs
- + testsuite/tests/driver/T13729/B/Setup.hs
- + testsuite/tests/driver/T13729/Makefile
- + testsuite/tests/driver/T13729/Setup.hs
- + testsuite/tests/driver/T13729/all.T
- + testsuite/tests/driver/T2057/Makefile
- + testsuite/tests/driver/T2057/README.md
- + testsuite/tests/driver/T2057/T2057.stderr
- + testsuite/tests/driver/T2057/all.T
- + testsuite/tests/driver/T2057/app/Main.hs
- + testsuite/tests/driver/T2057/pkgA1/A.hs
- + testsuite/tests/driver/T2057/pkgA1/pkg.conf
- + testsuite/tests/driver/T2057/pkgA2/A.hs
- + testsuite/tests/driver/T2057/pkgA2/pkg.conf
- + testsuite/tests/driver/T2057/pkgB/B.hs
- + testsuite/tests/driver/T2057/pkgB/pkg.conf
- + testsuite/tests/driver/T20604/T20604.stdout-javascript-unknown-ghcjs
- testsuite/tests/driver/T20604/all.T
- testsuite/tests/driver/T4437.hs
- testsuite/tests/driver/all.T
- testsuite/tests/driver/fat-iface/fat010.stdout-javascript-unknown-ghcjs
- testsuite/tests/driver/recomp011/all.T
- testsuite/tests/driver/recompHash/recompHash.stdout-javascript-unknown-ghcjs
- testsuite/tests/driver/recompNoTH/recompNoTH.stdout-javascript-unknown-ghcjs
- − testsuite/tests/driver/th-new-test/th-new-test.stdout-javascript-unknown-ghcjs
- + testsuite/tests/exceptions/T26759.hs
- + testsuite/tests/exceptions/T26759.stderr
- + testsuite/tests/exceptions/T26759a.hs
- + testsuite/tests/exceptions/T26759a.stderr
- + testsuite/tests/exceptions/T26759a.stdout
- testsuite/tests/exceptions/all.T
- + testsuite/tests/ffi/should_compile/T26852.h
- + testsuite/tests/ffi/should_compile/T26852.hs
- + testsuite/tests/ffi/should_compile/T26852.stderr
- testsuite/tests/ffi/should_compile/all.T
- + testsuite/tests/ffi/should_run/PrimFFIUnboxedSum.hs
- + testsuite/tests/ffi/should_run/PrimFFIUnboxedSum.stdout
- + testsuite/tests/ffi/should_run/PrimFFIUnboxedSum_cmm.cmm
- testsuite/tests/ffi/should_run/all.T
- + testsuite/tests/ghc-api/T25121_status.hs
- + testsuite/tests/ghc-api/T25121_status.stdout
- + testsuite/tests/ghc-api/T26910.hs
- + testsuite/tests/ghc-api/T26910.stdout
- + testsuite/tests/ghc-api/T26910_Input.hs
- testsuite/tests/ghc-api/all.T
- testsuite/tests/ghc-api/annotations-literals/literals.stdout
- testsuite/tests/ghc-api/fixed-nodes/FixedNodes.hs
- testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.hs
- + testsuite/tests/ghci-wasm/T26998.hs
- testsuite/tests/ghci-wasm/all.T
- + testsuite/tests/ghci/custom-external-interpreter-commands/Main.hs
- + testsuite/tests/ghci/custom-external-interpreter-commands/all.T
- + testsuite/tests/ghci/custom-external-interpreter-commands/custom-external-interpreter-commands.stdout
- testsuite/tests/ghci/prog-mhu005/Makefile
- testsuite/tests/ghci/prog-mhu005/all.T
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005b.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005b.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005c.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005c.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005c.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005d.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005d.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005d.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005e.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005e.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005e.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005f.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005f.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005f.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005g.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005g.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005g.stdout
- testsuite/tests/ghci/prog022/Makefile
- testsuite/tests/ghci/prog022/all.T
- + testsuite/tests/ghci/prog022/ghci.prog022c.script
- + testsuite/tests/ghci/prog022/ghci.prog022c.stderr
- + testsuite/tests/ghci/prog022/ghci.prog022c.stdout
- + testsuite/tests/ghci/prog022/ghci.prog022d.script
- + testsuite/tests/ghci/prog022/ghci.prog022d.stderr
- + testsuite/tests/ghci/prog022/ghci.prog022d.stdout
- + testsuite/tests/ghci/prog022/ghci.prog022e.script
- + testsuite/tests/ghci/prog022/ghci.prog022e.stderr
- + testsuite/tests/ghci/prog022/ghci.prog022e.stdout
- + testsuite/tests/ghci/prog022/ghci.prog022f.script
- + testsuite/tests/ghci/prog022/ghci.prog022f.stderr
- + testsuite/tests/ghci/prog022/ghci.prog022f.stdout
- testsuite/tests/ghci/scripts/ListTuplePunsPpr.stdout
- testsuite/tests/ghci/scripts/T10963.stderr
- + testsuite/tests/ghci/scripts/T24632.hs
- + testsuite/tests/ghci/scripts/T24632.script
- + testsuite/tests/ghci/scripts/T24632.stdout
- testsuite/tests/ghci/scripts/all.T
- testsuite/tests/ghci/scripts/ghci064.stdout
- testsuite/tests/ghci/should_run/BinaryArray.hs
- testsuite/tests/ghci/should_run/all.T
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- + testsuite/tests/javascript/T24886.hs
- + testsuite/tests/javascript/T24886.stderr
- + testsuite/tests/javascript/T24886.stdout
- testsuite/tests/javascript/all.T
- + testsuite/tests/javascript/js-c-sources/T27033.hs
- + testsuite/tests/javascript/js-c-sources/T27033.stdout
- + testsuite/tests/javascript/js-c-sources/T27033_c.c
- + testsuite/tests/javascript/js-c-sources/T27033_js.js
- testsuite/tests/javascript/js-c-sources/all.T
- testsuite/tests/javascript/js-mk_tup.hs
- testsuite/tests/javascript/js-mk_tup.stdout
- + testsuite/tests/lib/stm/T26028.hs
- + testsuite/tests/lib/stm/T26028.stdout
- + testsuite/tests/lib/stm/T26291a.hs
- + testsuite/tests/lib/stm/T26291a.stdout
- + testsuite/tests/lib/stm/T26291b.hs
- + testsuite/tests/lib/stm/T26291b.stdout
- + testsuite/tests/lib/stm/all.T
- testsuite/tests/linters/Makefile
- testsuite/tests/numeric/should_compile/T14170.stdout
- testsuite/tests/numeric/should_compile/T14465.stdout
- testsuite/tests/numeric/should_compile/T7116.stdout
- testsuite/tests/numeric/should_run/T7014.hs
- testsuite/tests/numeric/should_run/all.T
- + testsuite/tests/overloadedrecflds/should_compile/T26686.hs
- + testsuite/tests/overloadedrecflds/should_compile/T26686.stderr
- testsuite/tests/overloadedrecflds/should_compile/all.T
- testsuite/tests/overloadedrecflds/should_run/all.T
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- + testsuite/tests/parser/should_compile/T12002.hs
- + testsuite/tests/parser/should_compile/T12002.stderr
- testsuite/tests/parser/should_compile/all.T
- testsuite/tests/parser/should_fail/T17865.stderr
- + testsuite/tests/partial-sigs/should_compile/T11107.hs
- + testsuite/tests/partial-sigs/should_compile/T11107.stderr
- testsuite/tests/partial-sigs/should_compile/all.T
- + testsuite/tests/perf/compiler/T13820.hs
- testsuite/tests/perf/compiler/T9675.hs
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/perf/should_run/T1216.hs
- + testsuite/tests/perf/should_run/T1216.stdout
- testsuite/tests/perf/should_run/all.T
- testsuite/tests/perf/size/all.T
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/pmcheck/should_compile/T11303.hs
- + testsuite/tests/polykinds/T18186.hs
- + testsuite/tests/polykinds/T18186.stderr
- testsuite/tests/polykinds/all.T
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/profiling/should_run/callstack002.stderr
- testsuite/tests/profiling/should_run/callstack002.stdout
- + testsuite/tests/qualified-strings/Makefile
- + testsuite/tests/qualified-strings/should_compile/Example/Length.hs
- + testsuite/tests/qualified-strings/should_compile/all.T
- + testsuite/tests/qualified-strings/should_compile/qstrings_redundant_pattern.hs
- + testsuite/tests/qualified-strings/should_compile/qstrings_redundant_pattern.stderr
- + testsuite/tests/qualified-strings/should_fail/Example/Length.hs
- + testsuite/tests/qualified-strings/should_fail/Makefile
- + testsuite/tests/qualified-strings/should_fail/all.T
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_expr.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_expr.stderr
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_pat.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_pat.stderr
- + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.stderr
- + testsuite/tests/qualified-strings/should_run/Example/ByteStringAscii.hs
- + testsuite/tests/qualified-strings/should_run/Example/ByteStringUtf8.hs
- + testsuite/tests/qualified-strings/should_run/Example/Text.hs
- + testsuite/tests/qualified-strings/should_run/Makefile
- + testsuite/tests/qualified-strings/should_run/all.T
- + testsuite/tests/qualified-strings/should_run/qstrings_expr.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_expr.stdout
- + testsuite/tests/qualified-strings/should_run/qstrings_pat.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_pat.stdout
- + testsuite/tests/qualified-strings/should_run/qstrings_th.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_th.stdout
- testsuite/tests/quasiquotation/qq005/test.T
- testsuite/tests/quasiquotation/qq006/test.T
- testsuite/tests/quotes/QQError.stderr
- + testsuite/tests/rebindable/T10381.hs
- testsuite/tests/rebindable/all.T
- testsuite/tests/roles/should_compile/Roles1.stderr
- testsuite/tests/roles/should_compile/Roles13.stderr
- testsuite/tests/roles/should_compile/Roles14.stderr
- testsuite/tests/roles/should_compile/Roles2.stderr
- testsuite/tests/roles/should_compile/Roles3.stderr
- testsuite/tests/roles/should_compile/Roles4.stderr
- testsuite/tests/roles/should_compile/T8958.stderr
- testsuite/tests/rts/all.T
- + testsuite/tests/rts/cloneThreadStackMigrating.hs
- testsuite/tests/rts/linker/Makefile
- + testsuite/tests/rts/linker/T6107.hs
- + testsuite/tests/rts/linker/T6107.stdout
- + testsuite/tests/rts/linker/T6107_sym1.s
- + testsuite/tests/rts/linker/T6107_sym2.s
- testsuite/tests/rts/linker/all.T
- + testsuite/tests/rts/resizeMutableByteArrayInPlace.hs
- testsuite/tests/saks/should_compile/all.T
- testsuite/tests/showIface/all.T
- + testsuite/tests/simd/should_run/FloatConstant.hs
- + testsuite/tests/simd/should_run/FloatConstant.stdout
- + testsuite/tests/simd/should_run/IntConstant.hs
- + testsuite/tests/simd/should_run/IntConstant.stdout
- + testsuite/tests/simd/should_run/StackAlignment32.hs
- + testsuite/tests/simd/should_run/StackAlignment32.stdout
- + testsuite/tests/simd/should_run/StackAlignment32_main.c
- + testsuite/tests/simd/should_run/StackAlignment64.hs
- + testsuite/tests/simd/should_run/StackAlignment64.stdout
- + testsuite/tests/simd/should_run/StackAlignment64_main.c
- testsuite/tests/simd/should_run/all.T
- testsuite/tests/simd/should_run/doublex2_arith.hs
- testsuite/tests/simd/should_run/doublex2_arith.stdout
- testsuite/tests/simd/should_run/doublex2_arith_baseline.hs
- testsuite/tests/simd/should_run/doublex2_arith_baseline.stdout
- testsuite/tests/simd/should_run/floatx4_arith.hs
- testsuite/tests/simd/should_run/floatx4_arith.stdout
- testsuite/tests/simd/should_run/floatx4_arith_baseline.hs
- testsuite/tests/simd/should_run/floatx4_arith_baseline.stdout
- testsuite/tests/simd/should_run/int16x8_arith.hs
- testsuite/tests/simd/should_run/int16x8_arith.stdout
- testsuite/tests/simd/should_run/int16x8_arith_baseline.hs
- testsuite/tests/simd/should_run/int16x8_arith_baseline.stdout
- testsuite/tests/simd/should_run/int16x8_shuffle.hs
- testsuite/tests/simd/should_run/int16x8_shuffle.stdout
- testsuite/tests/simd/should_run/int16x8_shuffle_baseline.hs
- testsuite/tests/simd/should_run/int16x8_shuffle_baseline.stdout
- testsuite/tests/simd/should_run/int32x4_arith.hs
- testsuite/tests/simd/should_run/int32x4_arith.stdout
- testsuite/tests/simd/should_run/int32x4_arith_baseline.hs
- testsuite/tests/simd/should_run/int32x4_arith_baseline.stdout
- testsuite/tests/simd/should_run/int64x2_arith.hs
- testsuite/tests/simd/should_run/int64x2_arith.stdout
- testsuite/tests/simd/should_run/int64x2_arith_baseline.hs
- testsuite/tests/simd/should_run/int64x2_arith_baseline.stdout
- testsuite/tests/simd/should_run/int8x16_arith.hs
- testsuite/tests/simd/should_run/int8x16_arith.stdout
- testsuite/tests/simd/should_run/int8x16_arith_baseline.hs
- testsuite/tests/simd/should_run/int8x16_arith_baseline.stdout
- testsuite/tests/simd/should_run/int8x16_shuffle.hs
- testsuite/tests/simd/should_run/int8x16_shuffle.stdout
- testsuite/tests/simd/should_run/int8x16_shuffle_baseline.hs
- testsuite/tests/simd/should_run/int8x16_shuffle_baseline.stdout
- testsuite/tests/simd/should_run/simd013C.c
- testsuite/tests/simplCore/should_compile/OpaqueNoCastWW.stderr
- + testsuite/tests/simplCore/should_compile/T12640.hs
- + testsuite/tests/simplCore/should_compile/T12640.stderr
- + testsuite/tests/simplCore/should_compile/T14908.hs
- + testsuite/tests/simplCore/should_compile/T14908_Deps.hs
- + testsuite/tests/simplCore/should_compile/T16122.hs
- + testsuite/tests/simplCore/should_compile/T16122.stderr
- + testsuite/tests/simplCore/should_compile/T18032.hs
- + testsuite/tests/simplCore/should_compile/T18032.stderr
- + testsuite/tests/simplCore/should_compile/T19166.hs
- + testsuite/tests/simplCore/should_compile/T19166.stderr
- + testsuite/tests/simplCore/should_compile/T25718.hs
- + testsuite/tests/simplCore/should_compile/T25718.stderr
- + testsuite/tests/simplCore/should_compile/T25718a.hs
- + testsuite/tests/simplCore/should_compile/T25718a.stderr
- + testsuite/tests/simplCore/should_compile/T25718b.hs
- + testsuite/tests/simplCore/should_compile/T25718b.stderr
- + testsuite/tests/simplCore/should_compile/T25718c.hs
- + testsuite/tests/simplCore/should_compile/T25718c.stderr-ws-32
- + testsuite/tests/simplCore/should_compile/T25718c.stderr-ws-64
- + testsuite/tests/simplCore/should_compile/T26642.hs
- testsuite/tests/simplCore/should_compile/T3717.stderr
- testsuite/tests/simplCore/should_compile/T3772.stdout
- testsuite/tests/simplCore/should_compile/T4908.stderr
- testsuite/tests/simplCore/should_compile/T4930.stderr
- testsuite/tests/simplCore/should_compile/T7360.stderr
- testsuite/tests/simplCore/should_compile/T8274.stdout
- testsuite/tests/simplCore/should_compile/T9400.stderr
- + testsuite/tests/simplCore/should_compile/T9445.hs
- + testsuite/tests/simplCore/should_compile/TrickyJoins.hs
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_compile/noinline01.stderr
- testsuite/tests/simplCore/should_compile/par01.stderr
- + testsuite/tests/simplCore/should_run/T27071.hs
- + testsuite/tests/simplCore/should_run/T27071.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/simplStg/should_run/all.T
- + testsuite/tests/simplStg/should_run/unpack_enum.hs
- + testsuite/tests/simplStg/should_run/unpack_enum.stdout
- testsuite/tests/th/QQTopError.stderr
- testsuite/tests/th/TH_Roles2.stderr
- testsuite/tests/th/all.T
- + testsuite/tests/typecheck/T13180/T13180.hs
- + testsuite/tests/typecheck/T13180/T13180.hs-boot
- + testsuite/tests/typecheck/T13180/T13180.stderr
- + testsuite/tests/typecheck/T13180/T13180A.hs
- + testsuite/tests/typecheck/T13180/all.T
- + testsuite/tests/typecheck/should_compile/T11141.hs
- + testsuite/tests/typecheck/should_compile/T11141.stderr
- + testsuite/tests/typecheck/should_compile/T11505Bar.hs
- + testsuite/tests/typecheck/should_compile/T11505Foo.hs
- + testsuite/tests/typecheck/should_compile/T11505Foo.hs-boot
- + testsuite/tests/typecheck/should_compile/T12046.hs
- testsuite/tests/typecheck/should_compile/T13032.stderr
- + testsuite/tests/typecheck/should_compile/T14151.hs
- testsuite/tests/typecheck/should_compile/T18406b.stderr
- testsuite/tests/typecheck/should_compile/T18529.stderr
- testsuite/tests/typecheck/should_compile/T26225.hs
- testsuite/tests/typecheck/should_compile/all.T
- + testsuite/tests/typecheck/should_fail/T12694.hs
- + testsuite/tests/typecheck/should_fail/T12694.stderr
- + testsuite/tests/typecheck/should_fail/T16275.stderr
- + testsuite/tests/typecheck/should_fail/T16275A.hs
- + testsuite/tests/typecheck/should_fail/T16275B.hs
- + testsuite/tests/typecheck/should_fail/T16275B.hs-boot
- + testsuite/tests/typecheck/should_fail/T26823.hs
- + testsuite/tests/typecheck/should_fail/T26823.stderr
- testsuite/tests/typecheck/should_fail/all.T
- + testsuite/tests/vdq-rta/should_compile/T26967.hs
- + testsuite/tests/vdq-rta/should_compile/T26967.stderr
- + testsuite/tests/vdq-rta/should_compile/T26967_tyop.hs
- + testsuite/tests/vdq-rta/should_compile/T26967_tyop.stderr
- testsuite/tests/vdq-rta/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/deriveConstants/Main.hs
- utils/genprimopcode/Main.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Parser.hs
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6874166e4ff881608e9d6ceb77b0c8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6874166e4ff881608e9d6ceb77b0c8…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
27 Mar '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
5b6757d7 by mangoiv at 2026-03-27T17:23:19-04:00
ci: build i386 non-validate for deb12
This is a small fix that will unlock ghcup metadata to run, i386 debian
12 was missing as a job.
- - - - -
3 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
Changes:
=====================================
.gitlab/generate-ci/gen_ci.hs
=====================================
@@ -1173,17 +1173,17 @@ debian_x86 =
debian_aarch64 :: [JobGroup Job]
debian_aarch64 =
- [
- disableValidate (standardBuildsWithConfig AArch64 (Linux Debian11) (splitSectionsBroken vanilla))
- , disableValidate (standardBuildsWithConfig AArch64 (Linux Debian12) (splitSectionsBroken vanilla))
- , fastCI (standardBuildsWithConfig AArch64 (Linux Debian13) (splitSectionsBroken vanilla))
- -- LLVM backend bootstrap
- , onlyRule LLVMBackend (validateBuilds AArch64 (Linux Debian13) llvm)
+ [ disableValidate (standardBuildsWithConfig AArch64 (Linux Debian11) (splitSectionsBroken vanilla))
+ , disableValidate (standardBuildsWithConfig AArch64 (Linux Debian12) (splitSectionsBroken vanilla))
+ , fastCI (standardBuildsWithConfig AArch64 (Linux Debian13) (splitSectionsBroken vanilla))
+ -- LLVM backend bootstrap
+ , onlyRule LLVMBackend (validateBuilds AArch64 (Linux Debian13) llvm)
]
debian_i386 :: [JobGroup Job]
debian_i386 =
[ disableValidate (standardBuildsWithConfig I386 (Linux Debian11) (splitSectionsBroken vanilla))
+ , disableValidate (standardBuildsWithConfig I386 (Linux Debian12) (splitSectionsBroken vanilla))
, addValidateRule I386Backend (standardBuildsWithConfig I386 (Linux Debian13) (splitSectionsBroken vanilla))
]
=====================================
.gitlab/jobs.yaml
=====================================
@@ -664,6 +664,68 @@
"TEST_ENV": "i386-linux-deb11-validate"
}
},
+ "i386-linux-deb12-validate": {
+ "after_script": [
+ ".gitlab/ci.sh save_cache",
+ ".gitlab/ci.sh save_test_output",
+ ".gitlab/ci.sh clean",
+ "cat ci_timings.txt"
+ ],
+ "allow_failure": false,
+ "artifacts": {
+ "expire_in": "2 weeks",
+ "paths": [
+ "ghc-i386-linux-deb12-validate.tar.xz",
+ "junit.xml",
+ "unexpected-test-output.tar.gz"
+ ],
+ "reports": {
+ "junit": "junit.xml"
+ },
+ "when": "always"
+ },
+ "cache": {
+ "key": "i386-linux-deb12-$CACHE_REV",
+ "paths": [
+ "cabal-cache",
+ "toolchain"
+ ]
+ },
+ "dependencies": [],
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/i386-linux-deb12:$DOCKER_REV",
+ "needs": [
+ {
+ "artifacts": false,
+ "job": "hadrian-ghc-in-ghci"
+ }
+ ],
+ "rules": [
+ {
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bi386-linux-deb12-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "when": "on_success"
+ }
+ ],
+ "script": [
+ "sudo chown ghc:ghc -R .",
+ ".gitlab/ci.sh setup",
+ ".gitlab/ci.sh configure",
+ ".gitlab/ci.sh build_hadrian",
+ ".gitlab/ci.sh test_hadrian"
+ ],
+ "stage": "full-build",
+ "tags": [
+ "x86_64-linux"
+ ],
+ "variables": {
+ "BIGNUM_BACKEND": "gmp",
+ "BIN_DIST_NAME": "ghc-i386-linux-deb12-validate",
+ "BUILD_FLAVOUR": "validate",
+ "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "RUNTEST_ARGS": "",
+ "TEST_ENV": "i386-linux-deb12-validate"
+ }
+ },
"i386-linux-deb13-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
@@ -1400,6 +1462,69 @@
"XZ_OPT": "-9"
}
},
+ "nightly-i386-linux-deb12-validate": {
+ "after_script": [
+ ".gitlab/ci.sh save_cache",
+ ".gitlab/ci.sh save_test_output",
+ ".gitlab/ci.sh clean",
+ "cat ci_timings.txt"
+ ],
+ "allow_failure": false,
+ "artifacts": {
+ "expire_in": "8 weeks",
+ "paths": [
+ "ghc-i386-linux-deb12-validate.tar.xz",
+ "junit.xml",
+ "unexpected-test-output.tar.gz"
+ ],
+ "reports": {
+ "junit": "junit.xml"
+ },
+ "when": "always"
+ },
+ "cache": {
+ "key": "i386-linux-deb12-$CACHE_REV",
+ "paths": [
+ "cabal-cache",
+ "toolchain"
+ ]
+ },
+ "dependencies": [],
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/i386-linux-deb12:$DOCKER_REV",
+ "needs": [
+ {
+ "artifacts": false,
+ "job": "hadrian-ghc-in-ghci"
+ }
+ ],
+ "rules": [
+ {
+ "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)",
+ "when": "on_success"
+ }
+ ],
+ "script": [
+ "sudo chown ghc:ghc -R .",
+ ".gitlab/ci.sh setup",
+ ".gitlab/ci.sh configure",
+ ".gitlab/ci.sh build_hadrian",
+ ".gitlab/ci.sh test_hadrian"
+ ],
+ "stage": "full-build",
+ "tags": [
+ "x86_64-linux"
+ ],
+ "variables": {
+ "BIGNUM_BACKEND": "gmp",
+ "BIN_DIST_NAME": "ghc-i386-linux-deb12-validate",
+ "BUILD_FLAVOUR": "validate",
+ "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "RUNTEST_ARGS": "",
+ "TEST_ENV": "i386-linux-deb12-validate",
+ "XZ_OPT": "-9"
+ }
+ },
"nightly-i386-linux-deb13-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
@@ -4156,6 +4281,70 @@
"XZ_OPT": "-9"
}
},
+ "release-i386-linux-deb12-release+no_split_sections": {
+ "after_script": [
+ ".gitlab/ci.sh save_cache",
+ ".gitlab/ci.sh save_test_output",
+ ".gitlab/ci.sh clean",
+ "cat ci_timings.txt"
+ ],
+ "allow_failure": false,
+ "artifacts": {
+ "expire_in": "1 year",
+ "paths": [
+ "ghc-i386-linux-deb12-release+no_split_sections.tar.xz",
+ "junit.xml",
+ "unexpected-test-output.tar.gz"
+ ],
+ "reports": {
+ "junit": "junit.xml"
+ },
+ "when": "always"
+ },
+ "cache": {
+ "key": "i386-linux-deb12-$CACHE_REV",
+ "paths": [
+ "cabal-cache",
+ "toolchain"
+ ]
+ },
+ "dependencies": [],
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/i386-linux-deb12:$DOCKER_REV",
+ "needs": [
+ {
+ "artifacts": false,
+ "job": "hadrian-ghc-in-ghci"
+ }
+ ],
+ "rules": [
+ {
+ "if": "(\"true\" == \"true\") && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null)",
+ "when": "on_success"
+ }
+ ],
+ "script": [
+ "sudo chown ghc:ghc -R .",
+ ".gitlab/ci.sh setup",
+ ".gitlab/ci.sh configure",
+ ".gitlab/ci.sh build_hadrian",
+ ".gitlab/ci.sh test_hadrian"
+ ],
+ "stage": "full-build",
+ "tags": [
+ "x86_64-linux"
+ ],
+ "variables": {
+ "BIGNUM_BACKEND": "gmp",
+ "BIN_DIST_NAME": "ghc-i386-linux-deb12-release+no_split_sections",
+ "BUILD_FLAVOUR": "release+no_split_sections",
+ "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "IGNORE_PERF_FAILURES": "all",
+ "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "RUNTEST_ARGS": "",
+ "TEST_ENV": "i386-linux-deb12-release+no_split_sections",
+ "XZ_OPT": "-9"
+ }
+ },
"release-i386-linux-deb13-release+no_split_sections": {
"after_script": [
".gitlab/ci.sh save_cache",
=====================================
.gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
=====================================
@@ -244,7 +244,8 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map):
}
a32 = { "Linux_Debian": { "( >= 11 && < 12 )": deb11_i386
- , ">= 12": deb12_i386
+ , "( >= 12 && < 13 )": deb12_i386
+ , ">= 13": deb13_i386
, "unknown_versioning": deb11_i386 }
, "Linux_Ubuntu": { "unknown_versioning": deb11_i386 }
, "Linux_Mint" : { "unknown_versioning": deb11_i386 }
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5b6757d78e4e808678feb740ff5d4eb…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5b6757d78e4e808678feb740ff5d4eb…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
27 Mar '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
9831385b by Vladislav Zavialov at 2026-03-27T17:22:30-04:00
Infix holes in types (#11107)
This patch introduces several improvements that follow naturally from
refactoring HsOpTy to represent the operator as an HsType, aligning it
with the approach taken by OpApp and HsExpr.
User-facing changes:
1. Infix holes (t1 `_` t2) are now permitted in types, following the
precedent set by term-level expressions.
Test case: T11107
2. Error messages for illegal promotion ticks are now reported at more
precise source locations.
Test case: T17865
Internal changes:
* The definition of HsOpTy now mirrors that of OpApp:
| HsOpTy (XOpTy p) (LHsType p) (LHsType p) (LHsType p)
| OpApp (XOpApp p) (LHsExpr p) (LHsExpr p) (LHsExpr p)
This moves us one step closer to unifying HsType and HsExpr.
* Ignoring locations,
the old pattern match (HsOpTy x prom lhs op rhs)
is now written as (HsOpTy x lhs (HsTyVar x' prom op) rhs)
but we also handle (HsOpTy x lhs (HsWildCardTy x') rhs)
Constructors other than HsTyVar and HsWildCardTy never appear
in the operator position.
* The various definitions across the compiler have been updated to work
with the new representation, drawing inspiration from the term-level
pipeline where appropriate. For example,
ppr_infix_ty <=> ppr_infix_expr
get_tyop <=> get_op
lookupTypeFixityRn <=> lookupExprFixityRn
(the latter is factored out from rnExpr)
Test cases: T11107 T17865
- - - - -
30 changed files:
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Fixity.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/ThToHs.hs
- compiler/Language/Haskell/Syntax/Type.hs
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_fail/T17865.stderr
- + testsuite/tests/partial-sigs/should_compile/T11107.hs
- + testsuite/tests/partial-sigs/should_compile/T11107.stderr
- testsuite/tests/partial-sigs/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs
Changes:
=====================================
compiler/GHC/Hs/Type.hs
=====================================
@@ -683,11 +683,12 @@ ignoreParens ty = ty
mkAnonWildCardTy :: EpToken "_" -> HsType GhcPs
mkAnonWildCardTy tok = HsWildCardTy tok
-mkHsOpTy :: (Anno (IdOccGhcP p) ~ SrcSpanAnnN)
+mkHsOpTy :: (Anno (IdOccGhcP p) ~ EpAnn a)
=> PromotionFlag
- -> LHsType (GhcPass p) -> LocatedN (IdOccP (GhcPass p))
+ -> LHsType (GhcPass p) -> LIdOccP (GhcPass p)
-> LHsType (GhcPass p) -> HsType (GhcPass p)
-mkHsOpTy prom ty1 op ty2 = HsOpTy noExtField prom ty1 op ty2
+mkHsOpTy prom ty1 op ty2 = HsOpTy noExtField ty1 tyop ty2
+ where tyop = L (l2l op) $ HsTyVar noAnn prom op
mkHsAppTy :: LHsType (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p)
mkHsAppTy t1 t2 = addCLocA t1 t2 (HsAppTy noExtField t1 t2)
@@ -745,7 +746,7 @@ hsTyGetAppHead_maybe = go
go (L _ (HsTyVar _ _ ln)) = Just ln
go (L _ (HsAppTy _ l _)) = go l
go (L _ (HsAppKindTy _ t _)) = go t
- go (L _ (HsOpTy _ _ _ ln _)) = Just ln
+ go (L _ (HsOpTy _ _ op _)) = go op
go (L _ (HsParTy _ t)) = go t
go (L _ (HsKindSig _ t _)) = go t
go _ = Nothing
@@ -1457,9 +1458,14 @@ ppr_mono_ty (HsAppTy _ fun_ty arg_ty)
= hsep [ppr_mono_lty fun_ty, ppr_mono_lty arg_ty]
ppr_mono_ty (HsAppKindTy _ ty k)
= ppr_mono_lty ty <+> char '@' <> ppr_mono_lty k
-ppr_mono_ty (HsOpTy _ prom ty1 (L _ op) ty2)
- = sep [ ppr_mono_lty ty1
- , sep [pprOccWithTick Infix prom op, ppr_mono_lty ty2 ] ]
+ppr_mono_ty (HsOpTy _ ty1 tyop ty2)
+ | Just pp_op <- ppr_infix_ty tyop
+ = sep [pp_ty1, sep [pp_op, pp_ty2]]
+ | otherwise -- This shouldn't happen unless the user constructs weird ASTs via the GHC API
+ = hang (ppr tyop) 2 (sep [pp_ty1, pp_ty2])
+ where
+ pp_ty1 = ppr_mono_lty ty1
+ pp_ty2 = ppr_mono_lty ty2
ppr_mono_ty (HsParTy _ ty)
= parens (ppr_mono_lty ty)
-- Put the parens in where the user did
@@ -1476,6 +1482,11 @@ ppr_mono_ty (XHsType t) = case ghcPass @p of
HsRecTy _ flds -> pprHsConDeclRecFields flds
GhcRn -> ppr t
+ppr_infix_ty :: (OutputableBndrId p) => LHsType (GhcPass p) -> Maybe SDoc
+ppr_infix_ty (L _ (HsTyVar _ prom (L _ op))) = Just (pprOccWithTick Infix prom op)
+ppr_infix_ty (L _ (HsWildCardTy _)) = Just (text "`_`")
+ppr_infix_ty _ = Nothing
+
--------------------------
ppr_fun_ty :: (OutputableBndrId p)
=> HsMultAnn (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -> SDoc
=====================================
compiler/GHC/Hs/Utils.hs
=====================================
@@ -632,7 +632,7 @@ nlHsTyConApp :: forall p a. IsSrcSpanAnn p a
nlHsTyConApp prom fixity tycon tys
| Infix <- fixity
, HsValArg _ ty1 : HsValArg _ ty2 : rest <- tys
- = foldl' mk_app (noLocA $ HsOpTy noExtField prom ty1 (noLocA tycon) ty2) rest
+ = foldl' mk_app (noLocA $ mkHsOpTy prom ty1 (noLocA tycon) ty2) rest
| otherwise
= foldl' mk_app (nlHsTyVar prom $ forgetUserRdr @p tycon) tys
where
=====================================
compiler/GHC/HsToCore/Quote.hs
=====================================
@@ -1473,8 +1473,7 @@ repTy (HsTupleTy _ _ tys) = do tys1 <- repLTys tys
repTy (HsSumTy _ tys) = do tys1 <- repLTys tys
tcon <- repUnboxedSumTyCon (length tys)
repTapps tcon tys1
-repTy (HsOpTy _ prom ty1 n ty2) = repLTy ((nlHsTyVar prom (getName n) `nlHsAppTy` ty1)
- `nlHsAppTy` ty2)
+repTy (HsOpTy _ ty1 op ty2) = repLTy ((op `nlHsAppTy` ty1) `nlHsAppTy` ty2)
repTy (HsParTy _ t) = repLTy t
repTy (HsStarTy _) = repTStar
repTy (HsKindSig _ t k) = do
=====================================
compiler/GHC/Iface/Ext/Ast.hs
=====================================
@@ -1922,9 +1922,9 @@ instance ToHie (LocatedA (HsType GhcRn)) where
HsSumTy _ tys ->
[ toHie tys
]
- HsOpTy _ _prom a op b ->
+ HsOpTy _ a op b ->
[ toHie a
- , toHie $ C Use op
+ , toHie op
, toHie b
]
HsParTy _ a ->
=====================================
compiler/GHC/Parser.y
=====================================
@@ -2316,15 +2316,14 @@ infixtype :: { forall b. DisambTD b => PV (LocatedA b) }
: ftype %shift { $1 }
| ftype tyop infixtype { $1 >>= \ $1 ->
$3 >>= \ $3 ->
- do { let (op, prom) = $2
- ; when (looksLikeMult $1 op $3) $ hintLinear (getLocA op)
- ; mkHsOpTyPV prom $1 op $3 } }
+ do { when (looksLikeMult $1 $2 $3) $ hintLinear (getLocA $2)
+ ; mkHsOpTyPV $1 $2 $3 } }
| unpackedness infixtype { $2 >>= \ $2 ->
mkUnpackednessPV $1 $2 }
ftype :: { forall b. DisambTD b => PV (LocatedA b) }
: atype { mkHsAppTyHeadPV $1 }
- | tyop { failOpFewArgs (fst $1) }
+ | tyop { failOpFewArgs $1 }
| ftype tyarg { $1 >>= \ $1 ->
mkHsAppTyPV $1 $2 }
| ftype PREFIX_AT atype { $1 >>= \ $1 ->
@@ -2334,15 +2333,12 @@ tyarg :: { LHsType GhcPs }
: atype { $1 }
| unpackedness atype {% addUnpackednessP $1 $2 }
-tyop :: { (LocatedN RdrName, PromotionFlag) }
- : qtyconop { ($1, NotPromoted) }
- | tyvarop { ($1, NotPromoted) }
- | SIMPLEQUOTE qconop {% do { op <- amsr (sLL $1 $> (unLoc $2))
- (NameAnnQuote (epTok $1) (gl $2) [])
- ; return (op, IsPromoted) } }
- | SIMPLEQUOTE varop {% do { op <- amsr (sLL $1 $> (unLoc $2))
- (NameAnnQuote (epTok $1) (gl $2) [])
- ; return (op, IsPromoted) } }
+tyop :: { LHsType GhcPs }
+ : qtyconop { sL1a $1 (HsTyVar noAnn NotPromoted $1) }
+ | tyvarop { sL1a $1 (HsTyVar noAnn NotPromoted $1) }
+ | SIMPLEQUOTE qconop { sLLa $1 $> (HsTyVar (epTok $1) IsPromoted $2) }
+ | SIMPLEQUOTE varop { sLLa $1 $> (HsTyVar (epTok $1) IsPromoted $2) }
+ | '`' '_' '`' { sLLa $1 $> (mkAnonWildCardTy (epTok $2)) } -- TODO: reuse hole_op (blocked on #27111)
atype :: { LHsType GhcPs }
: ntgtycon {% amsA' (sL1 $1 (HsTyVar noAnn NotPromoted $1)) } -- Not including unit tuples
@@ -4475,12 +4471,12 @@ hintLinear span = do
unless linearEnabled $ addError $ mkPlainErrorMsgEnvelope span $ PsErrLinearFunction
-- Does this look like (a %m)?
-looksLikeMult :: LHsType GhcPs -> LocatedN RdrName -> LHsType GhcPs -> Bool
-looksLikeMult ty1 l_op ty2
- | Unqual op_name <- unLoc l_op
+looksLikeMult :: LHsType GhcPs -> LHsType GhcPs -> LHsType GhcPs -> Bool
+looksLikeMult ty1 tyop ty2
+ | HsTyVar _ _ (L _ (Unqual op_name)) <- unLoc tyop
, occNameFS op_name == fsLit "%"
, Strict.Just ty1_pos <- getBufSpan (getLocA ty1)
- , Strict.Just pct_pos <- getBufSpan (getLocA l_op)
+ , Strict.Just pct_pos <- getBufSpan (getLocA tyop)
, Strict.Just ty2_pos <- getBufSpan (getLocA ty2)
, bufSpanEnd ty1_pos /= bufSpanStart pct_pos
, bufSpanEnd pct_pos == bufSpanStart ty2_pos
=====================================
compiler/GHC/Parser/PostProcess.hs
=====================================
@@ -1140,8 +1140,8 @@ checkTyClHdr is_cls ty
go cs l (HsTyVar _ _ ltc@(L _ tc)) acc ops cps fix
| isRdrTc tc = return (ltc, acc, fix, (reverse ops), cps, cs Semi.<> comments l)
- go cs l (HsOpTy _ _ t1 ltc@(L _ tc) t2) acc ops cps _fix
- | isRdrTc tc = return (ltc, lhs:rhs:acc, Infix, (reverse ops), cps, cs Semi.<> comments l)
+ go cs l (HsOpTy _ t1 tyop t2) acc ops cps _fix
+ = goL (cs Semi.<> comments l) tyop (lhs:rhs:acc) ops cps Infix
where lhs = HsValArg noExtField t1
rhs = HsValArg noExtField t2
go cs l (HsParTy (o,c) ty) acc ops cps fix = goL (cs Semi.<> comments l) ty acc (o:ops) (c:cps) fix
@@ -2409,7 +2409,7 @@ class DisambTD b where
-- | Disambiguate @f \@t@ (visible kind application)
mkHsAppKindTyPV :: LocatedA b -> EpToken "@" -> LHsType GhcPs -> PV (LocatedA b)
-- | Disambiguate @f \# x@ (infix operator)
- mkHsOpTyPV :: PromotionFlag -> LHsType GhcPs -> LocatedN RdrName -> LHsType GhcPs -> PV (LocatedA b)
+ mkHsOpTyPV :: LHsType GhcPs -> LHsType GhcPs -> LHsType GhcPs -> PV (LocatedA b)
-- | Disambiguate @{-\# UNPACK \#-} t@ (unpack/nounpack pragma)
mkUnpackednessPV :: Located UnpackednessPragma -> LocatedA b -> PV (LocatedA b)
@@ -2417,8 +2417,8 @@ instance DisambTD (HsType GhcPs) where
mkHsAppTyHeadPV = return
mkHsAppTyPV t1 t2 = return (mkHsAppTy t1 t2)
mkHsAppKindTyPV t at ki = return (mkHsAppKindTy at t ki)
- mkHsOpTyPV prom t1 op t2 = do
- let (L l ty) = mkLHsOpTy prom t1 op t2
+ mkHsOpTyPV t1 tyop t2 = do
+ let (L l ty) = mkLHsOpTy t1 tyop t2
!cs <- getCommentsFor (locA l)
return (L (addCommentsToEpAnn l cs) ty)
mkUnpackednessPV = addUnpackednessP
@@ -2460,11 +2460,11 @@ instance DisambTD DataConBuilder where
addFatalError $ mkPlainErrorMsgEnvelope (getEpTokenSrcSpan at) $
(PsErrUnexpectedKindAppInDataCon (unLoc lhs) (unLoc ki))
- mkHsOpTyPV prom lhs tc rhs = do
+ mkHsOpTyPV lhs op@(L _ (HsTyVar _ prom tc)) rhs = do
check_no_ops (unLoc rhs) -- check the RHS because parsing type operators is right-associative
data_con <- eitherToP $ tyConToDataCon tc
!cs <- getCommentsFor (locA l)
- checkNotPromotedDataCon prom data_con
+ checkNotPromotedDataCon (getLocA op) prom data_con
return $ L (addCommentsToEpAnn l cs) (InfixDataConBuilder lhs data_con rhs)
where
l = combineLocsA lhs rhs
@@ -2473,6 +2473,9 @@ instance DisambTD DataConBuilder where
addError $ mkPlainErrorMsgEnvelope (locA l) $
(PsErrInvalidInfixDataCon (unLoc lhs) (unLoc tc) (unLoc rhs))
check_no_ops _ = return ()
+ mkHsOpTyPV _ (L l (HsWildCardTy _)) _ =
+ addFatalError $ mkPlainErrorMsgEnvelope (getHasLoc l) $ PsErrInvalidInfixHole
+ mkHsOpTyPV _ op _ = pprPanic "mkHsOpTyPV: impossible type operator" (ppr op)
mkUnpackednessPV unpk constr_stuff
| L _ (InfixDataConBuilder lhs data_con rhs) <- constr_stuff
@@ -2488,7 +2491,7 @@ instance DisambTD DataConBuilder where
tyToDataConBuilder :: LHsType GhcPs -> PV (LocatedA DataConBuilder)
tyToDataConBuilder (L l (HsTyVar _ prom v)) = do
data_con <- eitherToP $ tyConToDataCon v
- checkNotPromotedDataCon prom data_con
+ checkNotPromotedDataCon (locA l) prom data_con
return $ L l (PrefixDataConBuilder nilOL data_con)
tyToDataConBuilder (L l (HsTupleTy _ HsBoxedOrConstraintTuple ts)) = do
let data_con = L (l2l l) (getRdrName (tupleDataCon Boxed (length ts)))
@@ -2501,10 +2504,14 @@ tyToDataConBuilder t =
(PsErrInvalidDataCon (unLoc t))
-- | Rejects declarations such as @data T = 'MkT@ (note the leading tick).
-checkNotPromotedDataCon :: PromotionFlag -> LocatedN RdrName -> PV ()
-checkNotPromotedDataCon NotPromoted _ = return ()
-checkNotPromotedDataCon IsPromoted (L l name) =
- addError $ mkPlainErrorMsgEnvelope (locA l) $
+checkNotPromotedDataCon
+ :: SrcSpan -- ^ The enclosing SrcSpan containing the tick
+ -> PromotionFlag
+ -> LocatedN RdrName
+ -> PV ()
+checkNotPromotedDataCon _ NotPromoted _ = return ()
+checkNotPromotedDataCon loc IsPromoted (L _ name) =
+ addError $ mkPlainErrorMsgEnvelope loc $
PsErrIllegalPromotionQuoteDataCon name
mkUnboxedSumCon :: LHsType GhcPs -> ConTag -> Arity -> (LocatedN RdrName, HsConDeclH98Details GhcPs)
@@ -3460,12 +3467,15 @@ failSpliceOrQuoteTwice lvl =
warnStarIsType :: MonadP m => SrcSpan -> m ()
warnStarIsType span = addPsMessage span PsWarnStarIsType
-failOpFewArgs :: MonadP m => LocatedN RdrName -> m a
-failOpFewArgs (L loc op) =
+failOpFewArgs :: MonadP m => LHsType GhcPs -> m a
+failOpFewArgs (L _ (HsTyVar _ _ (L loc op))) =
do { star_is_type <- getBit StarIsTypeBit
; let is_star_type = if star_is_type then StarIsType else StarIsNotType
; addFatalError $ mkPlainErrorMsgEnvelope (locA loc) $
(PsErrOpFewArgs is_star_type op) }
+failOpFewArgs (L l (HsWildCardTy _)) =
+ addFatalError $ mkPlainErrorMsgEnvelope (getHasLoc l) $ PsErrInvalidInfixHole
+failOpFewArgs op = pprPanic "failOpFewArgs: impossible type operator" (ppr op)
requireExplicitNamespaces :: MonadP m => ExplicitNamespaceKeyword -> m ()
requireExplicitNamespaces kw = do
@@ -3701,10 +3711,10 @@ mkSumOrTuplePat l Boxed a@Sum{} _ =
addFatalError $
mkPlainErrorMsgEnvelope (locA l) $ PsErrUnsupportedBoxedSumPat a
-mkLHsOpTy :: PromotionFlag -> LHsType GhcPs -> LocatedN RdrName -> LHsType GhcPs -> LHsType GhcPs
-mkLHsOpTy prom x op y =
+mkLHsOpTy :: LHsType GhcPs -> LHsType GhcPs -> LHsType GhcPs -> LHsType GhcPs
+mkLHsOpTy x op y =
let loc = locA x `combineSrcSpans` locA op `combineSrcSpans` locA y
- in L (noAnnSrcSpan loc) (mkHsOpTy prom x op y)
+ in L (noAnnSrcSpan loc) (HsOpTy noExtField x op y)
mkMultExpr :: EpToken "%" -> LHsExpr GhcPs -> TokRarrow -> HsMultAnnOf (LHsExpr GhcPs) GhcPs
mkMultExpr pct t@(L _ (HsOverLit _ (OverLit _ (HsIntegral (IL (SourceText (unpackFS -> "1")) _ 1))))) arr
=====================================
compiler/GHC/Rename/Expr.hs
=====================================
@@ -50,7 +50,6 @@ import GHC.Unit.Module ( isInteractiveModule )
import GHC.Types.Basic (TypeOrKind (TypeLevel))
import GHC.Types.FieldLabel
-import GHC.Types.Fixity
import GHC.Types.Id.Make
import GHC.Types.Name
import GHC.Types.Name.Set
@@ -401,12 +400,7 @@ rnExpr (OpApp _ e1 op e2)
-- we used to avoid fixity stuff, but we can't easily tell any
-- more, so I've removed the test. Adding HsPars in GHC.Tc.Deriv.Generate
-- should prevent bad things happening.
- ; fixity <- case op' of
- L _ (HsVar _ (L _ (WithUserRdr _ n))) -> lookupFixityRn n
- L _ (XExpr (HsRecSelRn f)) -> lookupFieldFixityRn f
- _ -> return (Fixity minPrecedence InfixL)
- -- c.f. lookupFixity for unbound
-
+ ; fixity <- lookupExprFixityRn op'
; lexical_negation <- xoptM LangExt.LexicalNegation
; let negation_handling | lexical_negation = KeepNegationIntact
| otherwise = ReassociateNegation
=====================================
compiler/GHC/Rename/Fixity.hs
=====================================
@@ -11,7 +11,8 @@ module GHC.Rename.Fixity
, lookupFixityRn
, lookupFixityRn_help
, lookupFieldFixityRn
- , lookupTyFixityRn
+ , lookupExprFixityRn
+ , lookupTypeFixityRn
) where
import GHC.Prelude
@@ -26,6 +27,7 @@ import GHC.Unit.Module.ModIface
import GHC.Types.Fixity.Env
import GHC.Types.Name
import GHC.Types.Name.Env
+import GHC.Types.Name.Reader
import GHC.Types.Fixity
import GHC.Types.SrcLoc
@@ -198,8 +200,19 @@ lookupFixityRn_help name
doc = text "Checking fixity for" <+> ppr name
---------------
-lookupTyFixityRn :: LocatedN Name -> RnM Fixity
-lookupTyFixityRn = lookupFixityRn . unLoc
-
lookupFieldFixityRn :: FieldOcc GhcRn -> RnM Fixity
lookupFieldFixityRn (FieldOcc _ n) = lookupFixityRn (unLoc n)
+
+lookupExprFixityRn :: LHsExpr GhcRn -> RnM Fixity
+lookupExprFixityRn e =
+ case e of
+ L _ (HsVar _ op) -> lookupFixityRn (unLocWithUserRdr op)
+ L _ (XExpr (HsRecSelRn f)) -> lookupFieldFixityRn f
+ _ -> return (Fixity minPrecedence InfixL)
+ -- c.f. lookupFixity for unbound
+
+lookupTypeFixityRn :: LHsType GhcRn -> RnM Fixity
+lookupTypeFixityRn t =
+ case t of
+ L _ (HsTyVar _ _ op) -> lookupFixityRn (unLocWithUserRdr op)
+ _ -> return (Fixity minPrecedence InfixL)
=====================================
compiler/GHC/Rename/HsType.hs
=====================================
@@ -54,7 +54,7 @@ import GHC.Rename.Utils ( mapFvRn, bindLocalNamesFV
, typeAppErr, newLocalBndrRn, checkDupRdrNames
, checkShadowedRdrNames )
import GHC.Rename.Fixity ( lookupFieldFixityRn, lookupFixityRn
- , lookupTyFixityRn )
+ , lookupTypeFixityRn )
import GHC.Rename.Unbound ( notInScopeErr, WhereLooking(WL_LocalOnly) )
import GHC.Tc.Errors.Types
import GHC.Tc.Errors.Ppr ( pprHsDocContext )
@@ -67,7 +67,6 @@ import GHC.Types.Name
import GHC.Types.SrcLoc
import GHC.Types.Name.Set
import GHC.Types.FieldLabel
-import GHC.Types.Error
import GHC.Utils.Misc
import GHC.Types.Fixity ( compareFixity, negateFixity )
@@ -551,16 +550,13 @@ rnHsTyKi env tv@(HsTyVar _ ip (L loc rdr_name))
; checkPromotedDataConName env tv Prefix ip name
; return (HsTyVar noAnn ip loc_name_with_rdr, unitFV name) }
-rnHsTyKi env ty@(HsOpTy _ prom ty1 l_op ty2)
- = setSrcSpan (getLocA l_op) $
- do { let op_rdr = unLoc l_op
- ; (l_op', fvs1) <- rnHsTyOp env (ppr ty) l_op
- ; let op_name = unLoc l_op'
- ; fix <- lookupTyFixityRn l_op'
+rnHsTyKi env ty@(HsOpTy _ ty1 tyop ty2)
+ = setSrcSpan (getLocA tyop) $
+ do { (tyop', fvs1) <- rnHsTyOp env ty tyop
+ ; fix <- lookupTypeFixityRn tyop'
; (ty1', fvs2) <- rnLHsTyKi env ty1
; (ty2', fvs3) <- rnLHsTyKi env ty2
- ; res_ty <- mkHsOpTyRn prom (fmap (WithUserRdr op_rdr) l_op') fix ty1' ty2'
- ; checkPromotedDataConName env ty Infix prom op_name
+ ; res_ty <- mkHsOpTyRn tyop' fix ty1' ty2'
; return (res_ty, plusFVs [fvs1, fvs2, fvs3]) }
rnHsTyKi env (HsParTy _ ty)
@@ -770,15 +766,20 @@ rnLTyVar (L loc rdr_name)
; return (L loc tyvar) }
--------------
-rnHsTyOp :: RnTyKiEnv -> SDoc -> LocatedN RdrName
- -> RnM (LocatedN Name, FreeVars)
-rnHsTyOp env overall_ty (L loc op)
+rnHsTyOp :: RnTyKiEnv -> HsType GhcPs -> LHsType GhcPs
+ -> RnM (LHsType GhcRn, FreeVars)
+rnHsTyOp env overall_ty tyop
+ | L l (HsTyVar ann prom (L loc op)) <- tyop
= do { op' <- rnTyVar env op
; unlessXOptM LangExt.TypeOperators $
if (op' `hasKey` eqTyConKey) -- See [eqTyCon (~) compatibility fallback] in GHC.Rename.Env
then addDiagnostic TcRnTypeEqualityRequiresOperators
- else addErr $ TcRnIllegalTypeOperator overall_ty op
- ; return (L loc op', unitFV op') }
+ else addErr $ TcRnIllegalTypeOperator (ppr overall_ty) op
+ ; checkPromotedDataConName env overall_ty Infix prom op'
+ ; let tyop' = L l (HsTyVar ann prom (L loc (WithUserRdr op op')))
+ ; return (tyop', unitFV op') }
+ | otherwise
+ = rnLHsTyKi env tyop
--------------
checkWildCard :: RnTyKiEnv
@@ -1400,33 +1401,33 @@ precedence and does not require rearrangement.
---------------
-- Building (ty1 `op1` (ty2a `op2` ty2b))
-mkHsOpTyRn :: PromotionFlag
- -> LocatedN (WithUserRdr Name) -> Fixity -> LHsType GhcRn -> LHsType GhcRn
+mkHsOpTyRn :: LHsType GhcRn
+ -> Fixity -> LHsType GhcRn -> LHsType GhcRn
-> RnM (HsType GhcRn)
-mkHsOpTyRn prom1 op1 fix1 ty1 (L loc2 (HsOpTy _ prom2 ty2a op2 ty2b))
- = do { fix2 <- lookupTyFixityRn (fmap getName op2)
- ; mk_hs_op_ty prom1 op1 fix1 ty1 prom2 op2 fix2 ty2a ty2b loc2 }
+mkHsOpTyRn tyop1 fix1 ty1 (L loc2 (HsOpTy _ ty2a tyop2 ty2b))
+ = do { fix2 <- lookupTypeFixityRn tyop2
+ ; mk_hs_op_ty tyop1 fix1 ty1 tyop2 fix2 ty2a ty2b loc2 }
-mkHsOpTyRn prom1 op1 _ ty1 ty2 -- Default case, no rearrangement
- = return (HsOpTy noExtField prom1 ty1 op1 ty2)
+mkHsOpTyRn tyop _ ty1 ty2 -- Default case, no rearrangement
+ = return (HsOpTy noExtField ty1 tyop ty2)
---------------
-mk_hs_op_ty :: PromotionFlag -> LocatedN (WithUserRdr Name) -> Fixity -> LHsType GhcRn
- -> PromotionFlag -> LocatedN (WithUserRdr Name) -> Fixity -> LHsType GhcRn
+mk_hs_op_ty :: LHsType GhcRn -> Fixity -> LHsType GhcRn
+ -> LHsType GhcRn -> Fixity -> LHsType GhcRn
-> LHsType GhcRn -> SrcSpanAnnA
-> RnM (HsType GhcRn)
-mk_hs_op_ty prom1 op1 fix1 ty1 prom2 op2 fix2 ty2a ty2b loc2
- | nofix_error = do { precParseErr (NormalOp (unLoc op1),fix1)
- (NormalOp (unLoc op2),fix2)
+mk_hs_op_ty tyop1 fix1 ty1 tyop2 fix2 ty2a ty2b loc2
+ | nofix_error = do { precParseErr (get_tyop tyop1,fix1)
+ (get_tyop tyop2,fix2)
; return (ty1 `op1ty` (L loc2 (ty2a `op2ty` ty2b))) }
| associate_right = return (ty1 `op1ty` (L loc2 (ty2a `op2ty` ty2b)))
| otherwise = do { -- Rearrange to ((ty1 `op1` ty2a) `op2` ty2b)
- new_ty <- mkHsOpTyRn prom1 op1 fix1 ty1 ty2a
+ new_ty <- mkHsOpTyRn tyop1 fix1 ty1 ty2a
; return (noLocA new_ty `op2ty` ty2b) }
where
- lhs `op1ty` rhs = HsOpTy noExtField prom1 lhs op1 rhs
- lhs `op2ty` rhs = HsOpTy noExtField prom2 lhs op2 rhs
+ lhs `op1ty` rhs = HsOpTy noExtField lhs tyop1 rhs
+ lhs `op2ty` rhs = HsOpTy noExtField lhs tyop2 rhs
(nofix_error, associate_right) = compareFixity fix1 fix2
@@ -1493,6 +1494,11 @@ get_op (L _ (HsHole (HoleVar (L _ uv)))) = UnboundOp uv
get_op (L _ (XExpr (HsRecSelRn fld))) = RecFldOp fld
get_op other = pprPanic "get_op" (ppr other)
+get_tyop :: LHsType GhcRn -> OpName
+get_tyop (L _ (HsTyVar _ _ n)) = NormalOp (unLoc n)
+get_tyop (L _ (HsWildCardTy _)) = UnboundOp (Unqual (mkVarOcc "_"))
+get_tyop other = pprPanic "get_tyop" (ppr other)
+
-- Parser left-associates everything, but
-- derived instances may have correctly-associated things to
-- in the right operand. So we just check that the right operand is OK
@@ -2119,8 +2125,8 @@ extract_lty (L _ ty) acc
extract_hs_mult_ann m $ -- See Note [Ordering of implicit variables]
extract_lty ty2 acc
HsIParamTy _ _ ty -> extract_lty ty acc
- HsOpTy _ _ ty1 tv ty2 -> extract_lty ty1 $
- extract_tv tv $
+ HsOpTy _ ty1 op ty2 -> extract_lty ty1 $
+ extract_lty op $
extract_lty ty2 acc
HsParTy _ ty -> extract_lty ty acc
HsSpliceTy {} -> acc -- Type splices mention no tvs
=====================================
compiler/GHC/Rename/Pat.hs
=====================================
@@ -1314,6 +1314,16 @@ rn_ty_pat_var lrdr@(L l rdr) = do
name <- lookupTypeOccTPRnM rdr
pure (L l $ WithUserRdr rdr name)
+rn_tyop_pat :: LHsType GhcPs -> TPRnM (LHsType GhcRn)
+rn_tyop_pat tyop
+ | L l (HsTyVar ann prom l_op) <- tyop
+ = do l_op' <- rn_ty_pat_var l_op
+ let op_name = getName l_op'
+ when (isDataConName op_name && not (isPromoted prom)) $
+ liftRn $ addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Infix op_name)
+ return (L l $ HsTyVar ann prom l_op')
+ | otherwise = rn_lty_pat tyop
+
-- | Rename type patterns
--
-- For the difference between `rn_ty_pat` and `rnHsTyKi` see Note [CpsRn monad]
@@ -1373,15 +1383,13 @@ rn_ty_pat (HsSumTy an tys) = do
tys' <- mapM rn_lty_pat tys
pure (HsSumTy an tys')
-rn_ty_pat (HsOpTy _ prom ty1 l_op ty2) = do
+rn_ty_pat (HsOpTy _ ty1 tyop ty2) = do
ty1' <- rn_lty_pat ty1
- l_op' <- rn_ty_pat_var l_op
+ tyop' <- rn_tyop_pat tyop
ty2' <- rn_lty_pat ty2
- fix <- liftRn $ lookupTyFixityRn $ fmap getName l_op'
- let op_name = getName l_op'
- when (isDataConName op_name && not (isPromoted prom)) $
- liftRn $ addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Infix op_name)
- liftRn $ mkHsOpTyRn prom l_op' fix ty1' ty2'
+ liftRn $ do
+ fix <- lookupTypeFixityRn tyop'
+ mkHsOpTyRn tyop' fix ty1' ty2'
rn_ty_pat (HsParTy an ty) = do
ty' <- rn_lty_pat ty
=====================================
compiler/GHC/Tc/Gen/App.hs
=====================================
@@ -1136,15 +1136,11 @@ expr_to_type earg =
do { lhs' <- go lhs
; rhs' <- unwrap_wc rhs
; return (L l (HsAppKindTy noExtField lhs' rhs')) }
- go (L l e@(OpApp _ lhs op rhs)) =
+ go (L l (OpApp _ lhs op rhs)) =
do { lhs' <- go lhs
; op' <- go op
; rhs' <- go rhs
- ; op_id <- unwrap_op_tv op'
- ; return (L l (HsOpTy noExtField NotPromoted lhs' op_id rhs')) }
- where
- unwrap_op_tv (L _ (HsTyVar _ _ op_id)) = return op_id
- unwrap_op_tv _ = failWith $ TcRnIllformedTypeArgument (L l e)
+ ; return (L l (HsOpTy noExtField lhs' op' rhs')) }
go (L l (HsOverLit _ ol))
= do { let lit = tyLitFromOverloadedLit (ol_val ol)
; return (L l (HsTyLit noExtField lit)) }
=====================================
compiler/GHC/Tc/Gen/HsType.hs
=====================================
@@ -103,7 +103,7 @@ import GHC.Core.TyCo.Ppr
import GHC.Builtin.Types.Prim
import GHC.Types.Error
import GHC.Types.Name.Env
-import GHC.Types.Name.Reader( WithUserRdr(..), lookupLocalRdrOcc )
+import GHC.Types.Name.Reader
import GHC.Types.Var
import GHC.Types.Var.Set
import GHC.Core.TyCon
@@ -1146,8 +1146,9 @@ tcHsType _ (HsSpliceTy (HsUntypedSpliceNested n) s) _ = pprPanic "tcHsType: inva
tcHsType mode (HsFunTy _ mult ty1 ty2) exp_kind
= tc_fun_type mode mult ty1 ty2 exp_kind
-tcHsType mode (HsOpTy _ _ ty1 (L _ (WithUserRdr _ op)) ty2) exp_kind
- | op `hasKey` unrestrictedFunTyConKey
+tcHsType mode (HsOpTy _ ty1 tyop ty2) exp_kind
+ | L _ (HsTyVar _ _ op) <- tyop
+ , unLocWithUserRdr op `hasKey` unrestrictedFunTyConKey
= tc_fun_type mode (HsUnannotated noExtField) ty1 ty2 exp_kind
--------- Foralls
@@ -1531,12 +1532,15 @@ splitHsAppTys_maybe hs_ty
is_app :: HsType GhcRn -> Bool
is_app (HsAppKindTy {}) = True
is_app (HsAppTy {}) = True
- is_app (HsOpTy _ _ _ (L _ (WithUserRdr _ op)) _)
- = not (op `hasKey` unrestrictedFunTyConKey)
+ is_app (HsOpTy _ _ tyop _)
+ | L _ (HsTyVar _ _ op) <- tyop
+ , unLocWithUserRdr op `hasKey` unrestrictedFunTyConKey
-- I'm not sure why this funTyConKey test is necessary
-- Can it even happen? Perhaps for t1 `(->)` t2
-- but then maybe it's ok to treat that like a normal
-- application rather than using the special rule for HsFunTy
+ = False
+ is_app (HsOpTy {}) = True
is_app (HsTyVar {}) = True
is_app (HsParTy _ (L _ ty)) = is_app ty
is_app _ = False
@@ -1552,9 +1556,8 @@ splitHsAppTys hs_ty = go (noLocA hs_ty) []
go (L _ (HsAppTy _ f a)) as = go f (HsValArg noExtField a : as)
go (L _ (HsAppKindTy _ ty k)) as = go ty (HsTypeArg noExtField k : as)
go (L sp (HsParTy _ f)) as = go f (HsArgPar (locA sp) : as)
- go (L _ (HsOpTy _ prom l op@(L sp _) r)) as
- = ( L (l2l sp) (HsTyVar noAnn prom op)
- , HsValArg noExtField l : HsValArg noExtField r : as )
+ go (L _ (HsOpTy _ l tyop r)) as =
+ (tyop, HsValArg noExtField l : HsValArg noExtField r : as)
go f as = (f, as)
---------------------------
=====================================
compiler/GHC/Tc/Gen/Pat.hs
=====================================
@@ -549,7 +549,7 @@ pat_to_type (NPat _ (L _ ol) _ _)
pat_to_type (ConPat _ lname (InfixCon left right))
= do { lty <- pat_to_type (unLoc left)
; rty <- pat_to_type (unLoc right)
- ; let { t = noLocA (HsOpTy noExtField NotPromoted lty lname rty)}
+ ; let { t = noLocA (mkHsOpTy NotPromoted lty lname rty)}
; pure t }
pat_to_type (ConPat _ lname (PrefixCon args))
= do { let { appHead = noLocA (HsTyVar noAnn NotPromoted lname) }
=====================================
compiler/GHC/Tc/Gen/Sig.hs
=====================================
@@ -292,7 +292,7 @@ no_anon_wc_ty lty = go lty
HsListTy _ ty -> go ty
HsTupleTy _ _ tys -> gos tys
HsSumTy _ tys -> gos tys
- HsOpTy _ _ ty1 _ ty2 -> go ty1 && go ty2
+ HsOpTy _ ty1 tyop ty2 -> go tyop && go ty1 && go ty2
HsParTy _ ty -> go ty
HsIParamTy _ _ ty -> go ty
HsKindSig _ ty kind -> go ty && go kind
=====================================
compiler/GHC/ThToHs.hs
=====================================
@@ -1870,7 +1870,7 @@ cvtTypeKind typeOrKind ty
let px = parenthesizeHsType opPrec x'
py = parenthesizeHsType opPrec y'
in do { eq_tc <- returnLA eqTyCon_RDR
- ; returnLA (HsOpTy noExtField NotPromoted px eq_tc py) }
+ ; returnLA (mkHsOpTy NotPromoted px eq_tc py) }
-- The long-term goal is to remove the above case entirely and
-- subsume it under the case for InfixT. See #15815, comment:6,
-- for more details.
=====================================
compiler/Language/Haskell/Syntax/Type.hs
=====================================
@@ -806,13 +806,13 @@ data HsType pass
, hst_ctxt :: LHsContext pass -- Context C => blah
, hst_body :: LHsType pass }
+ -- | Type variable, type constructor, or (promoted) data constructor.
+ --
+ -- Includes named wildcards (such as @_foo@), but not bare wildcards @_@.
| HsTyVar (XTyVar pass)
- PromotionFlag -- Whether explicitly promoted,
- -- for the pretty printer
- (LIdOccP pass)
- -- Type variable, type constructor, or data constructor
- -- see Note [Promotions (HsTyVar)]
- -- See Note [Located RdrNames] in GHC.Hs.Expr
+ PromotionFlag -- ^ Whether explicitly promoted, for the pretty printer.
+ -- See Note [Promotions (HsTyVar)]
+ (LIdOccP pass) -- ^ See Note [Located RdrNames] in GHC.Hs.Expr
| HsAppTy (XAppTy pass)
(LHsType pass)
@@ -838,9 +838,9 @@ data HsType pass
[LHsType pass] -- Element types (length gives arity)
| HsOpTy (XOpTy pass)
- PromotionFlag -- Whether explicitly promoted,
- -- for the pretty printer
- (LHsType pass) (LIdOccP pass) (LHsType pass)
+ (LHsType pass) -- ^ First argument
+ (LHsType pass) -- ^ Operator (always a @HsTyVar@ or a @HsWildCardTy@)
+ (LHsType pass) -- ^ Second argument
| HsParTy (XParTy pass)
(LHsType pass) -- See Note [Parens in HsSyn] in GHC.Hs.Expr
=====================================
testsuite/tests/parser/should_compile/DumpParsedAst.stderr
=====================================
@@ -388,7 +388,6 @@
[]))
(HsOpTy
(NoExtField)
- (NotPromoted)
(L
(EpAnn
(EpaSpan { DumpParsedAst.hs:11:11 })
@@ -411,12 +410,22 @@
(L
(EpAnn
(EpaSpan { DumpParsedAst.hs:11:13 })
- (NameAnnTrailing
+ (AnnListItem
[])
(EpaComments
[]))
- (Exact
- {Name: :}))
+ (HsTyVar
+ (NoEpTok)
+ (NotPromoted)
+ (L
+ (EpAnn
+ (EpaSpan { DumpParsedAst.hs:11:13 })
+ (NameAnnTrailing
+ [])
+ (EpaComments
+ []))
+ (Exact
+ {Name: :}))))
(L
(EpAnn
(EpaSpan { DumpParsedAst.hs:11:15-16 })
=====================================
testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
=====================================
@@ -335,7 +335,6 @@
[]))
(HsOpTy
(NoExtField)
- (NotPromoted)
(L
(EpAnn
(EpaSpan { DumpRenamedAst.hs:13:11 })
@@ -360,14 +359,24 @@
(L
(EpAnn
(EpaSpan { DumpRenamedAst.hs:13:13 })
- (NameAnnTrailing
+ (AnnListItem
[])
(EpaComments
[]))
- (WithUserRdr
- (Exact
- {Name: :})
- {Name: :}))
+ (HsTyVar
+ (NoEpTok)
+ (NotPromoted)
+ (L
+ (EpAnn
+ (EpaSpan { DumpRenamedAst.hs:13:13 })
+ (NameAnnTrailing
+ [])
+ (EpaComments
+ []))
+ (WithUserRdr
+ (Exact
+ {Name: :})
+ {Name: :}))))
(L
(EpAnn
(EpaSpan { DumpRenamedAst.hs:13:15-16 })
=====================================
testsuite/tests/parser/should_fail/T17865.stderr
=====================================
@@ -1,9 +1,8 @@
-
-T17865.hs:3:11: error: [GHC-80236]
+T17865.hs:3:10: error: [GHC-80236]
Illegal promotion quote mark in the declaration of
data/newtype constructor MkT
-T17865.hs:5:13: error: [GHC-80236]
+T17865.hs:5:11: error: [GHC-80236]
Illegal promotion quote mark in the declaration of
data/newtype constructor MkT'
@@ -14,3 +13,4 @@ T17865.hs:7:16: error: [GHC-80236]
T17865.hs:9:17: error: [GHC-80236]
Illegal promotion quote mark in the declaration of
data/newtype constructor (:>$)
+
=====================================
testsuite/tests/partial-sigs/should_compile/T11107.hs
=====================================
@@ -0,0 +1,5 @@
+{-# LANGUAGE PartialTypeSignatures #-}
+module T11107 where
+
+e :: Int `_` Bool
+e = Left 0
\ No newline at end of file
=====================================
testsuite/tests/partial-sigs/should_compile/T11107.stderr
=====================================
@@ -0,0 +1,4 @@
+T11107.hs:4:10: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
+ • Found type wildcard ‘_’ standing for ‘Either :: * -> * -> *’
+ • In the type signature: e :: Int `_` Bool
+
=====================================
testsuite/tests/partial-sigs/should_compile/all.T
=====================================
@@ -109,3 +109,4 @@ test('T22065', normal, compile, [''])
test('T16152', normal, compile, [''])
test('T20076', expect_broken(20076), compile, [''])
test('T26256', normal, compile, [''])
+test('T11107', normal, compile, [''])
=====================================
utils/check-exact/ExactPrint.hs
=====================================
@@ -3969,11 +3969,11 @@ instance ExactPrint (HsType GhcPs) where
tys' <- markAnnotated tys
an1 <- markClosingParen an0
return (HsSumTy an1 tys')
- exact (HsOpTy x promoted t1 lo t2) = do
+ exact (HsOpTy x t1 lo t2) = do
t1' <- markAnnotated t1
lo' <- markAnnotated lo
t2' <- markAnnotated t2
- return (HsOpTy x promoted t1' lo' t2')
+ return (HsOpTy x t1' lo' t2')
exact (HsParTy (o,c) ty) = do
o' <- markEpToken o
ty' <- markAnnotated ty
=====================================
utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs
=====================================
@@ -102,7 +102,7 @@ dropHsDocTy = drop_sig_ty
drop_ty (HsFunTy x w a b) = HsFunTy x w (drop_lty a) (drop_lty b)
drop_ty (HsListTy x a) = HsListTy x (drop_lty a)
drop_ty (HsTupleTy x a b) = HsTupleTy x a (map drop_lty b)
- drop_ty (HsOpTy x p a b c) = HsOpTy x p (drop_lty a) b (drop_lty c)
+ drop_ty (HsOpTy x a b c) = HsOpTy x (drop_lty a) (drop_lty b) (drop_lty c)
drop_ty (HsParTy x a) = HsParTy x (drop_lty a)
drop_ty (HsKindSig x a b) = HsKindSig x (drop_lty a) b
drop_ty (HsDocTy _ a _) = drop_ty $ unL a
=====================================
utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
=====================================
@@ -1345,17 +1345,15 @@ ppr_mono_ty (HsAppTy _ fun_ty arg_ty) unicode =
hsep [ppr_mono_lty fun_ty unicode, ppr_mono_lty arg_ty unicode]
ppr_mono_ty (HsAppKindTy _ fun_ty arg_ki) unicode =
hsep [ppr_mono_lty fun_ty unicode, atSign <> ppr_mono_lty arg_ki unicode]
-ppr_mono_ty (HsOpTy _ prom ty1 op ty2) unicode =
- ppr_mono_lty ty1 unicode <+> ppr_op_prom <+> ppr_mono_lty ty2 unicode
+ppr_mono_ty (HsOpTy _ ty1 tyop ty2) unicode
+ | Just pp_op <- ppr_infix_ty tyop
+ = pp_ty1 <+> pp_op <+> pp_ty2
+ | otherwise -- This shouldn't happen unless the user constructs weird ASTs via the GHC API
+ = let pp_op = ppr_mono_lty tyop unicode
+ in hsep [hsep [pp_op, pp_ty1], pp_ty2]
where
- ppr_op_prom
- | isPromoted prom =
- char '\'' <> ppr_op
- | otherwise =
- ppr_op
- ppr_op
- | isSymOcc (getOccName op) = ppLDocName op
- | otherwise = char '`' <> ppLDocName op <> char '`'
+ pp_ty1 = ppr_mono_lty ty1 unicode
+ pp_ty2 = ppr_mono_lty ty2 unicode
ppr_mono_ty (HsParTy _ ty) unicode =
parens (ppr_mono_lty ty unicode)
-- = ppr_mono_lty ty unicode
@@ -1367,6 +1365,18 @@ ppr_mono_ty (HsTyLit _ t) u = ppr_tylit t u
ppr_mono_ty (HsStarTy _) unicode = starSymbol unicode
ppr_mono_ty (XHsType HsRedacted{}) _ = error "ppr_mono_ty: HsRedacted can't be used here"
+ppr_infix_ty :: LHsType DocNameI -> Maybe LaTeX
+ppr_infix_ty (L _ (HsTyVar _ prom op)) = Just pp_op_prom
+ where
+ pp_op_prom
+ | isPromoted prom = char '\'' <> pp_op
+ | otherwise = pp_op
+ pp_op
+ | isSymOcc (getOccName op) = ppLDocName op
+ | otherwise = char '`' <> ppLDocName op <> char '`'
+ppr_infix_ty (L _ (HsWildCardTy _)) = Just (text "`_`")
+ppr_infix_ty _ = Nothing
+
ppr_tylit :: HsLit DocNameI -> Bool -> LaTeX
ppr_tylit (HsNatural _ n) _ = integer (il_value n)
ppr_tylit (HsString _ s) _ = text (show s)
=====================================
utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
=====================================
@@ -1863,15 +1863,15 @@ ppr_mono_ty (HsAppKindTy _ fun_ty arg_ki) unicode qual _ =
[ ppr_mono_lty fun_ty unicode qual HideEmptyContexts
, atSign <> ppr_mono_lty arg_ki unicode qual HideEmptyContexts
]
-ppr_mono_ty (HsOpTy _ prom ty1 op ty2) unicode qual _ =
- ppr_mono_lty ty1 unicode qual HideEmptyContexts <+> ppr_op_prom <+> ppr_mono_lty ty2 unicode qual HideEmptyContexts
+ppr_mono_ty (HsOpTy _ ty1 tyop ty2) unicode qual _
+ | Just pp_op <- ppr_infix_ty tyop qual
+ = pp_ty1 <+> pp_op <+> pp_ty2
+ | otherwise -- This shouldn't happen unless the user constructs weird ASTs via the GHC API
+ = let pp_op = ppr_mono_lty tyop unicode qual HideEmptyContexts
+ in hsep [hsep [pp_op, pp_ty1], pp_ty2]
where
- ppr_op_prom
- | isPromoted prom =
- promoQuote ppr_op
- | otherwise =
- ppr_op
- ppr_op = ppLDocName qual Infix op
+ pp_ty1 = ppr_mono_lty ty1 unicode qual HideEmptyContexts
+ pp_ty2 = ppr_mono_lty ty2 unicode qual HideEmptyContexts
ppr_mono_ty (HsParTy _ ty) unicode qual emptyCtxts =
parens (ppr_mono_lty ty unicode qual emptyCtxts)
-- = parens (ppr_mono_lty ctxt_prec ty unicode qual emptyCtxts)
@@ -1882,6 +1882,16 @@ ppr_mono_ty (HsWildCardTy _) _ _ _ = char '_'
ppr_mono_ty (HsTyLit _ n) _ _ _ = ppr_tylit n
ppr_mono_ty (XHsType HsRedacted{}) _ _ _ = error "ppr_mono_ty: HsRedacted can't be used here"
+ppr_infix_ty :: LHsType DocNameI -> Qualification -> Maybe Html
+ppr_infix_ty (L _ (HsTyVar _ prom op)) qual = Just pp_op_prom
+ where
+ pp_op_prom
+ | isPromoted prom = promoQuote pp_op
+ | otherwise = pp_op
+ pp_op = ppLDocName qual Infix op
+ppr_infix_ty (L _ (HsWildCardTy _)) _ = Just (toHtml ("`_`" :: LText))
+ppr_infix_ty _ _ = Nothing
+
ppr_tylit :: HsLit DocNameI -> Html
ppr_tylit (HsNatural _ n) = toHtml (show (il_value n))
ppr_tylit (HsString _ s) = toHtml (show s)
=====================================
utils/haddock/haddock-api/src/Haddock/Convert.hs
=====================================
@@ -842,7 +842,8 @@ synifyType _ boundTvs (TyConApp tc tys) =
| L _ (HsExplicitListTy _ IsPromoted tTy') <- stripKindSig tTy ->
noLocA $ HsExplicitListTy noExtField IsPromoted (hTy : tTy')
| otherwise ->
- noLocA $ HsOpTy noExtField IsPromoted hTy (noLocA $ noUserRdr $ getName tc) tTy
+ let tyop = noLocA $ HsTyVar noAnn IsPromoted (noLocA $ noUserRdr $ getName tc)
+ in noLocA $ HsOpTy noExtField hTy tyop tTy
-- ditto for implicit parameter tycons
| tc `hasKey` ipClassKey
, [name, ty] <- tys
@@ -854,9 +855,8 @@ synifyType _ boundTvs (TyConApp tc tys) =
noLocA $
HsOpTy
noExtField
- NotPromoted
(synifyType WithinType boundTvs ty1)
- (noLocA $ noUserRdr eqTyConName)
+ (noLocA $ HsTyVar noAnn NotPromoted (noLocA $ noUserRdr eqTyConName))
(synifyType WithinType boundTvs ty2)
-- and infix type operators
| isSymOcc (nameOccName (getName tc))
@@ -864,9 +864,8 @@ synifyType _ boundTvs (TyConApp tc tys) =
mk_app_tys
( HsOpTy
noExtField
- prom
(synifyType WithinType boundTvs ty1)
- (noLocA $ noUserRdr $ getName tc)
+ (noLocA $ HsTyVar noAnn prom (noLocA $ noUserRdr $ getName tc))
(synifyType WithinType boundTvs ty2)
)
tys_rest
=====================================
utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
=====================================
@@ -465,8 +465,8 @@ reparenTypePrec = go
paren p PREC_CON $ HsAppTy x (goL PREC_FUN fun_ty) (goL PREC_CON arg_ty)
go p (HsAppKindTy x fun_ty arg_ki) =
paren p PREC_CON $ HsAppKindTy x (goL PREC_FUN fun_ty) (goL PREC_CON arg_ki)
- go p (HsOpTy x prom ty1 op ty2) =
- paren p PREC_FUN $ HsOpTy x prom (goL PREC_OP ty1) op (goL PREC_OP ty2)
+ go p (HsOpTy x ty1 op ty2) =
+ paren p PREC_FUN $ HsOpTy x (goL PREC_OP ty1) op (goL PREC_OP ty2)
go p (HsParTy _ t) = unXRec @a $ goL p t -- pretend the paren doesn't exist - it will be added back if needed
go _ t@HsTyVar{} = t
go _ t@HsStarTy{} = t
=====================================
utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
=====================================
@@ -399,11 +399,11 @@ renameType t = case t of
return (HsAppTy noAnn lhs rhs)
HsTupleTy _ b ts -> return . HsTupleTy noAnn b =<< mapM renameLType ts
HsSumTy _ ts -> HsSumTy noAnn <$> mapM renameLType ts
- HsOpTy _ prom a (L loc op) b -> do
- op' <- renameName (getName op)
+ HsOpTy _ a op b -> do
+ op' <- renameLType op
a' <- renameLType a
b' <- renameLType b
- return (HsOpTy noAnn prom a' (L loc op') b')
+ return (HsOpTy noAnn a' op' b')
HsParTy _ ty -> return . (HsParTy noAnn) =<< renameLType ty
HsKindSig _ ty k -> do
ty' <- renameLType ty
=====================================
utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs
=====================================
@@ -104,8 +104,8 @@ renameType (HsFunTy x w la lr) = HsFunTy x <$> renameHsMultAnn w <*> renameLType
renameType (HsListTy x lt) = HsListTy x <$> renameLType lt
renameType (HsTupleTy x srt lt) = HsTupleTy x srt <$> mapM renameLType lt
renameType (HsSumTy x lt) = HsSumTy x <$> mapM renameLType lt
-renameType (HsOpTy x f la lop lb) =
- HsOpTy x <$> pure f <*> renameLType la <*> renameLNameOcc lop <*> renameLType lb
+renameType (HsOpTy x la lop lb) =
+ HsOpTy x <$> renameLType la <*> renameLType lop <*> renameLType lb
renameType (HsParTy x lt) = HsParTy x <$> renameLType lt
renameType (HsIParamTy x ip lt) = HsIParamTy x ip <$> renameLType lt
renameType (HsKindSig x lt lk) = HsKindSig x <$> renameLType lt <*> pure lk
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9831385bbdcbf43665b62212233e811…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9831385bbdcbf43665b62212233e811…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/elem-tests] Add a test for `elem` fusion
by Simon Jakobi (@sjakobi2) 27 Mar '26
by Simon Jakobi (@sjakobi2) 27 Mar '26
27 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/elem-tests at Glasgow Haskell Compiler / GHC
Commits:
8789f4a7 by Simon Jakobi at 2026-03-27T20:55:11+01:00
Add a test for `elem` fusion
- - - - -
7 changed files:
- + libraries/base/tests/perf/ElemFusionUnknownList.hs
- + libraries/base/tests/perf/ElemFusionUnknownList_O1.stderr
- + libraries/base/tests/perf/ElemFusionUnknownList_O2.stderr
- + libraries/base/tests/perf/ElemNoFusion.hs
- + libraries/base/tests/perf/ElemNoFusion_O1.stderr
- + libraries/base/tests/perf/ElemNoFusion_O2.stderr
- libraries/base/tests/perf/all.T
Changes:
=====================================
libraries/base/tests/perf/ElemFusionUnknownList.hs
=====================================
@@ -0,0 +1,14 @@
+module ElemFusionUnknownList where
+
+-- These should fuse with producers over unknown list inputs at -O1 and -O2.
+fusionElemMap :: Int -> [Int] -> Bool
+fusionElemMap x = elem x . map (+1)
+
+fusionNotElemMap :: Int -> [Int] -> Bool
+fusionNotElemMap x = notElem x . map (+1)
+
+fusionElemConcatMap :: Int -> [Int] -> Bool
+fusionElemConcatMap x = elem x . concatMap (\y -> [y + 1, y + 2])
+
+fusionNotElemConcatMap :: Int -> [Int] -> Bool
+fusionNotElemConcatMap x = notElem x . concatMap (\y -> [y + 1, y + 2])
=====================================
libraries/base/tests/perf/ElemFusionUnknownList_O1.stderr
=====================================
@@ -0,0 +1,80 @@
+fusionNotElemConcatMap
+ = \ x x1 ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> True;
+ : y ys ->
+ case y of { I# x2 ->
+ case x of { I# x3 ->
+ case ==# x3 (+# x2 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x2 2#) of {
+ __DEFAULT -> jump go1 ys;
+ 1# -> False
+ };
+ 1# -> False
+ }
+ }
+ }
+ }; } in
+ jump go1 x1
+
+fusionElemConcatMap
+ = \ x x1 ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> False;
+ : y ys ->
+ case y of { I# x2 ->
+ case x of { I# x3 ->
+ case ==# x3 (+# x2 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x2 2#) of {
+ __DEFAULT -> jump go1 ys;
+ 1# -> True
+ };
+ 1# -> True
+ }
+ }
+ }
+ }; } in
+ jump go1 x1
+
+fusionNotElemMap
+ = \ x eta ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> True;
+ : y ys ->
+ case x of { I# x1 ->
+ case y of { I# x2 ->
+ case ==# x1 (+# x2 1#) of {
+ __DEFAULT -> jump go1 ys;
+ 1# -> False
+ }
+ }
+ }
+ }; } in
+ jump go1 eta
+
+fusionElemMap
+ = \ x eta ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> False;
+ : y ys ->
+ case x of { I# x1 ->
+ case y of { I# x2 ->
+ case ==# x1 (+# x2 1#) of {
+ __DEFAULT -> jump go1 ys;
+ 1# -> True
+ }
+ }
+ }
+ }; } in
+ jump go1 eta
+
=====================================
libraries/base/tests/perf/ElemFusionUnknownList_O2.stderr
=====================================
@@ -0,0 +1,128 @@
+fusionNotElemConcatMap
+ = \ x x1 ->
+ case x1 of {
+ [] -> True;
+ : y ys ->
+ case y of { I# x2 ->
+ case x of { I# x3 ->
+ case ==# x3 (+# x2 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x2 2#) of {
+ __DEFAULT ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> True;
+ : y1 ys1 ->
+ case y1 of { I# x4 ->
+ case ==# x3 (+# x4 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x4 2#) of {
+ __DEFAULT -> jump go1 ys1;
+ 1# -> False
+ };
+ 1# -> False
+ }
+ }
+ }; } in
+ jump go1 ys;
+ 1# -> False
+ };
+ 1# -> False
+ }
+ }
+ }
+ }
+
+fusionElemConcatMap
+ = \ x x1 ->
+ case x1 of {
+ [] -> False;
+ : y ys ->
+ case y of { I# x2 ->
+ case x of { I# x3 ->
+ case ==# x3 (+# x2 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x2 2#) of {
+ __DEFAULT ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> False;
+ : y1 ys1 ->
+ case y1 of { I# x4 ->
+ case ==# x3 (+# x4 1#) of {
+ __DEFAULT ->
+ case ==# x3 (+# x4 2#) of {
+ __DEFAULT -> jump go1 ys1;
+ 1# -> True
+ };
+ 1# -> True
+ }
+ }
+ }; } in
+ jump go1 ys;
+ 1# -> True
+ };
+ 1# -> True
+ }
+ }
+ }
+ }
+
+fusionNotElemMap
+ = \ x eta ->
+ case eta of {
+ [] -> True;
+ : y ys ->
+ case x of { I# x1 ->
+ case y of { I# x2 ->
+ case ==# x1 (+# x2 1#) of {
+ __DEFAULT ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> True;
+ : y1 ys1 ->
+ case y1 of { I# x3 ->
+ case ==# x1 (+# x3 1#) of {
+ __DEFAULT -> jump go1 ys1;
+ 1# -> False
+ }
+ }
+ }; } in
+ jump go1 ys;
+ 1# -> False
+ }
+ }
+ }
+ }
+
+fusionElemMap
+ = \ x eta ->
+ case eta of {
+ [] -> False;
+ : y ys ->
+ case x of { I# x1 ->
+ case y of { I# x2 ->
+ case ==# x1 (+# x2 1#) of {
+ __DEFAULT ->
+ joinrec {
+ go1 ds
+ = case ds of {
+ [] -> False;
+ : y1 ys1 ->
+ case y1 of { I# x3 ->
+ case ==# x1 (+# x3 1#) of {
+ __DEFAULT -> jump go1 ys1;
+ 1# -> True
+ }
+ }
+ }; } in
+ jump go1 ys;
+ 1# -> True
+ }
+ }
+ }
+ }
+
=====================================
libraries/base/tests/perf/ElemNoFusion.hs
=====================================
@@ -0,0 +1,12 @@
+module ElemNoFusion where
+
+import Data.List (sort)
+import Data.List.NonEmpty (NonEmpty)
+import qualified Data.List.NonEmpty as NonEmpty
+
+-- These should not fuse with elem, even at -O1 and -O2.
+noFusionElemNonEmptyToList :: Int -> NonEmpty Int -> Bool
+noFusionElemNonEmptyToList x = elem x . NonEmpty.toList
+
+noFusionElemSort :: Int -> [Int] -> Bool
+noFusionElemSort x = elem x . sort
=====================================
libraries/base/tests/perf/ElemNoFusion_O1.stderr
=====================================
@@ -0,0 +1,5 @@
+noFusionElemSort = \ x x1 -> elem $fEqInt x (actualSort gtInt x1)
+
+noFusionElemNonEmptyToList
+ = \ x x1 -> case x1 of { :| a1 as -> elem $fEqInt x (: a1 as) }
+
=====================================
libraries/base/tests/perf/ElemNoFusion_O2.stderr
=====================================
@@ -0,0 +1,5 @@
+noFusionElemSort = \ x x1 -> elem $fEqInt x (actualSort gtInt x1)
+
+noFusionElemNonEmptyToList
+ = \ x x1 -> case x1 of { :| a1 as -> elem $fEqInt x (: a1 as) }
+
=====================================
libraries/base/tests/perf/all.T
=====================================
@@ -26,6 +26,34 @@ test('T17752_O2',
'-O2 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
"sed -n '/^is[A-Za-z]*$/,/^$/p'"])
+test('ElemFusionUnknownList_O1',
+ [only_ways(['normal']), extra_files(['ElemFusionUnknownList.hs'])],
+ multimod_compile_filter,
+ ['ElemFusionUnknownList',
+ '-O1 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
+ "sed -n '/^fusion[A-Za-z]*$/,/^$/p'"])
+
+test('ElemFusionUnknownList_O2',
+ [only_ways(['normal']), extra_files(['ElemFusionUnknownList.hs'])],
+ multimod_compile_filter,
+ ['ElemFusionUnknownList',
+ '-O2 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
+ "sed -n '/^fusion[A-Za-z]*$/,/^$/p'"])
+
+test('ElemNoFusion_O1',
+ [only_ways(['normal']), extra_files(['ElemNoFusion.hs'])],
+ multimod_compile_filter,
+ ['ElemNoFusion',
+ '-O1 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
+ "sed -n '/^noFusion[A-Za-z]*/,/^$/p'"])
+
+test('ElemNoFusion_O2',
+ [only_ways(['normal']), extra_files(['ElemNoFusion.hs'])],
+ multimod_compile_filter,
+ ['ElemNoFusion',
+ '-O2 -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
+ "sed -n '/^noFusion[A-Za-z]*/,/^$/p'"])
+
#--------------------------------------
# We don't expect the code in test to vary at all, but the variance is set to
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8789f4a7c3242c2ec8434cc7cf3da3e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8789f4a7c3242c2ec8434cc7cf3da3e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/text-read-implementation-into-base] 31 commits: Check that shift values are valid
by Wolfgang Jeltsch (@jeltsch) 27 Mar '26
by Wolfgang Jeltsch (@jeltsch) 27 Mar '26
27 Mar '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/text-read-implementation-into-base at Glasgow Haskell Compiler / GHC
Commits:
aa5dfe67 by Sylvain Henry at 2026-03-26T03:48:56-04:00
Check that shift values are valid
In GHC's codebase in non-DEBUG builds we silently substitute shiftL/R
with unsafeShiftL/R for performance reasons. However we were not
checking that the shift value was valid for unsafeShiftL/R, leading to
wrong computations, but only in non-DEBUG builds.
This patch adds the necessary checks and reports an error when a wrong
shift value is passed.
- - - - -
c8a7b588 by Sylvain Henry at 2026-03-26T03:48:56-04:00
Implement basic value range analysis (#25718)
Perform basic value range analysis to try to determine at compile time
the result of the application of some comparison primops (ltWord#, etc.).
This subsumes the built-in rewrite rules used previously to check if one
of the comparison argument was a bound (e.g. (x :: Word8) <= 255 is
always True). Our analysis is more powerful and handles type
conversions: e.g. word8ToWord x <= 255 is now detected as always True too.
We also use value range analysis to filter unreachable alternatives in
case-expressions. To support this, we had to allow case-expressions for
primitive types to not have a DEFAULT alternative (as was assumed before
and checked in Core lint).
- - - - -
a5ec467e by ARATA Mizuki at 2026-03-26T03:49:49-04:00
rts: Align stack to 64-byte boundary in StgRun on x86
When LLVM spills AVX/AVX-512 vector registers to the stack, it requires
32-byte (__m256) or 64-byte (__m512) alignment. If the stack is not
sufficiently aligned, LLVM inserts a realignment prologue that reserves
%rbp as a frame pointer, conflicting with GHC's use of %rbp as an STG
callee-saved register and breaking the tail-call-based calling convention.
Previously, GHC worked around this by lying to LLVM about the stack
alignment and rewriting aligned vector loads/stores (VMOVDQA, VMOVAPS)
to unaligned ones (VMOVDQU, VMOVUPS) in the LLVM Mangler. This had two
problems:
- It did not extend to AVX-512, which requires 64-byte alignment. (#26595)
- When Haskell calls a C function that takes __m256/__m512 arguments on
the stack, the callee requires genuine alignment, which could cause a
segfault. (#26822)
This patch genuinely aligns the stack to 64 bytes in StgRun by saving
the original stack pointer before alignment and restoring it in
StgReturn. We now unconditionally advertise 64-byte stack alignment to
LLVM for all x86 targets, making rewriteAVX in the LLVM Mangler
unnecessary. STG_RUN_STACK_FRAME_SIZE is increased from 48 to 56 bytes
on non-Windows x86-64 to store the saved stack pointer.
Closes #26595 and #26822
Co-Authored-By: Claude Opus 4.5 <noreply(a)anthropic.com>
- - - - -
661da815 by Teo Camarasu at 2026-03-26T03:50:33-04:00
ghc-internal: Float Generics to near top of module graph
We remove GHC.Internal.Generics from the critical path of the
`ghc-internal` module graph. GHC.Internal.Generics used to be in the
middle of the module graph, but now it is nearer the top (built later).
This change thins out the module graph and allows us to get rid of the
ByteOrder hs-boot file.
We implement this by moving Generics instances from the module where the
datatype is defined to the GHC.Internal.Generics module. This trades off
increasing the compiled size of GHC.Internal.Generics with reducing the
dependency footprint of datatype modules.
Not all instances are moved to GHC.Internal.Generics. For instance,
`GHC.Internal.Control.Monad.Fix` keeps its instance as it is one of the
very last modules compiled in `ghc-internal` and so inverting the
relationship here would risk adding GHC.Internal.Generics back onto the
critical path.
We also don't change modules that are re-exported from the `template-haskell` or `ghc-heap`.
This is done to make it easy to eventually move `Generics` to `base`
once something like #26657 is implemented.
Resolves #26930
Metric Decrease:
T21839c
- - - - -
45428f88 by sheaf at 2026-03-26T03:51:31-04:00
Avoid infinite loop in deep subsumption
This commit ensures we only unify after we recur in the deep subsumption
code in the FunTy vs non-FunTy case of GHC.Tc.Utils.Unify.tc_sub_type_deep,
to avoid falling into an infinite loop.
See the new Wrinkle [Avoiding a loop in tc_sub_type_deep] in
Note [FunTy vs non-FunTy case in tc_sub_type_deep] in GHC.Tc.Utils.Unify.
Fixes #26823
Co-authored-by: simonpj <simon.peytonjones(a)gmail.com>
- - - - -
2823b039 by Ian Duncan at 2026-03-26T03:52:21-04:00
AArch64: fix MOVK regUsageOfInstr to mark dst as both read and written
MOVK (move with keep) modifies only a 16-bit slice of the destination
register, so the destination is both read and written. The register
allocator must know this to avoid clobbering live values. Update
regUsageOfInstr to list the destination in both src and dst sets.
No regression test: triggering the misallocation requires specific
register pressure around a MOVK sequence, which is difficult to
reliably provoke from Haskell source.
- - - - -
57b7878d by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #12002
Closes #12002.
- - - - -
c8f9df2d by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #12046
Closes #12046.
Co-authored-by: Andreas Klebinger <klebinger.andreas(a)gmx.at>
- - - - -
615d72ac by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #13180
Closes #13180.
- - - - -
423eebcf by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #11141
Closes #11141.
- - - - -
286849a4 by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #11505
Closes #11505.
- - - - -
7db149d9 by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression perf test for #13820
Closes #13820.
- - - - -
e73c4adb by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #10381
Closes #10381.
- - - - -
5ebcfb57 by Benjamin Maurer at 2026-03-26T03:54:02-04:00
Generate assembly on x86 for word2float (#22252)
We used to emit C function call for MO_UF_Conv primitive.
Now emits direct assembly instead.
Co-Authored-By: Sylvain Henry <sylvain(a)haskus.fr>
Co-Authored-By: Claude Sonnet 4.6 <noreply(a)anthropic.com>
- - - - -
5b550754 by Matthew Pickering at 2026-03-26T03:54:51-04:00
rts: forward clone-stack messages after TSO migration
MSG_CLONE_STACK assumed that the target TSO was still owned by the
capability that received the message. This is not always true: the TSO
can migrate before the inbox entry is handled.
When that happened, handleCloneStackMessage could clone a live stack from
the wrong capability and use the wrong capability for allocation and
performTryPutMVar, leading to stack sanity failures such as
checkStackFrame: weird activation record found on stack.
Fix this by passing the current capability into
handleCloneStackMessage, rechecking msg->tso->cap at handling time, and
forwarding the message if the TSO has migrated. Once ownership matches,
use the executing capability consistently for cloneStack, rts_apply, and
performTryPutMVar.
Fixes #27008
- - - - -
ef0a1bd2 by mangoiv at 2026-03-26T03:55:34-04:00
release tracking: adopt release tracking ticket from #16816
- - - - -
a7f40fd9 by mangoiv at 2026-03-26T03:55:34-04:00
release tracking: add a release tracking ticket
Brings the information in the release tracking ticket up to date with
https://gitlab.haskell.org/ghc/ghc-hq/-/blob/main/release-management.mkd
Resolves #26691
- - - - -
161d3285 by Teo Camarasu at 2026-03-26T03:56:18-04:00
Revert "Set default eventlog-flush-interval to 5s"
Flushing the eventlog forces a synchronisation of all the capabilities
and there was a worry that this might lead to a performance cost for
some highly parallel workloads.
This reverts commit 66b96e2a591d8e3d60e74af3671344dfe4061cf2.
- - - - -
36eed985 by Cheng Shao at 2026-03-26T03:57:03-04:00
ghc-boot: move GHC.Data.SmallArray to ghc-boot
This commit moves `GHC.Data.SmallArray` from the `ghc` library to
`ghc-boot`, so that it can be used by `ghci` as well:
- The `Binary` (from `ghc`) instance of `SmallArray` is moved to
`GHC.Utils.Binary`
- Util functions `replicateSmallArrayIO`, `mapSmallArrayIO`,
`mapSmallArrayM_`, `imapSmallArrayM_` , `smallArrayFromList` and
`smallArrayToList` are added
- The `Show` instance is added
- The `Binary` (from `binary`) instance is added
- - - - -
fdf828ae by Cheng Shao at 2026-03-26T03:57:03-04:00
compiler: use `Binary` instance of `BCOByteArray` for bytecode objects
This commit defines `Binary` (from `compiler`) instance of
`BCOByteArray` which serializes the underlying buffer directly, and
uses it directly in bytecode object serialization. Previously we reuse
the `Binary` (from `binary`) instance, and this change allows us to
avoid double-copying via an intermediate `ByteString` when using
`put`/`get` in `binnary`. Also see added comment for explanation.
- - - - -
3bf62d0a by Cheng Shao at 2026-03-26T03:57:03-04:00
ghci: use SmallArray directly in ResolvedBCO
This patch makes ghci use `SmallArray` directly in `ResolvedBCO` when
applicable, making the memory representation more compact and reducing
marshaling overhead. Closes #27058.
- - - - -
3d6492ce by Wen Kokke at 2026-03-26T03:57:53-04:00
Fix race condition between flushEventLog and start/endEventLogging.
This commit changes `flushEventLog` to acquire/release the `state_change` mutex to prevent interleaving with `startEventLogging` and `endEventLogging`. In the current RTS, `flushEventLog` _does not_ acquire this mutex, which may lead to eventlog corruption on the following interleaving:
- `startEventLogging` writes the new `EventLogWriter` to `event_log_writer`.
- `flushEventLog` flushes some events to `event_log_writer`.
- `startEventLogging` writes the eventlog header to `event_log_writer`.
This causes the eventlog to be written out in an unreadable state, with one or more events preceding the eventlog header.
This commit renames the old function to `flushEventLog_` and defines `flushEventLog` simply as:
```c
void flushEventLog(Capability **cap USED_IF_THREADS)
{
ACQUIRE_LOCK(&state_change_mutex);
flushEventLog_(cap);
RELEASE_LOCK(&state_change_mutex);
}
```
The old function is still needed internally within the compilation unit, where it is used in `endEventLogging` in a context where the `state_change` mutex has already been acquired. I've chosen to mark `flushEventLog_` as static and let other uses of `flushEventLog` within the RTS refer to the new version. There is one use in `hs_init_ghc` via `flushTrace`, where the new locking behaviour should be harmless, and one use in `handle_tick`, which I believe was likely vulnerable to the same race condition, so the new locking behaviour is desirable.
I have not added a test. The behaviour is highly non-deterministic and requires a program that concurrently calls `flushEventLog` and `startEventLogging`/`endEventLogging`. I encountered the issue while developing `eventlog-socket` and within that context have verified that my patch likely addresses the issue: a test that used to fail within the first dozen or so runs now has been running on repeat for several hours.
- - - - -
7b9a75f0 by Phil Hazelden at 2026-03-26T03:58:37-04:00
Fix build with werror on glibc 2.43.
We've been defining `_XOPEN_SOURCE` and `_POSIX_C_SOURCE` to the same
values as defined in glibc prior to 2.43. But in 2.43, glibc changes
them to new values, which means we get a warning when redefining them.
By `#undef`ing them first, we no longer get a warning.
Closes #27076.
- - - - -
fe6e76c5 by Tobias Haslop at 2026-03-26T03:59:30-04:00
Fix broken Haddock link to Bifunctor class in description of Functor class
- - - - -
adf797e1 by Wolfgang Jeltsch at 2026-03-27T20:36:26+02:00
Move most of the `System.IO` implementation into `base`
This involves a rewrite of the `combine` helper function to avoid the
use of `last`, which would now be flagged as an error.
Metric Increase:
T12227
T12707
T5642
- - - - -
4a954273 by Wolfgang Jeltsch at 2026-03-27T20:49:08+02:00
Move I/O-related `Read` instances into `base`
Metric Increase:
T12425
T13035
- - - - -
48d2a860 by Wolfgang Jeltsch at 2026-03-27T20:49:08+02:00
Move most of the `Numeric` implementation into `base`
The `showHex` operation and the `showIntAtBase` operation, which
underlies it, are kept in `GHC.Internal.Numeric`, because `showHex` is
used in a few places in `ghc-internal`; everything else is moved.
- - - - -
db6abc1a by Wolfgang Jeltsch at 2026-03-27T21:50:57+02:00
Move the instance `Read ByteOrder` into `base`
- - - - -
41c1ce44 by Wolfgang Jeltsch at 2026-03-27T21:51:14+02:00
Move the implementation of version parsing into `base`
- - - - -
6c8b3e9b by Wolfgang Jeltsch at 2026-03-27T21:51:14+02:00
Move the implementation of `readConstr` into `base`
- - - - -
129fcf80 by Wolfgang Jeltsch at 2026-03-27T21:52:19+02:00
Move the `Text.Read` implementation into `base`
- - - - -
149 changed files:
- + .gitlab/issue_templates/release_tracking.md
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/Cmm/Node.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToLlvm.hs
- compiler/GHC/CmmToLlvm/Config.hs
- compiler/GHC/CmmToLlvm/Mangler.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/ConstantFold.hs
- + compiler/GHC/Core/Opt/Range.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Driver/Config/CmmToLlvm.hs
- compiler/GHC/Prelude/Basic.hs
- compiler/GHC/StgToCmm/Expr.hs
- compiler/GHC/StgToCmm/Utils.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Utils/Binary.hs
- compiler/ghc.cabal.in
- docs/users_guide/9.16.1-notes.rst
- libraries/base/src/Control/Concurrent.hs
- libraries/base/src/Data/Data.hs
- libraries/base/src/Data/Functor/Classes.hs
- libraries/base/src/Data/Functor/Compose.hs
- libraries/base/src/Data/Version.hs
- libraries/base/src/GHC/ByteOrder.hs
- libraries/base/src/GHC/IO/Handle.hs
- libraries/base/src/Numeric.hs
- libraries/base/src/Prelude.hs
- libraries/base/src/System/IO.hs
- libraries/base/src/Text/Printf.hs
- libraries/base/src/Text/Read.hs
- compiler/GHC/Data/SmallArray.hs → libraries/ghc-boot/GHC/Data/SmallArray.hs
- libraries/ghc-boot/ghc-boot.cabal.in
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/ByteOrder.hs
- − libraries/ghc-internal/src/GHC/Internal/ByteOrder.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Char.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Functor/Const.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Functor/Identity.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Monoid.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Semigroup/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Traversable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Control.hs
- libraries/ghc-internal/src/GHC/Internal/Functor/ZipList.hs
- libraries/ghc-internal/src/GHC/Internal/Generics.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Device.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
- libraries/ghc-internal/src/GHC/Internal/IO/IOMode.hs
- libraries/ghc-internal/src/GHC/Internal/Numeric.hs
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
- libraries/ghc-internal/src/GHC/Internal/System/IO.hs
- − libraries/ghc-internal/src/GHC/Internal/Text/Read.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Bits.hs
- libraries/ghci/GHCi/CreateBCO.hs
- libraries/ghci/GHCi/ResolvedBCO.hs
- rts/CloneStack.c
- rts/CloneStack.h
- rts/Messages.c
- rts/RtsFlags.c
- rts/StgCRun.c
- rts/eventlog/EventLog.c
- rts/include/rts/Constants.h
- rts/include/rts/PosixSource.h
- testsuite/tests/codeGen/should_run/Word2Float32.hs
- testsuite/tests/codeGen/should_run/Word2Float32.stdout
- testsuite/tests/codeGen/should_run/Word2Float64.hs
- testsuite/tests/codeGen/should_run/Word2Float64.stdout
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/ghci/scripts/ListTuplePunsPpr.stdout
- testsuite/tests/ghci/scripts/T10963.stderr
- testsuite/tests/ghci/scripts/ghci064.stdout
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- + testsuite/tests/parser/should_compile/T12002.hs
- + testsuite/tests/parser/should_compile/T12002.stderr
- testsuite/tests/parser/should_compile/all.T
- + testsuite/tests/perf/compiler/T13820.hs
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/plugins/plugins09.stdout
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/plugins/plugins11.stdout
- testsuite/tests/plugins/static-plugins.stdout
- + testsuite/tests/rebindable/T10381.hs
- testsuite/tests/rebindable/all.T
- testsuite/tests/rts/all.T
- + testsuite/tests/rts/cloneThreadStackMigrating.hs
- + testsuite/tests/simd/should_run/StackAlignment32.hs
- + testsuite/tests/simd/should_run/StackAlignment32.stdout
- + testsuite/tests/simd/should_run/StackAlignment32_main.c
- + testsuite/tests/simd/should_run/StackAlignment64.hs
- + testsuite/tests/simd/should_run/StackAlignment64.stdout
- + testsuite/tests/simd/should_run/StackAlignment64_main.c
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simplCore/should_compile/T19166.hs
- + testsuite/tests/simplCore/should_compile/T19166.stderr
- + testsuite/tests/simplCore/should_compile/T25718.hs
- + testsuite/tests/simplCore/should_compile/T25718.stderr
- + testsuite/tests/simplCore/should_compile/T25718a.hs
- + testsuite/tests/simplCore/should_compile/T25718a.stderr
- + testsuite/tests/simplCore/should_compile/T25718b.hs
- + testsuite/tests/simplCore/should_compile/T25718b.stderr
- + testsuite/tests/simplCore/should_compile/T25718c.hs
- + testsuite/tests/simplCore/should_compile/T25718c.stderr-ws-32
- + testsuite/tests/simplCore/should_compile/T25718c.stderr-ws-64
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/typecheck/T13180/T13180.hs
- + testsuite/tests/typecheck/T13180/T13180.hs-boot
- + testsuite/tests/typecheck/T13180/T13180.stderr
- + testsuite/tests/typecheck/T13180/T13180A.hs
- + testsuite/tests/typecheck/T13180/all.T
- + testsuite/tests/typecheck/should_compile/T11141.hs
- + testsuite/tests/typecheck/should_compile/T11141.stderr
- + testsuite/tests/typecheck/should_compile/T11505Bar.hs
- + testsuite/tests/typecheck/should_compile/T11505Foo.hs
- + testsuite/tests/typecheck/should_compile/T11505Foo.hs-boot
- + testsuite/tests/typecheck/should_compile/T12046.hs
- testsuite/tests/typecheck/should_compile/T26225.hs
- testsuite/tests/typecheck/should_compile/T9497a.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/holes.stderr
- testsuite/tests/typecheck/should_compile/holes3.stderr
- testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr
- + testsuite/tests/typecheck/should_fail/T26823.hs
- + testsuite/tests/typecheck/should_fail/T26823.stderr
- testsuite/tests/typecheck/should_fail/T9497d.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug973.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/DefaultSignatures.html
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/PatternSyns.html
- utils/haddock/html-test/ref/PatternSyns2.html
- utils/haddock/html-test/ref/QuasiExpr.html
- utils/haddock/html-test/ref/Test.html
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0d0f69c702426e7fae09fc13b64249…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0d0f69c702426e7fae09fc13b64249…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/text-read-uncovering] 30 commits: Check that shift values are valid
by Wolfgang Jeltsch (@jeltsch) 27 Mar '26
by Wolfgang Jeltsch (@jeltsch) 27 Mar '26
27 Mar '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/text-read-uncovering at Glasgow Haskell Compiler / GHC
Commits:
aa5dfe67 by Sylvain Henry at 2026-03-26T03:48:56-04:00
Check that shift values are valid
In GHC's codebase in non-DEBUG builds we silently substitute shiftL/R
with unsafeShiftL/R for performance reasons. However we were not
checking that the shift value was valid for unsafeShiftL/R, leading to
wrong computations, but only in non-DEBUG builds.
This patch adds the necessary checks and reports an error when a wrong
shift value is passed.
- - - - -
c8a7b588 by Sylvain Henry at 2026-03-26T03:48:56-04:00
Implement basic value range analysis (#25718)
Perform basic value range analysis to try to determine at compile time
the result of the application of some comparison primops (ltWord#, etc.).
This subsumes the built-in rewrite rules used previously to check if one
of the comparison argument was a bound (e.g. (x :: Word8) <= 255 is
always True). Our analysis is more powerful and handles type
conversions: e.g. word8ToWord x <= 255 is now detected as always True too.
We also use value range analysis to filter unreachable alternatives in
case-expressions. To support this, we had to allow case-expressions for
primitive types to not have a DEFAULT alternative (as was assumed before
and checked in Core lint).
- - - - -
a5ec467e by ARATA Mizuki at 2026-03-26T03:49:49-04:00
rts: Align stack to 64-byte boundary in StgRun on x86
When LLVM spills AVX/AVX-512 vector registers to the stack, it requires
32-byte (__m256) or 64-byte (__m512) alignment. If the stack is not
sufficiently aligned, LLVM inserts a realignment prologue that reserves
%rbp as a frame pointer, conflicting with GHC's use of %rbp as an STG
callee-saved register and breaking the tail-call-based calling convention.
Previously, GHC worked around this by lying to LLVM about the stack
alignment and rewriting aligned vector loads/stores (VMOVDQA, VMOVAPS)
to unaligned ones (VMOVDQU, VMOVUPS) in the LLVM Mangler. This had two
problems:
- It did not extend to AVX-512, which requires 64-byte alignment. (#26595)
- When Haskell calls a C function that takes __m256/__m512 arguments on
the stack, the callee requires genuine alignment, which could cause a
segfault. (#26822)
This patch genuinely aligns the stack to 64 bytes in StgRun by saving
the original stack pointer before alignment and restoring it in
StgReturn. We now unconditionally advertise 64-byte stack alignment to
LLVM for all x86 targets, making rewriteAVX in the LLVM Mangler
unnecessary. STG_RUN_STACK_FRAME_SIZE is increased from 48 to 56 bytes
on non-Windows x86-64 to store the saved stack pointer.
Closes #26595 and #26822
Co-Authored-By: Claude Opus 4.5 <noreply(a)anthropic.com>
- - - - -
661da815 by Teo Camarasu at 2026-03-26T03:50:33-04:00
ghc-internal: Float Generics to near top of module graph
We remove GHC.Internal.Generics from the critical path of the
`ghc-internal` module graph. GHC.Internal.Generics used to be in the
middle of the module graph, but now it is nearer the top (built later).
This change thins out the module graph and allows us to get rid of the
ByteOrder hs-boot file.
We implement this by moving Generics instances from the module where the
datatype is defined to the GHC.Internal.Generics module. This trades off
increasing the compiled size of GHC.Internal.Generics with reducing the
dependency footprint of datatype modules.
Not all instances are moved to GHC.Internal.Generics. For instance,
`GHC.Internal.Control.Monad.Fix` keeps its instance as it is one of the
very last modules compiled in `ghc-internal` and so inverting the
relationship here would risk adding GHC.Internal.Generics back onto the
critical path.
We also don't change modules that are re-exported from the `template-haskell` or `ghc-heap`.
This is done to make it easy to eventually move `Generics` to `base`
once something like #26657 is implemented.
Resolves #26930
Metric Decrease:
T21839c
- - - - -
45428f88 by sheaf at 2026-03-26T03:51:31-04:00
Avoid infinite loop in deep subsumption
This commit ensures we only unify after we recur in the deep subsumption
code in the FunTy vs non-FunTy case of GHC.Tc.Utils.Unify.tc_sub_type_deep,
to avoid falling into an infinite loop.
See the new Wrinkle [Avoiding a loop in tc_sub_type_deep] in
Note [FunTy vs non-FunTy case in tc_sub_type_deep] in GHC.Tc.Utils.Unify.
Fixes #26823
Co-authored-by: simonpj <simon.peytonjones(a)gmail.com>
- - - - -
2823b039 by Ian Duncan at 2026-03-26T03:52:21-04:00
AArch64: fix MOVK regUsageOfInstr to mark dst as both read and written
MOVK (move with keep) modifies only a 16-bit slice of the destination
register, so the destination is both read and written. The register
allocator must know this to avoid clobbering live values. Update
regUsageOfInstr to list the destination in both src and dst sets.
No regression test: triggering the misallocation requires specific
register pressure around a MOVK sequence, which is difficult to
reliably provoke from Haskell source.
- - - - -
57b7878d by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #12002
Closes #12002.
- - - - -
c8f9df2d by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #12046
Closes #12046.
Co-authored-by: Andreas Klebinger <klebinger.andreas(a)gmx.at>
- - - - -
615d72ac by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #13180
Closes #13180.
- - - - -
423eebcf by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #11141
Closes #11141.
- - - - -
286849a4 by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #11505
Closes #11505.
- - - - -
7db149d9 by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression perf test for #13820
Closes #13820.
- - - - -
e73c4adb by Simon Jakobi at 2026-03-26T03:53:07-04:00
Add regression test for #10381
Closes #10381.
- - - - -
5ebcfb57 by Benjamin Maurer at 2026-03-26T03:54:02-04:00
Generate assembly on x86 for word2float (#22252)
We used to emit C function call for MO_UF_Conv primitive.
Now emits direct assembly instead.
Co-Authored-By: Sylvain Henry <sylvain(a)haskus.fr>
Co-Authored-By: Claude Sonnet 4.6 <noreply(a)anthropic.com>
- - - - -
5b550754 by Matthew Pickering at 2026-03-26T03:54:51-04:00
rts: forward clone-stack messages after TSO migration
MSG_CLONE_STACK assumed that the target TSO was still owned by the
capability that received the message. This is not always true: the TSO
can migrate before the inbox entry is handled.
When that happened, handleCloneStackMessage could clone a live stack from
the wrong capability and use the wrong capability for allocation and
performTryPutMVar, leading to stack sanity failures such as
checkStackFrame: weird activation record found on stack.
Fix this by passing the current capability into
handleCloneStackMessage, rechecking msg->tso->cap at handling time, and
forwarding the message if the TSO has migrated. Once ownership matches,
use the executing capability consistently for cloneStack, rts_apply, and
performTryPutMVar.
Fixes #27008
- - - - -
ef0a1bd2 by mangoiv at 2026-03-26T03:55:34-04:00
release tracking: adopt release tracking ticket from #16816
- - - - -
a7f40fd9 by mangoiv at 2026-03-26T03:55:34-04:00
release tracking: add a release tracking ticket
Brings the information in the release tracking ticket up to date with
https://gitlab.haskell.org/ghc/ghc-hq/-/blob/main/release-management.mkd
Resolves #26691
- - - - -
161d3285 by Teo Camarasu at 2026-03-26T03:56:18-04:00
Revert "Set default eventlog-flush-interval to 5s"
Flushing the eventlog forces a synchronisation of all the capabilities
and there was a worry that this might lead to a performance cost for
some highly parallel workloads.
This reverts commit 66b96e2a591d8e3d60e74af3671344dfe4061cf2.
- - - - -
36eed985 by Cheng Shao at 2026-03-26T03:57:03-04:00
ghc-boot: move GHC.Data.SmallArray to ghc-boot
This commit moves `GHC.Data.SmallArray` from the `ghc` library to
`ghc-boot`, so that it can be used by `ghci` as well:
- The `Binary` (from `ghc`) instance of `SmallArray` is moved to
`GHC.Utils.Binary`
- Util functions `replicateSmallArrayIO`, `mapSmallArrayIO`,
`mapSmallArrayM_`, `imapSmallArrayM_` , `smallArrayFromList` and
`smallArrayToList` are added
- The `Show` instance is added
- The `Binary` (from `binary`) instance is added
- - - - -
fdf828ae by Cheng Shao at 2026-03-26T03:57:03-04:00
compiler: use `Binary` instance of `BCOByteArray` for bytecode objects
This commit defines `Binary` (from `compiler`) instance of
`BCOByteArray` which serializes the underlying buffer directly, and
uses it directly in bytecode object serialization. Previously we reuse
the `Binary` (from `binary`) instance, and this change allows us to
avoid double-copying via an intermediate `ByteString` when using
`put`/`get` in `binnary`. Also see added comment for explanation.
- - - - -
3bf62d0a by Cheng Shao at 2026-03-26T03:57:03-04:00
ghci: use SmallArray directly in ResolvedBCO
This patch makes ghci use `SmallArray` directly in `ResolvedBCO` when
applicable, making the memory representation more compact and reducing
marshaling overhead. Closes #27058.
- - - - -
3d6492ce by Wen Kokke at 2026-03-26T03:57:53-04:00
Fix race condition between flushEventLog and start/endEventLogging.
This commit changes `flushEventLog` to acquire/release the `state_change` mutex to prevent interleaving with `startEventLogging` and `endEventLogging`. In the current RTS, `flushEventLog` _does not_ acquire this mutex, which may lead to eventlog corruption on the following interleaving:
- `startEventLogging` writes the new `EventLogWriter` to `event_log_writer`.
- `flushEventLog` flushes some events to `event_log_writer`.
- `startEventLogging` writes the eventlog header to `event_log_writer`.
This causes the eventlog to be written out in an unreadable state, with one or more events preceding the eventlog header.
This commit renames the old function to `flushEventLog_` and defines `flushEventLog` simply as:
```c
void flushEventLog(Capability **cap USED_IF_THREADS)
{
ACQUIRE_LOCK(&state_change_mutex);
flushEventLog_(cap);
RELEASE_LOCK(&state_change_mutex);
}
```
The old function is still needed internally within the compilation unit, where it is used in `endEventLogging` in a context where the `state_change` mutex has already been acquired. I've chosen to mark `flushEventLog_` as static and let other uses of `flushEventLog` within the RTS refer to the new version. There is one use in `hs_init_ghc` via `flushTrace`, where the new locking behaviour should be harmless, and one use in `handle_tick`, which I believe was likely vulnerable to the same race condition, so the new locking behaviour is desirable.
I have not added a test. The behaviour is highly non-deterministic and requires a program that concurrently calls `flushEventLog` and `startEventLogging`/`endEventLogging`. I encountered the issue while developing `eventlog-socket` and within that context have verified that my patch likely addresses the issue: a test that used to fail within the first dozen or so runs now has been running on repeat for several hours.
- - - - -
7b9a75f0 by Phil Hazelden at 2026-03-26T03:58:37-04:00
Fix build with werror on glibc 2.43.
We've been defining `_XOPEN_SOURCE` and `_POSIX_C_SOURCE` to the same
values as defined in glibc prior to 2.43. But in 2.43, glibc changes
them to new values, which means we get a warning when redefining them.
By `#undef`ing them first, we no longer get a warning.
Closes #27076.
- - - - -
fe6e76c5 by Tobias Haslop at 2026-03-26T03:59:30-04:00
Fix broken Haddock link to Bifunctor class in description of Functor class
- - - - -
adf797e1 by Wolfgang Jeltsch at 2026-03-27T20:36:26+02:00
Move most of the `System.IO` implementation into `base`
This involves a rewrite of the `combine` helper function to avoid the
use of `last`, which would now be flagged as an error.
Metric Increase:
T12227
T12707
T5642
- - - - -
4a954273 by Wolfgang Jeltsch at 2026-03-27T20:49:08+02:00
Move I/O-related `Read` instances into `base`
Metric Increase:
T12425
T13035
- - - - -
48d2a860 by Wolfgang Jeltsch at 2026-03-27T20:49:08+02:00
Move most of the `Numeric` implementation into `base`
The `showHex` operation and the `showIntAtBase` operation, which
underlies it, are kept in `GHC.Internal.Numeric`, because `showHex` is
used in a few places in `ghc-internal`; everything else is moved.
- - - - -
db6abc1a by Wolfgang Jeltsch at 2026-03-27T21:50:57+02:00
Move the instance `Read ByteOrder` into `base`
- - - - -
41c1ce44 by Wolfgang Jeltsch at 2026-03-27T21:51:14+02:00
Move the implementation of version parsing into `base`
- - - - -
6c8b3e9b by Wolfgang Jeltsch at 2026-03-27T21:51:14+02:00
Move the implementation of `readConstr` into `base`
- - - - -
144 changed files:
- + .gitlab/issue_templates/release_tracking.md
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/Cmm/Node.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToLlvm.hs
- compiler/GHC/CmmToLlvm/Config.hs
- compiler/GHC/CmmToLlvm/Mangler.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/ConstantFold.hs
- + compiler/GHC/Core/Opt/Range.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Driver/Config/CmmToLlvm.hs
- compiler/GHC/Prelude/Basic.hs
- compiler/GHC/StgToCmm/Expr.hs
- compiler/GHC/StgToCmm/Utils.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Utils/Binary.hs
- compiler/ghc.cabal.in
- docs/users_guide/9.16.1-notes.rst
- libraries/base/src/Control/Concurrent.hs
- libraries/base/src/Data/Data.hs
- libraries/base/src/Data/Version.hs
- libraries/base/src/GHC/ByteOrder.hs
- libraries/base/src/GHC/IO/Handle.hs
- libraries/base/src/Numeric.hs
- libraries/base/src/Prelude.hs
- libraries/base/src/System/IO.hs
- libraries/base/src/Text/Printf.hs
- compiler/GHC/Data/SmallArray.hs → libraries/ghc-boot/GHC/Data/SmallArray.hs
- libraries/ghc-boot/ghc-boot.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/ByteOrder.hs
- − libraries/ghc-internal/src/GHC/Internal/ByteOrder.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Char.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Functor/Const.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Functor/Identity.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Monoid.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Semigroup/Internal.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Traversable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Control.hs
- libraries/ghc-internal/src/GHC/Internal/Functor/ZipList.hs
- libraries/ghc-internal/src/GHC/Internal/Generics.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Device.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
- libraries/ghc-internal/src/GHC/Internal/IO/IOMode.hs
- libraries/ghc-internal/src/GHC/Internal/Numeric.hs
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
- libraries/ghc-internal/src/GHC/Internal/System/IO.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Bits.hs
- libraries/ghci/GHCi/CreateBCO.hs
- libraries/ghci/GHCi/ResolvedBCO.hs
- rts/CloneStack.c
- rts/CloneStack.h
- rts/Messages.c
- rts/RtsFlags.c
- rts/StgCRun.c
- rts/eventlog/EventLog.c
- rts/include/rts/Constants.h
- rts/include/rts/PosixSource.h
- testsuite/tests/codeGen/should_run/Word2Float32.hs
- testsuite/tests/codeGen/should_run/Word2Float32.stdout
- testsuite/tests/codeGen/should_run/Word2Float64.hs
- testsuite/tests/codeGen/should_run/Word2Float64.stdout
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/ghci/scripts/ListTuplePunsPpr.stdout
- testsuite/tests/ghci/scripts/T10963.stderr
- testsuite/tests/ghci/scripts/ghci064.stdout
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- + testsuite/tests/parser/should_compile/T12002.hs
- + testsuite/tests/parser/should_compile/T12002.stderr
- testsuite/tests/parser/should_compile/all.T
- + testsuite/tests/perf/compiler/T13820.hs
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/plugins/plugins09.stdout
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/plugins/plugins11.stdout
- testsuite/tests/plugins/static-plugins.stdout
- + testsuite/tests/rebindable/T10381.hs
- testsuite/tests/rebindable/all.T
- testsuite/tests/rts/all.T
- + testsuite/tests/rts/cloneThreadStackMigrating.hs
- + testsuite/tests/simd/should_run/StackAlignment32.hs
- + testsuite/tests/simd/should_run/StackAlignment32.stdout
- + testsuite/tests/simd/should_run/StackAlignment32_main.c
- + testsuite/tests/simd/should_run/StackAlignment64.hs
- + testsuite/tests/simd/should_run/StackAlignment64.stdout
- + testsuite/tests/simd/should_run/StackAlignment64_main.c
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simplCore/should_compile/T19166.hs
- + testsuite/tests/simplCore/should_compile/T19166.stderr
- + testsuite/tests/simplCore/should_compile/T25718.hs
- + testsuite/tests/simplCore/should_compile/T25718.stderr
- + testsuite/tests/simplCore/should_compile/T25718a.hs
- + testsuite/tests/simplCore/should_compile/T25718a.stderr
- + testsuite/tests/simplCore/should_compile/T25718b.hs
- + testsuite/tests/simplCore/should_compile/T25718b.stderr
- + testsuite/tests/simplCore/should_compile/T25718c.hs
- + testsuite/tests/simplCore/should_compile/T25718c.stderr-ws-32
- + testsuite/tests/simplCore/should_compile/T25718c.stderr-ws-64
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/typecheck/T13180/T13180.hs
- + testsuite/tests/typecheck/T13180/T13180.hs-boot
- + testsuite/tests/typecheck/T13180/T13180.stderr
- + testsuite/tests/typecheck/T13180/T13180A.hs
- + testsuite/tests/typecheck/T13180/all.T
- + testsuite/tests/typecheck/should_compile/T11141.hs
- + testsuite/tests/typecheck/should_compile/T11141.stderr
- + testsuite/tests/typecheck/should_compile/T11505Bar.hs
- + testsuite/tests/typecheck/should_compile/T11505Foo.hs
- + testsuite/tests/typecheck/should_compile/T11505Foo.hs-boot
- + testsuite/tests/typecheck/should_compile/T12046.hs
- testsuite/tests/typecheck/should_compile/T26225.hs
- testsuite/tests/typecheck/should_compile/T9497a.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/holes.stderr
- testsuite/tests/typecheck/should_compile/holes3.stderr
- testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr
- + testsuite/tests/typecheck/should_fail/T26823.hs
- + testsuite/tests/typecheck/should_fail/T26823.stderr
- testsuite/tests/typecheck/should_fail/T9497d.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug973.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/DefaultSignatures.html
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/PatternSyns.html
- utils/haddock/html-test/ref/PatternSyns2.html
- utils/haddock/html-test/ref/QuasiExpr.html
- utils/haddock/html-test/ref/Test.html
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/38ed246d58d81f0e097c30d6651cff…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/38ed246d58d81f0e097c30d6651cff…
You're receiving this email because of your account on gitlab.haskell.org.
1
0