[Git][ghc/ghc][wip/25924] Revert "Do not use an error thunk for an absent dictionary"
by Zubin (@wz1000) 23 Jun '26
by Zubin (@wz1000) 23 Jun '26
23 Jun '26
Zubin pushed to branch wip/25924 at Glasgow Haskell Compiler / GHC
Commits:
9fe864da by Zubin Duggal at 2026-06-23T15:26:30+05:30
Revert "Do not use an error thunk for an absent dictionary"
This reverts commit b09571e2055c24daffa170e74fe8ef424285307e.
- - - - -
1 changed file:
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
Changes:
=====================================
compiler/GHC/Core/Opt/WorkWrap/Utils.hs
=====================================
@@ -30,7 +30,6 @@ import GHC.Core.Subst
import GHC.Core.Type
import GHC.Core.Multiplicity
import GHC.Core.Coercion
-import GHC.Core.Predicate( isDictTy )
import GHC.Core.Reduction
import GHC.Core.FamInstEnv
import GHC.Core.Predicate( isEqualityClass )
@@ -1069,25 +1068,21 @@ unbox_one_arg opts arg_var
-- same type as @id@. Otherwise, no suitable filler could be found.
mkAbsentFiller :: WwOpts -> Id -> StrictnessMark -> Maybe CoreExpr
mkAbsentFiller opts arg str
- -- The lifted case: bind 'absentError'. See (AF1) in Note [Absent fillers]
- -- We want to use this case if possible, because we get a nice runtime panic message
- -- if we are wrong (like we were in #11126). Otherwise we fall through to the
- -- less-desirable mkLitRubbish case.
+ -- The lifted case: Bind 'absentError' for a nice panic message if we are
+ -- wrong (like we were in #11126). See (1) in Note [Absent fillers]
| mightBeLiftedType arg_ty
- , not (isDictTy arg_ty) -- See (AF4) in Note [Absent fillers]
- , not (isStrictDmd (idDemandInfo arg)) -- See (AF2)
- , not (isMarkedStrict str) -- in Note [Absent fillers]
+ , not is_strict
+ , not (isMarkedStrict str) -- See (2) in Note [Absent fillers]
= Just (mkAbsentErrorApp arg_ty msg)
-- The default case for mono rep: Bind `RUBBISH[rr] arg_ty`
- -- See Note [Absent fillers]
- -- (AF3): mkLitRubbish returns Nothing if the representation is not
- -- monomorphic, in which case we can't make a filler
+ -- See Note [Absent fillers], the main part
| otherwise
= mkLitRubbish arg_ty
where
- arg_ty = idType arg
+ arg_ty = idType arg
+ is_strict = isStrictDmd (idDemandInfo arg)
msg = renderWithContext
(defaultSDocContext { sdocSuppressUniques = True })
@@ -1250,7 +1245,7 @@ conjure filler values at any type (and any representation or levity!).
Needless to say, there are some wrinkles:
-(AF1) In case we have a absent, /lazy/, and /lifted/ arg, we use an error-thunk
+ 1. In case we have a absent, /lazy/, and /lifted/ arg, we use an error-thunk
instead. If absence analysis was wrong (e.g., #11126) and the binding
in fact is used, then we get a nice panic message instead of undefined
runtime behavior (See Modes of failure from Note [Rubbish literals]).
@@ -1258,7 +1253,7 @@ Needless to say, there are some wrinkles:
Obviously, we can't use an error-thunk if the value is of unlifted rep
(like 'Int#' or 'MutVar#'), because we'd immediately evaluate the panic.
-(AF2) We also mustn't put an error-thunk (that fills in for an absent value of
+ 2. We also mustn't put an error-thunk (that fills in for an absent value of
lifted rep) in a strict field, because #16970 establishes the invariant
that strict fields are always evaluated, by possibly (re-)evaluating what is put in
a strict field. That's the reason why 'zs' binds a rubbish literal instead
@@ -1284,8 +1279,8 @@ Needless to say, there are some wrinkles:
strictness check in place on top of threading through the marks from the
constructor. It's a *really* cheap and easy check to make anyway.
-(AF3) We can only emit a LitRubbish if the arg's type `arg_ty` is mono-rep, e.g.
- of the form `TYPE rep` where `rep` is not (and doesn't contain) a variable.
+ 3. We can only emit a LitRubbish if the arg's type @arg_ty@ is mono-rep, e.g.
+ of the form @TYPE rep@ where @rep@ is not (and doesn't contain) a variable.
Why? Because if we don't know its representation (e.g. size in memory,
register class), we don't know what or how much rubbish to emit in codegen.
'mkLitRubbish' returns 'Nothing' in this case and we simply fall
@@ -1295,30 +1290,8 @@ Needless to say, there are some wrinkles:
have to be representation monomorphic. But in the future, we might allow
levity polymorphism, e.g. a polymorphic levity variable in 'BoxedRep'.
-(AF4) Consider (#24934)
- f :: (a~b) => blah {-# INLINE f #-}
- f d x = case eq_sel d of co -> body
- In #24934 it turned out that `co` was unused; and we discarded the
- entire case-scrutinisation via the `exprOkToDiscard` test in
- `GHC.Core.Opt.Simplify.Iteration.rebuildCase`. So now `d` is absent.
- But in the /unfolding/ for some reason we did not discard the `case`;
- so when we inline `f` we end up evaluating that `d` argument. So we had
- better not replace it with an error thunk!
-
- The root of it is this: `exprOkToDiscard` assumes that a dictionary is
- non-bottom (Note [exprOkForSpeculation and type classes]); but then we replace
- the (a~b) dictionary with an error thunk, breaking the invariant that every
- dictionary is non-bottom. (If -XDictsStrict is on, the invariant is even
- more important.)
-
- Simple solution: never use an error thunk for a dictionary; instead fall
- through to mkRubbishLit. (The only downside is that we lose the compiler
- debugging advantages of (AF1).)
-
- This is quite delicate.
-
-While (AF1) and (AF2) are simply an optimisation in terms of compiler debugging
-experience, (AF3) should be irrelevant in most programs, if not all.
+While (1) and (2) are simply an optimisation in terms of compiler debugging
+experience, (3) should be irrelevant in most programs, if not all.
Historical note: I did try the experiment of using an error thunk for unlifted
things too, relying on the simplifier to drop it as dead code. But this is
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9fe864daa77a968b9f7e996e93d3883…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9fe864daa77a968b9f7e996e93d3883…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] EPA: remove LocatedL / SrcSpanAnnL and LocatedLI / SrcSpanAnnLI
by Marge Bot (@marge-bot) 23 Jun '26
by Marge Bot (@marge-bot) 23 Jun '26
23 Jun '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
44309cd3 by Alan Zimmerman at 2026-06-23T05:56:20-04:00
EPA: remove LocatedL / SrcSpanAnnL and LocatedLI / SrcSpanAnnLI
This is part of a refactor towards only having LocatedA / SrcSpanAnnA
It removes the stated items, but has to add back one for BooleanFormula,
LocatedBF / SrcSpanAnnBF
This commit also use the HsConDetails RecCon extension point to
capture the braces in a record constructor
- - - - -
62 changed files:
- compiler/GHC/Data/BooleanFormula.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Stats.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/ThToHs.hs
- compiler/Language/Haskell/Syntax.hs
- compiler/Language/Haskell/Syntax/ImpExp.hs
- ghc/GHCi/UI.hs
- testsuite/tests/ghc-api/exactprint/T22919.stderr
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr
- testsuite/tests/module/mod185.stderr
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/parser/should_compile/KindSigs.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T15323.stderr
- testsuite/tests/parser/should_compile/T20452.stderr
- testsuite/tests/parser/should_compile/T20718.stderr
- testsuite/tests/parser/should_compile/T20718b.stderr
- testsuite/tests/parser/should_compile/T20846.stderr
- testsuite/tests/parser/should_compile/T23315/T23315.stderr
- testsuite/tests/printer/AnnotationNoListTuplePuns.stdout
- testsuite/tests/printer/T18791.stderr
- testsuite/tests/printer/Test10309.hs
- testsuite/tests/printer/Test20297.stdout
- testsuite/tests/printer/Test24533.stdout
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Main.hs
- utils/check-exact/Utils.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44309cd377f115d3e6b788097750bd5…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44309cd377f115d3e6b788097750bd5…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Don't use global variables to address concurrency bugs! (fixes #27234)
by Marge Bot (@marge-bot) 23 Jun '26
by Marge Bot (@marge-bot) 23 Jun '26
23 Jun '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
9284a1f7 by Simon Hengel at 2026-06-23T05:55:33-04:00
Don't use global variables to address concurrency bugs! (fixes #27234)
This was originally introduce with
88f38b03025386f0f1e8f5861eed67d80495168a to address #17922.
In this specific case a better fix would have been to synchronize on
stderr:
withHandle_ "stderrSupportsAnsiColors" stderr $ \ _ -> do
...
But apparently the dependency on `terminfo` was removed in
32ab07bf3d6ce45e8ea5b55e8095174a6b42a7f0, preventing #17922 in the first
place.
- - - - -
2 changed files:
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/SysTools/Terminal.hs
Changes:
=====================================
compiler/GHC/Driver/DynFlags.hs
=====================================
@@ -546,6 +546,7 @@ initDynFlags dflags = do
`catchIOError` \_ -> return False
ghcNoUnicodeEnv <- lookupEnv "GHC_NO_UNICODE"
let useUnicode' = isNothing ghcNoUnicodeEnv && canUseUnicode
+ canUseColor <- stderrSupportsAnsiColors
maybeGhcColorsEnv <- lookupEnv "GHC_COLORS"
maybeGhcColoursEnv <- lookupEnv "GHC_COLOURS"
let adjustCols (Just env) = Col.parseScheme env
@@ -557,9 +558,9 @@ initDynFlags dflags = do
return dflags{
useUnicode = useUnicode',
useColor = useColor',
- canUseColor = stderrSupportsAnsiColors,
+ canUseColor = canUseColor,
-- if the terminal supports color, we assume it supports links as well
- canUseErrorLinks = stderrSupportsAnsiColors,
+ canUseErrorLinks = canUseColor,
colScheme = colScheme',
tmpDir = TempDir tmp_dir
}
=====================================
compiler/GHC/SysTools/Terminal.hs
=====================================
@@ -14,17 +14,9 @@ import qualified Graphics.Win32 as Win32
import qualified System.Win32 as Win32
#endif
-import System.IO.Unsafe
-
--- | Does the controlling terminal support ANSI color sequences?
--- This memoized to avoid thread-safety issues in ncurses (see #17922).
-stderrSupportsAnsiColors :: Bool
-stderrSupportsAnsiColors = unsafePerformIO stderrSupportsAnsiColors'
-{-# NOINLINE stderrSupportsAnsiColors #-}
-
-- | Check if ANSI escape sequences can be used to control color in stderr.
-stderrSupportsAnsiColors' :: IO Bool
-stderrSupportsAnsiColors' = do
+stderrSupportsAnsiColors :: IO Bool
+stderrSupportsAnsiColors = do
#if !defined(mingw32_HOST_OS)
-- Equivalent of https://hackage.haskell.org/package/ansi-terminal/docs/System-Console-ANSI.…
isTerminal <- hIsTerminalDevice stderr
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9284a1f77cec58abc94f29e18e8c69e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9284a1f77cec58abc94f29e18e8c69e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/mangoiv/26616] compiler: refactor error reporting code for ExplicitLevelImports
by Magnus (@MangoIV) 23 Jun '26
by Magnus (@MangoIV) 23 Jun '26
23 Jun '26
Magnus pushed to branch wip/mangoiv/26616 at Glasgow Haskell Compiler / GHC
Commits:
9a7ea5b5 by mangoiv at 2026-06-23T11:56:29+02:00
compiler: refactor error reporting code for ExplicitLevelImports
Refactors error reporting code for ExplicitLevelImports to pass in a
RdrName and a GlobalReaderElt to be able to report errors that are
faithful to the source and to more precisely distinguish between names
that are in scope from different qualifications.
Fixes #27385 and #26616
- - - - -
53 changed files:
- + changelog.d/26616
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Rename/Splice.hs-boot
- compiler/GHC/Rename/Unbound.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Name/Reader.hs
- testsuite/tests/quotes/LiftErrMsg.stderr
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/quotes/LiftErrMsgTyped.stderr
- testsuite/tests/splice-imports/SI03.stderr
- testsuite/tests/splice-imports/SI05.stderr
- testsuite/tests/splice-imports/SI08.stderr
- testsuite/tests/splice-imports/SI08_oneshot.stderr
- testsuite/tests/splice-imports/SI16.stderr
- testsuite/tests/splice-imports/SI18.stderr
- testsuite/tests/splice-imports/SI20.stderr
- testsuite/tests/splice-imports/SI25.stderr
- testsuite/tests/splice-imports/SI28.stderr
- testsuite/tests/splice-imports/SI29.stderr
- testsuite/tests/splice-imports/SI31.stderr
- testsuite/tests/splice-imports/SI36.stderr
- testsuite/tests/splice-imports/T26088.stderr
- testsuite/tests/splice-imports/T26090.stderr
- + testsuite/tests/splice-imports/T26616.hs
- + testsuite/tests/splice-imports/T26616.stderr
- testsuite/tests/splice-imports/all.T
- testsuite/tests/th/T16976z.stderr
- testsuite/tests/th/T17820a.stderr
- testsuite/tests/th/T17820b.stderr
- testsuite/tests/th/T17820c.stderr
- testsuite/tests/th/T17820d.stderr
- testsuite/tests/th/T17820e.stderr
- testsuite/tests/th/T21547.stderr
- testsuite/tests/th/T23829_hasty.stderr
- testsuite/tests/th/T23829_hasty_b.stderr
- testsuite/tests/th/T23829_tardy.ghc.stderr
- testsuite/tests/th/T26098_local.stderr
- testsuite/tests/th/T26098_quote.stderr
- testsuite/tests/th/T26098_splice.stderr
- testsuite/tests/th/T26099.stderr
- testsuite/tests/th/T26568.stderr
- testsuite/tests/th/T5795.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9a7ea5b53f65f6b72aeb1814dbce649…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9a7ea5b53f65f6b72aeb1814dbce649…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/mangoiv/unused-type] compiler: rename ZonkAny to UnusedType and add pretty printing logic
by Magnus (@MangoIV) 23 Jun '26
by Magnus (@MangoIV) 23 Jun '26
23 Jun '26
Magnus pushed to branch wip/mangoiv/unused-type at Glasgow Haskell Compiler / GHC
Commits:
aedfa343 by mangoiv at 2026-06-23T10:58:01+02:00
compiler: rename ZonkAny to UnusedType and add pretty printing logic
ZonkAny is a hard to understand name for users who do not know how the
compiler works internally. Additionally, it is confusing that ZonkAny,
while being a concrete type *represents* a meta variable, espeically in
the compiler output.
This patch changes the name of ZonkAny to UnusedType which is closer to
its intended semantics and adds special pretty printing logic to display
this type in the same fashion the compiler displays meta variables in
other places, whenever they leak from the implementation to the user.
It also exports the type from ghc-internal:GHC.Internal.Types in order
to expose documentation.
Fixes #27390
Co-Authored-By: Sam Derbyshire <sam.derbyshire(a)gmail.com>
- - - - -
29 changed files:
- + changelog.d/unused-type
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- libraries/ghc-internal/src/GHC/Internal/Types.hs
- 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/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/perf/compiler/T11068.stdout
- testsuite/tests/pmcheck/should_compile/T12957.stderr
- testsuite/tests/profiling/should_run/staticcallstack002.stdout
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T13156.stdout
- testsuite/tests/simplCore/should_compile/T26615.stderr
- testsuite/tests/typecheck/should_fail/T13292.stderr
- + testsuite/tests/typecheck/should_fail/T27390-explicit-kinds.stderr
- + testsuite/tests/typecheck/should_fail/T27390.hs
- + testsuite/tests/typecheck/should_fail/T27390.stderr
- + testsuite/tests/typecheck/should_fail/T27390a.hs
- testsuite/tests/typecheck/should_fail/all.T
Changes:
=====================================
changelog.d/unused-type
=====================================
@@ -0,0 +1,12 @@
+section: compiler
+synopsis: Rename ZonkAny to UnusedType and add pretty printing logic for it.
+issues: #27390
+mrs: !16212
+
+description: {
+ After unification, GHC fills in unconstrained type variables such as ``alpha`` in
+ ``(length :: [alpha] -> Int) ([] :: List alpha) :: Int`` with a fixed type.
+ This type was, confusingly to the user, called ``ZonkAny``.
+ This type is now renamed ``UnusedType``, with special pretty-printing logic to make
+ it display like an ordinary metavariable.
+}
=====================================
compiler/GHC/Builtin/Names.hs
=====================================
@@ -1904,8 +1904,8 @@ unsatisfiableClassNameKey = mkPreludeTyConUnique 170
anyTyConKey :: Unique
anyTyConKey = mkPreludeTyConUnique 171
-zonkAnyTyConKey :: Unique
-zonkAnyTyConKey = mkPreludeTyConUnique 172
+unusedTypeTyConKey :: Unique
+unusedTypeTyConKey = mkPreludeTyConUnique 172
-- Custom user type-errors
errorMessageTypeErrorFamKey :: Unique
=====================================
compiler/GHC/Builtin/Types.hs
=====================================
@@ -93,7 +93,7 @@ module GHC.Builtin.Types (
cTupleSelId, cTupleSelIdName,
-- * Any
- anyTyCon, anyTy, anyTypeOfKind, zonkAnyTyCon,
+ anyTyCon, anyTy, anyTypeOfKind, unusedTypeTyCon,
-- * Recovery TyCon
makeRecoveryTyCon,
@@ -300,7 +300,7 @@ wiredInTyCons :: [TyCon]
wiredInTyCons = map (dataConTyCon . snd) boxingDataCons
++ [ anyTyCon
- , zonkAnyTyCon
+ , unusedTypeTyCon
, boolTyCon
, charTyCon
, stringTyCon
@@ -410,58 +410,89 @@ doubleDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "D#")
-- Any
{-
-Note [Any types]
-~~~~~~~~~~~~~~~~
-The type constructors `Any` and `ZonkAny` are closed type families declared thus:
+Note [The types Any and UnusedType]
+~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
+The type constructors `Any` and `UnusedType` are closed type families declared as:
- type family Any :: forall k. k where { }
- type family ZonkAny :: forall k. Nat -> k where { }
+ type family Any :: forall k. k where { }
+ type family UnusedType :: forall k. Symbol -> k where { }
They are used when we want a type of a particular kind, but we don't really care
-what that type is. The leading example is this: `ZonkAny` is used to instantiate
-un-constrained type variables after type checking. For example, consider the
-term (length [] :: Int), where
+what that type is. The leading example that is relevant for GHC itself is this:
- length :: forall a. [a] -> Int
- [] :: forall a. [a]
+ `UnusedType` is used to instantiate unconstrained type variables after type
+ checking. For example, consider the term (length [] :: Int), where
-We must type-apply `length` and `[]`, but to what type? It doesn't matter!
-The typechecker will end up with
+ length :: forall a. [a] -> Int
+ [] :: forall a. [a]
- length @alpha ([] @alpha)
+ We must type-apply `length` and `[]`, but to what type? It doesn't matter!
+ The typechecker will end up with
-where `alpha` is an un-constrained unification variable. The "zonking" process zaps
-that unconstrained `alpha` to an arbitrary type (ZonkAny @Type 3), where the `3` is
-arbitrary (see wrinkle (Any5) below). This is done in `GHC.Tc.Zonk.Type.commitFlexi`.
-So we end up with
+ length @alpha ([] @alpha)
- length @(ZonkAny @Type 3) ([] @(ZonkAny @Type 3))
+ where `alpha` is an unconstrained unification variable. The "zonking" process
+ zaps that unconstrained `alpha` to an arbitrary type (UnusedType @Type "a_3"),
+ where the `3` is arbitrary (see wrinkle (Any3) below) and "a" is the name string
+ of the meta variable. This is done in `GHC.Tc.Zonk.Type.commitFlexi`.
+ So we end up with
-`Any` and `ZonkAny` differ only in the presence of the `Nat` argument; see
-wrinkle (Any4).
+ length @(UnusedType @Type "a_3") ([] @(UnusedType @Type "a_3"))
-Wrinkles:
+`Any` and `UnusedType` differ only in the presence of the `Symbol` argument; see (Any6).
-(Any1) `Any` and `ZonkAny` are kind polymorphic since in some program we may
- need to use `ZonkAny` to fill in a type variable of some kind other than *
- (see #959 for examples).
-
-(Any2) They are /closed/ type families, with no instances. For example, suppose that
+(Any1) They are /closed/ type families, with no instances. For example, suppose that
with alpha :: '(k1, k2) we add a given coercion
g :: alpha ~ (Fst alpha, Snd alpha)
- and we zonked alpha = ZonkAny @(k1,k2) n. Then, if `ZonkAny` was a /data/ type,
- we'd get inconsistency because we'd have a Given equality with `ZonkAny` on one
+ and we zonked alpha = UnusedType @(k1,k2) n. Then, if `UnusedType` was a /data/ type,
+ we'd get inconsistency because we'd have a Given equality with `UnusedType` on one
side and '(,) on the other. See also #9097 and #9636.
- See #25244 for a suggestion that we instead use an /open/ type family for which
- you cannot provide instances. Probably the difference is not very important.
+ They are not /data/ types, and that's important for the code generator,
+ because the code gen may enter a data value.
+
+ A closed type family with no equations behaves differently than an open type
+ family with no equations due to Note [Insoluble fundeps] IFD0 in
+ GHC.Tc.Solver.FunDeps, so it was argued in #25244 that perhaps 'Any' should
+ rather be an open type family for which new equations cannot be written.
+
+(Any2) `Any` and `UnusedType` are kind polymorphic since in some programs we may
+ need to use `UnusedType` to fill in a type variable of some kind other than Type
+ e.g. TYPE r for some r, or types of the form _ -> Type.
+
+(Any3) `Any` and `UnusedType` are wired-in so we can easily refer to them where we
+ don't have a name environment.
+
+(Any4) User facing aspects of the types Any and UnusedType:
+
+ `Any` is defined in ghc-internal:GHC.Internal.Types, and exported. `Any`
+ is available to users because it is a useful type in userspace and is thus
+ re-exported from base:GHC.Exts.
+
+ `UnusedType` is exported mainly for documentation in case a user stumbles over
+ it in debug output of GHC.
+
+ The key property of 'Any' is that it is safe to coerce a type to 'Any' as long
+ as the representation is unchanged. That is, it is OK to use 'unsafeCoerce#' to
+ go from 'ty :: TYPE r' to 'Any :: TYPE r' and back.
+ This can be useful when e.g. implementing dependent maps or similar typed
+ container types, storing values of type `Any`.
+
+(Any5) Warnings about unused bindings of type `Any` and `UnusedType` are suppressed,
+ following the same rationale of supressing warning about the unit type.
+
+ For example, consider (#25895):
+
+ do { forever (return ()); blah }
-(Any3) They do not claim to be /data/ types, and that's important for
- the code generator, because the code gen may /enter/ a data value
- but never enters a function value.
+ where forever :: forall a b. IO a -> IO b
+ Nothing constrains `b`, so it will be instantiated with `Any` or `UnusedType`.
+ But we certainly don't want to complain about a discarded do-binding.
-(Any4) `ZonkAny` takes a `Nat` argument so that we can readily make up /distinct/
- types (#24817). Consider
+(Any6) Wrinkle - Pattern match checking.
+
+ The first reason why `UnusedType` takes a `Symbol` argument is that
+ we can readily make up /distinct/ types (#24817) for the Pmc. Consider
data SBool a where { STrue :: SBool True; SFalse :: SBool False }
@@ -475,53 +506,33 @@ Wrinkles:
Now, what are `alpha` and `beta`? If we zonk both of them to the same type
`Any @Type`, the pattern-match checker will (wrongly) report that the first
branch is inaccessible. So we zonk them to two /different/ types:
- alpha := ZonkAny @Type 4 and beta := ZonkAny @Type k 5
+ alpha := UnusedType @Type "a_4" and beta := UnusedType @Type k "b_5"
(The actual numbers are arbitrary; they just need to differ.)
The unique-name generation comes from field `tcg_zany_n` of `TcGblEnv`; and
- `GHC.Tc.Zonk.Type.commitFlexi` calls `GHC.Tc.Utils.Monad.newZonkAnyType` to
+ `GHC.Tc.Zonk.Type.commitFlexi` calls `GHC.Tc.Utils.Monad.newUnusedTypeType` to
make up a fresh type.
If this example seems unconvincing (e.g. in this case foo must be bottom)
see #24817 for larger but more compelling examples.
-(Any5) `Any` and `ZonkAny` are wired-in so we can easily refer to it where we
- don't have a name environment (e.g. see Rules.matchRule for one example)
-
-(Any6) `Any` is defined in library module ghc-prim:GHC.Types, and exported so that
- it is available to users. For this reason it's treated like any other
- wired-in type:
- - has a fixed unique, anyTyConKey,
- - lives in the global name cache
- Currently `ZonkAny` is not available to users; but it could easily be.
+(Any7) Wrinkle - Error reporting.
-(Any7) Properties of `Any`:
- * When `Any` is instantiated at a lifted type it is inhabited by at least one value,
- namely bottom.
+ There's a second reason why `UnusedType` takes a `Symbol` argument, which is that
+ we use it to neatly display zonked unfilled metavariables without leaking
+ implementation details of code generation.
- * You can safely coerce any /lifted/ type to `Any` and back with `unsafeCoerce`.
+ `UnusedType` is handled specially in the pretty-printer to avoid confusing
+ compiler output. For example, `UnusedType "foo_3" :: Type` is displayed as `foo_3`.
- * You can safely coerce any /unlifted/ type to `Any` and back with `unsafeCoerceUnlifted`.
+ That special handling is implemented in GHC.Iface.Type.pprTyTcApp and more
+ specifically ppr_iface_unused_ty_tycon.
- * You can coerce /any/ type to `Any` and back with `unsafeCoerce#`, but it's only safe when
- the kinds of both the type and `Any` match.
+ See testcase T27390 for an example of the pretty-printing in action.
- * For lifted/unlifted types `unsafeCoerce[Unlifted]` should be preferred over
- `unsafeCoerce#` as they prevent accidentally coercing between types with kinds
- that don't match.
-
- See examples in ghc-prim:GHC.Types
-
-(Any8) Warning about unused bindings of type `Any` and `ZonkAny` are suppressed,
- following the same rationale of supressing warning about the unit type.
-
- For example, consider (#25895):
-
- do { forever (return ()); blah }
-
- where forever :: forall a b. IO a -> IO b
- Nothing constrains `b`, so it will be instantiates with `Any` or `ZonkAny`.
- But we certainly don't want to complain about a discarded do-binding.
+ Historical note: in the past, `UnusedType` was called `ZonkAny` (or `Any` before that).
+ We renamed it to `UnusedType` and added this special treatment in the pretty-printer to avoid
+ confusing mentions of zonking.
The Any tycon used to be quite magic, but we have since been able to
implement it merely with an empty kind polymorphic type family. See #10886 for a
@@ -534,7 +545,7 @@ anyTyConName =
mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Any") anyTyConKey anyTyCon
anyTyCon :: TyCon
--- See Note [Any types]
+-- See Note [The types Any and UnusedType]
anyTyCon = mkFamilyTyCon anyTyConName kind binders 0 res_kind Nothing
(ClosedSynFamilyTyCon Nothing)
Nothing
@@ -550,22 +561,22 @@ anyTy = mkTyConTy anyTyCon
anyTypeOfKind :: Kind -> Type
anyTypeOfKind kind = mkTyConApp anyTyCon [kind]
-zonkAnyTyConName :: Name
-zonkAnyTyConName =
- mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "ZonkAny") zonkAnyTyConKey zonkAnyTyCon
+unusedTypeTyConName :: Name
+unusedTypeTyConName =
+ mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "UnusedType") unusedTypeTyConKey unusedTypeTyCon
-zonkAnyTyCon :: TyCon
--- ZonkAnyTyCon :: forall k. Nat -> k
--- See Note [Any types]
-zonkAnyTyCon = mkFamilyTyCon zonkAnyTyConName kind bndrs 0 res_kind
+unusedTypeTyCon :: TyCon
+-- unusedTypeTyCon :: forall k. Symbol -> k
+-- See Note [The types Any and UnusedType]
+unusedTypeTyCon = mkFamilyTyCon unusedTypeTyConName kind bndrs 0 res_kind
Nothing
(ClosedSynFamilyTyCon Nothing)
Nothing
NotInjective
where
- [kv,nat_kv] = mkTemplateKindVars [liftedTypeKind, naturalTy]
+ [kv,sym_kv] = mkTemplateKindVars [liftedTypeKind, typeSymbolKind]
bndrs = [ mkNamedTyConBinder Specified kv
- , mkAnonTyConBinder nat_kv ]
+ , mkAnonTyConBinder sym_kv ]
res_kind = mkTyVarTy kv
kind = mkTyConKind bndrs res_kind
=====================================
compiler/GHC/HsToCore/Expr.hs
=====================================
@@ -1281,11 +1281,11 @@ warnDiscardedDoBindings rhs@(L rhs_loc _) m_ty elt_ty
do { fam_inst_envs <- dsGetFamInstEnvs
; let norm_elt_ty = topNormaliseType fam_inst_envs elt_ty
supressible_ty =
- isUnitTy norm_elt_ty || isAnyTy norm_elt_ty || isZonkAnyTy norm_elt_ty
+ isUnitTy norm_elt_ty || isAnyTy norm_elt_ty || isUnusedTypeTy norm_elt_ty
-- Warn about discarding things in 'monadic' binding,
-- however few types are excluded:
-- * Unit type `()`
- -- * `ZonkAny` or `Any` type see (Any8) of Note [Any types]
+ -- * `UnusedType` or `Any` type see (Any5) of Note [The types Any and UnusedType]
; if warn_unused && not supressible_ty
then diagnosticDs (DsUnusedDoBind rhs elt_ty)
else
=====================================
compiler/GHC/Iface/Type.hs
=====================================
@@ -7,7 +7,7 @@ This module defines interface types and binders
-}
-{-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE MultiWayIf, OverloadedRecordDot #-}
module GHC.Iface.Type (
IfExtName,
IfLclName(..), mkIfLclName, ifLclNameFS,
@@ -1740,6 +1740,7 @@ pprTyTcApp ctxt_prec tc tys =
sdocOption sdocPrintExplicitKinds $ \print_kinds ->
sdocOption sdocPrintTypeAbbreviations $ \print_type_abbreviations ->
getPprDebug $ \debug ->
+ getPprStyle $ \style ->
if | ifaceTyConName tc `hasKey` ipClassKey
, IA_Arg (IfaceLitTy (IfaceStrTyLit n))
@@ -1791,6 +1792,14 @@ pprTyTcApp ctxt_prec tc tys =
| Just doc <- ppr_equality ctxt_prec tc (appArgsIfaceTypes tys)
-> doc
+ -- See Note [The types Any and UnusedType], specifically (Any6) and (Any7)
+ | ifaceTyConName tc `hasKey` unusedTypeTyConKey
+ , ((arg_k, _) : (IfaceLitTy (IfaceStrTyLit arg_nm), _) : args_usr)
+ <- appArgsIfaceTypesForAllTyFlags tys
+ -- if arg_k is a kind with more than 0 arguments, then _ might not be [] here
+ , userStyle style
+ -> ppr_iface_unused_ty_tycon ctxt_prec arg_k arg_nm args_usr
+
| otherwise
-> ppr_iface_tc_app ppr_app_arg ctxt_prec tc $
appArgsIfaceTypesForAllTyFlags $ stripInvisArgs (PrintExplicitKinds print_kinds) tys
@@ -1802,6 +1811,23 @@ ppr_kind_type ctxt_prec = sdocOption sdocStarIsType $ \case
False -> pprPrefixOcc liftedTypeKindTyConName
True -> maybeParen ctxt_prec starPrec starLit
+-- | user-style printer that pretty-prints an 'UnusedType @k "foo_3" to foo_3.
+-- If -fprint-explicit-kinds or -fprint-explicit-runtime-reps are set, instead
+-- prints them to (foo3 :: k).
+-- See Note [The types Any and UnusedType], specifically (Any6) and (Any7) for why this is useful.
+ppr_iface_unused_ty_tycon :: PprPrec -> IfaceType -> LexicalFastString -> [(IfaceType, ForAllTyFlag)] -> SDoc
+ppr_iface_unused_ty_tycon ctxt_prec arg_k arg_nm args_usr
+ = sdocOption sdocPrintExplicitKinds $ \print_kinds ->
+ sdocOption sdocPrintExplicitRuntimeReps $ \print_reps ->
+ if print_kinds || print_reps
+ then prettyMeta $ \nm ->
+ maybeParen sig_prec sigPrec $ nm <+> text "::" <+> pprIfaceType arg_k
+ else prettyMeta id
+ where sig_prec = if null args_usr then ctxt_prec else appPrec
+ prettyMeta add_ty
+ = pprIfacePrefixApp ctxt_prec (add_ty $ ppr arg_nm)
+ $ map (ppr_app_arg appPrec) args_usr
+
-- | Pretty-print a type-level equality.
-- Returns (Just doc) if the argument is a /saturated/ application
-- of eqTyCon (~)
@@ -2190,7 +2216,8 @@ instance Binary IfaceTyConSort where
0 -> return IfaceNormalTyCon
1 -> IfaceTupleTyCon <$> get bh <*> get bh
2 -> IfaceSumTyCon <$> get bh
- _ -> return IfaceEqualityTyCon
+ 3 -> return IfaceEqualityTyCon
+ _ -> panic "get IfaceTyConSort"
instance Binary IfaceTyConInfo where
put_ bh (IfaceTyConInfo i s) = put_ bh i >> put_ bh s
=====================================
compiler/GHC/Tc/Types.hs
=====================================
@@ -582,8 +582,8 @@ data TcGblEnv
-- ^ Allows us to choose unique DFun names.
tcg_zany_n :: TcRef Integer,
- -- ^ A source of unique identities for ZonkAny instances
- -- See Note [Any types] in GHC.Builtin.Types, wrinkle (Any4)
+ -- ^ A source of unique identities for UnusedType instances
+ -- See Note [The types Any and UnusedType] in GHC.Builtin.Types, wrinkle (Any6)
tcg_merged :: [(Module, Fingerprint)],
-- ^ The requirements we merged with; we always have to recompile
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -154,7 +154,7 @@ module GHC.Tc.Utils.Monad(
getCCIndexM, getCCIndexTcM,
-- * Zonking
- liftZonkM, newZonkAnyType,
+ liftZonkM, newUnusedType,
-- * Complete matches
localAndImportedCompleteMatches, getCompleteMatchesTcM,
@@ -168,7 +168,7 @@ import GHC.Prelude
import GHC.Builtin.Names
-import GHC.Builtin.Types( zonkAnyTyCon )
+import GHC.Builtin.Types( unusedTypeTyCon )
import GHC.Tc.Errors.Types
import GHC.Tc.Errors.Hole.Plugin ( HoleFitPlugin, HoleFitPluginR (..) )
@@ -197,7 +197,7 @@ import GHC.Core.Coercion ( isReflCo )
import GHC.Core.Multiplicity
import GHC.Core.InstEnv
import GHC.Core.FamInstEnv
-import GHC.Core.Type( mkNumLitTy )
+import GHC.Core.Type( mkStrLitTy )
import GHC.Core.TyCo.Rep( CoercionHole(..) )
import GHC.Core.TyCo.FVs( coVarsOfCo )
import GHC.Core.TyCon ( TyCon )
@@ -2258,17 +2258,24 @@ chooseUniqueOccTc fn =
; writeTcRef dfun_n_var (extendOccSet set occ)
; return occ }
-newZonkAnyType :: Kind -> TcM Type
--- Return a type (ZonkAny @k n), where n is fresh
--- Recall ZonkAny :: forall k. Natural -> k
--- See Note [Any types] in GHC.Builtin.Types, wrinkle (Any4)
-newZonkAnyType kind
+newUnusedType :: Name -> Kind -> TcM Type
+-- Return a type (UnusedType @k sym_n), where sym
+-- is a name and n is a fresh Integer.
+-- Recall UnusedType :: forall k. Symbol -> k
+-- See Note [The types Any and UnusedType] in GHC.Builtin.Types, wrinkle (Any6)
+newUnusedType name kind
= do { env <- getGblEnv
; let zany_n_var = tcg_zany_n env
; i <- readTcRef zany_n_var
; let !i2 = i+1
; writeTcRef zany_n_var i2
- ; return (mkTyConApp zonkAnyTyCon [kind, mkNumLitTy i]) }
+ -- Mind that the "_" here is load-bearing:
+ -- name foo1 with zany_n_var = 1 musn't be equal to
+ -- name foo with zany_n_var = 11 b/c that way the Pmc
+ -- would consider them equal. Using "_" suffices because
+ -- numbers never start with _ and so (legal) identfiers like
+ -- foo_ would become foo__1 which is distinct from e.g. foo_1
+ ; return (mkTyConApp unusedTypeTyCon [kind, mkStrLitTy $ getOccFS name `appendFS` fsLit "_" `appendFS` fsLit (show i) ]) }
getConstraintVar :: TcM (TcRef WantedConstraints)
getConstraintVar = do { env <- getLclEnv; return (tcl_lie env) }
=====================================
compiler/GHC/Tc/Utils/TcType.hs
=====================================
@@ -85,7 +85,7 @@ module GHC.Tc.Utils.TcType (
isSigmaTy, isRhoTy, isRhoExpTy, isOverloadedTy,
isFloatingPrimTy, isDoubleTy, isFloatTy, isIntTy, isWordTy, isStringTy,
isIntegerTy, isNaturalTy,
- isBoolTy, isUnitTy, isAnyTy, isZonkAnyTy, isCharTy,
+ isBoolTy, isUnitTy, isAnyTy, isUnusedTypeTy, isCharTy,
isTauTy, isTauTyCon, tcIsTyVarTy,
isPredTy, isSimplePredTy, isTyVarClassPred,
checkValidClsArgs, hasTyVarHead,
@@ -2057,7 +2057,7 @@ isFloatTy, isDoubleTy,
isFloatPrimTy, isDoublePrimTy,
isIntegerTy, isNaturalTy,
isIntTy, isWordTy, isBoolTy,
- isUnitTy, isAnyTy, isZonkAnyTy, isCharTy :: Type -> Bool
+ isUnitTy, isAnyTy, isUnusedTypeTy, isCharTy :: Type -> Bool
isFloatTy = is_tc floatTyConKey
isDoubleTy = is_tc doubleTyConKey
isFloatPrimTy = is_tc floatPrimTyConKey
@@ -2069,7 +2069,7 @@ isWordTy = is_tc wordTyConKey
isBoolTy = is_tc boolTyConKey
isUnitTy = is_tc unitTyConKey
isAnyTy = is_tc anyTyConKey
-isZonkAnyTy = is_tc zonkAnyTyConKey
+isUnusedTypeTy = is_tc unusedTypeTyConKey
isCharTy = is_tc charTyConKey
-- | Check whether the type is of the form @Any :: k@,
=====================================
compiler/GHC/Tc/Zonk/Type.hs
=====================================
@@ -1,3 +1,4 @@
+{-# LANGUAGE OverloadedRecordDot #-}
{-
(c) The University of Glasgow 2006
(c) The AQUA Project, Glasgow University, 1996-1998
@@ -43,7 +44,7 @@ import GHC.Tc.Types.TcRef
import GHC.Tc.TyCl.Build ( TcMethInfo, MethInfo )
import GHC.Tc.Utils.Env ( tcLookupGlobalOnly )
import GHC.Tc.Utils.TcType
-import GHC.Tc.Utils.Monad ( newZonkAnyType, setSrcSpanA, liftZonkM, traceTc, addErr )
+import GHC.Tc.Utils.Monad ( newUnusedType, setSrcSpanA, liftZonkM, traceTc, addErr )
import GHC.Tc.Types.Evidence
import GHC.Tc.Errors.Types
import GHC.Tc.Zonk.Env
@@ -470,11 +471,11 @@ commitFlexi DefaultFlexi tv zonked_kind
; return manyDataConTy }
| Just (ConcreteFRR origin) <- isConcreteTyVar_maybe tv
= do { addErr $ TcRnZonkerMessage (ZonkerCannotDefaultConcrete origin)
- ; newZonkAnyType zonked_kind }
+ ; newUnusedType tv.varName zonked_kind }
| otherwise
- = do { traceTc "Defaulting flexi tyvar to ZonkAny:" (pprTyVar tv)
- -- See Note [Any types] in GHC.Builtin.Types, esp wrinkle (Any4)
- ; newZonkAnyType zonked_kind }
+ = do { traceTc "Defaulting flexi tyvar to UnusedType:" (pprTyVar tv)
+ -- See Note [The types Any and UnusedType] in GHC.Builtin.Types, esp wrinkle (Any6)
+ ; newUnusedType tv.varName zonked_kind }
zonkCoVarOcc :: CoVar -> ZonkTcM Coercion
zonkCoVarOcc cv
=====================================
libraries/ghc-internal/src/GHC/Internal/Types.hs
=====================================
@@ -35,6 +35,7 @@ module GHC.Internal.Types (
SPEC(..),
Symbol,
Any,
+ UnusedType,
-- * Type equality
type (~), type (~~), Coercible,
@@ -284,48 +285,53 @@ data Symbol
* *
********************************************************************* -}
--- | The type constructor @Any :: forall k. k@ is a type to which you can unsafely coerce any type, and back.
+-- | The type constructor @Any :: forall k. k@ allows creating an arbitrary type
+-- of the given kind.
--
--- For @unsafeCoerce@ this means for all lifted types @t@ that
--- @unsafeCoerce (unsafeCoerce x :: Any) :: t@ is equivalent to @x@ and safe.
+-- It can be used to create a placeholder type when you only have a kind in hand.
--
--- The same is true for *all* types when using
--- @
--- unsafeCoerce# :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
--- (a :: TYPE r1) (b :: TYPE r2).
--- a -> b
--- @
--- but /only/ if you instantiate @r1@ and @r2@ to the /same/ runtime representation.
--- For example using @(unsafeCoerce# :: forall (a :: TYPE IntRep) (b :: TYPE IntRep). a -> b) x@
--- is fine, but @(unsafeCoerce# :: forall (a :: TYPE IntRep) (b :: TYPE FloatRep). a -> b)@
--- will likely cause seg-faults or worse.
--- For this resason, users should always prefer unsafeCoerce over unsafeCoerce# when possible.
+-- You can use 'unsafeCoerce#' to unsafely coerce a value from @ty :: k@ to @Any \@k@
+-- and back. As per the documentation of 'unsafeCoerce#', this is only sound if both
+-- sides have the __exact same__runtime representation. Some examples:
--
--- Here are some more examples:
-- @
--- bad_a1 :: Any @(TYPE 'IntRep)
--- bad_a1 = unsafeCoerce# True
---
--- bad_a2 :: Any @(TYPE ('BoxedRep 'UnliftedRep))
--- bad_a2 = unsafeCoerce# True
+-- unsafeCoerce# True :: (Any :: Type) -- OK
+-- unsafeCoerce# (1# :: Int#) :: (Any :: TYPE IntRep) -- OK
+-- unsafeCoerce# True :: (Any :: Type IntRep) -- INVALID
+-- unsafeCoerce True :: (Any :: UnliftedType) -- INVALID
+-- unsafeCoerce (ba :: ByteArray#) :: (Any :: Type) -- INVALID
-- @
--- Here @bad_a1@ is bad because we started with @True :: (Bool :: Type)@, represented by a boxed heap pointer,
--- and coerced it to @a1 :: Any @(TYPE 'IntRep)@, whose representation is a non-pointer integer.
--- That's why we had to use `unsafeCoerce#`; it is really unsafe because it can change representations.
--- Similarly @bad_a2@ is bad because although both @True@ and @bad_a2@ are represented by a heap pointer,
--- @True@ is lifted but @bad_a2@ is not; bugs here may be rather subtle.
--
--- If you must use unsafeCoerce# to cast to `Any`, type annotations are recommended
--- to make sure that @Any@ has the correct kind. As casting between different runtimereps is
--- unsound. For example to cast a @ByteArray#@ to @Any@ you might use:
--- @
--- unsafeCoerce# b :: (Any :: TYPE ('BoxedRep 'Unlifted))
--- @
+-- To avoid accidentally unsafe-coercing between different representations,
+-- it is recommended to:
+-- - use explicit type annotations or type applications at every use-site
+-- of 'unsafeCoerce#'
+-- - use representation-monomorphic variants such as 'unsafeCoerce' or
+-- 'unsafeCoerceUnlifted'.
+--
+-- In particular, this also implies it is safe to round-trip unsafe-coercion via 'Any',
+-- as long as the kinds line up e.g. @unsafeCoerce (unsafeCoerce (val :: a) :: 'Any') :: a@
+-- is safe in that way.
type family Any :: k where { }
--- See Note [Any types] in GHC.Builtin.Types. Also, for a bit of history on Any see
+-- See Note [The types Any and UnusedType] in GHC.Builtin.Types. Also, for a bit of history on Any see
-- #10886. Note that this must be a *closed* type family: we need to ensure
-- that this can't reduce to a `data` type for the results discussed in
--- Note [Any types].
+-- Note [The types Any and UnusedType].
+--
+
+-- | @UnusedType \@k "foo"@ denotes an arbitrary type of kind
+-- @k@ and is pretty-printed as @foo@ .
+--
+-- This type is used internally by GHC to fill in otherwise
+-- unconstrained type variables, such as @a@ in @length \@a []@.
+-- It is exported purely for documentation purposes.
+--
+-- You shouldn't ever see this type in the compiler's output if
+-- you don't specifically ask for it, for instance when viewing
+-- core, since the compiler will try hard to output a given
+-- @'UnusedType' "m_0"@ simply as @m_0@.
+type family UnusedType :: Symbol -> k where { }
+-- See Note [The types Any and UnusedType] in GHC.Builtin.Types.
{- *********************************************************************
* *
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -3489,6 +3489,8 @@ module GHC.Base where
type UnliftedRep = BoxedRep Unlifted
type UnliftedType :: *
type UnliftedType = TYPE UnliftedRep
+ type UnusedType :: forall k0. Symbol -> k0
+ type family UnusedType k1 where
type VecCount :: *
data VecCount = Vec2 | Vec4 | Vec8 | Vec16 | Vec32 | Vec64
type VecElem :: *
@@ -5620,6 +5622,8 @@ module GHC.Exts where
type UnliftedRep = BoxedRep Unlifted
type UnliftedType :: *
type UnliftedType = TYPE UnliftedRep
+ type UnusedType :: forall k0. Symbol -> k0
+ type family UnusedType k1 where
type VecCount :: *
data VecCount = Vec2 | Vec4 | Vec8 | Vec16 | Vec32 | Vec64
type VecElem :: *
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -3489,6 +3489,8 @@ module GHC.Base where
type UnliftedRep = BoxedRep Unlifted
type UnliftedType :: *
type UnliftedType = TYPE UnliftedRep
+ type UnusedType :: forall k0. Symbol -> k0
+ type family UnusedType k1 where
type VecCount :: *
data VecCount = Vec2 | Vec4 | Vec8 | Vec16 | Vec32 | Vec64
type VecElem :: *
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -3489,6 +3489,8 @@ module GHC.Base where
type UnliftedRep = BoxedRep Unlifted
type UnliftedType :: *
type UnliftedType = TYPE UnliftedRep
+ type UnusedType :: forall k0. Symbol -> k0
+ type family UnusedType k1 where
type VecCount :: *
data VecCount = Vec2 | Vec4 | Vec8 | Vec16 | Vec32 | Vec64
type VecElem :: *
=====================================
testsuite/tests/interface-stability/ghc-experimental-exports.stdout
=====================================
@@ -6083,6 +6083,8 @@ module GHC.PrimOps where
type UnliftedRep = BoxedRep Unlifted
type UnliftedType :: *
type UnliftedType = TYPE UnliftedRep
+ type UnusedType :: forall k0. Symbol -> k0
+ type family UnusedType k1 where
type VecCount :: *
data VecCount = Vec2 | Vec4 | Vec8 | Vec16 | Vec32 | Vec64
type VecElem :: *
=====================================
testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
=====================================
@@ -6083,6 +6083,8 @@ module GHC.PrimOps where
type UnliftedRep = BoxedRep Unlifted
type UnliftedType :: *
type UnliftedType = TYPE UnliftedRep
+ type UnusedType :: forall k0. Symbol -> k0
+ type family UnusedType k1 where
type VecCount :: *
data VecCount = Vec2 | Vec4 | Vec8 | Vec16 | Vec32 | Vec64
type VecElem :: *
=====================================
testsuite/tests/interface-stability/ghc-prim-exports.stdout
=====================================
@@ -6975,6 +6975,8 @@ module GHC.Types where
type UnliftedRep = BoxedRep Unlifted
type UnliftedType :: *
type UnliftedType = TYPE UnliftedRep
+ type UnusedType :: forall k0. Symbol -> k0
+ type family UnusedType k1 where
type VecCount :: *
data VecCount = Vec2 | Vec4 | Vec8 | Vec16 | Vec32 | Vec64
type VecElem :: *
=====================================
testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
=====================================
@@ -6978,6 +6978,8 @@ module GHC.Types where
type UnliftedRep = BoxedRep Unlifted
type UnliftedType :: *
type UnliftedType = TYPE UnliftedRep
+ type UnusedType :: forall k0. Symbol -> k0
+ type family UnusedType k1 where
type VecCount :: *
data VecCount = Vec2 | Vec4 | Vec8 | Vec16 | Vec32 | Vec64
type VecElem :: *
=====================================
testsuite/tests/perf/compiler/T11068.stdout
=====================================
@@ -23,137 +23,137 @@
`cast` (GHC.Internal.Generics.N:M1
`cast` (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.L1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
- ((GHC.Internal.Generics.U1 @(*) @(GHC.Internal.Types.ZonkAny 0))
+ ((GHC.Internal.Generics.U1
`cast` (Sym (GHC.Internal.Generics.N:M1
= GHC.Internal.Generics.R1
= GHC.Internal.Generics.R1
=====================================
testsuite/tests/pmcheck/should_compile/T12957.stderr
=====================================
@@ -1,7 +1,6 @@
T12957.hs:4:5: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
Pattern match(es) are non-exhaustive
- In a case alternative:
- Patterns of type ‘[GHC.Internal.Types.ZonkAny 0]’ not matched: []
+ In a case alternative: Patterns of type ‘[a_0]’ not matched: []
T12957.hs:4:16: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
Pattern match is redundant
=====================================
testsuite/tests/profiling/should_run/staticcallstack002.stdout
=====================================
@@ -1,4 +1,4 @@
-Just (InfoProv {ipName = "sat_s1Rh_info", ipDesc = THUNK, ipTyDesc = "ZonkAny 0", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "staticcallstack002.hs", ipSrcSpan = "10:23-39"})
-Just (InfoProv {ipName = "sat_s1RB_info", ipDesc = THUNK, ipTyDesc = "ZonkAny 1", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "staticcallstack002.hs", ipSrcSpan = "11:23-42"})
-Just (InfoProv {ipName = "sat_s1RV_info", ipDesc = THUNK, ipTyDesc = "ZonkAny 2", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "staticcallstack002.hs", ipSrcSpan = "12:23-46"})
-Just (InfoProv {ipName = "sat_s1Sf_info", ipDesc = THUNK, ipTyDesc = "ZonkAny 3", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "staticcallstack002.hs", ipSrcSpan = "13:23-44"})
+Just (InfoProv {ipName = "main_sat_t2fs_info", ipDesc = THUNK, ipTyDesc = "UnusedType \"a_0\"", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "staticcallstack002.hs", ipSrcSpan = "10:23-39"})
+Just (InfoProv {ipName = "main_sat_t2fJ_info", ipDesc = THUNK, ipTyDesc = "UnusedType \"a_1\"", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "staticcallstack002.hs", ipSrcSpan = "11:23-42"})
+Just (InfoProv {ipName = "main_sat_t2g0_info", ipDesc = THUNK, ipTyDesc = "UnusedType \"a_2\"", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "staticcallstack002.hs", ipSrcSpan = "12:23-46"})
+Just (InfoProv {ipName = "main_sat_t2gh_info", ipDesc = THUNK, ipTyDesc = "UnusedType \"a_3\"", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "staticcallstack002.hs", ipSrcSpan = "13:23-44"})
=====================================
testsuite/tests/simplCore/should_compile/Makefile
=====================================
@@ -188,7 +188,7 @@ T13155:
T13156:
$(RM) -f T13156.hi T13156.o
- '$(TEST_HC)' $(TEST_HC_OPTS) -c T13156.hs -O -ddump-prep -dsuppress-uniques | grep "case.*Any"
+ '$(TEST_HC)' $(TEST_HC_OPTS) -c T13156.hs -O -ddump-prep -dsuppress-uniques | grep "case.*UnusedType"
# There should be a single 'case r @ GHC.Types.Any'
.PHONY: T4138
=====================================
testsuite/tests/simplCore/should_compile/T13156.stdout
=====================================
@@ -1,2 +1,2 @@
- case r @(GHC.Internal.Types.ZonkAny 0) of { __DEFAULT ->
- case r @(GHC.Internal.Types.ZonkAny 1) of { __DEFAULT -> r @a }
+ case r @(GHC.Internal.Types.UnusedType "a_0") of { __DEFAULT ->
+ case r @(GHC.Internal.Types.UnusedType "a_1") of { __DEFAULT ->
=====================================
testsuite/tests/simplCore/should_compile/T26615.stderr
=====================================
@@ -2,7 +2,7 @@
==================== Tidy Core ====================
Result size of Tidy Core
- = {terms: 1,209, types: 1,139, coercions: 18, joins: 17/29}
+ = {terms: 1,209, types: 1,155, coercions: 18, joins: 17/29}
-- RHS size: {terms: 6, types: 8, coercions: 0, joins: 0/0}
unArray :: forall a. Array a -> SmallArray# a
@@ -15,45 +15,29 @@ unArray :: forall a. Array a -> SmallArray# a
unArray = \ (@a) (ds :: Array a) -> case ds of { Array ds1 -> ds1 }
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$trModule4 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 20 0}]
-T26615a.$trModule4 = "main"#
+$trModule1 :: Addr#
+[GblId, Unf=OtherCon []]
+$trModule1 = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$trModule3 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$trModule3 = GHC.Internal.Types.TrNameS T26615a.$trModule4
+$trModule2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$trModule2 = GHC.Internal.Types.TrNameS $trModule1
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$trModule2 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 30 0}]
-T26615a.$trModule2 = "T26615a"#
+$trModule3 :: Addr#
+[GblId, Unf=OtherCon []]
+$trModule3 = "T26615a"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$trModule1 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$trModule1 = GHC.Internal.Types.TrNameS T26615a.$trModule2
+$trModule4 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$trModule4 = GHC.Internal.Types.TrNameS $trModule3
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-T26615a.$trModule :: GHC.Internal.Types.Module
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$trModule
- = GHC.Internal.Types.Module T26615a.$trModule3 T26615a.$trModule1
+T26615a.$trModule [InlPrag=[~]] :: GHC.Internal.Types.Module
+[GblId, Unf=OtherCon []]
+T26615a.$trModule = GHC.Internal.Types.Module $trModule2 $trModule4
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
$krep :: GHC.Internal.Types.KindRep
@@ -104,33 +88,24 @@ $krep6
GHC.Internal.Types.$tcSmallArray# $krep5
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tcLeaf2 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 20 0}]
-T26615a.$tcLeaf2 = "Leaf"#
+$tcLeaf1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tcLeaf1 = "Leaf"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tcLeaf1 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tcLeaf1 = GHC.Internal.Types.TrNameS T26615a.$tcLeaf2
+$tcLeaf2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tcLeaf2 = GHC.Internal.Types.TrNameS $tcLeaf1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tcLeaf :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tcLeaf [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tcLeaf
= GHC.Internal.Types.TyCon
13798714324392902582#Word64
3237499036029031497#Word64
T26615a.$trModule
- T26615a.$tcLeaf1
+ $tcLeaf2
0#
GHC.Internal.Types.krep$*->*->*
@@ -160,372 +135,284 @@ $krep10 :: GHC.Internal.Types.KindRep
$krep10 = GHC.Internal.Types.KindRepFun $krep2 $krep9
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'L1 [InlPrag=[~]] :: GHC.Internal.Types.KindRep
+$krep11 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-T26615a.$tc'L1 = GHC.Internal.Types.KindRepFun $krep3 $krep10
+$krep11 = GHC.Internal.Types.KindRepFun $krep3 $krep10
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'L3 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 20 0}]
-T26615a.$tc'L3 = "'L"#
+$tc'L1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tc'L1 = "'L"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'L2 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tc'L2 = GHC.Internal.Types.TrNameS T26615a.$tc'L3
+$tc'L2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tc'L2 = GHC.Internal.Types.TrNameS $tc'L1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'L :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tc'L [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tc'L
= GHC.Internal.Types.TyCon
8570419491837374712#Word64
2090006989092642392#Word64
T26615a.$trModule
- T26615a.$tc'L2
+ $tc'L2
2#
- T26615a.$tc'L1
+ $krep11
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tcArray2 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 30 0}]
-T26615a.$tcArray2 = "Array"#
+$tcArray1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tcArray1 = "Array"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tcArray1 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tcArray1 = GHC.Internal.Types.TrNameS T26615a.$tcArray2
+$tcArray2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tcArray2 = GHC.Internal.Types.TrNameS $tcArray1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tcArray :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tcArray [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tcArray
= GHC.Internal.Types.TyCon
10495761415291712389#Word64
7580086293698619153#Word64
T26615a.$trModule
- T26615a.$tcArray1
+ $tcArray2
0#
GHC.Internal.Types.krep$*Arr*
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-$krep11 :: GHC.Internal.Types.KindRep
+$krep12 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-$krep11
+$krep12
= GHC.Internal.Types.KindRepTyConApp T26615a.$tcArray $krep4
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Array1 [InlPrag=[~]] :: GHC.Internal.Types.KindRep
+$krep13 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-T26615a.$tc'Array1 = GHC.Internal.Types.KindRepFun $krep6 $krep11
+$krep13 = GHC.Internal.Types.KindRepFun $krep6 $krep12
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Array3 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 30 0}]
-T26615a.$tc'Array3 = "'Array"#
+$tc'Array1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tc'Array1 = "'Array"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Array2 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tc'Array2 = GHC.Internal.Types.TrNameS T26615a.$tc'Array3
+$tc'Array2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tc'Array2 = GHC.Internal.Types.TrNameS $tc'Array1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Array :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tc'Array [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tc'Array
= GHC.Internal.Types.TyCon
12424115309881832159#Word64
15542868641947707803#Word64
T26615a.$trModule
- T26615a.$tc'Array2
+ $tc'Array2
1#
- T26615a.$tc'Array1
+ $krep13
-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0}
-$krep12 :: [GHC.Internal.Types.KindRep]
+$krep14 :: [GHC.Internal.Types.KindRep]
[GblId, Unf=OtherCon []]
-$krep12
+$krep14
= GHC.Internal.Types.:
@GHC.Internal.Types.KindRep
$krep9
(GHC.Internal.Types.[] @GHC.Internal.Types.KindRep)
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-$krep13 :: GHC.Internal.Types.KindRep
+$krep15 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-$krep13
- = GHC.Internal.Types.KindRepTyConApp T26615a.$tcArray $krep12
+$krep15
+ = GHC.Internal.Types.KindRepTyConApp T26615a.$tcArray $krep14
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tcHashMap2 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 30 0}]
-T26615a.$tcHashMap2 = "HashMap"#
+$tcHashMap1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tcHashMap1 = "HashMap"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tcHashMap1 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tcHashMap1
- = GHC.Internal.Types.TrNameS T26615a.$tcHashMap2
+$tcHashMap2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tcHashMap2 = GHC.Internal.Types.TrNameS $tcHashMap1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tcHashMap :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tcHashMap [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tcHashMap
= GHC.Internal.Types.TyCon
2021755758654901686#Word64
8209241086311595496#Word64
T26615a.$trModule
- T26615a.$tcHashMap1
+ $tcHashMap2
0#
GHC.Internal.Types.krep$*->*->*
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Empty1 [InlPrag=[~]] :: GHC.Internal.Types.KindRep
+$krep16 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-T26615a.$tc'Empty1
+$krep16
= GHC.Internal.Types.KindRepTyConApp T26615a.$tcHashMap $krep8
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Empty3 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 30 0}]
-T26615a.$tc'Empty3 = "'Empty"#
+$tc'Empty1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tc'Empty1 = "'Empty"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Empty2 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tc'Empty2 = GHC.Internal.Types.TrNameS T26615a.$tc'Empty3
+$tc'Empty2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tc'Empty2 = GHC.Internal.Types.TrNameS $tc'Empty1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Empty :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tc'Empty [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tc'Empty
= GHC.Internal.Types.TyCon
2520556399233147460#Word64
17224648764450205443#Word64
T26615a.$trModule
- T26615a.$tc'Empty2
+ $tc'Empty2
2#
- T26615a.$tc'Empty1
+ $krep16
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-$krep14 :: GHC.Internal.Types.KindRep
+$krep17 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-$krep14 = GHC.Internal.Types.KindRepFun $krep9 T26615a.$tc'Empty1
+$krep17 = GHC.Internal.Types.KindRepFun $krep9 $krep16
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Leaf1 [InlPrag=[~]] :: GHC.Internal.Types.KindRep
+$krep18 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-T26615a.$tc'Leaf1 = GHC.Internal.Types.KindRepFun $krep1 $krep14
+$krep18 = GHC.Internal.Types.KindRepFun $krep1 $krep17
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Leaf3 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 30 0}]
-T26615a.$tc'Leaf3 = "'Leaf"#
+$tc'Leaf1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tc'Leaf1 = "'Leaf"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Leaf2 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tc'Leaf2 = GHC.Internal.Types.TrNameS T26615a.$tc'Leaf3
+$tc'Leaf2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tc'Leaf2 = GHC.Internal.Types.TrNameS $tc'Leaf1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Leaf :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tc'Leaf [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tc'Leaf
= GHC.Internal.Types.TyCon
5773656560257991946#Word64
17028074687139582545#Word64
T26615a.$trModule
- T26615a.$tc'Leaf2
+ $tc'Leaf2
2#
- T26615a.$tc'Leaf1
+ $krep18
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-$krep15 :: GHC.Internal.Types.KindRep
+$krep19 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-$krep15 = GHC.Internal.Types.KindRepFun $krep13 T26615a.$tc'Empty1
+$krep19 = GHC.Internal.Types.KindRepFun $krep15 $krep16
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Collision1 [InlPrag=[~]] :: GHC.Internal.Types.KindRep
+$krep20 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-T26615a.$tc'Collision1
- = GHC.Internal.Types.KindRepFun $krep1 $krep15
+$krep20 = GHC.Internal.Types.KindRepFun $krep1 $krep19
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Collision3 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 40 0}]
-T26615a.$tc'Collision3 = "'Collision"#
+$tc'Collision1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tc'Collision1 = "'Collision"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Collision2 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tc'Collision2
- = GHC.Internal.Types.TrNameS T26615a.$tc'Collision3
+$tc'Collision2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tc'Collision2 = GHC.Internal.Types.TrNameS $tc'Collision1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Collision :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tc'Collision [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tc'Collision
= GHC.Internal.Types.TyCon
18175105753528304021#Word64
13986842878006680511#Word64
T26615a.$trModule
- T26615a.$tc'Collision2
+ $tc'Collision2
2#
- T26615a.$tc'Collision1
+ $krep20
-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0}
-$krep16 :: [GHC.Internal.Types.KindRep]
+$krep21 :: [GHC.Internal.Types.KindRep]
[GblId, Unf=OtherCon []]
-$krep16
+$krep21
= GHC.Internal.Types.:
@GHC.Internal.Types.KindRep
- T26615a.$tc'Empty1
+ $krep16
(GHC.Internal.Types.[] @GHC.Internal.Types.KindRep)
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-$krep17 :: GHC.Internal.Types.KindRep
+$krep22 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-$krep17
- = GHC.Internal.Types.KindRepTyConApp T26615a.$tcArray $krep16
+$krep22
+ = GHC.Internal.Types.KindRepTyConApp T26615a.$tcArray $krep21
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Full1 [InlPrag=[~]] :: GHC.Internal.Types.KindRep
+$krep23 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-T26615a.$tc'Full1
- = GHC.Internal.Types.KindRepFun $krep17 T26615a.$tc'Empty1
+$krep23 = GHC.Internal.Types.KindRepFun $krep22 $krep16
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Full3 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 30 0}]
-T26615a.$tc'Full3 = "'Full"#
+$tc'Full1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tc'Full1 = "'Full"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Full2 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tc'Full2 = GHC.Internal.Types.TrNameS T26615a.$tc'Full3
+$tc'Full2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tc'Full2 = GHC.Internal.Types.TrNameS $tc'Full1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'Full :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tc'Full [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tc'Full
= GHC.Internal.Types.TyCon
12008762105994325570#Word64
13514145886440831186#Word64
T26615a.$trModule
- T26615a.$tc'Full2
+ $tc'Full2
2#
- T26615a.$tc'Full1
+ $krep23
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'BitmapIndexed1 [InlPrag=[~]]
- :: GHC.Internal.Types.KindRep
+$krep24 :: GHC.Internal.Types.KindRep
[GblId, Unf=OtherCon []]
-T26615a.$tc'BitmapIndexed1
- = GHC.Internal.Types.KindRepFun $krep1 T26615a.$tc'Full1
+$krep24 = GHC.Internal.Types.KindRepFun $krep1 $krep23
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'BitmapIndexed3 :: Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 50 0}]
-T26615a.$tc'BitmapIndexed3 = "'BitmapIndexed"#
+$tc'BitmapIndexed1 :: Addr#
+[GblId, Unf=OtherCon []]
+$tc'BitmapIndexed1 = "'BitmapIndexed"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'BitmapIndexed2 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615a.$tc'BitmapIndexed2
- = GHC.Internal.Types.TrNameS T26615a.$tc'BitmapIndexed3
+$tc'BitmapIndexed2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$tc'BitmapIndexed2 = GHC.Internal.Types.TrNameS $tc'BitmapIndexed1
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
-T26615a.$tc'BitmapIndexed :: GHC.Internal.Types.TyCon
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
+T26615a.$tc'BitmapIndexed [InlPrag=[~]] :: GHC.Internal.Types.TyCon
+[GblId, Unf=OtherCon []]
T26615a.$tc'BitmapIndexed
= GHC.Internal.Types.TyCon
15226751910432948177#Word64
957331387129868915#Word64
T26615a.$trModule
- T26615a.$tc'BitmapIndexed2
+ $tc'BitmapIndexed2
2#
- T26615a.$tc'BitmapIndexed1
+ $krep24
-- RHS size: {terms: 98, types: 109, coercions: 0, joins: 3/4}
T26615a.$wdisjointCollisions [InlPrag=INLINABLE[2]]
@@ -538,7 +425,7 @@ T26615a.$wdisjointCollisions [InlPrag=INLINABLE[2]]
Str=<LP(SC(S,C(1,L)),A)><L><1L><L><L>,
Unf=Unf{Src=StableUser, TopLvl=True,
Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [30 0 20 0 0] 406 10
+ Guidance=IF_ARGS [90 0 20 0 0] 406 10
Tmpl= \ (@k)
(@a)
(@b)
@@ -586,7 +473,7 @@ T26615a.$wdisjointCollisions [InlPrag=INLINABLE[2]]
Arity=5,
Str=<L><L><L><L><L>,
Unf=OtherCon []]
- lookupInArrayCont_ _ [Occ=Dead]
+ lookupInArrayCont_ ($dEq1 [Occ=Dead] :: Eq k)
(k1 [Occ=Once1] :: k)
(ary1 [Occ=Once1!] :: Array (Leaf k b))
(i1 [Occ=Once1!] :: Int)
@@ -654,24 +541,23 @@ T26615a.$wdisjointCollisions
$s$wfoldr_ [InlPrag=[2],
Occ=LoopBreaker,
Dmd=SC(S,C(1,C(1,C(1,L))))]
- :: Bool -> Int# -> Int# -> SmallArray# (Leaf k a) -> Bool
+ :: SmallArray# (Leaf k a) -> Int# -> Int# -> Bool -> Bool
[LclId[JoinId(4)(Nothing)],
Arity=4,
Str=<L><L><L><L>,
Unf=OtherCon []]
- $s$wfoldr_ (sc :: Bool)
+ $s$wfoldr_ (sc :: SmallArray# (Leaf k a))
(sc1 :: Int#)
(sc2 :: Int#)
- (sc3 :: SmallArray# (Leaf k a))
- = case >=# sc1 sc2 of {
+ (sc3 :: Bool)
+ = case >=# sc2 sc1 of {
__DEFAULT ->
- case indexSmallArray# @Lifted @(Leaf k a) sc3 sc1 of
- { (# ipv1 #) ->
+ case indexSmallArray# @Lifted @(Leaf k a) sc sc2 of { (# ipv1 #) ->
case ipv1 of { L kA ds1 ->
join {
$j :: Bool
[LclId[JoinId(0)(Nothing)]]
- $j = jump $s$wfoldr_ sc (+# sc1 1#) sc2 sc3 } in
+ $j = jump $s$wfoldr_ sc sc1 (+# sc2 1#) sc3 } in
joinrec {
$wlookupInArrayCont_ [InlPrag=[2],
Occ=LoopBreaker,
@@ -703,13 +589,13 @@ T26615a.$wdisjointCollisions
jump $wlookupInArrayCont_ kA ww2 0# lvl2
}
};
- 1# -> sc
+ 1# -> sc3
}; } in
jump $s$wfoldr_
- GHC.Internal.Types.True
- 0#
- (sizeofSmallArray# @Lifted @(Leaf k a) ipv)
ipv
+ (sizeofSmallArray# @Lifted @(Leaf k a) ipv)
+ 0#
+ GHC.Internal.Types.True
}
}
@@ -728,28 +614,28 @@ Rec {
-- RHS size: {terms: 133, types: 126, coercions: 0, joins: 1/2}
T26615a.disjointSubtrees_$s$wdisjointSubtrees [InlPrag=INLINABLE[2],
Occ=LoopBreaker]
- :: forall b a k.
- Word#
- -> SmallArray# (Leaf k a) -> Int# -> Eq k => HashMap k b -> Bool
+ :: forall k a b.
+ Eq k =>
+ Int# -> Word# -> SmallArray# (Leaf k a) -> HashMap k b -> Bool
[GblId[StrictWorker([~, ~, ~, ~, !])],
Arity=5,
- Str=<L><L><L><LP(SC(S,C(1,L)),A)><1L>,
+ Str=<LP(SC(S,C(1,L)),A)><L><L><L><1L>,
Unf=OtherCon []]
T26615a.disjointSubtrees_$s$wdisjointSubtrees
- = \ (@b)
+ = \ (@k)
(@a)
- (@k)
- (sc :: Word#)
- (sc1 :: SmallArray# (Leaf k a))
- (sc2 :: Int#)
- (sc3 :: Eq k)
+ (@b)
+ (sc :: Eq k)
+ (sc1 :: Int#)
+ (sc2 :: Word#)
+ (sc3 :: SmallArray# (Leaf k a))
(_b :: HashMap k b) ->
case _b of {
Empty -> GHC.Internal.Types.True;
Leaf bx ds ->
case ds of { L kB ds1 ->
case kB of k0 { __DEFAULT ->
- case eqWord# bx sc of {
+ case eqWord# bx sc2 of {
__DEFAULT -> GHC.Internal.Types.True;
1# ->
joinrec {
@@ -770,7 +656,7 @@ T26615a.disjointSubtrees_$s$wdisjointSubtrees
__DEFAULT ->
case indexSmallArray# @Lifted @(Leaf k a) ww ww1 of { (# ipv #) ->
case ipv of { L kx v ->
- case == @k sc3 k2 kx of {
+ case == @k sc k2 kx of {
False -> jump $wlookupInArrayCont_ k2 ww (+# ww1 1#) ww2;
True -> GHC.Internal.Types.False
}
@@ -780,19 +666,19 @@ T26615a.disjointSubtrees_$s$wdisjointSubtrees
}
}; } in
jump $wlookupInArrayCont_
- k0 sc1 0# (sizeofSmallArray# @Lifted @(Leaf k a) sc1)
+ k0 sc3 0# (sizeofSmallArray# @Lifted @(Leaf k a) sc3)
}
}
};
Collision bx bx1 ->
T26615a.$wdisjointCollisions
- @k @a @b sc3 sc (T26615a.Array @(Leaf k a) sc1) bx bx1;
+ @k @a @b sc sc2 (T26615a.Array @(Leaf k a) sc3) bx bx1;
BitmapIndexed bx bx1 ->
let {
m :: Word#
[LclId]
m = uncheckedShiftL#
- 1## (word2Int# (and# (uncheckedShiftRL# sc sc2) 31##)) } in
+ 1## (word2Int# (and# (uncheckedShiftRL# sc2 sc1) 31##)) } in
case and# m bx of {
__DEFAULT ->
case indexSmallArray#
@@ -803,7 +689,7 @@ T26615a.disjointSubtrees_$s$wdisjointSubtrees
of
{ (# ipv #) ->
T26615a.disjointSubtrees_$s$wdisjointSubtrees
- @b @a @k sc sc1 (+# sc2 5#) sc3 ipv
+ @k @a @b sc (+# sc1 5#) sc2 sc3 ipv
};
0## -> GHC.Internal.Types.True
};
@@ -812,17 +698,17 @@ T26615a.disjointSubtrees_$s$wdisjointSubtrees
@Lifted
@(HashMap k b)
bx
- (word2Int# (and# (uncheckedShiftRL# sc sc2) 31##))
+ (word2Int# (and# (uncheckedShiftRL# sc2 sc1) 31##))
of
{ (# ipv #) ->
T26615a.disjointSubtrees_$s$wdisjointSubtrees
- @b @a @k sc sc1 (+# sc2 5#) sc3 ipv
+ @k @a @b sc (+# sc1 5#) sc2 sc3 ipv
}
}
end Rec }
Rec {
--- RHS size: {terms: 705, types: 732, coercions: 18, joins: 13/23}
+-- RHS size: {terms: 705, types: 748, coercions: 18, joins: 13/23}
T26615a.$wdisjointSubtrees [InlPrag=INLINABLE[2], Occ=LoopBreaker]
:: forall k a b. Eq k => Int# -> HashMap k a -> HashMap k b -> Bool
[GblId[StrictWorker([~, ~, !])],
@@ -841,7 +727,7 @@ T26615a.$wdisjointSubtrees [InlPrag=INLINABLE[2], Occ=LoopBreaker]
join {
fail [Occ=Once3!T[1]] :: (# #) -> Bool
[LclId[JoinId(1)(Nothing)], Arity=1, Str=<L>, Unf=OtherCon []]
- fail _ [Occ=Dead, OS=OneShot]
+ fail (ds1 [Occ=Dead, OS=OneShot] :: (# #))
= case _b of wild [Occ=Once1] {
__DEFAULT ->
case GHC.Internal.Control.Exception.Base.patError
@@ -860,7 +746,7 @@ T26615a.$wdisjointSubtrees [InlPrag=INLINABLE[2], Occ=LoopBreaker]
Arity=5,
Str=<L><L><L><L><L>,
Unf=OtherCon []]
- lookupCont_ _ [Occ=Dead]
+ lookupCont_ ($dEq1 [Occ=Dead] :: Eq k)
(ds4 [Occ=Once1!] :: Word)
(ds5 [Occ=Once1] :: k)
(ds6 [Occ=Once1!] :: Int)
@@ -896,7 +782,7 @@ T26615a.$wdisjointSubtrees [InlPrag=INLINABLE[2], Occ=LoopBreaker]
Arity=5,
Str=<L><L><L><L><L>,
Unf=OtherCon []]
- lookupInArrayCont_ _ [Occ=Dead]
+ lookupInArrayCont_ ($dEq2 [Occ=Dead] :: Eq k)
(k1 [Occ=Once1] :: k)
(ary [Occ=Once1!] :: Array (Leaf k a))
(i [Occ=Once1!] :: Int)
@@ -1000,7 +886,7 @@ T26615a.$wdisjointSubtrees [InlPrag=INLINABLE[2], Occ=LoopBreaker]
Arity=5,
Str=<L><L><L><L><L>,
Unf=OtherCon []]
- lookupCont_ _ [Occ=Dead]
+ lookupCont_ ($dEq1 [Occ=Dead] :: Eq k)
(ds3 [Occ=Once1!] :: Word)
(ds4 [Occ=Once1] :: k)
(ds5 [Occ=Once1!] :: Int)
@@ -1034,7 +920,7 @@ T26615a.$wdisjointSubtrees [InlPrag=INLINABLE[2], Occ=LoopBreaker]
Arity=5,
Str=<L><L><L><L><L>,
Unf=OtherCon []]
- lookupInArrayCont_ _ [Occ=Dead]
+ lookupInArrayCont_ ($dEq2 [Occ=Dead] :: Eq k)
(k1 [Occ=Once1] :: k)
(ary [Occ=Once1!] :: Array (Leaf k b))
(i [Occ=Once1!] :: Int)
@@ -1179,23 +1065,23 @@ T26615a.$wdisjointSubtrees [InlPrag=INLINABLE[2], Occ=LoopBreaker]
@(*)
@(SmallArray# (HashMap k a)
-> SmallArray# (HashMap k b) -> Int#)
- @(GHC.Internal.Types.ZonkAny 0
- -> GHC.Internal.Types.ZonkAny 1 -> Int#)
+ @(GHC.Internal.Types.UnusedType 0 "a"
+ -> GHC.Internal.Types.UnusedType 1 "b" -> Int#)
of
{ GHC.Internal.Unsafe.Coerce.UnsafeRefl v2 ->
case reallyUnsafePtrEquality#
@Lifted
@Lifted
- @(GHC.Internal.Types.ZonkAny 0)
- @(GHC.Internal.Types.ZonkAny 1)
+ @(GHC.Internal.Types.UnusedType 0 "a")
+ @(GHC.Internal.Types.UnusedType 1 "b")
(bx1
`cast` (SelCo:Fun(arg) (Sub (Sym v2))
:: SmallArray# (HashMap k a)
- ~R# GHC.Internal.Types.ZonkAny 0))
+ ~R# GHC.Internal.Types.UnusedType 0 "a"))
(bx3
`cast` (SelCo:Fun(arg) (SelCo:Fun(res) (Sub (Sym v2)))
:: SmallArray# (HashMap k b)
- ~R# GHC.Internal.Types.ZonkAny 1))
+ ~R# GHC.Internal.Types.UnusedType 1 "b"))
of {
__DEFAULT ->
joinrec {
@@ -1324,51 +1210,49 @@ T26615a.$wdisjointSubtrees [InlPrag=INLINABLE[2], Occ=LoopBreaker]
}; } in
jump go (GHC.Internal.Types.W# (and# 4294967295## bx1));
Full bx1 ->
+ joinrec {
+ go [Occ=LoopBreakerT[1]] :: Int -> Bool
+ [LclId[JoinId(1)(Nothing)], Arity=1, Str=<L>, Unf=OtherCon []]
+ go (i :: Int)
+ = case GHC.Internal.Classes.ltInt i (GHC.Internal.Types.I# 0#) of {
+ False ->
+ case i of { I# i# ->
+ case indexSmallArray# @Lifted @(HashMap k a) bx i# of
+ { (# ipv [Occ=Once1] #) ->
+ case indexSmallArray# @Lifted @(HashMap k b) bx1 i# of
+ { (# ipv1 [Occ=Once1] #) ->
+ case T26615a.$wdisjointSubtrees @k @a @b $dEq (+# ww 5#) ipv ipv1
+ of {
+ False -> GHC.Internal.Types.False;
+ True -> jump go (GHC.Internal.Types.I# (-# i# 1#))
+ }
+ }
+ }
+ };
+ True -> GHC.Internal.Types.True
+ }; } in
case GHC.Internal.Unsafe.Coerce.unsafeEqualityProof
@(*)
@(SmallArray# (HashMap k a) -> SmallArray# (HashMap k b) -> Int#)
- @(GHC.Internal.Types.ZonkAny 0
- -> GHC.Internal.Types.ZonkAny 1 -> Int#)
+ @(GHC.Internal.Types.UnusedType 0 "a"
+ -> GHC.Internal.Types.UnusedType 1 "b" -> Int#)
of
{ GHC.Internal.Unsafe.Coerce.UnsafeRefl v2 ->
case reallyUnsafePtrEquality#
@Lifted
@Lifted
- @(GHC.Internal.Types.ZonkAny 0)
- @(GHC.Internal.Types.ZonkAny 1)
+ @(GHC.Internal.Types.UnusedType 0 "a")
+ @(GHC.Internal.Types.UnusedType 1 "b")
(bx
`cast` (SelCo:Fun(arg) (Sub (Sym v2))
:: SmallArray# (HashMap k a)
- ~R# GHC.Internal.Types.ZonkAny 0))
+ ~R# GHC.Internal.Types.UnusedType 0 "a"))
(bx1
`cast` (SelCo:Fun(arg) (SelCo:Fun(res) (Sub (Sym v2)))
:: SmallArray# (HashMap k b)
- ~R# GHC.Internal.Types.ZonkAny 1))
+ ~R# GHC.Internal.Types.UnusedType 1 "b"))
of {
- __DEFAULT ->
- joinrec {
- go [Occ=LoopBreakerT[1]] :: Int -> Bool
- [LclId[JoinId(1)(Nothing)], Arity=1, Str=<L>, Unf=OtherCon []]
- go (i :: Int)
- = case GHC.Internal.Classes.ltInt i (GHC.Internal.Types.I# 0#) of {
- False ->
- case i of { I# i# ->
- case indexSmallArray# @Lifted @(HashMap k a) bx i# of
- { (# ipv [Occ=Once1] #) ->
- case indexSmallArray# @Lifted @(HashMap k b) bx1 i# of
- { (# ipv1 [Occ=Once1] #) ->
- case T26615a.$wdisjointSubtrees
- @k @a @b $dEq (+# ww 5#) ipv ipv1
- of {
- False -> GHC.Internal.Types.False;
- True -> jump go (GHC.Internal.Types.I# (-# i# 1#))
- }
- }
- }
- };
- True -> GHC.Internal.Types.True
- }; } in
- jump go (GHC.Internal.Types.I# 31#);
+ __DEFAULT -> jump go (GHC.Internal.Types.I# 31#);
1# -> GHC.Internal.Types.False
}
}
@@ -1385,7 +1269,7 @@ T26615a.$wdisjointSubtrees
join {
fail [Dmd=MC(1,L)] :: (# #) -> Bool
[LclId[JoinId(1)(Nothing)], Arity=1, Str=<A>, Unf=OtherCon []]
- fail _ [Occ=Dead, OS=OneShot]
+ fail (ds1 [Occ=Dead, OS=OneShot] :: (# #))
= case _b of {
__DEFAULT -> case lvl1 of {};
Empty -> GHC.Internal.Types.True;
@@ -1508,7 +1392,7 @@ T26615a.$wdisjointSubtrees
};
Collision bx bx1 ->
T26615a.disjointSubtrees_$s$wdisjointSubtrees
- @a @b @k bx bx1 ww $dEq ds
+ @k @b @a $dEq ww bx bx1 ds
} } in
case ds of {
Empty -> GHC.Internal.Types.True;
@@ -1661,7 +1545,7 @@ T26615a.$wdisjointSubtrees
of
{ (# ipv #) ->
T26615a.disjointSubtrees_$s$wdisjointSubtrees
- @b @a @k bx bx1 (+# ww 5#) $dEq ipv
+ @k @a @b $dEq (+# ww 5#) bx bx1 ipv
};
0## -> GHC.Internal.Types.True
};
@@ -1674,7 +1558,7 @@ T26615a.$wdisjointSubtrees
of
{ (# ipv #) ->
T26615a.disjointSubtrees_$s$wdisjointSubtrees
- @b @a @k bx bx1 (+# ww 5#) $dEq ipv
+ @k @a @b $dEq (+# ww 5#) bx bx1 ipv
}
};
BitmapIndexed bx bx1 ->
@@ -1686,21 +1570,23 @@ T26615a.$wdisjointSubtrees
case GHC.Internal.Unsafe.Coerce.unsafeEqualityProof
@(*)
@(SmallArray# (HashMap k a) -> SmallArray# (HashMap k b) -> Int#)
- @(GHC.Internal.Types.ZonkAny 0
- -> GHC.Internal.Types.ZonkAny 1 -> Int#)
+ @(GHC.Internal.Types.UnusedType 0 "a"
+ -> GHC.Internal.Types.UnusedType 1 "b" -> Int#)
of
{ GHC.Internal.Unsafe.Coerce.UnsafeRefl v2 ->
case reallyUnsafePtrEquality#
@Lifted
@Lifted
- @(GHC.Internal.Types.ZonkAny 0)
- @(GHC.Internal.Types.ZonkAny 1)
+ @(GHC.Internal.Types.UnusedType 0 "a")
+ @(GHC.Internal.Types.UnusedType 1 "b")
(bx1
`cast` (SelCo:Fun(arg) (Sub (Sym v2))
- :: SmallArray# (HashMap k a) ~R# GHC.Internal.Types.ZonkAny 0))
+ :: SmallArray# (HashMap k a)
+ ~R# GHC.Internal.Types.UnusedType 0 "a"))
(bx3
`cast` (SelCo:Fun(arg) (SelCo:Fun(res) (Sub (Sym v2)))
- :: SmallArray# (HashMap k b) ~R# GHC.Internal.Types.ZonkAny 1))
+ :: SmallArray# (HashMap k b)
+ ~R# GHC.Internal.Types.UnusedType 1 "b"))
of {
__DEFAULT ->
let {
@@ -1829,21 +1715,23 @@ T26615a.$wdisjointSubtrees
case GHC.Internal.Unsafe.Coerce.unsafeEqualityProof
@(*)
@(SmallArray# (HashMap k a) -> SmallArray# (HashMap k b) -> Int#)
- @(GHC.Internal.Types.ZonkAny 0
- -> GHC.Internal.Types.ZonkAny 1 -> Int#)
+ @(GHC.Internal.Types.UnusedType 0 "a"
+ -> GHC.Internal.Types.UnusedType 1 "b" -> Int#)
of
{ GHC.Internal.Unsafe.Coerce.UnsafeRefl v2 ->
case reallyUnsafePtrEquality#
@Lifted
@Lifted
- @(GHC.Internal.Types.ZonkAny 0)
- @(GHC.Internal.Types.ZonkAny 1)
+ @(GHC.Internal.Types.UnusedType 0 "a")
+ @(GHC.Internal.Types.UnusedType 1 "b")
(bx
`cast` (SelCo:Fun(arg) (Sub (Sym v2))
- :: SmallArray# (HashMap k a) ~R# GHC.Internal.Types.ZonkAny 0))
+ :: SmallArray# (HashMap k a)
+ ~R# GHC.Internal.Types.UnusedType 0 "a"))
(bx1
`cast` (SelCo:Fun(arg) (SelCo:Fun(res) (Sub (Sym v2)))
- :: SmallArray# (HashMap k b) ~R# GHC.Internal.Types.ZonkAny 1))
+ :: SmallArray# (HashMap k b)
+ ~R# GHC.Internal.Types.UnusedType 1 "b"))
of {
__DEFAULT ->
let {
@@ -1910,88 +1798,72 @@ disjointSubtrees
------ Local rules for imported ids --------
"SC:$wdisjointSubtrees1" [1]
- forall (@a)
+ forall (@k)
(@b)
- (@k)
- (sc :: Word#)
- (sc1 :: SmallArray# (Leaf k a))
+ (@a)
+ (sc :: Eq k)
+ (sc1 :: Int#)
(sc2 :: Word#)
(sc3 :: SmallArray# (Leaf k b))
- (sc4 :: Int#)
- (sc5 :: Eq k).
+ (sc4 :: Word#)
+ (sc5 :: SmallArray# (Leaf k a)).
T26615a.$wdisjointSubtrees @k
@b
@a
- sc5
- sc4
+ sc
+ sc1
(T26615a.Collision @k @b sc2 sc3)
- (T26615a.Collision @k @a sc sc1)
+ (T26615a.Collision @k @a sc4 sc5)
= T26615a.$wdisjointCollisions
- @k @b @a sc5 sc2 (T26615a.Array @(Leaf k b) sc3) sc sc1
+ @k @b @a sc sc2 (T26615a.Array @(Leaf k b) sc3) sc4 sc5
"SC:$wdisjointSubtrees0" [1]
- forall (@b)
+ forall (@k)
(@a)
- (@k)
- (sc :: Word#)
- (sc1 :: SmallArray# (Leaf k a))
- (sc2 :: Int#)
- (sc3 :: Eq k).
+ (@b)
+ (sc :: Eq k)
+ (sc1 :: Int#)
+ (sc2 :: Word#)
+ (sc3 :: SmallArray# (Leaf k a)).
T26615a.$wdisjointSubtrees @k
@a
@b
- sc3
- sc2
- (T26615a.Collision @k @a sc sc1)
+ sc
+ sc1
+ (T26615a.Collision @k @a sc2 sc3)
= T26615a.disjointSubtrees_$s$wdisjointSubtrees
- @b @a @k sc sc1 sc2 sc3
+ @k @a @b sc sc1 sc2 sc3
[2 of 2] Compiling T26615 ( T26615.hs, T26615.o )
==================== Tidy Core ====================
Result size of Tidy Core
- = {terms: 614, types: 666, coercions: 18, joins: 8/14}
+ = {terms: 614, types: 682, coercions: 18, joins: 8/14}
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615.$trModule2 :: GHC.Internal.Prim.Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 30 0}]
-T26615.$trModule2 = "T26615"#
+$trModule1 :: GHC.Internal.Prim.Addr#
+[GblId, Unf=OtherCon []]
+$trModule1 = "T26615"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615.$trModule1 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615.$trModule1 = GHC.Internal.Types.TrNameS T26615.$trModule2
+$trModule2 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$trModule2 = GHC.Internal.Types.TrNameS $trModule1
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-T26615.$trModule4 :: GHC.Internal.Prim.Addr#
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 20 0}]
-T26615.$trModule4 = "main"#
+$trModule3 :: GHC.Internal.Prim.Addr#
+[GblId, Unf=OtherCon []]
+$trModule3 = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-T26615.$trModule3 :: GHC.Internal.Types.TrName
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615.$trModule3 = GHC.Internal.Types.TrNameS T26615.$trModule4
+$trModule4 :: GHC.Internal.Types.TrName
+[GblId, Unf=OtherCon []]
+$trModule4 = GHC.Internal.Types.TrNameS $trModule3
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
-T26615.$trModule :: GHC.Internal.Types.Module
-[GblId,
- Unf=Unf{Src=<vanilla>, TopLvl=True,
- Value=True, ConLike=True, WorkFree=True, Expandable=True,
- Guidance=IF_ARGS [] 10 10}]
-T26615.$trModule
- = GHC.Internal.Types.Module T26615.$trModule3 T26615.$trModule1
+T26615.$trModule [InlPrag=[~]] :: GHC.Internal.Types.Module
+[GblId, Unf=OtherCon []]
+T26615.$trModule = GHC.Internal.Types.Module $trModule4 $trModule2
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
lvl :: GHC.Internal.Prim.Addr#
@@ -2128,7 +2000,7 @@ $wpoly_lookupCont_
end Rec }
Rec {
--- RHS size: {terms: 448, types: 507, coercions: 18, joins: 8/13}
+-- RHS size: {terms: 448, types: 523, coercions: 18, joins: 8/13}
T26615.$s$wdisjointSubtrees [InlPrag=[~], Occ=LoopBreaker]
:: forall a b.
GHC.Internal.Prim.Int#
@@ -2143,7 +2015,7 @@ T26615.$s$wdisjointSubtrees
join {
fail [Dmd=MC(1,L)] :: (# #) -> Bool
[LclId[JoinId(1)(Nothing)], Arity=1, Str=<A>, Unf=OtherCon []]
- fail _ [Occ=Dead, OS=OneShot]
+ fail (ds1 [Occ=Dead, OS=OneShot] :: (# #))
= case _b of wild {
__DEFAULT -> case lvl1 of {};
T26615a.Empty -> GHC.Internal.Types.True;
@@ -2190,30 +2062,28 @@ T26615.$s$wdisjointSubtrees
$s$wfoldr_ [InlPrag=[2],
Occ=LoopBreaker,
Dmd=SC(S,C(1,C(1,C(1,L))))]
- :: Bool
- -> GHC.Internal.Prim.Int#
- -> GHC.Internal.Prim.Int#
- -> GHC.Internal.Prim.SmallArray# (T26615a.Leaf [Char] a)
- -> Bool
+ :: GHC.Internal.Prim.SmallArray# (T26615a.Leaf [Char] a)
+ -> GHC.Internal.Prim.Int# -> GHC.Internal.Prim.Int# -> Bool -> Bool
[LclId[JoinId(4)(Nothing)],
Arity=4,
Str=<L><L><L><L>,
Unf=OtherCon []]
- $s$wfoldr_ (sc :: Bool)
+ $s$wfoldr_ (sc
+ :: GHC.Internal.Prim.SmallArray# (T26615a.Leaf [Char] a))
(sc1 :: GHC.Internal.Prim.Int#)
(sc2 :: GHC.Internal.Prim.Int#)
- (sc3 :: GHC.Internal.Prim.SmallArray# (T26615a.Leaf [Char] a))
- = case GHC.Internal.Prim.>=# sc1 sc2 of {
+ (sc3 :: Bool)
+ = case GHC.Internal.Prim.>=# sc2 sc1 of {
__DEFAULT ->
case GHC.Internal.Prim.indexSmallArray#
- @GHC.Internal.Types.Lifted @(T26615a.Leaf String a) sc3 sc1
+ @GHC.Internal.Types.Lifted @(T26615a.Leaf String a) sc sc2
of
{ (# ipv1 #) ->
case ipv1 of { T26615a.L kA ds2 ->
join {
$j :: Bool
[LclId[JoinId(0)(Nothing)]]
- $j = jump $s$wfoldr_ sc (GHC.Internal.Prim.+# sc1 1#) sc2 sc3 } in
+ $j = jump $s$wfoldr_ sc sc1 (GHC.Internal.Prim.+# sc2 1#) sc3 } in
joinrec {
$wlookupInArrayCont_ [InlPrag=[2],
Occ=LoopBreaker,
@@ -2258,14 +2128,14 @@ T26615.$s$wdisjointSubtrees
jump $wlookupInArrayCont_ kA bx3 0# lvl2
}
};
- 1# -> sc
+ 1# -> sc3
}; } in
jump $s$wfoldr_
- GHC.Internal.Types.True
- 0#
+ bx1
(GHC.Internal.Prim.sizeofSmallArray#
@GHC.Internal.Types.Lifted @(T26615a.Leaf String a) bx1)
- bx1
+ 0#
+ GHC.Internal.Types.True
};
T26615a.BitmapIndexed bx2 bx3 ->
let {
@@ -2317,23 +2187,23 @@ T26615.$s$wdisjointSubtrees
@(GHC.Internal.Prim.SmallArray# (HashMap String a)
-> GHC.Internal.Prim.SmallArray# (HashMap String b)
-> GHC.Internal.Prim.Int#)
- @(GHC.Internal.Types.ZonkAny 0
- -> GHC.Internal.Types.ZonkAny 1 -> GHC.Internal.Prim.Int#)
+ @(GHC.Internal.Types.UnusedType 0 "a"
+ -> GHC.Internal.Types.UnusedType 1 "b" -> GHC.Internal.Prim.Int#)
of
{ GHC.Internal.Unsafe.Coerce.UnsafeRefl v2 ->
case GHC.Internal.Prim.reallyUnsafePtrEquality#
@GHC.Internal.Types.Lifted
@GHC.Internal.Types.Lifted
- @(GHC.Internal.Types.ZonkAny 0)
- @(GHC.Internal.Types.ZonkAny 1)
+ @(GHC.Internal.Types.UnusedType 0 "a")
+ @(GHC.Internal.Types.UnusedType 1 "b")
(bx1
`cast` (SelCo:Fun(arg) (Sub (Sym v2))
:: GHC.Internal.Prim.SmallArray# (HashMap String a)
- ~R# GHC.Internal.Types.ZonkAny 0))
+ ~R# GHC.Internal.Types.UnusedType 0 "a"))
(bx3
`cast` (SelCo:Fun(arg) (SelCo:Fun(res) (Sub (Sym v2)))
:: GHC.Internal.Prim.SmallArray# (HashMap String b)
- ~R# GHC.Internal.Types.ZonkAny 1))
+ ~R# GHC.Internal.Types.UnusedType 1 "b"))
of {
__DEFAULT ->
joinrec {
@@ -2495,23 +2365,23 @@ T26615.$s$wdisjointSubtrees
@(GHC.Internal.Prim.SmallArray# (HashMap String a)
-> GHC.Internal.Prim.SmallArray# (HashMap String b)
-> GHC.Internal.Prim.Int#)
- @(GHC.Internal.Types.ZonkAny 0
- -> GHC.Internal.Types.ZonkAny 1 -> GHC.Internal.Prim.Int#)
+ @(GHC.Internal.Types.UnusedType 0 "a"
+ -> GHC.Internal.Types.UnusedType 1 "b" -> GHC.Internal.Prim.Int#)
of
{ GHC.Internal.Unsafe.Coerce.UnsafeRefl v2 ->
case GHC.Internal.Prim.reallyUnsafePtrEquality#
@GHC.Internal.Types.Lifted
@GHC.Internal.Types.Lifted
- @(GHC.Internal.Types.ZonkAny 0)
- @(GHC.Internal.Types.ZonkAny 1)
+ @(GHC.Internal.Types.UnusedType 0 "a")
+ @(GHC.Internal.Types.UnusedType 1 "b")
(bx
`cast` (SelCo:Fun(arg) (Sub (Sym v2))
:: GHC.Internal.Prim.SmallArray# (HashMap String a)
- ~R# GHC.Internal.Types.ZonkAny 0))
+ ~R# GHC.Internal.Types.UnusedType 0 "a"))
(bx1
`cast` (SelCo:Fun(arg) (SelCo:Fun(res) (Sub (Sym v2)))
:: GHC.Internal.Prim.SmallArray# (HashMap String b)
- ~R# GHC.Internal.Types.ZonkAny 1))
+ ~R# GHC.Internal.Types.UnusedType 1 "b"))
of {
__DEFAULT ->
joinrec {
@@ -2564,7 +2434,7 @@ f = \ (@a)
------ Local rules for imported ids --------
"SPEC/T26615 $wdisjointSubtrees @String @_ @_" [2]
- forall (@a) (@b) ($dEq :: Eq String).
+ forall (@a) (@b) ($dEq [Occ=Dead] :: Eq String).
T26615a.$wdisjointSubtrees @String @a @b $dEq
= T26615.$s$wdisjointSubtrees @a @b
=====================================
testsuite/tests/typecheck/should_fail/T13292.stderr
=====================================
@@ -14,15 +14,15 @@ T13292a.hs:4:12: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)]
In an equation for ‘someFunc’: someFunc = return ()
T13292.hs:6:1: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)]
- • Couldn't match type ‘GHC.Internal.Types.ZonkAny 0’ with ‘IO’
+ • Couldn't match type ‘m0_0’ with ‘IO’
Expected: IO ()
- Actual: GHC.Internal.Types.ZonkAny 0 ()
+ Actual: m0_0 ()
• When checking the type of the IO action ‘main’
T13292.hs:6:1: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)]
- • Couldn't match type ‘GHC.Internal.Types.ZonkAny 0’ with ‘IO’
+ • Couldn't match type ‘m0_0’ with ‘IO’
Expected: IO ()
- Actual: GHC.Internal.Types.ZonkAny 0 ()
+ Actual: m0_0 ()
• In the expression: main
When checking the type of the IO action ‘main’
=====================================
testsuite/tests/typecheck/should_fail/T27390-explicit-kinds.stderr
=====================================
@@ -0,0 +1,28 @@
+T27390a.hs:4:12: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)]
+ • Ambiguous type variable ‘m0’ arising from a use of ‘return’
+ prevents the constraint ‘(Monad m0)’ from being solved.
+ Relevant bindings include
+ someFunc :: m0 () (bound at T27390a.hs:4:1)
+ Probable fix: use a type annotation to specify what ‘m0’ should be.
+ Potentially matching instances:
+ instance Monad IO -- Defined in ‘GHC.Internal.Base’
+ instance Monad Maybe -- Defined in ‘GHC.Internal.Base’
+ ...plus six others
+ ...plus one instance involving out-of-scope types
+ (use -fprint-potential-instances to see them all)
+ • In the expression: return ()
+ In an equation for ‘someFunc’: someFunc = return ()
+
+T27390.hs:6:1: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)]
+ • Couldn't match type ‘m0_0 :: Type -> Type’ with ‘IO’
+ Expected: IO ()
+ Actual: (m0_0 :: Type -> Type) ()
+ • When checking the type of the IO action ‘main’
+
+T27390.hs:6:1: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)]
+ • Couldn't match type ‘m0_0 :: Type -> Type’ with ‘IO’
+ Expected: IO ()
+ Actual: (m0_0 :: Type -> Type) ()
+ • In the expression: main
+ When checking the type of the IO action ‘main’
+
=====================================
testsuite/tests/typecheck/should_fail/T27390.hs
=====================================
@@ -0,0 +1,6 @@
+{-# language NoStarIsType #-}
+module Main where
+
+import T27390a
+
+main = someFunc
=====================================
testsuite/tests/typecheck/should_fail/T27390.stderr
=====================================
@@ -0,0 +1,28 @@
+T27390a.hs:4:12: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)]
+ • Ambiguous type variable ‘m0’ arising from a use of ‘return’
+ prevents the constraint ‘(Monad m0)’ from being solved.
+ Relevant bindings include
+ someFunc :: m0 () (bound at T27390a.hs:4:1)
+ Probable fix: use a type annotation to specify what ‘m0’ should be.
+ Potentially matching instances:
+ instance Monad IO -- Defined in ‘GHC.Internal.Base’
+ instance Monad Maybe -- Defined in ‘GHC.Internal.Base’
+ ...plus six others
+ ...plus one instance involving out-of-scope types
+ (use -fprint-potential-instances to see them all)
+ • In the expression: return ()
+ In an equation for ‘someFunc’: someFunc = return ()
+
+T27390.hs:6:1: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)]
+ • Couldn't match type ‘m0_0’ with ‘IO’
+ Expected: IO ()
+ Actual: m0_0 ()
+ • When checking the type of the IO action ‘main’
+
+T27390.hs:6:1: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)]
+ • Couldn't match type ‘m0_0’ with ‘IO’
+ Expected: IO ()
+ Actual: m0_0 ()
+ • In the expression: main
+ When checking the type of the IO action ‘main’
+
=====================================
testsuite/tests/typecheck/should_fail/T27390a.hs
=====================================
@@ -0,0 +1,4 @@
+module T27390a where
+
+
+someFunc = return ()
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -448,6 +448,8 @@ test('T13075', normal, compile_fail, [''])
test('LevPolyBounded', normal, compile_fail, [''])
test('T13487', normal, compile, [''])
test('T13292', normal, multimod_compile, ['T13292', '-v0 -fdefer-type-errors'])
+test('T27390', normal, multimod_compile, ['T27390', '-v0 -fdefer-type-errors'])
+test('T27390-explicit-kinds', [extra_files(['T27390.hs', 'T27390a.hs'])], multimod_compile, ['T27390', '-v0 -fdefer-type-errors -fprint-explicit-kinds'])
test('T13300', normal, compile_fail, [''])
test('T13311', normal, compile_fail, [''])
test('T13446', normal, compile_fail, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aedfa3433e2bba7f7085def50fcff4d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aedfa3433e2bba7f7085def50fcff4d…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/andreask/fix-prof-segv] Fix a profiling race condition resulting in segfaults.
by Andreas Klebinger (@AndreasK) 23 Jun '26
by Andreas Klebinger (@AndreasK) 23 Jun '26
23 Jun '26
Andreas Klebinger pushed to branch wip/andreask/fix-prof-segv at Glasgow Haskell Compiler / GHC
Commits:
1e1ac862 by Andreas Klebinger at 2026-06-23T08:47:23+00:00
Fix a profiling race condition resulting in segfaults.
StgToCmm: Don't assume tagged FUN closures in closureCodeBody.
When entering a closure the self/node pointer might not be tagged in
some situations when a thunk is evaluated by multiple threads.
So we most AND away the tag bits rather than subtracting an expected tag.
Apply.cmm: Fix a race condition occuring when a thunk is mutated during GC.
In stg_ap_0_fast when might need to run GC before entering a thunk. If this happens
another thread or the GC itself might mutate the closure making entering it no longer
valid. We now check for this.
Add test and changelog for #27123 fixes.
- - - - -
5 changed files:
- + changelog.d/T27123.md
- compiler/GHC/StgToCmm/Bind.hs
- rts/Apply.cmm
- + testsuite/tests/rts/T27123.hs
- testsuite/tests/rts/all.T
Changes:
=====================================
changelog.d/T27123.md
=====================================
@@ -0,0 +1,7 @@
+section: compiler
+synopsis: Fix two crashes that could happen in a multithreaded setting when profiling.
+description: There were two bugs that could cause occasional segfaults or crashes with
+an `PAP object entered` error when profiling. They only happened when two threads
+where racing to evaluate the same thunk, and specific GC timings.
+mrs: !16214
+issues: #27123
=====================================
compiler/GHC/StgToCmm/Bind.hs
=====================================
@@ -587,9 +587,8 @@ closureCodeBody top_lvl bndr cl_info cc args@(arg0:_) body fv_details
-- ticky after heap check to avoid double counting
; tickyEnterFun cl_info
; enterCostCentreFun cc
- (CmmMachOp (mo_wordSub platform)
- [ CmmReg (CmmLocal node) -- See [NodeReg clobbered with loopification]
- , mkIntExpr platform (toTargetInt (fromDynTag (funTag platform cl_info))) ])
+ (cmmUntag platform (CmmReg (CmmLocal node))) -- See [NodeReg clobbered with loopification]
+
; fv_bindings <- mapM bind_fv fv_details
-- Load free vars out of closure *after*
-- heap check, to reduce live vars over check
=====================================
rts/Apply.cmm
=====================================
@@ -99,12 +99,14 @@ again:
W_ info;
P_ untaggedfun;
W_ arity;
+ W_ closure_type;
// We must obey the correct heap object observation pattern in
// Note [Heap memory barriers] in SMP.h.
untaggedfun = UNTAG(fun);
info = %INFO_PTR(untaggedfun);
+ closure_type = TO_W_( %INFO_TYPE(%STD_INFO(info)) );
switch [INVALID_OBJECT .. N_CLOSURE_TYPES]
- (TO_W_( %INFO_TYPE(%STD_INFO(info)) )) {
+ (closure_type) {
case
IND,
IND_STATIC:
@@ -212,10 +214,17 @@ again:
// We can't use the value of 'info' any more, because if
// STK_CHK_GEN() did a GC then the closure we're looking
// at may have changed, e.g. a THUNK_SELECTOR may have
- // been evaluated by the GC. So we reload the info
- // pointer now.
+ // been evaluated by the GC.
+ // We always reload the info pointer now. And if
+ // the closure type changed we need to take a different case
+ // alt altogether so we retry from the start in that case.
+
untaggedfun = UNTAG(fun);
info = %INFO_PTR(untaggedfun);
+ if(closure_type != TO_W_( %INFO_TYPE(%STD_INFO(info)) ) )
+ {
+ goto again;
+ }
jump %ENTRY_CODE(info)
(stg_restore_cccs_eval_info, CCCS)
=====================================
testsuite/tests/rts/T27123.hs
=====================================
@@ -0,0 +1,65 @@
+{-# OPTIONS_GHC -fno-full-laziness -fno-worker-wrapper #-}
+{-# LANGUAGE MagicHash, UnboxedTuples #-}
+
+-- This test checks that the auto-apply code (stg_ap_0_fast, stg_ap_p) is robust
+-- against another thread or the GC evaluating a closure at the same time.
+
+module Main
+ -- (main)
+where
+
+import Control.Monad
+import Control.Concurrent
+import System.IO
+import GHC.Data.SmallArray
+import GHC.Exts
+import GHC.IO
+
+type Arr = SmallMutableArray RealWorld (Int->Int)
+
+io :: (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
+io f = IO f
+
+io_ :: (State# RealWorld -> State# RealWorld ) -> IO ()
+io_ f = IO (\s -> case f s of s2 -> (# s2, () #))
+
+{-# NOINLINE readSmallArray #-}
+readSmallArray (SmallMutableArray arr) (I# idx) = IO $ \s -> case readSmallArray# arr idx s of
+ (# s2, r #) -> (# s2, r #)
+
+-- Continually overwrites the array with unevaluated thunks that will evaluated to
+-- a PAP under profiling.
+{-# NOINLINE mkThunks #-}
+mkThunks :: Arr -> IO ()
+mkThunks arr = do
+ forever $ do
+ yield
+ forM_ [0..100] $ \_j -> do
+ forM_ [0..5 :: Int] $ \i -> do
+ -- With profiling results in a thunk that will evaluate to a PAP capturing the SCC
+ let g = {-# SCC g #-} succ
+ io_ (writeSmallArray arr i g)
+
+-- Evaluate the array repeatedly in the given order.
+{-# NOINLINE evaluateThunks #-}
+evaluateThunks :: Arr -> [Int] -> IO ()
+evaluateThunks arr idxs = do
+ forever $ do
+ yield
+ -- putStr "." >> hFlush stdout
+ forM [0..5000::Int] $ \j -> do
+ forM_ idxs $ \i -> do
+ !g <- readSmallArray arr i
+ seq (g i) (pure ())
+
+main :: IO ()
+main = do
+ -- We spawn three threads. Two are evaluating the thunks in the array in opposite directions
+ -- One thread is
+ arr <- io (newSmallArray 6 (id))
+ _ <- forkIO $ do
+ evaluateThunks arr [0..5]
+ _ <- forkIO $ do
+ evaluateThunks arr [5,4..0]
+ forkIO $ mkThunks arr
+ threadDelay 10_000_000
=====================================
testsuite/tests/rts/all.T
=====================================
@@ -687,3 +687,5 @@ test('ClosureTable',
['-debug -O0 ClosureTable_c.c -I{top}/../rts -I{top}/../rts/include'])
test('resizeMutableByteArrayInPlace', [req_cmm, extra_ways(['optasm', 'sanity']), only_ways(['optasm', 'sanity'])], compile_and_run, [''])
+
+test('T27123', [extra_ways(['optasm']), when(have_profiling(), extra_ways(['prof']))], compile_and_run, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e1ac862c818faca2fd6a45fa34fa4c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e1ac862c818faca2fd6a45fa34fa4c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/andreask/fix-prof-segv] Apply 2 suggestion(s) to 2 file(s)
by Andreas Klebinger (@AndreasK) 23 Jun '26
by Andreas Klebinger (@AndreasK) 23 Jun '26
23 Jun '26
Andreas Klebinger pushed to branch wip/andreask/fix-prof-segv at Glasgow Haskell Compiler / GHC
Commits:
f7643584 by Andreas Klebinger at 2026-06-23T08:44:15+00:00
Apply 2 suggestion(s) to 2 file(s)
Co-authored-by: Zubin <zubin.duggal(a)gmail.com>
Co-authored-by: Magnus <contact(a)mangoiv.com>
- - - - -
2 changed files:
- changelog.d/T27123.md
- rts/Apply.cmm
Changes:
=====================================
changelog.d/T27123.md
=====================================
@@ -1,6 +1,6 @@
section: compiler
synopsis: Fix two crashes that could happen in a multithreaded setting when profiling.
-description: There where two bugs that could cause occasional segfaults or crashes with
+description: There were two bugs that could cause occasional segfaults or crashes with
an `PAP object entered` error when profiling. They only happened when two threads
where racing to evaluate the same thunk, and specific GC timings.
mrs: !16214
=====================================
rts/Apply.cmm
=====================================
@@ -215,7 +215,7 @@ again:
// STK_CHK_GEN() did a GC then the closure we're looking
// at may have changed, e.g. a THUNK_SELECTOR may have
// been evaluated by the GC.
- // We always reload reload the info pointer now. And if
+ // We always reload the info pointer now. And if
// the closure type changed we need to take a different case
// alt altogether so we retry from the start in that case.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7643584f63a2fbfea300a0c9597ebd…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7643584f63a2fbfea300a0c9597ebd…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fendor/no-code-output-constr] 2 commits: Introduce 'NoCodeOutput' constructor to avoid partial `backendCodeOutput`
by Hannes Siebenhandl (@fendor) 23 Jun '26
by Hannes Siebenhandl (@fendor) 23 Jun '26
23 Jun '26
Hannes Siebenhandl pushed to branch wip/fendor/no-code-output-constr at Glasgow Haskell Compiler / GHC
Commits:
c3f5364b by fendor at 2026-06-23T10:39:42+02:00
Introduce 'NoCodeOutput' constructor to avoid partial `backendCodeOutput`
This makes `backendCodeOutput` total, but forces us to explicitly handle
the new `NoCodeOutput` case when using it.
Thus, we add some new `panic`'s when generating files.
The advantage is that `backendCodeOutput` can be used for checking
capabilities without requiring a prior check via `backendWritesFiles`.
- - - - -
04d96784 by Matthew Pickering at 2026-06-23T10:40:39+02:00
Add failing test for `-finfo-table-map` and bytecode backend
If you compile a module using the bytecode backend, with
-finfo-table-map, then the info table map doesn't get populated for the
module.
This is because the -finfo-table-map code path is implemented mostly in
the StgToCmm phase which isn't run when creating bytecode.
Ticket #27039
- - - - -
8 changed files:
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Main/Compile.hs
- compiler/GHC/Driver/Pipeline.hs
- testsuite/tests/ghci/scripts/all.T
- + testsuite/tests/ghci/scripts/bytecodeIPE.hs
- + testsuite/tests/ghci/scripts/bytecodeIPE.script
- + testsuite/tests/ghci/scripts/bytecodeIPE.stdout
Changes:
=====================================
compiler/GHC/Driver/Backend.hs
=====================================
@@ -117,7 +117,6 @@ import GHC.Driver.Phases
import GHC.Utils.Error
-import GHC.Utils.Panic
import GHC.Driver.Pipeline.Monad
import GHC.Platform
@@ -374,6 +373,7 @@ data DefunctionalizedCodeOutput
| ViaCCodeOutput
| LlvmCodeOutput
| JSCodeOutput
+ | NoCodeOutput
-- | Names a function that tells the driver what should happen after
@@ -773,8 +773,8 @@ backendCodeOutput (Named NCG) = NcgCodeOutput
backendCodeOutput (Named LLVM) = LlvmCodeOutput
backendCodeOutput (Named ViaC) = ViaCCodeOutput
backendCodeOutput (Named JavaScript) = JSCodeOutput
-backendCodeOutput (Named Bytecode) = panic "backendCodeOutput: bytecodeBackend"
-backendCodeOutput (Named NoBackend) = panic "backendCodeOutput: noBackend"
+backendCodeOutput (Named Bytecode) = NoCodeOutput
+backendCodeOutput (Named NoBackend) = NoCodeOutput
backendUseJSLinker :: Backend -> Bool
backendUseJSLinker (Named NCG) = False
=====================================
compiler/GHC/Driver/CodeOutput.hs
=====================================
@@ -63,6 +63,7 @@ import GHC.Types.Unique.Supply ( UniqueTag(..) )
import System.IO
import Data.Set (Set)
import qualified Data.Set as Set
+import GHC.Plugins (panic)
{-
************************************************************************
@@ -129,6 +130,7 @@ codeOutput logger tmpfs llvm_config dflags unit_state this_mod filenm location g
ViaCCodeOutput -> outputC logger dflags filenm dus1 final_stream pkg_deps
LlvmCodeOutput -> outputLlvm logger llvm_config dflags filenm dus1 final_stream
JSCodeOutput -> outputJS logger llvm_config dflags filenm final_stream
+ NoCodeOutput -> panic "codeOutput: expected code output backend but got NoCodeOutput"
; stubs_exist <- outputForeignStubs logger tmpfs dflags unit_state this_mod location stubs
; return (filenm, stubs_exist, foreign_fps, a)
}
=====================================
compiler/GHC/Driver/Main/Compile.hs
=====================================
@@ -670,6 +670,8 @@ hscGenHardCode hsc_env cgguts mod_loc output_filename = do
-- next withTiming after this will be "Assembler" (hard code only).
withTiming logger (text "CodeGen"<+>brackets (ppr this_mod)) (const ())
$ case backendCodeOutput (backend dflags) of
+ NoCodeOutput ->
+ panic "hscGenHardCode: expected code output backend but got NoCodeOutput"
JSCodeOutput ->
do
let js_config = initStgToJSConfig dflags
=====================================
compiler/GHC/Driver/Pipeline.hs
=====================================
@@ -743,6 +743,8 @@ compileEmptyStub dflags hsc_env basename location mod_name = do
let home_unit = hsc_home_unit hsc_env
case backendCodeOutput (backend dflags) of
+ NoCodeOutput ->
+ panic "compileEmptyStub: expected code output backend but got NoCodeOutput"
JSCodeOutput -> do
empty_stub <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js"
let src = ppr (mkHomeModule home_unit mod_name) <+> text "= 0;"
=====================================
testsuite/tests/ghci/scripts/all.T
=====================================
@@ -385,6 +385,14 @@ test('ListTuplePunsPpr', normal, ghci_script, ['ListTuplePunsPpr.script'])
test('ListTuplePunsPprNoAbbrevTuple', [limit_stdout_lines(14)], ghci_script, ['ListTuplePunsPprNoAbbrevTuple.script'])
test('T24459', normal, ghci_script, ['T24459.script'])
test('T24632', normal, ghci_script, ['T24632.script'])
+# bytecode backend doesn't support '-finfo-table-map' (#27039)
+test('bytecodeIPE',
+ [ extra_hc_opts('-finfo-table-map')
+ , extra_files(['bytecodeIPE.hs'])
+ , req_rts_linker
+ , when(arch('wasm32') or arch('javascript'), skip)
+ ],
+ ghci_script, ['bytecodeIPE.script'])
# Test package renaming in GHCi session
test('GhciPackageRename',
=====================================
testsuite/tests/ghci/scripts/bytecodeIPE.hs
=====================================
@@ -0,0 +1,12 @@
+module BytecodeIPE where
+
+import Data.Maybe (isJust)
+import GHC.InfoProv (whereFrom)
+
+marker :: String
+marker = id "bytecode-stub-init"
+{-# NOINLINE marker #-}
+
+-- `whereFrom` only succeeds if the module's IPE initializer ran.
+probe :: IO Bool
+probe = isJust <$> whereFrom marker
=====================================
testsuite/tests/ghci/scripts/bytecodeIPE.script
=====================================
@@ -0,0 +1,2 @@
+:load bytecodeIPE.hs
+probe
=====================================
testsuite/tests/ghci/scripts/bytecodeIPE.stdout
=====================================
@@ -0,0 +1 @@
+False
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/332e590f0efc57c6d41bdabb25f1f6…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/332e590f0efc57c6d41bdabb25f1f6…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/terrorjack/asan] 9 commits: hadrian: add support for building with AddressSanitizer
by Cheng Shao (@TerrorJack) 23 Jun '26
by Cheng Shao (@TerrorJack) 23 Jun '26
23 Jun '26
Cheng Shao pushed to branch wip/terrorjack/asan at Glasgow Haskell Compiler / GHC
Commits:
a160554c by Cheng Shao at 2026-06-23T08:37:24+00:00
hadrian: add support for building with AddressSanitizer
This patch adds a +asan flavour transformer to hadrian to build all
stage1+ C/C++ code with AddressBehaviorSanitizer. This is particularly
useful to catch potential out-of-bounds and use-after-free bugs in the
RTS codebase.
- - - - -
1ee9e876 by Cheng Shao at 2026-06-23T08:37:34+00:00
ci: add ubsan+asan job
We now have a
`x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan`
validate/nightly job with both UBSan/ASan enabled. This is enabled in
full-ci pipelines as well as MR pipelines with `test-sanitizer` label.
- - - - -
12b1c4e1 by Cheng Shao at 2026-06-23T08:37:34+00:00
rts: add ASAN instrumentation to mblock allocator
- - - - -
d69db72c by Cheng Shao at 2026-06-23T08:37:34+00:00
rts: add ASAN instrumentation to mgroup allocator
- - - - -
a9ba6486 by Cheng Shao at 2026-06-23T08:37:34+00:00
rts: add ASAN instrumentation to block allocator
- - - - -
a1c625f1 by Cheng Shao at 2026-06-23T08:37:34+00:00
rts: add ASAN instrumentation to cap->pinned_object_empty
- - - - -
22a39627 by Cheng Shao at 2026-06-23T08:37:34+00:00
rts: add ASAN instrumentation to gc_thread->free_blocks
- - - - -
65d3c885 by Cheng Shao at 2026-06-23T08:37:34+00:00
rts: add ASAN instrumentation to hash table free list
- - - - -
73c0b897 by Cheng Shao at 2026-06-23T08:37:34+00:00
rts: add ASAN instrumentation to per-Task InCall free list
- - - - -
18 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- hadrian/doc/flavours.md
- hadrian/src/Flavour.hs
- rts/Hash.c
- rts/Task.c
- rts/include/Stg.h
- + rts/include/rts/ASANUtils.h
- rts/rts.cabal
- rts/sm/BlockAlloc.c
- rts/sm/GCUtils.c
- rts/sm/MBlock.c
- rts/sm/Storage.c
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/ffi/should_run/all.T
- testsuite/tests/rts/T18623/all.T
- testsuite/tests/rts/all.T
Changes:
=====================================
.gitlab/generate-ci/gen_ci.hs
=====================================
@@ -167,6 +167,7 @@ data BuildConfig
, tablesNextToCode :: Bool
, threadSanitiser :: Bool
, ubsan :: Bool
+ , asan :: Bool
, noSplitSections :: Bool
, validateNonmovingGc :: Bool
, textWithSIMDUTF :: Bool
@@ -178,7 +179,7 @@ configureArgsStr :: BuildConfig -> String
configureArgsStr bc = unwords $
["--enable-unregisterised"| unregisterised bc ]
++ ["--disable-tables-next-to-code" | not (tablesNextToCode bc) ]
- ++ ["--with-intree-gmp" | Just _ <- [crossTarget bc] ]
+ ++ ["--with-intree-gmp" | isJust (crossTarget bc) || ubsan bc || asan bc ]
++ ["--with-system-libffi" | crossTarget bc == Just "wasm32-wasi" ]
++ ["--enable-ipe-data-compression" | withZstd bc ]
++ ["--enable-strict-ghc-toolchain-check"]
@@ -193,6 +194,7 @@ mkJobFlavour BuildConfig{..} = Flavour buildFlavour opts
[HostFullyStatic | hostFullyStatic] ++
[ThreadSanitiser | threadSanitiser] ++
[UBSan | ubsan] ++
+ [ASan | asan] ++
[NoSplitSections | noSplitSections, buildFlavour == Release ] ++
[BootNonmovingGc | validateNonmovingGc ] ++
[TextWithSIMDUTF | textWithSIMDUTF]
@@ -206,11 +208,12 @@ data FlavourTrans =
| HostFullyStatic
| ThreadSanitiser
| UBSan
+ | ASan
| NoSplitSections
| BootNonmovingGc
| TextWithSIMDUTF
-data BaseFlavour = Release | Validate | SlowValidate deriving Eq
+data BaseFlavour = Release | QuickValidate | Validate | SlowValidate deriving Eq
-----------------------------------------------------------------------------
-- Build Configurations
@@ -236,6 +239,7 @@ vanilla = BuildConfig
, tablesNextToCode = True
, threadSanitiser = False
, ubsan = False
+ , asan = False
, noSplitSections = False
, validateNonmovingGc = False
, textWithSIMDUTF = False
@@ -290,8 +294,14 @@ llvm = vanilla { llvmBootstrap = True }
tsan :: BuildConfig
tsan = vanilla { threadSanitiser = True }
-enableUBSan :: BuildConfig
-enableUBSan = vanilla { withDwarf = True, ubsan = True }
+sanitizers :: BuildConfig
+sanitizers =
+ vanilla
+ { buildFlavour = QuickValidate,
+ withDwarf = True,
+ ubsan = True,
+ asan = True
+ }
noTntc :: BuildConfig
noTntc = vanilla { tablesNextToCode = False }
@@ -376,6 +386,7 @@ flavourString :: Flavour -> String
flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . flavour_string) trans
where
base_string Release = "release"
+ base_string QuickValidate = "quick-validate"
base_string Validate = "validate"
base_string SlowValidate = "slow-validate"
@@ -385,6 +396,7 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f
flavour_string HostFullyStatic = "host_fully_static"
flavour_string ThreadSanitiser = "thread_sanitizer_cmm"
flavour_string UBSan = "ubsan"
+ flavour_string ASan = "asan"
flavour_string NoSplitSections = "no_split_sections"
flavour_string BootNonmovingGc = "boot_nonmoving_gc"
flavour_string TextWithSIMDUTF = "text_simdutf"
@@ -723,6 +735,7 @@ data ValidateRule
| WasmBackend -- ^ Run this job when the "wasm" label is present
| FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set.
| NonmovingGc -- ^ Run this job when the "non-moving GC" label is set.
+ | Sanitizers -- ^ Run this job when the "test-sanitizers" label is set.
| IpeData -- ^ Run this job when the "IPE" label is set
| TestPrimops -- ^ Run this job when "test-primops" label is set
| I386Backend -- ^ Run this job when the "i386" label is set
@@ -770,6 +783,7 @@ validateRuleString RiscV = labelString "RISC-V"
validateRuleString WasmBackend = labelString "wasm"
validateRuleString FreeBSDLabel = labelString "FreeBSD"
validateRuleString NonmovingGc = labelString "non-moving GC"
+validateRuleString Sanitizers = labelString "test-sanitizers"
validateRuleString IpeData = labelString "IPE"
validateRuleString TestPrimops = labelString "test-primops"
validateRuleString I386Backend = labelString "i386"
@@ -1231,15 +1245,25 @@ fedora_x86 =
, hackage_doc_job (disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora43) releaseConfig))
, disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora43) dwarf)
, disableValidate (standardBuilds Amd64 (Linux Fedora43))
- -- For UBSan jobs, only enable for validate/nightly pipelines.
- -- Also disable docs since it's not the point for UBSan jobs.
+ -- For UBSan/ASan jobs, only enable for validate/nightly
+ -- pipelines. Disable docs and use quick-validate to skip
+ -- linting/assertion to avoid unnecessary overhead.
+ --
+ -- See
+ -- https://github.com/llvm/llvm-project/blob/llvmorg-21.1.8/compiler-rt/lib/sa…
+ -- for ASAN options help, for now these are required to pass the
+ -- testsuite
, modifyJobs
( setVariable "HADRIAN_ARGS" "--docs=none"
. addVariable
"UBSAN_OPTIONS"
"suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions"
+ . addVariable
+ "ASAN_OPTIONS"
+ "detect_leaks=false:handle_segv=0:handle_sigfpe=0:verify_asan_link_order=false"
)
- $ validateBuilds Amd64 (Linux Fedora43) enableUBSan
+ $ addValidateRule Sanitizers
+ $ validateBuilds Amd64 (Linux Fedora43) sanitizers
]
where
hackage_doc_job = rename (<> "-hackage") . modifyJobs (addVariable "HADRIAN_ARGS" "--haddock-for-hackage")
=====================================
.gitlab/jobs.yaml
=====================================
@@ -3142,7 +3142,7 @@
"XZ_OPT": "-9"
}
},
- "nightly-x86_64-linux-fedora43-release": {
+ "nightly-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -3153,7 +3153,7 @@
"artifacts": {
"expire_in": "8 weeks",
"paths": [
- "ghc-x86_64-linux-fedora43-release.tar.xz",
+ "ghc-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -3195,17 +3195,20 @@
"x86_64-linux"
],
"variables": {
+ "ASAN_OPTIONS": "detect_leaks=false:handle_segv=0:handle_sigfpe=0:verify_asan_link_order=false",
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
- "BUILD_FLAVOUR": "release",
- "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan",
+ "BUILD_FLAVOUR": "quick-validate+debug_info+ubsan+asan",
+ "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
+ "HADRIAN_ARGS": "--docs=none",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora43-release",
+ "TEST_ENV": "x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan",
+ "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions",
"XZ_OPT": "-9"
}
},
- "nightly-x86_64-linux-fedora43-release-hackage": {
+ "nightly-x86_64-linux-fedora43-release": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -3262,14 +3265,13 @@
"BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
"BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "HADRIAN_ARGS": "--haddock-for-hackage",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-fedora43-release",
"XZ_OPT": "-9"
}
},
- "nightly-x86_64-linux-fedora43-validate": {
+ "nightly-x86_64-linux-fedora43-release-hackage": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -3280,7 +3282,7 @@
"artifacts": {
"expire_in": "8 weeks",
"paths": [
- "ghc-x86_64-linux-fedora43-validate.tar.xz",
+ "ghc-x86_64-linux-fedora43-release.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -3323,16 +3325,17 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
- "BUILD_FLAVOUR": "validate",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
+ "BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "HADRIAN_ARGS": "--haddock-for-hackage",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora43-validate",
+ "TEST_ENV": "x86_64-linux-fedora43-release",
"XZ_OPT": "-9"
}
},
- "nightly-x86_64-linux-fedora43-validate+debug_info": {
+ "nightly-x86_64-linux-fedora43-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -3343,7 +3346,7 @@
"artifacts": {
"expire_in": "8 weeks",
"paths": [
- "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
+ "ghc-x86_64-linux-fedora43-validate.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -3386,16 +3389,16 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
- "BUILD_FLAVOUR": "validate+debug_info",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
+ "BUILD_FLAVOUR": "validate",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info",
+ "TEST_ENV": "x86_64-linux-fedora43-validate",
"XZ_OPT": "-9"
}
},
- "nightly-x86_64-linux-fedora43-validate+debug_info+ubsan": {
+ "nightly-x86_64-linux-fedora43-validate+debug_info": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -3406,7 +3409,7 @@
"artifacts": {
"expire_in": "8 weeks",
"paths": [
- "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan.tar.xz",
+ "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -3449,14 +3452,12 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan",
- "BUILD_FLAVOUR": "validate+debug_info+ubsan",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
+ "BUILD_FLAVOUR": "validate+debug_info",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "HADRIAN_ARGS": "--docs=none",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info+ubsan",
- "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions",
+ "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info",
"XZ_OPT": "-9"
}
},
@@ -7051,7 +7052,7 @@
"TEST_ENV": "x86_64-linux-deb13-zstd-validate"
}
},
- "x86_64-linux-fedora43-release": {
+ "x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -7062,7 +7063,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-fedora43-release.tar.xz",
+ "ghc-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -7088,7 +7089,7 @@
],
"rules": [
{
- "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && ((\"true\" == \"true\")))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-quick-validate\\+debug_info\\+ubsan\\+asan(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*test-sanitizers.*/)))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
@@ -7104,16 +7105,19 @@
"x86_64-linux"
],
"variables": {
+ "ASAN_OPTIONS": "detect_leaks=false:handle_segv=0:handle_sigfpe=0:verify_asan_link_order=false",
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
- "BUILD_FLAVOUR": "release",
- "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan",
+ "BUILD_FLAVOUR": "quick-validate+debug_info+ubsan+asan",
+ "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
+ "HADRIAN_ARGS": "--docs=none",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora43-release"
+ "TEST_ENV": "x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan",
+ "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions"
}
},
- "x86_64-linux-fedora43-release-hackage": {
+ "x86_64-linux-fedora43-release": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -7150,7 +7154,7 @@
],
"rules": [
{
- "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && ((\"true\" == \"true\")))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
@@ -7170,13 +7174,12 @@
"BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
"BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "HADRIAN_ARGS": "--haddock-for-hackage",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-fedora43-release"
}
},
- "x86_64-linux-fedora43-validate": {
+ "x86_64-linux-fedora43-release-hackage": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -7187,7 +7190,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-fedora43-validate.tar.xz",
+ "ghc-x86_64-linux-fedora43-release.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -7213,7 +7216,7 @@
],
"rules": [
{
- "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
@@ -7230,15 +7233,16 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
- "BUILD_FLAVOUR": "validate",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
+ "BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "HADRIAN_ARGS": "--haddock-for-hackage",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora43-validate"
+ "TEST_ENV": "x86_64-linux-fedora43-release"
}
},
- "x86_64-linux-fedora43-validate+debug_info": {
+ "x86_64-linux-fedora43-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -7249,7 +7253,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
+ "ghc-x86_64-linux-fedora43-validate.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -7275,7 +7279,7 @@
],
"rules": [
{
- "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+debug_info(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
@@ -7292,15 +7296,15 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
- "BUILD_FLAVOUR": "validate+debug_info",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
+ "BUILD_FLAVOUR": "validate",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info"
+ "TEST_ENV": "x86_64-linux-fedora43-validate"
}
},
- "x86_64-linux-fedora43-validate+debug_info+ubsan": {
+ "x86_64-linux-fedora43-validate+debug_info": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -7311,7 +7315,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan.tar.xz",
+ "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -7337,7 +7341,7 @@
],
"rules": [
{
- "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+debug_info\\+ubsan(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+debug_info(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
@@ -7354,14 +7358,12 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan",
- "BUILD_FLAVOUR": "validate+debug_info+ubsan",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
+ "BUILD_FLAVOUR": "validate+debug_info",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "HADRIAN_ARGS": "--docs=none",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info+ubsan",
- "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions"
+ "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info"
}
},
"x86_64-linux-rocky8-validate": {
=====================================
hadrian/doc/flavours.md
=====================================
@@ -218,6 +218,10 @@ The supported transformers are listed below:
<td><code>ubsan</code></td>
<td>Build all stage1+ C/C++ code with UndefinedBehaviorSanitizer support</td>
</tr>
+ <tr>
+ <td><code>asan</code></td>
+ <td>Build all stage1+ C/C++ code with AddressSanitizer support</td>
+ </tr>
<tr>
<td><code>llvm</code></td>
<td>Use GHC's LLVM backend (`-fllvm`) for all stage1+ compilation.</td>
=====================================
hadrian/src/Flavour.hs
=====================================
@@ -8,6 +8,7 @@ module Flavour
, splitSections
, enableThreadSanitizer
, enableUBSan
+ , enableASan
, enableLateCCS
, enableHashUnitIds
, enableDebugInfo, enableTickyGhc
@@ -58,6 +59,7 @@ flavourTransformers = M.fromList
, "thread_sanitizer" =: enableThreadSanitizer False
, "thread_sanitizer_cmm" =: enableThreadSanitizer True
, "ubsan" =: enableUBSan
+ , "asan" =: enableASan
, "llvm" =: viaLlvmBackend
, "profiled_ghc" =: enableProfiledGhc
, "no_dynamic_ghc" =: disableDynamicGhcPrograms
@@ -304,6 +306,28 @@ enableUBSan =
builder Testsuite ? arg "--config=have_ubsan=True"
]
+-- | Build all stage1+ C/C++ code with AddressSanitizer support:
+-- https://clang.llvm.org/docs/AddressSanitizer.html
+enableASan :: Flavour -> Flavour
+enableASan =
+ addArgs $
+ notStage0
+ ? mconcat
+ [ package rts
+ ? builder (Cabal Flags)
+ ? arg "+asan"
+ <> (staged needSharedLibSAN ? arg "+shared-libsan"),
+ builder (Ghc CompileHs) ? arg "-optc-fsanitize=address",
+ builder (Ghc CompileCWithGhc) ? arg "-optc-fsanitize=address",
+ builder (Ghc CompileCppWithGhc) ? arg "-optcxx-fsanitize=address",
+ builder (Ghc LinkHs)
+ ? pure ["-optc-fsanitize=address", "-optl-fsanitize=address"]
+ <> (staged needSharedLibSAN ? arg "-optl-shared-libsan"),
+ builder (Cc CompileC) ? arg "-fsanitize=address",
+ builder Testsuite
+ ? pure ["--config=have_asan=True", "-e", "config.timeout=1800"]
+ ]
+
-- | Use the LLVM backend in target stages
viaLlvmBackend :: Flavour -> Flavour
viaLlvmBackend = addArgs $ staged buildingForTarget ? builder Ghc ? arg "-fllvm"
=====================================
rts/Hash.c
=====================================
@@ -283,6 +283,7 @@ allocHashList (HashTable *table)
if (table->freeList != NULL) {
HashList *hl = table->freeList;
table->freeList = hl->next;
+ __ghc_asan_unpoison_memory_region(hl, offsetof(HashList, next));
return hl;
} else {
/* We allocate one block of memory which contains:
@@ -302,8 +303,11 @@ allocHashList (HashTable *table)
table->freeList = hl + 1;
HashList *p = table->freeList;
- for (; p < hl + HCHUNK - 1; p++)
+ for (; p < hl + HCHUNK - 1; p++) {
+ __ghc_asan_poison_memory_region(p, offsetof(HashList, next));
p->next = p + 1;
+ }
+ __ghc_asan_poison_memory_region(p, offsetof(HashList, next));
p->next = NULL;
return hl;
}
@@ -318,6 +322,7 @@ freeHashList (HashTable *table, HashList *hl)
// HashListChunks.
hl->next = table->freeList;
table->freeList = hl;
+ __ghc_asan_poison_memory_region(hl, offsetof(HashList, next));
}
STATIC_INLINE void
@@ -388,9 +393,10 @@ removeHashTable_inlined(HashTable *table, StgWord key, const void *data,
table->dir[segment][index] = hl->next;
else
prev->next = hl->next;
+ void *hl_data = (void*)hl->data;
freeHashList(table,hl);
table->kcount--;
- return (void *) hl->data;
+ return hl_data;
}
prev = hl;
}
=====================================
rts/Task.c
=====================================
@@ -183,6 +183,7 @@ freeTask (Task *task)
stgFree(incall);
}
for (incall = task->spare_incalls; incall != NULL; incall = next) {
+ __ghc_asan_unpoison_memory_region(incall, sizeof(InCall));
next = incall->next;
stgFree(incall);
}
@@ -252,6 +253,7 @@ newInCall (Task *task)
if (task->spare_incalls != NULL) {
incall = task->spare_incalls;
+ __ghc_asan_unpoison_memory_region(incall, sizeof(InCall));
task->spare_incalls = incall->next;
task->n_spare_incalls--;
} else {
@@ -283,6 +285,7 @@ endInCall (Task *task)
stgFree(incall);
} else {
incall->next = task->spare_incalls;
+ __ghc_asan_poison_memory_region(incall, sizeof(InCall));
task->spare_incalls = incall;
task->n_spare_incalls++;
}
=====================================
rts/include/Stg.h
=====================================
@@ -331,6 +331,7 @@ external prototype return neither of these types to workaround #11395.
#include "stg/MachRegsForHost.h"
#include "stg/Regs.h"
#include "stg/Ticky.h"
+#include "rts/ASANUtils.h"
#include "rts/TSANUtils.h"
#if IN_STG_CODE
=====================================
rts/include/rts/ASANUtils.h
=====================================
@@ -0,0 +1,33 @@
+#pragma once
+
+#if defined(__SANITIZE_ADDRESS__)
+#define ASAN_ENABLED
+#elif defined(__has_feature)
+#if __has_feature(address_sanitizer)
+#define ASAN_ENABLED
+#endif
+#endif
+
+#if defined(ASAN_ENABLED)
+#include <sanitizer/asan_interface.h>
+#define USED_IF_ASAN
+#else
+#include <stdlib.h>
+#define USED_IF_ASAN __attribute__((unused))
+#endif
+
+static inline void
+__ghc_asan_poison_memory_region(void const volatile *addr USED_IF_ASAN,
+ size_t size USED_IF_ASAN) {
+#if defined(ASAN_ENABLED)
+ __asan_poison_memory_region(addr, size);
+#endif
+}
+
+static inline void
+__ghc_asan_unpoison_memory_region(void const volatile *addr USED_IF_ASAN,
+ size_t size USED_IF_ASAN) {
+#if defined(ASAN_ENABLED)
+ __asan_unpoison_memory_region(addr, size);
+#endif
+}
=====================================
rts/rts.cabal
=====================================
@@ -97,6 +97,12 @@ flag ubsan
UndefinedBehaviorSanitizer.
default: False
manual: True
+flag asan
+ description:
+ Link with -fsanitize=address, to be enabled when building with
+ AddressSanitizer.
+ default: False
+ manual: True
flag shared-libsan
description:
Link with -shared-libsan, to guarantee only one copy of the
@@ -205,6 +211,9 @@ library
if flag(ubsan)
ld-options: -fsanitize=undefined
+ if flag(asan)
+ ld-options: -fsanitize=address
+
if flag(shared-libsan)
ld-options: -shared-libsan
@@ -283,6 +292,7 @@ library
-- ^ generated
rts/ghc_ffi.h
rts/Adjustor.h
+ rts/ASANUtils.h
rts/ExecPage.h
rts/BlockSignals.h
rts/Bytecodes.h
=====================================
rts/sm/BlockAlloc.c
=====================================
@@ -261,6 +261,8 @@ initGroup(bdescr *head)
head[i].flags = 0;
}
#endif
+
+ __ghc_asan_unpoison_memory_region(head->start, (W_)head->blocks * BLOCK_SIZE);
}
#if SIZEOF_VOID_P == SIZEOF_LONG
@@ -474,6 +476,7 @@ alloc_mega_group (uint32_t node, StgWord mblocks)
bd = alloc_mega_group_from_free_list(&deferred_free_mblock_list[node], n, &best);
if(bd)
{
+ __ghc_asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
return bd;
}
else if(!best)
@@ -490,6 +493,7 @@ alloc_mega_group (uint32_t node, StgWord mblocks)
if (bd)
{
+ __ghc_asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
return bd;
}
else if (best)
@@ -500,6 +504,7 @@ alloc_mega_group (uint32_t node, StgWord mblocks)
(best_mblocks-mblocks)*MBLOCK_SIZE);
best->blocks = MBLOCK_GROUP_BLOCKS(best_mblocks - mblocks);
+ __ghc_asan_unpoison_memory_region(MBLOCK_ROUND_DOWN(bd), mblocks * MBLOCK_SIZE);
initMBlock(MBLOCK_ROUND_DOWN(bd), node);
}
else
@@ -880,6 +885,8 @@ free_mega_group (bdescr *mg)
IF_DEBUG(sanity, checkFreeListSanity());
}
+
+ __ghc_asan_poison_memory_region(mg->start, (W_)mg->blocks * BLOCK_SIZE);
}
static void
@@ -927,6 +934,8 @@ free_deferred_mega_groups (uint32_t node)
// coalesce forwards
coalesce_mblocks(mg);
+ __ghc_asan_poison_memory_region(mg->start, (W_)mg->blocks * BLOCK_SIZE);
+
// initialize search for next round
prev = mg;
bd = prev->link;
@@ -1050,6 +1059,8 @@ freeGroup(bdescr *p)
setup_tail(p);
free_list_insert(node,p);
+ __ghc_asan_poison_memory_region(p->start, (W_)p->blocks * BLOCK_SIZE);
+
IF_DEBUG(sanity, checkFreeListSanity());
}
=====================================
rts/sm/GCUtils.c
=====================================
@@ -348,6 +348,7 @@ alloc_todo_block (gen_workspace *ws, uint32_t size)
} else {
if (gct->free_blocks) {
bd = gct->free_blocks;
+ __ghc_asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
gct->free_blocks = bd->link;
} else {
// We allocate in chunks of at most 16 blocks, use one
@@ -357,6 +358,9 @@ alloc_todo_block (gen_workspace *ws, uint32_t size)
StgWord n_blocks = stg_min(chunk_size, 1 << (MBLOCK_SHIFT - BLOCK_SHIFT - 1));
allocBlocks_sync(n_blocks, &bd);
gct->free_blocks = bd->link;
+ for (bdescr *bd = gct->free_blocks; bd; bd = bd->link) {
+ __ghc_asan_poison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
+ }
}
}
initBdescr(bd, ws->gen, ws->gen->to);
=====================================
rts/sm/MBlock.c
=====================================
@@ -641,6 +641,8 @@ getMBlocks(uint32_t n)
ret = getCommittedMBlocks(n);
+ __ghc_asan_unpoison_memory_region(ret, (W_)n * MBLOCK_SIZE);
+
debugTrace(DEBUG_gc, "allocated %d megablock(s) at %p",n,ret);
mblocks_allocated += n;
@@ -673,6 +675,8 @@ freeMBlocks(void *addr, uint32_t n)
mblocks_allocated -= n;
+ __ghc_asan_poison_memory_region(addr, (W_)n * MBLOCK_SIZE);
+
decommitMBlocks(addr, n);
}
=====================================
rts/sm/Storage.c
=====================================
@@ -1242,6 +1242,10 @@ start_new_pinned_block(Capability *cap)
ACQUIRE_SM_LOCK;
bd = allocNursery(cap->node, NULL, PINNED_EMPTY_SIZE);
RELEASE_SM_LOCK;
+
+ for (bdescr *pbd = bd; pbd; pbd = pbd->link) {
+ __ghc_asan_poison_memory_region(pbd->start, (W_)pbd->blocks * BLOCK_SIZE);
+ }
}
// Bump up the nursery pointer to avoid the pathological situation
@@ -1267,6 +1271,7 @@ start_new_pinned_block(Capability *cap)
}
cap->pinned_object_empty = bd->link;
+ __ghc_asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
newNurseryBlock(bd);
if (bd->link != NULL) {
bd->link->u.back = cap->pinned_object_empty;
=====================================
testsuite/driver/testglobals.py
=====================================
@@ -197,6 +197,9 @@ class TestConfig:
# Are we running with UndefinedBehaviorSanitizer enabled?
self.have_ubsan = False
+ # Are we running with AddressSanitizer enabled?
+ self.have_asan = False
+
# Do symbols use leading underscores?
self.leading_underscore = False
=====================================
testsuite/driver/testlib.py
=====================================
@@ -1118,6 +1118,9 @@ def have_thread_sanitizer( ) -> bool:
def have_ubsan( ) -> bool:
return config.have_ubsan
+def have_asan( ) -> bool:
+ return config.have_asan
+
def gcc_as_cmmp() -> bool:
return config.cmm_cpp_is_gcc
=====================================
testsuite/tests/ffi/should_run/all.T
=====================================
@@ -192,6 +192,9 @@ test('rts_clearMemory', [
extra_ways(['g1', 'nursery_chunks', 'nonmoving', 'compacting_gc', 'sanity']),
# On windows, nonmoving way fails with bad exit code (2816)
when(opsys('mingw32'), fragile(23091)),
+ # For simplicity, ASAN poisoning/unpoisoning logic is omitted
+ # from rts_clearMemory implementation
+ when(have_asan(), skip),
req_c,
pre_cmd('$MAKE -s --no-print-directory rts_clearMemory_setup') ],
# Same hack as ffi023
=====================================
testsuite/tests/rts/T18623/all.T
=====================================
@@ -8,6 +8,8 @@ test('T18623',
# Recent versions of osx report an error when running `ulimit -v`
when(opsys('darwin'), skip),
when(arch('powerpc64le'), skip),
+ # ASan can't allocate shadow memory
+ when(have_asan(), skip),
cmd_prefix('ulimit -v ' + str(8 * 1024 ** 2) + ' && '),
ignore_stdout],
run_command,
=====================================
testsuite/tests/rts/all.T
=====================================
@@ -105,6 +105,8 @@ def remove_parenthesis(s):
return re.sub(r'\s+\([^)]*\)', '', s)
test('outofmem', [ when(opsys('darwin'), skip),
+ # ASan shadow memory allocation blows up
+ when(have_asan(), skip),
# this is believed to cause other processes to die
# that happen concurrently while the outofmem test
# runs in CI. As such we'll need to disable it on
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68053a558b154c0220acce9b5e5429…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68053a558b154c0220acce9b5e5429…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/terrorjack/asan] 107 commits: Implement List.elem via foldr
by Cheng Shao (@TerrorJack) 23 Jun '26
by Cheng Shao (@TerrorJack) 23 Jun '26
23 Jun '26
Cheng Shao pushed to branch wip/terrorjack/asan at Glasgow Haskell Compiler / GHC
Commits:
72c8de5c by Simon Jakobi at 2026-05-23T18:41:42-04:00
Implement List.elem via foldr
...in order to allow specialization to Eq instances.
The implementation of notElem is updated for consistency.`
Corresponding CLC proposal:
https://github.com/haskell/core-libraries-committee/issues/412
Addresses #27096.
- - - - -
3268c610 by Alan Zimmerman at 2026-05-23T18:42:30-04:00
EPA: Fix span for qualified multiline string
Fix the span for a qualified multiline string like
Text."""
I'm a multiline
Text value
!
"""
to extend to the end of the entire string, not just the first line.
Closes #27274
- - - - -
1f096790 by Alan Zimmerman at 2026-05-23T18:43:20-04:00
EPA: Fix exact printing namespace-specified wildcards
Ensures correct printing of imports of the form
import Data.Bool (data True(data ..))
import Data.Bool (data True(type ..))
Closes #27291
- - - - -
56ada7c0 by Mrjtjmn at 2026-05-23T18:44:19-04:00
Fix ambiguous syntax of BangPatterns in users guide
Update documentation for the BangPatterns extension to specify
how surrounding whitespace affects interpretation of `!`.
* Only when there is whitespace before `!` and no whitespace after,
it is recognized as a BangPattern.
* Other cases `⟨varid⟩!⟨varid⟩`, `⟨varid⟩ ! ⟨varid⟩`, `⟨varid⟩! ⟨varid⟩`
are treated as infix operators.
- - - - -
579aa0b7 by Simon Jakobi at 2026-05-25T16:31:26-04:00
Ensure that SetOps.{minusList,unionListsOrd} can be specialized
...by marking them INLINABLE. Haddock allocates 0.1–0.3% less as a
result.
This also removes some redundant constraints on unionListsOrd.
- - - - -
cccf45da by Cheng Shao at 2026-05-25T16:32:13-04:00
wasm: ensure post-linker output is synchronous ESM
This patch fixes wasm backend's post-linker output script to ensure
it's synchronous ESM and doesn't use top-level await, which doesn't
work in ServiceWorkers. Fixes #27257.
- - - - -
8db331a3 by Zubin Duggal at 2026-05-26T04:54:03-04:00
Update to semaphore-compat 2.0.0 using v2 of the protocol
On Linux and other POSIX platforms, GHC's -jsem jobserver client now
speaks v2 of the semaphore-compat protocol, which uses Unix domain
sockets in place of POSIX named semaphores. This avoids the libc-ABI
issues that affected the old implementation. Windows is unaffected
and continues to use the v1 protocol (Win32 named semaphores); its
reported protocol version remains v1.
When GHC receives a -jsem name whose protocol version it does not
support, it emits a -Wsemaphore-version-mismatch warning and falls
back to -j<N> rather than crashing. ghc --info exposes the supported
version in a new "Semaphore version" entry so cabal-install can detect
a mismatch before invoking GHC.
Users on a cabal-install that predates the v2 update will continue to
build successfully on Linux/POSIX, but will lose the cross-process
-jsem coordination and fall back to -j<N> per GHC invocation. Users
must upgrade to a cabal-install that supports protocol v2 to recover
full parallelism.
Also fix a leak in cleanupSem (#27253): cleanupSem used to snapshot
heldTokens and release them before killing the loop, while the loop's
in-flight acquire/release children could still be mutating it.
Cleanup now runs inside the loop's own exit handler, after draining
the active child via a new activeChild TVar, so the snapshot has no
concurrent mutator.
See also:
- GHC proposal amendment: https://github.com/ghc-proposals/ghc-proposals/pull/673
- cabal-install patch: https://github.com/haskell/cabal/pull/11628
- semaphore-compat MR: https://gitlab.haskell.org/ghc/semaphore-compat/-/merge_requests/8
Bump semaphore-compat submodule to 2.0.0
Fixes #25087 and #27253
- - - - -
17be4f1f by Alan Zimmerman at 2026-05-26T04:54:52-04:00
EPA: Record semicolons in HsModifier
Ensure the semi colons are captured in the ParsedSource for code like
%True;; %False;
instance C D
It makes HsModifier (and hence HsModifierOf) LocatedA, so the semi
colons can be recorded as [TrailingAnn]
Also rename pprHsModifiers to pprLHsModifiers to match.
Closes #27294
- - - - -
8f991755 by fendor at 2026-05-26T11:02:52-04:00
Revert prog003 acceptance
We thought the commit 286f1adff3e78d775ff325caff71d0cee25d710b fixed the
test, but due to changes to ghci, modules loaded during the GHCi
session, the test was actually no longer testing what it set out to do,
"fixing" the broken test.
As modules are added to the `interactive-session` home unit, the object code needs
to be compiled with `-this-unit-id interactive-session`, otherwise the
object code won't be used.
Once this has been fixed in the test, the test fails as expected again.
- - - - -
277a3687 by mangoiv at 2026-05-26T11:03:40-04:00
libraries/process: bump submodule to v1.6.29.0
This submodule bump resolves a segfault on macos 15.
Fixes #27144
- - - - -
6779bb0c by mangoiv at 2026-05-26T11:03:40-04:00
libraries/unix: in submodule, don't pick branch 2.7
The 2.7 branch is outdated and the module has been advanced far beyond
it anyway, so remove that line.
- - - - -
4a645683 by Simon Peyton Jones at 2026-05-27T21:41:59-04:00
Trim the continuation in mkDupableContWithDmds
When there are no remaining argument demands, it means the application
is bottoming. In this case, we can trim the continuation to avoid the
panic that was observed in #27261.
See Note [Trimming the continuation for bottoming functions] in
GHC.Core.Opt.Simplify.Iteration.
- - - - -
8ab506ff by Cheng Shao at 2026-05-27T21:42:47-04:00
ghci: fix module name string lifetime in hs_hpc_module invocation
This patch makes hpcAddModule pass a properly malloced module name
string to hs_hpc_module, instead of using useAsCString which causes
use-after-free of module name string. Fixes #27297.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
b0233814 by sheaf at 2026-05-27T21:43:31-04:00
Relax acceptance threshold for T10421
As seen in #27289, the 1% acceptance threshold for this text was
overly narrow, resulting in spurious test failures. This commit widens
the acceptance threshold to 2%. Fixes #27289.
- - - - -
63ce5770 by Luite Stegeman at 2026-05-28T12:23:35-04:00
Fixes for black holes
- suspend duplicate work for eager black holes
- detect eager black holes in checkBlockingQueues
- don't overwrite existing black holes even if they're not
in an eager blackhole frame
- don't deadlock on self when thunk is already blackholed
Fixes #26936
- - - - -
037a80dc by Tom McLaughlin at 2026-05-28T12:24:36-04:00
Event/Windows.hsc: rethrow exceptions in overlapped IO
This prevents the WinIO manager from swallowing exceptions in overlapped IO. It
was added to make WinIO support possible in the `network` library. See
https://gitlab.haskell.org/ghc/ghc/-/issues/27283.
We also bump __IO_MANAGER_WINIO__ to 2 so libraries can gate on this using CPP.
- - - - -
2d53bcdb by Wolfgang Jeltsch at 2026-05-28T12:25:21-04:00
Allow `downsweep` to use nodes of an existing module graph
To this end, `downsweep` has not been able to use the nodes of a module
graph obtained from a previous downsweeping round. In some GHC API
applications, downsweeping is performed somewhat incrementally and
therefore could profit from reusing such existing results. This
contribution makes this possible.
Resolves #27054.
Co-authored-by: Matthew Pickering <matthewtpickering(a)gmail.com>
- - - - -
f4fbb583 by Simon Jakobi at 2026-05-28T12:26:04-04:00
Add regression test for T11226
Closes #11226.
- - - - -
ed29a5e6 by Sven Tennie at 2026-05-28T17:30:36-04:00
Add optional config setting for LibDir (#19174)
Previously, the `libDir` was derived from `topDir`. This won't work for
inplace stage2 cross-compilers where binaries and libraries are in
different stage dirs (`_build/stage1/` for executables and
`_build/stage2` for libraries).
`LibDir` is set in the inplace `settings` files. For bindists, we
generate a new `settings` file with no `LibDir` entry. GHC then defaults
to use `topDir` as `libDir` again. This keeps the bindist relocatable.
If `LibDir` is a relative path, it is interpreted relatively to
`topDir`.
The global package db is part of the `lib/` folder. If we want to point
for inplace cross-compilers to the succeeding stage's folder, this is
done by setting `LibDir`. Thus, the global package db must be found
relative to `libDir`` (which may default to `topDir` or be set by
`LibDir`).
The complexity of settings becomes scary. So, add a test to ensure
`LibDir` works as expected.
- - - - -
8339cf8f by Sven Tennie at 2026-05-28T17:30:36-04:00
Add Haddock to FileSettings
Helping to understand the fields' meanings without deeper analyses.
- - - - -
4ce251e4 by Sylvain Henry at 2026-05-28T17:31:39-04:00
foundation test: skip signed minBound `quot` (-1) (#27222)
`minBound `quot` (-1)` for fixed-width signed integers is platform
dependent: the mathematical result -minBound is not representable in
the type. On x86, IDIV traps; LLVM's sdiv is undefined behaviour in
this case; on AArch64/RISC-V, SDIV wraps to minBound.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
b8ba7e61 by Simon Jakobi at 2026-05-28T17:32:23-04:00
Prevent dictionary-passing in checkTyEqRhs
...by pre-specializing it to TcM.
Previously, wherever checkTyEqRhs was used in other modules, the
Core showed dictionary passing ($fMonadIOEnv). The added SPECIALIZE
pragma prevents this.
- - - - -
d603477f by David Eichmann at 2026-05-29T13:17:12-04:00
Hadrian: create a ghc-internal .def file per ghc-internal dll
The .def file generated from rts/win32/libHSghc-internal.def.in contains
the name of the ghc-internal dll. The correct dll name differs based
on if the dll is inplace/final and if using the Dynamic way. Previously,
this was not accounted for and inconsistent dlls names where used. That
led to failure when loading dlls at runtime in experiments with windows
dynamic linking.
- - - - -
1fc21753 by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: copy backend interface haddocks to Native backend (#27305)
The haddock comments documenting the BigNat backend interface (function
contracts, expected MutableWordArray# sizes, return-value semantics, etc.)
were attached to the FFI backend module. Copy them to the Native backend
so they remain in tree once the FFI backend is removed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
717059df by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: remove FFI backend (#27305)
The FFI backend of ghc-bignum (now part of ghc-internal) had no known
users and is easy to recreate by relinking ghc-internal with a custom
backend. Remove the backend module, the bignum-ffi cabal flag, and the
ffi option from Hadrian's --bignum selector. The backend interface
documentation now lives in the Native backend module.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
4bb3b1d8 by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: remove Check backend (#27305)
The Check backend of ghc-bignum (now part of ghc-internal) compared the
selected backend's output against the Native backend for validation.
It had no known users. Remove the backend module, the bignum-check
cabal flag, the bignumCheck Hadrian flavour field, and the check-
prefix in Hadrian's --bignum selector.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
6b3044a0 by David Eichmann at 2026-05-30T11:58:48-04:00
Add code comments to allocator code
- - - - -
f4e04210 by Matthew Pickering at 2026-05-30T11:59:34-04:00
hadrian: Refactor system-cxx-std-lib rules
I noticed a few things wrong with the hadrian rules for
`system-cxx-std-lib` rules.
* For `text` there is an ad-hoc check to depend on `system-cxx-std-lib`
outside of `configurePackage`.
* The `system-cxx-std-lib` dependency is not read from cabal files.
* Recache is not called on the packge database after the `.conf` file is
generated, a more natural place for this rule is `registerRules`.
Treating this uniformly like other packages is complicated by it not
having any source code or a cabal file. However we can do a bit better
by reporting the dependency firstly in `PackageData` and then needing
the `.conf` file in the same place as every other package in
`configurePackage`.
This commit increases the `shakeVersion`, to provide backwards
compatibility to previous builds with different PackageData.
Fixes #25303
Co-authored-by: Sven Tennie <sven.tennie(a)gmail.com>
- - - - -
576987d0 by Simon Jakobi at 2026-06-02T04:53:36-04:00
compiler: use nubOrd from containers
Address #27103 by replacing GHC.Utils.Misc.ordNub[On] with
Data.Containers.ListUtils.nubOrd[On].
Note that nubOrd suffers from a small inefficiency, a fix for which
will be included in the next containers release:
https://github.com/haskell/containers/issues/1202
- - - - -
deea53c3 by David Eichmann at 2026-06-02T04:54:22-04:00
Hadrian: disable response files for GHC/Haddock builders on non-Windows
This makes debugging build errors easier on non-windows hosts.
See issue #27230
- - - - -
f2f5c6ba by Nikita Efremov at 2026-06-02T16:04:54+00:00
fix typo : compete with performance, not complete
- - - - -
5524ea0e by Wolfgang Jeltsch at 2026-06-03T08:01:26-04:00
Make the current `base` buildable with GHC 9.14
This comprises the following changes:
* Disable some imports into `GHC.Base` for GHC 9.14
* Disable some imports into `Prelude` for GHC 9.14
* Disable separate `ArrowLoop` import for GHC 9.14
* Disable `GHC.Internal.STM` import for GHC 9.14
* Disable `GHC.Internal.Unicode.Version` import for GHC 9.14
* Disable `GHC.Internal.TH.Monad` import for GHC 9.14
* Add alternative `fixIO` import for GHC 9.14
* Add alternative `unsafeCodeCoerce` import for GHC 9.14
* Disable hiding of imported SIMD operations for GHC 9.14
* Disable use of GHC 9.14’s `printToHandleFinalizerExceptionHandler`
* Enable use of `getFileHash` from `ghc-internal` for GHC 9.14
* Make `thenA` available for GHC 9.14
* Make `thenM` available for GHC 9.14
* Disable translation of `IoManagerFlagPoll` for GHC 9.14
* Add `hGetNewlineMode` for GHC 9.14
- - - - -
d3438055 by Enrico Maria De Angelis at 2026-06-03T08:02:17-04:00
Fix #27067 - Clarify haddocks on `minusNaturalMaybe`
- - - - -
f9bcfac2 by sheaf at 2026-06-03T14:47:19-04:00
Avoid mkTick in Core Prep breaking ANF
As discovered in #27182, mkTick can break ANF. This patch introduces a
variant of mkTick that skips the single optimisation that could break
ANF. This is preferrable over switching to the raw Tick constructor,
as the latter may introduce spurious cost centres in profiling reports.
This is a temporary measure until we more thoroughly refactor how
mkTick works (see #27141).
See Note [mkTick breaks ANF] in GHC.CoreToStg.Prep.
Fixes #27182
- - - - -
cf1fd661 by Artem Pelenitsyn at 2026-06-03T14:48:09-04:00
clarify comment for getSizeofMutableByteArray#: we get the size in bytes, not "elements"
- - - - -
a3b431f3 by David Eichmann at 2026-06-04T10:10:19+00:00
Hadrian: convert env variable ACLOCAL_PATH to unix paths.
Convert ACLOCAL_PATH to a unix style path when invoking autoreconf.
Autoreconf doesn't handle windows paths.
See Note [Autoreconf unix paths from ACLOCAL_PATH].
Fixes #27311
- - - - -
18f6138a by Simon Jakobi at 2026-06-04T20:20:31-04:00
testsuite: Deduplicate --only test names
config.only is assumed to be a set, but supplying --only overwrote it
with the (list) argparse result, which can contain duplicates. When a
test ran, config.only.remove(name) dropped only the first occurrence,
so a duplicated name lingered and was later misreported as a
"test not found" framework failure. Store it as a set instead.
Fixes #27322
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
2f3cc9ff by Simon Jakobi at 2026-06-08T07:55:49-04:00
testsuite: detect fast bignum via ghc-internal, not removed ghc-bignum
The ghc-bignum package was merged into ghc-internal, so the BIGNUM_GMP
probe in test.mk ran `ghc-pkg field ghc-bignum exposed-modules`, which
fails with "cannot find package ghc-bignum". That error went to stderr
and leaked into the captured stderr of every makefile_test, causing
spurious [bad stderr] failures across the suite. The probe also silently
returned empty, so config.have_fast_bignum was wrongly False even on GMP
builds.
Probe ghc-internal's extra-libraries for the gmp library instead: the
GMP backend module is an other-module (not exposed), but GMP_LIBS adds
gmp to extra-libraries only on a GMP build, so this distinguishes the
backends. Redirect stderr to keep any future missing-package error off
the harness's stderr.
This also removes a stale comment as per suggestion from hsyl20.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
eb3bf6e7 by Alan Zimmerman at 2026-06-08T07:56:32-04:00
EPA: Rename Transform.anchorEof to addModuleCommentOrigDeltas
This now matches what it actually does.
- - - - -
498bb21a by David Eichmann at 2026-06-09T18:02:39-04:00
Hadrian: avoid response files when command line is short enough
This replaces the logic of always using response files on Windows.
With the new condition based on command line lenght, reponse files
can be avoided in many more cases (on windows).
Now that response files are only used in a small number of cases,
response files are always kept and the -r / --keep-response-files
command line options have been removed
The response file paths are nolonger randomized. They are placed in the
`_build/rsp` directory. This ensures they are ignored by git and we
that Hadrian reuses response file paths when rebuilding rather than
leaving stale response files around.
Update user guide putting response files in its own section
- - - - -
87f510a5 by Simon Hengel at 2026-06-09T18:03:25-04:00
Don't use non-breaking spaces
- - - - -
41a19379 by David Eichmann at 2026-06-09T18:04:11-04:00
Hadrian: remove unused wrapper scripts from windows bindist
These wrapper scripts are only installed on non-relocatable builds
which are not generally supported on windows.
- - - - -
ce01ccb6 by sheaf at 2026-06-10T05:08:48-04:00
Don't drop ticks around variables of type `IO ()`
GHC.Core.Utils.mkTick is responsible for placing a tick on a Core
expression. It contains logic for dropping SCCs (non-counting profiling
ticks) around non-function variables, as such variables cannot
meaningfully contribute to profiles. However, the logic for what counts
as a function was incorrect: it used `isFunTy` which returns 'False' for
types such as 'IO ()' where the function arrow is hidden under a
newtype.
We now use 'mightBeFunTy' instead of 'isFunTy'. This ensures we don't
drop ticks in cases we aren't sure.
On the way, we improve the documentation of 'isFunTy', 'isPiTy' and
'mightBeFunTy', and update the latter's implementation to consistently
handle unary classes.
Fixes #27225
-------------------------
Metric Decrease:
T5642
-------------------------
- - - - -
d311c4f1 by Simon Jakobi at 2026-06-10T05:09:32-04:00
testsuite: Add regression test for #4081
Check that a strict constructor field is unboxed once outside an
enclosing loop, not re-inspected each iteration (the float-out
case-floating from 9cb20b488). Uses simonpj's `data T a = T !a` example
from the ticket; T4081.stderr captures the expected Core.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
333df444 by sheaf at 2026-06-10T05:10:25-04:00
Check for cabal-install >= 3.12 upfront
Starting with commit 8cb99552f607f6bc4000e45ab32532d50c8bb996, Hadrian
requires cabal-install >= 3.12 in order to use the 'cabal path' command
that was introduced in version 3.12, as per
https://github.com/haskell/cabal/blob/a51c4ee1556d816ad86e90db7e6330dd51b0b…
This was not reflected in the Hadrian build script, causing a delayed
build failure instead of enforcing the version requirement upfront,
which this patch does.
Fixes #27317
- - - - -
98c20394 by sheaf at 2026-06-10T05:11:09-04:00
Fix crash in Data.Data instance for HsCtxt
The Data.Data instance for HsCtxt contained an error for the 'toConstr'
method, which could trigger for example when looking at -ddump-tc-ast
traces. Replace it with the 'abstractConstr' pattern used in the rest of
the codebase.
- - - - -
5ac9ce7d by Zubin Duggal at 2026-06-10T21:26:32+05:30
hadrian: Remove old package.conf files when generating new ones
Old package.conf files might exists with different hashes, causing issues like #26661
Fixes #26661
- - - - -
c9015f09 by sheaf at 2026-06-11T12:40:28-04:00
Fix AArch64 clobbering bug for MUL2
On AArch64, the code generator could clobber one of the input operands
when computing the lower bits of a MUL2 operation. This rendered invalid
the subsequent computation of the high bits.
This commit fixes that by using a temporary register. The register
allocator can remove the redundant move in the common case when the
registers do not conflict.
Fixes #27046
- - - - -
7ab90288 by Rodrigo Mesquita at 2026-06-11T12:41:11-04:00
fix: make T27131 less flaky
It seems that T27131 fails flakily in a race where we check the flag
before the capability had the chance to process the mailbox which sets
the flag. This seemingly should only happen if the capability ends up
being the same for setting and checking the flag.
- - - - -
8965cb76 by Marc Scholten at 2026-06-12T04:53:22-04:00
haddock: render modules concurrently
- - - - -
8cc0b64a by Duncan Coutts at 2026-06-12T04:54:06-04:00
Promote HAVE_PREEMPTION from Timer.c to OSThreads.h
We will want to know about HAVE_PREEMPTION in more places.
HAVE_PREEMPTION tells us that we do have OS threads available,
irrespective of whether THREADED is defined. In particular,
HAVE_PREEMPTION is defined on all proper OSs, but not on WASM (and
hyopthetically may not be true on some other platforms like
micro-controllers, RTOSs, VM hypervisors etc).
- - - - -
cce574ed by Duncan Coutts at 2026-06-12T04:54:06-04:00
Define ACQUIRE_LOCK_ALWAYS and friends
Fix issue #27335
Like the atomic _ALWAYS variants, these lock actions are always defined,
rather than being dependent on whether we are in the THREADED case. All
the "normal" LOCK macros are defined to be no-ops when !THREADED.
The use case for the _ALWAYS variants is where we are using OS threads
even in the non-threaded RTS. This includes everything to do with the
timer/ticker thread, which is used in the non-threaded RTS too.
In particular, we will want to use this for eventlog things, because the
timer thread performs eventlogging concurrently with the main
capability, even in the non-threaded RTS.
- - - - -
1f28d1f6 by Duncan Coutts at 2026-06-12T04:54:06-04:00
Use ACQUIRE/RELEASE_LOCK_ALWAYS with eventBufMutex
Even in the non-threaded RTS the eventBufMutex is needed by both the
main capability and the timer/ticker thread, so always use the mutex.
This should fix #25165 which is about the main capability and the timer
thread posting events to the eventlog buffer concurrently and thereby
corrupting the buffer data.
- - - - -
0ff29782 by Duncan Coutts at 2026-06-12T04:54:06-04:00
Expose eventBufMutex in the EventLog interface/header
We will need it in forkProcess to ensure we don't write to the global
eventlog buffer concurrently with trying to flush eventlog buffers and
do the fork().
- - - - -
7a688395 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Split flushAllCapsEventsBufs into safe and unlocked version
Following the convention that unlocked versions have a trailing _
underscore in their name. This one requires the caller to hold the
eventlog global buffer mutex. We will need this in forkProcess.
- - - - -
341ed474 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Remove redundant use of stopTimer in setNumCapabilities
Historically, the comment here was:
We must stop the interval timer while we are changing the
capabilities array lest handle_tick may try to context switch
an old capability. See #17289.
and
We must disable the timer while we do this since the tick handler may
call contextSwitchAllCapabilities, which may see the capabilities array
as we free it.
What this refers to is that historically, when changing the number of
capabilities, the array of capabilities was reallocated to a new size,
allocating new ones and freeing the old ones, thus invalidating all
existing capbility pointers.
Strangely, for good measure the code used to call stopTimer twice (hence
the two similar comments above).
However, since commit a3eccf06292dd666b24606251a52da2b466a9612, the
capabilities array is no longer reallocated. Instead the array is
allcoated once on RTS startup to the maximum size it could ever be
allowed to be, and then capabilities get enabled/disabled at runtime. So
the capability pointers never become invalid anymore. At worst, they may
point to capabilities that are disabled.
Thus we no longer need to stop the timer (twice) while we change the
number of enabled capabilities. This also partially solves issue #27105,
which notes that stopTimer is being used as if it were synchronous, when
it is not. At least for this case, the solution is that stopTimer is not
needed at all!
- - - - -
674858e3 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Remove redundant use of stopTimer in forkProcess
but replace it with taking the eventlog buffer lock during the fork.
Fixes issue #27105
The original reason to block the timer during a fork was that
historically the timer was implemented using a periodic timer signal,
and the signal itself would interrupt the fork system call (returning
EINTR). For large processes (where fork() takes a while) this could
permanently livelock: the timer always would go off before the fork
could complete, which got retried in a loop forever.
The timer is no longer implemented as a unix signal, but uses threads.
Thus the original problem no longer exists. The only remaining reason to
block the timer tick is to prevent actions taken by the tick from
interfering with the delicate process involved in fork (taking a load of
locks and pausing everything).
The only thing we need to do is to prevent the eventlog from being
written to or flushed while the fork is taking place. To achieve this
all we need to do is hold the mutex for the global eventlog buffer.
This removes the last use of stopTimer that expects stopTimer to work
synchronously (which it was not) and thus solves issue #27105. To be
clear, we solve issue #27105 not by making stopTimer synchronous, but by
eliminating the use sites that expected it to be synchronous.
- - - - -
40764930 by sheaf at 2026-06-12T14:54:43-04:00
Add type family performance test for #26426
Some GHC versions produced large numbers of coercions after typechecking
and desugaring when compiling the program in #26426:
Version | Typechecker time | Typechecker allocations | Coercions
-------:|-----------------:|------------------------:|---------:
9.6 | 47 ms | 48 MB | 110k
9.8 | 1000 ms | 486 MB | 10,437k
9.10 | 922 ms | 489 MB | 10,436k
9.12 | 906 ms | 482 MB | 10,437k
9.14 | 63 ms | 55 MB | 333k
10.0 | 47 ms | 64 MB | 35k
The improvement 9.12 -> 9.14 was due to commit 22d11fa818fae2c95c494fc0fac1f8cb4c6e7cb6,
while the improvement 9.14 -> 10.0 was due to commit 0b7df6db9e46df40e86fbff1a66dc10440b99db5.
As the behaviour of GHC seems better than it's ever been on this program,
we declare victory, adding this performance test to ensure we don't
regress on this program.
On the way, we update Note [Combining equalities] in GHC.Tc.SolveR.Equality
with the explanation of the 9.12 -> 9.14 improvement (getting rid of an
exponential blowup in coercion sizes), and we update
Note [Exploiting closed type families] in GHC.Tc.Solver.FunDeps with
the explanation of the 9.14 -> 10.0 improvement (bringing down coercion
size growth from cubic to quadratic).
- - - - -
0f3d0a71 by Zubin Duggal at 2026-06-12T14:55:30-04:00
compiler: mark tool messages as errors/warnings depending on the exit code
Fixes #27370
- - - - -
d9ea2d76 by mangoiv at 2026-06-13T04:41:51-04:00
libraries/process: bump submodule to v1.6.30.0
- bump the submodule to the appropriate tag
- suppress benign warning resulting from the change
- - - - -
6ebaaba3 by David Eichmann at 2026-06-13T04:42:37-04:00
ghc-toolchain: don't throw when candidate executables are not found
Fixes #27369
- - - - -
6c65e1e1 by David Eichmann at 2026-06-13T04:43:23-04:00
CI: lint-changelog checks for no-changelog label in script instead of rules
- - - - -
bab37cc6 by konsumlamm at 2026-06-13T19:10:21+02:00
Implement CLC proposal #378
Add `Data.Double` and `Data.Float` modules
Document that GHC uses IEEE 754
- - - - -
fb5246ad by fendor at 2026-06-15T18:07:23-04:00
Drop `preloadClosure` from `UnitState`
It is always hard-coded to the same value.
Backpack Unit instantiation isn't using it any more.
Allows us to simplify the API and get rid of `improveUnit`.
- - - - -
291ce3aa by ARATA Mizuki at 2026-06-15T18:08:26-04:00
RISC-V NCG: Zero-extend the result of castFloatToWord32
According to the ISA manual, FMV.X.W sign-extends the result.
We need to truncate the result to avoid creating an exotic Word32 value.
Fixes #27300
- - - - -
011be91f by ARATA Mizuki at 2026-06-15T18:08:26-04:00
RISC-V NCG: Treat d28-d31 (ft8-ft11) as caller-saved
According to the calling convention, the registers d28-d31 (ft8-ft11) are caller-saved.
Fixes #27306
- - - - -
e8a54713 by ARATA Mizuki at 2026-06-15T18:08:26-04:00
RISC-V NCG: Set rounding mode when emitting `truncate`
If we omit the rounding mode for `fcvt`, `dyn` will be used.
We do not want that for `truncate`, so we set `rtz`.
In other places, we set `rne` because we do not use the dynamic rounding mode.
Fixes #27303
- - - - -
9438bec7 by Zubin Duggal at 2026-06-15T18:09:11-04:00
rts: fix validate build with gcc 16. `__attribute__((regparm(1)))` is ignored on x86_64 and now
gcc warns that it is ignored:
rts/sm/Evac.h:35:1: error:
error: ‘regparm’ attribute ignored [-Werror=attributes]
See https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=ccead81bbc39668376eb5cf47066a…
Fixes #27366
- - - - -
893e6133 by Andrew Lelechenko at 2026-06-15T23:55:36+01:00
base: more NonEmpty zips
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/409
- - - - -
1314f2fd by David Eichmann at 2026-06-16T05:46:52-04:00
Hadrian: fix ghc-internal .def file name
- - - - -
7f72bcb3 by mangoiv at 2026-06-16T05:47:39-04:00
compiler: ignore camelCase and Eta reduce hlint hints
These do not cohere with the style used in GHC. After disabling them,
hlint lints are much less noisy again.
- - - - -
842bef9f by Alan Zimmerman at 2026-06-16T05:48:25-04:00
EPA: Use standard type family declaration for Anno
- - - - -
f6d30767 by Wolfgang Jeltsch at 2026-06-16T15:32:34-04:00
Fix two issues in the documentation of pipeline interruption
One issue is a typo (“interreuptible”), the other one the lack of an end
of a sentence, which has been reconstructed from the message of
633bbc1fd4762a2bb73ba1c5b9e0c279f1dd3c40, the commit that introduced
said documentation.
- - - - -
a3fa10e0 by Christian Georgii at 2026-06-16T15:33:26-04:00
Find plugins in sibling home units in multiple-home-unit sessions
In a multiple-home-unit session (e.g. `cabal repl --enable-multi-repl` or HLS), enabling a plugin with -fplugin that is defined in (or reexported by) another home unit failed with a "hidden package" error. The plugin module finder only searched the current home unit and the registered external packages, never the sibling home units.
findPluginModuleNoHsc now searches the home units that the current home unit depends on, following module reexports and respecting hidden modules, exactly as ordinary import resolution does in findImportedModuleNoHsc. To avoid two divergent copies of this logic, the shared home-unit search (the current home unit first, then its dependencies in priority order, with the accompanying ordering invariant) is extracted into findHomeModuleAmongDeps, which both findImportedModuleNoHsc and findPluginModuleNoHsc now call.
Add testsuite/tests/driver/multipleHomeUnits/plugin01, which loads a plugin as byte-code from a sibling home unit, and plugin02, in which the consumer enables a plugin reexported by a sibling home unit without depending on the plugin's own home unit directly.
Fixes #27349
- - - - -
d216412b by Ian-Woo Kim at 2026-06-16T20:25:57-04:00
Make the order of usages deterministic
It has been observed that the ordering of usages can be non-determinstic
in parallel builds. Therefore, this contribution introduces sorting of
usages based on a platform- and race-independent sorting criterion.
Resolves #26877.
Co-authored-by: Wolfgang Jeltsch <wolfgang(a)well-typed.com>
- - - - -
8e1cc105 by Wolfgang Jeltsch at 2026-06-16T20:25:57-04:00
Change the descriptions of two existing changelog entries
The descriptions now describe the changes in a user-friendly manner, as
opposed to describing the contributions that led to these changes in a
developer-friendly manner.
- - - - -
636c1c7a by Ian Duncan at 2026-06-16T20:26:50-04:00
AArch64: use SXTH, not SXTW, for W32 signExtendReg
signExtendReg was using SXTH (sign-extend halfword, 16-bit) for
W32-to-W64 sign extension. This should be SXTW (sign-extend word,
32-bit). SXTH only sign-extends the lower 16 bits, producing wrong
results for 32-bit values whose bit 15 differs from bit 31.
Other fixes:
- At sub-W64, code gen for MO_S_Mul2 should use W32 registers for
SMULL source operands as per the ARM spec (SMULL Xd, Wn, Wm),
and not W64.
- Ensure signExtendReg uses the source width for the source operand
in SXTW/SXTH/SXTB instructions. GNU as requires sxtw Xd,Wn (not
sxtw Xd,Xn), while LLVM's integrated assembler on macOS is lenient.
- Fix overflow flag computation for `MO_S_Mul2`. The overflow bit
was exactly inverted for sub-W64 operands.
Fixes #26978 and #27047
- - - - -
b734c75d by Igor Ranieri at 2026-06-16T20:27:32-04:00
haddock: Update CONTRIBUTING with missing step, add missing test
dependency
- - - - -
7fe4f2ec by Luite Stegeman at 2026-06-17T05:35:09-04:00
tag inference: don't confuse functions with their return values
inferTagRhs was mixing up taggedness for closures and return values
for function closures. We really shouldn't assign TagTuple to a
properly tagged function returning a tuple.
We fix this by keeping track of functions (TagFun) separately from
values (TagVal) and keeping track of their return value. TagFun is
also used for join points.
fixes #27005
- - - - -
4671c126 by Sebastian Graf at 2026-06-17T05:35:55-04:00
Seed the simplifier's in-scope set for open expressions
simplifyExpr simplifies expressions typed at the GHCi prompt and the
results of Template Haskell splices. Such an expression may be open: at a
GHCi debugger breakpoint its free variables include RuntimeUnk skolems
standing for as-yet-unknown types.
The simplifier began with an in-scope set holding only the wildcard
binder, so when it instantiated the unsafeCoerce# wrapper that GHCi
builds around a result, it formed a substitution whose range mentioned a
free skolem that was not in scope. That breaks the substitution invariant
and, in a compiler built with assertions, trips substTy's sanity check.
Seed the initial in-scope set with the free variables of the expression.
For a closed expression this adds nothing.
See Note [Seed the in-scope set for open expressions].
Fixes #17833 and its duplicate #21118.
- - - - -
67d41299 by Sebastian Graf at 2026-06-18T05:18:24-04:00
Desugar a `case` scrutinee only once (#27383, #20251)
In `dsExpr` for `HsCase` we desugared the scrutinee /twice/: once to
build the Core `case` itself, and again inside `matchWrapper`, which
re-desugared the source scrutinee (via `addHsScrutTmCs`) purely to
record long-distance information for the pattern-match checker.
For a single `case` that is merely wasteful. But for nested cases it
is catastrophic. Consider
case (case (case e of ... ) of ... ) of ...
Desugaring the outer scrutinee desugars the middle `case` twice, each
of which desugars the inner `case` twice, and so on. The work doubles
at every level, so desugaring takes O(2^n) time in the nesting depth.
That is the blowup reported in #27383; it is also what makes the
machine-generated program in #20251 take an age to compile.
The fix is simple. `matchWrapper` is handed the scrutinee anyway, so
we give it the Core expression we have /already/ desugared, and record
the long-distance term constraint with `addCoreScrutTmCs` instead of
re-desugaring from source. This is just what `matchSinglePatVar`
already does for single-pattern matches.
So:
* `matchWrapper` now takes `Maybe [CoreExpr]` rather than
`Maybe [LHsExpr GhcTc]`.
* The `HsCase` equation of `dsExpr` passes the already-desugared
`core_discrim`; the arrow desugarer passes its match variables.
* `addHsScrutTmCs` had no other use, so it is gone.
Desugaring is now linear in the nesting depth. (The coverage checker
still runs `simpleOptExpr` over each scrutinee, which leaves the total
at O(n^2); that is ample.) The long-distance information itself is
unchanged: the checker sees precisely the Core that backs the
generated code.
Test: deSugar/should_compile/T27383
- - - - -
fa5defde by Rodrigo Mesquita at 2026-06-18T05:19:11-04:00
fix: Save FastStrings in the PMC
There is no point in adding the unique to the occurrence FastString we
create, since it is part of the Id anyway.
Adding it to the FastString, meant each FastString was unique
unnecessarily!
In a separate branch, running the compiler on test `InstanceMatching`
observed 30000 `FastString`s created by this code path.
Plus, `fsLit "pm"` follows the existing pattern in `mkPmId`.
- - - - -
4efb4a66 by Alan Zimmerman at 2026-06-18T14:41:14-04:00
TTG: Add extension points to HsConDetails
Extend HsConDetails as
data HsConDetails p arg rec
= PrefixCon !(XPrefixCon p) [arg] -- C @t1 @t2 p1 p2 p3
| RecCon !(XRecCon p) rec -- C { x = p1, y = p2 }
| InfixCon !(XInfixCon p) arg arg -- p1 `C` p2
| XHsConDetails !(XXHsConDetails p)
type family XPrefixCon p
type family XRecCon p
type family XInfixCon p
type family XXHsConDetails p
- - - - -
c8d27dd4 by Simon Jakobi at 2026-06-18T14:41:59-04:00
CI: quiet submodule clean output in after_script and setup
The clean and cleanup_submodules functions ran 'git submodule foreach
git clean -xdf', flooding the job log with 'Entering ...' and
'Removing ...' lines. Pass --quiet to 'git submodule' and -q to 'git
clean' to drop the success output; errors are still reported.
Co-Authored-By: Claude Opus 4.8 <noreply(a)anthropic.com>
- - - - -
09326ca6 by Matthew Pickering at 2026-06-20T23:41:12+02:00
Add missing req_interp modifier to T18441fail3 and T18441fail19
These tests require the interpreter but they were failing in a different
way with the javascript backend because the interpreter was disabled and
stderr is ignored by the test.
- - - - -
521e55bf by Matthew Pickering at 2026-06-20T23:41:13+02:00
hadrian: Fill in more of the default.host toolchain file
When you are building a cross compiler this file will be used to build
stage1 and it's libraries, so we need enough information here to work
accurately. There is still more work to be done (see for example, word
size is still fixed).
- - - - -
23c9b6c3 by Matthew Pickering at 2026-06-20T23:42:52+02:00
hadrian: Build stage 2 cross compilers
* Most of hadrian is abstracted over the stage in order to remove the
assumption that the target of all stages is the same platform. This
allows the RTS to be built for two different targets for example.
* Abstracts the bindist creation logic to allow building either normal
or cross bindists. Normal bindists use stage 1 libraries and a stage 2
compiler. Cross bindists use stage 2 libararies and a stage 2
compiler.
* hadrian: Make binary-dist-dir the default build target. This allows us
to have the logic in one place about which libraries/stages to build
with cross compilers. Fixes #24192
New hadrian target:
* `binary-dist-dir-cross`: Build a cross compiler bindist (compiler =
stage 1, libraries = stage 2)
This commit also contains various changes to make stage2 compilers
feasible.
-------------------------
Metric Decrease:
LinkableUsage02
ManyAlternatives
ManyConstructors
MultiComponentModulesRecomp
MultiLayerModulesRecomp
RecordUpdPerf
T10421
T12150
T12227
T12425
T12707
T13035
T13379
T13820
T15703
T16577
T18140
T18282
T18698a
T18698b
T18923
T1969
T20049
T21839c
T3294
T4801
T5030
T5321FD
T5321Fun
T5631
T5642
T6048
T783
T9020
T9198
T9233
T9630
T9872d
T9961
parsing001
T3064
Metric Increase:
T26989
hard_hole_fits
-------------------------
Co-authored-by: Sven Tennie <sven.tennie(a)gmail.com>
- - - - -
26fed8ab by Matthew Pickering at 2026-06-20T23:42:52+02:00
ci: Test cross bindists
We remove the special logic for testing in-tree cross
compilers and instead test cross compiler bindists, like we do for all
other platforms.
- - - - -
80c8910e by Matthew Pickering at 2026-06-20T23:42:52+02:00
ci: Introduce CROSS_STAGE variable
In preparation for building and testing stage3 bindists we introduce the
CROSS_STAGE variable which is used by a CI job to determine what kind of
bindist the CI job should produce.
At the moment we are only using CROSS_STAGE=2 but in the future we will
have some jobs which set CROSS_STAGE=3 to produce native bindists for a
target, but produced by a cross compiler, which can be tested on by
another CI job on the native platform.
CROSS_STAGE=2: Build a normal cross compiler bindist
CROSS_STAGE=3: Build a stage 3 bindist, one which is a native compiler and library for the target
- - - - -
8215573d by Sven Tennie at 2026-06-20T23:42:52+02:00
ci: Increase timeout for emulators
Test runs with emulators naturally take longer than on native machines.
Generate jobs.yml
- - - - -
5acb7dbc by Matthew Pickering at 2026-06-20T23:42:52+02:00
ci: Javascript don't set CROSS_EMULATOR
There is no CROSS_EMULATOR needed to run javascript binaries, so we
don't set the CROSS_EMULATOR to some dummy value.
- - - - -
48345343 by Sven Tennie at 2026-06-20T23:42:52+02:00
Javascript skip T23697
See #22355 about how HSC2HS and the Javascript target don't play well
together.
- - - - -
5e44fd05 by Sven Tennie at 2026-06-20T23:42:52+02:00
Mark T24602 as fragile
It was skipped before (due to CROSS_EMULATOR being set, which changed
for JS), so we don't make things worse by marking it as fragile.
- - - - -
ab349ec2 by Sven Tennie at 2026-06-20T23:42:52+02:00
Fix T22744 for GHCJS
In fact, this test needs Template Haskell, not necessarily an
interpreter.
- - - - -
c73352d8 by Sven Tennie at 2026-06-20T23:42:52+02:00
haddock-test: fix GHCJS haddock test failures
Add --ghc-pkg-path flag support so haddock test runner can find
cross-prefixed ghc-pkg (e.g. javascript-unknown-ghcjs-ghc-pkg) which
is not on $PATH in cross install directories.
Skip haddockHtmlTest on GHCJS: Threaded.hs uses forkOS in a TH splice,
which GHCJS RTS doesn't support. Mark with js_skip in all.T.
- - - - -
5e814e76 by Andreas Klebinger at 2026-06-22T23:00:24-04:00
compiler: Deduplicate hscTidy
This function was accidentally duplicated during a refactor.
Fixes #27351
- - - - -
473b97eb by sheaf at 2026-06-22T23:01:22-04:00
Avoid mkTick in Core Prep breaking ANF (part II)
Hotfix for 2f9579765f55b3920ceb2e04995ff41a9d0e2d4e fixing a small
oversight in the call to tickTickedExpr from mkTick, in which we
improperly recursively called mkTick without passing on the preserve_anf
flag.
Fixes #27386
- - - - -
3b3e2125 by Cheng Shao at 2026-06-23T09:50:14+02:00
rts: add is-valid-utf8.c to .ubsan-suppressions
A minor one in `bytestring` that might surface when building with
+ubsan using clang.
- - - - -
78f88661 by Cheng Shao at 2026-06-23T08:30:23+00:00
hadrian: add support for building with AddressSanitizer
This patch adds a +asan flavour transformer to hadrian to build all
stage1+ C/C++ code with AddressBehaviorSanitizer. This is particularly
useful to catch potential out-of-bounds and use-after-free bugs in the
RTS codebase.
- - - - -
3e5e4c95 by Cheng Shao at 2026-06-23T08:30:26+00:00
ci: add ubsan+asan job
We now have a
`x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan`
validate/nightly job with both UBSan/ASan enabled. This is enabled in
full-ci pipelines as well as MR pipelines with `test-sanitizer` label.
- - - - -
0c08c5d6 by Cheng Shao at 2026-06-23T08:30:26+00:00
rts: add ASAN instrumentation to mblock allocator
- - - - -
72d1b42a by Cheng Shao at 2026-06-23T08:30:26+00:00
rts: add ASAN instrumentation to mgroup allocator
- - - - -
571867d9 by Cheng Shao at 2026-06-23T08:30:26+00:00
rts: add ASAN instrumentation to block allocator
- - - - -
cde4bebb by Cheng Shao at 2026-06-23T08:30:26+00:00
rts: add ASAN instrumentation to cap->pinned_object_empty
- - - - -
01c24ed7 by Cheng Shao at 2026-06-23T08:30:26+00:00
rts: add ASAN instrumentation to gc_thread->free_blocks
- - - - -
fe94d645 by Cheng Shao at 2026-06-23T08:30:26+00:00
rts: add ASAN instrumentation to hash table free list
- - - - -
68053a55 by Cheng Shao at 2026-06-23T08:30:26+00:00
rts: add ASAN instrumentation to per-Task InCall free list
- - - - -
442 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitmodules
- boot
- + changelog.d/T17833
- + changelog.d/T26978
- + changelog.d/T27046
- + changelog.d/T27047
- + changelog.d/T27182.md
- + changelog.d/T27225
- + changelog.d/T27261
- + changelog.d/T27308
- + changelog.d/T27317
- + changelog.d/T27359
- + changelog.d/T27386
- + changelog.d/bump-process
- + changelog.d/deterministic-usage-order
- + changelog.d/elem-via-foldr-27096
- + changelog.d/fix-blackhole-handling
- + changelog.d/fix-exponential-case-desugar-27383
- + changelog.d/fix-plugin-finder-multi-home-unit.md
- changelog.d/hadrian-response-files.md
- + changelog.d/hadrian-stale-package-confs-26661
- + changelog.d/hadrian-system-cxx-std-lib-25303
- + changelog.d/jobserver-leak-fix
- + changelog.d/libdir-setting
- + changelog.d/module-graph-reuse-in-downsweep
- changelog.d/more-efficient-home-unit-imports-finding
- + changelog.d/remove-bignum-check-backend
- + changelog.d/remove-bignum-ffi-backend
- + changelog.d/semaphore-v2
- + changelog.d/stage2-cross-compilers
- + changelog.d/tag-inference-27005
- + changelog.d/tool-messages-27370
- + changelog.d/wasm-fix-serviceworker
- + changelog.d/windows-rethrow-overlapped-exception
- compiler/.hlint.yaml
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/CmmToAsm/BlockLayout.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Instr.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
- compiler/GHC/CmmToAsm/RV64/Regs.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/Simplify.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Data/List/NonEmpty.hs
- compiler/GHC/Data/List/SetOps.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Config/Interpreter.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main/Interactive.hs
- compiler/GHC/Driver/Main/Passes.hs
- compiler/GHC/Driver/Main/Passes.hs-boot
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeAction.hs
- compiler/GHC/Driver/MakeSem.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Arrows.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Match.hs-boot
- compiler/GHC/HsToCore/Match/Constructor.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Linker/Unit.hs
- compiler/GHC/Parser.y
- 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/PostProcess/Haddock.hs
- compiler/GHC/Parser/Types.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Settings.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/Stg/EnforceEpt.hs
- compiler/GHC/Stg/EnforceEpt/Rewrite.hs
- compiler/GHC/Stg/EnforceEpt/TagSig.hs
- compiler/GHC/Stg/EnforceEpt/Types.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/SysTools/Process.hs
- compiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Unit.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Utils/Logger.hs
- compiler/GHC/Utils/Misc.hs
- compiler/Language/Haskell/Syntax/Binds.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/Language/Haskell/Syntax/Decls/Foreign.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Pat.hs
- compiler/Language/Haskell/Syntax/Type.hs
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/bugs.rst
- docs/users_guide/exts/stolen_syntax.rst
- docs/users_guide/javascript.rst
- docs/users_guide/using-warnings.rst
- docs/users_guide/using.rst
- ghc/GHCi/UI.hs
- hadrian/README.md
- hadrian/bindist/config.mk.in
- hadrian/build-cabal
- hadrian/cfg/default.host.target.in
- + hadrian/cfg/system.config.host.in
- hadrian/cfg/system.config.in
- + hadrian/cfg/system.config.target.in
- hadrian/doc/flavours.md
- hadrian/doc/user-settings.md
- hadrian/hadrian.cabal
- hadrian/src/Base.hs
- + hadrian/src/BindistConfig.hs
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Context.hs
- hadrian/src/Expression.hs
- hadrian/src/Flavour.hs
- hadrian/src/Flavour/Type.hs
- hadrian/src/Hadrian/Builder.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
- hadrian/src/Hadrian/Haskell/Cabal/Type.hs
- hadrian/src/Hadrian/Haskell/Hash.hs
- hadrian/src/Hadrian/Oracles/Path.hs
- hadrian/src/Hadrian/Oracles/TextFile.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Main.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Oracles/Flavour.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Oracles/TestSettings.hs
- hadrian/src/Packages.hs
- hadrian/src/Rules.hs
- hadrian/src/Rules/BinaryDist.hs
- hadrian/src/Rules/CabalReinstall.hs
- hadrian/src/Rules/Changelog.hs
- hadrian/src/Rules/Compile.hs
- hadrian/src/Rules/Documentation.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/Library.hs
- hadrian/src/Rules/Program.hs
- hadrian/src/Rules/Register.hs
- hadrian/src/Rules/Rts.hs
- hadrian/src/Rules/Test.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/Cabal.hs
- hadrian/src/Settings/Builders/Common.hs
- hadrian/src/Settings/Builders/Configure.hs
- hadrian/src/Settings/Builders/DeriveConstants.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Builders/Hsc2Hs.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Builders/SplitSections.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Flavours/GhcInGhci.hs
- hadrian/src/Settings/Flavours/Performance.hs
- hadrian/src/Settings/Flavours/QuickCross.hs
- hadrian/src/Settings/Packages.hs
- hadrian/src/Settings/Program.hs
- hadrian/src/Settings/Warnings.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Arrow.hs
- libraries/base/src/Control/Monad.hs
- libraries/base/src/Data/Array/Byte.hs
- + libraries/base/src/Data/Double.hs
- libraries/base/src/Data/Fixed.hs
- + libraries/base/src/Data/Float.hs
- libraries/base/src/Data/List/NonEmpty.hs
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Conc.hs
- libraries/base/src/GHC/Conc/Sync.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Fingerprint.hs
- libraries/base/src/GHC/IO/Handle.hs
- libraries/base/src/GHC/RTS/Flags.hs
- libraries/base/src/GHC/Unicode.hs
- libraries/base/src/GHC/Weak.hs
- libraries/base/src/GHC/Weak/Finalize.hs
- libraries/base/src/Prelude.hs
- libraries/base/src/System/IO.hs
- libraries/base/src/System/Mem/Weak.hs
- libraries/base/tests/all.T
- libraries/base/tests/perf/ElemNoFusion_O1.stderr
- libraries/base/tests/perf/ElemNoFusion_O2.stderr
- libraries/ghc-bignum/ghc-bignum.cabal
- + libraries/ghc-boot/GHC/Data/ShortByteString.hs
- libraries/ghc-boot/GHC/Settings/Utils.hs
- libraries/ghc-boot/ghc-boot.cabal.in
- libraries/ghc-internal/bignum-backend.rst
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Bignum/Backend.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Check.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/FFI.hs
- libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Native.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Selected.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
- libraries/ghc-internal/src/GHC/Internal/List.hs
- libraries/ghc-internal/src/GHC/Internal/Natural.hs
- libraries/ghci/GHCi/Coverage.hs
- libraries/ghci/GHCi/Run.hs
- libraries/process
- libraries/semaphore-compat
- m4/fp_find_nm.m4
- m4/prep_target_file.m4
- rts/.ubsan-suppressions
- rts/Capability.c
- rts/Hash.c
- rts/Messages.c
- rts/Schedule.c
- rts/Task.c
- rts/ThreadPaused.c
- rts/Threads.c
- rts/Timer.c
- rts/Updates.h
- rts/eventlog/EventLog.c
- rts/eventlog/EventLog.h
- rts/include/Stg.h
- + rts/include/rts/ASANUtils.h
- rts/include/rts/OSThreads.h
- rts/include/rts/storage/ClosureMacros.h
- rts/rts.cabal
- rts/sm/BlockAlloc.c
- rts/sm/Evac.h
- rts/sm/GCUtils.c
- rts/sm/MBlock.c
- rts/sm/Storage.c
- rts/win32/libHSghc-internal.def.in
- testsuite/driver/runtests.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/ghc-config/ghc-config.hs
- testsuite/mk/test.mk
- testsuite/tests/MiniQuickCheck.hs
- + testsuite/tests/codeGen/should_gen_asm/aarch64-sxth-mul2.asm
- + testsuite/tests/codeGen/should_gen_asm/aarch64-sxth-mul2.cmm
- + testsuite/tests/codeGen/should_gen_asm/aarch64-sxtw.asm
- + testsuite/tests/codeGen/should_gen_asm/aarch64-sxtw.cmm
- testsuite/tests/codeGen/should_gen_asm/all.T
- testsuite/tests/codeGen/should_run/T16617.hs
- testsuite/tests/codeGen/should_run/T16617.stdout
- + testsuite/tests/codeGen/should_run/T27046.hs
- + testsuite/tests/codeGen/should_run/T27046_cmm.cmm
- + testsuite/tests/codeGen/should_run/aarch64-sxtw-cmm.cmm
- + testsuite/tests/codeGen/should_run/aarch64-sxtw-run.hs
- + testsuite/tests/codeGen/should_run/aarch64-sxtw-run.stdout
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/core-to-stg/T14895.stderr
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/deSugar/should_compile/T27383.hs
- testsuite/tests/deSugar/should_compile/all.T
- testsuite/tests/diagnostic-codes/codes.stdout
- + testsuite/tests/driver/T27370/Makefile
- + testsuite/tests/driver/T27370/T27370.hs
- + testsuite/tests/driver/T27370/T27370.pp
- + testsuite/tests/driver/T27370/T27370.stderr
- + testsuite/tests/driver/T27370/all.T
- + testsuite/tests/driver/multipleHomeUnits/plugin01/all.T
- + testsuite/tests/driver/multipleHomeUnits/plugin01/appunit
- + testsuite/tests/driver/multipleHomeUnits/plugin01/p/MyPlugin.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin01/pluginunit
- + testsuite/tests/driver/multipleHomeUnits/plugin01/q/App.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin02/all.T
- + testsuite/tests/driver/multipleHomeUnits/plugin02/appunit
- + testsuite/tests/driver/multipleHomeUnits/plugin02/p/MyPlugin.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin02/pluginunit
- + testsuite/tests/driver/multipleHomeUnits/plugin02/q/App.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin02/r/RexLib.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin02/reexportunit
- testsuite/tests/ffi/should_run/all.T
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/A.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/B.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/C.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/D.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/X.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Y.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Z.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.stdout
- testsuite/tests/ghc-api/downsweep/OldModLocation.hs
- testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs
- testsuite/tests/ghc-api/downsweep/all.T
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs
- + testsuite/tests/ghc-api/settings/LibDir.hs
- + testsuite/tests/ghc-api/settings/LibDir.stdout
- + testsuite/tests/ghc-api/settings/all.T
- testsuite/tests/ghc-e/should_fail/all.T
- testsuite/tests/ghci.debugger/scripts/all.T
- testsuite/tests/ghci/prog003/prog003.T
- testsuite/tests/ghci/prog003/prog003.script
- testsuite/tests/haddock/haddock_testsuite/Makefile
- testsuite/tests/haddock/haddock_testsuite/all.T
- testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr
- 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/javascript/closure/all.T
- testsuite/tests/numeric/should_run/foundation.hs
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T20452.stderr
- + testsuite/tests/perf/compiler/T26426.hs
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/perf/should_run/T11226.hs
- + testsuite/tests/perf/should_run/T11226.stdout
- testsuite/tests/perf/should_run/all.T
- testsuite/tests/printer/Makefile
- testsuite/tests/printer/PprModifiers.hs
- + testsuite/tests/printer/PprQualifiedStrings.hs
- testsuite/tests/printer/Test24533.stdout
- + testsuite/tests/printer/Test27291.hs
- testsuite/tests/printer/all.T
- + testsuite/tests/profiling/should_compile/T27182.hs
- + testsuite/tests/profiling/should_compile/T27386.hs
- testsuite/tests/profiling/should_compile/all.T
- + testsuite/tests/profiling/should_run/T27225.hs
- + testsuite/tests/profiling/should_run/T27225.stdout
- + testsuite/tests/profiling/should_run/T27225b.hs
- + testsuite/tests/profiling/should_run/T27225b.stdout
- testsuite/tests/profiling/should_run/all.T
- testsuite/tests/profiling/should_run/caller-cc/CallerCc1.prof.sample
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/profiling/should_run/scc001.prof.sample
- testsuite/tests/rts/T18623/all.T
- testsuite/tests/rts/T27131.hs
- testsuite/tests/rts/T27131.stdout
- testsuite/tests/rts/all.T
- + testsuite/tests/simplCore/should_compile/T27261.hs
- + testsuite/tests/simplCore/should_compile/T27261_aux.hs
- + testsuite/tests/simplCore/should_compile/T4081.hs
- + testsuite/tests/simplCore/should_compile/T4081.stderr
- testsuite/tests/simplCore/should_compile/T4201.stdout
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/simplCore/should_run/T27005.hs
- + testsuite/tests/simplCore/should_run/T27005.stdout
- + testsuite/tests/simplCore/should_run/T27005_aux.hs
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/simplStg/should_compile/T24806.hs
- testsuite/tests/simplStg/should_compile/T24806.stderr
- + testsuite/tests/simplStg/should_compile/T27005b.hs
- + testsuite/tests/simplStg/should_compile/T27005b.stderr
- testsuite/tests/simplStg/should_compile/all.T
- testsuite/tests/simplStg/should_compile/inferTags004.hs
- testsuite/tests/simplStg/should_compile/inferTags004.stderr
- + testsuite/tests/simplStg/should_run/T27005a.hs
- + testsuite/tests/simplStg/should_run/T27005a.stdout
- testsuite/tests/simplStg/should_run/all.T
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Main.hs
- utils/check-exact/Transform.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Program.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
- utils/haddock/CONTRIBUTING.md
- utils/haddock/haddock-api/haddock-api.cabal
- utils/haddock/haddock-api/src/Haddock.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker.hs
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml.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/Create.hs
- utils/haddock/haddock-api/src/Haddock/Interface/LexParseRn.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs
- utils/haddock/haddock-api/src/Haddock/Options.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
- utils/haddock/haddock-api/src/Haddock/Utils.hs
- utils/haddock/haddock-test/haddock-test.cabal
- utils/haddock/haddock-test/src/Test/Haddock/Config.hs
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/Test.html
- utils/haddock/html-test/ref/TypeFamilies3.html
- utils/jsffi/prelude.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7cb8c39a300db113f4c584023ecd5…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7cb8c39a300db113f4c584023ecd5…
You're receiving this email because of your account on gitlab.haskell.org.
1
0