[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Include current phase in the range for rule/unfoldings
by Marge Bot (@marge-bot) 02 Feb '26
by Marge Bot (@marge-bot) 02 Feb '26
02 Feb '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
269c4087 by Simon Peyton Jones at 2026-02-01T19:38:10-05:00
Include current phase in the range for rule/unfoldings
This MR fixes a bad loop in the compiler: #26826.
The fix is to add (WAR2) to
Note [What is active in the RHS of a RULE or unfolding?]
in GHC.Core.Opt.Simplify.Utils
- - - - -
ddf1434f by Vladislav Zavialov at 2026-02-01T19:38:52-05:00
Refactor: merge HsMultilineString into HsString (#26860)
Before this patch, HsLit defined two separate constructors to represent
single-line and multi-line strings:
data HsLit x
...
| HsString (XHsString x) FastString
| HsMultilineString (XHsMultilineString x) FastString
I found this to be an unnecessary complication and an obstacle to unifying
HsLit with HsTyLit. Now we use HsString for both kinds of literals.
One user-facing change here is `ppr (HsString st s)` behaving differently for
single-line strings containing newlines:
x = "first line \
\asdf\n\
\second line"
Previously, the literal was fed to `ftext` with its newlines, producing an
ill-formed SDoc. This issue is now addressed by using `split` for both
single-line and multi-line strings:
vcat $ map text $ split '\n' (unpackFS src)
See the parser/should_fail/T26860ppr test.
In addition (and unrelatedly to the main payload of this patch),
drop the unused pmPprHsLit helper.
- - - - -
2b4f463c by Simon Peyton Jones at 2026-02-02T17:32:32+00:00
Remove exprIsCheap from doFloatFromRhs
See #26854 and Note [Float when expandable]
This patch simplifies the code, by removing an extra unnecessary test.
- - - - -
f453623d by Brandon Chinn at 2026-02-02T16:47:03-05:00
Refactor: make function patterns exhaustive
Also added missing (==) logic for:
* HsMultilineString
* HsInt{8,16,32}
* HsWord{8,16,32}
- - - - -
22 changed files:
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/String.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/InlinePragma.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- + testsuite/tests/parser/should_fail/T26860ppr.hs
- + testsuite/tests/parser/should_fail/T26860ppr.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/simplCore/should_compile/T26826.hs
- testsuite/tests/simplCore/should_compile/all.T
- utils/check-exact/ExactPrint.hs
Changes:
=====================================
compiler/GHC/Core/Opt/OccurAnal.hs
=====================================
@@ -1417,16 +1417,17 @@ then we *must* choose f to be a loop breaker. Example: see Note
That is the whole reason for computing rule_fv_env in mkLoopBreakerNodes.
Wrinkles:
-* We only consider /active/ rules. See Note [Finding rule RHS free vars]
+(RLB1) We only consider /active/ rules.
+ This is important: see Note [Finding rule RHS free vars]
-* We need only consider free vars that are also binders in this Rec
+(RLB2) We need only consider free vars that are also binders in this Rec
group. See also Note [Finding rule RHS free vars]
-* We only consider variables free in the *RHS* of the rule, in
+(RLB3) We only consider variables free in the *RHS* of the rule, in
contrast to the way we build the Rec group in the first place (Note
[Rule dependency info])
-* Why "transitive sequence of rules"? Because active rules apply
+(RLB4) Why "transitive sequence of rules"? Because active rules apply
unconditionally, without checking loop-breaker-ness.
See Note [Loop breaker dependencies].
@@ -1854,10 +1855,13 @@ makeNode !env imp_rule_edges bndr_set (bndr, rhs)
add_rule_uds (_, l, r) uds = l `andUDs` r `andUDs` uds
-------- active_rule_fvs ------------
+ -- See Note [Rules and loop breakers]
active_rule_fvs = foldr add_active_rule imp_rule_fvs rules_w_uds
add_active_rule (rule, _, rhs_uds) fvs
- | is_active (ruleActivation rule)
+ | is_active (ruleActivation rule) -- See (RLB1)
= udFreeVars bndr_set rhs_uds `unionVarSet` fvs
+ -- Only consider the `rhs_uss`, not the LHS ones; see (RLB3)
+ -- udFreeVars restricts to bndr_set; see (RLB2)
| otherwise
= fvs
=====================================
compiler/GHC/Core/Opt/Simplify/Env.hs
=====================================
@@ -12,7 +12,7 @@ module GHC.Core.Opt.Simplify.Env (
-- * Environments
SimplEnv(..), pprSimplEnv, -- Temp not abstract
- SimplPhase(..), isActive,
+ SimplPhase(..), isActive, simplStartPhase, simplEndPhase,
seArityOpts, seCaseCase, seCaseFolding, seCaseMerge, seCastSwizzle,
seDoEtaReduction, seEtaExpand, seFloatEnable, seInline, seNames,
seOptCoercionOpts, sePhase, sePlatform, sePreInline,
@@ -293,7 +293,9 @@ data SimplMode = SimplMode -- See comments in GHC.Core.Opt.Simplify.Monad
-- | See Note [SimplPhase]
data SimplPhase
-- | A simplifier phase: InitialPhase, Phase 2, Phase 1, Phase 0, FinalPhase
+ -- NB: (SimplPhase p) is equivalent to (SimplPhaseRange p p)
= SimplPhase CompilerPhase
+
-- | Simplifying the RHS of a rule or of a stable unfolding: the range of
-- phases of the activation of the rule/stable unfolding.
--
@@ -302,13 +304,18 @@ data SimplPhase
--
-- See Note [What is active in the RHS of a RULE or unfolding?]
-- in GHC.Core.Opt.Simplify.Utils.
- | SimplPhaseRange
- { simplStartPhase :: CompilerPhase
- , simplEndPhase :: CompilerPhase
- }
+ | SimplPhaseRange CompilerPhase CompilerPhase
deriving Eq
+simplStartPhase :: SimplPhase -> CompilerPhase
+simplStartPhase (SimplPhase p) = p
+simplStartPhase (SimplPhaseRange p _) = p
+
+simplEndPhase :: SimplPhase -> CompilerPhase
+simplEndPhase (SimplPhase p) = p
+simplEndPhase (SimplPhaseRange _ p) = p
+
instance Outputable SimplPhase where
ppr (SimplPhase p) = ppr p
ppr (SimplPhaseRange s e) = brackets $ ppr s <> ellipsis <> ppr e
@@ -322,12 +329,13 @@ instance Outputable SimplPhase where
--
-- See Note [SimplPhase].
isActive :: SimplPhase -> ActivationGhc -> Bool
-isActive (SimplPhase p) act = isActiveInPhase p act
-isActive (SimplPhaseRange start end) act =
- -- To check whether the activation is active throughout the whole phase range,
- -- it's sufficient to check the endpoints of the phase range, because an
- -- activation can never have gaps (all activations are phase intervals).
- isActiveInPhase start act && isActiveInPhase end act
+isActive (SimplPhase p) act
+ = isActiveInPhase p act
+isActive (SimplPhaseRange start end) act
+ = -- To check whether the activation is active throughout the whole phase range,
+ -- it's sufficient to check the endpoints of the phase range, because an
+ -- activation can never have gaps (all activations are phase intervals).
+ isActiveInPhase start act && isActiveInPhase end act
{- Note [SimplPhase]
~~~~~~~~~~~~~~~~~~~~
@@ -807,8 +815,9 @@ doFloatFromRhs fe lvl rec strict_bind (SimplFloats { sfLetFloats = LetFloats fs
&& want_to_float
&& can_float
where
- want_to_float = isTopLevel lvl || exprIsCheap rhs || exprIsExpandable rhs
- -- See Note [Float when cheap or expandable]
+ want_to_float = isTopLevel lvl || exprIsExpandable rhs
+ -- See Note [Float when expandable]
+
can_float = case ff of
FltLifted -> True
FltOkSpec -> isNotTopLevel lvl && isNonRec rec
@@ -820,16 +829,29 @@ doFloatFromRhs fe lvl rec strict_bind (SimplFloats { sfLetFloats = LetFloats fs
floatEnabled lvl FloatNestedOnly = not (isTopLevel lvl)
floatEnabled _ FloatEnabled = True
-{-
-Note [Float when cheap or expandable]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We want to float a let from a let if the residual RHS is
- a) cheap, such as (\x. blah)
- b) expandable, such as (f b) if f is CONLIKE
-But there are
- - cheap things that are not expandable (eg \x. expensive)
- - expandable things that are not cheap (eg (f b) where b is CONLIKE)
-so we must take the 'or' of the two.
+{- Note [Float when expandable]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We float when that would leave us with a RHS that is /expandable/ (#26854).
+The whole purpose of the local-let-floating is to end up with
+ let x = rhs
+where rhs has an expandable unfolding, so that `exprIsConApp_maybe` will look
+inside `x`.
+
+Historical aside:
+
+ In the long-distant (2011) past, we made `want_to_float` true if
+ EITHER exprIsExpandable OR exprIsCheap
+ But that seems wrong: there is no point in floating for expressions that are
+ cheap but not expandable:
+ * It costs more to test
+ * It gives no benefit
+ * Very few expressions are cheap but not expandable (e.g. error calls)
+ We justified this OR by saying that there may be:
+ - cheap things that are not expandable (eg \x. expensive)
+ - expandable things that are not cheap (eg (f b) where b is CONLIKE)
+ But that's not true: (\x.expensive) is certainly expandable.
+
+End of historial aside
-}
emptyLetFloats :: LetFloats
=====================================
compiler/GHC/Core/Opt/Simplify/Utils.hs
=====================================
@@ -1099,7 +1099,7 @@ updModeForStableUnfoldings :: ActivationGhc -> SimplMode -> SimplMode
-- See Note [Simplifying inside stable unfoldings]
updModeForStableUnfoldings unf_act current_mode
= current_mode
- { sm_phase = phaseFromActivation (sm_phase current_mode) unf_act
+ { sm_phase = phaseForRuleOrUnf (sm_phase current_mode) unf_act
-- See Note [What is active in the RHS of a RULE or unfolding?]
, sm_eta_expand = False
-- See Note [Eta expansion in stable unfoldings and rules]
@@ -1123,27 +1123,32 @@ updModeForRuleRHS :: ActivationGhc -> SimplMode -> SimplMode
updModeForRuleRHS rule_act current_mode =
current_mode
-- See Note [What is active in the RHS of a RULE or unfolding?]
- { sm_phase = phaseFromActivation (sm_phase current_mode) rule_act
+ { sm_phase = phaseForRuleOrUnf (sm_phase current_mode) rule_act
, sm_eta_expand = False
-- See Note [Eta expansion in stable unfoldings and rules]
}
--- | Compute the phase range to set the 'SimplMode' to
--- when simplifying the RHS of a rule or of a stable unfolding.
+-- | `phaseForRuleOrUnf` computes the phase range to use when
+-- simplifying the RHS of a rule or of a stable unfolding.
--
+-- This subtle function implements the careful plan described in
-- See Note [What is active in the RHS of a RULE or unfolding?]
-phaseFromActivation
- :: SimplPhase -- ^ the current simplifier phase
+phaseForRuleOrUnf
+ :: SimplPhase -- ^ the current simplifier phase
-> ActivationGhc -- ^ the activation of the RULE or stable unfolding
-> SimplPhase
-phaseFromActivation p act
- | isNeverActive act
- = p
+phaseForRuleOrUnf current_phase act
+ | start == end
+ = SimplPhase start
| otherwise
- = SimplPhaseRange act_start act_end
+ = SimplPhaseRange start end
where
- act_start = beginPhase act
- act_end = endPhase act
+ start, end :: CompilerPhase
+ start = beginPhase act `earliestPhase` simplStartPhase current_phase
+ end = endPhase act `latestPhase` simplEndPhase current_phase
+ -- The beginPhase/endPhase implements (WAR1)
+ -- The simplStartPhase/simplEndPhase implements (WAR2)
+ -- of Note [What is active in the RHS of a RULE or unfolding?]
{- Note [Simplifying rules]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1275,26 +1280,47 @@ Our carefully crafted plan is as follows:
-------------------------------------------------------------
When simplifying the RHS of a RULE R with activation range A,
- fire only other rules R' that are active throughout all of A.
+ fire only other rules R' that are active
+ (WAR1) throughout all of A
+ (WAR2) in the current phase
+ See `phaseForRuleOrUnf`.
-------------------------------------------------------------
-Reason: R might fire in any phase in A. Then R' can fire only if R' is active
-in that phase. If not, it's not safe to unconditionally fire R' in the RHS of R.
+Reasons for (WAR1):
+ * R might fire in any phase in A. Then R' can fire only if R' is active in that
+ phase. If not, it's not safe to unconditionally fire R' in the RHS of R.
+
+Reasons for (WAR2):
+ * If A is empty (e.g. a NOINLINE pragma, so the unfolding is never active)
+ we don't want to vacuously satisfy (WAR1) and thereby fire /all/ RULES in
+ the unfolding. Two RULES may be crafted so that they are never simultaneously
+ active, and will loop if they are.
+
+ * Suppose we are in Phase 2, looking at a stable unfolding for INLINE [1].
+ If we just do (WAR1) we will fire RULES active in phase 1; but the
+ occurrence analyser ignores any rules not active in the current phase.
+ So occ-anal may fail to detect a loop breaker; see #26826 for details.
+ See Note [Rules and loop breakers] in GHC.Core.Opt.OccurAnal.
+
+ * Aesthetically, this means that when the simplifer is in phase N, it
+ won't switch to a phase-range that doesn't include N (e.g. might be later
+ than N). This is what caused #26826.
+
+ * Also note that as the current phase advances, it'll eventually be inside
+ the range specified by (WAR1), and hence will not widen the range.
+ Unless the latter is empty, of course.
This plan is implemented by:
- 1. Setting the simplifier phase to the range of phases
- corresponding to the start/end phases of the rule's activation.
+ 1. Setting the simplifier phase to the /range/ of phases
+ corresponding to the start/end phases of the rule's activation, implementing
+ (WAR1) and (WAR2). This happens in `phaseForRuleOrUnf`.
+
2. When checking whether another rule is active, we use the function
isActive :: SimplPhase -> Activation -> Bool
from GHC.Core.Opt.Simplify.Env, which checks whether the other rule is
active throughout the whole range of phases.
-However, if the rule whose RHS we are simplifying is never active, instead of
-setting the phase range to an empty interval, we keep the current simplifier
-phase. This special case avoids firing ALL rules in the RHS of a never-active
-rule.
-
You might wonder about a situation such as the following:
module M1 where
@@ -1307,6 +1333,7 @@ It looks tempting to use "r1" when simplifying the RHS of "r2", yet we
**must not** do so: for any module M that imports M1, we are going to start
simplification in M starting at InitialPhase, and we will see the
fully simplified rules RHSs imported from M1.
+
Conclusion: stick to the plan.
Note [Simplifying inside stable unfoldings]
=====================================
compiler/GHC/Core/Opt/WorkWrap.hs
=====================================
@@ -914,9 +914,9 @@ mkStrWrapperInlinePrag (InlinePragma { inl_inline = fn_inl
where
srcTxt = SourceText $ fsLit "{-# INLINE"
-- See Note [Wrapper activation]
- wrapper_phase = foldr (laterPhase . get_rule_phase) earliest_inline_phase rules
- earliest_inline_phase = beginPhase fn_act `laterPhase` nextPhase InitialPhase
- -- laterPhase (nextPhase InitialPhase) is a temporary hack
+ wrapper_phase = foldr (latestPhase . get_rule_phase) earliest_inline_phase rules
+ earliest_inline_phase = beginPhase fn_act `latestPhase` nextPhase InitialPhase
+ -- latestPhase (nextPhase InitialPhase) is a temporary hack
-- to inline no earlier than phase 2. I got regressions in
-- 'mate', due to changes in full laziness due to Note [Case
-- MFEs], when I did earlier inlining.
=====================================
compiler/GHC/Hs/Lit.hs
=====================================
@@ -45,7 +45,6 @@ import Language.Haskell.Syntax.Lit
type instance XHsChar (GhcPass _) = SourceText
type instance XHsCharPrim (GhcPass _) = SourceText
type instance XHsString (GhcPass _) = SourceText
-type instance XHsMultilineString (GhcPass _) = SourceText
type instance XHsStringPrim (GhcPass _) = SourceText
type instance XHsInt (GhcPass _) = NoExtField
type instance XHsIntPrim (GhcPass _) = SourceText
@@ -147,7 +146,6 @@ hsLitNeedsParens p = go
go (HsChar {}) = False
go (HsCharPrim {}) = False
go (HsString {}) = False
- go (HsMultilineString {}) = False
go (HsStringPrim {}) = False
go (HsInt _ x) = p > topPrec && il_neg x
go (HsFloatPrim {}) = False
@@ -177,7 +175,6 @@ convertLit :: XXLit (GhcPass p)~DataConCantHappen => HsLit (GhcPass p) -> HsLit
convertLit (HsChar a x) = HsChar a x
convertLit (HsCharPrim a x) = HsCharPrim a x
convertLit (HsString a x) = HsString a x
-convertLit (HsMultilineString a x) = HsMultilineString a x
convertLit (HsStringPrim a x) = HsStringPrim a x
convertLit (HsInt a x) = HsInt a x
convertLit (HsIntPrim a x) = HsIntPrim a x
@@ -212,8 +209,7 @@ Equivalently it's True if
instance IsPass p => Outputable (HsLit (GhcPass p)) where
ppr (HsChar st c) = pprWithSourceText st (pprHsChar c)
ppr (HsCharPrim st c) = pprWithSourceText st (pprPrimChar c)
- ppr (HsString st s) = pprWithSourceText st (pprHsString s)
- ppr (HsMultilineString st s) =
+ ppr (HsString st s) =
case st of
NoSourceText -> pprHsString s
SourceText src -> vcat $ map text $ split '\n' (unpackFS src)
@@ -248,36 +244,6 @@ instance Outputable OverLitVal where
ppr (HsFractional f) = ppr f
ppr (HsIsString st s) = pprWithSourceText st (pprHsString s)
--- | pmPprHsLit pretty prints literals and is used when pretty printing pattern
--- match warnings. All are printed the same (i.e., without hashes if they are
--- primitive and not wrapped in constructors if they are boxed). This happens
--- mainly for too reasons:
--- * We do not want to expose their internal representation
--- * The warnings become too messy
-pmPprHsLit :: forall p. IsPass p => HsLit (GhcPass p) -> SDoc
-pmPprHsLit (HsChar _ c) = pprHsChar c
-pmPprHsLit (HsCharPrim _ c) = pprHsChar c
-pmPprHsLit (HsString st s) = pprWithSourceText st (pprHsString s)
-pmPprHsLit (HsMultilineString st s) = pprWithSourceText st (pprHsString s)
-pmPprHsLit (HsStringPrim _ s) = pprHsBytes s
-pmPprHsLit (HsInt _ i) = integer (il_value i)
-pmPprHsLit (HsIntPrim _ i) = integer i
-pmPprHsLit (HsWordPrim _ w) = integer w
-pmPprHsLit (HsInt8Prim _ i) = integer i
-pmPprHsLit (HsInt16Prim _ i) = integer i
-pmPprHsLit (HsInt32Prim _ i) = integer i
-pmPprHsLit (HsInt64Prim _ i) = integer i
-pmPprHsLit (HsWord8Prim _ w) = integer w
-pmPprHsLit (HsWord16Prim _ w) = integer w
-pmPprHsLit (HsWord32Prim _ w) = integer w
-pmPprHsLit (HsWord64Prim _ w) = integer w
-pmPprHsLit (HsFloatPrim _ f) = ppr f
-pmPprHsLit (HsDoublePrim _ d) = ppr d
-pmPprHsLit (XLit x) = case ghcPass @p of
- GhcTc -> case x of
- (HsInteger _ i _) -> integer i
- (HsRat f _) -> ppr f
-
negateOverLitVal :: OverLitVal -> OverLitVal
negateOverLitVal (HsIntegral i) = HsIntegral (negateIntegralLit i)
negateOverLitVal (HsFractional f) = HsFractional (negateFractionalLit f)
=====================================
compiler/GHC/Hs/Syn/Type.hs
=====================================
@@ -75,7 +75,6 @@ hsLitType :: forall p. IsPass p => HsLit (GhcPass p) -> Type
hsLitType (HsChar _ _) = charTy
hsLitType (HsCharPrim _ _) = charPrimTy
hsLitType (HsString _ _) = stringTy
-hsLitType (HsMultilineString _ _) = stringTy
hsLitType (HsStringPrim _ _) = addrPrimTy
hsLitType (HsInt _ _) = intTy
hsLitType (HsIntPrim _ _) = intPrimTy
=====================================
compiler/GHC/HsToCore/Match/Literal.hs
=====================================
@@ -117,7 +117,6 @@ dsLit l = do
HsDoublePrim _ fl -> return (Lit (LitDouble (rationalFromFractionalLit fl)))
HsChar _ c -> return (mkCharExpr c)
HsString _ str -> mkStringExprFS str
- HsMultilineString _ str -> mkStringExprFS str
HsInt _ i -> return (mkIntExpr platform (il_value i))
XLit x -> case ghcPass @p of
GhcTc -> case x of
@@ -463,7 +462,6 @@ getSimpleIntegralLit (XLit (HsInteger _ i ty)) = Just (i, ty)
getSimpleIntegralLit HsChar{} = Nothing
getSimpleIntegralLit HsCharPrim{} = Nothing
getSimpleIntegralLit HsString{} = Nothing
-getSimpleIntegralLit HsMultilineString{} = Nothing
getSimpleIntegralLit HsStringPrim{} = Nothing
getSimpleIntegralLit (XLit (HsRat{})) = Nothing
getSimpleIntegralLit HsFloatPrim{} = Nothing
=====================================
compiler/GHC/HsToCore/Quote.hs
=====================================
@@ -3077,7 +3077,6 @@ repLiteral lit
HsChar _ _ -> Just charLName
HsCharPrim _ _ -> Just charPrimLName
HsString _ _ -> Just stringLName
- HsMultilineString _ _ -> Just stringLName
_ -> Nothing
mk_integer :: Integer -> MetaM (HsLit GhcTc)
=====================================
compiler/GHC/Parser.y
=====================================
@@ -4131,7 +4131,7 @@ literal :: { Located (HsLit GhcPs) }
: CHAR { sL1 $1 $ HsChar (getCHARs $1) $ getCHAR $1 }
| STRING { sL1 $1 $ HsString (getSTRINGs $1)
$ getSTRING $1 }
- | STRING_MULTI { sL1 $1 $ HsMultilineString (getSTRINGMULTIs $1)
+ | STRING_MULTI { sL1 $1 $ HsString (getSTRINGMULTIs $1)
$ getSTRINGMULTI $1 }
| PRIMINTEGER { sL1 $1 $ HsIntPrim (getPRIMINTEGERs $1)
$ getPRIMINTEGER $1 }
=====================================
compiler/GHC/Parser/String.hs
=====================================
@@ -392,9 +392,9 @@ proposal: https://github.com/ghc-proposals/ghc-proposals/pull/569
Multiline string literals are syntax sugar for normal string literals,
with an extra post processing step. This all happens in the Lexer; that
-is, HsMultilineString will contain the post-processed string. This matches
-the same behavior as HsString, which contains the normalized string
-(see Note [Literal source text]).
+is, the multi-line HsString will contain the post-processed string.
+This matches the behavior of the single-line HsString, which contains
+the normalized string too (see Note [Literal source text]).
The canonical steps for post processing a multiline string are:
1. Collapse string gaps
=====================================
compiler/GHC/Rename/Expr.hs
=====================================
@@ -352,18 +352,13 @@ rnExpr (HsOverLabel src v)
hs_ty_arg = mkEmptyWildCardBndrs $ wrapGenSpan $
HsTyLit noExtField (HsStrTy NoSourceText v)
-rnExpr (HsLit x lit) | Just (src, s) <- stringLike lit
+rnExpr (HsLit x lit) | HsString src s <- lit
= do { opt_OverloadedStrings <- xoptM LangExt.OverloadedStrings
; if opt_OverloadedStrings then
rnExpr (HsOverLit x (mkHsIsString src s))
else do {
; rnLit lit
; return (HsLit x (convertLit lit), emptyFVs) } }
- where
- stringLike = \case
- HsString src s -> Just (src, s)
- HsMultilineString src s -> Just (src, s)
- _ -> Nothing
rnExpr (HsLit x lit)
= do { rnLit lit
=====================================
compiler/GHC/Tc/Gen/HsType.hs
=====================================
@@ -4786,7 +4786,6 @@ promotionErr name err
tyLitFromLit :: HsLit GhcRn -> Maybe (HsTyLit GhcRn)
tyLitFromLit (HsString x str) = Just (HsStrTy x str)
-tyLitFromLit (HsMultilineString x str) = Just (HsStrTy x str)
tyLitFromLit (HsChar x char) = Just (HsCharTy x char)
tyLitFromLit _ = Nothing
=====================================
compiler/GHC/ThToHs.hs
=====================================
@@ -1462,10 +1462,11 @@ cvtLit (BytesPrimL (Bytes fptr off sz)) = do
BS.packCStringLen (ptr `plusPtr` fromIntegral off, fromIntegral sz)
force bs
return $ HsStringPrim NoSourceText bs
-cvtLit _ = panic "Convert.cvtLit: Unexpected literal"
- -- cvtLit should not be called on IntegerL, RationalL
- -- That precondition is established right here in
- -- "GHC.ThToHs", hence panic
+-- cvtLit should not be called on IntegerL, RationalL
+-- That precondition is established right here in
+-- "GHC.ThToHs", hence panic
+cvtLit (IntegerL _) = panic "Convert.cvtLit: Unexpected literal"
+cvtLit (RationalL _) = panic "Convert.cvtLit: Unexpected literal"
quotedSourceText :: String -> SourceText
quotedSourceText s = SourceText $ fsLit $ "\"" ++ s ++ "\""
=====================================
compiler/GHC/Types/InlinePragma.hs
=====================================
@@ -104,9 +104,8 @@ module GHC.Types.InlinePragma
, endPhase
-- *** Queries
, isActiveInPhase
- , laterPhase
- , laterThanPhase
- , nextPhase
+ , latestPhase, earliestPhase
+ , laterThanPhase, nextPhase
) where
import GHC.Prelude
@@ -422,13 +421,21 @@ nextPhase (Phase 0) = FinalPhase
nextPhase (Phase n) = Phase (n-1)
nextPhase FinalPhase = FinalPhase
-laterPhase :: CompilerPhase -> CompilerPhase -> CompilerPhase
--- ^ Returns the later of two phases
-laterPhase (Phase n1) (Phase n2) = Phase (n1 `min` n2)
-laterPhase InitialPhase p2 = p2
-laterPhase FinalPhase _ = FinalPhase
-laterPhase p1 InitialPhase = p1
-laterPhase _ FinalPhase = FinalPhase
+earliestPhase :: CompilerPhase -> CompilerPhase -> CompilerPhase
+-- ^ Returns the earliest of two phases
+earliestPhase (Phase n1) (Phase n2) = Phase (n1 `max` n2)
+earliestPhase InitialPhase _ = InitialPhase
+earliestPhase FinalPhase p2 = p2
+earliestPhase _ InitialPhase = InitialPhase
+earliestPhase p1 FinalPhase = p1
+
+latestPhase :: CompilerPhase -> CompilerPhase -> CompilerPhase
+-- ^ Returns the latest of two phases
+latestPhase (Phase n1) (Phase n2) = Phase (n1 `min` n2)
+latestPhase InitialPhase p2 = p2
+latestPhase FinalPhase _ = FinalPhase
+latestPhase p1 InitialPhase = p1
+latestPhase _ FinalPhase = FinalPhase
-- | @p1 `laterThanOrEqualPhase` p2@ computes whether @p1@ happens (strictly)
-- after @p2@.
=====================================
compiler/Language/Haskell/Syntax/Extension.hs
=====================================
@@ -609,7 +609,6 @@ type family XXParStmtBlock x x'
type family XHsChar x
type family XHsCharPrim x
type family XHsString x
-type family XHsMultilineString x
type family XHsStringPrim x
type family XHsInt x
type family XHsIntPrim x
=====================================
compiler/Language/Haskell/Syntax/Lit.hs
=====================================
@@ -47,8 +47,6 @@ data HsLit x
-- ^ Unboxed character
| HsString (XHsString x) {- SourceText -} FastString
-- ^ String
- | HsMultilineString (XHsMultilineString x) {- SourceText -} FastString
- -- ^ String
| HsStringPrim (XHsStringPrim x) {- SourceText -} !ByteString
-- ^ Packed bytes
| HsInt (XHsInt x) IntegralLit
@@ -81,19 +79,44 @@ data HsLit x
| XLit !(XXLit x)
instance (Eq (XXLit x)) => Eq (HsLit x) where
- (HsChar _ x1) == (HsChar _ x2) = x1==x2
- (HsCharPrim _ x1) == (HsCharPrim _ x2) = x1==x2
- (HsString _ x1) == (HsString _ x2) = x1==x2
- (HsStringPrim _ x1) == (HsStringPrim _ x2) = x1==x2
- (HsInt _ x1) == (HsInt _ x2) = x1==x2
- (HsIntPrim _ x1) == (HsIntPrim _ x2) = x1==x2
- (HsWordPrim _ x1) == (HsWordPrim _ x2) = x1==x2
- (HsInt64Prim _ x1) == (HsInt64Prim _ x2) = x1==x2
- (HsWord64Prim _ x1) == (HsWord64Prim _ x2) = x1==x2
- (HsFloatPrim _ x1) == (HsFloatPrim _ x2) = x1==x2
- (HsDoublePrim _ x1) == (HsDoublePrim _ x2) = x1==x2
- (XLit x1) == (XLit x2) = x1==x2
- _ == _ = False
+ HsChar _ x1 == HsChar _ x2 = x1 == x2
+ HsChar{} == _ = False
+ HsCharPrim _ x1 == HsCharPrim _ x2 = x1 == x2
+ HsCharPrim{} == _ = False
+ HsString _ x1 == HsString _ x2 = x1 == x2
+ HsString{} == _ = False
+ HsMultilineString _ x1 == HsMultilineString _ x2 = x1 == x2
+ HsMultilineString{} == _ = False
+ HsStringPrim _ x1 == HsStringPrim _ x2 = x1 == x2
+ HsStringPrim{} == _ = False
+ HsInt _ x1 == HsInt _ x2 = x1 == x2
+ HsInt{} == _ = False
+ HsIntPrim _ x1 == HsIntPrim _ x2 = x1 == x2
+ HsIntPrim{} == _ = False
+ HsWordPrim _ x1 == HsWordPrim _ x2 = x1 == x2
+ HsWordPrim{} == _ = False
+ HsInt8Prim _ x1 == HsInt8Prim _ x2 = x1 == x2
+ HsInt8Prim{} == _ = False
+ HsInt16Prim _ x1 == HsInt16Prim _ x2 = x1 == x2
+ HsInt16Prim{} == _ = False
+ HsInt32Prim _ x1 == HsInt32Prim _ x2 = x1 == x2
+ HsInt32Prim{} == _ = False
+ HsInt64Prim _ x1 == HsInt64Prim _ x2 = x1 == x2
+ HsInt64Prim{} == _ = False
+ HsWord8Prim _ x1 == HsWord8Prim _ x2 = x1 == x2
+ HsWord8Prim{} == _ = False
+ HsWord16Prim _ x1 == HsWord16Prim _ x2 = x1 == x2
+ HsWord16Prim{} == _ = False
+ HsWord32Prim _ x1 == HsWord32Prim _ x2 = x1 == x2
+ HsWord32Prim{} == _ = False
+ HsWord64Prim _ x1 == HsWord64Prim _ x2 = x1 == x2
+ HsWord64Prim{} == _ = False
+ HsFloatPrim _ x1 == HsFloatPrim _ x2 = x1 == x2
+ HsFloatPrim{} == _ = False
+ HsDoublePrim _ x1 == HsDoublePrim _ x2 = x1 == x2
+ HsDoublePrim{} == _ = False
+ XLit x1 == XLit x2 = x1 == x2
+ XLit{} == _ = False
-- | Haskell Overloaded Literal
data HsOverLit p
@@ -114,18 +137,23 @@ data OverLitVal
deriving Data
instance Eq OverLitVal where
- (HsIntegral i1) == (HsIntegral i2) = i1 == i2
- (HsFractional f1) == (HsFractional f2) = f1 == f2
- (HsIsString _ s1) == (HsIsString _ s2) = s1 == s2
- _ == _ = False
+ HsIntegral i1 == HsIntegral i2 = i1 == i2
+ HsIntegral{} == _ = False
+ HsFractional f1 == HsFractional f2 = f1 == f2
+ HsFractional{} == _ = False
+ HsIsString _ s1 == HsIsString _ s2 = s1 == s2
+ HsIsString{} == _ = False
instance Ord OverLitVal where
- compare (HsIntegral i1) (HsIntegral i2) = i1 `compare` i2
- compare (HsIntegral _) (HsFractional _) = LT
- compare (HsIntegral _) (HsIsString _ _) = LT
- compare (HsFractional f1) (HsFractional f2) = f1 `compare` f2
- compare (HsFractional _) (HsIntegral _) = GT
- compare (HsFractional _) (HsIsString _ _) = LT
- compare (HsIsString _ s1) (HsIsString _ s2) = s1 `lexicalCompareFS` s2
- compare (HsIsString _ _) (HsIntegral _) = GT
- compare (HsIsString _ _) (HsFractional _) = GT
+ -- HsIntegral
+ HsIntegral i1 `compare` HsIntegral i2 = i1 `compare` i2
+ HsIntegral{} `compare` HsFractional{} = LT
+ HsIntegral{} `compare` HsIsString{} = LT
+ -- HsFractional
+ HsFractional{} `compare` HsIntegral{} = GT
+ HsFractional f1 `compare` HsFractional f2 = f1 `compare` f2
+ HsFractional{} `compare` HsIsString{} = LT
+ -- HsIsString
+ HsIsString{} `compare` HsIntegral{} = GT
+ HsIsString{} `compare` HsFractional{} = GT
+ HsIsString _ s1 `compare` HsIsString _ s2 = s1 `lexicalCompareFS` s2
=====================================
testsuite/tests/parser/should_fail/T26860ppr.hs
=====================================
@@ -0,0 +1,11 @@
+{-# LANGUAGE NoOverloadedStrings #-}
+
+module T26860ppr where
+
+-- Test that the error message containing the string literal is well-formatted.
+-- See also: parser/should_fail/MultilineStringsError
+x :: Int
+x = "first line \
+ \asdf\n\
+ \second line"
+
=====================================
testsuite/tests/parser/should_fail/T26860ppr.stderr
=====================================
@@ -0,0 +1,13 @@
+T26860ppr.hs:8:5: error: [GHC-83865]
+ • Couldn't match type ‘[Char]’ with ‘Int’
+ Expected: Int
+ Actual: String
+ • In the expression:
+ "first line \
+ \asdf\n\
+ \second line"
+ In an equation for ‘x’:
+ x = "first line \
+ \asdf\n\
+ \second line"
+
=====================================
testsuite/tests/parser/should_fail/all.T
=====================================
@@ -244,3 +244,4 @@ test('T25530', normal, compile_fail, [''])
test('T26418', normal, compile_fail, [''])
test('T12488c', normal, compile_fail, [''])
test('T12488d', normal, compile_fail, [''])
+test('T26860ppr', normal, compile_fail, [''])
=====================================
testsuite/tests/simplCore/should_compile/T26826.hs
=====================================
@@ -0,0 +1,86 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeData #-}
+
+module T26826 where
+
+import Data.Kind (Type)
+
+type data AstSpan =
+ FullSpan | PrimalStepSpan AstSpan | PlainSpan
+
+data SAstSpan (s :: AstSpan) where
+ SFullSpan :: SAstSpan FullSpan
+ SPrimalStepSpan :: SAstSpan s -> SAstSpan (PrimalStepSpan s)
+ SPlainSpan :: SAstSpan PlainSpan
+
+class KnownSpan (s :: AstSpan) where
+ knownSpan :: SAstSpan s
+
+instance KnownSpan FullSpan where
+ knownSpan = SFullSpan
+
+instance KnownSpan s => KnownSpan (PrimalStepSpan s) where
+ knownSpan = SPrimalStepSpan (knownSpan @s)
+
+instance KnownSpan PlainSpan where
+ knownSpan = SPlainSpan
+
+class ADReady target where
+ ttlet :: target a -> (target a -> target b) -> target b
+ ttletPrimal :: target a -> (target a -> target b) -> target b
+ ttletPlain :: target a -> (target a -> target b) -> target b
+ tplainPart :: target a -> target a
+ tfromPlain :: target a -> target a
+ tprimalPart :: target a -> target a
+ tfromPrimal :: target a -> target a
+
+type SpanTargetFam target (s :: AstSpan) (y :: Type) = target y
+
+type AstEnv target = ()
+
+data AstTensor (s :: AstSpan) (y :: Type) where
+ AstLet
+ :: forall a b s1 s2.
+ KnownSpan s1
+ => AstTensor s1 a
+ -> AstTensor s2 b
+ -> AstTensor s2 b
+
+ AstPrimalPart :: KnownSpan s' => AstTensor s' a -> AstTensor (PrimalStepSpan s') a
+ AstFromPrimal :: AstTensor (PrimalStepSpan s') a -> AstTensor s' a
+ AstPlainPart :: KnownSpan s' => AstTensor s' a -> AstTensor PlainSpan a
+ AstFromPlain :: AstTensor PlainSpan a -> AstTensor s' a
+
+interpretAst
+ :: forall target s y. (ADReady target, KnownSpan s)
+ => AstEnv target -> AstTensor s y
+ -> SpanTargetFam target s y
+{-# INLINE [1] interpretAst #-}
+interpretAst !env
+ = \case
+ AstLet @_ @_ @s1 @s2 u v ->
+ case knownSpan @s1 of
+ SFullSpan ->
+ ttlet (interpretAst env u)
+ (\_w -> interpretAst env v)
+ SPrimalStepSpan _ ->
+ ttletPrimal (interpretAst env u)
+ (\_w -> interpretAst env v)
+ SPlainSpan ->
+ ttletPlain (interpretAst env u)
+ (\_w -> interpretAst env v)
+ AstPrimalPart a ->
+ tprimalPart (interpretAst env a)
+ AstFromPrimal a ->
+ tfromPrimal (interpretAst env a)
+ AstPlainPart a ->
+ tplainPart (interpretAst env a)
+ AstFromPlain a ->
+ tfromPlain (interpretAst env a)
=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -578,4 +578,6 @@ test('T26615', [grep_errmsg(r'fEqList')], multimod_compile, ['T26615', '-O -fsp
# T26722: there should be no reboxing in $wg
test('T26722', [grep_errmsg(r'SPEC')], compile, ['-O -dno-typeable-binds'])
+
test('T26805', [grep_errmsg(r'fromInteger')], compile, ['-O -dno-typeable-binds -ddump-simpl -dsuppress-uniques'])
+test('T26826', normal, compile, ['-O'])
=====================================
utils/check-exact/ExactPrint.hs
=====================================
@@ -4794,7 +4794,6 @@ hsLit2String lit =
HsChar src v -> toSourceTextWithSuffix src v ""
HsCharPrim src p -> toSourceTextWithSuffix src p ""
HsString src v -> toSourceTextWithSuffix src v ""
- HsMultilineString src v -> toSourceTextWithSuffix src v ""
HsStringPrim src v -> toSourceTextWithSuffix src v ""
HsInt _ (IL src _ v) -> toSourceTextWithSuffix src v ""
HsIntPrim src v -> toSourceTextWithSuffix src v ""
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f856b07bcbfad98d67c9790e03053a…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f856b07bcbfad98d67c9790e03053a…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Peyton Jones pushed new branch wip/T26868 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T26868
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Peyton Jones pushed to branch wip/T20264 at Glasgow Haskell Compiler / GHC
Commits:
99746f25 by Simon Peyton Jones at 2026-02-02T17:44:36+00:00
Onward
- - - - -
2 changed files:
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/TyCo/FVs.hs
Changes:
=====================================
compiler/GHC/Core/Opt/Specialise.hs
=====================================
@@ -1728,6 +1728,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
-- , text "rhs_bndrs" <+> ppr (sep (map (pprBndr LambdaBind) rhs_bndrs))
-- , text "rhs_body" <+> ppr rhs_body
-- , text "subst'" <+> ppr subst'
+-- , text "subst_in_scope'" <+> ppr (substInScopeSet subst')
-- ]) $ return ()
@@ -1819,11 +1820,12 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
, text "rule_act" <+> ppr rule_act
]
--- ; pprTrace "spec_call: rule" (vcat [ -- text "poly_qvars" <+> ppr poly_qvars
--- text "rule_bndrs" <+> ppr rule_bndrs
+-- ; pprTrace "spec_call: rule" (vcat [ text "rule_bndrs" <+> ppr rule_bndrs
-- , text "rule_lhs_args" <+> ppr rule_lhs_args
-- , text "all_call_args" <+> ppr all_call_args
-- , ppr spec_rule ]) $
+-- return ()
+
; return ( spec_rule : rules_acc
, (spec_fn, spec_rhs1) : pairs_acc
, rhs_uds2 `thenUDs` uds_acc
@@ -2703,6 +2705,11 @@ specHeader subst (bndr:bndrs) (SpecDict dict_arg : args)
; (_, subst4, rule_bs, rule_es, spec_bs, dx, spec_args) <- specHeader subst3 bndrs args
; let dx' = tv_binds `appOL` dx1 `appOL` dx
+-- ; pprTrace "specHeader" (vcat [ text "dict_arg" <+> ppr dict_arg
+-- , text "tv_bndrs" <+> ppr tv_bndrs
+-- , text "tv_binds" <+> ppr tv_binds
+-- , text "in_scope" <+> ppr (substInScopeSet subst4) ]) $
+-- return ()
; pure ( True, subst4 -- Ha! A useful specialisation!
, bndr' : rule_bs, Var bndr' : rule_es
, spec_bs, dx', spec_dict : spec_args ) }
@@ -2733,11 +2740,14 @@ specHeader subst (bndr:bndrs) (UnspecArg : args)
bindAuxiliaryTyVars :: Subst -> CoreExpr -> (TyVarSet, OrdList FloatBind)
+-- (bindAuxiliaryTyVars subst dict_arg) returns bindings for any
+-- free tyvars of dict_arg that are not in scope, but have an unfolding
+-- And it return the set of precisely those tyvars, the binders of the bindings
bindAuxiliaryTyVars subst dict_arg
= go emptyVarSet need_bind_tvs
where
- go _ []
- = (emptyVarSet, nilOL)
+ go tv_bndrs []
+ = (tv_bndrs, nilOL)
go tv_bndrs (tv:tvs)
| tv `elemVarSet` tv_bndrs
= go tv_bndrs tvs
@@ -2749,11 +2759,11 @@ bindAuxiliaryTyVars subst dict_arg
, child_binds `appOL` unitOL (mkDB (NonRec tv (Type unf)))
`appOL` rest_binds )
| otherwise
- = pprTrace "addTyVarBindings: unxpected 1" (ppr tv $$ ppr dict_arg) $
- go tv_bndrs tvs
+ = pprPanic "addTyVarBindings: unxpected 1" (ppr tv $$ ppr dict_arg)
need_bind_tvs = exprSomeFreeVarsList needs_binding dict_arg
in_scope = substInScopeSet subst
+
needs_binding var
| isGlobalVar var
= False
=====================================
compiler/GHC/Core/TyCo/FVs.hs
=====================================
@@ -630,9 +630,12 @@ tyCoVarsOfTypesList tys = fvVarList $ tyCoFVsOfTypes tys
tyCoFVsOfType :: Type -> FV
-- See Note [Free variables of types]
tyCoFVsOfType (TyVarTy v) f bound_vars (acc_list, acc_set)
- | not (f v) = (acc_list, acc_set)
| v `elemVarSet` bound_vars = (acc_list, acc_set)
| v `elemVarSet` acc_set = (acc_list, acc_set)
+ | not (f v) = (acc_list, acc_set) -- Do this after checking bound_vars, because
+ -- maybe `f` uses the /identity/ of the tyvar,
+ -- and that makes no sense for bound vars
+ -- Ordering wrt `acc_set` is not important
| otherwise = tyCoFVsOfType (tyVarKind v) f
emptyVarSet -- See Note [Closing over free variable kinds]
(v:acc_list, extendVarSet acc_set v)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99746f25364f1733c037a54421db844…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99746f25364f1733c037a54421db844…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26854] 8 commits: determinism: Use deterministic map for Strings in TyLitMap
by Simon Peyton Jones (@simonpj) 02 Feb '26
by Simon Peyton Jones (@simonpj) 02 Feb '26
02 Feb '26
Simon Peyton Jones pushed to branch wip/T26854 at Glasgow Haskell Compiler / GHC
Commits:
aeeb4a20 by Matthew Pickering at 2026-01-30T11:42:47-05:00
determinism: Use deterministic map for Strings in TyLitMap
When generating typeable evidence the types we need evidence for all
cached in a TypeMap, the order terms are retrieved from a type map
determines the order the bindings appear in the program.
A TypeMap is quite diligent to use deterministic maps, apart from in the
TyLitMap, which uses a UniqFM for storing strings, whose ordering
depends on the Unique of the FastString.
This can cause non-deterministic .hi and .o files.
An unexpected side-effect is the error message but RecordDotSyntaxFail8
changing. I looked into this with Sam and this change caused the
constraints to be solved in a different order which results in a
slightly different error message. I have accepted the new test, since
the output before was non-deterministic and the new output is consistent
with the other messages in that file.
Fixes #26846
- - - - -
9e4d70c2 by Andrew Lelechenko at 2026-01-30T11:43:29-05:00
Upgrade text submodule to 2.1.4
- - - - -
631fa5ae by Recursion Ninja at 2026-01-31T22:30:11+00:00
Decouple `L.S.H.Decls` from importing `GHC.Types.Basic`
Data-types within `GHC.Types.Basic` which describe components of
the AST are migrated to `Language.Haskell.Syntax.Basic`. Related
function definitions are also moved.
Types moved to L.H.S. because they are part of the AST:
* TopLevelFlag
* RuleName
Types moved from L.H.S. to GHC.Hs. because they are not needed in the AST:
* TyConFlavour
* TypeOrData
* NewOrData
Migrated instances:
* `Outputable` instances moved to in `GHC.Utils.Outputable`
* `Binary` instance of `Boxity` moved to to `GHC.Utils.Binary`
* Other `Binary` instances are orphans to be migrated later.
The `OverlapMode` data-type is given a TTG extension point.
The `OverlapFlag` data-type, which depends on `OverlapMode`,
is updated to support `OverlapMode` with a GHC "pass" type paramerter.
In order to avoid module import cycles, `OverlapMode` and `OverlapFlag`
are migrated to new modules (no way around this).
* Migrated `OverlapMode` to new module `Language.Haskell.Syntax.Overlap`
* Migrated `OverlapFlag` to new module `GHC.Hs.Decls.Overlap`
- - - - -
9769cc03 by Simon Hengel at 2026-02-01T04:21:03-05:00
Update the documentation for MultiWayIf (fixes #25376)
(so that it matches the implementation)
- - - - -
5fc9442a by Peter Trommler at 2026-02-01T04:21:44-05:00
hadrian: Fix dependency generation for assembler
Assembler files allow # for comments unless in column 1. A modern
cpp for C treats those a preprocessor directives. We tell gcc that
a .S file is assembler with cpp and not C.
Fixes #26819
- - - - -
269c4087 by Simon Peyton Jones at 2026-02-01T19:38:10-05:00
Include current phase in the range for rule/unfoldings
This MR fixes a bad loop in the compiler: #26826.
The fix is to add (WAR2) to
Note [What is active in the RHS of a RULE or unfolding?]
in GHC.Core.Opt.Simplify.Utils
- - - - -
ddf1434f by Vladislav Zavialov at 2026-02-01T19:38:52-05:00
Refactor: merge HsMultilineString into HsString (#26860)
Before this patch, HsLit defined two separate constructors to represent
single-line and multi-line strings:
data HsLit x
...
| HsString (XHsString x) FastString
| HsMultilineString (XHsMultilineString x) FastString
I found this to be an unnecessary complication and an obstacle to unifying
HsLit with HsTyLit. Now we use HsString for both kinds of literals.
One user-facing change here is `ppr (HsString st s)` behaving differently for
single-line strings containing newlines:
x = "first line \
\asdf\n\
\second line"
Previously, the literal was fed to `ftext` with its newlines, producing an
ill-formed SDoc. This issue is now addressed by using `split` for both
single-line and multi-line strings:
vcat $ map text $ split '\n' (unpackFS src)
See the parser/should_fail/T26860ppr test.
In addition (and unrelatedly to the main payload of this patch),
drop the unused pmPprHsLit helper.
- - - - -
2b4f463c by Simon Peyton Jones at 2026-02-02T17:32:32+00:00
Remove exprIsCheap from doFloatFromRhs
See #26854 and Note [Float when expandable]
This patch simplifies the code, by removing an extra unnecessary test.
- - - - -
66 changed files:
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Core/Map/Type.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Hs/Decls.hs
- + compiler/GHC/Hs/Decls/Overlap.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/String.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/InlinePragma.hs
- compiler/GHC/Types/Name.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/Language/Haskell/Syntax/Basic.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- + compiler/Language/Haskell/Syntax/Decls/Overlap.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/ghc.cabal.in
- docs/users_guide/exts/multiway_if.rst
- hadrian/src/Builder.hs
- hadrian/src/Rules/Compile.hs
- hadrian/src/Settings/Builders/Cc.hs
- hadrian/src/Settings/Packages.hs
- libraries/text
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/ghc-api/TypeMapStringLiteral.hs
- testsuite/tests/ghc-api/all.T
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- + testsuite/tests/parser/should_fail/T26860ppr.hs
- + testsuite/tests/parser/should_fail/T26860ppr.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/simplCore/should_compile/T26826.hs
- testsuite/tests/simplCore/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.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/-/compare/59b6865ba62b600aec4d17d2775f14…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/59b6865ba62b600aec4d17d2775f14…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/mp/ghc-9.10.1-determinism] determinism: Use a stable sort in WithHsDocIdentifiers binary instance
by Matthew Pickering (@mpickering) 02 Feb '26
by Matthew Pickering (@mpickering) 02 Feb '26
02 Feb '26
Matthew Pickering pushed to branch wip/mp/ghc-9.10.1-determinism at Glasgow Haskell Compiler / GHC
Commits:
06ea36f3 by Matthew Pickering at 2026-02-02T17:28:42+00:00
determinism: Use a stable sort in WithHsDocIdentifiers binary instance
`WithHsDocIdentifiers` is defined as
```
71 data WithHsDocIdentifiers a pass = WithHsDocIdentifiers
72 { hsDocString :: !a
73 , hsDocIdentifiers :: ![Located (IdP pass)]
74 }
```
This list of names is populated from `rnHsDocIdentifiers`, which calls
`lookupGRE`, which calls `lookupOccEnv_AllNameSpaces`, which calls
`nonDetEltsUFM` and returns the results in an order depending on
uniques.
Sorting the list with a stable sort before returning the interface makes
the output deterministic and follows the approach taken by other fields
in `Docs`.
Fixes #26858
- - - - -
1 changed file:
- compiler/GHC/Hs/Doc.hs
Changes:
=====================================
compiler/GHC/Hs/Doc.hs
=====================================
@@ -50,6 +50,7 @@ import qualified GHC.Utils.Outputable as O
import GHC.Hs.Extension
import GHC.Types.Unique.Map
import Data.List (sortBy)
+import Data.Function
import GHC.Hs.DocString
@@ -88,7 +89,7 @@ instance Outputable a => Outputable (WithHsDocIdentifiers a pass) where
instance Binary a => Binary (WithHsDocIdentifiers a GhcRn) where
put_ bh (WithHsDocIdentifiers s ids) = do
put_ bh s
- put_ bh $ BinLocated <$> ids
+ put_ bh $ BinLocated <$> (sortBy (stableNameCmp `on` getName) ids)
get bh =
liftA2 WithHsDocIdentifiers (get bh) (fmap unBinLocated <$> get bh)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06ea36f3018cf094c3bbbc8bbb6772c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06ea36f3018cf094c3bbbc8bbb6772c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
sheaf pushed new branch wip/debug-join-point at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/debug-join-point
You're receiving this email because of your account on gitlab.haskell.org.
1
0
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
8d17a905 by sheaf at 2026-02-02T18:13:58+01:00
WIP: debugging
- - - - -
3 changed files:
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Types/Id.hs
- testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
Changes:
=====================================
compiler/GHC/Core/SimpleOpt.hs
=====================================
@@ -1080,23 +1080,36 @@ joinPointBinding_maybe bndr rhs
-- need to demote it to a quasi join-point.
-- See Note [Quasi join points] in GHC.Core.Opt.Simplify.Iteration.
| Just orig_cat <- joinId_maybe bndr
- , AlwaysTailCalled
- { tailCallArity = _new_arity
- , tailCallJoinPointType = new_cat }
- <- tailCallInfo (idOccInfo bndr)
- = assertPpr (idJoinArity bndr == _new_arity)
- ( vcat [ text "joinPointBinding_maybe: incompatible join arities "
- , text "bndr:" <+> ppr bndr
- , text "rhs:" <+> ppr rhs
- , text "prev arity:" <+> ppr (idJoinArity bndr)
- , text " new arity:" <+> ppr _new_arity
- , text "orig_cat:" <+> ppr orig_cat
- , text " new_cat:" <+> ppr new_cat
- ]
- ) $ Just $
- if orig_cat == new_cat
- then (bndr, rhs)
- else (asJoinId bndr new_cat (idJoinArity bndr), rhs)
+ = case tailCallInfo (idOccInfo bndr) of
+ NoTailCallInfo ->
+ pprTrace "joinPointBinding_maybe: lost join?"
+ (vcat
+ [ text "bndr:" <+> ppr bndr
+ , text "rhs:" <+> ppr rhs
+ , text "arity:" <+> ppr (idJoinArity bndr)
+ , text "cat:" <+> ppr orig_cat
+ , text "occ_info:" <+> ppr (idOccInfo bndr)
+ ]) $
+ -- SLD TODO: I don't understand how this can happen, but apparently
+ -- it can. For now I'm preserving the join, but further investigation
+ -- is needed.
+ Just (bndr, rhs)
+ AlwaysTailCalled
+ { tailCallArity = _new_arity
+ , tailCallJoinPointType = new_cat } ->
+ assertPpr (idJoinArity bndr == _new_arity)
+ ( vcat [ text "joinPointBinding_maybe: incompatible join arities "
+ , text "bndr:" <+> ppr bndr
+ , text "rhs:" <+> ppr rhs
+ , text "prev arity:" <+> ppr (idJoinArity bndr)
+ , text " new arity:" <+> ppr _new_arity
+ , text "orig_cat:" <+> ppr orig_cat
+ , text " new_cat:" <+> ppr new_cat
+ ]
+ ) $ Just $
+ if orig_cat == new_cat
+ then (bndr, rhs)
+ else (asJoinId bndr new_cat (idJoinArity bndr), rhs)
| AlwaysTailCalled
{ tailCallArity = join_arity
=====================================
compiler/GHC/Types/Id.hs
=====================================
@@ -692,10 +692,16 @@ idJoinArity id =
JoinPoint { joinPointArity = ar } -> ar
NotJoinPoint -> pprPanic "idJoinArity" (ppr id)
-asJoinId :: Id -> JoinPointCategory -> JoinArity -> JoinId
+asJoinId :: HasDebugCallStack => Id -> JoinPointCategory -> JoinArity -> JoinId
asJoinId id cat arity
= warnPprTrace (not (isLocalId id))
"global id being marked as join var" (ppr id) $
+ -- SLD TODO debugging
+ pprTrace "asJoinId"
+ ( vcat [ text "id:" <+> ppr id
+ , text "cat:" <+> ppr cat
+ , text "callstack:" <+> callStackDoc
+ ]) $
id `setIdDetails` JoinId cat arity cbv_info
where
cbv_info = case Var.idDetails id of
=====================================
testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
=====================================
@@ -133,3 +133,50 @@ testQuasiTransitivity b n =
True -> {-# SCC "ticked" #-} j3 10
False -> j3 20
)
+
+--------------------------------------------------------------------------------
+-- Extracted from a GHC bootstrapping bug
+
+data AB = A | B
+
+data Int2 = MkInt2
+
+expt :: Int2 -> Int2
+expt _ = MkInt2
+{-# NOINLINE expt #-}
+
+add :: Int2 -> Int2 -> Int2
+add _ _ = MkInt2
+{-# NOINLINE add #-}
+
+big :: Int2 -> AB
+big _ = A
+{-# NOINLINE big #-}
+
+baz :: Int2
+baz = MkInt2
+{-# NOINLINE baz #-}
+
+no :: a
+no = no
+{-# NOINLINE no #-}
+
+mul :: Int2 -> Int2 -> Int2
+mul !_ !_ = no
+{-# INLINE mul #-}
+
+data T2 a b = MkT2 a b
+
+floatToDigits2 :: T2 Int2 Int2 -> T2 Int2 Int2
+floatToDigits2 ( MkT2 f0 e0 ) =
+ let
+ MkT2 f e =
+ let n = e0
+ in
+ case big n of
+ A -> MkT2 f0 ( add e0 n )
+ B -> MkT2 f0 e0
+ r = let be = expt e in mul f be
+
+ in
+ MkT2 r baz
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d17a90585f186ee1d46776fcfc62a2…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d17a90585f186ee1d46776fcfc62a2…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
0bcd1aec by sheaf at 2026-02-02T17:57:59+01:00
WIP: debugging
- - - - -
3 changed files:
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Types/Id.hs
- testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
Changes:
=====================================
compiler/GHC/Core/SimpleOpt.hs
=====================================
@@ -1080,23 +1080,33 @@ joinPointBinding_maybe bndr rhs
-- need to demote it to a quasi join-point.
-- See Note [Quasi join points] in GHC.Core.Opt.Simplify.Iteration.
| Just orig_cat <- joinId_maybe bndr
- , AlwaysTailCalled
- { tailCallArity = _new_arity
- , tailCallJoinPointType = new_cat }
- <- tailCallInfo (idOccInfo bndr)
- = assertPpr (idJoinArity bndr == _new_arity)
- ( vcat [ text "joinPointBinding_maybe: incompatible join arities "
- , text "bndr:" <+> ppr bndr
- , text "rhs:" <+> ppr rhs
- , text "prev arity:" <+> ppr (idJoinArity bndr)
- , text " new arity:" <+> ppr _new_arity
- , text "orig_cat:" <+> ppr orig_cat
- , text " new_cat:" <+> ppr new_cat
- ]
- ) $ Just $
- if orig_cat == new_cat
- then (bndr, rhs)
- else (asJoinId bndr new_cat (idJoinArity bndr), rhs)
+ = case tailCallInfo (idOccInfo bndr) of
+ NoTailCallInfo ->
+ pprTrace "joinPointBinding_maybe: lost join?"
+ (vcat
+ [ text "bndr:" <+> ppr bndr
+ , text "rhs:" <+> ppr rhs
+ , text "arity:" <+> ppr (idJoinArity bndr)
+ , text "cat:" <+> ppr orig_cat
+ , text "occ_info:" <+> ppr (idOccInfo bndr)
+ ])
+ Nothing
+ AlwaysTailCalled
+ { tailCallArity = _new_arity
+ , tailCallJoinPointType = new_cat } ->
+ assertPpr (idJoinArity bndr == _new_arity)
+ ( vcat [ text "joinPointBinding_maybe: incompatible join arities "
+ , text "bndr:" <+> ppr bndr
+ , text "rhs:" <+> ppr rhs
+ , text "prev arity:" <+> ppr (idJoinArity bndr)
+ , text " new arity:" <+> ppr _new_arity
+ , text "orig_cat:" <+> ppr orig_cat
+ , text " new_cat:" <+> ppr new_cat
+ ]
+ ) $ Just $
+ if orig_cat == new_cat
+ then (bndr, rhs)
+ else (asJoinId bndr new_cat (idJoinArity bndr), rhs)
| AlwaysTailCalled
{ tailCallArity = join_arity
=====================================
compiler/GHC/Types/Id.hs
=====================================
@@ -692,10 +692,16 @@ idJoinArity id =
JoinPoint { joinPointArity = ar } -> ar
NotJoinPoint -> pprPanic "idJoinArity" (ppr id)
-asJoinId :: Id -> JoinPointCategory -> JoinArity -> JoinId
+asJoinId :: HasDebugCallStack => Id -> JoinPointCategory -> JoinArity -> JoinId
asJoinId id cat arity
= warnPprTrace (not (isLocalId id))
"global id being marked as join var" (ppr id) $
+ -- SLD TODO debugging
+ pprTrace "asJoinId"
+ ( vcat [ text "id:" <+> ppr id
+ , text "cat:" <+> ppr cat
+ , text "callstack:" <+> callStackDoc
+ ]) $
id `setIdDetails` JoinId cat arity cbv_info
where
cbv_info = case Var.idDetails id of
=====================================
testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
=====================================
@@ -133,3 +133,50 @@ testQuasiTransitivity b n =
True -> {-# SCC "ticked" #-} j3 10
False -> j3 20
)
+
+--------------------------------------------------------------------------------
+-- Extracted from a GHC bootstrapping bug
+
+data AB = A | B
+
+data Int2 = MkInt2
+
+expt :: Int2 -> Int2
+expt _ = MkInt2
+{-# NOINLINE expt #-}
+
+add :: Int2 -> Int2 -> Int2
+add _ _ = MkInt2
+{-# NOINLINE add #-}
+
+big :: Int2 -> AB
+big _ = A
+{-# NOINLINE big #-}
+
+baz :: Int2
+baz = MkInt2
+{-# NOINLINE baz #-}
+
+no :: a
+no = no
+{-# NOINLINE no #-}
+
+mul :: Int2 -> Int2 -> Int2
+mul !_ !_ = no
+{-# INLINE mul #-}
+
+data T2 a b = MkT2 a b
+
+floatToDigits2 :: T2 Int2 Int2 -> T2 Int2 Int2
+floatToDigits2 ( MkT2 f0 e0 ) =
+ let
+ MkT2 f e =
+ let n = e0
+ in
+ case big n of
+ A -> MkT2 f0 ( add e0 n )
+ B -> MkT2 f0 e0
+ r = let be = expt e in mul f be
+
+ in
+ MkT2 r baz
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bcd1aec81de7f1f227bcd073ca717f…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bcd1aec81de7f1f227bcd073ca717f…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/cross-windows-wine-iserv] 53 commits: base: don't expose GHC.Num.{BigNat, Integer, Natural}
by Cheng Shao (@TerrorJack) 02 Feb '26
by Cheng Shao (@TerrorJack) 02 Feb '26
02 Feb '26
Cheng Shao pushed to branch wip/cross-windows-wine-iserv at Glasgow Haskell Compiler / GHC
Commits:
30f442a9 by Teo Camarasu at 2026-01-20T13:57:26-05:00
base: don't expose GHC.Num.{BigNat, Integer, Natural}
We no longer expose GHC.Num.{BigNat, Integer, Natural} from base instead users should get these modules from ghc-bignum.
We make this change to insulate end users from changes to GHC's implementation of big numbers.
Implements CLC proposal 359: https://github.com/haskell/core-libraries-committee/issues/359
- - - - -
75a9053d by Teo Camarasu at 2026-01-20T13:58:07-05:00
base: deprecate GHC internals in GHC.Num
Implements CLC proposal: https://github.com/haskell/core-libraries-committee/issues/360
- - - - -
9534b032 by Andreas Klebinger at 2026-01-20T13:58:50-05:00
ghc-experimental: Update Changelog
I tried to reconstruct a high level overview of the changes and when
they were made since we introduced it.
Fixes #26506
Co-authored-by: Teo Camarasu <teofilcamarasu(a)gmail.com>
- - - - -
346f2f5a by Cheng Shao at 2026-01-20T13:59:30-05:00
hadrian: remove RTS options in ghc-in-ghci flavour
This patch removes the RTS options passed to ghc in ghc-in-ghci
flavour, to workaround command line argument handling issue in
hls/hie-boot that results in `-O64M` instead of `+RTS -O64M -RTS`
being passed to ghc. It's not a hadrian bug per se, since ghc's own
ghc-in-ghci multi repl works fine, but we should still make sure HLS
works. Closes #26801.
- - - - -
759fd15a by Andreas Klebinger at 2026-01-21T16:05:28-05:00
Don't build GHC with -Wcompat
Without bumping the boot compiler the warnings it produces are often not
actionable leading to pointless noise.
Fixes #26800
- - - - -
3172db94 by Torsten Schmits at 2026-01-21T16:06:11-05:00
Use the correct field of ModOrigin when formatting error message listing hidden reexports
- - - - -
485c12b2 by Cheng Shao at 2026-01-21T16:06:54-05:00
Revert "hadrian: handle findExecutable "" gracefully"
This reverts commit 1e5752f64a522c4025365856d92f78073a7b3bba. The
underlying issue has been fixed in
https://github.com/haskell/directory/commit/75828696e7145adc09179111a0d631b…
and present since 1.3.9.0, and hadrian directory lower bound is
1.3.9.0, so we can revert our own in house hack now.
- - - - -
5efb58dc by Cheng Shao at 2026-01-21T16:07:36-05:00
rts: fix typo in TICK_ALLOC_RTS
This patch fixes a typo in the `TICK_ALLOC_RTS` macro, the original
`bytes` argument was silently dropped. The Cmm code has its own
version of `TICK_ALLOC_RTS` not affected by this typo, it affected the
C RTS, and went unnoticed because the variable `n` happened to also be
available at its call site. But the number was incorrect. Also fixes
its call site since `WDS()` is not available in C.
- - - - -
c406ea69 by Cheng Shao at 2026-01-21T16:07:36-05:00
rts: remove broken & unused ALLOC_P_TICKY
This patch removes the `ALLOC_P_TICKY` macro from the rts, it's
unused, and its expanded code is already broken.
- - - - -
34a27e20 by Simon Peyton Jones at 2026-01-21T16:08:17-05:00
Make the implicit-parameter class have representational role
This MR addresses #26737, by making the built-in class IP
have a representational role for its second parameter.
See Note [IP: implicit parameter class] in
ghc-internal:GHC.Internal.Classes.IP
In fact, IP is (unfortunately, currently) exposed by
base:GHC.Base, so we ran a quick CLC proposal to
agree the change:
https://github.com/haskell/core-libraries-committee/issues/385
Some (small) compilations get faster because they only need to
load (small) interface file GHC.Internal.Classes.IP.hi,
rather than (large) GHC.Internal.Classes.hi.
Metric Decrease:
T10421
T12150
T12425
T24582
T5837
T5030
- - - - -
ca79475f by Cheng Shao at 2026-01-21T16:09:00-05:00
testsuite: avoid re.sub in favor of simple string replacements
This patch refactors the testsuite driver and avoids the usage of
re.sub in favor of simple string replacements when possible. The
changes are not comprehensive, and there are still a lot of re.sub
usages lingering around the tree, but this already addresses a major
performance bottleneck in the testsuite driver that might has to do
with quadratic or worse slowdown in cpython's regular expression
engine when handling certain regex patterns with large strings.
Especially on i386, and i386 jobs are the bottlenecks of all full-ci
validate pipelines!
Here are the elapsed times of testing x86_64/i386 with -j48 before
this patch:
x86_64: `Build completed in 6m06s`
i386: `Build completed in 1h36m`
And with this patch:
x86_64: `Build completed in 4m55s`
i386: `Build completed in 4m23s`
Fixes #26786.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
88c93796 by Zubin Duggal at 2026-01-21T16:09:42-05:00
ghc-toolchain: Also configure windres on non-windows platforms.
It may be needed for cross compilation.
Fixes #24588
- - - - -
9788c0ec by Cheng Shao at 2026-01-21T16:10:24-05:00
ghci: print external interpreter trace messages to stderr instead of stdout
This patch makes ghci print external interpreter trace messages to
stderr instead of stdout, which is a much saner choice for diagnostic
information. Closes #26807.
- - - - -
0491f08a by Sylvain Henry at 2026-01-22T03:44:26-05:00
GC: don't use CAS without PARALLEL_GC on
If we're not using the parallel GC, there is no reason to do a costly
CAS. This was flagged as taking time in a perf profile.
- - - - -
211a8f56 by Sylvain Henry at 2026-01-22T03:44:26-05:00
GC: suffix parallel GC with "par" instead of "thr"
Avoid some potential confusion (see discussion in !15351).
- - - - -
77a23cbd by fendor at 2026-01-22T03:45:08-05:00
Remove blanket ignore that covers libraries/
- - - - -
18bf7f5c by Léana Jiang at 2026-01-22T08:58:45-05:00
doc: update Flavour type in hadrian user-settings
- - - - -
3d5a1365 by Cheng Shao at 2026-01-22T08:59:28-05:00
hadrian: add missing notCross predicate for stage0 -O0
There are a few hard-coded hadrian args that pass -O0 when compiling
some heavy modules in stage0, which only makes sense when not
cross-compiling and when cross-compiling we need properly optimized
stage0 packages. So this patch adds the missing `notCross` predicate
in those places.
- - - - -
ee937134 by Matthew Pickering at 2026-01-22T09:00:10-05:00
Fix ghc-experimental GHC.Exception.Backtrace.Experimental module
This module wasn't added to the cabal file so it was never compiled or
included in the library.
- - - - -
1b490f5a by Zubin Duggal at 2026-01-22T09:00:53-05:00
hadrian: Add ghc-{experimental,internal}.cabal to the list of dependencies of the doc target
We need these files to detect the version of these libraries
Fixes #26738
- - - - -
cdb74049 by Cheng Shao at 2026-01-22T14:52:36-05:00
rts: avoid Cmm loop to initialize Array#/SmallArray#
Previously, `newArray#`/`newSmallArray#` called an RTS C function to
allocate the `Array#`/`SmallArray#`, then used a Cmm loop to
initialize the elements. Cmm doesn't have native for-loop so the code
is a bit awkward, and it's less efficient than a C loop, since the C
compiler can effectively vectorize the loop with optimizations.
So this patch moves the loop that initializes the elements to the C
side. `allocateMutArrPtrs`/`allocateSmallMutArrPtrs` now takes a new
`init` argument and initializes the elements if `init` is non-NULL.
- - - - -
4c784f00 by Cheng Shao at 2026-01-22T14:53:19-05:00
Fix testsuite run for +ipe flavour transformer
This patch makes the +ipe flavour transformer pass the entire
testsuite:
- An RTS debug option `-DI` is added, the IPE trace information is now
only printed with `-DI`. The test cases that do require IPE trace
are now run with `-DI`.
- The testsuite config option `ghc_with_ipe` is added, enabled when
running the testsuite with `+ipe`, which skips a few tests that are
sensitive to eventlog output, allocation patterns etc that can fail
under `+ipe`.
This is the first step towards #26799.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
be8e5236 by Ben Gamari at 2026-01-23T03:28:45-05:00
hadrian: Bump QuickCheck upper bound
This patch bumps QuickCheck upper bound to 2.18. selftest rule
manually tested to work with current latest QuickCheck-2.17.1.0.
- - - - -
5aa328fb by Zubin Duggal at 2026-01-23T03:29:30-05:00
Add genindex to index.rst. This adds a link to the index in the navigation bar.
Fixes #26437
- - - - -
917ab8ff by Oleg Grenrus at 2026-01-23T10:52:55-05:00
Export labelThread from Control.Concurrent
- - - - -
3f5e8d80 by Cheng Shao at 2026-01-23T10:53:37-05:00
ci: only push perf notes on master/release branches
This patch fixes push_perf_notes logic in ci.sh to only push perf
notes on master/release branches. We used to unconditionally push perf
notes even in MRs, but the perf numbers in the wip branches wouldn't
be used as baseline anyway, plus this is causing a space leak in the
ghc-performance-notes repo. See #25317 for the perf notes repo size
problem.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
414b9593 by Cheng Shao at 2026-01-24T07:11:51-05:00
ci: remove duplicate keys in .gitlab-ci.yml
This patch removes accidentally duplicate keys in `.gitlab-ci.yml`.
The YAML spec doesn't allow duplicate keys in the first place, and
according to GitLab docs
(https://docs.gitlab.com/ci/yaml/yaml_optimization/#anchors) the
latest key overrides the earlier entries.
- - - - -
e5cb5491 by Cheng Shao at 2026-01-24T07:12:34-05:00
hadrian: drop obsolete configure/make builder logic for libffi
This patch drops obsolete hadrian logic around `Configure
libffiPath`/`Make libffiPath` builders, they are no longer needed
after libffi-clib has landed. Closes #26815.
- - - - -
2d160222 by Simon Hengel at 2026-01-24T07:13:17-05:00
Fix typo in roles.rst
- - - - -
56db94f7 by Peter Trommler at 2026-01-26T11:26:18+01:00
PPC NCG: Generate clear right insn at arch width
The clear right immediate (clrrxi) is only available in word and
doubleword width. Generate clrrxi instructions at architecture
width for all MachOp widths.
Fixes #24145
- - - - -
5957a8ad by Wolfgang Jeltsch at 2026-01-27T06:11:40-05:00
Add operations for obtaining operating-system handles
This contribution implements CLC proposal #369. It adds operations for
obtaining POSIX file descriptors and Windows handles that underlie
Haskell handles. Those operating system handles can also be obtained
without such additional operations, but this is more involved and, more
importantly, requires using internals.
- - - - -
86a0510c by Greg Steuck at 2026-01-27T06:12:34-05:00
Move flags to precede patterns for grep and read files directly
This makes the tests pass with non-GNU (i.e. POSIX-complicant) tools.
There's no reason to use cat and pipe where direct file argument works.
- - - - -
50761451 by Cheng Shao at 2026-01-27T21:51:23-05:00
ci: update darwin boot ghc to 9.10.3
This patch updates darwin boot ghc to 9.10.3, along with other related
updates, and pays off some technical debt here:
- Update `nixpkgs` and use the `nixpkgs-25.05-darwin` channel.
- Update the `niv` template.
- Update LLVM to 21 and update `llvm-targets` to reflect LLVM 21
layout changes for arm64/x86_64 darwin targets.
- Use `stdenvNoCC` to prevent nix packaged apple sdk from being used
by boot ghc, and manually set `DEVELOPER_DIR`/`SDKROOT` to enforce
the usage of system-wide command line sdk for macos.
- When building nix derivation for boot ghc, run `configure` via the
`arch` command so that `configure` and its subprocesses pick up the
manually specified architecture.
- Remove the previous horrible hack that obliterates `configure` to
make autoconf test result in true. `configure` now properly does its
job.
- Remove the now obsolete configure args and post install settings
file patching logic.
- Use `scheme-small` for texlive to avoid build failures in certain
unused texlive packages, especially on x86_64-darwin.
- - - - -
94dcd15e by Matthew Pickering at 2026-01-27T21:52:05-05:00
Evaluate backtraces for "error" exceptions at the moment they are thrown
See Note [Capturing the backtrace in throw] and
Note [Hiding precise exception signature in throw] which explain the
implementation.
This commit makes `error` and `throw` behave the same with regard to
backtraces. Previously, exceptions raised by `error` would not contain
useful IPE backtraces.
I did try and implement `error` in terms of `throw` but it started to
involve putting diverging functions into hs-boot files, which seemed to
risky if the compiler wouldn't be able to see if applying a function
would diverge.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/383
Fixes #26751
- - - - -
ef35e3ea by Teo Camarasu at 2026-01-27T21:52:46-05:00
ghc-internal: move all Data instances to Data.Data
Most instances of Data are defined in GHC.Internal.Data.Data.
Let's move all remaining instance there.
This moves other modules down in the dependency hierarchy allowing for
more parallelism, and it decreases the likelihood that we would need to
load this heavy .hi file if we don't actually need it.
Resolves #26830
Metric Decrease:
T12227
T16875
- - - - -
5e0ec555 by sheaf at 2026-01-28T06:56:38-05:00
Add test case for #25679
This commit adds the T25679 test case. The test now passes, thanks to
commit 1e53277af36d3f0b6ad5491f70ffc5593a49dcfd.
Fixes #25679
- - - - -
f1cd1611 by sheaf at 2026-01-28T06:56:38-05:00
Improve defaulting of representational equalities
This commit makes the defaulting of representational equalities, introduced
in 1e53277a, a little bit more robust. Now, instead of calling the eager
unifier, it calls the full-blown constraint solver, which means that it can
handle some subtle situations, e.g. involving functional dependencies and
type-family injectivity annotations, such as:
type family F a = r | r -> a
type instance F Int = Bool
[W] F beta ~R Bool
- - - - -
25edf516 by sheaf at 2026-01-28T06:56:38-05:00
Improve errors for unsolved representational equalities
This commit adds a new field of CtLoc, CtExplanations, which allows the
typechecker to leave some information about what it has done. For the moment,
it is only used to improve error messages for unsolved representational
equalities. The typechecker will now accumulate, when unifying at
representational role:
- out-of-scope newtype constructors,
- type constructors that have nominal role in a certain argument,
- over-saturated type constructors,
- AppTys, e.g. `c a ~R# c b`, to report that we must assume that 'c' has
nominal role in its parameters,
- data family applications that do not reduce, potentially preventing
newtype unwrapping.
Now, instead of having to re-construct the possible errors after the fact,
we simply consult the CtExplanations field.
Additionally, this commit modifies the typechecker error messages that
concern out-of-scope newtype constructors. The error message now depends
on whether we have an import suggestion to provide to the user:
- If we have an import suggestion for the newtype constructor,
the message will be of the form:
The data constructor MkN of the newtype N is out of scope
Suggested fix: add 'MkN' to the import list in the import of 'M'
- If we don't have any import suggestions, the message will be
of the form:
NB: The type 'N' is an opaque newtype, whose constructor is hidden
Fixes #15850, #20289, #20468, #23731, #25949, #26137
- - - - -
4d0e6da1 by Simon Peyton Jones at 2026-01-28T06:57:19-05:00
Fix two bugs in short-cut constraint solving
There are two main changes here:
* Use `isSolvedWC` rather than `isEmptyWC` in `tryShortCutSolver`
The residual constraint may have some fully-solved, but
still-there implications, and we don't want them to abort short
cut solving! That bug caused #26805.
* In the short-cut solver, we abandon the fully-solved residual
constraint; but we may thereby lose track of Givens that are
needed, and either report them as redundant or prune evidence
bindings that are in fact needed.
This bug stopped the `constraints` package from compiling;
see the trail in !15389.
The second bug led me to (another) significant refactoring
of the mechanism for tracking needed EvIds. See the new
Note [Tracking needed EvIds] in GHC.Tc.Solver.Solve
It's simpler and much less head-scratchy now.
Some particulars:
* An EvBindsVar now tracks NeededEvIds
* We deal with NeededEvIds for an implication only when it is
fully solved. Much simpler!
* `tryShortCutTcS` now takes a `TcM WantedConstraints` rather than
`TcM Bool`, so that is can plumb the needed EvIds correctly.
* Remove `ic_need` and `ic_need_implic` from Implication (hooray),
and add `ics_dm` and `ics_non_dm` to `IC_Solved`.
Pure refactor
* Shorten data constructor `CoercionHole` to `CH`, following
general practice in GHC.
* Rename `EvBindMap` to `EvBindsMap` for consistency
- - - - -
662480b7 by Cheng Shao at 2026-01-28T06:58:00-05:00
ci: use debian validate bindists instead of fedora release bindists in testing stage
This patch changes the `abi-test`, `hadrian-multi` and `perf` jobs in
the full-ci pipeline testing stage to use debian validate bindists
instead of fedora release bindists, to increase pipeline level
parallelism and allow full-ci pipelines to complete earlier. Closes #26818.
- - - - -
39581ec6 by Cheng Shao at 2026-01-28T06:58:40-05:00
ci: run perf test with -j$cores
This patch makes the perf ci job compile Cabal with -j$cores to speed
up the job.
- - - - -
607b287b by Wolfgang Jeltsch at 2026-01-28T15:41:53+02:00
Remove `GHC.Desugar` from `base`
`GHC.Desugar` was deprecated and should have been removed in GHC 9.14.
However, the removal was forgotten, although there was a code block that
was intended to trigger a compilation error when the GHC version in use
was 9.14 or later. This code sadly didn’t work, because the
`__GLASGOW_HASKELL__` macro was misspelled as `__GLASGOW_HASKELL`.
- - - - -
e8f5a45d by sterni at 2026-01-29T04:19:18-05:00
users_guide: fix runtime error during build with Sphinx 9.1.0
Appears that pathto is stricter about what it accepts now.
Tested Sphinx 8.2.3 and 9.1.0 on the ghc-9.10 branch.
Resolves #26810.
Co-authored-by: Martin Weinelt <hexa(a)darmstadt.ccc.de>
- - - - -
ce2d62fb by Jessica Clarke at 2026-01-29T19:48:51-05:00
PPC NCG: Use libcall for 64-bit cmpxchg on 32-bit PowerPC
There is no native instruction for this, and even if there were a
register pair version we could use, the implementation here is assuming
the values fit in a single register, and we end up only using / defining
the low halves of the registers.
Fixes: b4d39adbb5 ("PrimOps: Add CAS op for all int sizes")
Fixes: #23969
- - - - -
43d97761 by Michael Karcher at 2026-01-29T19:49:43-05:00
NCG for PPC: add pattern for CmmRegOff to iselExpr64
Closes #26828
- - - - -
aeeb4a20 by Matthew Pickering at 2026-01-30T11:42:47-05:00
determinism: Use deterministic map for Strings in TyLitMap
When generating typeable evidence the types we need evidence for all
cached in a TypeMap, the order terms are retrieved from a type map
determines the order the bindings appear in the program.
A TypeMap is quite diligent to use deterministic maps, apart from in the
TyLitMap, which uses a UniqFM for storing strings, whose ordering
depends on the Unique of the FastString.
This can cause non-deterministic .hi and .o files.
An unexpected side-effect is the error message but RecordDotSyntaxFail8
changing. I looked into this with Sam and this change caused the
constraints to be solved in a different order which results in a
slightly different error message. I have accepted the new test, since
the output before was non-deterministic and the new output is consistent
with the other messages in that file.
Fixes #26846
- - - - -
9e4d70c2 by Andrew Lelechenko at 2026-01-30T11:43:29-05:00
Upgrade text submodule to 2.1.4
- - - - -
631fa5ae by Recursion Ninja at 2026-01-31T22:30:11+00:00
Decouple `L.S.H.Decls` from importing `GHC.Types.Basic`
Data-types within `GHC.Types.Basic` which describe components of
the AST are migrated to `Language.Haskell.Syntax.Basic`. Related
function definitions are also moved.
Types moved to L.H.S. because they are part of the AST:
* TopLevelFlag
* RuleName
Types moved from L.H.S. to GHC.Hs. because they are not needed in the AST:
* TyConFlavour
* TypeOrData
* NewOrData
Migrated instances:
* `Outputable` instances moved to in `GHC.Utils.Outputable`
* `Binary` instance of `Boxity` moved to to `GHC.Utils.Binary`
* Other `Binary` instances are orphans to be migrated later.
The `OverlapMode` data-type is given a TTG extension point.
The `OverlapFlag` data-type, which depends on `OverlapMode`,
is updated to support `OverlapMode` with a GHC "pass" type paramerter.
In order to avoid module import cycles, `OverlapMode` and `OverlapFlag`
are migrated to new modules (no way around this).
* Migrated `OverlapMode` to new module `Language.Haskell.Syntax.Overlap`
* Migrated `OverlapFlag` to new module `GHC.Hs.Decls.Overlap`
- - - - -
9769cc03 by Simon Hengel at 2026-02-01T04:21:03-05:00
Update the documentation for MultiWayIf (fixes #25376)
(so that it matches the implementation)
- - - - -
5fc9442a by Peter Trommler at 2026-02-01T04:21:44-05:00
hadrian: Fix dependency generation for assembler
Assembler files allow # for comments unless in column 1. A modern
cpp for C treats those a preprocessor directives. We tell gcc that
a .S file is assembler with cpp and not C.
Fixes #26819
- - - - -
269c4087 by Simon Peyton Jones at 2026-02-01T19:38:10-05:00
Include current phase in the range for rule/unfoldings
This MR fixes a bad loop in the compiler: #26826.
The fix is to add (WAR2) to
Note [What is active in the RHS of a RULE or unfolding?]
in GHC.Core.Opt.Simplify.Utils
- - - - -
ddf1434f by Vladislav Zavialov at 2026-02-01T19:38:52-05:00
Refactor: merge HsMultilineString into HsString (#26860)
Before this patch, HsLit defined two separate constructors to represent
single-line and multi-line strings:
data HsLit x
...
| HsString (XHsString x) FastString
| HsMultilineString (XHsMultilineString x) FastString
I found this to be an unnecessary complication and an obstacle to unifying
HsLit with HsTyLit. Now we use HsString for both kinds of literals.
One user-facing change here is `ppr (HsString st s)` behaving differently for
single-line strings containing newlines:
x = "first line \
\asdf\n\
\second line"
Previously, the literal was fed to `ftext` with its newlines, producing an
ill-formed SDoc. This issue is now addressed by using `split` for both
single-line and multi-line strings:
vcat $ map text $ split '\n' (unpackFS src)
See the parser/should_fail/T26860ppr test.
In addition (and unrelatedly to the main payload of this patch),
drop the unused pmPprHsLit helper.
- - - - -
b28e31b8 by Cheng Shao at 2026-02-02T14:58:10+01:00
WIP
- - - - -
272 changed files:
- .gitignore
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/darwin/nix/sources.json
- .gitlab/darwin/toolchain.nix
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Core/Map/Type.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/TyCo/Tidy.hs
- compiler/GHC/Core/TyCon/RecWalk.hs
- compiler/GHC/Data/Maybe.hs
- compiler/GHC/Hs/Decls.hs
- + compiler/GHC/Hs/Decls/Overlap.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/String.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Rename/Unbound.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/Runtime/Interpreter/Init.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Runtime/Utils.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Default.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/CtLoc.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/InlinePragma.hs
- compiler/GHC/Types/Name.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Monad.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/Trace.hs
- compiler/Language/Haskell/Syntax/Basic.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- + compiler/Language/Haskell/Syntax/Decls/Overlap.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/ghc.cabal.in
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/exts/multiway_if.rst
- docs/users_guide/exts/roles.rst
- docs/users_guide/index.rst
- docs/users_guide/rtd-theme/layout.html
- docs/users_guide/runtime_control.rst
- hadrian/doc/user-settings.md
- hadrian/hadrian.cabal
- hadrian/src/Builder.hs
- hadrian/src/Context.hs
- hadrian/src/Flavour.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Rules/Compile.hs
- hadrian/src/Rules/Docspec.hs
- hadrian/src/Rules/Documentation.hs
- hadrian/src/Rules/Lint.hs
- hadrian/src/Settings/Builders/Cc.hs
- hadrian/src/Settings/Builders/Configure.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Builders/Make.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Flavours/GhcInGhci.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/Control/Concurrent.hs
- libraries/base/src/Data/Array/Byte.hs
- − libraries/base/src/GHC/Desugar.hs
- libraries/base/src/GHC/Num.hs
- − libraries/base/src/GHC/Num/BigNat.hs
- − libraries/base/src/GHC/Num/Integer.hs
- − libraries/base/src/GHC/Num/Natural.hs
- libraries/base/src/System/CPUTime/Utils.hs
- + libraries/base/src/System/IO/OS.hs
- libraries/base/src/System/Timeout.hs
- libraries/base/tests/IO/all.T
- + libraries/base/tests/IO/osHandles001FileDescriptors.hs
- + libraries/base/tests/IO/osHandles001FileDescriptors.stdout
- + libraries/base/tests/IO/osHandles001WindowsHandles.hs
- + libraries/base/tests/IO/osHandles001WindowsHandles.stdout
- + libraries/base/tests/IO/osHandles002FileDescriptors.hs
- + libraries/base/tests/IO/osHandles002FileDescriptors.stderr
- + libraries/base/tests/IO/osHandles002FileDescriptors.stdin
- + libraries/base/tests/IO/osHandles002FileDescriptors.stdout
- + libraries/base/tests/IO/osHandles002WindowsHandles.hs
- + libraries/base/tests/IO/osHandles002WindowsHandles.stderr
- + libraries/base/tests/IO/osHandles002WindowsHandles.stdin
- + libraries/base/tests/IO/osHandles002WindowsHandles.stdout
- libraries/base/tests/T23454.stderr
- libraries/base/tests/perf/Makefile
- libraries/ghc-bignum/ghc-bignum.cabal
- libraries/ghc-compact/tests/all.T
- libraries/ghc-experimental/CHANGELOG.md
- libraries/ghc-experimental/ghc-experimental.cabal.in
- libraries/ghc-experimental/src/GHC/Exception/Backtrace/Experimental.hs
- libraries/ghc-experimental/src/GHC/TypeNats/Experimental.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Classes.hs
- + libraries/ghc-internal/src/GHC/Internal/Classes/IP.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Err.hs
- libraries/ghc-internal/src/GHC/Internal/Exts.hs
- libraries/ghc-internal/src/GHC/Internal/Functor/ZipList.hs
- + libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/all.T
- + libraries/ghc-internal/tests/stack-annotation/ann_frame005.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- libraries/ghci/GHCi/Run.hs
- libraries/ghci/GHCi/Server.hs
- libraries/ghci/GHCi/Utils.hsc
- + libraries/ghci/cbits/ghci_msvcrt_assert_shim.c
- libraries/ghci/ghci.cabal.in
- libraries/text
- llvm-targets
- rts/AllocArray.c
- rts/AllocArray.h
- rts/ClosureTable.c
- rts/Heap.c
- rts/PrimOps.cmm
- rts/RtsFlags.c
- rts/Threads.c
- rts/Trace.c
- rts/Weak.c
- rts/include/Cmm.h
- rts/include/rts/Flags.h
- rts/include/stg/Ticky.h
- rts/rts.cabal
- rts/sm/Evac.c
- rts/sm/Evac_thr.c → rts/sm/Evac_par.c
- rts/sm/Scav_thr.c → rts/sm/Scav_par.c
- rts/sm/Storage.c
- testsuite/driver/runtests.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/driver/testutil.py
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/default/T25825.hs
- testsuite/tests/default/all.T
- testsuite/tests/deriving/should_fail/T1496.stderr
- testsuite/tests/deriving/should_fail/T4846.stderr
- testsuite/tests/deriving/should_fail/T5498.stderr
- testsuite/tests/deriving/should_fail/T6147.stderr
- testsuite/tests/deriving/should_fail/T7148.stderr
- testsuite/tests/deriving/should_fail/T7148a.stderr
- testsuite/tests/deriving/should_fail/T8984.stderr
- testsuite/tests/deriving/should_fail/deriving-via-fail.stderr
- testsuite/tests/deriving/should_fail/deriving-via-fail4.stderr
- testsuite/tests/deriving/should_fail/deriving-via-fail5.stderr
- testsuite/tests/driver/T16318/Makefile
- testsuite/tests/driver/T18125/Makefile
- testsuite/tests/gadt/CasePrune.stderr
- + testsuite/tests/ghc-api/TypeMapStringLiteral.hs
- testsuite/tests/ghc-api/all.T
- testsuite/tests/ghci.debugger/scripts/T8487.stdout
- testsuite/tests/ghci.debugger/scripts/break011.stdout
- testsuite/tests/ghci.debugger/scripts/break017.stdout
- testsuite/tests/ghci.debugger/scripts/break025.stdout
- testsuite/tests/indexed-types/should_fail/T9580.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/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/linear/should_fail/LinearRole.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- + testsuite/tests/parser/should_fail/T26860ppr.hs
- + testsuite/tests/parser/should_fail/T26860ppr.stderr
- testsuite/tests/parser/should_fail/all.T
- testsuite/tests/roles/should_fail/RolesIArray.stderr
- testsuite/tests/rts/Makefile
- testsuite/tests/rts/all.T
- testsuite/tests/rts/ipe/all.T
- + testsuite/tests/simplCore/should_compile/T26805.hs
- + testsuite/tests/simplCore/should_compile/T26805.stderr
- + testsuite/tests/simplCore/should_compile/T26826.hs
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/th/TH_implicitParams.stdout
- + testsuite/tests/typecheck/should_compile/T26737.hs
- + testsuite/tests/typecheck/should_compile/T26805a.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T10285.stderr
- testsuite/tests/typecheck/should_fail/T10534.stderr
- testsuite/tests/typecheck/should_fail/T10715b.stderr
- testsuite/tests/typecheck/should_fail/T11347.stderr
- testsuite/tests/typecheck/should_fail/T15801.stderr
- + testsuite/tests/typecheck/should_fail/T15850.hs
- + testsuite/tests/typecheck/should_fail/T15850.stderr
- + testsuite/tests/typecheck/should_fail/T15850_Lib.hs
- + testsuite/tests/typecheck/should_fail/T20289.hs
- + testsuite/tests/typecheck/should_fail/T20289.stderr
- + testsuite/tests/typecheck/should_fail/T20289_A.hs
- testsuite/tests/typecheck/should_fail/T22645.stderr
- testsuite/tests/typecheck/should_fail/T22924a.stderr
- + testsuite/tests/typecheck/should_fail/T23731.hs
- + testsuite/tests/typecheck/should_fail/T23731.stderr
- + testsuite/tests/typecheck/should_fail/T23731b.hs
- + testsuite/tests/typecheck/should_fail/T23731b.stderr
- + testsuite/tests/typecheck/should_fail/T23731b_aux.hs
- + testsuite/tests/typecheck/should_fail/T25679.hs
- + testsuite/tests/typecheck/should_fail/T25679.stderr
- + testsuite/tests/typecheck/should_fail/T25949.hs
- + testsuite/tests/typecheck/should_fail/T25949.stderr
- + testsuite/tests/typecheck/should_fail/T25949_aux.hs
- + testsuite/tests/typecheck/should_fail/T26137.hs
- + testsuite/tests/typecheck/should_fail/T26137.stderr
- testsuite/tests/typecheck/should_fail/TcCoercibleFail.stderr
- testsuite/tests/typecheck/should_fail/TcCoercibleFail3.stderr
- testsuite/tests/typecheck/should_fail/all.T
- utils/check-exact/ExactPrint.hs
- utils/ghc-toolchain/exe/Main.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.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/-/compare/22304cd248af6b61f198a055653603…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/22304cd248af6b61f198a055653603…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/andreask/ticked_joins] Allow join point Ids to occur below ticks & casts
by sheaf (@sheaf) 02 Feb '26
by sheaf (@sheaf) 02 Feb '26
02 Feb '26
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
d72882fd by sheaf at 2026-02-02T15:15:12+01:00
Allow join point Ids to occur below ticks & casts
This commit classifies all join points into two categories:
- true join points
- quasi join points
A quasi join point is a join point for which a jump is enclosed within
a profiling tick or a cast.
The only operational difference is that, for quasi join points, we
cannot perform the case-of-case transformation described in
Note [Join points and case-of-case] in GHC.Core.Opt.Simplify.Iteration.
All of this is explained in detail in Note [Quasi join points].
Fixes #26693 and #26642
Improves on #14610, #26157 and #26422, as it means casts/profiling ticks
don't prevent join points, but it doesn't entirely fix these issues
because we are still inhibiting optimisations (lack of case-of-case).
- - - - -
33 changed files:
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/Exitify.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/FloatOut.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Monad.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/Unfold.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Id.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- testsuite/tests/profiling/should_run/T2552.prof.sample
- testsuite/tests/profiling/should_run/ioprof.prof.sample
- testsuite/tests/profiling/should_run/scc001.prof.sample
- + testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
- testsuite/tests/simplCore/should_compile/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d72882fd67646e4cb17885ddd0515f7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d72882fd67646e4cb17885ddd0515f7…
You're receiving this email because of your account on gitlab.haskell.org.
1
0