
[Git][ghc/ghc][wip/T25965] 4 commits: Simplifier: Constant fold invald tagToEnum# calls to bottom expr.
by Simon Peyton Jones (@simonpj) 22 Apr '25
by Simon Peyton Jones (@simonpj) 22 Apr '25
22 Apr '25
Simon Peyton Jones pushed to branch wip/T25965 at Glasgow Haskell Compiler / GHC
Commits:
2e204269 by Andreas Klebinger at 2025-04-22T12:20:41+02:00
Simplifier: Constant fold invald tagToEnum# calls to bottom expr.
When applying tagToEnum# to a out-of-range value it's best to simply
constant fold it to a bottom expression. That potentially allows more
dead code elimination and makes debugging easier.
Fixes #25976
- - - - -
7250fc0c by Matthew Pickering at 2025-04-22T16:24:04-04:00
Move -fno-code note into Downsweep module
This note was left behind when all the code which referred to it was
moved into the GHC.Driver.Downsweep module
- - - - -
d2dc89b4 by Matthew Pickering at 2025-04-22T16:24:04-04:00
Apply editing notes to Note [-fno-code mode] suggested by sheaf
These notes were suggested in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/14241
- - - - -
04f7475e by Simon Peyton Jones at 2025-04-22T22:13:27+01:00
Fix infelicities in the Specialiser
On the way to #23109 (unary classes) I discovered some infelicities
(or maybe tiny bugs, I forget) in the type-class specialiser.
I also tripped over #25965, an outright bug in the rule matcher
Specifically:
* Refactor: I enhanced `wantCallsFor`, whih previously always said
`True`, to discard calls of class-ops, data constructors etc. This is
a bit more efficient; and it means we don't need to worry about
filtering them out later.
* Fix: I tidied up some tricky logic that eliminated redundant
specialisations. It wasn't working correctly. See the expanded
Note [Specialisations already covered], and
(MP3) in Note [Specialising polymorphic dictionaries].
See also the new top-level `alreadyCovered`
function, which now goes via `GHC.Core.Rules.ruleLhsIsMoreSpecific`
I also added a useful Note [The (CI-KEY) invariant]
* Fix #25965: fixed a tricky bug in the `go_fam_fam` in
`GHC.Core.Unify.uVarOrFam`, which allows matching to succeed
without binding all type varibles.
I enhanced Note [Apartness and type families] some more
* #25703. This ticket "just works" with -fpolymorphic-specialisation;
but I was surprised that it worked! In this MR I added documentation
to Note [Interesting dictionary arguments] to explain; and tests to
ensure it stays fixed.
- - - - -
15 changed files:
- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Types/Basic.hs
- + testsuite/tests/simplCore/should_compile/T25703.hs
- + testsuite/tests/simplCore/should_compile/T25703.stderr
- + testsuite/tests/simplCore/should_compile/T25703a.hs
- + testsuite/tests/simplCore/should_compile/T25703a.stderr
- + testsuite/tests/simplCore/should_compile/T25965.hs
- + testsuite/tests/simplCore/should_compile/T25976.hs
- testsuite/tests/simplCore/should_compile/all.T
Changes:
=====================================
compiler/GHC/Core/Opt/ConstantFold.hs
=====================================
@@ -69,7 +69,6 @@ import GHC.Cmm.MachOp ( FMASign(..) )
import GHC.Cmm.Type ( Width(..) )
import GHC.Data.FastString
-import GHC.Data.Maybe ( orElse )
import GHC.Utils.Outputable
import GHC.Utils.Misc
@@ -1997,6 +1996,14 @@ because we don't expect the user to call tagToEnum# at all; we merely
generate calls in derived instances of Enum. So we compromise: a
rewrite rule rewrites a bad instance of tagToEnum# to an error call,
and emits a warning.
+
+We also do something similar if we can see that the argument of tagToEnum is out
+of bounds, e.g. `tagToEnum# 99# :: Bool`.
+Replacing this with an error expression is better for two reasons:
+* It allow us to eliminate more dead code in cases like `case tagToEnum# 99# :: Bool of ...`
+* Should we actually end up executing the relevant code at runtime the user will
+ see a meaningful error message, instead of a segfault or incorrect result.
+See #25976.
-}
tagToEnumRule :: RuleM CoreExpr
@@ -2008,9 +2015,13 @@ tagToEnumRule = do
Just (tycon, tc_args) | isEnumerationTyCon tycon -> do
let tag = fromInteger i
correct_tag dc = (dataConTagZ dc) == tag
- (dc:rest) <- return $ filter correct_tag (tyConDataCons_maybe tycon `orElse` [])
- massert (null rest)
- return $ mkTyApps (Var (dataConWorkId dc)) tc_args
+ Just dataCons <- pure $ tyConDataCons_maybe tycon
+ case filter correct_tag dataCons of
+ (dc:rest) -> do
+ massert (null rest)
+ pure $ mkTyApps (Var (dataConWorkId dc)) tc_args
+ -- Literal is out of range, e.g. tagToEnum @Bool #4
+ [] -> pure $ mkImpossibleExpr ty "tagToEnum: Argument out of range"
-- See Note [tagToEnum#]
_ -> warnPprTrace True "tagToEnum# on non-enumeration type" (ppr ty) $
=====================================
compiler/GHC/Core/Opt/Specialise.hs
=====================================
@@ -1243,14 +1243,15 @@ specExpr env (Let bind body)
-- Note [Fire rules in the specialiser]
fireRewriteRules :: SpecEnv -> InExpr -> [OutExpr] -> (InExpr, [OutExpr])
fireRewriteRules env (Var f) args
- | Just (rule, expr) <- specLookupRule env f args InitialPhase (getRules (se_rules env) f)
+ | let rules = getRules (se_rules env) f
+ , Just (rule, expr) <- specLookupRule env f args activeInInitialPhase rules
, let rest_args = drop (ruleArity rule) args -- See Note [Extra args in the target]
zapped_subst = Core.zapSubst (se_subst env)
expr' = simpleOptExprWith defaultSimpleOpts zapped_subst expr
-- simplOptExpr needed because lookupRule returns
-- (\x y. rhs) arg1 arg2
- , (fun, args) <- collectArgs expr'
- = fireRewriteRules env fun (args++rest_args)
+ , (fun', args') <- collectArgs expr'
+ = fireRewriteRules env fun' (args'++rest_args)
fireRewriteRules _ fun args = (fun, args)
--------------
@@ -1620,7 +1621,7 @@ specCalls :: Bool -- True => specialising imported fn
-- This function checks existing rules, and does not create
-- duplicate ones. So the caller does not need to do this filtering.
--- See 'already_covered'
+-- See `alreadyCovered`
type SpecInfo = ( [CoreRule] -- Specialisation rules
, [(Id,CoreExpr)] -- Specialised definition
@@ -1644,15 +1645,13 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
= -- pprTrace "specCalls: some" (vcat
-- [ text "function" <+> ppr fn
- -- , text "calls:" <+> ppr calls_for_me
- -- , text "subst" <+> ppr (se_subst env) ]) $
+ -- , text "calls:" <+> ppr calls_for_me
+ -- , text "subst" <+> ppr (se_subst env) ]) $
foldlM spec_call ([], [], emptyUDs) calls_for_me
| otherwise -- No calls or RHS doesn't fit our preconceptions
- = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me && not (isClassOpId fn))
+ = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me)
"Missed specialisation opportunity for" (ppr fn $$ trace_doc) $
- -- isClassOpId: class-op Ids never inline; we specialise them
- -- through fireRewriteRules. So don't complain about missed opportunities
-- Note [Specialisation shape]
-- pprTrace "specCalls: none" (ppr fn <+> ppr calls_for_me) $
return ([], [], emptyUDs)
@@ -1664,6 +1663,10 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
fn_unf = realIdUnfolding fn -- Ignore loop-breaker-ness here
inl_prag = idInlinePragma fn
inl_act = inlinePragmaActivation inl_prag
+ is_active = isActive (beginPhase inl_act) :: Activation -> Bool
+ -- is_active: inl_act is the activation we are going to put in the new
+ -- SPEC rule; so we want to see if it is covered by another rule with
+ -- that same activation.
is_local = isLocalId fn
is_dfun = isDFunId fn
dflags = se_dflags env
@@ -1674,16 +1677,6 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
(rhs_bndrs, rhs_body) = collectBindersPushingCo rhs
-- See Note [Account for casts in binding]
- already_covered :: SpecEnv -> [CoreRule] -> [CoreExpr] -> Bool
- already_covered env new_rules args -- Note [Specialisations already covered]
- = isJust (specLookupRule env fn args (beginPhase inl_act)
- (new_rules ++ existing_rules))
- -- Rules: we look both in the new_rules (generated by this invocation
- -- of specCalls), and in existing_rules (passed in to specCalls)
- -- inl_act: is the activation we are going to put in the new SPEC
- -- rule; so we want to see if it is covered by another rule with
- -- that same activation.
-
----------------------------------------------------------
-- Specialise to one particular call pattern
spec_call :: SpecInfo -- Accumulating parameter
@@ -1717,8 +1710,12 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
-- , ppr dx_binds ]) $
-- return ()
+ ; let all_rules = rules_acc ++ existing_rules
+ -- all_rules: we look both in the rules_acc (generated by this invocation
+ -- of specCalls), and in existing_rules (passed in to specCalls)
; if not useful -- No useful specialisation
- || already_covered rhs_env2 rules_acc rule_lhs_args
+ || alreadyCovered rhs_env2 rule_bndrs fn rule_lhs_args is_active all_rules
+ -- See (SC1) in Note [Specialisations already covered]
then return spec_acc
else
do { -- Run the specialiser on the specialised RHS
@@ -1780,7 +1777,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
spec_fn_details
= case idDetails fn of
JoinId join_arity _ -> JoinId (join_arity - join_arity_decr) Nothing
- DFunId is_nt -> DFunId is_nt
+ DFunId unary -> DFunId unary
_ -> VanillaId
; spec_fn <- newSpecIdSM (idName fn) spec_fn_ty spec_fn_details spec_fn_info
@@ -1804,6 +1801,8 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
, ppr spec_fn <+> dcolon <+> ppr spec_fn_ty
, ppr rhs_bndrs, ppr call_args
, ppr spec_rule
+ , text "acc" <+> ppr rules_acc
+ , text "existing" <+> ppr existing_rules
]
; -- pprTrace "spec_call: rule" _rule_trace_doc
@@ -1812,19 +1811,35 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
, spec_uds `thenUDs` uds_acc
) } }
+alreadyCovered :: SpecEnv
+ -> [Var] -> Id -> [CoreExpr] -- LHS of possible new rule
+ -> (Activation -> Bool) -- Which rules are active
+ -> [CoreRule] -> Bool
+-- Note [Specialisations already covered] esp (SC2)
+alreadyCovered env bndrs fn args is_active rules
+ = case specLookupRule env fn args is_active rules of
+ Nothing -> False
+ Just (rule, _)
+ | isAutoRule rule -> -- Discard identical rules
+ -- We know that (fn args) is an instance of RULE
+ -- Check if RULE is an instance of (fn args)
+ ruleLhsIsMoreSpecific in_scope bndrs args rule
+ | otherwise -> True -- User rules dominate
+ where
+ in_scope = substInScopeSet (se_subst env)
+
-- Convenience function for invoking lookupRule from Specialise
-- The SpecEnv's InScopeSet should include all the Vars in the [CoreExpr]
specLookupRule :: SpecEnv -> Id -> [CoreExpr]
- -> CompilerPhase -- Look up rules as if we were in this phase
+ -> (Activation -> Bool) -- Which rules are active
-> [CoreRule] -> Maybe (CoreRule, CoreExpr)
-specLookupRule env fn args phase rules
+specLookupRule env fn args is_active rules
= lookupRule ropts in_scope_env is_active fn args rules
where
dflags = se_dflags env
in_scope = substInScopeSet (se_subst env)
in_scope_env = ISE in_scope (whenActiveUnfoldingFun is_active)
ropts = initRuleOpts dflags
- is_active = isActive phase
{- Note [Specialising DFuns]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2323,21 +2338,24 @@ This plan is implemented in the Rec case of specBindItself.
Note [Specialisations already covered]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We obviously don't want to generate two specialisations for the same
-argument pattern. There are two wrinkles
-
-1. We do the already-covered test in specDefn, not when we generate
-the CallInfo in mkCallUDs. We used to test in the latter place, but
-we now iterate the specialiser somewhat, and the Id at the call site
-might therefore not have all the RULES that we can see in specDefn
-
-2. What about two specialisations where the second is an *instance*
-of the first? If the more specific one shows up first, we'll generate
-specialisations for both. If the *less* specific one shows up first,
-we *don't* currently generate a specialisation for the more specific
-one. (See the call to lookupRule in already_covered.) Reasons:
- (a) lookupRule doesn't say which matches are exact (bad reason)
- (b) if the earlier specialisation is user-provided, it's
- far from clear that we should auto-specialise further
+argument pattern. Wrinkles
+
+(SC1) We do the already-covered test in specDefn, not when we generate
+ the CallInfo in mkCallUDs. We used to test in the latter place, but
+ we now iterate the specialiser somewhat, and the Id at the call site
+ might therefore not have all the RULES that we can see in specDefn
+
+(SC2) What about two specialisations where the second is an *instance*
+ of the first? It's a bit arbitrary, but here's what we do:
+ * If the existing one is user-specified, via a SPECIALISE pragma, we
+ suppress the further specialisation.
+ * If the existing one is auto-generated, we generate a second RULE
+ for the more specialised version.
+ The latter is important because we don't want the accidental order
+ of calls to determine what specialisations we generate.
+
+(SC3) Annoyingly, we /also/ eliminate duplicates in `filterCalls`.
+ See (MP3) in Note [Specialising polymorphic dictionaries]
Note [Auto-specialisation and RULES]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2800,12 +2818,10 @@ non-dictionary bindings too.
Note [Specialising polymorphic dictionaries]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
Note June 2023: This has proved to be quite a tricky optimisation to get right
see (#23469, #23109, #21229, #23445) so it is now guarded by a flag
`-fpolymorphic-specialisation`.
-
Consider
class M a where { foo :: a -> Int }
@@ -2845,11 +2861,26 @@ Here are the moving parts:
function.
(MP3) If we have f :: forall m. Monoid m => blah, and two calls
- (f @(Endo b) (d :: Monoid (Endo b))
- (f @(Endo (c->c)) (d :: Monoid (Endo (c->c)))
+ (f @(Endo b) (d1 :: Monoid (Endo b))
+ (f @(Endo (c->c)) (d2 :: Monoid (Endo (c->c)))
we want to generate a specialisation only for the first. The second
is just a substitution instance of the first, with no greater specialisation.
- Hence the call to `remove_dups` in `filterCalls`.
+ Hence the use of `removeDupCalls` in `filterCalls`.
+
+ You might wonder if `d2` might be more specialised than `d1`; but no.
+ This `removeDupCalls` thing is at the definition site of `f`, and both `d1`
+ and `d2` are in scope. So `d1` is simply more polymorphic than `d2`, but
+ is just as specialised.
+
+ This distinction is sadly lost once we build a RULE, so `alreadyCovered`
+ can't be so clever. E.g if we have an existing RULE
+ forall @a (d1:Ord Int) (d2: Eq a). f @a @Int d1 d2 = ...
+ and a putative new rule
+ forall (d1:Ord Int) (d2: Eq Int). f @Int @Int d1 d2 = ...
+ we /don't/ want the existing rule to subsume the new one.
+
+ So we sadly put up with having two rather different places where we
+ eliminate duplicates: `alreadyCovered` and `removeDupCalls`.
All this arose in #13873, in the unexpected form that a SPECIALISE
pragma made the program slower! The reason was that the specialised
@@ -2947,16 +2978,29 @@ data CallInfoSet = CIS Id (Bag CallInfo)
-- The list of types and dictionaries is guaranteed to
-- match the type of f
-- The Bag may contain duplicate calls (i.e. f @T and another f @T)
- -- These dups are eliminated by already_covered in specCalls
+ -- These dups are eliminated by alreadyCovered in specCalls
data CallInfo
- = CI { ci_key :: [SpecArg] -- All arguments
+ = CI { ci_key :: [SpecArg] -- Arguments of the call
+ -- See Note [The (CI-KEY) invariant]
+
, ci_fvs :: IdSet -- Free Ids of the ci_key call
-- /not/ including the main id itself, of course
-- NB: excluding tyvars:
-- See Note [Specialising polymorphic dictionaries]
}
+{- Note [The (CI-KEY) invariant]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Invariant (CI-KEY):
+ In the `ci_key :: [SpecArg]` field of `CallInfo`,
+ * The list is non-empty
+ * The least element is always a `SpecDict`
+
+In this way the RULE has as few args as possible, which broadens its
+applicability, since rules only fire when saturated.
+-}
+
type DictExpr = CoreExpr
ciSetFilter :: (CallInfo -> Bool) -> CallInfoSet -> CallInfoSet
@@ -3045,10 +3089,7 @@ mkCallUDs' env f args
ci_key :: [SpecArg]
ci_key = dropWhileEndLE (not . isSpecDict) $
zipWith mk_spec_arg args pis
- -- Drop trailing args until we get to a SpecDict
- -- In this way the RULE has as few args as possible,
- -- which broadens its applicability, since rules only
- -- fire when saturated
+ -- Establish (CI-KEY): drop trailing args until we get to a SpecDict
mk_spec_arg :: OutExpr -> PiTyBinder -> SpecArg
mk_spec_arg arg (Named bndr)
@@ -3086,34 +3127,76 @@ site, so we only look through ticks that RULE matching looks through
-}
wantCallsFor :: SpecEnv -> Id -> Bool
-wantCallsFor _env _f = True
- -- We could reduce the size of the UsageDetails by being less eager
- -- about collecting calls for LocalIds: there is no point for
- -- ones that are lambda-bound. We can't decide this by looking at
- -- the (absence of an) unfolding, because unfoldings for local
- -- functions are discarded by cloneBindSM, so no local binder will
- -- have an unfolding at this stage. We'd have to keep a candidate
- -- set of let-binders.
- --
- -- Not many lambda-bound variables have dictionary arguments, so
- -- this would make little difference anyway.
- --
- -- For imported Ids we could check for an unfolding, but we have to
- -- do so anyway in canSpecImport, and it seems better to have it
- -- all in one place. So we simply collect usage info for imported
- -- overloaded functions.
-
-{- Note [Interesting dictionary arguments]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider this
- \a.\d:Eq a. let f = ... in ...(f d)...
-There really is not much point in specialising f wrt the dictionary d,
-because the code for the specialised f is not improved at all, because
-d is lambda-bound. We simply get junk specialisations.
-
-What is "interesting"? Just that it has *some* structure. But what about
-variables? We look in the variable's /unfolding/. And that means
-that we must be careful to ensure that dictionaries have unfoldings,
+-- See Note [wantCallsFor]
+wantCallsFor _env f
+ = case idDetails f of
+ RecSelId {} -> False
+ DataConWorkId {} -> False
+ DataConWrapId {} -> False
+ ClassOpId {} -> False
+ PrimOpId {} -> False
+ FCallId {} -> False
+ TickBoxOpId {} -> False
+ CoVarId {} -> False
+
+ DFunId {} -> True
+ VanillaId {} -> True
+ JoinId {} -> True
+ WorkerLikeId {} -> True
+ RepPolyId {} -> True
+
+{- Note [wantCallsFor]
+~~~~~~~~~~~~~~~~~~~~~~
+`wantCallsFor env f` says whether the Specialiser should collect calls for
+function `f`; other thing being equal, the fewer calls we collect the better. It
+is False for things we can't specialise:
+
+* ClassOpId: never inline and we don't have a defn to specialise; we specialise
+ them through fireRewriteRules.
+* PrimOpId: are never overloaded
+* Data constructors: we never specialise them
+
+We could reduce the size of the UsageDetails by being less eager about
+collecting calls for some LocalIds: there is no point for ones that are
+lambda-bound. We can't decide this by looking at the (absence of an) unfolding,
+because unfoldings for local functions are discarded by cloneBindSM, so no local
+binder will have an unfolding at this stage. We'd have to keep a candidate set
+of let-binders.
+
+Not many lambda-bound variables have dictionary arguments, so this would make
+little difference anyway.
+
+For imported Ids we could check for an unfolding, but we have to do so anyway in
+canSpecImport, and it seems better to have it all in one place. So we simply
+collect usage info for imported overloaded functions.
+
+Note [Interesting dictionary arguments]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In `mkCallUDs` we only use `SpecDict` for dictionaries of which
+`interestingDict` holds. Otherwise we use `UnspecArg`. Two reasons:
+
+* Consider this
+ \a.\d:Eq a. let f = ... in ...(f d)...
+ There really is not much point in specialising f wrt the dictionary d,
+ because the code for the specialised f is not improved at all, because
+ d is lambda-bound. We simply get junk specialisations.
+
+* Consider this (#25703):
+ f :: (Eq a, Show b) => a -> b -> INt
+ goo :: forall x. (Eq x) => x -> blah
+ goo @x (d:Eq x) (arg:x) = ...(f @x @Int d $fShowInt)...
+ If we built a `ci_key` with a (SpecDict d) for `d`, we would end up
+ discarding the call at the `\d`. But if we use `UnspecArg` for that
+ uninteresting `d`, we'll get a `ci_key` of
+ f @x @Int UnspecArg (SpecDict $fShowInt)
+ and /that/ can float out to f's definition and specialise nicely.
+ Hooray. (NB: the call can float only if `-fpolymorphic-specialisation`
+ is on; otherwise it'll be trapped by the `\@x -> ...`.)(
+
+What is "interesting"? (See `interestingDict`.) Just that it has *some*
+structure. But what about variables? We look in the variable's /unfolding/.
+And that means that we must be careful to ensure that dictionaries /have/
+unfoldings,
* cloneBndrSM discards non-Stable unfoldings
* specBind updates the unfolding after specialisation
@@ -3159,7 +3242,7 @@ Now `f` turns into:
meth @a dc ....
When we specialise `f`, at a=Int say, that superclass selection can
-nfire (via rewiteClassOps), but that info (that 'dc' is now a
+fire (via rewiteClassOps), but that info (that 'dc' is now a
particular dictionary `C`, of type `C Int`) must be available to
the call `meth @a dc`, so that we can fire the `meth` class-op, and
thence specialise `wombat`.
@@ -3286,7 +3369,11 @@ dumpUDs :: [CoreBndr] -> UsageDetails -> (UsageDetails, OrdList DictBind)
-- Used at a lambda or case binder; just dump anything mentioning the binder
dumpUDs bndrs uds@(MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })
| null bndrs = (uds, nilOL) -- Common in case alternatives
- | otherwise = -- pprTrace "dumpUDs" (ppr bndrs $$ ppr free_uds $$ ppr dump_dbs) $
+ | otherwise = -- pprTrace "dumpUDs" (vcat
+ -- [ text "bndrs" <+> ppr bndrs
+ -- , text "uds" <+> ppr uds
+ -- , text "free_uds" <+> ppr free_uds
+ -- , text "dump-dbs" <+> ppr dump_dbs ]) $
(free_uds, dump_dbs)
where
free_uds = uds { ud_binds = free_dbs, ud_calls = free_calls }
@@ -3325,20 +3412,17 @@ callsForMe fn uds@MkUD { ud_binds = orig_dbs, ud_calls = orig_calls }
calls_for_me = case lookupDVarEnv orig_calls fn of
Nothing -> []
Just cis -> filterCalls cis orig_dbs
- -- filterCalls: drop calls that (directly or indirectly)
- -- refer to fn. See Note [Avoiding loops (DFuns)]
----------------------
filterCalls :: CallInfoSet -> FloatedDictBinds -> [CallInfo]
--- Remove dominated calls (Note [Specialising polymorphic dictionaries])
--- and loopy DFuns (Note [Avoiding loops (DFuns)])
+-- Remove
+-- (a) dominated calls: (MP3) in Note [Specialising polymorphic dictionaries]
+-- (b) loopy DFuns: Note [Avoiding loops (DFuns)]
filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs })
- | isDFunId fn -- Note [Avoiding loops (DFuns)] applies only to DFuns
- = filter ok_call de_dupd_calls
- | otherwise -- Do not apply it to non-DFuns
- = de_dupd_calls -- See Note [Avoiding loops (non-DFuns)]
+ | isDFunId fn = filter ok_call de_dupd_calls -- Deals with (b)
+ | otherwise = de_dupd_calls
where
- de_dupd_calls = remove_dups call_bag
+ de_dupd_calls = removeDupCalls call_bag -- Deals with (a)
dump_set = foldl' go (unitVarSet fn) dbs
-- This dump-set could also be computed by splitDictBinds
@@ -3352,10 +3436,10 @@ filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs })
ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set
-remove_dups :: Bag CallInfo -> [CallInfo]
+removeDupCalls :: Bag CallInfo -> [CallInfo]
-- Calls involving more generic instances beat more specific ones.
-- See (MP3) in Note [Specialising polymorphic dictionaries]
-remove_dups calls = foldr add [] calls
+removeDupCalls calls = foldr add [] calls
where
add :: CallInfo -> [CallInfo] -> [CallInfo]
add ci [] = [ci]
@@ -3364,12 +3448,20 @@ remove_dups calls = foldr add [] calls
| otherwise = ci2 : add ci1 cis
beats_or_same :: CallInfo -> CallInfo -> Bool
+-- (beats_or_same ci1 ci2) is True if specialising on ci1 subsumes ci2
+-- That is: ci1's types are less specialised than ci2
+-- ci1 specialises on the same dict args as ci2
beats_or_same (CI { ci_key = args1 }) (CI { ci_key = args2 })
= go args1 args2
where
- go [] _ = True
+ go [] [] = True
go (arg1:args1) (arg2:args2) = go_arg arg1 arg2 && go args1 args2
- go (_:_) [] = False
+
+ -- If one or the other runs dry, the other must still have a SpecDict
+ -- because of the (CI-KEY) invariant. So neither subsumes the other;
+ -- one is more specialised (faster code) but the other is more generally
+ -- applicable.
+ go _ _ = False
go_arg (SpecType ty1) (SpecType ty2) = isJust (tcMatchTy ty1 ty2)
go_arg UnspecType UnspecType = True
=====================================
compiler/GHC/Core/Rules.hs
=====================================
@@ -9,7 +9,7 @@
-- The 'CoreRule' datatype itself is declared elsewhere.
module GHC.Core.Rules (
-- ** Looking up rules
- lookupRule, matchExprs,
+ lookupRule, matchExprs, ruleLhsIsMoreSpecific,
-- ** RuleBase, RuleEnv
RuleBase, RuleEnv(..), mkRuleEnv, emptyRuleEnv,
@@ -587,8 +587,8 @@ findBest :: InScopeSet -> (Id, [CoreExpr])
findBest _ _ (rule,ans) [] = (rule,ans)
findBest in_scope target (rule1,ans1) ((rule2,ans2):prs)
- | isMoreSpecific in_scope rule1 rule2 = findBest in_scope target (rule1,ans1) prs
- | isMoreSpecific in_scope rule2 rule1 = findBest in_scope target (rule2,ans2) prs
+ | ruleIsMoreSpecific in_scope rule1 rule2 = findBest in_scope target (rule1,ans1) prs
+ | ruleIsMoreSpecific in_scope rule2 rule1 = findBest in_scope target (rule2,ans2) prs
| debugIsOn = let pp_rule rule
= ifPprDebug (ppr rule)
(doubleQuotes (ftext (ruleName rule)))
@@ -603,15 +603,25 @@ findBest in_scope target (rule1,ans1) ((rule2,ans2):prs)
where
(fn,args) = target
-isMoreSpecific :: InScopeSet -> CoreRule -> CoreRule -> Bool
--- The call (rule1 `isMoreSpecific` rule2)
+ruleIsMoreSpecific :: InScopeSet -> CoreRule -> CoreRule -> Bool
+-- The call (rule1 `ruleIsMoreSpecific` rule2)
-- sees if rule2 can be instantiated to look like rule1
--- See Note [isMoreSpecific]
-isMoreSpecific _ (BuiltinRule {}) _ = False
-isMoreSpecific _ (Rule {}) (BuiltinRule {}) = True
-isMoreSpecific in_scope (Rule { ru_bndrs = bndrs1, ru_args = args1 })
- (Rule { ru_bndrs = bndrs2, ru_args = args2 })
- = isJust (matchExprs in_scope_env bndrs2 args2 args1)
+-- See Note [ruleIsMoreSpecific]
+ruleIsMoreSpecific in_scope rule1 rule2
+ = case rule1 of
+ BuiltinRule {} -> False
+ Rule { ru_bndrs = bndrs1, ru_args = args1 }
+ -> ruleLhsIsMoreSpecific in_scope bndrs1 args1 rule2
+
+ruleLhsIsMoreSpecific :: InScopeSet
+ -> [Var] -> [CoreExpr] -- LHS of a possible new rule
+ -> CoreRule -- An existing rule
+ -> Bool -- New one is more specific
+ruleLhsIsMoreSpecific in_scope bndrs1 args1 rule2
+ = case rule2 of
+ BuiltinRule {} -> True
+ Rule { ru_bndrs = bndrs2, ru_args = args2 }
+ -> isJust (matchExprs in_scope_env bndrs2 args2 args1)
where
full_in_scope = in_scope `extendInScopeSetList` bndrs1
in_scope_env = ISE full_in_scope noUnfoldingFun
@@ -620,9 +630,9 @@ isMoreSpecific in_scope (Rule { ru_bndrs = bndrs1, ru_args = args1 })
noBlackList :: Activation -> Bool
noBlackList _ = False -- Nothing is black listed
-{- Note [isMoreSpecific]
+{- Note [ruleIsMoreSpecific]
~~~~~~~~~~~~~~~~~~~~~~~~
-The call (rule1 `isMoreSpecific` rule2)
+The call (rule1 `ruleIsMoreSpecific` rule2)
sees if rule2 can be instantiated to look like rule1.
Wrinkle:
@@ -825,7 +835,7 @@ bound on the LHS:
The rule looks like
forall (a::*) (d::Eq Char) (x :: Foo a Char).
- f (Foo a Char) d x = True
+ f @(Foo a Char) d x = True
Matching the rule won't bind 'a', and legitimately so. We fudge by
pretending that 'a' is bound to (Any :: *).
=====================================
compiler/GHC/Core/Unify.hs
=====================================
@@ -331,35 +331,57 @@ Wrinkles
`DontBindMe`, the unifier must return `SurelyApart`, not `MaybeApart`. See
`go_fam` in `uVarOrFam`
-(ATF6) You might think that when /matching/ the um_fam_env will always be empty,
- because type-class-instance and type-family-instance heads can't include type
- families. E.g. instance C (F a) where ... -- Illegal
-
- But you'd be wrong: when "improving" type family constraint we may have a
- type family on the LHS of a match. Consider
+(ATF6) When /matching/ can we ever have a type-family application on the LHS, in
+ the template? You might think not, because type-class-instance and
+ type-family-instance heads can't include type families. E.g.
+ instance C (F a) where ... -- Illegal
+
+ But you'd be wrong: even when matching, we can see type families in the LHS template:
+ * In `checkValidClass`, in `check_dm` we check that the default method has the
+ right type, using matching, both ways. And that type may have type-family
+ applications in it. Example in test CoOpt_Singletons.
+
+ * In the specialiser: see the call to `tcMatchTy` in
+ `GHC.Core.Opt.Specialise.beats_or_same`
+
+ * With -fpolymorphic-specialsation, we might get a specialiation rule like
+ RULE forall a (d :: Eq (Maybe (F a))) .
+ f @(Maybe (F a)) d = ...
+ See #25965.
+
+ * A user-written RULE could conceivably have a type-family application
+ in the template. It might not be a good rule, but I don't think we currently
+ check for this.
+
+ In all these cases we are only interested in finding a substitution /for
+ type variables/ that makes the match work. So we simply want to recurse into
+ the arguments of the type family. E.g.
+ Template: forall a. Maybe (F a)
+ Target: Mabybe (F Int)
+ We want to succeed with substitution [a :-> Int]. See (ATF9).
+
+ Conclusion: where we enter via `tcMatchTy`, `tcMatchTys`, `tc_match_tys`,
+ etc, we always end up in `tc_match_tys_x`. There we invoke the unifier
+ but we do not distinguish between `SurelyApart` and `MaybeApart`. So in
+ these cases we can set `um_bind_fam_fun` to `neverBindFam`.
+
+(ATF7) There is one other, very special case of matching where we /do/ want to
+ bind type families in `um_fam_env`, namely in GHC.Tc.Solver.Equality, the call
+ to `tcUnifyTyForInjectivity False` in `improve_injective_wanted_top`.
+ Consider
+ of a match. Consider
type family G6 a = r | r -> a
type instance G6 [a] = [G a]
type instance G6 Bool = Int
- and the Wanted constraint [W] G6 alpha ~ [Int]. We /match/ each type instance
- RHS against [Int]! So we try
- [G a] ~ [Int]
+ and suppose we haev a Wanted constraint
+ [W] G6 alpha ~ [Int]
+. According to Section 5.2 of "Injective type families for Haskell", we /match/
+ the RHS each type instance [Int]. So we try
+ Template: [G a] Target: [Int]
and we want to succeed with MaybeApart, so that we can generate the improvement
- constraint [W] alpha ~ [beta] where beta is fresh.
- See Section 5.2 of "Injective type families for Haskell".
-
- A second place that we match with type-fams on the LHS is in `checkValidClass`.
- In `check_dm` we check that the default method has the right type, using matching,
- both ways. And that type may have type-family applications in it. Example in
- test CoOpt_Singletons.
-
-(ATF7) You might think that (ATF6) is a very special case, and in /other/ uses of
- matching, where we enter via `tc_match_tys_x` we will never see a type-family
- in the template. But actually we do see that case in the specialiser: see
- the call to `tcMatchTy` in `GHC.Core.Opt.Specialise.beats_or_same`
-
- Also: a user-written RULE could conceivably have a type-family application
- in the template. It might not be a good rule, but I don't think we currently
- check for this.
+ constraint
+ [W] alpha ~ [beta]
+ where beta is fresh. We do this by binding [G a :-> Int]
(ATF8) The treatment of type families is governed by
um_bind_fam_fun :: BindFamFun
@@ -399,6 +421,8 @@ Wrinkles
Key point: when decomposing (F tys1 ~ F tys2), we should /also/ extend the
type-family substitution.
+ (ATF11-1) All this cleverness only matters when unifying, not when matching
+
(ATF12) There is a horrid exception for the injectivity check. See (UR1) in
in Note [Specification of unification].
@@ -595,7 +619,7 @@ tc_match_tys_x :: HasDebugCallStack
-> [Type]
-> Maybe Subst
tc_match_tys_x bind_tv match_kis (Subst in_scope id_env tv_env cv_env) tys1 tys2
- = case tc_unify_tys alwaysBindFam -- (ATF7) in Note [Apartness and type families]
+ = case tc_unify_tys neverBindFam -- (ATF7) in Note [Apartness and type families]
bind_tv
False -- Matching, not unifying
False -- Not an injectivity check
@@ -1857,6 +1881,7 @@ uVarOrFam env ty1 ty2 kco
= go_fam_fam tc1 tys1 tys2 kco
-- Now check if we can bind the (F tys) to the RHS
+ -- This can happen even when matching: see (ATF7)
| BindMe <- um_bind_fam_fun env tc1 tys1 rhs
= -- ToDo: do we need an occurs check here?
do { extendFamEnv tc1 tys1 rhs
@@ -1881,11 +1906,6 @@ uVarOrFam env ty1 ty2 kco
-- go_fam_fam: LHS and RHS are both saturated type-family applications,
-- for the same type-family F
go_fam_fam tc tys1 tys2 kco
- | tcEqTyConAppArgs tys1 tys2
- -- Detect (F tys ~ F tys); otherwise we'd build an infinite substitution
- = return ()
-
- | otherwise
-- Decompose (F tys1 ~ F tys2): (ATF9)
-- Use injectivity information of F: (ATF10)
-- But first bind the type-fam if poss: (ATF11)
@@ -1902,13 +1922,19 @@ uVarOrFam env ty1 ty2 kco
(inj_tys1, noninj_tys1) = partitionByList inj tys1
(inj_tys2, noninj_tys2) = partitionByList inj tys2
- bind_fam_if_poss | BindMe <- um_bind_fam_fun env tc tys1 rhs1
- = extendFamEnv tc tys1 rhs1
- | um_unif env
- , BindMe <- um_bind_fam_fun env tc tys2 rhs2
- = extendFamEnv tc tys2 rhs2
- | otherwise
- = return ()
+ bind_fam_if_poss
+ | not (um_unif env) -- Not when matching (ATF11-1)
+ = return ()
+ | tcEqTyConAppArgs tys1 tys2 -- Detect (F tys ~ F tys);
+ = return () -- otherwise we'd build an infinite substitution
+ | BindMe <- um_bind_fam_fun env tc tys1 rhs1
+ = extendFamEnv tc tys1 rhs1
+ | um_unif env
+ , BindMe <- um_bind_fam_fun env tc tys2 rhs2
+ = extendFamEnv tc tys2 rhs2
+ | otherwise
+ = return ()
+
rhs1 = mkTyConApp tc tys2 `mkCastTy` mkSymCo kco
rhs2 = mkTyConApp tc tys1 `mkCastTy` kco
@@ -1993,7 +2019,7 @@ data UMState = UMState
-- in um_foralls; i.e. variables bound by foralls inside the types being unified
-- When /matching/ um_fam_env is usually empty; but not quite always.
- -- See (ATF6) and (ATF7) of Note [Apartness and type families]
+ -- See (ATF7) of Note [Apartness and type families]
newtype UM a
= UM' { unUM :: UMState -> UnifyResultM (UMState, a) }
=====================================
compiler/GHC/Driver/Downsweep.hs
=====================================
@@ -947,6 +947,71 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = do
hostFullWays
in dflags_c
+{- Note [-fno-code mode]
+~~~~~~~~~~~~~~~~~~~~~~~~
+GHC offers the flag -fno-code for the purpose of parsing and typechecking a
+program without generating object files. This is intended to be used by tooling
+and IDEs to provide quick feedback on any parser or type errors as cheaply as
+possible.
+
+When GHC is invoked with -fno-code, no object files or linked output will be
+generated. As many errors and warnings as possible will be generated, as if
+-fno-code had not been passed. The session DynFlags will have
+backend == NoBackend.
+
+-fwrite-interface
+~~~~~~~~~~~~~~~~
+Whether interface files are generated in -fno-code mode is controlled by the
+-fwrite-interface flag. The -fwrite-interface flag is a no-op if -fno-code is
+not also passed. Recompilation avoidance requires interface files, so passing
+-fno-code without -fwrite-interface should be avoided. If -fno-code were
+re-implemented today, there would be no need for -fwrite-interface as it
+would considered always on; this behaviour is as it is for backwards compatibility.
+
+================================================================
+IN SUMMARY: ALWAYS PASS -fno-code AND -fwrite-interface TOGETHER
+================================================================
+
+Template Haskell
+~~~~~~~~~~~~~~~~
+A module using Template Haskell may invoke an imported function from inside a
+splice. This will cause the type-checker to attempt to execute that code, which
+would fail if no object files had been generated. See #8025. To rectify this,
+during the downsweep we patch the DynFlags in the ModSummary of any home module
+that is imported by a module that uses Template Haskell to generate object
+code.
+
+The flavour of the generated code depends on whether `-fprefer-byte-code` is enabled
+or not in the module which needs the code generation. If the module requires byte-code then
+dependencies will generate byte-code, otherwise they will generate object files.
+In the case where some modules require byte-code and some object files, both are
+generated by enabling `-fbyte-code-and-object-code`, the test "fat015" tests these
+configurations.
+
+The object files (and interface files if -fwrite-interface is disabled) produced
+for Template Haskell are written to temporary files.
+
+Note that since Template Haskell can run arbitrary IO actions, -fno-code mode
+is no more secure than running without it.
+
+Potential TODOS:
+~~~~~
+* Remove -fwrite-interface and have interface files always written in -fno-code
+ mode
+* Both .o and .dyn_o files are generated for template haskell, but we only need
+ .dyn_o. Fix it.
+* In make mode, a message like
+ Compiling A (A.hs, /tmp/ghc_123.o)
+ is shown if downsweep enabled object code generation for A. Perhaps we should
+ show "nothing" or "temporary object file" instead. Note that one
+ can currently use -keep-tmp-files and inspect the generated file with the
+ current behaviour.
+* Offer a -no-codedir command line option, and write what were temporary
+ object files there. This would speed up recompilation.
+* Use existing object files (if they are up to date) instead of always
+ generating temporary ones.
+-}
+
-- | Populate the Downsweep cache with the root modules.
mkRootMap
:: [ModuleNodeInfo]
=====================================
compiler/GHC/Driver/Make.hs
=====================================
@@ -1246,70 +1246,6 @@ addSptEntries hsc_env mlinkable =
, spt <- bc_spt_entries bco
]
-{- Note [-fno-code mode]
-~~~~~~~~~~~~~~~~~~~~~~~~
-GHC offers the flag -fno-code for the purpose of parsing and typechecking a
-program without generating object files. This is intended to be used by tooling
-and IDEs to provide quick feedback on any parser or type errors as cheaply as
-possible.
-
-When GHC is invoked with -fno-code no object files or linked output will be
-generated. As many errors and warnings as possible will be generated, as if
--fno-code had not been passed. The session DynFlags will have
-backend == NoBackend.
-
--fwrite-interface
-~~~~~~~~~~~~~~~~
-Whether interface files are generated in -fno-code mode is controlled by the
--fwrite-interface flag. The -fwrite-interface flag is a no-op if -fno-code is
-not also passed. Recompilation avoidance requires interface files, so passing
--fno-code without -fwrite-interface should be avoided. If -fno-code were
-re-implemented today, -fwrite-interface would be discarded and it would be
-considered always on; this behaviour is as it is for backwards compatibility.
-
-================================================================
-IN SUMMARY: ALWAYS PASS -fno-code AND -fwrite-interface TOGETHER
-================================================================
-
-Template Haskell
-~~~~~~~~~~~~~~~~
-A module using template haskell may invoke an imported function from inside a
-splice. This will cause the type-checker to attempt to execute that code, which
-would fail if no object files had been generated. See #8025. To rectify this,
-during the downsweep we patch the DynFlags in the ModSummary of any home module
-that is imported by a module that uses template haskell, to generate object
-code.
-
-The flavour of the generated code depends on whether `-fprefer-byte-code` is enabled
-or not in the module which needs the code generation. If the module requires byte-code then
-dependencies will generate byte-code, otherwise they will generate object files.
-In the case where some modules require byte-code and some object files, both are
-generated by enabling `-fbyte-code-and-object-code`, the test "fat015" tests these
-configurations.
-
-The object files (and interface files if -fwrite-interface is disabled) produced
-for template haskell are written to temporary files.
-
-Note that since template haskell can run arbitrary IO actions, -fno-code mode
-is no more secure than running without it.
-
-Potential TODOS:
-~~~~~
-* Remove -fwrite-interface and have interface files always written in -fno-code
- mode
-* Both .o and .dyn_o files are generated for template haskell, but we only need
- .dyn_o. Fix it.
-* In make mode, a message like
- Compiling A (A.hs, /tmp/ghc_123.o)
- is shown if downsweep enabled object code generation for A. Perhaps we should
- show "nothing" or "temporary object file" instead. Note that one
- can currently use -keep-tmp-files and inspect the generated file with the
- current behaviour.
-* Offer a -no-codedir command line option, and write what were temporary
- object files there. This would speed up recompilation.
-* Use existing object files (if they are up to date) instead of always
- generating temporary ones.
--}
-- Note [When source is considered modified]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Tc/Solver/Equality.hs
=====================================
@@ -3017,6 +3017,7 @@ improve_wanted_top_fun_eqs fam_tc lhs_tys rhs_ty
improve_injective_wanted_top :: FamInstEnvs -> [Bool] -> TyCon -> [TcType] -> Xi -> TcS [TypeEqn]
-- Interact with top-level instance declarations
+-- See Section 5.2 in the Injective Type Families paper
improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty
= concatMapM do_one branches
where
@@ -3035,6 +3036,7 @@ improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty
do_one branch@(CoAxBranch { cab_tvs = branch_tvs, cab_lhs = branch_lhs_tys, cab_rhs = branch_rhs })
| let in_scope1 = in_scope `extendInScopeSetList` branch_tvs
, Just subst <- tcUnifyTyForInjectivity False in_scope1 branch_rhs rhs_ty
+ -- False: matching, not unifying
= do { let inSubst tv = tv `elemVarEnv` getTvSubstEnv subst
unsubstTvs = filterOut inSubst branch_tvs
-- The order of unsubstTvs is important; it must be
=====================================
compiler/GHC/Types/Basic.hs
=====================================
@@ -85,7 +85,7 @@ module GHC.Types.Basic (
CompilerPhase(..), PhaseNum, beginPhase, nextPhase, laterPhase,
Activation(..), isActive, competesWith,
- isNeverActive, isAlwaysActive, activeInFinalPhase,
+ isNeverActive, isAlwaysActive, activeInFinalPhase, activeInInitialPhase,
activateAfterInitial, activateDuringFinal, activeAfter,
RuleMatchInfo(..), isConLike, isFunLike,
=====================================
testsuite/tests/simplCore/should_compile/T25703.hs
=====================================
@@ -0,0 +1,7 @@
+module T25703 where
+
+f :: (Eq a, Show b) => a -> b -> Int
+f x y = f x y
+
+goo :: forall x. (Eq x) => x -> Int
+goo arg = f arg (3::Int)
=====================================
testsuite/tests/simplCore/should_compile/T25703.stderr
=====================================
@@ -0,0 +1,2 @@
+Rule fired: SPEC f @_ @Int (T25703)
+Rule fired: SPEC f @_ @Int (T25703)
=====================================
testsuite/tests/simplCore/should_compile/T25703a.hs
=====================================
@@ -0,0 +1,69 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+
+{-# OPTIONS_GHC -O2 -fspecialise-aggressively #-}
+
+-- This pragma is just here to pretend that the function body of 'foo' is huge
+-- and should never be inlined.
+{-# OPTIONS_GHC -funfolding-use-threshold=-200 #-}
+
+module T25703a where
+
+import Data.Kind
+import Data.Type.Equality
+import Data.Proxy
+import GHC.TypeNats
+
+-- Pretend this is some big dictionary that absolutely must get
+-- specialised away for performance reasons.
+type C :: Nat -> Constraint
+class C i where
+ meth :: Proxy i -> Double
+instance C 0 where
+ meth _ = 0.1
+instance C 1 where
+ meth _ = 1.1
+instance C 2 where
+ meth _ = 2.1
+
+{-# INLINEABLE foo #-}
+foo :: forall a (n :: Nat) (m :: Nat)
+ . ( Eq a, C n, C m )
+ => a -> ( Proxy n, Proxy m ) -> Int -> Double
+-- Pretend this is a big complicated function, too big to inline,
+-- for which we absolutely must specialise away the 'C n', 'C m'
+-- dictionaries for performance reasons.
+foo a b c
+ = if a == a
+ then meth @n Proxy + fromIntegral c
+ else 2 * meth @m Proxy
+
+-- Runtime dispatch to a specialisation of 'foo'
+foo_spec :: forall a (n :: Nat) (m :: Nat)
+ . ( Eq a, KnownNat n, KnownNat m )
+ => a -> ( Proxy n, Proxy m ) -> Int -> Double
+foo_spec a b c
+ | Just Refl <- sameNat @n @0 Proxy Proxy
+ , Just Refl <- sameNat @m @0 Proxy Proxy
+ = foo @a @0 @0 a b c
+ | Just Refl <- sameNat @n @0 Proxy Proxy
+ , Just Refl <- sameNat @m @1 Proxy Proxy
+ = foo @a @0 @1 a b c
+ | Just Refl <- sameNat @n @1 Proxy Proxy
+ , Just Refl <- sameNat @m @1 Proxy Proxy
+ = foo @a @1 @1 a b c
+ | Just Refl <- sameNat @n @0 Proxy Proxy
+ , Just Refl <- sameNat @m @2 Proxy Proxy
+ = foo @a @0 @2 a b c
+ | Just Refl <- sameNat @n @1 Proxy Proxy
+ , Just Refl <- sameNat @m @2 Proxy Proxy
+ = foo @a @1 @2 a b c
+ | Just Refl <- sameNat @n @2 Proxy Proxy
+ , Just Refl <- sameNat @m @2 Proxy Proxy
+ = foo @a @2 @2 a b c
+ | otherwise
+ = error $ unlines
+ [ "f: no specialisation"
+ , "n: " ++ show (natVal @n Proxy)
+ , "m: " ++ show (natVal @m Proxy)
+ ]
=====================================
testsuite/tests/simplCore/should_compile/T25703a.stderr
=====================================
@@ -0,0 +1,6 @@
+Rule fired: SPEC foo @_ @2 @2 (T25703a)
+Rule fired: SPEC foo @_ @1 @2 (T25703a)
+Rule fired: SPEC foo @_ @0 @2 (T25703a)
+Rule fired: SPEC foo @_ @1 @1 (T25703a)
+Rule fired: SPEC foo @_ @0 @1 (T25703a)
+Rule fired: SPEC foo @_ @0 @0 (T25703a)
=====================================
testsuite/tests/simplCore/should_compile/T25965.hs
=====================================
@@ -0,0 +1,18 @@
+{-# LANGUAGE TypeFamilies #-}
+{-# OPTIONS_GHC -O -fpolymorphic-specialisation #-}
+
+module Foo where
+
+type family F a
+
+data T a = T1
+
+instance Eq (T a) where { (==) x y = False }
+
+foo :: Eq a => a -> Bool
+foo x | x==x = True
+ | otherwise = foo x
+
+bar :: forall b. b -> T (F b) -> Bool
+bar y x = foo x
+
=====================================
testsuite/tests/simplCore/should_compile/T25976.hs
=====================================
@@ -0,0 +1,10 @@
+{-# LANGUAGE MagicHash #-}
+
+module T25976 where
+
+import GHC.PrimOps (tagToEnum#)
+
+-- Spoiler - it's all dead code since tagToEnum 3# is undefined
+main = case (tagToEnum# 4# :: Bool) of
+ True -> print "Dead Code"
+ False -> print "Dead Code"
=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -541,3 +541,10 @@ test('T25883', normal, compile_grep_core, [''])
test('T25883b', normal, compile_grep_core, [''])
test('T25883c', normal, compile_grep_core, [''])
test('T25883d', [extra_files(['T25883d_import.hs'])], multimod_compile_filter, ['T25883d', '-O -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques', r'grep -e "y ="'])
+
+test('T25976', [grep_errmsg('Dead Code')], compile, ['-O -ddump-simpl -dsuppress-uniques -dno-typeable-binds'])
+
+test('T25965', normal, compile, ['-O'])
+test('T25703', [grep_errmsg(r'SPEC')], compile, ['-O -fpolymorphic-specialisation -ddump-rule-firings'])
+test('T25703a', [grep_errmsg(r'SPEC')], compile, ['-O -fpolymorphic-specialisation -ddump-rule-firings'])
+
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c97630788324493974f1cb712c7b0…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c97630788324493974f1cb712c7b0…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/T24603] Bisect attempt for ghc js backend
by Serge S. Gulin (@gulin.serge) 22 Apr '25
by Serge S. Gulin (@gulin.serge) 22 Apr '25
22 Apr '25
Serge S. Gulin pushed to branch wip/T24603 at Glasgow Haskell Compiler / GHC
Commits:
e51544af by Serge S. Gulin at 2025-04-22T23:51:48+03:00
Bisect attempt for ghc js backend
submodule
- - - - -
2 changed files:
- libraries/Cabal
- libraries/ghc-internal/jsbits/base.js
Changes:
=====================================
libraries/Cabal
=====================================
@@ -1 +1 @@
-Subproject commit 703582f80f6d7f0c914ef4b885affcfc7b7b6ec8
+Subproject commit 26f1cd7a3a01ad5c5bdfd8a240654e9233bc298a
=====================================
libraries/ghc-internal/jsbits/base.js
=====================================
@@ -1,7 +1,7 @@
//#OPTIONS: CPP
#include "HsBaseConfig.h"
-// #define GHCJS_TRACE_IO 1
+#define GHCJS_TRACE_IO 1
#ifdef GHCJS_TRACE_IO
function h$logIO() { h$log.apply(h$log, arguments); }
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e51544af137e6236ec6632f8d8ea182…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e51544af137e6236ec6632f8d8ea182…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][master] 2 commits: Move -fno-code note into Downsweep module
by Marge Bot (@marge-bot) 22 Apr '25
by Marge Bot (@marge-bot) 22 Apr '25
22 Apr '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
7250fc0c by Matthew Pickering at 2025-04-22T16:24:04-04:00
Move -fno-code note into Downsweep module
This note was left behind when all the code which referred to it was
moved into the GHC.Driver.Downsweep module
- - - - -
d2dc89b4 by Matthew Pickering at 2025-04-22T16:24:04-04:00
Apply editing notes to Note [-fno-code mode] suggested by sheaf
These notes were suggested in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/14241
- - - - -
2 changed files:
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Make.hs
Changes:
=====================================
compiler/GHC/Driver/Downsweep.hs
=====================================
@@ -947,6 +947,71 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = do
hostFullWays
in dflags_c
+{- Note [-fno-code mode]
+~~~~~~~~~~~~~~~~~~~~~~~~
+GHC offers the flag -fno-code for the purpose of parsing and typechecking a
+program without generating object files. This is intended to be used by tooling
+and IDEs to provide quick feedback on any parser or type errors as cheaply as
+possible.
+
+When GHC is invoked with -fno-code, no object files or linked output will be
+generated. As many errors and warnings as possible will be generated, as if
+-fno-code had not been passed. The session DynFlags will have
+backend == NoBackend.
+
+-fwrite-interface
+~~~~~~~~~~~~~~~~
+Whether interface files are generated in -fno-code mode is controlled by the
+-fwrite-interface flag. The -fwrite-interface flag is a no-op if -fno-code is
+not also passed. Recompilation avoidance requires interface files, so passing
+-fno-code without -fwrite-interface should be avoided. If -fno-code were
+re-implemented today, there would be no need for -fwrite-interface as it
+would considered always on; this behaviour is as it is for backwards compatibility.
+
+================================================================
+IN SUMMARY: ALWAYS PASS -fno-code AND -fwrite-interface TOGETHER
+================================================================
+
+Template Haskell
+~~~~~~~~~~~~~~~~
+A module using Template Haskell may invoke an imported function from inside a
+splice. This will cause the type-checker to attempt to execute that code, which
+would fail if no object files had been generated. See #8025. To rectify this,
+during the downsweep we patch the DynFlags in the ModSummary of any home module
+that is imported by a module that uses Template Haskell to generate object
+code.
+
+The flavour of the generated code depends on whether `-fprefer-byte-code` is enabled
+or not in the module which needs the code generation. If the module requires byte-code then
+dependencies will generate byte-code, otherwise they will generate object files.
+In the case where some modules require byte-code and some object files, both are
+generated by enabling `-fbyte-code-and-object-code`, the test "fat015" tests these
+configurations.
+
+The object files (and interface files if -fwrite-interface is disabled) produced
+for Template Haskell are written to temporary files.
+
+Note that since Template Haskell can run arbitrary IO actions, -fno-code mode
+is no more secure than running without it.
+
+Potential TODOS:
+~~~~~
+* Remove -fwrite-interface and have interface files always written in -fno-code
+ mode
+* Both .o and .dyn_o files are generated for template haskell, but we only need
+ .dyn_o. Fix it.
+* In make mode, a message like
+ Compiling A (A.hs, /tmp/ghc_123.o)
+ is shown if downsweep enabled object code generation for A. Perhaps we should
+ show "nothing" or "temporary object file" instead. Note that one
+ can currently use -keep-tmp-files and inspect the generated file with the
+ current behaviour.
+* Offer a -no-codedir command line option, and write what were temporary
+ object files there. This would speed up recompilation.
+* Use existing object files (if they are up to date) instead of always
+ generating temporary ones.
+-}
+
-- | Populate the Downsweep cache with the root modules.
mkRootMap
:: [ModuleNodeInfo]
=====================================
compiler/GHC/Driver/Make.hs
=====================================
@@ -1246,70 +1246,6 @@ addSptEntries hsc_env mlinkable =
, spt <- bc_spt_entries bco
]
-{- Note [-fno-code mode]
-~~~~~~~~~~~~~~~~~~~~~~~~
-GHC offers the flag -fno-code for the purpose of parsing and typechecking a
-program without generating object files. This is intended to be used by tooling
-and IDEs to provide quick feedback on any parser or type errors as cheaply as
-possible.
-
-When GHC is invoked with -fno-code no object files or linked output will be
-generated. As many errors and warnings as possible will be generated, as if
--fno-code had not been passed. The session DynFlags will have
-backend == NoBackend.
-
--fwrite-interface
-~~~~~~~~~~~~~~~~
-Whether interface files are generated in -fno-code mode is controlled by the
--fwrite-interface flag. The -fwrite-interface flag is a no-op if -fno-code is
-not also passed. Recompilation avoidance requires interface files, so passing
--fno-code without -fwrite-interface should be avoided. If -fno-code were
-re-implemented today, -fwrite-interface would be discarded and it would be
-considered always on; this behaviour is as it is for backwards compatibility.
-
-================================================================
-IN SUMMARY: ALWAYS PASS -fno-code AND -fwrite-interface TOGETHER
-================================================================
-
-Template Haskell
-~~~~~~~~~~~~~~~~
-A module using template haskell may invoke an imported function from inside a
-splice. This will cause the type-checker to attempt to execute that code, which
-would fail if no object files had been generated. See #8025. To rectify this,
-during the downsweep we patch the DynFlags in the ModSummary of any home module
-that is imported by a module that uses template haskell, to generate object
-code.
-
-The flavour of the generated code depends on whether `-fprefer-byte-code` is enabled
-or not in the module which needs the code generation. If the module requires byte-code then
-dependencies will generate byte-code, otherwise they will generate object files.
-In the case where some modules require byte-code and some object files, both are
-generated by enabling `-fbyte-code-and-object-code`, the test "fat015" tests these
-configurations.
-
-The object files (and interface files if -fwrite-interface is disabled) produced
-for template haskell are written to temporary files.
-
-Note that since template haskell can run arbitrary IO actions, -fno-code mode
-is no more secure than running without it.
-
-Potential TODOS:
-~~~~~
-* Remove -fwrite-interface and have interface files always written in -fno-code
- mode
-* Both .o and .dyn_o files are generated for template haskell, but we only need
- .dyn_o. Fix it.
-* In make mode, a message like
- Compiling A (A.hs, /tmp/ghc_123.o)
- is shown if downsweep enabled object code generation for A. Perhaps we should
- show "nothing" or "temporary object file" instead. Note that one
- can currently use -keep-tmp-files and inspect the generated file with the
- current behaviour.
-* Offer a -no-codedir command line option, and write what were temporary
- object files there. This would speed up recompilation.
-* Use existing object files (if they are up to date) instead of always
- generating temporary ones.
--}
-- Note [When source is considered modified]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e2042693ace5f7e857315b40750f0…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e2042693ace5f7e857315b40750f0…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][master] Simplifier: Constant fold invald tagToEnum# calls to bottom expr.
by Marge Bot (@marge-bot) 22 Apr '25
by Marge Bot (@marge-bot) 22 Apr '25
22 Apr '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
2e204269 by Andreas Klebinger at 2025-04-22T12:20:41+02:00
Simplifier: Constant fold invald tagToEnum# calls to bottom expr.
When applying tagToEnum# to a out-of-range value it's best to simply
constant fold it to a bottom expression. That potentially allows more
dead code elimination and makes debugging easier.
Fixes #25976
- - - - -
3 changed files:
- compiler/GHC/Core/Opt/ConstantFold.hs
- + testsuite/tests/simplCore/should_compile/T25976.hs
- testsuite/tests/simplCore/should_compile/all.T
Changes:
=====================================
compiler/GHC/Core/Opt/ConstantFold.hs
=====================================
@@ -69,7 +69,6 @@ import GHC.Cmm.MachOp ( FMASign(..) )
import GHC.Cmm.Type ( Width(..) )
import GHC.Data.FastString
-import GHC.Data.Maybe ( orElse )
import GHC.Utils.Outputable
import GHC.Utils.Misc
@@ -1997,6 +1996,14 @@ because we don't expect the user to call tagToEnum# at all; we merely
generate calls in derived instances of Enum. So we compromise: a
rewrite rule rewrites a bad instance of tagToEnum# to an error call,
and emits a warning.
+
+We also do something similar if we can see that the argument of tagToEnum is out
+of bounds, e.g. `tagToEnum# 99# :: Bool`.
+Replacing this with an error expression is better for two reasons:
+* It allow us to eliminate more dead code in cases like `case tagToEnum# 99# :: Bool of ...`
+* Should we actually end up executing the relevant code at runtime the user will
+ see a meaningful error message, instead of a segfault or incorrect result.
+See #25976.
-}
tagToEnumRule :: RuleM CoreExpr
@@ -2008,9 +2015,13 @@ tagToEnumRule = do
Just (tycon, tc_args) | isEnumerationTyCon tycon -> do
let tag = fromInteger i
correct_tag dc = (dataConTagZ dc) == tag
- (dc:rest) <- return $ filter correct_tag (tyConDataCons_maybe tycon `orElse` [])
- massert (null rest)
- return $ mkTyApps (Var (dataConWorkId dc)) tc_args
+ Just dataCons <- pure $ tyConDataCons_maybe tycon
+ case filter correct_tag dataCons of
+ (dc:rest) -> do
+ massert (null rest)
+ pure $ mkTyApps (Var (dataConWorkId dc)) tc_args
+ -- Literal is out of range, e.g. tagToEnum @Bool #4
+ [] -> pure $ mkImpossibleExpr ty "tagToEnum: Argument out of range"
-- See Note [tagToEnum#]
_ -> warnPprTrace True "tagToEnum# on non-enumeration type" (ppr ty) $
=====================================
testsuite/tests/simplCore/should_compile/T25976.hs
=====================================
@@ -0,0 +1,10 @@
+{-# LANGUAGE MagicHash #-}
+
+module T25976 where
+
+import GHC.PrimOps (tagToEnum#)
+
+-- Spoiler - it's all dead code since tagToEnum 3# is undefined
+main = case (tagToEnum# 4# :: Bool) of
+ True -> print "Dead Code"
+ False -> print "Dead Code"
=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -541,3 +541,5 @@ test('T25883', normal, compile_grep_core, [''])
test('T25883b', normal, compile_grep_core, [''])
test('T25883c', normal, compile_grep_core, [''])
test('T25883d', [extra_files(['T25883d_import.hs'])], multimod_compile_filter, ['T25883d', '-O -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques', r'grep -e "y ="'])
+
+test('T25976', [grep_errmsg('Dead Code')], compile, ['-O -ddump-simpl -dsuppress-uniques -dno-typeable-binds'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2e2042693ace5f7e857315b40750f02…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2e2042693ace5f7e857315b40750f02…
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:
384b62be by Simon Peyton Jones at 2025-04-22T20:20:55+01:00
Wibble unsed var
- - - - -
1 changed file:
- compiler/GHC/Core/FVs.hs
Changes:
=====================================
compiler/GHC/Core/FVs.hs
=====================================
@@ -656,7 +656,7 @@ stableUnfoldingFVs unf
| otherwise = Nothing
unfoldingFVs :: Unfolding -> FV
-unfoldingFVs (CoreUnfolding { uf_tmpl = rhs, uf_src = src })
+unfoldingFVs (CoreUnfolding { uf_tmpl = rhs })
= exprFVs rhs
unfoldingFVs (DFunUnfolding { df_bndrs = bndrs, df_args = args })
= FV.delFVs (mkVarSet bndrs) $ exprsFVs args
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/384b62be6287cc270220ad6174898de…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/384b62be6287cc270220ad6174898de…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Peyton Jones pushed to branch wip/T23109a at Glasgow Haskell Compiler / GHC
Commits:
6cd9b8b6 by Simon Peyton Jones at 2025-04-22T17:47:48+01:00
Fix `augment`!
- - - - -
1 changed file:
- libraries/ghc-internal/src/GHC/Internal/Base.hs
Changes:
=====================================
libraries/ghc-internal/src/GHC/Internal/Base.hs
=====================================
@@ -1809,7 +1809,12 @@ build g = g (:) []
augment :: forall a. (forall b. (a->b->b) -> b -> b) -> [a] -> [a]
{-# INLINE [1] augment #-}
-augment g = g (:)
+-- Give it one argument so that it inlines with one arg
+-- But (crucially) the body is a lambda so that `g` is visibly applied
+-- to two args, and hence we know that in a call
+-- augment (\c n. blah)
+-- both c and n are OneShot
+augment g = \xs -> g (:) xs
{-# RULES
"fold/build" forall k z (g::forall b. (a->b->b) -> b -> b) .
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6cd9b8b6ad68d904df353c9ba298d12…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6cd9b8b6ad68d904df353c9ba298d12…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/T20264] 116 commits: hadrian: Make hash_unit_ids into a flavour transformer (and enable for release flavour)
by Simon Peyton Jones (@simonpj) 22 Apr '25
by Simon Peyton Jones (@simonpj) 22 Apr '25
22 Apr '25
Simon Peyton Jones pushed to branch wip/T20264 at Glasgow Haskell Compiler / GHC
Commits:
0e0231e7 by Matthew Pickering at 2025-03-28T18:36:33-04:00
hadrian: Make hash_unit_ids into a flavour transformer (and enable for release flavour)
The primary reason for this change is to make the `release` flavour
enable `--hash-unit-ids` by default without any further user intervention.
* Packagers don't have to be aware of this special flag they should be
using.
* release builds on CI are uniformly testing with hashes (see !13418)
Fixes #25379
- - - - -
9fc54c12 by Rodrigo Mesquita at 2025-03-28T18:37:10-04:00
driver: Move DynFlags consistency fixes off Main
These consistency fixes found in Main.hs are required for the proper
functioning of the compiler and should live together with all remaining
fixes in `makeDynFlagsConsistent`.
This is especially relevant to GHC applications that shouldn't have to
copy/fix themselves possibly inconsistent DynFlags.
Additionally, outputs information when verbosity is high about these
consistency fixes that were previously quiet, adds information to the
Note on consistency of DynFlags, and improves one of the fixes that
incorrectly used `dynNow`.
- - - - -
2fdd0be9 by sheaf at 2025-03-28T18:37:53-04:00
Remove GhcHint from TcRnNotInScope constructor
This is a tiny refactoring which:
- removes GhcHint/ImportError fields from some constructors of
TcRnMessage, using the TcRnMessageDetailed mechanism instead to
report this informaiton:
- removes the GhcHint and ImportErrors fields from TcRnNotInScope
- removes the GhcHint field from TcRnTermNameInType
- ensures that we only include these hints and import errors when the
-fhelpful-errors flag is turned on
Fixes #25874
- - - - -
9e5cd064 by ARATA Mizuki at 2025-03-31T14:53:34-04:00
Better support for SSE3 and SSE4.1
In particular:
* Pass appropriate attributes to LLVM
* Define preprocessor macros for them
- - - - -
c2c7dd51 by ARATA Mizuki at 2025-03-31T14:53:34-04:00
x86: Add support for SSSE3
This commit adds the `-mssse3` flag, which controls usage of SSSE3 instructions in x86 code generation.
- - - - -
d7c62580 by ARATA Mizuki at 2025-03-31T14:53:34-04:00
x86 NCG SIMD: Implement 128-bit integer vector arithmetics
This commit implements the following operations on integer vectors:
* negateIntNXM#
* plus{Int,Word}NXM#
* minus{Int,Word}NXM#
* times{Int,Word}NXM#
* quot{Int,Word}NXM#
* rem{Int,Word}NXM#
* min{Int,Word}NXM#
* max{Int,Word}NXM#
where (N,M) is one of (8,16), (16,8), (32,4), or (64,2).
Closes #25643
- - - - -
f5ea4e7e by ARATA Mizuki at 2025-03-31T14:53:34-04:00
x86 NCG SIMD: Implement 128-bit integer vector shuffle
This commit implements the following operations:
* shuffle{Int,Word}8X16#
* shuffle{Int,Word}16X8#
* shuffle{Int,Word}32X4#
* shuffle{Int,Word}64X2#
See #25643
- - - - -
5eeb6645 by Simon Peyton Jones at 2025-03-31T14:54:16-04:00
Re-jig the way that the Simplifier tries RULES
As #25170 showed, if a new RULE appears, it could change the simplifier's
behaviour a bit, even if it never fires; and that messes up deterministic
compilation. (This was particularly nasty if the rule wasn't even transitively
below the module being compiled.)
This MR rejigs the use of `tryRules` so that behaviour does not change
when a new, unrelated RULE is added. It's described in
* Note [When to apply rewrite rules]
* Note [tryRules: plan (BEFORE)]
* Note [tryRules: plan (AFTER)]
The main change is in the refactored version of
* simplOutId
* rebuildCall
The little state machine that was embedded in ArgInfo is gone.
As I wandered around the Simplifier I also found opportunities for
some loosely-related refactoring:
* In several places, the /substitution/ in the SimpleEnv is empty;
all we care about is the in-scope set and the flags. So
- I made a synonym `SimplEnvIS` that embodies that invariant,
- used it in a number of type signatures (notably `rebuild`)
- added some assertion checks (via `checkSimlEnvIS`)
* I moved the hanlding of `runRW` out of `rebuildCall` (where we
would have to test repeatedly) and into the new `simplOutId`, which
fires up `rebuildCall`. Now it is only tested once.
-------------------------
Metric Decrease:
T9020
T9961
-------------------------
- - - - -
f534474a by sheaf at 2025-03-31T14:54:59-04:00
Add comment: no qualified Names in the LocalRdrEnv
This commit adds a reference to section 5.5.1 of the Haskell 2010 report,
to explain that qualified names can't occur in the LocalRdrEnv.
Fixes #25875
- - - - -
d5ea80c6 by Patrick at 2025-03-31T14:55:42-04:00
Fix deadlock/loop in interface rehydration (#25858)
In #25858, GHC hangs when processing modules with class defaults due to a
circular dependency in the interface rehydration process. The deadlock/loop
occurred when eager class defaults rehydration accessed not-yet-complete module details.
To fix the immediate deadlock/loop.
`tcIfaceDefaults` is refactored, we use the class name directly from the iface
and use `forM` for lazy loading the class, which algins with the handling of other fields
of ModDetails. This laziness ensure rehydration waits for HomePackageTable (HPT) to
be updated and prevent premature evaluation of ModDetails inside `fixIO``.
As suggested by Matthew, class defaults importing is also refactored
to align with the compiler's established interface loading conventions.
- add class defaults field to ExternalPackageState (EPS).
- rehydrate and store class defaults in EPS at `loadInterface`.
- Instead of using `tcIfaceDefaults` in `tcRnImports`, we add and use
`tcGetClsDefaults` to read defaults directly from HPT or EPS
when importing modules.
Tests:
- T25858, T25858v1-2: Test class hydration in defaults
- T25858v3-4: Test type list hydration in defaults
New Note [Tricky rehydrating IfaceDefaults loop] is added.
Thanks to @sheaf (Sam), @mpickering (Matthew), and @simonpj (Simon) for their
valuable input and analysis.
Fixes #25858.
- - - - -
2d419d8d by Matthew Pickering at 2025-04-02T16:12:36-04:00
Use unsafePerformIO in definition of computeFingerprint
computeFingerprint is morally a pure function, which is implemented by
mutating a buffer. Using unsafePerformIO inside the definition allows it
to be used in pure contexts, fixing one place where an ad-hoc call to
unsafePerformIO is already needed.
- - - - -
ccdf979b by Matthew Pickering at 2025-04-02T16:12:37-04:00
driver: Fix recompilation checking for exported defaults
Since the exported defaults are not associated with any identifier from
the module, they are just added to the export hash rather than
the fine-grained recompilation logic.
Fixes #25855
- - - - -
c5bf9892 by Matthew Pickering at 2025-04-02T16:12:37-04:00
driver: Fix recompilation checking for COMPLETE pragmas
A {-# COMPLETE P, Q #-} pragma is associated with the pattern synonyms P
and Q during recompilation checking. Therefore, the existence of a
pattern synonym becomes part of the ABI hash for P and Q.
Then if a module uses these pattern synonyms and a complete pragma
changes, it will trigger recompilation in that module.
Fixes #25854
- - - - -
d0fd9370 by sheaf at 2025-04-02T16:14:05-04:00
Handle named default exports separately
This commit changes the way we check for duplicate exports of named
default declarations. They are now treated entirely separately from
other exports, because in an export list of the form
module M ( default Cls, Cls )
the default declaration does not export the class 'Cls', but only its
default declarations.
Also fixes a bug in Backpack where named default exports were getting
dropped entirely. No test for that.
Fixes #25857
- - - - -
62d04494 by Cheng Shao at 2025-04-03T05:56:17-04:00
ci: add x86_64-linux-ubuntu24_04 nightly/release jobs
- - - - -
327952e4 by Cheng Shao at 2025-04-03T05:56:17-04:00
rel-eng: add ubuntu24_04 bindists to ghcup metadata and fetch gitlab scripts
- - - - -
aa1e3b8b by sheaf at 2025-04-03T05:57:24-04:00
GHC settings: always unescape escaped spaces
In #25204, it was noted that GHC didn't properly deal with having
spaces in its executable path, as it would compute an invalid path
for the C compiler.
The original fix in 31bf85ee49fe2ca0b17eaee0774e395f017a9373 used a
trick: escape spaces before splitting up flags into a list. This fixed
the behaviour with extra flags (e.g. -I), but forgot to also unescape
for non-flags, e.g. for an executable path (such as the C compiler).
This commit rectifies this oversight by consistently unescaping the
spaces that were introduced in order to split up argument lists.
Fixes #25204
- - - - -
34a9b55d by lazyLambda at 2025-04-04T06:22:26-04:00
Driver: make MonadComprehensions imply ParallelListComp
This commit changes GHC.Driver.Flags.impliedXFlags to make the
MonadComprehensions extension enable the ParallelListComp extension.
Fixes #25645
- - - - -
d99eb7cd by sheaf at 2025-04-04T06:23:28-04:00
NamedDefaults: handle poly-kinded unary classes
With this commit, we accept named default declarations for poly-kinded
classes such as Typeable, e.g.
default Typeable (Char)
This used to fail because we assumed the kind of the class was monomorphic,
e.g.
Type -> Constraint
(Type -> Type) -> Constraint
Nat -> Constraint
Now, we can handle a simple polymorphic class such as
Typeable :: forall k. k -> Constraint
Note that we keep the restriction that the class must only have
one visible argument.
This is all explained in the new Note [Instance check for default declarations]
in GHC.Tc.Gen.Default.
Fixes #25882
- - - - -
4cbc90de by sheaf at 2025-04-04T11:39:05-04:00
LLVM: add type annotations to AtomicFetch_cmm.cmm
- - - - -
e2237305 by sheaf at 2025-04-04T11:39:05-04:00
Cmm lint: lint argument types of CallishMachOps
This commit adds a new check to Cmm lint to ensure that the argument
types to a CallishMachOp are correct. The lack of this check was
detected in the AtomicFetch test: the literals being passed as the
second arguments to operations such as 'fetch_add', 'fetch_and'... were
of the wrong width, which tripped up the LLVM backend.
- - - - -
9363e547 by Cheng Shao at 2025-04-04T11:39:50-04:00
ci: add ghc-wasm-meta integration testing jobs
This patch adds ghc-wasm-meta integration testing jobs to the CI
pipeline, which are only triggered via the `test-wasm` MR label or
manually when the `wasm` label is set.
These jobs will fetch the wasm bindists and test them against a
variety of downstream projects, similarly to head.hackage jobs for
native bindists, offering a convenient way to catch potential
downstream breakage while refactoring the wasm backend.
- - - - -
27029e60 by Adam Gundry at 2025-04-04T11:40:36-04:00
base: Minor fixes to GHC.Records haddocks
This corrects a stale reference to OverloadedRecordFields (which should
be OverloadedRecordDot), fixes the haddock link syntax and adds an
@since pragma.
- - - - -
f827c4c6 by Rodrigo Mesquita at 2025-04-07T11:22:10-04:00
Parametrize default logger action with Handles
Introduce `defaultLogActionWithHandles` to allow GHC applications to use
GHC's formatting but using custom handles.
`defaultLogAction` is then trivially reimplemented as
```
defaultLogActionWithHandles stdout stderr
```
- - - - -
5dade5fd by sheaf at 2025-04-07T11:23:02-04:00
Finer-grained recompilation checking for exports
This commit refines the recompilation checking logic, to avoid
recompiling modules with an explicit import list when the modules they
import start exporting new items.
More specifically, when:
1. module N imports module M,
2. M is changed, but in a way that:
a. preserves the exports that N imports
b. does not introduce anything that forces recompilation downstream,
such as orphan instances
then we no longer require recompilation of N.
Note that there is more to (2a) as initially meets the eye:
- if N includes a whole module or "import hiding" import of M,
then we require that the export list of M does not change,
- if N only includes explicit imports, we check that the imported
items don't change, e.g.
- if we have @import M(T(K, f), g)@, we must check that N
continues to export all these identifiers, with the same Avail
structure (i.e. we should error if N stops bundling K or f with
T)
- if we have @import M(T(..))@, we must check that the children
of T have not changed
See Note [When to recompile when export lists change?] in GHC.Iface.Recomp.
This is all tested in the new tests RecompExports{1,2,3,4,5}
Fixes #25881
- - - - -
f32d6c2b by Andreas Klebinger at 2025-04-07T22:01:25-04:00
NCG: AArch64 - Add -finter-module-far-jumps.
When enabled the arm backend will assume jumps to targets outside of the
current module are further than 128MB away.
This will allow for code to work if:
* The current module results in less than 128MB of code.
* The whole program is loaded within a 4GB memory region.
We have seen a few reports of broken linkers (#24648) where this flag might allow
a program to compile/run successfully at a very small performance cost.
-------------------------
Metric Increase:
T783
-------------------------
- - - - -
553c280b by Andreas Klebinger at 2025-04-07T22:02:11-04:00
Revert "rts: fix small argument passing on big-endian arch (fix #23387)"
Based on analysis documented in #25791 this doesn't fully fix the big
while introducing new bugs on little endian architectures.
A more complete fix will have to be implemented to fix #23387
This reverts commit 4f02d3c1a7b707e609bb3aea1dc6324fa19a5c39.
- - - - -
b0dc6599 by Andreas Klebinger at 2025-04-07T22:02:11-04:00
Interpreter: Fixes to handling of subword value reads/writes.
Load subword values as full words from the stack truncating/expanding as
neccesary when dealing with subwords. This way byte order is implicitly
correct.
This commit also fixes the order in which we are pushing literals onto
the stack on big endian archs.
Last but not least we enable a test for ghci which actually tests these
subword operations.
- - - - -
ed38c09b by Cheng Shao at 2025-04-07T22:02:53-04:00
testsuite: don't test WasmControlFlow stdout
This patch solves a potential test flakiness in `WasmControlFlow` by
removing `WasmControlFlow.stdout` which is not so portable/stable as
it seems. See added `Note [WasmControlFlow]` for more detailed
explanation.
- - - - -
f807c590 by Rodrigo Mesquita at 2025-04-08T17:41:51-04:00
debugger: Add docs to obtainTermFromId
- - - - -
5dba052d by Rodrigo Mesquita at 2025-04-08T17:41:51-04:00
Move logic to find and set Breakpoint to GHC
Breakpoints are uniquely identified by a module and an index unique
within that module. `ModBreaks` of a Module contains arrays mapping from
this unique breakpoint index to information about each breakpoint. For
instance, `modBreaks_locs` stores the `SrcSpan` for each breakpoint.
To find a breakpoint using the line number you need to go through all
breakpoints in the array for a given module and look at the line and
column stored in the `SrcSpan`s. Similarly for columns and finding
breakpoints by name.
This logic previously lived within the `GHCi` application sources,
however, it is common to any GHC applications wanting to set
breakpoints, like the upcoming `ghc-debugger`.
This commit moves this logic for finding and setting breakpoints to the
GHC library so it can be used by both `ghci` and `ghc-debugger`.
- - - - -
bc0b9f73 by Rodrigo Mesquita at 2025-04-08T17:41:51-04:00
Refactor and move logic for identifier breakpoints
Breakpoints can be set on functions using syntax of the form
`[Module.]function`. The parsing, resolution (e.g. inferring implicit
module), and validation of this syntax for referring to functions was
tightly coupled with its GHCi use.
This commit extracts the general purpose bits of resolving this syntax
into `GHC.Runtime.Debugger.Breakpoints` so it can be further used by
other GHC applications and to improve the code structure of GHCi.
Moreover, a few utilities that do splitting and joining of identifiers
as strings were moved to `GHC.Runtime.Eval.Utils`, which also can be
used in the future to clean up `GHC.Runtime.Eval` a bit.
- - - - -
4f728d21 by Rodrigo Mesquita at 2025-04-08T17:41:51-04:00
debugger: derive Ord for BreakpointIds
- - - - -
5528771c by Rodrigo Mesquita at 2025-04-08T17:41:51-04:00
debugger: Move context utils from GHCi to GHC
Moves `enclosingTickSpan`, `getCurrentBreakSpan`, and
`getCurrentBreakModule`, general utilities on the internal debugger
state, into the GHC library.
- - - - -
4871f543 by sheaf at 2025-04-08T17:42:43-04:00
Implicit quantification in type synonyms: add test
This adds a test for ticket #24090, which involves implicit
quantification in type synonyms.
The underlying issue was fixed in 0d4ee209dfe53e5074d786487f531dabc36d561c.
- - - - -
48917d3c by sheaf at 2025-04-08T17:42:44-04:00
Turn on implicit-rhs-quantification by default
This flag was added to GHC 9.8, and will be removed in a future GHC
release. In preparation, this commit adds it to the default warning
flags.
- - - - -
629be068 by Rodrigo Mesquita at 2025-04-08T17:43:26-04:00
debugger: Add breakpoints to every Stmt
While single-stepping through a Haskell program we stop at every
breakpoint. However, we don't introduce breakpoints at every single
expression (e.g. single variables) because they would be too many and
uninteresting.
That said, in a do-block, it is expected that stepping over would break
at every line, even if it isn't particularly interesting (e.g. a single
arg like getArgs). Moreover, let-statements in do-blocks, despite only
being evaluated once needed, lead to surprising jumps while stepping
through because some have outermost (outside the let) breakpoints
while others don't.
This commit makes every statement in a do-block have a breakpoint.
This leads to predictable stepping through in a do-block.
Duplicate breakpoints in the same location are avoided using the
existing blacklist mechanism, which was missing a check in one relevant place.
Fixes #25932
- - - - -
99a3affd by Matthew Pickering at 2025-04-08T17:44:08-04:00
driver: refactor: Split downsweep and MakeAction into separate modules.
This will facilitate using the downsweep functions in other parts of
the compiler than just --make mode.
Also, the GHC.Driver.Make module was huge. Now it's still huge but
slightly smaller!
- - - - -
ecfec4df by sheaf at 2025-04-09T14:13:12-04:00
Store user-written qualification in the GhcRn AST
This commit ensures we store the original user-written module
qualification in the renamed AST. This allows us to take into account
the user-written qualification in error messages.
Fixes #25877
- - - - -
97c884e2 by sheaf at 2025-04-09T14:13:12-04:00
TcRnIllegalTermLevelUse: simpler error when possible
This commit makes GHC emit a simple error message in the case of an
illegal term-level use of a data constructor: we will try to report an
out-of-scope error instead of a "Illegal term level use" error, as the
latter might be a bit overwhelming for newcomers.
We do this when we have a data constructor import suggestion to provide
to the user. For example:
module M where { data A = A }
module N where
import M(A)
x = Bool
-- Illegal term-level use of Bool
y = A
-- Data constructor not in scope: A.
-- Perhaps add 'A' to the import list of 'M'.
This commit also revamps the "similar names" suggestion mechanism,
and in particular its treatment of name spaces. Now, which name spaces
we suggest is based solely on what we are looking for, and no longer on
the NameSpace of the Name we have. This is because, for illegal term-level
use errors, it doesn't make much sense to change the suggestions based
on the fact that we resolved to e.g. a type constructor/class; what
matters is what we were expecting to see in this position.
See GHC.Rename.Unbound.{suggestionIsRelevant,relevantNameSpace} as well
as the new constructors to GHC.Tc.Errors.Types.WhatLooking.
Fixes #23982
- - - - -
bff645ab by Rodrigo Mesquita at 2025-04-09T14:13:57-04:00
driver: Split Session functions out of Main
This commit moves out functions that help in creating and validating a
GHC multi session from Main into the ghc library where they can be used by
other GHC applications.
Moreover, `Mode` processing and `checkOptions` linting were moved to
separate modules within the ghc-bin executable package.
In particular:
- Move `Mode` types and functions (referring to the mode GHC is running
on) to `ghc-bin:GHC.Driver.Session.Mode`
- Move `checkOptions` and aux functions, which validates GHC DynFlags
based on the mode, to `ghc-bin:GHC.Driver.Session.Lint`
- Moves `initMulti`, `initMake`, and aux functions, which initializes a make/multi-unit
session, into `ghc:GHC.Driver.Session.Units`.
- - - - -
501b015e by Rodrigo Mesquita at 2025-04-09T14:13:57-04:00
docs: Improve haddock of ExecComplete
- - - - -
dea98988 by Andreas Klebinger at 2025-04-09T19:23:57-04:00
Avoid oversaturing constructor workers.
Constructor applications always need to take the exact number of
arguments. If we can't ensure that instead apply the constructor worker
like a regular function.
Fixes #23865
- - - - -
f1acdd2c by sheaf at 2025-04-09T19:25:41-04:00
NamedDefaults: require the class to be standard
We now only default type variables if they only appear in constraints
of the form `C v`, where `C` is either a standard class or a class with
an in-scope default declaration.
This rectifies an oversight in the original implementation of the
NamedDefault extensions that was remarked in #25775; that implementation
allowed type variables to appear in unary constraints which had arbitrary
classes at the head.
See the rewritten Note [How type-class constraints are defaulted] for
details of the implementation.
Fixes #25775
Fixes #25778
- - - - -
5712e0d6 by Vladislav Zavialov at 2025-04-10T05:17:38+00:00
Retry type/class declarations and instances (#12088)
Retry type/class declarations and instances to account for non-lexical
dependencies arising from type/data family instances.
This patch improves the kind checker's ability to use type instances in kind
checking of other declarations in the same module.
* Key change: tcTyAndClassDecls now does multiple passes over the TyClGroups,
as long as it is able to make progress.
See the new Note [Retrying TyClGroups] in GHC.Tc.TyCl
* Supporting change: FVs of a TyClGroup are now recorded in its extension
field, namely XCTyClGroup.
See the new Note [Prepare TyClGroup FVs] in GHC.Rename.Module
* Instances are no longer inserted at the earliest positions where their FVs
are bound. This is a simplification.
See the new Note [Put instances at the end] in GHC.Rename.Module
* Automatic unpacking is now more predictable, but fewer fields get unpacked
by default. Use explicit {-# UNPACK #-} pragmas instead.
See the new Note [Flaky -funbox-strict-fields with type/data families]
For the wide range of newly accepted programs, consult the added test cases.
Fixed tickets:
#12088, #12239, #14668, #15561, #16410, #16448, #16693,
#19611, #20875, #21172, #22257, #25238, #25834
Metric Decrease:
T8095
- - - - -
bc73a78d by sheaf at 2025-04-10T15:07:24-04:00
checkFamApp: don't be so eager to cycle break
As remarked in #25933, a pure refactoring of checkTyEqRhs in
ab77fc8c7adebd610aa0bd99d653f9a6cc78a374 inadvertently changed behaviour,
as it caused GHC to introduce cycle-breaker variables in some
unnecessary circumstances.
This commit refactors 'GHC.Tc.Utils.Unify.checkFamApp' in a way that
should restore the old behaviour, so that, when possible, we first
recur into the arguments and only introduce a cycle breaker if this
recursion fails (e.g. due to an occurs check failure).
Fixes #25933
- - - - -
3acd8182 by Andreas Klebinger at 2025-04-10T22:32:12-04:00
Expand docs for RTS flag `-M`.
The behaviour of how/when exceptions are raised was not really covered
in the docs.
- - - - -
026c1a39 by Adam Sandberg Ericsson at 2025-04-10T22:32:56-04:00
add cases for more SchedulerStatus codes in rts_checkSchedStatus
- - - - -
5977c6a1 by sheaf at 2025-04-10T22:33:46-04:00
Squash warnings in GHC.Runtime.Heap.Inspect
There were incomplete record selector warnings in GHC.Runtime.Heap.Inspect
due to the use of the partial 'dataArgs' record selector. This is fixed
by passing the fields to the 'extractSubTerms' function directly,
rather than passing a value of the parent data type.
- - - - -
6a3e38f5 by Andreas Klebinger at 2025-04-11T15:13:53-04:00
hadrian: Make ghcWithInterpreter the universal source of truth about availability of the interpreter
We were doing some ad-hoc checks in different places in hadrian to
determine whether we supported the interprter or not. Now this check if
confined to one function, `ghcWithInterpreter`, and all the places which
use this information consult `ghcWithInterpreter` to determine what to
do.
Fixes #25533.
- - - - -
207de6f1 by Matthew Pickering at 2025-04-11T15:14:37-04:00
testsuite: Fix running TH tests with profiled dynamic compiler
Previously, I had failed to update the ghc_th_way_flags logic for the
profiled dynamic compiler.
In addition to this `ghc_dynamic` was incorrectly set for profiled
dynamic compiler.
I also updated MultiLayerModulesTH_OneShot test to work for any compiler
linkage rather than just dynamic.
Fixes #25947
-------------------------
Metric Decrease:
MultiLayerModulesTH_Make
-------------------------
- - - - -
5455f2b9 by Matthew Pickering at 2025-04-12T08:31:36-04:00
driver: Add support for "Fixed" nodes in the ModuleGraph
A fixed node in the module graph is one which we presume is already
built. It's therefore up to the user to make sure that the interface
file and any relevant artifacts are available for a fixed node.
Fixed/Compile nodes are represented by the ModuleNodeInfo type, which
abstracts the common parts of Fixed/Compile nodes with accessor
functions of type `ModuleNodeInfo -> ...`.
Fixed nodes can only depend on other fixed nodes. This invariant can be
checked by the function `checkModuleGraph` or `mkModuleGraphChecked`.
--make mode is modified to work with fixed mode. In order to "compile" a
fixed node, the artifacts are just loaded into the HomePackageTable.
Currently nothing in the compiler will produce Fixed nodes but this is
tested with the FixedNodes GHC API test.
In subsequent patches we are going to remove the ExternalModuleGraph and
use Fixed nodes for modules in the module graph in oneshot mode.
Fixes #25920
- - - - -
ad64d5c2 by Cheng Shao at 2025-04-12T08:32:19-04:00
ci: remove manual case of ghc-wasm-meta downstream testing jobs
This patch removes the manual case of ghc-wasm-meta downstream testing
jobs; now the only way of including them in the pipeline and running
them is via the test-wasm label.
The reason of the removal is it proves to be problematic for MRs with
only the wasm label; the wasm job would succeed, then the pipeline
status would be waiting for manual action instead of succeeding. There
needs to be separate jobs for the label-triggered and manual-triggered
cases, but I don't think it's worth that extra complexity, the
label-triggered case is already sufficient.
- - - - -
b34890c7 by Vladislav Zavialov at 2025-04-13T01:08:21+03:00
Fix EmptyCase panic in tcMatches (#25960)
Due to faulty reasoning in Note [Pattern types for EmptyCase],
tcMatches was too keen to panic.
* Old (incorrect) assumption: pat_tys is a singleton list.
This does not hold when \case{} is checked against a function type
preceded by invisible forall. See the new T25960 test case.
* New (hopefully correct) assumption: vis_pat_tys is a singleton list.
This should follow from:
checkArgCounts :: MatchGroup GhcRn ... -> TcM VisArity
checkArgCounts (MG { mg_alts = L _ [] })
= return 1
...
- - - - -
84806ebc by Vladislav Zavialov at 2025-04-13T11:40:08-04:00
Remove unused type: TokenLocation
- - - - -
05eb50df by Vladislav Zavialov at 2025-04-13T19:16:38-04:00
Register EpToken in Parser.PostProcess.Haddock (#22558)
This change allows us to reject more badly placed Haddock comments.
Examples:
module
-- | Bad comment for the module
T17544_kw where
data Foo -- | Bad comment for MkFoo
where MkFoo :: Foo
newtype Bar -- | Bad comment for MkBar
where MkBar :: () -> Bar
class Cls a
-- | Bad comment for clsmethod
where
clsmethod :: a
- - - - -
01944e5e by Vladislav Zavialov at 2025-04-13T19:17:21-04:00
Reject puns in T2T (#24153)
This patch implements pun detection in T2T. Consider:
x = 42
f, g :: forall a -> ...
f (type x) = g x
In accordance with the specification, the `g x` function call is renamed
as a term, so `x` refers to the top-level binding `x = 42`, not to the
type variable binding `type x` as one might expect.
This is somewhat counterintuitive because `g` expects a type argument.
Forbidding puns in T2T allows us to produce a helpful error message:
Test.hs:5:16: error: [GHC-09591]
Illegal punned variable occurrence in a required type argument.
The name ‘x’ could refer to:
‘x’ defined at Test.hs:3:1
‘x’ bound at Test.hs:5:9
This commit is a follow up to 0dfb1fa799af254c8a1e1045fc3996af2d57a613
where checking for puns was left as future work.
- - - - -
cc580552 by Vladislav Zavialov at 2025-04-13T19:18:02-04:00
Additional test cases for #12088, #13790
Extract more test cases from ticket discussions, including multi-module
examples. Follow up to 5712e0d646f611dfbfedfd7ef6dff3a18c016edb
- - - - -
d47bf776 by Matthew Pickering at 2025-04-14T16:44:41+01:00
driver: Use ModuleGraph for oneshot and --make mode
This patch uses the `hsc_mod_graph` field for both oneshot and --make
mode. Therefore, if part of the compiler requires usage of the module
graph, you do so in a uniform way for the two different modes.
The `ModuleGraph` describes the relationship between the modules in the
home package and units in external packages. The `ModuleGraph` can be
queried when information about the transitive closure of a package is
needed. For example, the primary use of the ModuleGraph from within the
compiler is in the loader, which needs to know the transitive closure of
a module so it can load all the relevant objects for evaluation.
In --make mode, downsweep computes the ModuleGraph before any
compilation starts.
In oneshot mode, a thunk is created at the start of compilation, which
when forced will compute the module graph beneath the current module.
The thunk is only forced at the moment when the user uses Template
Haskell.
Finally, there are some situations where we need to discover what
dependencies to load but haven't loaded a module graph at all. In this
case, there is a fallback which computes the transitive closure on the
fly and doesn't cache the result. Presumably if you are going to call
getLinkDeps a lot, you would compute the right ModuleGraph before you
started.
Importantly, this removes the ExternalModuleGraph abstraction. This was quite
awkward to work with since it stored information about the home package
inside the EPS.
This patch will also be very useful when implementing explicit level
imports, which requires more significant use of the module graph in
order to determine which level instances are available at.
Towards #25795
-------------------------
Metric Decrease:
MultiLayerModulesTH_Make
MultiLayerModulesTH_OneShot
-------------------------
- - - - -
395e0ad1 by sheaf at 2025-04-16T12:33:26-04:00
base: remove .Internal modules (e.g. GHC.TypeLits)
This commit removes the following internal modules from base,
as per CLC proposal 217:
- GHC.TypeNats.Internal
- GHC.TypeLits.Internal
- GHC.ExecutionStack.Internal
Fixes #25007
- - - - -
e0f3ff11 by Patrick at 2025-04-17T04:31:12-04:00
Refactor Handling of Multiple Default Declarations
Fixes: #25912, #25914, #25934
Previously, GHC discarded all loaded defaults (tcg_default) when local
defaults were encountered during typechecking. According to the
exportable-named-default proposal (sections 2.4.2 and 2.4.3), local
defaults should be merged into tcg_default, retaining any defaults
already present while overriding where necessary.
Key Changes:
* Introduce DefaultProvenance to track the origin of default declarations
(local, imported, or built-in), replacing the original cd_module
in ClassDefaults with cd_provenance :: DefaultProvenance.
* Rename tcDefaults to tcDefaultDecls, limiting its responsibility to only
converting renamed class defaults into ClassDefaults.
* Add extendDefaultEnvWithLocalDefaults to merge local defaults into the
environment, with proper duplication checks:
- Duplicate local defaults for a class trigger an error.
- Local defaults override imported or built-in defaults.
* Update and add related notes: Note [Builtin class defaults],
Note [DefaultProvenance].
* Add regression tests: T25912, T25914, T25934.
Thanks sam and simon for the help on this patch.
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
386f1854 by Teo Camarasu at 2025-04-17T04:31:55-04:00
template-haskell: Remove `addrToByteArrayName` and `addrToByteArray`
These were part of the implementation of the `Lift ByteArray` instance and were errornously exported because this module lacked an explicit export list. They have no usages on Hackage.
Resolves #24782
- - - - -
b96e2f77 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove target info and fix host info (#24058)
The RTS isn't a compiler, hence it doesn't have a target and we remove
the reported target info displayed by "+RTS --info". We also fix the
host info displayed by "+RTS --info": the host of the RTS is the
RTS-building compiler's target, not the compiler's host (wrong when
doing cross-compilation).
- - - - -
6d9965f4 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove build info
As per the discussion in !13967, there is no reason to tag the RTS with
information about the build platform.
- - - - -
d52e9b3f by Vladislav Zavialov at 2025-04-18T20:47:15-04:00
Diagnostics: remove the KindMismatch constructor (#25957)
The KindMismatch constructor was only used as an intermediate
representation in pretty-printing.
Its removal addresses a problem detected by the "codes" test case:
[GHC-89223] is untested (constructor = KindMismatch)
In a concious deviation from the usual procedure, the error code
GHC-89223 is removed entirely rather than marked as Outdated.
The reason is that it never was user-facing in the first place.
- - - - -
e2f2f9d0 by Vladislav Zavialov at 2025-04-20T10:53:39-04:00
Add name for -Wunusable-unpack-pragmas
This warning had no name or flag and was triggered unconditionally.
Now it is part of -Wdefault.
In GHC.Tc.TyCl.tcTyClGroupsPass's strict mode, we now have to
force-enable this warning to ensure that detection of flawed groups
continues to work even if the user disables the warning with the
-Wno-unusable-unpack-pragmas option. Test case: T3990c
Also, the misnamed BackpackUnpackAbstractType is now called
UnusableUnpackPragma.
- - - - -
6caa6508 by Adam Gundry at 2025-04-20T10:54:22-04:00
Fix specialisation of incoherent instances (fixes #25883)
GHC normally assumes that class constraints are canonical, meaning that
the specialiser is allowed to replace one dictionary argument with another
provided that they have the same type. The `-fno-specialise-incoherents`
flag alters INCOHERENT instance definitions so that they will prevent
specialisation in some cases, by inserting `nospec`.
This commit fixes a bug in 7124e4ad76d98f1fc246ada4fd7bf64413ff2f2e, which
treated some INCOHERENT instance matches as if `-fno-specialise-incoherents`
was in effect, thereby unnecessarily preventing specialisation. In addition
it updates the relevant `Note [Rules for instance lookup]` and adds a new
`Note [Canonicity for incoherent matches]`.
- - - - -
0426fd6c by Adam Gundry at 2025-04-20T10:54:23-04:00
Add regression test for #23429
- - - - -
eec96527 by Adam Gundry at 2025-04-20T10:54:23-04:00
user's guide: update specification of overlapping/incoherent instances
The description of the instance resolution algorithm in the user's
guide was slightly out of date, because it mentioned in-scope given
constraints only at the end, whereas the implementation checks for
their presence before any of the other steps.
This also adds a warning to the user's guide about the impact of
incoherent instances on specialisation, and more clearly documents
some of the other effects of `-XIncoherentInstances`.
- - - - -
a00eeaec by Matthew Craven at 2025-04-20T10:55:03-04:00
Fix bytecode generation for `tagToEnum# <LITERAL>`
Fixes #25975.
- - - - -
0c34a817 by Joseph Fourment at 2025-04-22T17:44:10+01:00
compiler: introduce type variable unfoldings
The plan for #20264 is to introduce let-bound types to have observable sharing in types.
To avoid the need to carry an environment when dealing with occurrences of these type variables,
we embed the types they're bound to (if any) in a `tv_unfolding :: Maybe Type` attribute.
This way, one can look through let-bound type variables using `coreView` and friends.
In particular, definitional equality looks through unfoldings.
- - - - -
08b9fdfc by Joseph Fourment at 2025-04-22T17:44:10+01:00
simple-opt: don't inline type-lets
- - - - -
a6b89e66 by Joseph Fourment at 2025-04-22T17:44:10+01:00
specialise: fix type-lets in DFun unfoldings
During specialisation, a dictionary being specialised gets a new unfolding by turning
`DFun \ bndrs -> MkD @<T1> ... @<Tm> <op1> ... <opn>` into
`DFun \ spec_bndrs -> MkD @((\ bndrs -> TYPE: <T1>) spec_args) ... ((\ bndrs -> <opn>) spec_args)`
which in turns gets beta-reduced into
`DFun \ spec_bndrs -> MkD (let { bndrs = spec_args } in TYPE: <T1>) ... (let { bndrs = spec_args } in <opn>)`.
Previously, such let binders would immediately be substituted into the type so it didn't cause any issue,
but now we want to avoid inlining.
Arguments of the form `let { bndrs = spec_args } in TYPE: <T1>` are not considered as type arguments since they're
not of the canonical form `TYPE: something`.
This commit restores the previous behavior of substituting the specialised type arguments.
Alternatively, we could attach some floated type bindings to `DFun`s.
- - - - -
3885423d by Joseph Fourment at 2025-04-22T17:44:10+01:00
occur-anal: implement occurence analysis for type variables
In order to find out let-bound type variables that are used only once, in the hope of inlining them,
we need to track type variables as well in the occurrence analiser. Just like Id's, we attach an
`OccInfo` to each (immutable) type variable, and we walk into types and coercions to accurately gather
occurrences.
- - - - -
9c6ca7a2 by Joseph Fourment at 2025-04-22T17:44:10+01:00
simplifier: don't inline type-lets
Keep propagating type-lets further down the pipeline, in the simplifier.
We also update CallArity, CprAnal, DmdAnal, WorkWrap, and Specialise to ignore type-lets.
- - - - -
96c73f5e by Joseph Fourment at 2025-04-22T17:44:11+01:00
prep: make type-lets pass through CorePrep
As a first attempt, ignore type-lets in CorePrep to avoid crashes.
However, this is not enough: CorePrep also does some let-floating.
If we don't float type-lets along with value-level let-bindings,
the latter can float out of the scope of a type variable in use.
- - - - -
71766945 by Joseph Fourment at 2025-04-22T17:44:11+01:00
simple-opt: fix simple_type_bind
Also:
- Inline small types using a new typeIsSmallEnoughToInline predicate
- Inline single-occurrence variables
- - - - -
15c96eaf by Joseph Fourment at 2025-04-22T17:44:11+01:00
simple-opt: make beta-reduction use simple_bind_type
- - - - -
dd922887 by Joseph Fourment at 2025-04-22T17:44:11+01:00
iface: add IfaceTypeLetBndr to represent non-top-level type-let binders
IfaceLetBndr isn't fit to represent type-let binders, as it includes a
bunch of vacuous flags for Ids only.
Instead of putting squares in circles, I added a new constructor for type binders.
The downside is that it breaks existing iface files, so since we can't bootstrap
yet so we have to bootstrap a cherry-picked branch and then checkout again to build
with --freeze1.
To avoid similar issues in the future, IfaceTyVarInfoItem serialises with a tag
despite there being only one constructor for now.
- - - - -
4eeba99a by Joseph Fourment at 2025-04-22T17:44:11+01:00
dmd-anal: prefix unused variable with _ to avoid warning
- - - - -
954ebac8 by Joseph Fourment at 2025-04-22T17:44:11+01:00
type: inline unfoldView in sORTKind_maybe
- - - - -
124c8394 by Joseph Fourment at 2025-04-22T17:44:11+01:00
tidy: deal with type-lets
- - - - -
cff4dc4f by Joseph Fourment at 2025-04-22T17:44:11+01:00
notes: add Note [Type and coercion lets]
- - - - -
ea4881ee by Joseph Fourment at 2025-04-22T17:44:11+01:00
notes: update Note [Comparing nullary type synonyms] to account for type variables
While updating backlinks, I noticed the optimisation for type variables
could be performed in more places.
- - - - -
1c6e33cc by Joseph Fourment at 2025-04-22T17:44:11+01:00
simplifier: inline single-occurring type-lets
- - - - -
b87e3436 by Joseph Fourment at 2025-04-22T17:44:11+01:00
cleanup: remove NOINLINE on tyVarOccInfo
- - - - -
14d156dc by Simon Peyton Jones at 2025-04-22T17:44:11+01:00
Wibbles
- - - - -
7378fd25 by Simon Peyton Jones at 2025-04-22T17:44:11+01:00
Wibbles
- - - - -
1d57e70e by Simon Peyton Jones at 2025-04-22T17:44:57+01:00
Progress
- - - - -
b9d856f4 by Simon Peyton Jones at 2025-04-22T17:44:57+01:00
Progress
- - - - -
cc9285a9 by Simon Peyton Jones at 2025-04-22T17:44:57+01:00
More progress
- - - - -
ae735183 by Simon Peyton Jones at 2025-04-22T17:44:57+01:00
Progress
...doesn't compile though
- - - - -
8c3d2a4c by Simon Peyton Jones at 2025-04-22T17:44:57+01:00
Mostly working now
- - - - -
eb3507e8 by Simon Peyton Jones at 2025-04-22T17:44:58+01:00
Aggressively create type-lets
- - - - -
91d210e4 by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
more progress
- - - - -
dc9c84b8 by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
More progress
- - - - -
72faef28 by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Temp debug printing
- - - - -
43bea85c by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Remove bogus assert
- - - - -
bd5d85ac by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Fix anoher couple of bugs
in SimpleOpt and exprIsTrivial
- - - - -
b06bbffa by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Improve zonking of foreign decls to avoid TcTyVars escaping
- - - - -
2be43481 by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Wibbles
- - - - -
172fc5f8 by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Some small wibbles
- - - - -
b2b9b988 by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Improvements
- - - - -
e058f278 by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Rmmove trace
- - - - -
e7576d9f by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Wibbles
- - - - -
93c78c89 by Simon Peyton Jones at 2025-04-22T17:45:28+01:00
Use lambda, not let, in WorkWrap
Using type let did not work right with type lets and shadowing
Requires Lint to be OK join points under beta redexes -- but it is!
Needs better documentation
- - - - -
0259f51f by Simon Peyton Jones at 2025-04-22T17:45:29+01:00
Wibbles
- - - - -
a0eda323 by Simon Peyton Jones at 2025-04-22T17:45:29+01:00
More improvements
- - - - -
7d15fb5c by Simon Peyton Jones at 2025-04-22T17:45:29+01:00
More improvements
* Less cloning in SpecConstr
* Lint checks RULES for imported binders
- - - - -
6f303046 by Simon Peyton Jones at 2025-04-22T17:45:29+01:00
Comments only
- - - - -
85122f54 by Simon Peyton Jones at 2025-04-22T17:45:29+01:00
Wibble
- - - - -
51a29d7a by Simon Peyton Jones at 2025-04-22T17:45:29+01:00
Wibbles
- - - - -
a3b815fb by Simon Peyton Jones at 2025-04-22T17:45:29+01:00
Wibbles
.. getting Lint errors when compiling GHC.Internal.Classes
- - - - -
3af9b229 by Simon Peyton Jones at 2025-04-22T17:45:29+01:00
Wibbles
- - - - -
128c3b7c by Simon Peyton Jones at 2025-04-22T17:46:32+01:00
More improvements
..now getting to the back end an interface file generation
- - - - -
7a464100 by Simon Peyton Jones at 2025-04-22T17:46:32+01:00
Wibbles
- - - - -
598 changed files:
- .gitlab-ci.yml
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- compiler/GHC.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/Cmm/Lint.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/Cmm/Type.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/DataCon.hs
- compiler/GHC/Core/FVs.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/CallArity.hs
- compiler/GHC/Core/Opt/CprAnal.hs
- compiler/GHC/Core/Opt/DmdAnal.hs
- compiler/GHC/Core/Opt/Exitify.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify.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/Simplify/Utils.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/Predicate.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Seq.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Subst.hs
- compiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/TyCo/Compare.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Ppr.hs
- compiler/GHC/Core/TyCo/Ppr.hs-boot
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/TyCo/Tidy.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unfold/Make.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/CoreToStg.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- + compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Env/Types.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- + compiler/GHC/Driver/MakeAction.hs
- compiler/GHC/Driver/MakeFile.hs
- + compiler/GHC/Driver/Messager.hs
- compiler/GHC/Driver/Pipeline.hs-boot
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- + compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Extension.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Pmc/Utils.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Decl.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Binary.hs
- compiler/GHC/Iface/Recomp/Flags.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/IfaceToCore.hs-boot
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Platform.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Rename/Unbound.hs
- compiler/GHC/Rename/Utils.hs
- + compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Eval/Types.hs
- + compiler/GHC/Runtime/Eval/Utils.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/Config.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/SysTools/Process.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Infer.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Default.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/Rewrite.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/BasicTypes.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/ErrCtxt.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Backpack.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/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Validity.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Avail.hs
- compiler/GHC/Types/Breakpoint.hs
- compiler/GHC/Types/DefaultEnv.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/GREInfo.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Id.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Name.hs
- compiler/GHC/Types/Name/Occurrence.hs
- compiler/GHC/Types/Name/Ppr.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/TyThing.hs
- compiler/GHC/Types/TyThing/Ppr.hs
- compiler/GHC/Types/TypeEnv.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Unit/External.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Module/Deps.hs
- − compiler/GHC/Unit/Module/External/Graph.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/ModDetails.hs
- compiler/GHC/Unit/Module/ModIface.hs
- compiler/GHC/Unit/Module/ModNodeKey.hs
- compiler/GHC/Utils/Logger.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/Panic/Plain.hs
- compiler/GHC/Utils/Trace.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/Language/Haskell/Syntax/Expr.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Type.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/exts/instances.rst
- docs/users_guide/exts/monad_comprehensions.rst
- docs/users_guide/exts/named_defaults.rst
- docs/users_guide/exts/parallel_list_comprehensions.rst
- docs/users_guide/runtime_control.rst
- docs/users_guide/using-optimisation.rst
- docs/users_guide/using-warnings.rst
- docs/users_guide/using.rst
- + ghc/GHC/Driver/Session/Lint.hs
- + ghc/GHC/Driver/Session/Mode.hs
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Monad.hs
- ghc/Main.hs
- ghc/ghc-bin.cabal.in
- hadrian/doc/flavours.md
- hadrian/src/CommandLine.hs
- hadrian/src/Flavour.hs
- hadrian/src/Flavour/Type.hs
- hadrian/src/Hadrian/Haskell/Hash.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/Cabal.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Flavours/Release.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- − libraries/base/src/GHC/ExecutionStack/Internal.hs
- libraries/base/src/GHC/Records.hs
- − libraries/base/src/GHC/TypeLits/Internal.hs
- − libraries/base/src/GHC/TypeNats/Internal.hs
- + libraries/ghc-internal/cbits/int64x2minmax.c
- + libraries/ghc-internal/cbits/vectorQuotRem.c
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghci/GHCi/ResolvedBCO.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- libraries/template-haskell/changelog.md
- rts/Interpreter.c
- rts/RtsAPI.c
- rts/RtsUtils.c
- rts/include/RtsAPI.h
- testsuite/config/ghc
- testsuite/driver/testlib.py
- testsuite/ghc-config/ghc-config.hs
- testsuite/mk/boilerplate.mk
- testsuite/tests/backpack/should_fail/bkpfail51.stderr
- + testsuite/tests/bytecode/T25975.hs
- + testsuite/tests/bytecode/T25975.stdout
- testsuite/tests/bytecode/all.T
- testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm
- + testsuite/tests/core-to-stg/T23865.hs
- testsuite/tests/core-to-stg/all.T
- + testsuite/tests/default/T25775.hs
- + testsuite/tests/default/T25775.stderr
- + testsuite/tests/default/T25857.hs
- + testsuite/tests/default/T25857.stderr
- + testsuite/tests/default/T25858.hs
- + testsuite/tests/default/T25858.stdout
- + testsuite/tests/default/T25858v1.hs
- + testsuite/tests/default/T25858v1.stdout
- + testsuite/tests/default/T25858v1_helper.hs
- + testsuite/tests/default/T25858v2.hs
- + testsuite/tests/default/T25858v2.stdout
- + testsuite/tests/default/T25858v2_helper.hs
- + testsuite/tests/default/T25858v3.hs
- + testsuite/tests/default/T25858v3.stdout
- + testsuite/tests/default/T25858v3_helper.hs
- + testsuite/tests/default/T25858v4.hs
- + testsuite/tests/default/T25858v4.stdout
- + testsuite/tests/default/T25882.hs
- + testsuite/tests/default/T25912.hs
- + testsuite/tests/default/T25912.stdout
- + testsuite/tests/default/T25912_helper.hs
- + testsuite/tests/default/T25914.hs
- + testsuite/tests/default/T25934.hs
- testsuite/tests/default/all.T
- testsuite/tests/default/default-fail01.stderr
- testsuite/tests/default/default-fail02.stderr
- testsuite/tests/default/default-fail03.stderr
- testsuite/tests/default/default-fail04.stderr
- testsuite/tests/default/default-fail08.stderr
- + testsuite/tests/dependent/should_compile/GADTSingletons.hs
- + testsuite/tests/dependent/should_compile/T12088a.hs
- + testsuite/tests/dependent/should_compile/T12088b.hs
- + testsuite/tests/dependent/should_compile/T12088c.hs
- + testsuite/tests/dependent/should_compile/T12088d.hs
- + testsuite/tests/dependent/should_compile/T12088e.hs
- + testsuite/tests/dependent/should_compile/T12088f.hs
- + testsuite/tests/dependent/should_compile/T12088g.hs
- + testsuite/tests/dependent/should_compile/T12088i.hs
- + testsuite/tests/dependent/should_compile/T12088j.hs
- + testsuite/tests/dependent/should_compile/T12088mm1.hs
- + testsuite/tests/dependent/should_compile/T12088mm1_helper.hs
- + testsuite/tests/dependent/should_compile/T12088mm2.hs
- + testsuite/tests/dependent/should_compile/T12088mm2_helper.hs
- + testsuite/tests/dependent/should_compile/T12088mm3.hs
- + testsuite/tests/dependent/should_compile/T12088mm3_helper.hs
- + testsuite/tests/dependent/should_compile/T12088sg1.hs
- + testsuite/tests/dependent/should_compile/T12088sg2.hs
- + testsuite/tests/dependent/should_compile/T12088sg3.hs
- + testsuite/tests/dependent/should_compile/T12239.hs
- + testsuite/tests/dependent/should_compile/T13790.hs
- + testsuite/tests/dependent/should_compile/T14668a.hs
- + testsuite/tests/dependent/should_compile/T14668b.hs
- + testsuite/tests/dependent/should_compile/T15561.hs
- + testsuite/tests/dependent/should_compile/T16410.hs
- + testsuite/tests/dependent/should_compile/T16448.hs
- + testsuite/tests/dependent/should_compile/T16693.hs
- + testsuite/tests/dependent/should_compile/T19611.hs
- + testsuite/tests/dependent/should_compile/T20875.hs
- + testsuite/tests/dependent/should_compile/T21172.hs
- + testsuite/tests/dependent/should_compile/T22257a.hs
- + testsuite/tests/dependent/should_compile/T22257b.hs
- + testsuite/tests/dependent/should_compile/T25238.hs
- + testsuite/tests/dependent/should_compile/T25834.hs
- testsuite/tests/dependent/should_compile/all.T
- testsuite/tests/deriving/should_compile/T17339.stderr
- testsuite/tests/diagnostic-codes/codes.stdout
- + testsuite/tests/driver/RecompCompletePragma/A1.hs
- + testsuite/tests/driver/RecompCompletePragma/A2.hs
- + testsuite/tests/driver/RecompCompletePragma/A3.hs
- + testsuite/tests/driver/RecompCompletePragma/A4.hs
- + testsuite/tests/driver/RecompCompletePragma/B1.hs
- + testsuite/tests/driver/RecompCompletePragma/C1.hs
- + testsuite/tests/driver/RecompCompletePragma/C2.hs
- + testsuite/tests/driver/RecompCompletePragma/C3.hs
- + testsuite/tests/driver/RecompCompletePragma/Makefile
- + testsuite/tests/driver/RecompCompletePragma/RecompCompleteFixity.stderr
- + testsuite/tests/driver/RecompCompletePragma/RecompCompleteFixity.stdout
- + testsuite/tests/driver/RecompCompletePragma/RecompCompleteFixityA.hs
- + testsuite/tests/driver/RecompCompletePragma/RecompCompleteFixityB.hs
- + testsuite/tests/driver/RecompCompletePragma/RecompCompleteIndependence.hs
- + testsuite/tests/driver/RecompCompletePragma/RecompCompleteIndependence.stdout
- + testsuite/tests/driver/RecompCompletePragma/RecompCompletePragma.stderr
- + testsuite/tests/driver/RecompCompletePragma/RecompCompletePragma.stdout
- + testsuite/tests/driver/RecompCompletePragma/RecompCompletePragma2.stdout
- + testsuite/tests/driver/RecompCompletePragma/RecompCompletePragmaA.hs
- + testsuite/tests/driver/RecompCompletePragma/RecompCompletePragmaB.hs
- + testsuite/tests/driver/RecompCompletePragma/all.T
- + testsuite/tests/driver/RecompExportedDefault/A.hs
- + testsuite/tests/driver/RecompExportedDefault/A2.hs
- + testsuite/tests/driver/RecompExportedDefault/A3.hs
- + testsuite/tests/driver/RecompExportedDefault/A4.hs
- + testsuite/tests/driver/RecompExportedDefault/Makefile
- + testsuite/tests/driver/RecompExportedDefault/RecompExportedDefault.hs
- + testsuite/tests/driver/RecompExportedDefault/RecompExportedDefault.stdout
- + testsuite/tests/driver/RecompExportedDefault/all.T
- + testsuite/tests/driver/RecompExports/Makefile
- + testsuite/tests/driver/RecompExports/RecompExports1.stderr
- + testsuite/tests/driver/RecompExports/RecompExports1.stdout
- + testsuite/tests/driver/RecompExports/RecompExports1_M.hs_1
- + testsuite/tests/driver/RecompExports/RecompExports1_M.hs_2
- + testsuite/tests/driver/RecompExports/RecompExports1_M.hs_3
- + testsuite/tests/driver/RecompExports/RecompExports1_N.hs
- + testsuite/tests/driver/RecompExports/RecompExports2.stderr
- + testsuite/tests/driver/RecompExports/RecompExports2.stdout
- + testsuite/tests/driver/RecompExports/RecompExports2_M.hs_1
- + testsuite/tests/driver/RecompExports/RecompExports2_M.hs_2
- + testsuite/tests/driver/RecompExports/RecompExports2_M.hs_3
- + testsuite/tests/driver/RecompExports/RecompExports2_N.hs
- + testsuite/tests/driver/RecompExports/RecompExports3.stderr
- + testsuite/tests/driver/RecompExports/RecompExports3.stdout
- + testsuite/tests/driver/RecompExports/RecompExports3_M.hs_1
- + testsuite/tests/driver/RecompExports/RecompExports3_M.hs_2
- + testsuite/tests/driver/RecompExports/RecompExports3_M.hs_3
- + testsuite/tests/driver/RecompExports/RecompExports3_N.hs
- + testsuite/tests/driver/RecompExports/RecompExports4.stderr
- + testsuite/tests/driver/RecompExports/RecompExports4.stdout
- + testsuite/tests/driver/RecompExports/RecompExports4_M.hs_1
- + testsuite/tests/driver/RecompExports/RecompExports4_M.hs_2
- + testsuite/tests/driver/RecompExports/RecompExports4_N.hs
- + testsuite/tests/driver/RecompExports/RecompExports5.stdout
- + testsuite/tests/driver/RecompExports/RecompExports5_M.hs_1
- + testsuite/tests/driver/RecompExports/RecompExports5_M.hs_2
- + testsuite/tests/driver/RecompExports/RecompExports5_N.hs
- + testsuite/tests/driver/RecompExports/all.T
- testsuite/tests/driver/T20459.stderr
- testsuite/tests/driver/T24196/T24196.stderr
- testsuite/tests/driver/T24275/T24275.stderr
- testsuite/tests/driver/inline-check.stderr
- + testsuite/tests/ghc-api/fixed-nodes/FixedNodes.hs
- + testsuite/tests/ghc-api/fixed-nodes/FixedNodes.stdout
- + testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs
- + testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.stdout
- + testsuite/tests/ghc-api/fixed-nodes/Makefile
- + testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.hs
- + testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.stdout
- + testsuite/tests/ghc-api/fixed-nodes/T1.hs
- + testsuite/tests/ghc-api/fixed-nodes/T1A.hs
- + testsuite/tests/ghc-api/fixed-nodes/T1B.hs
- + testsuite/tests/ghc-api/fixed-nodes/T1C.hs
- + testsuite/tests/ghc-api/fixed-nodes/all.T
- testsuite/tests/ghc-api/settings-escape/T11938.hs → testsuite/tests/ghc-api/settings-escape/T24265.hs
- testsuite/tests/ghc-api/settings-escape/T11938.stderr → testsuite/tests/ghc-api/settings-escape/T24265.stderr
- + testsuite/tests/ghc-api/settings-escape/T25204.hs
- + testsuite/tests/ghc-api/settings-escape/T25204.stdout
- + testsuite/tests/ghc-api/settings-escape/T25204_C.c
- testsuite/tests/ghc-api/settings-escape/all.T
- + testsuite/tests/ghc-api/settings-escape/ghc-install-folder/ghc version.h
- testsuite/tests/ghc-api/settings-escape/ghc-install-folder/lib/.gitkeep → testsuite/tests/ghc-api/settings-escape/ghc-install-folder/lib with spaces/.gitkeep
- testsuite/tests/ghc-e/should_fail/T9930fail.stderr
- + testsuite/tests/ghci.debugger/scripts/T25932.hs
- + testsuite/tests/ghci.debugger/scripts/T25932.script
- + testsuite/tests/ghci.debugger/scripts/T25932.stdout
- testsuite/tests/ghci.debugger/scripts/T8487.script
- testsuite/tests/ghci.debugger/scripts/all.T
- testsuite/tests/ghci.debugger/scripts/break018.script
- testsuite/tests/ghci.debugger/scripts/break018.stdout
- testsuite/tests/ghci.debugger/scripts/dynbrk004.stdout
- testsuite/tests/ghci.debugger/scripts/dynbrk007.script
- testsuite/tests/ghci.debugger/scripts/dynbrk007.stdout
- testsuite/tests/ghci/scripts/T12550.stdout
- testsuite/tests/ghci/scripts/T4175.stdout
- testsuite/tests/ghci/scripts/ghci024.stdout
- testsuite/tests/ghci/scripts/ghci024.stdout-mingw32
- testsuite/tests/ghci/scripts/ghci064.stdout
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/hpc/fork/hpc_fork.stdout
- testsuite/tests/hpc/function/tough.stdout
- testsuite/tests/hpc/function2/tough2.stdout
- testsuite/tests/indexed-types/should_fail/T8550.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/template-haskell-exports.stdout
- testsuite/tests/linters/notes.stdout
- testsuite/tests/module/all.T
- testsuite/tests/module/mod132.stderr
- testsuite/tests/module/mod147.stderr
- testsuite/tests/module/mod58.stderr
- testsuite/tests/module/mod73.hs
- testsuite/tests/module/mod73.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_fail/readFail038.stderr
- testsuite/tests/perf/compiler/Makefile
- testsuite/tests/perf/compiler/WWRec.hs
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/perf/compiler/hard_hole_fits.stderr
- testsuite/tests/plugins/defaulting-plugin/DefaultLifted.hs
- testsuite/tests/polykinds/T18300.hs
- testsuite/tests/polykinds/T18300.stderr
- testsuite/tests/primops/should_run/all.T
- testsuite/tests/quasiquotation/T7918.hs
- testsuite/tests/rename/should_fail/SimilarNamesImport.stderr
- testsuite/tests/rename/should_fail/T19843c.stderr
- testsuite/tests/rename/should_fail/T23510a.hs
- testsuite/tests/rename/should_fail/T23510a.stderr
- + testsuite/tests/rename/should_fail/T23982.hs
- + testsuite/tests/rename/should_fail/T23982.stderr
- + testsuite/tests/rename/should_fail/T23982_aux.hs
- + testsuite/tests/rename/should_fail/T23982b.hs
- + testsuite/tests/rename/should_fail/T23982b.stderr
- + testsuite/tests/rename/should_fail/T23982b_aux.hs
- + testsuite/tests/rename/should_fail/T25877.hs
- + testsuite/tests/rename/should_fail/T25877.stderr
- + testsuite/tests/rename/should_fail/T25877_aux.hs
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/roles/should_compile/T8958.stderr
- testsuite/tests/rts/T13082/Makefile
- testsuite/tests/rts/T13082/T13082_fail.stderr → testsuite/tests/rts/T13082/T13082_fail.stdout
- testsuite/tests/showIface/Orphans.stdout
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simd/should_run/int16x8_arith.hs
- + testsuite/tests/simd/should_run/int16x8_arith.stdout
- + testsuite/tests/simd/should_run/int16x8_arith_baseline.hs
- + testsuite/tests/simd/should_run/int16x8_arith_baseline.stdout
- + testsuite/tests/simd/should_run/int16x8_shuffle.hs
- + testsuite/tests/simd/should_run/int16x8_shuffle.stdout
- + testsuite/tests/simd/should_run/int16x8_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/int16x8_shuffle_baseline.stdout
- + testsuite/tests/simd/should_run/int32x4_arith.hs
- + testsuite/tests/simd/should_run/int32x4_arith.stdout
- + testsuite/tests/simd/should_run/int32x4_arith_baseline.hs
- + testsuite/tests/simd/should_run/int32x4_arith_baseline.stdout
- + testsuite/tests/simd/should_run/int32x4_shuffle.hs
- + testsuite/tests/simd/should_run/int32x4_shuffle.stdout
- + testsuite/tests/simd/should_run/int32x4_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/int32x4_shuffle_baseline.stdout
- + testsuite/tests/simd/should_run/int64x2_arith.hs
- + testsuite/tests/simd/should_run/int64x2_arith.stdout
- + testsuite/tests/simd/should_run/int64x2_arith_baseline.hs
- + testsuite/tests/simd/should_run/int64x2_arith_baseline.stdout
- + testsuite/tests/simd/should_run/int64x2_shuffle.hs
- + testsuite/tests/simd/should_run/int64x2_shuffle.stdout
- + testsuite/tests/simd/should_run/int64x2_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/int64x2_shuffle_baseline.stdout
- + testsuite/tests/simd/should_run/int8x16_arith.hs
- + testsuite/tests/simd/should_run/int8x16_arith.stdout
- + testsuite/tests/simd/should_run/int8x16_arith_baseline.hs
- + testsuite/tests/simd/should_run/int8x16_arith_baseline.stdout
- + testsuite/tests/simd/should_run/int8x16_shuffle.hs
- + testsuite/tests/simd/should_run/int8x16_shuffle.stdout
- + testsuite/tests/simd/should_run/int8x16_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/int8x16_shuffle_baseline.stdout
- + testsuite/tests/simd/should_run/word16x8_arith.hs
- + testsuite/tests/simd/should_run/word16x8_arith.stdout
- + testsuite/tests/simd/should_run/word16x8_arith_baseline.hs
- + testsuite/tests/simd/should_run/word16x8_arith_baseline.stdout
- + testsuite/tests/simd/should_run/word32x4_arith.hs
- + testsuite/tests/simd/should_run/word32x4_arith.stdout
- + testsuite/tests/simd/should_run/word32x4_arith_baseline.hs
- + testsuite/tests/simd/should_run/word32x4_arith_baseline.stdout
- + testsuite/tests/simd/should_run/word64x2_arith.hs
- + testsuite/tests/simd/should_run/word64x2_arith.stdout
- + testsuite/tests/simd/should_run/word64x2_arith_baseline.hs
- + testsuite/tests/simd/should_run/word64x2_arith_baseline.stdout
- + testsuite/tests/simd/should_run/word8x16_arith.hs
- + testsuite/tests/simd/should_run/word8x16_arith.stdout
- + testsuite/tests/simd/should_run/word8x16_arith_baseline.hs
- + testsuite/tests/simd/should_run/word8x16_arith_baseline.stdout
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/RewriteHigherOrderPatterns.stderr
- testsuite/tests/simplCore/should_compile/T15445.stderr
- testsuite/tests/simplCore/should_compile/T18013.stderr
- testsuite/tests/simplCore/should_compile/T18668.stderr
- testsuite/tests/simplCore/should_compile/T23307c.stderr
- + testsuite/tests/simplCore/should_compile/T25883.hs
- + testsuite/tests/simplCore/should_compile/T25883.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883b.hs
- + testsuite/tests/simplCore/should_compile/T25883b.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883c.hs
- + testsuite/tests/simplCore/should_compile/T25883c.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883d.hs
- + testsuite/tests/simplCore/should_compile/T25883d.stderr
- + testsuite/tests/simplCore/should_compile/T25883d_import.hs
- + testsuite/tests/simplCore/should_compile/T3990b.hs
- + testsuite/tests/simplCore/should_compile/T3990b.stdout
- + testsuite/tests/simplCore/should_compile/T3990c.hs
- + testsuite/tests/simplCore/should_compile/T3990c.stdout
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_fail/T25672.stderr
- + testsuite/tests/simplCore/should_run/T23429.hs
- + testsuite/tests/simplCore/should_run/T23429.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/th/T15365.stderr
- testsuite/tests/th/T1835.stdout
- testsuite/tests/typecheck/should_compile/LoopOfTheDay1.hs
- testsuite/tests/typecheck/should_compile/LoopOfTheDay2.hs
- testsuite/tests/typecheck/should_compile/LoopOfTheDay3.hs
- + testsuite/tests/typecheck/should_compile/T25960.hs
- testsuite/tests/typecheck/should_compile/T7050.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T12729.stderr
- testsuite/tests/typecheck/should_fail/T12921.stderr
- testsuite/tests/typecheck/should_fail/T19978.stderr
- + testsuite/tests/typecheck/should_fail/T24090a.hs
- + testsuite/tests/typecheck/should_fail/T24090a.stderr
- + testsuite/tests/typecheck/should_fail/T24090b.hs
- testsuite/tests/wcompat-warnings/WCompatWarningsOn.stderr → testsuite/tests/typecheck/should_fail/T24090b.stderr
- + testsuite/tests/typecheck/should_fail/T25004k.hs
- + testsuite/tests/typecheck/should_fail/T25004k.stderr
- testsuite/tests/typecheck/should_fail/T3966.stderr
- + testsuite/tests/typecheck/should_fail/T3966b.hs
- + testsuite/tests/typecheck/should_fail/T3966b.stderr
- testsuite/tests/typecheck/should_fail/T6018fail.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/unpack_sums_5.stderr
- + testsuite/tests/vdq-rta/should_fail/T23738_fail_pun.hs
- + testsuite/tests/vdq-rta/should_fail/T23738_fail_pun.stderr
- testsuite/tests/vdq-rta/should_fail/all.T
- testsuite/tests/warnings/should_compile/WarnNoncanonical.stderr
- testsuite/tests/wasm/should_run/control-flow/README.md
- − testsuite/tests/wasm/should_run/control-flow/WasmControlFlow.stdout
- testsuite/tests/wasm/should_run/control-flow/all.T
- testsuite/tests/wcompat-warnings/Template.hs
- utils/check-exact/Parsers.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
- utils/haddock/haddock-api/src/Haddock/Interface.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Create.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/02400ee447021029796ae0cebed115…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/02400ee447021029796ae0cebed115…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

22 Apr '25
Simon Peyton Jones pushed new branch wip/T23298-test at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23298-test
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/fendor/ghci-debugger-unitid] 9 commits: RTS: remove target info and fix host info (#24058)
by Hannes Siebenhandl (@fendor) 22 Apr '25
by Hannes Siebenhandl (@fendor) 22 Apr '25
22 Apr '25
Hannes Siebenhandl pushed to branch wip/fendor/ghci-debugger-unitid at Glasgow Haskell Compiler / GHC
Commits:
b96e2f77 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove target info and fix host info (#24058)
The RTS isn't a compiler, hence it doesn't have a target and we remove
the reported target info displayed by "+RTS --info". We also fix the
host info displayed by "+RTS --info": the host of the RTS is the
RTS-building compiler's target, not the compiler's host (wrong when
doing cross-compilation).
- - - - -
6d9965f4 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove build info
As per the discussion in !13967, there is no reason to tag the RTS with
information about the build platform.
- - - - -
d52e9b3f by Vladislav Zavialov at 2025-04-18T20:47:15-04:00
Diagnostics: remove the KindMismatch constructor (#25957)
The KindMismatch constructor was only used as an intermediate
representation in pretty-printing.
Its removal addresses a problem detected by the "codes" test case:
[GHC-89223] is untested (constructor = KindMismatch)
In a concious deviation from the usual procedure, the error code
GHC-89223 is removed entirely rather than marked as Outdated.
The reason is that it never was user-facing in the first place.
- - - - -
e2f2f9d0 by Vladislav Zavialov at 2025-04-20T10:53:39-04:00
Add name for -Wunusable-unpack-pragmas
This warning had no name or flag and was triggered unconditionally.
Now it is part of -Wdefault.
In GHC.Tc.TyCl.tcTyClGroupsPass's strict mode, we now have to
force-enable this warning to ensure that detection of flawed groups
continues to work even if the user disables the warning with the
-Wno-unusable-unpack-pragmas option. Test case: T3990c
Also, the misnamed BackpackUnpackAbstractType is now called
UnusableUnpackPragma.
- - - - -
6caa6508 by Adam Gundry at 2025-04-20T10:54:22-04:00
Fix specialisation of incoherent instances (fixes #25883)
GHC normally assumes that class constraints are canonical, meaning that
the specialiser is allowed to replace one dictionary argument with another
provided that they have the same type. The `-fno-specialise-incoherents`
flag alters INCOHERENT instance definitions so that they will prevent
specialisation in some cases, by inserting `nospec`.
This commit fixes a bug in 7124e4ad76d98f1fc246ada4fd7bf64413ff2f2e, which
treated some INCOHERENT instance matches as if `-fno-specialise-incoherents`
was in effect, thereby unnecessarily preventing specialisation. In addition
it updates the relevant `Note [Rules for instance lookup]` and adds a new
`Note [Canonicity for incoherent matches]`.
- - - - -
0426fd6c by Adam Gundry at 2025-04-20T10:54:23-04:00
Add regression test for #23429
- - - - -
eec96527 by Adam Gundry at 2025-04-20T10:54:23-04:00
user's guide: update specification of overlapping/incoherent instances
The description of the instance resolution algorithm in the user's
guide was slightly out of date, because it mentioned in-scope given
constraints only at the end, whereas the implementation checks for
their presence before any of the other steps.
This also adds a warning to the user's guide about the impact of
incoherent instances on specialisation, and more clearly documents
some of the other effects of `-XIncoherentInstances`.
- - - - -
a00eeaec by Matthew Craven at 2025-04-20T10:55:03-04:00
Fix bytecode generation for `tagToEnum# <LITERAL>`
Fixes #25975.
- - - - -
e7bb646b by fendor at 2025-04-22T16:41:57+02:00
Add `UnitId` to `EvalBreakpoint`
The `EvalBreakpoint` is used to communicate that a breakpoint was
encountered during code evaluation.
This `EvalBreakpoint` needs to be converted to an `InternalBreakpointId`
which stores a `Module` to uniquely find the correct `Module` in the
Home Package Table.
The `EvalBreakpoint` used to store only a `ModuleName` which is then
converted to a `Module` based on the currently active home unit.
This is incorrect in the face of multiple home units, the break point
could be in an entirely other home unit!
To fix this, we additionally store the `UnitId` of the `Module` in
`EvalBreakpoint` to later reconstruct the correct `Module`
All of the changes are the consequence of extending `EvalBreakpoint`
with the additional `UnitId`.
- - - - -
55 changed files:
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Error/Codes.hs
- configure.ac
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/exts/instances.rst
- docs/users_guide/using-warnings.rst
- hadrian/src/Settings/Packages.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- rts/Exception.cmm
- rts/Interpreter.c
- rts/RtsUtils.c
- testsuite/ghc-config/ghc-config.hs
- + testsuite/tests/bytecode/T25975.hs
- + testsuite/tests/bytecode/T25975.stdout
- testsuite/tests/bytecode/all.T
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T23307c.stderr
- + testsuite/tests/simplCore/should_compile/T25883.hs
- + testsuite/tests/simplCore/should_compile/T25883.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883b.hs
- + testsuite/tests/simplCore/should_compile/T25883b.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883c.hs
- + testsuite/tests/simplCore/should_compile/T25883c.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883d.hs
- + testsuite/tests/simplCore/should_compile/T25883d.stderr
- + testsuite/tests/simplCore/should_compile/T25883d_import.hs
- + testsuite/tests/simplCore/should_compile/T3990c.hs
- + testsuite/tests/simplCore/should_compile/T3990c.stdout
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_fail/T25672.stderr
- + testsuite/tests/simplCore/should_run/T23429.hs
- + testsuite/tests/simplCore/should_run/T23429.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/typecheck/should_compile/T7050.stderr
- testsuite/tests/typecheck/should_fail/T3966.stderr
- + testsuite/tests/typecheck/should_fail/T3966b.hs
- + testsuite/tests/typecheck/should_fail/T3966b.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/unpack_sums_5.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1828d8116eeae9253577138f032aca…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1828d8116eeae9253577138f032aca…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

22 Apr '25
Simon Peyton Jones pushed to branch wip/T25440 at Glasgow Haskell Compiler / GHC
Commits:
465d7e9a by Simon Peyton Jones at 2025-04-22T16:21:26+01:00
Wibble test output
- - - - -
1 changed file:
- testsuite/tests/typecheck/should_compile/T25266a.stderr
Changes:
=====================================
testsuite/tests/typecheck/should_compile/T25266a.stderr
=====================================
@@ -1,16 +1,16 @@
-T25266a.hs:10:41: error: [GHC-25897]
- • Could not deduce ‘p1 ~ p2’
+T25266a.hs:10:39: error: [GHC-25897]
+ • Could not deduce ‘p2 ~ p1’
from the context: a ~ Int
bound by a pattern with constructor: T1 :: T Int,
in a case alternative
at T25266a.hs:10:23-24
- ‘p1’ is a rigid type variable bound by
+ ‘p2’ is a rigid type variable bound by
the inferred type of f :: p1 -> p2 -> T a -> Int
at T25266a.hs:(9,1)-(11,40)
- ‘p2’ is a rigid type variable bound by
+ ‘p1’ is a rigid type variable bound by
the inferred type of f :: p1 -> p2 -> T a -> Int
at T25266a.hs:(9,1)-(11,40)
- • In the expression: y
+ • In the expression: x
In the first argument of ‘length’, namely ‘[x, y]’
In the expression: length [x, y]
• Relevant bindings include
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/465d7e9ad9990d4224729149add3a32…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/465d7e9ad9990d4224729149add3a32…
You're receiving this email because of your account on gitlab.haskell.org.
1
0