Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
56b32c5a by sheaf at 2025-08-12T10:00:19-04:00
Improve deep subsumption
This commit improves the DeepSubsumption sub-typing implementation
in GHC.Tc.Utils.Unify.tc_sub_type_deep by being less eager to fall back
to unification.
For example, we now are properly able to prove the subtyping relationship
((∀ a. a->a) -> Int) -> Bool <= β[tau] Bool
for an unfilled metavariable β. In this case (with an AppTy on the right),
we used to fall back to unification. No longer: now, given that the LHS
is a FunTy and that the RHS is a deep rho type (does not need any instantiation),
we try to make the RHS into a FunTy, viz.
β := (->) γ
We can then continue using covariance & contravariance of the function
arrow, which allows us to prove the subtyping relationship, instead of
trying to unify which would cause us to error out with:
Couldn't match expected type ‘β’ with actual type ‘(->) ((∀ a. a -> a) -> Int)
See Note [FunTy vs non-FunTy case in tc_sub_type_deep] in GHC.Tc.Utils.Unify.
The other main improvement in this patch concerns type inference.
The main subsumption logic happens (before & after this patch) in
GHC.Tc.Gen.App.checkResultTy. However, before this patch, all of the
DeepSubsumption logic only kicked in in 'check' mode, not in 'infer' mode.
This patch adds deep instantiation in the 'infer' mode of checkResultTy
when we are doing deep subsumption, which allows us to accept programs
such as:
f :: Int -> (forall a. a->a)
g :: Int -> Bool -> Bool
test1 b =
case b of
True -> f
False -> g
test2 b =
case b of
True -> g
False -> f
See Note [Deeply instantiate in checkResultTy when inferring].
Finally, we add representation-polymorphism checks to ensure that the
lambda abstractions we introduce when doing subsumption obey the
representation polymorphism invariants of Note [Representation polymorphism invariants]
in GHC.Core. See Note [FunTy vs FunTy case in tc_sub_type_deep].
This is accompanied by a courtesy change to `(<.>) :: HsWrapper -> HsWrapper -> HsWrapper`,
adding the equation:
WpCast c1 <.> WpCast c2 = WpCast (c1 `mkTransCo` c2)
This is useful because mkWpFun does not introduce an eta-expansion when
both of the argument & result wrappers are casts; so this change allows
us to avoid introducing lambda abstractions when casts suffice.
Fixes #26225
- - - - -
26 changed files:
- compiler/GHC/Builtin/PrimOps/Ids.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Concrete.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Types/Id/Make.hs
- testsuite/tests/corelint/LintEtaExpand.stderr
- testsuite/tests/indexed-types/should_fail/T5439.stderr
- testsuite/tests/partial-sigs/should_compile/T10403.stderr
- testsuite/tests/partial-sigs/should_fail/T10615.stderr
- + testsuite/tests/rep-poly/NoEtaRequired.hs
- testsuite/tests/rep-poly/T21906.stderr
- testsuite/tests/rep-poly/all.T
- + testsuite/tests/typecheck/should_compile/T26225.hs
- + testsuite/tests/typecheck/should_compile/T26225b.hs
- testsuite/tests/typecheck/should_compile/all.T
- − testsuite/tests/typecheck/should_fail/T12563.stderr
- testsuite/tests/typecheck/should_fail/T14618.stderr
- testsuite/tests/typecheck/should_fail/T6022.stderr
- testsuite/tests/typecheck/should_fail/T8883.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail140.stderr
Changes:
=====================================
compiler/GHC/Builtin/PrimOps/Ids.hs
=====================================
@@ -99,7 +99,7 @@ computePrimOpConcTyVarsFromType nm tyvars arg_tys _res_ty = mkNameEnv concs
| tv `elem` [ runtimeRep1TyVar, runtimeRep2TyVar, runtimeRep3TyVar
, levity1TyVar, levity2TyVar ]
= listToMaybe $
- mapMaybe (\ (i,arg) -> Argument i <$> positiveKindPos_maybe tv arg)
+ mapMaybe (\ (i,arg) -> mkArgPos i <$> positiveKindPos_maybe tv arg)
(zip [1..] arg_tys)
| otherwise
= Nothing
@@ -124,7 +124,7 @@ negativeKindPos_maybe tv ty
)
where
recur (pos, scaled_ty)
- = Argument pos <$> positiveKindPos_maybe tv (scaledThing scaled_ty)
+ = mkArgPos pos <$> positiveKindPos_maybe tv (scaledThing scaled_ty)
-- (assumes we don't have any function types nested inside other types)
-- | Does this type variable appear in a kind in a positive position in the
@@ -145,7 +145,7 @@ positiveKindPos_maybe tv ty
)
where
recur (pos, scaled_ty)
- = Argument pos <$> negativeKindPos_maybe tv (scaledThing scaled_ty)
+ = mkArgPos pos <$> negativeKindPos_maybe tv (scaledThing scaled_ty)
-- (assumes we don't have any function types nested inside other types)
finish ty
| tv `elemVarSet` tyCoVarsOfType (typeKind ty)
=====================================
compiler/GHC/HsToCore.hs
=====================================
@@ -39,7 +39,7 @@ import GHC.HsToCore.Coverage
import GHC.HsToCore.Docs
import GHC.Tc.Types
-import GHC.Tc.Types.Origin ( Position(..) )
+import GHC.Tc.Types.Origin ( Position(..), mkArgPos )
import GHC.Tc.Utils.Monad ( finalSafeMode, fixSafeInstances )
import GHC.Tc.Module ( runTcInteractive )
@@ -780,7 +780,7 @@ mkUnsafeCoercePrimPair _old_id old_expr
arity = 1
concs = mkRepPolyIdConcreteTyVars
- [((mkTyVarTy openAlphaTyVar, Argument 1 Top), runtimeRep1TyVar)]
+ [((mkTyVarTy openAlphaTyVar, mkArgPos 1 Top), runtimeRep1TyVar)]
unsafeCoercePrimName
id = mkExportedLocalId (RepPolyId concs) unsafeCoercePrimName ty `setIdInfo` info
=====================================
compiler/GHC/Tc/Gen/App.hs
=====================================
@@ -430,7 +430,8 @@ tcApp rn_expr exp_res_ty
-- Step 5.2: typecheck the arguments, and monomorphise
-- any un-unified instantiation variables
; tc_args <- tcValArgs DoQL inst_args
- -- Step 5.3: typecheck the arguments
+ -- Step 5.3: zonk to expose the polymophism hidden under
+ -- QuickLook instantiation variables in `app_res_rho`
; app_res_rho <- liftZonkM $ zonkTcType app_res_rho
-- Step 5.4: subsumption check against the expected type
; res_wrap <- checkResultTy rn_expr tc_head inst_args
@@ -463,6 +464,8 @@ finishApp tc_head@(tc_fun,_) tc_args app_res_rho res_wrap
; traceTc "End tcApp }" (ppr tc_fun)
; return (mkHsWrap res_wrap res_expr) }
+-- | Connect up the inferred type of an application with the expected type.
+-- This is usually just a unification, but with deep subsumption there is more to do.
checkResultTy :: HsExpr GhcRn
-> (HsExpr GhcTc, AppCtxt) -- Head
-> [HsExprArg p] -- Arguments, just error messages
@@ -470,11 +473,29 @@ checkResultTy :: HsExpr GhcRn
-- expose foralls, but maybe not deeply instantiated
-> ExpRhoType -- Expected type; this is deeply skolemised
-> TcM HsWrapper
--- Connect up the inferred type of the application with the expected type
--- This is usually just a unification, but with deep subsumption there is more to do
-checkResultTy _ _ _ app_res_rho (Infer inf_res)
- = do { co <- fillInferResult app_res_rho inf_res
- ; return (mkWpCastN co) }
+checkResultTy rn_expr _fun _inst_args app_res_rho (Infer inf_res)
+ = fillInferResultDS (exprCtOrigin rn_expr) app_res_rho inf_res
+ -- See Note [Deeply instantiate in checkResultTy when inferring]
+
+{- Note [Deeply instantiate in checkResultTy when inferring]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+To accept the following program (T26225b) with -XDeepSubsumption, we need to
+deeply instantiate when inferring in checkResultTy:
+
+ f :: Int -> (forall a. a->a)
+ g :: Int -> Bool -> Bool
+
+ test b =
+ case b of
+ True -> f
+ False -> g
+
+If we don't deeply instantiate in the branches of the case expression, we will
+try to unify the type of 'f' with that of 'g', which fails. If we instead
+deeply instantiate 'f', we will fill the 'InferResult' with 'Int -> alpha -> alpha'
+which then successfully unifies with the type of 'g' when we come to fill the
+'InferResult' hole a second time for the second case branch.
+-}
checkResultTy rn_expr (tc_fun, fun_ctxt) inst_args app_res_rho (Check res_ty)
-- Unify with expected type from the context
@@ -502,8 +523,6 @@ checkResultTy rn_expr (tc_fun, fun_ctxt) inst_args app_res_rho (Check res_ty)
-- Even though both app_res_rho and res_ty are rho-types,
-- they may have nested polymorphism, so if deep subsumption
-- is on we must call tcSubType.
- -- Zonk app_res_rho first, because QL may have instantiated some
- -- delta variables to polytypes, and tcSubType doesn't expect that
do { wrap <- tcSubTypeDS rn_expr app_res_rho res_ty
; traceTc "checkResultTy 2 }" (ppr app_res_rho $$ ppr res_ty)
; return wrap } }
=====================================
compiler/GHC/Tc/Gen/Expr.hs
=====================================
@@ -1056,7 +1056,8 @@ tcSynArgA orig op sigma_ty arg_shapes res_shape thing_inside
tc_syn_arg _ (SynFun {}) _
= pprPanic "tcSynArgA hits a SynFun" (ppr orig)
tc_syn_arg res_ty (SynType the_ty) thing_inside
- = do { wrap <- tcSubType orig GenSigCtxt res_ty the_ty
+ = do { wrap <- addSubTypeCtxt res_ty the_ty $
+ tcSubType orig GenSigCtxt Nothing res_ty the_ty
; result <- thing_inside []
; return (result, wrap) }
=====================================
compiler/GHC/Tc/Gen/HsType.hs
=====================================
@@ -946,7 +946,7 @@ Terms are eagerly instantiated. This means that if you say
then `id` gets instantiated to have type alpha -> alpha. The variable
alpha is then unconstrained and regeneralized. So we may well end up with
- x = /\x. id @a
+ x = /\a. id @a
But we cannot do this in types, as we have no type-level lambda.
So, we must be careful only to instantiate at the last possible moment, when
@@ -954,9 +954,15 @@ we're sure we're never going to want the lost polymorphism again. This is done
in calls to `tcInstInvisibleTyBinders`; a particular case in point is in
`checkExpectedKind`.
+For example, suppose we have:
+ Actual: ∀ k2 k. k -> k2 -> k
+ Expected: ∀ k. k -> Type -> k
+We must very delicately instantiate just k2 to kappa, and then unify
+ (∀ k. k -> Type -> k) ~ (∀ k. k -> kappa -> k)
+
Otherwise, we are careful /not/ to instantiate. For example:
-* at a variable in `tcTyVar`
-* in `tcInferLHsTypeUnsaturated`, which is used by :kind in GHCi.
+ * at a variable in `tcTyVar`
+ * in `tcInferLHsTypeUnsaturated`, which is used by :kind in GHCi.
************************************************************************
* *
@@ -1977,6 +1983,8 @@ checkExpKind :: HsType GhcRn -> TcType -> TcKind -> ExpKind -> TcM TcType
checkExpKind rn_ty ty ki (Check ki') =
checkExpectedKind rn_ty ty ki ki'
checkExpKind _rn_ty ty ki (Infer cell) = do
+ -- NB: do not instantiate.
+ -- See Note [Do not always instantiate eagerly in types]
co <- fillInferResult ki cell
pure (ty `mkCastTy` co)
=====================================
compiler/GHC/Tc/Types/Evidence.hs
=====================================
@@ -199,28 +199,44 @@ instance Monoid HsWrapper where
mempty = WpHole
(<.>) :: HsWrapper -> HsWrapper -> HsWrapper
-WpHole <.> c = c
-c <.> WpHole = c
-c1 <.> c2 = c1 `WpCompose` c2
-
--- | Smart constructor to create a 'WpFun' 'HsWrapper'.
+WpHole <.> c = c
+c <.> WpHole = c
+WpCast c1 <.> WpCast c2 = WpCast (c1 `mkTransCo` c2)
+ -- If we can represent the HsWrapper as a cast, try to do so: this may avoid
+ -- unnecessary eta-expansion (see 'mkWpFun').
+c1 <.> c2 = c1 `WpCompose` c2
+
+-- | Smart constructor to create a 'WpFun' 'HsWrapper', which avoids introducing
+-- a lambda abstraction if the two supplied wrappers are either identities or
+-- casts.
+--
+-- PRECONDITION: either:
--
--- PRECONDITION: the "from" type of the first wrapper must have a syntactically
--- fixed RuntimeRep (see Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete).
+-- 1. both of the 'HsWrapper's are identities or casts, or
+-- 2. both the "from" and "to" types of the first wrapper have a syntactically
+-- fixed RuntimeRep (see Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete).
mkWpFun :: HsWrapper -> HsWrapper
-> Scaled TcTypeFRR -- ^ the "from" type of the first wrapper
- -- MUST have a fixed RuntimeRep
-> TcType -- ^ Either "from" type or "to" type of the second wrapper
-- (used only when the second wrapper is the identity)
-> HsWrapper
- -- NB: we can't check that the argument type has a fixed RuntimeRep with an assertion,
- -- because of [Wrinkle: Typed Template Haskell] in Note [hasFixedRuntimeRep]
- -- in GHC.Tc.Utils.Concrete.
mkWpFun WpHole WpHole _ _ = WpHole
mkWpFun WpHole (WpCast co2) (Scaled w t1) _ = WpCast (mk_wp_fun_co w (mkRepReflCo t1) co2)
mkWpFun (WpCast co1) WpHole (Scaled w _) t2 = WpCast (mk_wp_fun_co w (mkSymCo co1) (mkRepReflCo t2))
mkWpFun (WpCast co1) (WpCast co2) (Scaled w _) _ = WpCast (mk_wp_fun_co w (mkSymCo co1) co2)
-mkWpFun co1 co2 t1 _ = WpFun co1 co2 t1
+mkWpFun w_arg w_res t1 _ =
+ -- In this case, we will desugar to a lambda
+ --
+ -- \x. w_res[ e w_arg[x] ]
+ --
+ -- To satisfy Note [Representation polymorphism invariants] in GHC.Core,
+ -- it must be the case that both the lambda bound variable x and the function
+ -- argument w_arg[x] have a fixed runtime representation, i.e. that both the
+ -- "from" and "to" types of the first wrapper "w_arg" have a fixed runtime representation.
+ --
+ -- Unfortunately, we can't check this with an assertion here, because of
+ -- [Wrinkle: Typed Template Haskell] in Note [hasFixedRuntimeRep] in GHC.Tc.Utils.Concrete.
+ WpFun w_arg w_res t1
mkWpEta :: [Id] -> HsWrapper -> HsWrapper
-- (mkWpEta [x1, x2] wrap) [e]
=====================================
compiler/GHC/Tc/Types/Origin.hs
=====================================
@@ -1,9 +1,10 @@
{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE StandaloneKindSignatures #-}
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeFamilyDependencies #-}
-- | Describes the provenance of types as they flow through the type-checker.
-- The datatypes here are mainly used for error message generation.
@@ -39,7 +40,7 @@ module GHC.Tc.Types.Origin (
mkFRRUnboxedTuple, mkFRRUnboxedSum,
-- ** FixedRuntimeRep origin for rep-poly 'Id's
- RepPolyId(..), Polarity(..), Position(..),
+ RepPolyId(..), Polarity(..), Position(..), mkArgPos,
-- ** Arrow command FixedRuntimeRep origin
FRRArrowContext(..), pprFRRArrowContext,
@@ -78,7 +79,7 @@ import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Stack
import GHC.Utils.Monad
-import GHC.Utils.Misc( HasDebugCallStack )
+import GHC.Utils.Misc( HasDebugCallStack, nTimes )
import GHC.Types.Unique
import GHC.Types.Unique.Supply
@@ -1188,7 +1189,7 @@ data FixedRuntimeRepContext
-- See 'FRRArrowContext' for more details.
| FRRArrow !FRRArrowContext
- -- | A representation-polymorphic check arising from a call
+ -- | A representation-polymorphism check arising from a call
-- to 'matchExpectedFunTys' or 'matchActualFunTy'.
--
-- See 'ExpectedFunTyOrigin' for more details.
@@ -1197,6 +1198,13 @@ data FixedRuntimeRepContext
!Int
-- ^ argument position (1-indexed)
+ -- | A representation-polymorphism check arising from eta-expansion
+ -- performed as part of deep subsumption.
+ | forall p. FRRDeepSubsumption
+ { frrDSExpected :: Bool
+ , frrDSPosition :: Position p
+ }
+
-- | The description of a representation-polymorphic 'Id'.
data RepPolyId
-- | A representation-polymorphic 'PrimOp'.
@@ -1234,8 +1242,8 @@ pprFixedRuntimeRepContext (FRRRecordUpdate lbl _arg)
pprFixedRuntimeRepContext (FRRBinder binder)
= sep [ text "The binder"
, quotes (ppr binder) ]
-pprFixedRuntimeRepContext (FRRRepPolyId nm id what)
- = pprFRRRepPolyId id nm what
+pprFixedRuntimeRepContext (FRRRepPolyId nm id pos)
+ = text "The" <+> ppr pos <+> text "of" <+> pprRepPolyId id nm
pprFixedRuntimeRepContext FRRPatBind
= text "The pattern binding"
pprFixedRuntimeRepContext FRRPatSynArg
@@ -1277,6 +1285,13 @@ pprFixedRuntimeRepContext (FRRArrow arrowContext)
= pprFRRArrowContext arrowContext
pprFixedRuntimeRepContext (FRRExpectedFunTy funTyOrig arg_pos)
= pprExpectedFunTyOrigin funTyOrig arg_pos
+pprFixedRuntimeRepContext (FRRDeepSubsumption is_exp pos)
+ = hsep [ text "The", what, text "type of the"
+ , ppr (Argument pos)
+ , text "of the eta-expansion"
+ ]
+ where
+ what = if is_exp then text "expected" else text "actual"
instance Outputable FixedRuntimeRepContext where
ppr = pprFixedRuntimeRepContext
@@ -1305,34 +1320,117 @@ data ArgPos
* *
********************************************************************* -}
+{- Note [Positional information in representation-polymorphism errors]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider an invalid instantiation of the 'catch#' primop:
+
+ catch#
+ :: forall {q :: RuntimeRep} {k :: Levity} (a :: TYPE q)
+ (b :: TYPE (BoxedRep k)).
+ (State# RealWorld -> (# State# RealWorld, a #))
+ -> (b -> State# RealWorld -> (# State# RealWorld, a #))
+ -> State# RealWorld
+ -> (# State# RealWorld, a #)
+
+ boo :: forall r (a :: TYPE r). ...
+ boo = catch# @a
+
+The instantiation is invalid because we insist that the quantified RuntimeRep
+type variable 'q' be instantiated to a concrete RuntimeRep, as per
+Note [Representation-polymorphism checking built-ins] in GHC.Tc.Utils.Concrete.
+
+We report this as the following error message:
+
+ The result of the first argument of the primop ‘catch#’ does not have a fixed runtime representation.
+ Its type is: (a :: TYPE r).
+
+The positional information in this message, namely "The result of the first argument",
+is produced by using the 'Position' datatype. In this case:
+
+ pos :: Position Neg
+ pos = Result (Argument Top)
+ ppr pos = "result of the first argument"
+
+Other examples:
+
+ pos2 :: Position Neg
+ pos2 = Argument (Result (Result Top))
+ ppr pos2 = "3rd argument"
+
+ pos3 :: Position Pos
+ pos3 = Argument (Result (Argument (Result Top)))
+ ppr pos3 = "2nd argument of the 2nd argument"
+
+It's useful to keep track at the type-level whether we are in a positive or
+negative position in the type, as for primops we can usually tolerate
+representation-polymorphism in positive positions, but not in negative ones;
+for example
+
+ ($) :: forall {r} (a :: Type) (b :: TYPE r). (a -> b) -> a -> b
+
+
+This positional information is (currently) used to report representation-polymorphism
+errors in precisely the following two situations:
+
+ 1. Representation-polymorphic Ids with no binding, as described in
+ Note [Representation-polymorphic Ids with no binding] in GHC.Tc.Utils.Concrete.
+
+ This uses the 'FRRRepPolyId' constructor of 'FixedRuntimeRepContext'.
+
+ 2. When inserting eta-expansions for deep subsumption.
+ See Wrinkle [Representation-polymorphism checking during subtyping] in
+ Note [FunTy vs FunTy case in tc_sub_type_deep] in GHC.Tc.Utils.Unify.
+
+ This uses the 'FRRDeepSubsumption' constructor of 'FixedRuntimeRepContext'.
+-}
+
+-- | Are we in a positive (covariant) or negative (contravariant) position?
+--
+-- See Note [Positional information in representation-polymorphism errors].
data Polarity = Pos | Neg
+-- | Flip the 'Polarity': turn positive into negative and vice-versa.
type FlipPolarity :: Polarity -> Polarity
-type family FlipPolarity p where
+type family FlipPolarity p = r | r -> p where
FlipPolarity Pos = Neg
FlipPolarity Neg = Pos
-- | A position in which a type variable appears in a type;
-- in particular, whether it appears in a positive or a negative position.
+--
+-- See Note [Positional information in representation-polymorphism errors].
type Position :: Polarity -> Hs.Type
data Position p where
- -- | In the @i@-th argument of a function arrow
- Argument :: Int -> Position (FlipPolarity p) -> Position p
+ -- | In the argument of a function arrow
+ Argument :: Position p -> Position (FlipPolarity p)
-- | In the result of a function arrow
Result :: Position p -> Position p
-- | At the top level of a type
Top :: Position Pos
-
-pprFRRRepPolyId :: RepPolyId -> Name -> Position Neg -> SDoc
-pprFRRRepPolyId id nm (Argument i pos) =
- text "The" <+> what <+> speakNth i <+> text "argument of" <+> pprRepPolyId id nm
+deriving stock instance Show (Position p)
+instance Outputable (Position p) where
+ ppr = go 1
+ where
+ go :: Int -> Position q -> SDoc
+ go i (Argument (Result pos)) = go (i+1) (Argument pos)
+ go i (Argument pos) = speakNth i <+> text "argument" <+> aux 1 pos
+ go i (Result (Result pos)) = go i (Result pos)
+ go i (Result pos) = text "result" <+> aux i pos
+ go _ Top = text "top-level"
+
+ aux :: Int -> Position q -> SDoc
+ aux i pos = case pos of { Top -> empty; _ -> text "of the" <+> go i pos }
+
+-- | @'mkArgPos' i p@ makes the 'Position' @p@ relative to the @ith@ argument.
+--
+-- Example: @ppr (mkArgPos 3 (Result Top)) == "in the result of the 3rd argument"@.
+mkArgPos :: Int -> Position p -> Position (FlipPolarity p)
+mkArgPos i = go
where
- what = case pos of
- Top -> empty
- Result {} -> text "return type of the"
- _ -> text "nested return type inside the"
-pprFRRRepPolyId id nm (Result {}) =
- text "The result of" <+> pprRepPolyId id nm
+ go :: Position p -> Position (FlipPolarity p)
+ go Top = Argument $ nTimes (i-1) Result Top
+ go (Result p) = Result $ go p
+ go (Argument p) = Argument $ go p
pprRepPolyId :: RepPolyId -> Name -> SDoc
pprRepPolyId id nm = id_desc <+> quotes (ppr nm)
=====================================
compiler/GHC/Tc/Utils/Concrete.hs
=====================================
@@ -803,7 +803,7 @@ idConcreteTvs id
= mkNameEnv
[(tyVarName a_rep, ConcreteFRR $ FixedRuntimeRepOrigin (mkTyVarTy a)
$ FRRRepPolyId unsafeCoercePrimName RepPolyFunction
- $ Argument 1 Top)]
+ $ mkArgPos 1 Top)]
| otherwise
= idDetailsConcreteTvs $ idDetails id
=====================================
compiler/GHC/Tc/Utils/Unify.hs
=====================================
@@ -1,3 +1,4 @@
+{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE LambdaCase #-}
@@ -18,6 +19,7 @@ module GHC.Tc.Utils.Unify (
-- Full-blown subsumption
tcWrapResult, tcWrapResultO, tcWrapResultMono,
tcSubType, tcSubTypeSigma, tcSubTypePat, tcSubTypeDS,
+ addSubTypeCtxt,
tcSubTypeAmbiguity, tcSubMult,
checkConstraints, checkTvConstraints,
buildImplicationFor, buildTvImplication, emitResidualTvConstraint,
@@ -25,9 +27,10 @@ module GHC.Tc.Utils.Unify (
-- Skolemisation
DeepSubsumptionFlag(..), getDeepSubsumptionFlag, isRhoTyDS,
tcSkolemise, tcSkolemiseCompleteSig, tcSkolemiseExpectedType,
+ deeplyInstantiate,
-- Various unifications
- unifyType, unifyKind, unifyInvisibleType, unifyExpectedType,
+ unifyType, unifyKind, unifyInvisibleType,
unifyExprType, unifyTypeAndEmit, promoteTcType,
swapOverTyVars, touchabilityTest, checkTopShape, lhsPriority,
UnifyEnv(..), updUEnvLoc, setUEnvRole,
@@ -57,7 +60,7 @@ module GHC.Tc.Utils.Unify (
simpleUnifyCheck, UnifyCheckCaller(..), SimpleUnifyResult(..),
- fillInferResult,
+ fillInferResult, fillInferResultDS
) where
import GHC.Prelude
@@ -796,12 +799,14 @@ matchExpectedFunTys :: forall a.
-- Postcondition:
-- If exp_ty is Check {}, then [ExpPatType] and ExpRhoType results are all Check{}
-- If exp_ty is Infer {}, then [ExpPatType] and ExpRhoType results are all Infer{}
-matchExpectedFunTys herald _ arity (Infer inf_res) thing_inside
+matchExpectedFunTys herald _ctxt arity (Infer inf_res) thing_inside
= do { arg_tys <- mapM (new_infer_arg_ty herald) [1 .. arity]
; res_ty <- newInferExpType
; result <- thing_inside (map ExpFunPatTy arg_tys) res_ty
; arg_tys <- mapM (\(Scaled m t) -> Scaled m <$> readExpType t) arg_tys
; res_ty <- readExpType res_ty
+ -- NB: mkScaledFunTys arg_tys res_ty does not contain any foralls
+ -- (even nested ones), so no need to instantiate.
; co <- fillInferResult (mkScaledFunTys arg_tys res_ty) inf_res
; return (mkWpCastN co, result) }
@@ -1223,7 +1228,21 @@ unification variable. We discard the evidence.
-}
-
+-- | A version of 'fillInferResult' that also performs deep instantiation
+-- when deep subsumption is enabled.
+--
+-- See also Note [Instantiation of InferResult].
+fillInferResultDS :: CtOrigin -> TcRhoType -> InferResult -> TcM HsWrapper
+fillInferResultDS ct_orig rho inf_res
+ = do { massertPpr (isRhoTy rho) $
+ vcat [ text "fillInferResultDS: input type is not a rho-type"
+ , text "ty:" <+> ppr rho ]
+ ; ds_flag <- getDeepSubsumptionFlag
+ ; case ds_flag of
+ Shallow -> mkWpCastN <$> fillInferResult rho inf_res
+ Deep -> do { (inst_wrap, rho') <- deeplyInstantiate ct_orig rho
+ ; co <- fillInferResult rho' inf_res
+ ; return (mkWpCastN co <.> inst_wrap) } }
{-
************************************************************************
@@ -1290,27 +1309,34 @@ tcWrapResultO :: CtOrigin -> HsExpr GhcRn -> HsExpr GhcTc -> TcSigmaType -> ExpR
tcWrapResultO orig rn_expr expr actual_ty res_ty
= do { traceTc "tcWrapResult" (vcat [ text "Actual: " <+> ppr actual_ty
, text "Expected:" <+> ppr res_ty ])
- ; wrap <- tcSubTypeNC orig GenSigCtxt (Just $ HsExprRnThing rn_expr) actual_ty res_ty
+ ; wrap <- tcSubType orig GenSigCtxt (Just $ HsExprRnThing rn_expr) actual_ty res_ty
; return (mkHsWrap wrap expr) }
-tcWrapResultMono :: HsExpr GhcRn -> HsExpr GhcTc
- -> TcRhoType -- Actual -- a rho-type not a sigma-type
- -> ExpRhoType -- Expected
- -> TcM (HsExpr GhcTc)
--- A version of tcWrapResult to use when the actual type is a
+-- | A version of 'tcWrapResult' to use when the actual type is a
-- rho-type, so nothing to instantiate; just go straight to unify.
--- It means we don't need to pass in a CtOrigin
+-- It means we don't need to pass in a CtOrigin.
+tcWrapResultMono :: HasDebugCallStack
+ => HsExpr GhcRn -> HsExpr GhcTc
+ -> TcRhoType -- ^ Actual; a rho-type, not a sigma-type
+ -> ExpRhoType -- ^ Expected
+ -> TcM (HsExpr GhcTc)
tcWrapResultMono rn_expr expr act_ty res_ty
- = assertPpr (isRhoTy act_ty) (ppr act_ty $$ ppr rn_expr) $
- do { co <- unifyExpectedType rn_expr act_ty res_ty
+ = do { co <- tcSubTypeMono rn_expr act_ty res_ty
; return (mkHsWrapCo co expr) }
-unifyExpectedType :: HsExpr GhcRn
- -> TcRhoType -- Actual -- a rho-type not a sigma-type
- -> ExpRhoType -- Expected
- -> TcM TcCoercionN
-unifyExpectedType rn_expr act_ty exp_ty
- = case exp_ty of
+-- | A version of 'tcSubType' to use when the actual type is a rho-type,
+-- so that no instantiation is needed.
+tcSubTypeMono :: HasDebugCallStack
+ => HsExpr GhcRn
+ -> TcRhoType -- ^ Actual; a rho-type, not a sigma-type
+ -> ExpRhoType -- ^ Expected
+ -> TcM TcCoercionN
+tcSubTypeMono rn_expr act_ty exp_ty
+ = assertPpr (isDeepRhoTy act_ty)
+ (vcat [ text "Actual type is not a (deep) rho-type."
+ , text "act_ty:" <+> ppr act_ty
+ , text "rn_expr:" <+> ppr rn_expr]) $
+ case exp_ty of
Infer inf_res -> fillInferResult act_ty inf_res
Check exp_ty -> unifyType (Just $ HsExprRnThing rn_expr) act_ty exp_ty
@@ -1331,46 +1357,39 @@ tcSubTypePat _ _ (Infer inf_res) ty_expected
; return (mkWpCastN (mkSymCo co)) }
---------------
-tcSubType :: CtOrigin -> UserTypeCtxt
- -> TcSigmaType -- ^ Actual
- -> ExpRhoType -- ^ Expected
- -> TcM HsWrapper
--- Checks that 'actual' is more polymorphic than 'expected'
-tcSubType orig ctxt ty_actual ty_expected
- = addSubTypeCtxt ty_actual ty_expected $
- do { traceTc "tcSubType" (vcat [pprUserTypeCtxt ctxt, ppr ty_actual, ppr ty_expected])
- ; tcSubTypeNC orig ctxt Nothing ty_actual ty_expected }
----------------
+-- | A subtype check that performs deep subsumption.
+-- See also 'tcSubTypeMono', for when no instantiation is required.
tcSubTypeDS :: HsExpr GhcRn
-> TcRhoType -- Actual type -- a rho-type not a sigma-type
-> TcRhoType -- Expected type
-- DeepSubsumption <=> when checking, this type
-- is deeply skolemised
-> TcM HsWrapper
--- Similar signature to unifyExpectedType; does deep subsumption
-- Only one call site, in GHC.Tc.Gen.App.tcApp
tcSubTypeDS rn_expr act_rho exp_rho
- = tc_sub_type_deep (unifyExprType rn_expr) orig GenSigCtxt act_rho exp_rho
+ = tc_sub_type_deep Top (unifyExprType rn_expr) orig GenSigCtxt act_rho exp_rho
where
orig = exprCtOrigin rn_expr
---------------
-tcSubTypeNC :: CtOrigin -- ^ Used when instantiating
- -> UserTypeCtxt -- ^ Used when skolemising
- -> Maybe TypedThing -- ^ The expression that has type 'actual' (if known)
- -> TcSigmaType -- ^ Actual type
- -> ExpRhoType -- ^ Expected type
- -> TcM HsWrapper
-tcSubTypeNC inst_orig ctxt m_thing ty_actual res_ty
+
+-- | Checks that the 'actual' type is more polymorphic than the 'expected' type.
+tcSubType :: CtOrigin -- ^ Used when instantiating
+ -> UserTypeCtxt -- ^ Used when skolemising
+ -> Maybe TypedThing -- ^ The expression that has type 'actual' (if known)
+ -> TcSigmaType -- ^ Actual type
+ -> ExpRhoType -- ^ Expected type
+ -> TcM HsWrapper
+tcSubType inst_orig ctxt m_thing ty_actual res_ty
= case res_ty of
Check ty_expected -> tc_sub_type (unifyType m_thing) inst_orig ctxt
ty_actual ty_expected
Infer inf_res -> do { (wrap, rho) <- topInstantiate inst_orig ty_actual
-- See Note [Instantiation of InferResult]
- ; co <- fillInferResult rho inf_res
- ; return (mkWpCastN co <.> wrap) }
+ ; inst <- fillInferResultDS inst_orig rho inf_res
+ ; return (inst <.> wrap) }
---------------
tcSubTypeSigma :: CtOrigin -- where did the actual type arise / why are we
@@ -1388,9 +1407,9 @@ tcSubTypeAmbiguity :: UserTypeCtxt -- Where did this type arise
-> TcSigmaType -> TcSigmaType -> TcM HsWrapper
-- See Note [Ambiguity check and deep subsumption]
tcSubTypeAmbiguity ctxt ty_actual ty_expected
- = tc_sub_type_ds Shallow (unifyType Nothing)
- (AmbiguityCheckOrigin ctxt)
- ctxt ty_actual ty_expected
+ = tc_sub_type_ds Top Shallow (unifyType Nothing)
+ (AmbiguityCheckOrigin ctxt)
+ ctxt ty_actual ty_expected
---------------
addSubTypeCtxt :: TcType -> ExpType -> TcM a -> TcM a
@@ -1411,8 +1430,9 @@ addSubTypeCtxt ty_actual ty_expected thing_inside
{- Note [Instantiation of InferResult]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We now always instantiate before filling in InferResult, so that
-the result is a TcRhoType: see #17173 for discussion.
+When typechecking expressions (not types, not patterns), we always instantiate
+before filling in InferResult, so that the result is a TcRhoType.
+See #17173 for discussion.
For example:
@@ -1444,6 +1464,9 @@ For example:
There is one place where we don't want to instantiate eagerly,
namely in GHC.Tc.Module.tcRnExpr, which implements GHCi's :type
command. See Note [Implementing :type] in GHC.Tc.Module.
+
+This also means that, if DeepSubsumption is enabled, we should also instantiate
+deeply; we do this by using fillInferResultDS.
-}
---------------
@@ -1464,16 +1487,17 @@ tc_sub_type :: (TcType -> TcType -> TcM TcCoercionN) -- How to unify
----------------------
tc_sub_type unify inst_orig ctxt ty_actual ty_expected
= do { ds_flag <- getDeepSubsumptionFlag
- ; tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected }
+ ; tc_sub_type_ds Top ds_flag unify inst_orig ctxt ty_actual ty_expected }
----------------------
-tc_sub_type_ds :: DeepSubsumptionFlag
+tc_sub_type_ds :: Position p -- ^ position in the type (for error messages only)
+ -> DeepSubsumptionFlag
-> (TcType -> TcType -> TcM TcCoercionN)
-> CtOrigin -> UserTypeCtxt -> TcSigmaType
-> TcSigmaType -> TcM HsWrapper
-- tc_sub_type_ds is the main subsumption worker function
-- It takes an explicit DeepSubsumptionFlag
-tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected
+tc_sub_type_ds pos ds_flag unify inst_orig ctxt ty_actual ty_expected
| definitely_poly ty_expected -- See Note [Don't skolemise unnecessarily]
, isRhoTyDS ds_flag ty_actual
= do { traceTc "tc_sub_type (drop to equality)" $
@@ -1490,7 +1514,7 @@ tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected
; (sk_wrap, inner_wrap)
<- tcSkolemise ds_flag ctxt ty_expected $ \sk_rho ->
case ds_flag of
- Deep -> tc_sub_type_deep unify inst_orig ctxt ty_actual sk_rho
+ Deep -> tc_sub_type_deep pos unify inst_orig ctxt ty_actual sk_rho
Shallow -> tc_sub_type_shallow unify inst_orig ty_actual sk_rho
; return (sk_wrap <.> inner_wrap) }
@@ -1656,7 +1680,7 @@ The effects are in these main places:
see the call to tcDeeplySkolemise in tcSkolemiseScoped.
4. In GHC.Tc.Gen.App.tcApp we call tcSubTypeDS to match the result
- type. Without deep subsumption, unifyExpectedType would be sufficent.
+ type. Without deep subsumption, tcSubTypeMono would be sufficent.
In all these cases note that the deep skolemisation must be done /first/.
Consider (1)
@@ -1669,8 +1693,10 @@ Wrinkles:
(DS1) Note that we /always/ use shallow subsumption in the ambiguity check.
See Note [Ambiguity check and deep subsumption].
-(DS2) Deep subsumption requires deep instantiation too.
- See Note [The need for deep instantiation]
+(DS2) When doing deep subsumption, we must be careful not to needlessly
+ drop down to unification, e.g. in cases such as:
+ (Bool -> ∀ d. d->d) <= alpha beta gamma
+ See Note [FunTy vs non-FunTy case in tc_sub_type_deep].
(DS3) The interaction between deep subsumption and required foralls
(forall a -> ty) is a bit subtle. See #24696 and
@@ -1701,6 +1727,69 @@ ToDo: this eta-abstraction plays fast and loose with termination,
because it can introduce extra lambdas. Maybe add a `seq` to
fix this
+Note [FunTy vs FunTy case in tc_sub_type_deep]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The goal of tc_sub_type_deep is to produce an HsWrapper that "proves" that the
+actual type is a subtype of the expected type. The most important case is how
+we deal with function arrows. Suppose we have:
+
+ ty_actual = act_arg -> act_res
+ ty_expected = exp_arg -> exp_res
+
+To produce fun_wrap :: (act_arg -> act_res) ~> (exp_arg -> exp_res), we use
+the fact that the function arrow is contravariant in its argument type and
+covariant in its result type. Thus we recursively perform subtype checks
+on the argument types (with actual/expected switched) and the result types,
+to get:
+
+ arg_wrap :: exp_arg ~> act_arg -- NB: expected/actual have switched sides
+ res_wrap :: act_res ~> exp_res
+
+Then fun_wrap = mkWpFun arg_wrap res_wrap.
+
+Wrinkle [Representation-polymorphism checking during subtyping]
+
+ Inserting a WpFun HsWrapper amounts to impedance matching in deep subsumption
+ via eta-expansion:
+
+ f ==> \ (x :: exp_arg) -> res_wrap [ f (arg_wrap [x]) ]
+
+ As we produce a lambda, we must enforce the representation polymorphism
+ invariants described in Note [Representation polymorphism invariants] in GHC.Core.
+ That is, we must ensure that both x (the lambda binder) and (arg_wrap [x]) (the function argument)
+ have a fixed runtime representation.
+
+ Note however that desugaring mkWpFun does not always introduce a lambda: if
+ both the argument and result HsWrappers are casts, then a FunCo cast suffices,
+ in which case we should not perform representation-polymorphism checking.
+
+ This means that, in the FunTy/FunTy case of tc_sub_type_deep, we can skip
+ the representation-polymorphism checks if the produced argument and result
+ wrappers are identities or casts.
+ It is important to do so, otherwise we reject valid programs.
+
+ Here's a contrived example (there are undoubtedly more natural examples)
+ (see testsuite/tests/rep-poly/NoEtaRequired):
+
+ type Id :: k -> k
+ type family Id a where
+
+ type T :: TYPE r -> TYPE (Id r)
+ type family T a where
+
+ test :: forall r (a :: TYPE r). a :~~: T a -> ()
+ test HRefl =
+ let
+ f :: (a -> a) -> ()
+ f _ = ()
+ g :: T a -> T a
+ g = undefined
+ in f g
+
+ We don't need to eta-expand `g` to make `f g` typecheck; a cast suffices.
+ Hence we should not perform representation-polymorphism checks; they would
+ fail here.
+
Note [Setting the argument context]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider we are doing the ambiguity check for the (bogus)
@@ -1751,30 +1840,31 @@ complains.
The easiest solution was to use tcEqMult in tc_sub_type_deep, and
insist on equality. This is only in the DeepSubsumption code anyway.
-Note [The need for deep instantiation]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [FunTy vs non-FunTy case in tc_sub_type_deep]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider this, without Quick Look, but with Deep Subsumption:
f :: ∀a b c. a b c -> Int
g :: Bool -> ∀d. d -> d
-Consider the application (f g). We need to do the subsumption test
-
- (Bool -> ∀ d. d->d) <= (alpha beta gamma)
+To typecheck the application (f g), we need to do the subsumption test
-where alpha, beta, gamma are the unification variables that instantiate a,b,c,
-respectively. We must not drop down to unification, or we will reject the call.
-Rather we must deeply instantiate the LHS to get
+ (Bool -> ∀ d. d->d) <= alpha beta gamma
- (Bool -> delta -> delta) <= (alpha beta gamma)
+where alpha, beta, gamma are the unification variables that instantiate a,b,c
+(respectively). We must not drop down to unification, or we will reject the call.
+Instead, we should only unify alpha := (->), in which case we end up with the
+usual FunTy vs FunTy case of Note [FunTy vs FunTy case in tc_sub_type_deep]:
-and now we can unify to get
+ (Bool -> ∀ d. d->d) <= beta -> gamma
- alpha = (->)
- beta = Bool
- gamma = delta -> delta
+which is straightforwardly solved by beta := Bool, using covariance in the return
+type of the function arrow, and instantiating the forall before unifying with gamma.
-Hence the call to `deeplyInstantiate` in `tc_sub_type_deep`.
+The conclusion is this: when doing a deep subtype check (in tc_sub_type_deep),
+if the LHS is a FunTy and the RHS is a rho-type which is not a FunTy,
+then unify the RHS with a FunTy and continue by performing a sub-type check on
+the LHS vs the new RHS. And vice-versa (if it's the RHS that is a FunTy).
-See typecheck/should_compile/T11305 for an example of when this is important.
+See T11305 and T26225 for examples of when this is important.
Note [Deep subsumption and required foralls]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1837,12 +1927,17 @@ getDeepSubsumptionFlag :: TcM DeepSubsumptionFlag
getDeepSubsumptionFlag = do { ds <- xoptM LangExt.DeepSubsumption
; if ds then return Deep else return Shallow }
+-- | 'tc_sub_type_deep' is where the actual work happens for deep subsumption.
+--
+-- Given @ty_actual@ (a sigma-type) and @ty_expected@ (deeply skolemised, i.e.
+-- a deep rho type), it returns an 'HsWrapper' @wrap :: ty_actual ~> ty_expected@.
tc_sub_type_deep :: HasDebugCallStack
- => (TcType -> TcType -> TcM TcCoercionN) -- How to unify
- -> CtOrigin -- Used when instantiating
- -> UserTypeCtxt -- Used when skolemising
- -> TcSigmaType -- Actual; a sigma-type
- -> TcRhoType -- Expected; deeply skolemised
+ => Position p -- ^ Position in the type (for error messages only)
+ -> (TcType -> TcType -> TcM TcCoercionN) -- ^ How to unify
+ -> CtOrigin -- ^ Used when instantiating
+ -> UserTypeCtxt -- ^ Used when skolemising
+ -> TcSigmaType -- ^ Actual; a sigma-type
+ -> TcRhoType -- ^ Expected; deeply skolemised
-> TcM HsWrapper
-- If wrap = tc_sub_type_deep t1 t2
@@ -1850,63 +1945,161 @@ tc_sub_type_deep :: HasDebugCallStack
-- Here is where the work actually happens!
-- Precondition: ty_expected is deeply skolemised
-tc_sub_type_deep unify inst_orig ctxt ty_actual ty_expected
+tc_sub_type_deep pos unify inst_orig ctxt ty_actual ty_expected
= assertPpr (isDeepRhoTy ty_expected) (ppr ty_expected) $
do { traceTc "tc_sub_type_deep" $
vcat [ text "ty_actual =" <+> ppr ty_actual
, text "ty_expected =" <+> ppr ty_expected ]
; go ty_actual ty_expected }
where
- -- NB: 'go' is not recursive, except for doing coreView
- go ty_a ty_e | Just ty_a' <- coreView ty_a = go ty_a' ty_e
- | Just ty_e' <- coreView ty_e = go ty_a ty_e'
- go (TyVarTy tv_a) ty_e
- = do { lookup_res <- isFilledMetaTyVar_maybe tv_a
+ -- 'unwrap' removes top-level type synonyms & looks through filled meta-tyvars
+ unwrap :: TcType -> TcM TcType
+ unwrap ty
+ | Just ty' <- coreView ty
+ = unwrap ty'
+ unwrap ty@(TyVarTy tv)
+ = do { lookup_res <- isFilledMetaTyVar_maybe tv
; case lookup_res of
- Just ty_a' ->
- do { traceTc "tc_sub_type_deep following filled meta-tyvar:"
- (ppr tv_a <+> text "-->" <+> ppr ty_a')
- ; tc_sub_type_deep unify inst_orig ctxt ty_a' ty_e }
- Nothing -> just_unify ty_actual ty_expected }
-
- go ty_a@(FunTy { ft_af = af1, ft_mult = act_mult, ft_arg = act_arg, ft_res = act_res })
- ty_e@(FunTy { ft_af = af2, ft_mult = exp_mult, ft_arg = exp_arg, ft_res = exp_res })
- | isVisibleFunArg af1, isVisibleFunArg af2
- = if (isTauTy ty_a && isTauTy ty_e) -- Short cut common case to avoid
- then just_unify ty_actual ty_expected -- unnecessary eta expansion
- else
- -- This is where we do the co/contra thing, and generate a WpFun, which in turn
- -- causes eta-expansion, which we don't like; hence encouraging NoDeepSubsumption
- do { arg_wrap <- tc_sub_type_ds Deep unify given_orig GenSigCtxt exp_arg act_arg
- -- GenSigCtxt: See Note [Setting the argument context]
- ; res_wrap <- tc_sub_type_deep unify inst_orig ctxt act_res exp_res
- ; tcEqMult inst_orig act_mult exp_mult
- -- See Note [Multiplicity in deep subsumption]
- ; return (mkWpFun arg_wrap res_wrap (Scaled exp_mult exp_arg) exp_res) }
- -- arg_wrap :: exp_arg ~> act_arg
- -- res_wrap :: act-res ~> exp_res
- where
- given_orig = GivenOrigin (SigSkol GenSigCtxt exp_arg [])
-
- go ty_a ty_e
+ Just ty' -> unwrap ty'
+ Nothing -> return ty }
+ unwrap ty = return ty
+
+ go, go1 :: TcType -> TcType -> TcM HsWrapper
+ go ty_a ty_e =
+ do { ty_a' <- unwrap ty_a
+ ; ty_e' <- unwrap ty_e
+ ; go1 ty_a' ty_e' }
+
+ -- If ty_actual is not a rho-type, instantiate it first; otherwise
+ -- unification has no chance of succeeding.
+ go1 ty_a ty_e
| let (tvs, theta, _) = tcSplitSigmaTy ty_a
, not (null tvs && null theta)
= do { (in_wrap, in_rho) <- topInstantiate inst_orig ty_a
- ; body_wrap <- tc_sub_type_deep unify inst_orig ctxt in_rho ty_e
+ ; body_wrap <- go in_rho ty_e
; return (body_wrap <.> in_wrap) }
- | otherwise -- Revert to unification
- = do { -- It's still possible that ty_actual has nested foralls. Instantiate
- -- these, as there's no way unification will succeed with them in.
- -- See Note [The need for deep instantiation]
- (inst_wrap, rho_a) <- deeplyInstantiate inst_orig ty_actual
- ; unify_wrap <- just_unify rho_a ty_expected
- ; return (unify_wrap <.> inst_wrap) }
+ -- Main case: FunTy vs FunTy. go_fun does the work.
+ go1 (FunTy { ft_af = af1, ft_mult = act_mult, ft_arg = act_arg, ft_res = act_res })
+ (FunTy { ft_af = af2, ft_mult = exp_mult, ft_arg = exp_arg, ft_res = exp_res })
+ | isVisibleFunArg af1
+ , isVisibleFunArg af2
+ = go_fun af1 act_mult act_arg act_res
+ af2 exp_mult exp_arg exp_res
+
+ -- See Note [FunTy vs non-FunTy case in tc_sub_type_deep]
+ go1 (FunTy { ft_af = af1, ft_mult = act_mult, ft_arg = act_arg, ft_res = act_res }) ty_e
+ | isVisibleFunArg af1
+ = do { exp_mult <- newMultiplicityVar
+ ; exp_arg <- newOpenFlexiTyVarTy -- NB: no FRR check needed; we might not need to eta-expand
+ ; exp_res <- newOpenFlexiTyVarTy
+ ; let exp_funTy = FunTy { ft_af = af1, ft_mult = exp_mult, ft_arg = exp_arg, ft_res = exp_res }
+ ; unify_wrap <- just_unify exp_funTy ty_e
+ ; fun_wrap <- go_fun af1 act_mult act_arg act_res af1 exp_mult exp_arg exp_res
+ ; return $ unify_wrap <.> fun_wrap
+ -- unify_wrap :: exp_funTy ~> ty_e
+ -- fun_wrap :: ty_a ~> exp_funTy
+ }
+ go1 ty_a (FunTy { ft_af = af2, ft_mult = exp_mult, ft_arg = exp_arg, ft_res = exp_res })
+ | isVisibleFunArg af2
+ = do { act_mult <- newMultiplicityVar
+ ; act_arg <- newOpenFlexiTyVarTy -- NB: no FRR check needed; we might not need to eta-expand
+ ; act_res <- newOpenFlexiTyVarTy
+ ; let act_funTy = FunTy { ft_af = af2, ft_mult = act_mult, ft_arg = act_arg, ft_res = act_res }
+
+ ; unify_wrap <- just_unify ty_a act_funTy
+ ; fun_wrap <- go_fun af2 act_mult act_arg act_res af2 exp_mult exp_arg exp_res
+ ; return $ fun_wrap <.> unify_wrap
+ -- unify_wrap :: ty_a ~> act_funTy
+ -- fun_wrap :: act_funTy ~> ty_e
+ }
+
+ -- Otherwise, revert to unification.
+ go1 ty_a ty_e = just_unify ty_a ty_e
just_unify ty_a ty_e = do { cow <- unify ty_a ty_e
; return (mkWpCastN cow) }
+ -- FunTy/FunTy case: this is where we insert any necessary eta-expansions.
+ go_fun :: FunTyFlag -> Mult -> TcType -> TcType -- actual FunTy
+ -> FunTyFlag -> Mult -> TcType -> TcType -- expected FunTy
+ -> TcM HsWrapper
+ go_fun act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res
+ -- See Note [FunTy vs FunTy case in tc_sub_type_deep]
+ = do { arg_wrap <- tc_sub_type_ds (Argument pos) Deep unify given_orig GenSigCtxt exp_arg act_arg
+ -- GenSigCtxt: See Note [Setting the argument context]
+ ; res_wrap <- tc_sub_type_deep (Result pos) unify inst_orig ctxt act_res exp_res
+
+ -- See Note [Multiplicity in deep subsumption]
+ ; tcEqMult inst_orig act_mult exp_mult
+
+ ; mkWpFun_FRR pos
+ act_af act_mult act_arg act_res
+ exp_af exp_mult exp_arg exp_res
+ arg_wrap res_wrap
+ }
+ where
+ given_orig = GivenOrigin (SigSkol GenSigCtxt exp_arg [])
+
+-- | Like 'mkWpFun', except that it performs representation-polymorphism
+-- checks on the argument type.
+mkWpFun_FRR
+ :: Position p
+ -> FunTyFlag -> Type -> TcType -> Type -- actual FunTy
+ -> FunTyFlag -> Type -> TcType -> Type -- expected FunTy
+ -> HsWrapper -- ^ exp_arg ~> act_arg
+ -> HsWrapper -- ^ act_res ~> exp_res
+ -> TcM HsWrapper -- ^ act_funTy ~> exp_funTy
+mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res arg_wrap res_wrap
+ | needs_eta
+ -- See Wrinkle [Representation-polymorphism checking during subtyping]
+ = do { (exp_arg_co, exp_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption True pos) exp_arg
+ ; (act_arg_co, _act_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption False pos) act_arg
+ ; let
+ exp_arg_fun_co =
+ mkFunCo Nominal exp_af
+ (mkReflCo Nominal exp_mult)
+ (mkSymCo exp_arg_co)
+ (mkReflCo Nominal exp_res)
+ act_arg_fun_co =
+ mkFunCo Nominal act_af
+ (mkReflCo Nominal act_mult)
+ act_arg_co
+ (mkReflCo Nominal act_res)
+ arg_wrap_frr =
+ mkWpCastN (mkSymCo exp_arg_co) <.> arg_wrap <.> mkWpCastN act_arg_co
+ -- exp_arg_co :: exp_arg ~> exp_arg_frr
+ -- act_arg_co :: act_arg ~> act_arg_frr
+ -- arg_wrap :: exp_arg ~> act_arg
+ -- arg_wrap_frr :: exp_arg_frr ~> act_arg_frr
+
+ -- NB: because of the needs_eta guard, we know that mkWpFun will
+ -- return (WpFun ...); so we might as well just use the WpFun constructor.
+ ; return $
+ mkWpCastN exp_arg_fun_co
+ <.>
+ WpFun arg_wrap_frr res_wrap (Scaled exp_mult exp_arg_frr)
+ <.>
+ mkWpCastN act_arg_fun_co }
+ | otherwise
+ = return $
+ mkWpFun arg_wrap res_wrap (Scaled exp_mult exp_arg) exp_res
+ -- NB: because of 'needs_eta', this will never actually be a WpFun.
+ -- mkWpFun will turn it into a WpHole or WpCast, which is why
+ -- we can skip the hasFixedRuntimeRep checks in this case.
+ -- See Wrinkle [Representation-polymorphism checking during subtyping]
+ where
+ needs_eta :: Bool
+ needs_eta =
+ not (hole_or_cast arg_wrap)
+ ||
+ not (hole_or_cast res_wrap)
+ hole_or_cast :: HsWrapper -> Bool
+ hole_or_cast WpHole = True
+ hole_or_cast (WpCast {}) = True
+ hole_or_cast _ = False
+
-----------------------
deeplySkolemise :: SkolemInfo -> TcSigmaType
-> TcM ( HsWrapper
=====================================
compiler/GHC/Types/Id/Make.hs
=====================================
@@ -1950,7 +1950,7 @@ seqId = pcRepPolyId seqName ty concs info
Case (Var x) x openBetaTy [Alt DEFAULT [] (Var y)]
concs = mkRepPolyIdConcreteTyVars
- [ ((openBetaTy, Argument 2 Top), runtimeRep2TyVar)]
+ [ ((openBetaTy, mkArgPos 2 Top), runtimeRep2TyVar)]
arity = 2
@@ -2009,7 +2009,7 @@ oneShotId = pcRepPolyId oneShotName ty concs info
arity = 2
concs = mkRepPolyIdConcreteTyVars
- [((openAlphaTy, Argument 2 Top), runtimeRep1TyVar)]
+ [((openAlphaTy, mkArgPos 2 Top), runtimeRep1TyVar)]
----------------------------------------------------------------------
{- Note [Wired-in Ids for rebindable syntax]
@@ -2054,7 +2054,7 @@ leftSectionId = pcRepPolyId leftSectionName ty concs info
arity = 2
concs = mkRepPolyIdConcreteTyVars
- [((openAlphaTy, Argument 2 Top), runtimeRep1TyVar)]
+ [((openAlphaTy, mkArgPos 2 Top), runtimeRep1TyVar)]
-- See Note [Left and right sections] in GHC.Rename.Expr
-- See Note [Wired-in Ids for rebindable syntax]
@@ -2088,8 +2088,8 @@ rightSectionId = pcRepPolyId rightSectionName ty concs info
concs =
mkRepPolyIdConcreteTyVars
- [ ((openAlphaTy, Argument 3 Top), runtimeRep1TyVar)
- , ((openBetaTy , Argument 2 Top), runtimeRep2TyVar)]
+ [ ((openAlphaTy, mkArgPos 3 Top), runtimeRep1TyVar)
+ , ((openBetaTy , mkArgPos 2 Top), runtimeRep2TyVar)]
--------------------------------------------------------------------------------
@@ -2119,7 +2119,7 @@ coerceId = pcRepPolyId coerceName ty concs info
[Alt (DataAlt coercibleDataCon) [eq] (Cast (Var x) (mkCoVarCo eq))]
concs = mkRepPolyIdConcreteTyVars
- [((mkTyVarTy av, Argument 1 Top), rv)]
+ [((mkTyVarTy av, mkArgPos 1 Top), rv)]
{-
Note [seqId magic]
=====================================
testsuite/tests/corelint/LintEtaExpand.stderr
=====================================
@@ -15,7 +15,7 @@ in coerce BAD 1
CvSubst = []>
in coerce BAD 2
<no location info>: warning:
- • The return type of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
+ • The result of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
a :: TYPE q
Substitution: <InScope = {a q}
IdSubst = []
@@ -23,7 +23,7 @@ in coerce BAD 2
CvSubst = []>
in catch# BAD 1
<no location info>: warning:
- • The return type of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
+ • The result of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
‘q’ is not concrete.
Substitution: <InScope = {a q}
IdSubst = []
=====================================
testsuite/tests/indexed-types/should_fail/T5439.stderr
=====================================
@@ -1,16 +1,12 @@
-
-T5439.hs:83:33: error: [GHC-83865]
- • Couldn't match expected type: Attempt (HElemOf rs)
- with actual type: Attempt (HHead (HDrop n0 l0))
- -> Attempt (HElemOf l0)
- • Probable cause: ‘($)’ is applied to too few arguments
- In the second argument of ‘($)’, namely
- ‘inj $ Failure (e :: SomeException)’
+T5439.hs:83:28: error: [GHC-83865]
+ • Couldn't match type: Attempt (HElemOf rs)
+ with: Attempt (HHead (HDrop n0 l0)) -> Attempt (HElemOf l0)
+ Expected: f (Attempt (HHead (HDrop n0 l0)) -> Attempt (HElemOf l0))
+ Actual: f (Attempt (WaitOpResult (WaitOps rs)))
+ • In the first argument of ‘complete’, namely ‘ev’
+ In the first argument of ‘($)’, namely ‘complete ev’
In a stmt of a 'do' block:
c <- complete ev $ inj $ Failure (e :: SomeException)
- In the expression:
- do c <- complete ev $ inj $ Failure (e :: SomeException)
- return $ c || not first
• Relevant bindings include
register :: Bool -> Peano n -> WaitOps (HDrop n rs) -> IO Bool
(bound at T5439.hs:65:9)
@@ -30,3 +26,4 @@ T5439.hs:83:39: error: [GHC-83865]
‘inj $ Failure (e :: SomeException)’
In a stmt of a 'do' block:
c <- complete ev $ inj $ Failure (e :: SomeException)
+
=====================================
testsuite/tests/partial-sigs/should_compile/T10403.stderr
=====================================
@@ -1,22 +1,21 @@
-
T10403.hs:16:7: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
• Found extra-constraints wildcard standing for ‘Functor f’
Where: ‘f’ is a rigid type variable bound by
- the inferred type of h1 :: Functor f => (a1 -> a2) -> f a1 -> H f
+ the inferred type of h1 :: Functor f => (t -> b) -> f t -> H f
at T10403.hs:18:1-41
• In the type signature: h1 :: _ => _
T10403.hs:16:12: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
- • Found type wildcard ‘_’ standing for ‘(a1 -> a2) -> f a1 -> H f’
- Where: ‘a2’, ‘a1’, ‘f’ are rigid type variables bound by
- the inferred type of h1 :: Functor f => (a1 -> a2) -> f a1 -> H f
+ • Found type wildcard ‘_’ standing for ‘(t -> b) -> f t -> H f’
+ Where: ‘b’, ‘t’, ‘f’ are rigid type variables bound by
+ the inferred type of h1 :: Functor f => (t -> b) -> f t -> H f
at T10403.hs:18:1-41
• In the type signature: h1 :: _ => _
T10403.hs:20:7: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
- • Found type wildcard ‘_’ standing for ‘(a1 -> a2) -> f a1 -> H f’
- Where: ‘a2’, ‘a1’, ‘f’ are rigid type variables bound by
- the inferred type of h2 :: (a1 -> a2) -> f a1 -> H f
+ • Found type wildcard ‘_’ standing for ‘(t -> b) -> f t -> H f’
+ Where: ‘b’, ‘t’, ‘f’ are rigid type variables bound by
+ the inferred type of h2 :: (t -> b) -> f t -> H f
at T10403.hs:23:1-41
• In the type signature: h2 :: _
@@ -24,7 +23,8 @@ T10403.hs:23:15: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)]
• No instance for ‘Functor f’ arising from a use of ‘fmap’
Possible fix:
add (Functor f) to the context of
- the inferred type of h2 :: (a1 -> a2) -> f a1 -> H f
+ the inferred type of h2 :: (t -> b) -> f t -> H f
• In the second argument of ‘(.)’, namely ‘fmap (const ())’
In the expression: (H . fmap (const ())) (fmap f b)
In an equation for ‘h2’: h2 f b = (H . fmap (const ())) (fmap f b)
+
=====================================
testsuite/tests/partial-sigs/should_fail/T10615.stderr
=====================================
@@ -1,39 +1,34 @@
-
T10615.hs:5:7: error: [GHC-88464]
- • Found type wildcard ‘_’ standing for ‘w’
- Where: ‘w’ is a rigid type variable bound by
- the inferred type of f1 :: w -> f
+ • Found type wildcard ‘_’ standing for ‘t’
+ Where: ‘t’ is a rigid type variable bound by
+ the inferred type of f1 :: t -> f
at T10615.hs:6:1-10
To use the inferred type, enable PartialTypeSignatures
• In the type signature: f1 :: _ -> f
T10615.hs:6:6: error: [GHC-25897]
- • Couldn't match type ‘f’ with ‘b1 -> w’
- Expected: w -> f
- Actual: w -> b1 -> w
+ • Couldn't match expected type ‘f’ with actual type ‘b1 -> t’
‘f’ is a rigid type variable bound by
- the inferred type of f1 :: w -> f
+ the inferred type of f1 :: t -> f
at T10615.hs:5:1-12
• In the expression: const
In an equation for ‘f1’: f1 = const
- • Relevant bindings include f1 :: w -> f (bound at T10615.hs:6:1)
+ • Relevant bindings include f1 :: t -> f (bound at T10615.hs:6:1)
T10615.hs:8:7: error: [GHC-88464]
- • Found type wildcard ‘_’ standing for ‘w’
- Where: ‘w’ is a rigid type variable bound by
- the inferred type of f2 :: w -> _f
+ • Found type wildcard ‘_’ standing for ‘t’
+ Where: ‘t’ is a rigid type variable bound by
+ the inferred type of f2 :: t -> _f
at T10615.hs:9:1-10
To use the inferred type, enable PartialTypeSignatures
• In the type signature: f2 :: _ -> _f
T10615.hs:9:6: error: [GHC-25897]
- • Couldn't match type ‘_f’ with ‘b0 -> w’
- Expected: w -> _f
- Actual: w -> b0 -> w
+ • Couldn't match expected type ‘_f’ with actual type ‘b0 -> t’
‘_f’ is a rigid type variable bound by
- the inferred type of f2 :: w -> _f
+ the inferred type of f2 :: t -> _f
at T10615.hs:8:1-13
• In the expression: const
In an equation for ‘f2’: f2 = const
- • Relevant bindings include f2 :: w -> _f (bound at T10615.hs:9:1)
+ • Relevant bindings include f2 :: t -> _f (bound at T10615.hs:9:1)
=====================================
testsuite/tests/rep-poly/NoEtaRequired.hs
=====================================
@@ -0,0 +1,31 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE DataKinds, TypeFamilies, PolyKinds, StandaloneKindSignatures #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module NoEtaRequired where
+
+import Data.Proxy
+import Data.Type.Equality ( (:~~:)(..) )
+import GHC.Exts ( TYPE, RuntimeRep(..) )
+
+type Id :: k -> k
+type family Id a where
+
+type T :: TYPE r -> TYPE (Id r)
+type family T a where
+
+test :: forall r (a :: TYPE r). a :~~: T a -> ()
+test HRefl =
+ let
+ f :: (a -> a) -> ()
+ f _ = ()
+ g :: T a -> T a
+ g = undefined
+ in f g
+-- This test makes sure we DO NOT eta-expand 'g' to '\ x -> g x' when trying
+-- to make 'f g' typecheck. We CANNOT eta-expand here, as the binder 'x' would
+-- not have a fixed runtime representation.
+
=====================================
testsuite/tests/rep-poly/T21906.stderr
=====================================
@@ -1,5 +1,5 @@
T21906.hs:14:17: error: [GHC-55287]
- • The return type of the third argument of the primop ‘keepAlive#’
+ • The result of the third argument of the primop ‘keepAlive#’
does not have a fixed runtime representation.
Its type is:
b1 :: TYPE r1
@@ -12,7 +12,7 @@ T21906.hs:14:17: error: [GHC-55287]
In an equation for ‘test1’: test1 val s f = keepAlive# val s f
T21906.hs:21:25: error: [GHC-55287]
- • The return type of the first argument of the primop ‘catch#’
+ • The result of the first argument of the primop ‘catch#’
does not have a fixed runtime representation.
Its type is:
a1 :: TYPE q1
@@ -26,7 +26,7 @@ T21906.hs:21:25: error: [GHC-55287]
test2 action handle s = catch# action handle s
T21906.hs:30:17: error: [GHC-55287]
- • The nested return type inside the second argument of the primop ‘control0#’
+ • The result of the first argument of the first argument of the second argument of the primop ‘control0#’
does not have a fixed runtime representation.
Its type is:
b0 :: TYPE r0
@@ -39,7 +39,7 @@ T21906.hs:30:17: error: [GHC-55287]
In an equation for ‘test3’: test3 tag f s = control0# tag f s
T21906.hs:35:19: error: [GHC-55287]
- • The return type of the first argument of the primop ‘fork#’
+ • The result of the first argument of the primop ‘fork#’
does not have a fixed runtime representation.
Its type is:
a0 :: TYPE q0
=====================================
testsuite/tests/rep-poly/all.T
=====================================
@@ -112,6 +112,7 @@ test('RepPolyWrappedVar', normal, compile_fail, [''])
test('RepPolyWrappedVar2', [js_skip], compile, [''])
test('UnliftedNewtypesCoerceFail', normal, compile_fail, [''])
test('UnliftedNewtypesLevityBinder', normal, compile_fail, [''])
+test('NoEtaRequired', normal, compile, [''])
###############################################################################
## The following tests require rewriting in RuntimeReps, ##
=====================================
testsuite/tests/typecheck/should_compile/T26225.hs
=====================================
@@ -0,0 +1,78 @@
+{-# LANGUAGE DeepSubsumption #-}
+{-# LANGUAGE NamedWildCards #-}
+{-# LANGUAGE PartialTypeSignatures #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
+
+module T26225 where
+
+-- Recall: ty1 is a subtype of ty2, written ty1 ⊑ ty2,
+-- if we can use ty1 wherever ty2 is expected.
+-- Can also read as "ty1 is more polymorphic than ty2".
+-- Example: ∀ a. a -> a ⊑ Int -> Int, meaning that we can pass
+-- the identity function where one is expecting a function of type Int -> Int.
+
+-- Int -> (∀ a. a -> a) ⊑ α[tau]
+-- Accepted by GHC.
+ex0 :: ()
+ex0 =
+ let
+ f :: Int -> (∀ a. a -> a)
+ f _ = id
+ g :: _α -> ()
+ g _ = ()
+ in g f
+
+-- ((∀ a. a->a) -> Int) -> Bool ⊑ α[tau]
+-- Rejected by GHC up to and including 9.14.
+ex1' :: ()
+ex1' =
+ let
+ f :: ((∀ a. a -> a) -> Int) -> Bool
+ f _ = False
+ g :: _α -> ()
+ g _ = ()
+ in g f
+ -- Couldn't match expected type ‘α’ with actual type ‘((∀ a. a -> a) -> Int) -> Bool’
+
+-- ((∀ a. a->a) -> Int) -> Bool ⊑ β[tau] Bool
+-- Rejected by GHC up to and including 9.14.
+ex2' :: ()
+ex2' =
+ let
+ f :: ((∀ a. a -> a) -> Int) -> Bool
+ f _ = False
+ g :: _β Bool -> ()
+ g _ = ()
+ in g f
+ -- Couldn't match expected type ‘β’ with actual type ‘(->) ((∀ a. a -> a) -> Int)’
+
+-- ex3 :: β[tau] Bool ⊑ (∀ a. a->a) -> Bool
+-- Rejected by GHC up to and including 9.14.
+ex3 :: ()
+ex3 =
+ let
+ f :: _β Bool
+ f = undefined
+ g :: ((∀ a. a -> a) -> Bool) -> ()
+ g _ = ()
+ in g f
+ -- Couldn't match expected type ‘β’ with actual type ‘(->) (∀ a. a -> a)’
+
+-- ex3' :: F Int Bool ⊑ (∀ a. a->a) -> Bool, where F Int = (->) (Int -> Int)
+-- Rejected by GHC up to and including 9.14.
+ex3' :: ()
+ex3' =
+ let
+ f :: F Int Bool
+ f _ = False
+ g :: ((∀ a. a -> a) -> Bool) -> ()
+ g _ = ()
+ in g f
+ -- • Couldn't match type: Int -> Int
+ -- with: ∀ a. a -> a
+ -- Expected: (∀ a. a -> a) -> Bool
+ -- Actual: F Int Bool
+type family F a where { F Int = (->) (Int -> Int) }
=====================================
testsuite/tests/typecheck/should_compile/T26225b.hs
=====================================
@@ -0,0 +1,21 @@
+{-# LANGUAGE DeepSubsumption #-}
+{-# LANGUAGE RankNTypes #-}
+
+module T26225b where
+
+f :: Int -> (forall a. a->a)
+f _ x = x
+g :: Int -> Bool -> Bool
+g _ x = x
+
+test3 b =
+ case b of
+ True -> f
+ False -> g
+test3' b =
+ case b of
+ True -> g
+ False -> f
+-- Both of these currently error with:
+-- * Couldn't match type: forall a. a -> a
+-- with: Bool -> Bool
=====================================
testsuite/tests/typecheck/should_compile/all.T
=====================================
@@ -861,6 +861,8 @@ test('DeepSubsumption06', normal, compile, ['-XHaskell98'])
test('DeepSubsumption07', normal, compile, ['-XHaskell2010'])
test('DeepSubsumption08', normal, compile, [''])
test('DeepSubsumption09', normal, compile, [''])
+test('T26225', normal, compile, [''])
+test('T26225b', normal, compile, [''])
test('T21765', normal, compile, [''])
test('T21951a', normal, compile, ['-Wredundant-strictness-flags'])
test('T21951b', normal, compile, ['-Wredundant-strictness-flags'])
=====================================
testsuite/tests/typecheck/should_fail/T12563.stderr deleted
=====================================
@@ -1,15 +0,0 @@
-
-T12563.hs:8:15: error: [GHC-91028]
- • Couldn't match expected type ‘(forall a. f a) -> f r’
- with actual type ‘p’
- Cannot equate type variable ‘p’
- with a type involving polytypes: (forall a. f a) -> f r
- ‘p’ is a rigid type variable bound by
- the inferred type of x :: p -> f r
- at T12563.hs:8:1-15
- • In the first argument of ‘foo’, namely ‘g’
- In the expression: foo g
- In the expression: \ g -> foo g
- • Relevant bindings include
- g :: p (bound at T12563.hs:8:6)
- x :: p -> f r (bound at T12563.hs:8:1)
=====================================
testsuite/tests/typecheck/should_fail/T14618.stderr
=====================================
@@ -1,4 +1,3 @@
-
T14618.hs:7:14: error: [GHC-25897]
• Couldn't match expected type ‘b’ with actual type ‘a’
‘a’ is a rigid type variable bound by
@@ -19,3 +18,4 @@ T14618.hs:7:14: error: [GHC-25897]
f' = f
• Relevant bindings include
safeCoerce :: a -> b (bound at T14618.hs:7:1)
+
=====================================
testsuite/tests/typecheck/should_fail/T6022.stderr
=====================================
@@ -1,7 +1,7 @@
-
T6022.hs:4:1: error: [GHC-80003]
- • Non type-variable argument in the constraint: Eq ([a] -> a)
+ • Non type-variable argument in the constraint: Eq ([t] -> t)
• When checking the inferred type
- f :: forall {a}. Eq ([a] -> a) => ([a] -> a) -> Bool
+ f :: forall {t}. Eq ([t] -> t) => ([t] -> t) -> Bool
Suggested fix:
Perhaps you intended to use the ‘FlexibleContexts’ extension
+
=====================================
testsuite/tests/typecheck/should_fail/T8883.stderr
=====================================
@@ -1,9 +1,9 @@
-
T8883.hs:21:1: error: [GHC-80003]
- • Non type-variable argument in the constraint: Functor (PF a)
+ • Non type-variable argument in the constraint: Functor (PF t)
• When checking the inferred type
- fold :: forall {a} {b}.
- (Functor (PF a), Regular a) =>
- (PF a b -> b) -> a -> b
+ fold :: forall {t} {b}.
+ (Functor (PF t), Regular t) =>
+ (PF t b -> b) -> t -> b
Suggested fix:
Perhaps you intended to use the ‘FlexibleContexts’ extension
+
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -432,7 +432,7 @@ test('T12124', normal, compile_fail, [''])
test('T12430', normal, compile_fail, [''])
test('T12589', normal, compile_fail, [''])
test('T12529', normal, compile_fail, [''])
-test('T12563', normal, compile_fail, [''])
+test('T12563', normal, compile, ['']) # Turns out we can accept this one after all!
test('T12648', normal, compile_fail, [''])
test('T12729', normal, compile_fail, [''])
test('T12785b', normal, compile_fail, [''])
=====================================
testsuite/tests/typecheck/should_fail/tcfail140.stderr
=====================================
@@ -1,4 +1,3 @@
-
tcfail140.hs:11:7: error: [GHC-83865]
• Couldn't match expected type ‘t1 -> t’ with actual type ‘Int’
• The function ‘f’ is applied to two visible arguments,
@@ -17,13 +16,13 @@ tcfail140.hs:13:10: error: [GHC-83865]
rot :: p -> t (bound at tcfail140.hs:13:1)
tcfail140.hs:15:15: error: [GHC-83865]
- • Couldn't match expected type ‘a -> b’ with actual type ‘Int’
+ • Couldn't match expected type ‘t -> b’ with actual type ‘Int’
• In the first argument of ‘map’, namely ‘(3 `f`)’
In the expression: map (3 `f`) xs
In an equation for ‘bot’: bot xs = map (3 `f`) xs
• Relevant bindings include
- xs :: [a] (bound at tcfail140.hs:15:5)
- bot :: [a] -> [b] (bound at tcfail140.hs:15:1)
+ xs :: [t] (bound at tcfail140.hs:15:5)
+ bot :: [t] -> [b] (bound at tcfail140.hs:15:1)
tcfail140.hs:17:8: error: [GHC-27346]
• The data constructor ‘Just’ should have 1 argument, but has been given none
@@ -36,3 +35,4 @@ tcfail140.hs:20:1: error: [GHC-83865]
• Couldn't match expected type ‘Int’ with actual type ‘t0 -> Bool’
• The equation for ‘g’ has two visible arguments,
but its type ‘Int -> Int’ has only one
+
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/56b32c5a2d5d7cad89a12f4d74dc940…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/56b32c5a2d5d7cad89a12f4d74dc940…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
34fc50c1 by Ben Gamari at 2025-08-11T13:36:25-04:00
Kill IOPort#
This type is unnecessary, having been superceded by `MVar` and a rework
of WinIO's blocking logic.
See #20947.
See https://github.com/haskell/core-libraries-committee/issues/213.
- - - - -
38 changed files:
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Prim.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/GHC/Exts.hs
- − libraries/base/src/GHC/IOPort.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/Thread.hs
- libraries/ghc-internal/src/GHC/Internal/Exts.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Buffer.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Windows/Handle.hsc
- − libraries/ghc-internal/src/GHC/Internal/IOPort.hs
- libraries/ghc-internal/src/GHC/Internal/Prim/PtrEq.hs
- libraries/ghc-prim/changelog.md
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/RtsSymbols.c
- rts/external-symbols.list.in
- rts/include/stg/MiscClosures.h
- rts/include/stg/SMP.h
- rts/win32/AsyncWinIO.c
- rts/win32/libHSghc-internal.def
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/primops/should_run/UnliftedIOPort.hs
- testsuite/tests/primops/should_run/all.T
- utils/genprimopcode/Main.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/34fc50c13b47842e0d1f9879285a68b…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/34fc50c13b47842e0d1f9879285a68b…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/romes/26202] Deleted 1 commit: Update DOCKER_REV to !14579
by Rodrigo Mesquita (@alt-romes) 12 Aug '25
by Rodrigo Mesquita (@alt-romes) 12 Aug '25
12 Aug '25
Rodrigo Mesquita pushed to branch wip/romes/26202 at Glasgow Haskell Compiler / GHC
WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below.
Deleted commits:
15d7862e by Rodrigo Mesquita at 2025-08-12T13:29:22+00:00
Update DOCKER_REV to !14579
- - - - -
1 changed file:
- .gitlab-ci.yml
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -2,7 +2,7 @@ variables:
GIT_SSL_NO_VERIFY: "1"
# Commit of ghc/ci-images repository from which to pull Docker images
- DOCKER_REV: 6e9f8f17086e56e83adae4a8a9d63e2fec3cb6c7
+ DOCKER_REV: 73494a0823156dea9d3ef39e98dab1d5ccb30e15
# Sequential version number of all cached things.
# Bump to invalidate GitLab CI cache.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15d7862e98d4c5c3ee6146f8b6b5d9e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15d7862e98d4c5c3ee6146f8b6b5d9e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/romes/26202] 88 commits: Specialise: Improve specialisation by refactoring interestingDict
by Rodrigo Mesquita (@alt-romes) 12 Aug '25
by Rodrigo Mesquita (@alt-romes) 12 Aug '25
12 Aug '25
Rodrigo Mesquita pushed to branch wip/romes/26202 at Glasgow Haskell Compiler / GHC
Commits:
f707bab4 by Andreas Klebinger at 2025-07-12T14:56:16+01:00
Specialise: Improve specialisation by refactoring interestingDict
This MR addresses #26051, which concerns missed type-class specialisation.
The main payload of the MR is to completely refactor the key function
`interestingDict` in GHC.Core.Opt.Specialise
The main change is that we now also look at the structure of the
dictionary we consider specializing on, rather than only the type.
See the big `Note [Interesting dictionary arguments]`
- - - - -
ca7a9d42 by Simon Peyton Jones at 2025-07-12T14:56:16+01:00
Treat tuple dictionaries uniformly; don't unbox them
See `Note [Do not unbox class dictionaries]` in DmdAnal.hs,
sep (DNB1).
This MR reverses the plan in #23398, which suggested a special case to
unbox tuple dictionaries in worker/wrapper. But:
- This was the cause of a pile of complexity in the specialiser (#26158)
- Even with that complexity, specialision was still bad, very bad
See https://gitlab.haskell.org/ghc/ghc/-/issues/19747#note_626297
And it's entirely unnecessary! Specialision works fine without
unboxing tuple dictionaries.
- - - - -
be7296c9 by Andreas Klebinger at 2025-07-12T14:56:16+01:00
Remove complex special case from the type-class specialiser
There was a pretty tricky special case in Specialise which is no
longer necessary.
* Historical Note [Floating dictionaries out of cases]
* #26158
* #19747 https://gitlab.haskell.org/ghc/ghc/-/issues/19747#note_626297
This MR removes it. Hooray.
- - - - -
4acf3a86 by Ben Gamari at 2025-07-15T05:46:32-04:00
configure: bump version to 9.15
- - - - -
45efaf71 by Teo Camarasu at 2025-07-15T05:47:13-04:00
rts/nonmovingGC: remove n_free
We remove the nonmovingHeap.n_free variable.
We wanted this to track the length of nonmovingHeap.free.
But this isn't possible to do atomically.
When this isn't accurate we can get a segfault by going past the end of
the list.
Instead, we just count the length of the list when we grab it in
nonmovingPruneFreeSegment.
Resolves #26186
- - - - -
c635f164 by Ben Gamari at 2025-07-15T14:05:54-04:00
configure: Drop probing of ld.gold
As noted in #25716, `gold` has been dropped from binutils-2.44.
Fixes #25716.
Metric Increase:
size_hello_artifact_gzip
size_hello_unicode_gzip
ghc_prim_so
- - - - -
637bb538 by Ben Gamari at 2025-07-15T14:05:55-04:00
testsuite/recomp015: Ignore stderr
This is necessary since ld.bfd complains
that we don't have a .note.GNU-stack section,
potentially resulting in an executable stack.
- - - - -
d3cd4ec8 by Wen Kokke at 2025-07-15T14:06:39-04:00
Fix documentation for heap profile ID
- - - - -
73082769 by Ben Gamari at 2025-07-15T16:56:38-04:00
Bump win32-tarballs to v0.9
- - - - -
3b63b254 by Ben Gamari at 2025-07-15T16:56:39-04:00
rts/LoadArchive: Handle null terminated string tables
As of `llvm-ar` now emits filename tables terminated with null
characters instead of the usual POSIX `/\n` sequence.
Fixes #26150.
- - - - -
195f6527 by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: rename label so name doesn't conflict with param
- - - - -
63373b95 by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: Handle API set symbol versioning conflicts
- - - - -
48e9aa3e by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: Mark API set symbols as HIDDEN and correct symbol type
- - - - -
959e827a by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: Implement WEAK EXTERNAL undef redirection by target symbol name
- - - - -
65f19293 by Ben Gamari at 2025-07-15T16:56:39-04:00
rts/LoadArchive: Handle string table entries terminated with /
llvm-ar appears to terminate string table entries with `/\n` [1]. This
matters in the case of thin archives, since the filename is used. In the
past this worked since `llvm-ar` would produce archives with "small"
filenames when possible. However, now it appears to always use the
string table.
[1] https://github.com/llvm/llvm-project/blob/bfb686bb5ba503e9386dc899e1ebbe248…
- - - - -
9cbb3ef5 by Ben Gamari at 2025-07-15T16:56:39-04:00
testsuite: Mark T12497 as fixed
Thanks to the LLVM toolchain update.
Closes #22694.
- - - - -
2854407e by Ben Gamari at 2025-07-15T16:56:39-04:00
testsuite: Accept new output of T11223_link_order_a_b_2_fail on Windows
The archive member number changed due to the fact that llvm-ar now uses a
string table.
- - - - -
28439593 by Ben Gamari at 2025-07-15T16:56:39-04:00
rts/linker/PEi386: Implement IMAGE_REL_AMD64_SECREL
This appears to now be used by libc++ as distributed by msys2.
- - - - -
2b053755 by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: Cleanup merge resolution residue in lookupSymbolInDLL_PEi386 and make safe without dependent
- - - - -
e8acd2e7 by Wen Kokke at 2025-07-16T08:37:04-04:00
Remove the `profile_id` parameter from various RTS functions.
Various RTS functions took a `profile_id` parameter, intended to be used to
distinguish parallel heap profile breakdowns (e.g., `-hT` and `-hi`). However,
this feature was never implemented and the `profile_id` parameter was set to 0
throughout the RTS. This commit removes the parameter but leaves the hardcoded
profile ID in the functions that emit the encoded eventlog events as to not
change the protocol.
The affected functions are `traceHeapProfBegin`, `postHeapProfBegin`,
`traceHeapProfSampleString`, `postHeapProfSampleString`,
`traceHeapProfSampleCostCentre`, and `postHeapProfSampleCostCentre`.
- - - - -
76d392a2 by Wen Kokke at 2025-07-16T08:37:04-04:00
Make `traceHeapProfBegin` an init event.
- - - - -
bbaa44a7 by Peng Fan at 2025-07-16T16:50:42-04:00
NCG/LA64: Support finer-grained DBAR hints
For LA664 and newer uarchs, they have made finer granularity hints
available:
Bit4: ordering or completion (0: completion, 1: ordering)
Bit3: barrier for previous read (0: true, 1: false)
Bit2: barrier for previous write (0: true, 1: false)
Bit1: barrier for succeeding read (0: true, 1: false)
Bit0: barrier for succeeding write (0: true, 1: false)
And not affect the existing models because other hints are treated
as 'dbar 0' there.
- - - - -
7da86e16 by Andreas Klebinger at 2025-07-16T16:51:25-04:00
Disable -fprof-late-overloaded-calls for join points.
Currently GHC considers cost centres as destructive to
join contexts. Or in other words this is not considered valid:
join f x = ...
in
... -> scc<tick> jmp
This makes the functionality of `-fprof-late-overloaded-calls` not feasible
for join points in general. We used to try to work around this by putting the
ticks on the rhs of the join point rather than around the jump. However beyond
the loss of accuracy this was broken for recursive join points as we ended up
with something like:
rec-join f x = scc<tick> ... jmp f x
Which similarly is not valid as the tick once again destroys the tail call.
One might think we could limit ourselves to non-recursive tail calls and do
something clever like:
join f x = scc<tick> ...
in ... jmp f x
And sometimes this works! But sometimes the full rhs would look something like:
join g x = ....
join f x = scc<tick> ... -> jmp g x
Which, would again no longer be valid. I believe in the long run we can make
cost centre ticks non-destructive to join points. Or we could keep track of
where we are/are not allowed to insert a cost centre. But in the short term I will
simply disable the annotation of join calls under this flag.
- - - - -
7ee22fd5 by ARATA Mizuki at 2025-07-17T06:05:30-04:00
x86 NCG: Better lowering for shuffleFloatX4# and shuffleDoubleX2#
The new implementation
* make use of specialized instructions like (V)UNPCK{L,H}{PS,PD}, and
* do not require -mavx.
Close #26096
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
c6cd2da1 by Jappie Klooster at 2025-07-17T06:06:20-04:00
Update interact docs to explain about buffering
We need to tell the user to set to the
appropriate buffer format.
Otherwise, this function may get randomly stuck,
or just behave confusingly.
issue: https://gitlab.haskell.org/ghc/ghc/-/issues/26131
NB, I'm running this with cabal *NOT* ghci. ghci messes with buffering anyway.
```haskell
interaction :: String -> String
interaction "jappie" = "hi"
interaction "jakob" = "hello"
interaction x = "unkown input: " <> x
main :: IO ()
main = interact interaction
```
so in my input (prefixed by `>`) I get:
```
> jappie
unkown input: jappie
```
we confirmed later this was due to lack of \n matching.
Anyway movnig on to more unexpected stuff:
```haskell
main :: IO ()
main = do
interact (concatMap interaction . lines)
```
get's stuck forever.
actually `^D` (ctrl+d) unstucks it and runs all input as expected.
for example you can get:
```
> sdfkds
> fakdsf
unkown input: sdfkdsunkown input: fakdsf
```
This program works!
```haskell
interaction :: String -> String
interaction "jappie" = "hi \n"
interaction "jakob" = "hello \n"
interaction x = "unkown input: " <> x <> "\n"
main :: IO ()
main = do
interact (concatMap interaction . lines)
```
the reason is that linebuffering is set for both in and output by default.
so lines eats the input lines, and all the \n postfixes make sure the buffer
is put out.
- - - - -
9fa590a6 by Zubin Duggal at 2025-07-17T06:07:03-04:00
fetch_gitlab: Ensure we copy users_guide.pdf and Haddock.pdf to the release docs directory
Fixes #24093
- - - - -
cc650b4b by Andrew Lelechenko at 2025-07-17T12:30:24-04:00
Add Data.List.NonEmpty.mapMaybe
As per https://github.com/haskell/core-libraries-committee/issues/337
- - - - -
360fa82c by Duncan Coutts at 2025-07-17T12:31:14-04:00
base: Deprecate GHC.Weak.Finalize.runFinalizerBatch
https://github.com/haskell/core-libraries-committee/issues/342
- - - - -
f4e8466c by Alan Zimmerman at 2025-07-17T12:31:55-04:00
EPA: Update exact printing based on GHC 9.14 tests
As a result of migrating the GHC ghc-9.14 branch tests to
ghc-exactprint in
https://github.com/alanz/ghc-exactprint/tree/ghc-9.14, a couple of
discrepancies were picked up
- The opening paren for a DefaultDecl was printed in the wrong place
- The import declaration level specifiers were not printed.
This commit adds those fixes, and some tests for them.
The tests brought to light that the ImportDecl ppr instance had not
been updated for level specifiers, so it updates that too.
- - - - -
8b731e3c by Matthew Pickering at 2025-07-21T13:36:43-04:00
level imports: Fix infinite loop with cyclic module imports
I didn't anticipate that downsweep would run before we checked for
cyclic imports. Therefore we need to use the reachability function which
handles cyclic graphs.
Fixes #26087
- - - - -
d751a9f1 by Pierre Thierry at 2025-07-21T13:37:28-04:00
Fix documentation about deriving from generics
- - - - -
f8d9d016 by Andrew Lelechenko at 2025-07-22T21:13:28-04:00
Fix issues with toRational for types capable to represent infinite and not-a-number values
This commit fixes all of the following pitfalls:
> toRational (read "Infinity" :: Double)
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216 % 1
> toRational (read "NaN" :: Double)
269653970229347386159395778618353710042696546841345985910145121736599013708251444699062715983611304031680170819807090036488184653221624933739271145959211186566651840137298227914453329401869141179179624428127508653257226023513694322210869665811240855745025766026879447359920868907719574457253034494436336205824 % 1
> realToFrac (read "NaN" :: Double) -- With -O0
Infinity
> realToFrac (read "NaN" :: Double) -- With -O1
NaN
> realToFrac (read "NaN" :: Double) :: CDouble
Infinity
> realToFrac (read "NaN" :: CDouble) :: Double
Infinity
Implements https://github.com/haskell/core-libraries-committee/issues/338
- - - - -
5dabc718 by Zubin Duggal at 2025-07-22T21:14:10-04:00
haddock: Don't warn about missing link destinations for derived names.
Fixes #26114
- - - - -
9c3a0937 by Matthew Pickering at 2025-07-22T21:14:52-04:00
template haskell: use a precise condition when implicitly lifting
Implicit lifting corrects a level error by replacing references to `x`
with `$(lift x)`, therefore you can use a level `n` binding at level `n
+ 1`, if it can be lifted.
Therefore, we now have a precise check that the use level is 1 more than
the bind level.
Before this bug was not observable as you only had 0 and 1 contexts but
it is easily evident when using explicit level imports.
Fixes #26088
- - - - -
5144b22f by Andreas Klebinger at 2025-07-22T21:15:34-04:00
Add since tag and more docs for do-clever-arg-eta-expansion
Fixes #26113
- - - - -
c865623b by Andreas Klebinger at 2025-07-22T21:15:34-04:00
Add since tag for -fexpose-overloaded-unfoldings
Fixes #26112
- - - - -
49a44ab7 by Simon Hengel at 2025-07-23T17:59:55+07:00
Refactor GHC.Driver.Errors.printMessages
- - - - -
84711c39 by Simon Hengel at 2025-07-23T18:27:34+07:00
Respect `-fdiagnostics-as-json` for error messages from pre-processors
(fixes #25480)
- - - - -
d046b5ab by Simon Hengel at 2025-07-24T06:12:05-04:00
Include the rendered message in -fdiagnostics-as-json output
This implements #26173.
- - - - -
d2b89603 by Ben Gamari at 2025-07-24T06:12:47-04:00
rts/Interpreter: Factor out ctoi tuple info tables into data
Instead of a massive case let's put this into data which we can reuse
elsewhere.
- - - - -
4bc78496 by Sebastian Graf at 2025-07-24T16:19:34-04:00
CprAnal: Detect recursive newtypes (#25944)
While `cprTransformDataConWork` handles recursive data con workers, it
did not detect the case when a newtype is responsible for the recursion.
This is now detected in the `Cast` case of `cprAnal`.
The same reproducer made it clear that `isRecDataCon` lacked congruent
handling for `AppTy` and `CastTy`, now fixed.
Furthermore, the new repro case T25944 triggered this bug via an
infinite loop in `cprFix`, caused by the infelicity in `isRecDataCon`.
While it should be much less likely to trigger such an infinite loop now
that `isRecDataCon` has been fixed, I made sure to abort the loop after
10 iterations and emitting a warning instead.
Fixes #25944.
- - - - -
0a583689 by Sylvain Henry at 2025-07-24T16:20:26-04:00
STM: don't create a transaction in the rhs of catchRetry# (#26028)
We don't need to create a transaction for the rhs of (catchRetry#)
because contrary to the lhs we don't need to abort it on retry. Moreover
it is particularly harmful if we have code such as (#26028):
let cN = readTVar vN >> retry
tree = c1 `orElse` (c2 `orElse` (c3 `orElse` ...))
atomically tree
Because it will stack transactions for the rhss and the read-sets of all
the transactions will be iteratively merged in O(n^2) after the
execution of the most nested retry.
- - - - -
a49eca26 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Renaming around predicate types
.. we were (as it turned out) abstracting over
type-class selectors in SPECIALISATION rules!
Wibble isEqPred
- - - - -
f80375dd by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Refactor of Specialise.hs
This patch just tidies up `specHeader` a bit, removing one
of its many results, and adding some comments.
No change in behaviour.
Also add a few more `HasDebugCallStack` contexts.
- - - - -
1bd12371 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Improve treatment of SPECIALISE pragmas -- again!
This MR does another major refactor of the way that SPECIALISE
pragmas work, to fix #26115, #26116, #26117.
* We now /always/ solve forall-constraints in an all-or-nothing way.
See Note [Solving a Wanted forall-constraint] in GHC.Tc.Solver.Solve
This means we might have unsolved quantified constraints, which need
to be reported. See `inert_insts` in `getUnsolvedInerts`.
* I refactored the short-cut solver for type classes to work by
recursively calling the solver rather than by having a little baby
solver that kept being not clever enough.
See Note [Shortcut solving] in GHC.Tc.Solver.Dict
* I totally rewrote the desugaring of SPECIALISE pragmas, again.
The new story is in Note [Desugaring new-form SPECIALISE pragmas]
in GHC.HsToCore.Binds
Both old-form and new-form SPECIALISE pragmas now route through the same
function `dsSpec_help`. The tricky function `decomposeRuleLhs` is now used only
for user-written RULES, not for SPECIALISE pragmas.
* I improved `solveOneFromTheOther` to account for rewriter sets. Previously
it would solve a non-rewritten dict from a rewritten one. For equalities
we were already dealing with this, in
Some incidental refactoring
* A small refactor: `ebv_tcvs` in `EvBindsBar` now has a list of coercions, rather
than a set of tyvars. We just delay taking the free vars.
* GHC.Core.FVs.exprFVs now returns /all/ free vars.
Use `exprLocalFVs` for Local vars.
Reason: I wanted another variant for /evidence/ variables.
* Ues `EvId` in preference to `EvVar`. (Evidence variables are always Ids.)
Rename `isEvVar` to `isEvId`.
* I moved `inert_safehask` out of `InertCans` and into `InertSet` where it
more properly belongs.
Compiler-perf changes:
* There was a palpable bug (#26117) which this MR fixes in
newWantedEvVar, which bypassed all the subtle overlapping-Given
and shortcutting logic. (See the new `newWantedEvVar`.) Fixing this
but leads to extra dictionary bindings; they are optimised away quickly
but they made CoOpt_Read allocate 3.6% more.
* Hpapily T15164 improves.
* The net compiler-allocation change is 0.0%
Metric Decrease:
T15164
Metric Increase:
CoOpt_Read
T12425
- - - - -
953fd8f1 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Solve forall-constraints immediately, or not at all
This MR refactors the constraint solver to solve forall-constraints immediately,
rather than emitting an implication constraint to be solved later.
The most immediate motivation was that when solving quantified constraints
in SPECIALISE pragmas, we really really don't want to leave behind half-
solved implications. Also it's in tune with the approach of the new
short-cut solver, which recursively invokes the solver.
It /also/ saves quite a bit of plumbing; e.g
- The `wl_implics` field of `WorkList` is gone,
- The types of `solveSimpleWanteds` and friends are simplified.
- An EvFun contains binding, rather than an EvBindsVar ref-cell that
will in the future contain bindings. That makes `evVarsOfTerm`
simpler. Much nicer.
It also improves error messages a bit.
All described in Note [Solving a Wanted forall-constraint] in
GHC.Tc.Solver.Solve.
One tiresome point: in the tricky case of `inferConstraintsCoerceBased`
we make a forall-constraint. This we /do/ want to partially solve, so
we can infer a suitable context. (I'd be quite happy to force the user to
write a context, bt I don't want to change behavior.) So we want to generate
an /implication/ constraint in `emitPredSpecConstraints` rather than a
/forall-constraint/ as we were doing before. Discussed in (WFA3) of
the above Note.
Incidental refactoring
* `GHC.Tc.Deriv.Infer.inferConstraints` was consulting the state monad for
the DerivEnv that the caller had just consulted. Nicer to pass it as an
argument I think, so I have done that. No change in behaviour.
- - - - -
6921ab42 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Remove duplicated code in Ast.hs for evTermFreeVars
This is just a tidy up.
- - - - -
1165f587 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Small tc-tracing changes only
- - - - -
0776ffe0 by Simon Hengel at 2025-07-26T04:54:20-04:00
Respect `-fdiagnostics-as-json` for core diagnostics (see #24113)
- - - - -
cc1116e0 by Andrew Lelechenko at 2025-07-26T04:55:01-04:00
docs: add since pragma to Data.List.NonEmpty.mapMaybe
- - - - -
ee2dc248 by Simon Hengel at 2025-07-31T06:25:35-04:00
Update comments on `OptKind` to reflect the code reality
- - - - -
b029633a by Wen Kokke at 2025-07-31T06:26:21-04:00
rts: Disable --eventlog-flush-interval unless compiled with -threaded.
This commit fixes issue #26222:
Using --eventlog-flush-interval with the non-threaded RTS leads to eventlog corruption.
https://gitlab.haskell.org/ghc/ghc/-/issues/26222
This commit makes three changes when code is compiled against the non-threaded RTS:
1. It disables the --eventlog-flush-interval flag.
2. It disables the documentation for the --eventlog-flush-interval flag.
3. It disables the relevant state from RtsConfig and code from Timer.
4. It updates the entry for --eventlog-flush-interval in the users guide.
- - - - -
31159f1d by Wen Kokke at 2025-07-31T06:26:21-04:00
rts: Split T20006 into tests with and without -threaded
- - - - -
618687ef by Simon Hengel at 2025-07-31T06:27:03-04:00
docs/users_guide/win32-dlls.rst: Remove references to `readline`
- - - - -
083e40f1 by Rodrigo Mesquita at 2025-08-01T04:38:23-04:00
debugger: Uniquely identify breakpoints by internal id
Since b85b11994e0130ff2401dd4bbdf52330e0bcf776 (support inlining
breakpoints), a breakpoint has been identified at runtime by *two* pairs
of <module,index>.
- The first, aka a 'BreakpointId', uniquely identifies a breakpoint in
the source of a module by using the Tick index. A Tick index can index
into ModBreaks.modBreaks_xxx to fetch source-level information about
where that tick originated.
- When a user specifies e.g. a line breakpoint using :break, we'll reverse
engineer what a Tick index for that line
- We update the `BreakArray` of that module (got from the
LoaderState) at that tick index to `breakOn`.
- A BCO we can stop at is headed by a BRK_FUN instruction. This
instruction stores in an operand the `tick index` it is associated
to. We look it up in the associated `BreakArray` (also an operand)
and check wheter it was set to `breakOn`.
- The second, aka the `ibi_info_mod` + `ibi_info_ix` of the
`InternalBreakpointId`, uniquely index into the `imodBreaks_breakInfo`
-- the information we gathered during code generation about the
existing breakpoint *ocurrences*.
- Note that with optimisation there may be many occurrences of the
same source-tick-breakpoint across different modules. The
`ibi_info_ix` is unique per occurrence, but the `bi_tick_ix` may be
shared. See Note [Breakpoint identifiers] about this.
- Note that besides the tick ids, info ids are also stored in
`BRK_FUN` so the break handler can refer to the associated
`CgBreakInfo`.
In light of that, the driving changes come from the desire to have the
info_id uniquely identify the breakpoint at runtime, and the source tick
id being derived from it:
- An InternalBreakpointId should uniquely identify a breakpoint just
from the code-generation identifiers of `ibi_info_ix` and `ibi_info_mod`.
So we drop `ibi_tick_mod` and `ibi_tick_ix`.
- A BRK_FUN instruction need only record the "internal breakpoint id",
not the tick-level id.
So we drop the tick mod and tick index operands.
- A BreakArray should be indexed by InternalBreakpointId rather than
BreakpointId
That means we need to do some more work when setting a breakpoint.
Specifically, we need to figure out the internal ids (occurrences of a
breakpoint) from the source-level BreakpointId we want to set the
breakpoint at (recall :break refers to breaks at the source level).
Besides this change being an improvement to the handling of breakpoints
(it's clearer to have a single unique identifier than two competing
ones), it unlocks the possibility of generating "internal" breakpoints
during Cg (needed for #26042).
It should also be easier to introduce multi-threaded-aware `BreakArrays`
following this change (needed for #26064).
Se also the new Note [ModBreaks vs InternalModBreaks]
On i386-linux:
-------------------------
Metric Decrease:
interpreter_steplocal
-------------------------
- - - - -
bf03bbaa by Simon Hengel at 2025-08-01T04:39:05-04:00
Don't use MCDiagnostic for `ghcExit`
This changes the error message of `ghcExit` from
```
<no location info>: error:
Compilation had errors
```
to
```
Compilation had errors
```
- - - - -
a889ec75 by Simon Hengel at 2025-08-01T04:39:05-04:00
Respect `-fdiagnostics-as-json` for driver diagnostics (see #24113)
- - - - -
81577fe7 by Ben Gamari at 2025-08-02T04:29:39-04:00
configure: Allow override of CrossCompiling
As noted in #26236, the current inference logic is a bit simplistic. In
particular, there are many cases (e.g. building for a new libc) where
the target and host triples may differ yet we are still able to run the
produced artifacts as native code.
Closes #26236.
- - - - -
01136779 by Andreas Klebinger at 2025-08-02T04:30:20-04:00
rts: Support COFF BigObj files in archives.
- - - - -
1f9e4f54 by Stephen Morgan at 2025-08-03T15:14:08+10:00
refactor: Modify Data.List.sortOn to use (>) instead of compare. (#26184)
This lets a more efficient (>) operation be used if one exists.
This is technically a breaking change for malformed Ord instances, where
x > y is not equivalent to compare x y == GT.
Discussed by the CLC in issue #332: https://github.com/haskell/core-libraries-committee/issues/332
- - - - -
4f6bc9cf by fendor at 2025-08-04T17:50:06-04:00
Revert "base: Expose Backtraces constructor and fields"
This reverts commit 17db44c5b32fff82ea988fa4f1a233d1a27bdf57.
- - - - -
bcdec657 by Zubin Duggal at 2025-08-05T10:37:29+05:30
compiler: Export a version of `newNameCache` that is not prone to footguns.
`newNameCache` must be initialized with both a non-"reserved" unique tag, as well
as a list of known key names. Failing to do so results in hard to debug unique conflicts.
It is difficult for API users to tell which unique tags are safe to use. So instead of leaving
this up to the user to decide, we now export a version of `newNameCache` which uses a guaranteed
non-reserved unique tag. In fact, this is now the way the unique tag is initialized for all invocations
of the compiler.
The original version of `newNameCache` is now exported as `newNameCache'` for advanced users.
We also deprecate `initNameCache` as it is also prone to footguns and is completely subsumed in
functionality by `newNameCache` and `newNameCache'`.
Fixes #26135 and #26055
- - - - -
57d3b4a8 by Andrew Lelechenko at 2025-08-05T18:36:31-04:00
hadrian: bump Stackage snapshot to LTS 24.2 / GHC 9.10.2
In line with #25693 we should use GHC 9.10 as a boot compiler,
while Hadrian stack.yaml was stuck on GHC 9.6.
- - - - -
c2a78cea by Peng Fan at 2025-08-05T18:37:27-04:00
NCG/LA64: implement atomic write with finer-grained DBAR hints
Signed-off-by: Peng Fan <fanpeng(a)loongson.cn>
- - - - -
95231c8e by Teo Camarasu at 2025-08-06T08:35:58-04:00
CODEOWNERS: add CLC as codeowner of base
We also remove hvr, since I think he is no longer active
- - - - -
77df0ded by Andrew Lelechenko at 2025-08-06T08:36:39-04:00
Bump submodule text to 2.1.3
- - - - -
8af260d0 by Nikolaos Chatzikonstantinou at 2025-08-06T08:37:23-04:00
docs: fix internal import in getopt examples
This external-facing doc example shouldn't mention GHC internals when
using 'fromMaybe'.
- - - - -
69cc16ca by Marc Scholten at 2025-08-06T15:51:28-04:00
README: Add note on ghc.nix
- - - - -
93a2f450 by Daniel Díaz at 2025-08-06T15:52:14-04:00
Link to the "Strict Bindings" docs from the linear types docs
Strict Bidings are relevant for the kinds of multiplicity annotations
linear lets support.
- - - - -
246b7853 by Matthew Pickering at 2025-08-07T06:58:30-04:00
level imports: Check the level of exported identifiers
The level imports specification states that exported identifiers have to
be at level 0. This patch adds the requird level checks that all
explicitly mentioned identifiers occur at level 0.
For implicit export specifications (T(..) and module B), only level 0
identifiers are selected for re-export.
ghc-proposal: https://github.com/ghc-proposals/ghc-proposals/pull/705
Fixes #26090
- - - - -
358bc4fc by fendor at 2025-08-07T06:59:12-04:00
Bump GHC on darwin CI to 9.10.1
- - - - -
1903ae35 by Matthew Pickering at 2025-08-07T12:21:10+01:00
ipe: Place strings and metadata into specific .ipe section
By placing the .ipe metadata into a specific section it can be stripped
from the final binary if desired.
```
objcopy --remove-section .ipe <binary>
upx <binary>
```
Towards #21766
- - - - -
c80dd91c by Matthew Pickering at 2025-08-07T12:22:42+01:00
ipe: Place magic word at the start of entries in the .ipe section
The magic word "IPE\nIPE\n" is placed at the start of .ipe sections,
then if the section is stripped, we can check whether the section starts
with the magic word or not to determine whether there is metadata
present or not.
Towards #21766
- - - - -
cab42666 by Matthew Pickering at 2025-08-07T12:22:42+01:00
ipe: Use stable IDs for IPE entries
IPEs have historically been indexed and reported by their address.
This makes it impossible to compare profiles between runs, since the
addresses may change (due to ASLR) and also makes it tricky to separate
out the IPE map from the binary.
This small patch adds a stable identifier for each IPE entry.
The stable identifier is a single 64 bit word. The high-bits are a
per-module identifier and the low bits identify which entry in each
module.
1. When a node is added into the IPE buffer it is assigned a unique
identifier from an incrementing global counter.
2. Each entry already has an index by it's position in the
`IpeBufferListNode`.
The two are combined together by the `IPE_ENTRY_KEY` macro.
Info table profiling uses the stable identifier rather than the address
of the info table.
The benefits of this change are:
* Profiles from different runs can be easily compared
* The metadata can be extracted from the binary (via the eventlog for
example) and then stripped from the executable.
Fixes #21766
- - - - -
2860a9a5 by Simon Peyton Jones at 2025-08-07T20:29:18-04:00
In TcSShortCut, typechecker plugins should get empty Givens
Solving in TcShortCut mode means /ignoring the Givens/. So we
should not pass them to typechecker plugins!
Fixes #26258.
This is a fixup to the earlier MR:
commit 1bd12371feacc52394a0e660ef9349f9e8ee1c06
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Jul 21 10:04:49 2025 +0100
Improve treatment of SPECIALISE pragmas -- again!
- - - - -
2157db2d by sterni at 2025-08-08T15:32:39-04:00
hadrian: enable terminfo if --with-curses-* flags are given
The GHC make build system used to support WITH_TERMINFO in ghc.mk which
allowed controlling whether to build GHC with terminfo or not. hadrian
has replaced this with a system where this is effectively controlled by
the cross-compiling setting (the default WITH_TERMINFO value was bassed
on CrossCompiling, iirc).
This behavior is undesireable in some cases and there is not really a
good way to work around it. Especially for downstream packagers,
modifying this via UserSettings is not really feasible since such a
source file has to be kept in sync with Settings/Default.hs manually
since it can't import Settings.Default or any predefined Flavour
definitions.
To avoid having to add a new setting to cfg/system.config and/or a new
configure flag (though I'm happy to implement both if required), I've
chosen to take --with-curses-* being set explicitly as an indication
that the user wants to have terminfo enabled. This would work for
Nixpkgs which sets these flags [1] as well as haskell.nix [2] (which
goes to some extreme measures [3] [4] to force terminfo in all scenarios).
In general, I'm an advocate for making the GHC build be the same for
native and cross insofar it is possible since it makes packaging GHC and
Haskell related things while still supporting cross much less
compilicated. A more minimal GHC with reduced dependencies should
probably be a specific flavor, not the default.
Partially addresses #26288 by forcing terminfo to be built if the user
explicitly passes configure flags related to it. However, it isn't built
by default when cross-compiling yet nor is there an explicit way to
control the package being built.
[1]: https://github.com/NixOS/nixpkgs/blob/3a7266fcefcb9ce353df49ba3f292d0644376…
[2]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
[3]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
[4]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
- - - - -
b3c31488 by David Feuer at 2025-08-08T15:33:21-04:00
Add default QuasiQuoters
Add `defaultQuasiQuoter` and `namedDefaultQuasiQuoter` to make it easier
to write `QuasiQuoters` that give helpful error messages when they're
used in inappropriate contexts.
Closes #24434.
- - - - -
03555ed8 by Sylvain Henry at 2025-08-10T22:20:57-04:00
Handle non-fractional CmmFloats in Cmm's CBE (#26229)
Since f8d9d016305be355f518c141f6c6d4826f2de9a2, toRational for Float and
Double converts float's infinity and NaN into Rational's infinity and
NaN (respectively 1%0 and 0%0).
Cmm CommonBlockEliminator hashing function needs to take these values
into account as they can appear as literals now. See added testcase.
- - - - -
6c956af3 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Fix extensions list in `DoAndIfThenElse` docs
- - - - -
6dc420b1 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Document status of `RelaxedPolyRec` extension
This adds a brief extension page explaining the status of the
`RelaxedPolyRec` extension. The behaviour of this mode is already
explained elsewhere, so this page is mainly for completeness so that
various lists of extensions have somewhere to point to for this flag.
Fixes #18630
- - - - -
18036d52 by Simon Peyton Jones at 2025-08-11T11:31:20-04:00
Take more care in zonkEqTypes on AppTy/AppTy
This patch fixes #26256.
See Note [zonkEqTypes and the PKTI] in GHC.Tc.Solver.Equality
- - - - -
c8d76a29 by Zubin Duggal at 2025-08-11T11:32:02-04:00
ci: upgrade bootstrap compiler on windows to 9.10.1
- - - - -
411a43bd by Rodrigo Mesquita at 2025-08-12T13:29:22+00:00
build: Relax ghc/ghc-boot Cabal bound to 3.16
Fixes #26202
- - - - -
27798c68 by Rodrigo Mesquita at 2025-08-12T13:29:22+00:00
cabal-reinstall: Use haddock-api +in-tree-ghc
Fixes #26202
- - - - -
7edbc13d by Rodrigo Mesquita at 2025-08-12T13:29:22+00:00
cabal-reinstall: Pass --strict to Happy
This is necessary to make the generated Parser build successfully
This mimics Hadrian, which always passes --strict to happy.
Fixes #26202
- - - - -
69ee0896 by Rodrigo Mesquita at 2025-08-12T13:29:22+00:00
genprimopcode: Require higher happy version
I've bumped the happy version to forbid deprecated Happy versions which
don't successfully compile.
- - - - -
fa083131 by Rodrigo Mesquita at 2025-08-12T13:29:22+00:00
Bump CI index-state
Necessary to fix cabal.project-reinstall
- - - - -
15d7862e by Rodrigo Mesquita at 2025-08-12T13:29:22+00:00
Update DOCKER_REV to !14579
- - - - -
285 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/darwin/toolchain.nix
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- CODEOWNERS
- README.md
- cabal.project-reinstall
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/LA64/Instr.hs
- compiler/GHC/CmmToAsm/LA64/Ppr.hs
- compiler/GHC/CmmToAsm/PPC/Ppr.hs
- compiler/GHC/CmmToAsm/Ppr.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToLlvm/Data.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/FVs.hs
- compiler/GHC/Core/LateCC/OverloadedCalls.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/CprAnal.hs
- compiler/GHC/Core/Opt/DmdAnal.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Subst.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/Unfold/Make.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Driver/CmdLine.hs
- compiler/GHC/Driver/Errors.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Parser.y
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/InfoTableProv.hs
- compiler/GHC/SysTools/Process.hs
- compiler/GHC/SysTools/Tasks.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Infer.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.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/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Rewrite.hs
- compiler/GHC/Tc/Solver/Solve.hs
- + compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/Solver/Types.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.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/Type.hs
- compiler/GHC/Types/Error.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Utils/Error.hs
- compiler/GHC/Utils/Logger.hs
- compiler/Setup.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/conf.py
- docs/users_guide/debug-info.rst
- + docs/users_guide/diagnostics-as-json-schema-1_2.json
- docs/users_guide/eventlog-formats.rst
- docs/users_guide/expected-undocumented-flags.txt
- docs/users_guide/exts/doandifthenelse.rst
- docs/users_guide/exts/linear_types.rst
- + docs/users_guide/exts/relaxed_poly_rec.rst
- docs/users_guide/exts/strict.rst
- docs/users_guide/exts/types.rst
- docs/users_guide/profiling.rst
- docs/users_guide/runtime_control.rst
- docs/users_guide/using-optimisation.rst
- docs/users_guide/using.rst
- docs/users_guide/win32-dlls.rst
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Monad.hs
- hadrian/cabal.project
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- hadrian/stack.yaml
- hadrian/stack.yaml.lock
- libraries/base/changelog.md
- libraries/base/src/Control/Exception/Backtrace.hs
- libraries/base/src/Data/List/NonEmpty.hs
- libraries/base/src/GHC/Generics.hs
- libraries/base/src/GHC/Weak/Finalize.hs
- libraries/base/src/System/Console/GetOpt.hs
- libraries/ghc-boot/Setup.hs
- libraries/ghc-boot/ghc-boot.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- libraries/ghc-internal/src/GHC/Internal/Real.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghci/GHCi/Debugger.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/changelog.md
- libraries/text
- m4/find_ld.m4
- mk/get-win32-tarballs.py
- rts/Disassembler.c
- rts/Exception.cmm
- rts/IPE.c
- rts/Interpreter.c
- rts/PrimOps.cmm
- rts/ProfHeap.c
- rts/RaiseAsync.c
- rts/RetainerSet.c
- rts/RtsFlags.c
- rts/STM.c
- rts/Timer.c
- rts/Trace.c
- rts/Trace.h
- rts/eventlog/EventLog.c
- rts/eventlog/EventLog.h
- rts/include/rts/Flags.h
- rts/include/rts/IPE.h
- rts/linker/LoadArchive.c
- rts/linker/PEi386.c
- rts/sm/NonMoving.c
- rts/sm/NonMoving.h
- rts/sm/NonMovingAllocate.c
- rts/sm/Sanity.c
- testsuite/tests/corelint/T21115b.stderr
- + testsuite/tests/cpranal/sigs/T25944.hs
- + testsuite/tests/cpranal/sigs/T25944.stderr
- testsuite/tests/cpranal/sigs/all.T
- testsuite/tests/deriving/should_compile/T20815.hs
- testsuite/tests/deriving/should_fail/T12768.stderr
- testsuite/tests/deriving/should_fail/T1496.stderr
- testsuite/tests/deriving/should_fail/T5498.stderr
- testsuite/tests/deriving/should_fail/T7148.stderr
- testsuite/tests/deriving/should_fail/T7148a.stderr
- testsuite/tests/dmdanal/should_compile/T23398.hs
- testsuite/tests/dmdanal/should_compile/T23398.stderr
- testsuite/tests/driver/json.stderr
- testsuite/tests/driver/json_warn.stderr
- testsuite/tests/driver/recomp015/all.T
- testsuite/tests/haddock/haddock_testsuite/Makefile
- + testsuite/tests/haddock/haddock_testsuite/T26114.hs
- + testsuite/tests/haddock/haddock_testsuite/T26114.stdout
- testsuite/tests/haddock/haddock_testsuite/all.T
- testsuite/tests/hiefile/should_run/HieQueries.stdout
- testsuite/tests/hiefile/should_run/TestUtils.hs
- testsuite/tests/impredicative/T17332.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/lib/stm/T26028.hs
- + testsuite/tests/lib/stm/T26028.stdout
- + testsuite/tests/lib/stm/all.T
- + testsuite/tests/numeric/should_compile/T26229.hs
- testsuite/tests/numeric/should_compile/all.T
- testsuite/tests/numeric/should_run/T9810.stdout
- + testsuite/tests/partial-sigs/should_compile/T26256.hs
- + testsuite/tests/partial-sigs/should_compile/T26256.stderr
- testsuite/tests/partial-sigs/should_compile/all.T
- + testsuite/tests/perf/should_run/SpecTyFamRun.hs
- + testsuite/tests/perf/should_run/SpecTyFamRun.stdout
- + testsuite/tests/perf/should_run/SpecTyFam_Import.hs
- testsuite/tests/perf/should_run/all.T
- testsuite/tests/printer/Makefile
- + testsuite/tests/printer/TestLevelImports.hs
- + testsuite/tests/printer/TestNamedDefaults.hs
- testsuite/tests/printer/all.T
- testsuite/tests/quantified-constraints/T15290a.stderr
- testsuite/tests/quantified-constraints/T19690.stderr
- testsuite/tests/quantified-constraints/T19921.stderr
- testsuite/tests/quantified-constraints/T21006.stderr
- testsuite/tests/roles/should_fail/RolesIArray.stderr
- testsuite/tests/rts/all.T
- testsuite/tests/rts/flags/all.T
- testsuite/tests/rts/ipe/ipeMap.c
- testsuite/tests/rts/ipe/ipe_lib.c
- testsuite/tests/rts/linker/T11223/T11223_link_order_a_b_2_fail.stderr-ws-32-mingw32
- testsuite/tests/rts/linker/T11223/T11223_link_order_a_b_2_fail.stderr-ws-64-mingw32
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simd/should_run/doublex2_shuffle.hs
- + testsuite/tests/simd/should_run/doublex2_shuffle.stdout
- + testsuite/tests/simd/should_run/doublex2_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/doublex2_shuffle_baseline.stdout
- + testsuite/tests/simd/should_run/floatx4_shuffle.hs
- + testsuite/tests/simd/should_run/floatx4_shuffle.stdout
- + testsuite/tests/simd/should_run/floatx4_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/floatx4_shuffle_baseline.stdout
- + testsuite/tests/simplCore/should_compile/T26051.hs
- + testsuite/tests/simplCore/should_compile/T26051.stderr
- + testsuite/tests/simplCore/should_compile/T26051_Import.hs
- + testsuite/tests/simplCore/should_compile/T26115.hs
- + testsuite/tests/simplCore/should_compile/T26115.stderr
- + testsuite/tests/simplCore/should_compile/T26116.hs
- + testsuite/tests/simplCore/should_compile/T26116.stderr
- + testsuite/tests/simplCore/should_compile/T26117.hs
- + testsuite/tests/simplCore/should_compile/T26117.stderr
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/splice-imports/DodgyLevelExport.hs
- + testsuite/tests/splice-imports/DodgyLevelExport.stderr
- + testsuite/tests/splice-imports/DodgyLevelExportA.hs
- + testsuite/tests/splice-imports/LevelImportExports.hs
- + testsuite/tests/splice-imports/LevelImportExports.stdout
- + testsuite/tests/splice-imports/LevelImportExportsA.hs
- testsuite/tests/splice-imports/Makefile
- + testsuite/tests/splice-imports/ModuleExport.hs
- + testsuite/tests/splice-imports/ModuleExport.stderr
- + testsuite/tests/splice-imports/ModuleExportA.hs
- + testsuite/tests/splice-imports/ModuleExportB.hs
- + testsuite/tests/splice-imports/T26087.stderr
- + testsuite/tests/splice-imports/T26087A.hs
- + testsuite/tests/splice-imports/T26087B.hs
- + testsuite/tests/splice-imports/T26088.stderr
- + testsuite/tests/splice-imports/T26088A.hs
- + testsuite/tests/splice-imports/T26088B.hs
- + testsuite/tests/splice-imports/T26090.hs
- + testsuite/tests/splice-imports/T26090.stderr
- + testsuite/tests/splice-imports/T26090A.hs
- testsuite/tests/splice-imports/all.T
- testsuite/tests/typecheck/should_compile/T12427a.stderr
- testsuite/tests/typecheck/should_compile/T23171.hs
- + testsuite/tests/typecheck/should_compile/T26256a.hs
- testsuite/tests/typecheck/should_compile/TcSpecPragmas.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T14605.hs
- testsuite/tests/typecheck/should_fail/T14605.stderr
- testsuite/tests/typecheck/should_fail/T15801.stderr
- testsuite/tests/typecheck/should_fail/T18640a.stderr
- testsuite/tests/typecheck/should_fail/T18640b.stderr
- testsuite/tests/typecheck/should_fail/T19627.stderr
- testsuite/tests/typecheck/should_fail/T21530b.stderr
- testsuite/tests/typecheck/should_fail/T22912.stderr
- testsuite/tests/typecheck/should_fail/tcfail174.stderr
- utils/check-exact/ExactPrint.hs
- utils/genprimopcode/genprimopcode.cabal
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs
- utils/haddock/cabal.project
- utils/haddock/haddock-api/haddock-api.cabal
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37a3781114d7d8b5f58cffedc188c0…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37a3781114d7d8b5f58cffedc188c0…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/rafl/cover-data] Add release notes for 9.16.1 and move description of latest HPC changes there.
by Florian Ragwitz (@rafl) 12 Aug '25
by Florian Ragwitz (@rafl) 12 Aug '25
12 Aug '25
Florian Ragwitz pushed to branch wip/rafl/cover-data at Glasgow Haskell Compiler / GHC
Commits:
7606c791 by Florian Ragwitz at 2025-08-12T06:16:21-07:00
Add release notes for 9.16.1 and move description of latest HPC changes there.
- - - - -
3 changed files:
- − docs/users_guide/9.14.1-notes.rst
- + docs/users_guide/9.16.1-notes.rst
- docs/users_guide/release-notes.rst
Changes:
=====================================
docs/users_guide/9.14.1-notes.rst deleted
=====================================
@@ -1,296 +0,0 @@
-.. _release-9-14-1:
-
-Version 9.14.1
-==============
-
-The significant changes to the various parts of the compiler are listed in the
-following sections. See the `migration guide
-<https://gitlab.haskell.org/ghc/ghc/-/wikis/migration/9.14>`_ on the GHC Wiki
-for specific guidance on migrating programs to this release.
-
-Language
-~~~~~~~~
-
-* `GHC proposal 493: allow expressions in SPECIALISE pragmas <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0493-s…>`_
- has been implemented. SPECIALISE pragmas now allow arbitrary expressions such as: ::
-
- {-# SPECIALISE f @Int False :: Int -> Char #-}
-
- The ability to specify multiple specialisations in a single SPECIALISE pragma,
- with syntax of the form (note the comma between the type signatures): ::
-
- {-# SPECIALISE g : Int -> Int, Float -> Float #-}
-
- has been deprecated, and is scheduled to be removed in GHC 9.18.
- This deprecation is controlled by the newly introduced ``-Wdeprecated-pragmas``
- flag in ``-Wdefault``.
-
-* ``-Wincomplete-record-selectors`` is now part of `-Wall`, as specified
- by `GHC Proposal 516: add warning for incomplete record selectors <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0516-i…>`_.
- Hence, if a library is compiled with ``-Werror``, compilation may now fail. Solution: fix the library.
- Workaround: add ``-Werror=no-incomplete-record-selectors``.
-
- Note that this warning is at least
- as serious as a warning about missing patterns from a function definition, perhaps even
- more so, since it is invisible in the source program.
-
-* The combination of :extension:`ScopedTypeVariables` and :extension:`TypeApplications`
- no longer enables type applications in patterns, which now always requires
- :extension:`TypeAbstractions`. The warning flag``deprecated-type-abstractions``
- has also been removed from the compiler.
-
-* :extension:`OverloadedRecordUpdate` now passes the arguments to a ``setField`` function
- in the flipped order, as specified by `GHC Proposal 583: HasField redesign <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0583-h…>`_.
-
- Previously GHC expected ``setField`` to have this type: ::
-
- setField :: forall (fld :: Symbol) a r. r -> a -> r
-
- And that's what GHC expects now: ::
-
- setField :: forall (fld :: Symbol) a r. a -> r -> r
-
- That will break the combination of :extension:`OverloadedRecordUpdate` with :extension:`RebindableSyntax`.
-
-* Multiline strings are now accepted in foreign imports. (#25157)
-
-* GHC now does a better job at inferring types in calls to ``coerce``: instead of
- complaining about ambiguous type variables, GHC will consider that such type
- variables are determined by the ``Coercible`` constraints they appear in.
-
-* With :extension:`LinearTypes` record fields can now be non-linear. This means that
- the following record declaration is now valid:
-
- ::
-
- data Record = Rec { x %'Many :: Int, y :: Char }
-
- This causes the constructor to have type ``Rec :: Int %'Many -> Char %1 -> Record``.
-
-* The :extension:`ExplicitNamespaces` extension now allows the ``data``
- namespace specifier in import and export lists.
-
-* The ``-Wdata-kinds-tc`` warning has been deprecated, and the use of promoted
- data types in kinds is now an error (rather than a warning) unless the
- :extension:`DataKinds` extension is enabled. For example, the following code
- will be rejected unless :extension:`DataKinds` is on:
-
- import Data.Kind (Type)
- import GHC.TypeNats (Nat)
-
- -- Nat shouldn't be allowed here without DataKinds
- data Vec :: Nat -> Type -> Type
-
- (The ``-Wdata-kinds-tc`` warning was introduced in GHC 9.10 as part of a fix
- for an accidental oversight in which programs like the one above were
- mistakenly accepted without the use of :extension:`DataKinds`.)
-
-* The :extension:`MonadComprehensions` extension now implies :extension:`ParallelListComp` as was originally intended (see `Monad Comprehensions <https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/monad_comprehension…>`_).
-
-* In accordance with `GHC Proposal #281 <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0281-v…>`_,
- section 4.7 "Data constructors", the :extension:`RequiredTypeArguments`
- extension now allows visible forall in types of data constructors
- (:ghc-ticket:`25127`). The following declaration is now accepted by GHC:
-
- ::
-
- data T a where
- Typed :: forall a -> a -> T a
-
- See :ref:`visible-forall-in-gadts` for details.
-
-Compiler
-~~~~~~~~
-
-- An improved error message is introduced to refer users to the heap-controlling flags of the RTS when there is a heap overflow during compilation. (#25198)
-
-- The kind checker now does a better job of finding type family instances for
- use in the kinds of other declarations in the same module. This fixes a number
- of tickets:
- :ghc-ticket:`12088`, :ghc-ticket:`12239`, :ghc-ticket:`14668`, :ghc-ticket:`15561`,
- :ghc-ticket:`16410`, :ghc-ticket:`16448`, :ghc-ticket:`16693`, :ghc-ticket:`19611`,
- :ghc-ticket:`20875`, :ghc-ticket:`21172`, :ghc-ticket:`22257`, :ghc-ticket:`25238`,
- :ghc-ticket:`25834`.
-
-- The compiler no longer accepts invalid ``type`` namespace specifiers in
- subordinate import lists (:ghc-ticket:`22581`).
-
-- A new flag, :ghc-flag:`-Wuseless-specialisations`, controls warnings emitted when GHC
- determines that a SPECIALISE pragma would have no effect.
-
-- A new flag, :ghc-flag:`-Wrule-lhs-equalities`, controls warnings emitted for RULES
- whose left-hand side attempts to quantify over equality constraints that
- previous GHC versions accepted quantifying over. GHC will now drop such RULES,
- emitting a warning message controlled by this flag.
-
- This warning is intended to give visibility to the fact that the RULES that
- previous GHC versions generated in such circumstances could never fire.
-
-- A new flag, :ghc-flag:`-Wunusable-unpack-pragmas`, controls warnings emitted
- when GHC is unable to unpack a data constructor field annotated by the
- ``{-# UNPACK #-}`` pragma.
-
- Previous GHC versions issued this warning unconditionally. Now it is possible
- to disable it with ``-Wno-unusable-unpack-pragmas`` or turn it into an error
- with ``-Werror=unusable-unpack-pragmas``.
-
-- Introduce a new warning :ghc-flag:`-Wpattern-namespace-specifier` to detect
- uses of the now deprecated ``pattern`` namespace specifier in import/export
- lists. See `GHC Proposal #581, section 2.3 <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0581-n…>`_.
-
-- Code coverage (:ghc-flag:`-fhpc`) now treats uses of record fields
- (including via :extension:`RecordWildCards` or :extension:`NamedFieldPuns`)
- as if the fields were accessed using the generated record selector functions,
- marking the fields as covered in coverage reports (:ghc-ticket:`17834`,
- :ghc-ticket:`26191`). Note that this currently only works when record fields
- (or values contained within them) are bound to variables, and usage of those
- variables marks the record selectors as covered. That is, a pattern like
- ``Foo{bar = Bar{baz = b}}`` will mark ``bar`` and ``baz`` as covered if ``b``
- is used, but the similar pattern ``Foo{bar = Bar{baz = 42}}`` will mark
- neither as covered.
-
-- SIMD support in the X86 native code generator has been extended with 128-bit
- integer operations. Also, ``shuffleFloatX4#`` and ``shuffleDoubleX2#`` no longer
- require ``-mavx``.
-
-- JSON diagnostics produced with (:ghc-flag:`-fdiagnostics-as-json`) now
- include the `rendered` diagnostics message, in the exact same format as what
- GHC would have produced without -fdiagnostics-as-json (including ANSI escape
- sequences).
-
-GHCi
-~~~~
-
-- :ghci-cmd:`:info` now outputs type declarations with @-binders that are
- considered semantically significant. See the documentation for :ghci-cmd:`:info`
- itself for a more detailed explanation.
-
-- GHCi errors and warnings now have their own numeric error codes that are
- displayed alongside the error.
-
-Runtime system
-~~~~~~~~~~~~~~
-
-- Add new runtime flag :rts-flag:`--optimistic-linking` which instructs the
- runtime linker to continue in the presence of unknown symbols. By default this
- flag is not passed, preserving previous behavior.
-
-Cmm
-~~~
-
-``base`` library
-~~~~~~~~~~~~~~~~
-
-``ghc-prim`` library
-~~~~~~~~~~~~~~~~~~~~
-
-``ghc`` library
-~~~~~~~~~~~~~~~
-
-* The `UnknownDiagnostic` constructor now takes an additional type argument
- for the type of hints corresponding to the diagnostic, and an additional
- value-level argument used for existential wrapping of the hints of the inner
- diagnostic.
-
-* Changes to the HPT and HUG interface:
-
- - `addToHpt` and `addListToHPT` were moved from `GHC.Unit.Home.ModInfo` to `GHC.Unit.Home.PackageTable` and deprecated in favour of `addHomeModInfoToHpt` and `addHomeModInfosToHpt`.
- - `UnitEnvGraph` and operations `unitEnv_lookup_maybe`, `unitEnv_foldWithKey, `unitEnv_singleton`, `unitEnv_adjust`, `unitEnv_insert`, `unitEnv_new` were moved from `GHC.Unit.Env` to `GHC.Unit.Home.Graph`.
- - The HomePackageTable (HPT) is now exported from `GHC.Unit.Home.PackageTable`,
- and is now backed by an IORef to avoid by construction very bad memory leaks.
- This means the API to the HPT now is for the most part in IO. For instance,
- `emptyHomePackageTable` and `addHomeModInfoToHpt` are now in IO.
- - `mkHomeUnitEnv` was moved to `GHC.Unit.Home.PackageTable`, and now takes two
- extra explicit arguments. To restore previous behaviour, pass `emptyUnitState`
- and `Nothing` as the first two arguments additionally.
- - `hugElts` was removed. Users should prefer `allUnits` to get the keys of the
- HUG (the typical use case), or `traverse` or `unitEnv_foldWithKey` in other
- cases.
-
-* Changes to `Language.Haskell.Syntax.Expr`
-
- - The `ParStmtBlock` list argument of the `ParStmt` constructor of `StmtLR` is now `NonEmpty`.
-
-* As part of the implementation of `GHC proposal 493 <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0493-s…>`_,
- the `SpecSig` constructor of `Sig` has been deprecated. It is replaced by
- the constructor `SpecSigE` which supports expressions at the head, rather than
- a lone variable.
-
-``ghc-heap`` library
-~~~~~~~~~~~~~~~~~~~~
-
-* The functions `getClosureInfoTbl_maybe`, `getClosureInfoTbl`,
- `getClosurePtrArgs` and `getClosurePtrArgs_maybe` have been added to allow
- reading of the relevant Closure attributes without reliance on incomplete
- selectors.
-
-``ghc-experimental`` library
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-- ``ghc-experimental`` now exposes ``GHC.RTS.Flags`` and ``GHC.Stats`` as
- ``GHC.RTS.Flags.Experimental`` and ``GHC.Stats.Experimental``. These are
- *also* exposed in ``base``, however the ``base`` versions will be deprecated as
- part of the split base project. See `CLC proposal 289
- <https://github.com/haskell/core-libraries-committee/issues/289>`__.
- Downstream consumers of these flags are encouraged to migrate to the
- ``ghc-experimental`` versions.
-
-
-
-``template-haskell`` library
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-- As part of the implementation of `GHC proposal 493 <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0493-s…>`_,
- the ``SpecialiseP`` constructor of the Template Haskell ``Pragma`` type, as
- well as the helpers ``pragSpecD`` and ``pragSpecInlD``, have been deprecated.
-
- They are replaced, respectively, by ``SpecialiseEP``, ``pragSpecED`` and
- ``pragSpecInlED``.
-
-Included libraries
-~~~~~~~~~~~~~~~~~~
-
-The package database provided with this distribution also contains a number of
-packages other than GHC itself. See the changelogs provided with these packages
-for further change information.
-
-.. ghc-package-list::
-
- libraries/array/array.cabal: Dependency of ``ghc`` library
- libraries/base/base.cabal: Core library
- libraries/binary/binary.cabal: Dependency of ``ghc`` library
- libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library
- libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility
- libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility
- libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library
- libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library
- libraries/directory/directory.cabal: Dependency of ``ghc`` library
- libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library
- libraries/filepath/filepath.cabal: Dependency of ``ghc`` library
- compiler/ghc.cabal: The compiler itself
- libraries/ghci/ghci.cabal: The REPL interface
- libraries/ghc-boot/ghc-boot.cabal: Internal compiler library
- libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library
- libraries/ghc-compact/ghc-compact.cabal: Core library
- libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library
- libraries/ghc-prim/ghc-prim.cabal: Core library
- utils/haddock/haddock-api/haddock-api.cabal: Dependency of ``haddock`` executable
- utils/haddock/haddock-library/haddock-library.cabal: Dependency of ``haddock`` executable
- libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable
- libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable
- libraries/integer-gmp/integer-gmp.cabal: Core library
- libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library
- libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library
- libraries/pretty/pretty.cabal: Dependency of ``ghc`` library
- libraries/process/process.cabal: Dependency of ``ghc`` library
- libraries/stm/stm.cabal: Dependency of ``haskeline`` library
- libraries/template-haskell/template-haskell.cabal: Core library
- libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library
- libraries/text/text.cabal: Dependency of ``Cabal`` library
- libraries/time/time.cabal: Dependency of ``ghc`` library
- libraries/transformers/transformers.cabal: Dependency of ``ghc`` library
- libraries/unix/unix.cabal: Dependency of ``ghc`` library
- libraries/Win32/Win32.cabal: Dependency of ``ghc`` library
- libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable
- libraries/os-string/os-string.cabal: Dependency of ``filepath`` library
- libraries/file-io/file-io.cabal: Dependency of ``directory`` library
=====================================
docs/users_guide/9.16.1-notes.rst
=====================================
@@ -0,0 +1,99 @@
+.. _release-9-16-1:
+
+Version 9.16.1
+==============
+
+The significant changes to the various parts of the compiler are listed in the
+following sections. See the `migration guide
+<https://gitlab.haskell.org/ghc/ghc/-/wikis/migration/9.16>`_ on the GHC Wiki
+for specific guidance on migrating programs to this release.
+
+Language
+~~~~~~~~
+
+Compiler
+~~~~~~~~
+
+- Code coverage's (:ghc-flag:`-fhpc`) treatment of record fields now extends
+ beyond record fields accessed via :extension:`RecordWildCards` and
+ :extension:`NamedFieldPuns`, and also handles access to nested record fields.
+ That is, in a pattern such as ``Foo{bar = Bar{baz = b}}`` both ``bar`` and
+ ``baz`` will now be marked as covered if ``b`` is evaluated. Note that this
+ currently only works when record fields (or values contained within them) are
+ bound to variables. The very similar pattern ``Foo{bar = Bar{baz = 42}}``
+ will will not yet mark ``bar`` or ``baz`` as covered.
+
+GHCi
+~~~~
+
+Runtime system
+~~~~~~~~~~~~~~
+
+Cmm
+~~~
+
+``base`` library
+~~~~~~~~~~~~~~~~
+
+``ghc-prim`` library
+~~~~~~~~~~~~~~~~~~~~
+
+``ghc`` library
+~~~~~~~~~~~~~~~
+
+``ghc-heap`` library
+~~~~~~~~~~~~~~~~~~~~
+
+``ghc-experimental`` library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``template-haskell`` library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Included libraries
+~~~~~~~~~~~~~~~~~~
+
+The package database provided with this distribution also contains a number of
+packages other than GHC itself. See the changelogs provided with these packages
+for further change information.
+
+.. ghc-package-list::
+
+ libraries/array/array.cabal: Dependency of ``ghc`` library
+ libraries/base/base.cabal: Core library
+ libraries/binary/binary.cabal: Dependency of ``ghc`` library
+ libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library
+ libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility
+ libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility
+ libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library
+ libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library
+ libraries/directory/directory.cabal: Dependency of ``ghc`` library
+ libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library
+ libraries/filepath/filepath.cabal: Dependency of ``ghc`` library
+ compiler/ghc.cabal: The compiler itself
+ libraries/ghci/ghci.cabal: The REPL interface
+ libraries/ghc-boot/ghc-boot.cabal: Internal compiler library
+ libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library
+ libraries/ghc-compact/ghc-compact.cabal: Core library
+ libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library
+ libraries/ghc-prim/ghc-prim.cabal: Core library
+ utils/haddock/haddock-api/haddock-api.cabal: Dependency of ``haddock`` executable
+ utils/haddock/haddock-library/haddock-library.cabal: Dependency of ``haddock`` executable
+ libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable
+ libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable
+ libraries/integer-gmp/integer-gmp.cabal: Core library
+ libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library
+ libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library
+ libraries/pretty/pretty.cabal: Dependency of ``ghc`` library
+ libraries/process/process.cabal: Dependency of ``ghc`` library
+ libraries/stm/stm.cabal: Dependency of ``haskeline`` library
+ libraries/template-haskell/template-haskell.cabal: Core library
+ libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library
+ libraries/text/text.cabal: Dependency of ``Cabal`` library
+ libraries/time/time.cabal: Dependency of ``ghc`` library
+ libraries/transformers/transformers.cabal: Dependency of ``ghc`` library
+ libraries/unix/unix.cabal: Dependency of ``ghc`` library
+ libraries/Win32/Win32.cabal: Dependency of ``ghc`` library
+ libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable
+ libraries/os-string/os-string.cabal: Dependency of ``filepath`` library
+ libraries/file-io/file-io.cabal: Dependency of ``directory`` library
=====================================
docs/users_guide/release-notes.rst
=====================================
@@ -4,4 +4,4 @@ Release notes
.. toctree::
:maxdepth: 1
- 9.14.1-notes
+ 9.16.1-notes
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7606c7914a7c8848e56ea425d6bd23d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7606c7914a7c8848e56ea425d6bd23d…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fix-upload-libs] 63 commits: NCG/LA64: Support finer-grained DBAR hints
by Ben Gamari (@bgamari) 12 Aug '25
by Ben Gamari (@bgamari) 12 Aug '25
12 Aug '25
Ben Gamari pushed to branch wip/fix-upload-libs at Glasgow Haskell Compiler / GHC
Commits:
bbaa44a7 by Peng Fan at 2025-07-16T16:50:42-04:00
NCG/LA64: Support finer-grained DBAR hints
For LA664 and newer uarchs, they have made finer granularity hints
available:
Bit4: ordering or completion (0: completion, 1: ordering)
Bit3: barrier for previous read (0: true, 1: false)
Bit2: barrier for previous write (0: true, 1: false)
Bit1: barrier for succeeding read (0: true, 1: false)
Bit0: barrier for succeeding write (0: true, 1: false)
And not affect the existing models because other hints are treated
as 'dbar 0' there.
- - - - -
7da86e16 by Andreas Klebinger at 2025-07-16T16:51:25-04:00
Disable -fprof-late-overloaded-calls for join points.
Currently GHC considers cost centres as destructive to
join contexts. Or in other words this is not considered valid:
join f x = ...
in
... -> scc<tick> jmp
This makes the functionality of `-fprof-late-overloaded-calls` not feasible
for join points in general. We used to try to work around this by putting the
ticks on the rhs of the join point rather than around the jump. However beyond
the loss of accuracy this was broken for recursive join points as we ended up
with something like:
rec-join f x = scc<tick> ... jmp f x
Which similarly is not valid as the tick once again destroys the tail call.
One might think we could limit ourselves to non-recursive tail calls and do
something clever like:
join f x = scc<tick> ...
in ... jmp f x
And sometimes this works! But sometimes the full rhs would look something like:
join g x = ....
join f x = scc<tick> ... -> jmp g x
Which, would again no longer be valid. I believe in the long run we can make
cost centre ticks non-destructive to join points. Or we could keep track of
where we are/are not allowed to insert a cost centre. But in the short term I will
simply disable the annotation of join calls under this flag.
- - - - -
7ee22fd5 by ARATA Mizuki at 2025-07-17T06:05:30-04:00
x86 NCG: Better lowering for shuffleFloatX4# and shuffleDoubleX2#
The new implementation
* make use of specialized instructions like (V)UNPCK{L,H}{PS,PD}, and
* do not require -mavx.
Close #26096
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
c6cd2da1 by Jappie Klooster at 2025-07-17T06:06:20-04:00
Update interact docs to explain about buffering
We need to tell the user to set to the
appropriate buffer format.
Otherwise, this function may get randomly stuck,
or just behave confusingly.
issue: https://gitlab.haskell.org/ghc/ghc/-/issues/26131
NB, I'm running this with cabal *NOT* ghci. ghci messes with buffering anyway.
```haskell
interaction :: String -> String
interaction "jappie" = "hi"
interaction "jakob" = "hello"
interaction x = "unkown input: " <> x
main :: IO ()
main = interact interaction
```
so in my input (prefixed by `>`) I get:
```
> jappie
unkown input: jappie
```
we confirmed later this was due to lack of \n matching.
Anyway movnig on to more unexpected stuff:
```haskell
main :: IO ()
main = do
interact (concatMap interaction . lines)
```
get's stuck forever.
actually `^D` (ctrl+d) unstucks it and runs all input as expected.
for example you can get:
```
> sdfkds
> fakdsf
unkown input: sdfkdsunkown input: fakdsf
```
This program works!
```haskell
interaction :: String -> String
interaction "jappie" = "hi \n"
interaction "jakob" = "hello \n"
interaction x = "unkown input: " <> x <> "\n"
main :: IO ()
main = do
interact (concatMap interaction . lines)
```
the reason is that linebuffering is set for both in and output by default.
so lines eats the input lines, and all the \n postfixes make sure the buffer
is put out.
- - - - -
9fa590a6 by Zubin Duggal at 2025-07-17T06:07:03-04:00
fetch_gitlab: Ensure we copy users_guide.pdf and Haddock.pdf to the release docs directory
Fixes #24093
- - - - -
cc650b4b by Andrew Lelechenko at 2025-07-17T12:30:24-04:00
Add Data.List.NonEmpty.mapMaybe
As per https://github.com/haskell/core-libraries-committee/issues/337
- - - - -
360fa82c by Duncan Coutts at 2025-07-17T12:31:14-04:00
base: Deprecate GHC.Weak.Finalize.runFinalizerBatch
https://github.com/haskell/core-libraries-committee/issues/342
- - - - -
f4e8466c by Alan Zimmerman at 2025-07-17T12:31:55-04:00
EPA: Update exact printing based on GHC 9.14 tests
As a result of migrating the GHC ghc-9.14 branch tests to
ghc-exactprint in
https://github.com/alanz/ghc-exactprint/tree/ghc-9.14, a couple of
discrepancies were picked up
- The opening paren for a DefaultDecl was printed in the wrong place
- The import declaration level specifiers were not printed.
This commit adds those fixes, and some tests for them.
The tests brought to light that the ImportDecl ppr instance had not
been updated for level specifiers, so it updates that too.
- - - - -
8b731e3c by Matthew Pickering at 2025-07-21T13:36:43-04:00
level imports: Fix infinite loop with cyclic module imports
I didn't anticipate that downsweep would run before we checked for
cyclic imports. Therefore we need to use the reachability function which
handles cyclic graphs.
Fixes #26087
- - - - -
d751a9f1 by Pierre Thierry at 2025-07-21T13:37:28-04:00
Fix documentation about deriving from generics
- - - - -
f8d9d016 by Andrew Lelechenko at 2025-07-22T21:13:28-04:00
Fix issues with toRational for types capable to represent infinite and not-a-number values
This commit fixes all of the following pitfalls:
> toRational (read "Infinity" :: Double)
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216 % 1
> toRational (read "NaN" :: Double)
269653970229347386159395778618353710042696546841345985910145121736599013708251444699062715983611304031680170819807090036488184653221624933739271145959211186566651840137298227914453329401869141179179624428127508653257226023513694322210869665811240855745025766026879447359920868907719574457253034494436336205824 % 1
> realToFrac (read "NaN" :: Double) -- With -O0
Infinity
> realToFrac (read "NaN" :: Double) -- With -O1
NaN
> realToFrac (read "NaN" :: Double) :: CDouble
Infinity
> realToFrac (read "NaN" :: CDouble) :: Double
Infinity
Implements https://github.com/haskell/core-libraries-committee/issues/338
- - - - -
5dabc718 by Zubin Duggal at 2025-07-22T21:14:10-04:00
haddock: Don't warn about missing link destinations for derived names.
Fixes #26114
- - - - -
9c3a0937 by Matthew Pickering at 2025-07-22T21:14:52-04:00
template haskell: use a precise condition when implicitly lifting
Implicit lifting corrects a level error by replacing references to `x`
with `$(lift x)`, therefore you can use a level `n` binding at level `n
+ 1`, if it can be lifted.
Therefore, we now have a precise check that the use level is 1 more than
the bind level.
Before this bug was not observable as you only had 0 and 1 contexts but
it is easily evident when using explicit level imports.
Fixes #26088
- - - - -
5144b22f by Andreas Klebinger at 2025-07-22T21:15:34-04:00
Add since tag and more docs for do-clever-arg-eta-expansion
Fixes #26113
- - - - -
c865623b by Andreas Klebinger at 2025-07-22T21:15:34-04:00
Add since tag for -fexpose-overloaded-unfoldings
Fixes #26112
- - - - -
49a44ab7 by Simon Hengel at 2025-07-23T17:59:55+07:00
Refactor GHC.Driver.Errors.printMessages
- - - - -
84711c39 by Simon Hengel at 2025-07-23T18:27:34+07:00
Respect `-fdiagnostics-as-json` for error messages from pre-processors
(fixes #25480)
- - - - -
d046b5ab by Simon Hengel at 2025-07-24T06:12:05-04:00
Include the rendered message in -fdiagnostics-as-json output
This implements #26173.
- - - - -
d2b89603 by Ben Gamari at 2025-07-24T06:12:47-04:00
rts/Interpreter: Factor out ctoi tuple info tables into data
Instead of a massive case let's put this into data which we can reuse
elsewhere.
- - - - -
4bc78496 by Sebastian Graf at 2025-07-24T16:19:34-04:00
CprAnal: Detect recursive newtypes (#25944)
While `cprTransformDataConWork` handles recursive data con workers, it
did not detect the case when a newtype is responsible for the recursion.
This is now detected in the `Cast` case of `cprAnal`.
The same reproducer made it clear that `isRecDataCon` lacked congruent
handling for `AppTy` and `CastTy`, now fixed.
Furthermore, the new repro case T25944 triggered this bug via an
infinite loop in `cprFix`, caused by the infelicity in `isRecDataCon`.
While it should be much less likely to trigger such an infinite loop now
that `isRecDataCon` has been fixed, I made sure to abort the loop after
10 iterations and emitting a warning instead.
Fixes #25944.
- - - - -
0a583689 by Sylvain Henry at 2025-07-24T16:20:26-04:00
STM: don't create a transaction in the rhs of catchRetry# (#26028)
We don't need to create a transaction for the rhs of (catchRetry#)
because contrary to the lhs we don't need to abort it on retry. Moreover
it is particularly harmful if we have code such as (#26028):
let cN = readTVar vN >> retry
tree = c1 `orElse` (c2 `orElse` (c3 `orElse` ...))
atomically tree
Because it will stack transactions for the rhss and the read-sets of all
the transactions will be iteratively merged in O(n^2) after the
execution of the most nested retry.
- - - - -
a49eca26 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Renaming around predicate types
.. we were (as it turned out) abstracting over
type-class selectors in SPECIALISATION rules!
Wibble isEqPred
- - - - -
f80375dd by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Refactor of Specialise.hs
This patch just tidies up `specHeader` a bit, removing one
of its many results, and adding some comments.
No change in behaviour.
Also add a few more `HasDebugCallStack` contexts.
- - - - -
1bd12371 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Improve treatment of SPECIALISE pragmas -- again!
This MR does another major refactor of the way that SPECIALISE
pragmas work, to fix #26115, #26116, #26117.
* We now /always/ solve forall-constraints in an all-or-nothing way.
See Note [Solving a Wanted forall-constraint] in GHC.Tc.Solver.Solve
This means we might have unsolved quantified constraints, which need
to be reported. See `inert_insts` in `getUnsolvedInerts`.
* I refactored the short-cut solver for type classes to work by
recursively calling the solver rather than by having a little baby
solver that kept being not clever enough.
See Note [Shortcut solving] in GHC.Tc.Solver.Dict
* I totally rewrote the desugaring of SPECIALISE pragmas, again.
The new story is in Note [Desugaring new-form SPECIALISE pragmas]
in GHC.HsToCore.Binds
Both old-form and new-form SPECIALISE pragmas now route through the same
function `dsSpec_help`. The tricky function `decomposeRuleLhs` is now used only
for user-written RULES, not for SPECIALISE pragmas.
* I improved `solveOneFromTheOther` to account for rewriter sets. Previously
it would solve a non-rewritten dict from a rewritten one. For equalities
we were already dealing with this, in
Some incidental refactoring
* A small refactor: `ebv_tcvs` in `EvBindsBar` now has a list of coercions, rather
than a set of tyvars. We just delay taking the free vars.
* GHC.Core.FVs.exprFVs now returns /all/ free vars.
Use `exprLocalFVs` for Local vars.
Reason: I wanted another variant for /evidence/ variables.
* Ues `EvId` in preference to `EvVar`. (Evidence variables are always Ids.)
Rename `isEvVar` to `isEvId`.
* I moved `inert_safehask` out of `InertCans` and into `InertSet` where it
more properly belongs.
Compiler-perf changes:
* There was a palpable bug (#26117) which this MR fixes in
newWantedEvVar, which bypassed all the subtle overlapping-Given
and shortcutting logic. (See the new `newWantedEvVar`.) Fixing this
but leads to extra dictionary bindings; they are optimised away quickly
but they made CoOpt_Read allocate 3.6% more.
* Hpapily T15164 improves.
* The net compiler-allocation change is 0.0%
Metric Decrease:
T15164
Metric Increase:
CoOpt_Read
T12425
- - - - -
953fd8f1 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Solve forall-constraints immediately, or not at all
This MR refactors the constraint solver to solve forall-constraints immediately,
rather than emitting an implication constraint to be solved later.
The most immediate motivation was that when solving quantified constraints
in SPECIALISE pragmas, we really really don't want to leave behind half-
solved implications. Also it's in tune with the approach of the new
short-cut solver, which recursively invokes the solver.
It /also/ saves quite a bit of plumbing; e.g
- The `wl_implics` field of `WorkList` is gone,
- The types of `solveSimpleWanteds` and friends are simplified.
- An EvFun contains binding, rather than an EvBindsVar ref-cell that
will in the future contain bindings. That makes `evVarsOfTerm`
simpler. Much nicer.
It also improves error messages a bit.
All described in Note [Solving a Wanted forall-constraint] in
GHC.Tc.Solver.Solve.
One tiresome point: in the tricky case of `inferConstraintsCoerceBased`
we make a forall-constraint. This we /do/ want to partially solve, so
we can infer a suitable context. (I'd be quite happy to force the user to
write a context, bt I don't want to change behavior.) So we want to generate
an /implication/ constraint in `emitPredSpecConstraints` rather than a
/forall-constraint/ as we were doing before. Discussed in (WFA3) of
the above Note.
Incidental refactoring
* `GHC.Tc.Deriv.Infer.inferConstraints` was consulting the state monad for
the DerivEnv that the caller had just consulted. Nicer to pass it as an
argument I think, so I have done that. No change in behaviour.
- - - - -
6921ab42 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Remove duplicated code in Ast.hs for evTermFreeVars
This is just a tidy up.
- - - - -
1165f587 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Small tc-tracing changes only
- - - - -
0776ffe0 by Simon Hengel at 2025-07-26T04:54:20-04:00
Respect `-fdiagnostics-as-json` for core diagnostics (see #24113)
- - - - -
cc1116e0 by Andrew Lelechenko at 2025-07-26T04:55:01-04:00
docs: add since pragma to Data.List.NonEmpty.mapMaybe
- - - - -
ee2dc248 by Simon Hengel at 2025-07-31T06:25:35-04:00
Update comments on `OptKind` to reflect the code reality
- - - - -
b029633a by Wen Kokke at 2025-07-31T06:26:21-04:00
rts: Disable --eventlog-flush-interval unless compiled with -threaded.
This commit fixes issue #26222:
Using --eventlog-flush-interval with the non-threaded RTS leads to eventlog corruption.
https://gitlab.haskell.org/ghc/ghc/-/issues/26222
This commit makes three changes when code is compiled against the non-threaded RTS:
1. It disables the --eventlog-flush-interval flag.
2. It disables the documentation for the --eventlog-flush-interval flag.
3. It disables the relevant state from RtsConfig and code from Timer.
4. It updates the entry for --eventlog-flush-interval in the users guide.
- - - - -
31159f1d by Wen Kokke at 2025-07-31T06:26:21-04:00
rts: Split T20006 into tests with and without -threaded
- - - - -
618687ef by Simon Hengel at 2025-07-31T06:27:03-04:00
docs/users_guide/win32-dlls.rst: Remove references to `readline`
- - - - -
083e40f1 by Rodrigo Mesquita at 2025-08-01T04:38:23-04:00
debugger: Uniquely identify breakpoints by internal id
Since b85b11994e0130ff2401dd4bbdf52330e0bcf776 (support inlining
breakpoints), a breakpoint has been identified at runtime by *two* pairs
of <module,index>.
- The first, aka a 'BreakpointId', uniquely identifies a breakpoint in
the source of a module by using the Tick index. A Tick index can index
into ModBreaks.modBreaks_xxx to fetch source-level information about
where that tick originated.
- When a user specifies e.g. a line breakpoint using :break, we'll reverse
engineer what a Tick index for that line
- We update the `BreakArray` of that module (got from the
LoaderState) at that tick index to `breakOn`.
- A BCO we can stop at is headed by a BRK_FUN instruction. This
instruction stores in an operand the `tick index` it is associated
to. We look it up in the associated `BreakArray` (also an operand)
and check wheter it was set to `breakOn`.
- The second, aka the `ibi_info_mod` + `ibi_info_ix` of the
`InternalBreakpointId`, uniquely index into the `imodBreaks_breakInfo`
-- the information we gathered during code generation about the
existing breakpoint *ocurrences*.
- Note that with optimisation there may be many occurrences of the
same source-tick-breakpoint across different modules. The
`ibi_info_ix` is unique per occurrence, but the `bi_tick_ix` may be
shared. See Note [Breakpoint identifiers] about this.
- Note that besides the tick ids, info ids are also stored in
`BRK_FUN` so the break handler can refer to the associated
`CgBreakInfo`.
In light of that, the driving changes come from the desire to have the
info_id uniquely identify the breakpoint at runtime, and the source tick
id being derived from it:
- An InternalBreakpointId should uniquely identify a breakpoint just
from the code-generation identifiers of `ibi_info_ix` and `ibi_info_mod`.
So we drop `ibi_tick_mod` and `ibi_tick_ix`.
- A BRK_FUN instruction need only record the "internal breakpoint id",
not the tick-level id.
So we drop the tick mod and tick index operands.
- A BreakArray should be indexed by InternalBreakpointId rather than
BreakpointId
That means we need to do some more work when setting a breakpoint.
Specifically, we need to figure out the internal ids (occurrences of a
breakpoint) from the source-level BreakpointId we want to set the
breakpoint at (recall :break refers to breaks at the source level).
Besides this change being an improvement to the handling of breakpoints
(it's clearer to have a single unique identifier than two competing
ones), it unlocks the possibility of generating "internal" breakpoints
during Cg (needed for #26042).
It should also be easier to introduce multi-threaded-aware `BreakArrays`
following this change (needed for #26064).
Se also the new Note [ModBreaks vs InternalModBreaks]
On i386-linux:
-------------------------
Metric Decrease:
interpreter_steplocal
-------------------------
- - - - -
bf03bbaa by Simon Hengel at 2025-08-01T04:39:05-04:00
Don't use MCDiagnostic for `ghcExit`
This changes the error message of `ghcExit` from
```
<no location info>: error:
Compilation had errors
```
to
```
Compilation had errors
```
- - - - -
a889ec75 by Simon Hengel at 2025-08-01T04:39:05-04:00
Respect `-fdiagnostics-as-json` for driver diagnostics (see #24113)
- - - - -
81577fe7 by Ben Gamari at 2025-08-02T04:29:39-04:00
configure: Allow override of CrossCompiling
As noted in #26236, the current inference logic is a bit simplistic. In
particular, there are many cases (e.g. building for a new libc) where
the target and host triples may differ yet we are still able to run the
produced artifacts as native code.
Closes #26236.
- - - - -
01136779 by Andreas Klebinger at 2025-08-02T04:30:20-04:00
rts: Support COFF BigObj files in archives.
- - - - -
1f9e4f54 by Stephen Morgan at 2025-08-03T15:14:08+10:00
refactor: Modify Data.List.sortOn to use (>) instead of compare. (#26184)
This lets a more efficient (>) operation be used if one exists.
This is technically a breaking change for malformed Ord instances, where
x > y is not equivalent to compare x y == GT.
Discussed by the CLC in issue #332: https://github.com/haskell/core-libraries-committee/issues/332
- - - - -
4f6bc9cf by fendor at 2025-08-04T17:50:06-04:00
Revert "base: Expose Backtraces constructor and fields"
This reverts commit 17db44c5b32fff82ea988fa4f1a233d1a27bdf57.
- - - - -
bcdec657 by Zubin Duggal at 2025-08-05T10:37:29+05:30
compiler: Export a version of `newNameCache` that is not prone to footguns.
`newNameCache` must be initialized with both a non-"reserved" unique tag, as well
as a list of known key names. Failing to do so results in hard to debug unique conflicts.
It is difficult for API users to tell which unique tags are safe to use. So instead of leaving
this up to the user to decide, we now export a version of `newNameCache` which uses a guaranteed
non-reserved unique tag. In fact, this is now the way the unique tag is initialized for all invocations
of the compiler.
The original version of `newNameCache` is now exported as `newNameCache'` for advanced users.
We also deprecate `initNameCache` as it is also prone to footguns and is completely subsumed in
functionality by `newNameCache` and `newNameCache'`.
Fixes #26135 and #26055
- - - - -
57d3b4a8 by Andrew Lelechenko at 2025-08-05T18:36:31-04:00
hadrian: bump Stackage snapshot to LTS 24.2 / GHC 9.10.2
In line with #25693 we should use GHC 9.10 as a boot compiler,
while Hadrian stack.yaml was stuck on GHC 9.6.
- - - - -
c2a78cea by Peng Fan at 2025-08-05T18:37:27-04:00
NCG/LA64: implement atomic write with finer-grained DBAR hints
Signed-off-by: Peng Fan <fanpeng(a)loongson.cn>
- - - - -
95231c8e by Teo Camarasu at 2025-08-06T08:35:58-04:00
CODEOWNERS: add CLC as codeowner of base
We also remove hvr, since I think he is no longer active
- - - - -
77df0ded by Andrew Lelechenko at 2025-08-06T08:36:39-04:00
Bump submodule text to 2.1.3
- - - - -
8af260d0 by Nikolaos Chatzikonstantinou at 2025-08-06T08:37:23-04:00
docs: fix internal import in getopt examples
This external-facing doc example shouldn't mention GHC internals when
using 'fromMaybe'.
- - - - -
69cc16ca by Marc Scholten at 2025-08-06T15:51:28-04:00
README: Add note on ghc.nix
- - - - -
93a2f450 by Daniel Díaz at 2025-08-06T15:52:14-04:00
Link to the "Strict Bindings" docs from the linear types docs
Strict Bidings are relevant for the kinds of multiplicity annotations
linear lets support.
- - - - -
246b7853 by Matthew Pickering at 2025-08-07T06:58:30-04:00
level imports: Check the level of exported identifiers
The level imports specification states that exported identifiers have to
be at level 0. This patch adds the requird level checks that all
explicitly mentioned identifiers occur at level 0.
For implicit export specifications (T(..) and module B), only level 0
identifiers are selected for re-export.
ghc-proposal: https://github.com/ghc-proposals/ghc-proposals/pull/705
Fixes #26090
- - - - -
358bc4fc by fendor at 2025-08-07T06:59:12-04:00
Bump GHC on darwin CI to 9.10.1
- - - - -
1903ae35 by Matthew Pickering at 2025-08-07T12:21:10+01:00
ipe: Place strings and metadata into specific .ipe section
By placing the .ipe metadata into a specific section it can be stripped
from the final binary if desired.
```
objcopy --remove-section .ipe <binary>
upx <binary>
```
Towards #21766
- - - - -
c80dd91c by Matthew Pickering at 2025-08-07T12:22:42+01:00
ipe: Place magic word at the start of entries in the .ipe section
The magic word "IPE\nIPE\n" is placed at the start of .ipe sections,
then if the section is stripped, we can check whether the section starts
with the magic word or not to determine whether there is metadata
present or not.
Towards #21766
- - - - -
cab42666 by Matthew Pickering at 2025-08-07T12:22:42+01:00
ipe: Use stable IDs for IPE entries
IPEs have historically been indexed and reported by their address.
This makes it impossible to compare profiles between runs, since the
addresses may change (due to ASLR) and also makes it tricky to separate
out the IPE map from the binary.
This small patch adds a stable identifier for each IPE entry.
The stable identifier is a single 64 bit word. The high-bits are a
per-module identifier and the low bits identify which entry in each
module.
1. When a node is added into the IPE buffer it is assigned a unique
identifier from an incrementing global counter.
2. Each entry already has an index by it's position in the
`IpeBufferListNode`.
The two are combined together by the `IPE_ENTRY_KEY` macro.
Info table profiling uses the stable identifier rather than the address
of the info table.
The benefits of this change are:
* Profiles from different runs can be easily compared
* The metadata can be extracted from the binary (via the eventlog for
example) and then stripped from the executable.
Fixes #21766
- - - - -
2860a9a5 by Simon Peyton Jones at 2025-08-07T20:29:18-04:00
In TcSShortCut, typechecker plugins should get empty Givens
Solving in TcShortCut mode means /ignoring the Givens/. So we
should not pass them to typechecker plugins!
Fixes #26258.
This is a fixup to the earlier MR:
commit 1bd12371feacc52394a0e660ef9349f9e8ee1c06
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Jul 21 10:04:49 2025 +0100
Improve treatment of SPECIALISE pragmas -- again!
- - - - -
2157db2d by sterni at 2025-08-08T15:32:39-04:00
hadrian: enable terminfo if --with-curses-* flags are given
The GHC make build system used to support WITH_TERMINFO in ghc.mk which
allowed controlling whether to build GHC with terminfo or not. hadrian
has replaced this with a system where this is effectively controlled by
the cross-compiling setting (the default WITH_TERMINFO value was bassed
on CrossCompiling, iirc).
This behavior is undesireable in some cases and there is not really a
good way to work around it. Especially for downstream packagers,
modifying this via UserSettings is not really feasible since such a
source file has to be kept in sync with Settings/Default.hs manually
since it can't import Settings.Default or any predefined Flavour
definitions.
To avoid having to add a new setting to cfg/system.config and/or a new
configure flag (though I'm happy to implement both if required), I've
chosen to take --with-curses-* being set explicitly as an indication
that the user wants to have terminfo enabled. This would work for
Nixpkgs which sets these flags [1] as well as haskell.nix [2] (which
goes to some extreme measures [3] [4] to force terminfo in all scenarios).
In general, I'm an advocate for making the GHC build be the same for
native and cross insofar it is possible since it makes packaging GHC and
Haskell related things while still supporting cross much less
compilicated. A more minimal GHC with reduced dependencies should
probably be a specific flavor, not the default.
Partially addresses #26288 by forcing terminfo to be built if the user
explicitly passes configure flags related to it. However, it isn't built
by default when cross-compiling yet nor is there an explicit way to
control the package being built.
[1]: https://github.com/NixOS/nixpkgs/blob/3a7266fcefcb9ce353df49ba3f292d0644376…
[2]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
[3]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
[4]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
- - - - -
b3c31488 by David Feuer at 2025-08-08T15:33:21-04:00
Add default QuasiQuoters
Add `defaultQuasiQuoter` and `namedDefaultQuasiQuoter` to make it easier
to write `QuasiQuoters` that give helpful error messages when they're
used in inappropriate contexts.
Closes #24434.
- - - - -
03555ed8 by Sylvain Henry at 2025-08-10T22:20:57-04:00
Handle non-fractional CmmFloats in Cmm's CBE (#26229)
Since f8d9d016305be355f518c141f6c6d4826f2de9a2, toRational for Float and
Double converts float's infinity and NaN into Rational's infinity and
NaN (respectively 1%0 and 0%0).
Cmm CommonBlockEliminator hashing function needs to take these values
into account as they can appear as literals now. See added testcase.
- - - - -
6c956af3 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Fix extensions list in `DoAndIfThenElse` docs
- - - - -
6dc420b1 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Document status of `RelaxedPolyRec` extension
This adds a brief extension page explaining the status of the
`RelaxedPolyRec` extension. The behaviour of this mode is already
explained elsewhere, so this page is mainly for completeness so that
various lists of extensions have somewhere to point to for this flag.
Fixes #18630
- - - - -
18036d52 by Simon Peyton Jones at 2025-08-11T11:31:20-04:00
Take more care in zonkEqTypes on AppTy/AppTy
This patch fixes #26256.
See Note [zonkEqTypes and the PKTI] in GHC.Tc.Solver.Equality
- - - - -
c8d76a29 by Zubin Duggal at 2025-08-11T11:32:02-04:00
ci: upgrade bootstrap compiler on windows to 9.10.1
- - - - -
788ab6cb by Ben Gamari at 2025-08-12T09:11:01-04:00
gitlab/upload_libs: Drop mentions of ghc-prim
This package no longer exists. PrimOpWrappers has been moved to
ghc-internal.
Fixes #26177.
- - - - -
39d0be60 by Ben Gamari at 2025-08-12T09:11:01-04:00
gitlab-ci: Split up hackage-doc-tarball job into two
One for the nightly pipeline and another for the release pipeline. This
both improves the naming and makes the dependency structure more
explicit.
- - - - -
249 changed files:
- .gitlab-ci.yml
- .gitlab/darwin/toolchain.nix
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/upload_ghc_libs.py
- CODEOWNERS
- README.md
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/LA64/Instr.hs
- compiler/GHC/CmmToAsm/LA64/Ppr.hs
- compiler/GHC/CmmToAsm/PPC/Ppr.hs
- compiler/GHC/CmmToAsm/Ppr.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToLlvm/Data.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/FVs.hs
- compiler/GHC/Core/LateCC/OverloadedCalls.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/CprAnal.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Subst.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/Unfold/Make.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Driver/CmdLine.hs
- compiler/GHC/Driver/Errors.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Parser.y
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/InfoTableProv.hs
- compiler/GHC/SysTools/Process.hs
- compiler/GHC/SysTools/Tasks.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Infer.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.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/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Rewrite.hs
- compiler/GHC/Tc/Solver/Solve.hs
- + compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/Solver/Types.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.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/Type.hs
- compiler/GHC/Types/Error.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Utils/Error.hs
- compiler/GHC/Utils/Logger.hs
- configure.ac
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/conf.py
- docs/users_guide/debug-info.rst
- + docs/users_guide/diagnostics-as-json-schema-1_2.json
- docs/users_guide/expected-undocumented-flags.txt
- docs/users_guide/exts/doandifthenelse.rst
- docs/users_guide/exts/linear_types.rst
- + docs/users_guide/exts/relaxed_poly_rec.rst
- docs/users_guide/exts/strict.rst
- docs/users_guide/exts/types.rst
- docs/users_guide/profiling.rst
- docs/users_guide/runtime_control.rst
- docs/users_guide/using-optimisation.rst
- docs/users_guide/using.rst
- docs/users_guide/win32-dlls.rst
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Monad.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- hadrian/stack.yaml
- hadrian/stack.yaml.lock
- libraries/base/changelog.md
- libraries/base/src/Control/Exception/Backtrace.hs
- libraries/base/src/Data/List/NonEmpty.hs
- libraries/base/src/GHC/Generics.hs
- libraries/base/src/GHC/Weak/Finalize.hs
- libraries/base/src/System/Console/GetOpt.hs
- libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- libraries/ghc-internal/src/GHC/Internal/Real.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghci/GHCi/Debugger.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/changelog.md
- libraries/text
- rts/Disassembler.c
- rts/Exception.cmm
- rts/IPE.c
- rts/Interpreter.c
- rts/PrimOps.cmm
- rts/ProfHeap.c
- rts/RaiseAsync.c
- rts/RtsFlags.c
- rts/STM.c
- rts/Timer.c
- rts/eventlog/EventLog.c
- rts/include/rts/Flags.h
- rts/include/rts/IPE.h
- rts/linker/LoadArchive.c
- testsuite/tests/corelint/T21115b.stderr
- + testsuite/tests/cpranal/sigs/T25944.hs
- + testsuite/tests/cpranal/sigs/T25944.stderr
- testsuite/tests/cpranal/sigs/all.T
- testsuite/tests/deriving/should_compile/T20815.hs
- testsuite/tests/deriving/should_fail/T12768.stderr
- testsuite/tests/deriving/should_fail/T1496.stderr
- testsuite/tests/deriving/should_fail/T5498.stderr
- testsuite/tests/deriving/should_fail/T7148.stderr
- testsuite/tests/deriving/should_fail/T7148a.stderr
- testsuite/tests/driver/json.stderr
- testsuite/tests/driver/json_warn.stderr
- testsuite/tests/haddock/haddock_testsuite/Makefile
- + testsuite/tests/haddock/haddock_testsuite/T26114.hs
- + testsuite/tests/haddock/haddock_testsuite/T26114.stdout
- testsuite/tests/haddock/haddock_testsuite/all.T
- testsuite/tests/hiefile/should_run/HieQueries.stdout
- testsuite/tests/hiefile/should_run/TestUtils.hs
- testsuite/tests/impredicative/T17332.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/lib/stm/T26028.hs
- + testsuite/tests/lib/stm/T26028.stdout
- + testsuite/tests/lib/stm/all.T
- + testsuite/tests/numeric/should_compile/T26229.hs
- testsuite/tests/numeric/should_compile/all.T
- testsuite/tests/numeric/should_run/T9810.stdout
- + testsuite/tests/partial-sigs/should_compile/T26256.hs
- + testsuite/tests/partial-sigs/should_compile/T26256.stderr
- testsuite/tests/partial-sigs/should_compile/all.T
- testsuite/tests/printer/Makefile
- + testsuite/tests/printer/TestLevelImports.hs
- + testsuite/tests/printer/TestNamedDefaults.hs
- testsuite/tests/printer/all.T
- testsuite/tests/quantified-constraints/T15290a.stderr
- testsuite/tests/quantified-constraints/T19690.stderr
- testsuite/tests/quantified-constraints/T19921.stderr
- testsuite/tests/quantified-constraints/T21006.stderr
- testsuite/tests/roles/should_fail/RolesIArray.stderr
- testsuite/tests/rts/flags/all.T
- testsuite/tests/rts/ipe/ipeMap.c
- testsuite/tests/rts/ipe/ipe_lib.c
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simd/should_run/doublex2_shuffle.hs
- + testsuite/tests/simd/should_run/doublex2_shuffle.stdout
- + testsuite/tests/simd/should_run/doublex2_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/doublex2_shuffle_baseline.stdout
- + testsuite/tests/simd/should_run/floatx4_shuffle.hs
- + testsuite/tests/simd/should_run/floatx4_shuffle.stdout
- + testsuite/tests/simd/should_run/floatx4_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/floatx4_shuffle_baseline.stdout
- + testsuite/tests/simplCore/should_compile/T26115.hs
- + testsuite/tests/simplCore/should_compile/T26115.stderr
- + testsuite/tests/simplCore/should_compile/T26116.hs
- + testsuite/tests/simplCore/should_compile/T26116.stderr
- + testsuite/tests/simplCore/should_compile/T26117.hs
- + testsuite/tests/simplCore/should_compile/T26117.stderr
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/splice-imports/DodgyLevelExport.hs
- + testsuite/tests/splice-imports/DodgyLevelExport.stderr
- + testsuite/tests/splice-imports/DodgyLevelExportA.hs
- + testsuite/tests/splice-imports/LevelImportExports.hs
- + testsuite/tests/splice-imports/LevelImportExports.stdout
- + testsuite/tests/splice-imports/LevelImportExportsA.hs
- testsuite/tests/splice-imports/Makefile
- + testsuite/tests/splice-imports/ModuleExport.hs
- + testsuite/tests/splice-imports/ModuleExport.stderr
- + testsuite/tests/splice-imports/ModuleExportA.hs
- + testsuite/tests/splice-imports/ModuleExportB.hs
- + testsuite/tests/splice-imports/T26087.stderr
- + testsuite/tests/splice-imports/T26087A.hs
- + testsuite/tests/splice-imports/T26087B.hs
- + testsuite/tests/splice-imports/T26088.stderr
- + testsuite/tests/splice-imports/T26088A.hs
- + testsuite/tests/splice-imports/T26088B.hs
- + testsuite/tests/splice-imports/T26090.hs
- + testsuite/tests/splice-imports/T26090.stderr
- + testsuite/tests/splice-imports/T26090A.hs
- testsuite/tests/splice-imports/all.T
- testsuite/tests/typecheck/should_compile/T12427a.stderr
- testsuite/tests/typecheck/should_compile/T23171.hs
- + testsuite/tests/typecheck/should_compile/T26256a.hs
- testsuite/tests/typecheck/should_compile/TcSpecPragmas.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T14605.hs
- testsuite/tests/typecheck/should_fail/T14605.stderr
- testsuite/tests/typecheck/should_fail/T15801.stderr
- testsuite/tests/typecheck/should_fail/T18640a.stderr
- testsuite/tests/typecheck/should_fail/T18640b.stderr
- testsuite/tests/typecheck/should_fail/T19627.stderr
- testsuite/tests/typecheck/should_fail/T21530b.stderr
- testsuite/tests/typecheck/should_fail/T22912.stderr
- testsuite/tests/typecheck/should_fail/tcfail174.stderr
- utils/check-exact/ExactPrint.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe9dcff52ee5a03637fba60d9f4746…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe9dcff52ee5a03637fba60d9f4746…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fix-upload-libs] Apply 1 suggestion(s) to 1 file(s)
by Ben Gamari (@bgamari) 12 Aug '25
by Ben Gamari (@bgamari) 12 Aug '25
12 Aug '25
Ben Gamari pushed to branch wip/fix-upload-libs at Glasgow Haskell Compiler / GHC
Commits:
fe9dcff5 by Ben Gamari at 2025-08-12T13:10:22+00:00
Apply 1 suggestion(s) to 1 file(s)
- - - - -
1 changed file:
- .gitlab/rel_eng/upload_ghc_libs.py
Changes:
=====================================
.gitlab/rel_eng/upload_ghc_libs.py
=====================================
@@ -110,6 +110,7 @@ PACKAGES = {
Package('base', Path("libraries/base"), prep_base),
Package('ghc-internal', Path("libraries/ghc-internal"), prep_ghc_internal),
Package('ghc-experimental', Path("libraries/ghc-experimental"), no_prep),
+ Package('ghc-prim', Path("libraries/ghc-prim"), no_prep),
Package('integer-gmp', Path("libraries/integer-gmp"), no_prep),
Package('ghc-bignum', Path("libraries/ghc-bignum"), prep_ghc_bignum),
Package('template-haskell', Path("libraries/template-haskell"), no_prep),
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe9dcff52ee5a03637fba60d9f47461…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe9dcff52ee5a03637fba60d9f47461…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/26264] compiler: Attempt to systematize Unique tags by introducing an ADT for each different tag
by Zubin (@wz1000) 12 Aug '25
by Zubin (@wz1000) 12 Aug '25
12 Aug '25
Zubin pushed to branch wip/26264 at Glasgow Haskell Compiler / GHC
Commits:
742e29e0 by Zubin Duggal at 2025-08-12T18:34:21+05:30
compiler: Attempt to systematize Unique tags by introducing an ADT for each different tag
Fixes #26264
- - - - -
26 changed files:
- compiler/GHC/Builtin/Uniques.hs
- compiler/GHC/Cmm/Info.hs
- compiler/GHC/Cmm/Pipeline.hs
- compiler/GHC/Cmm/UniqueRenamer.hs
- compiler/GHC/CmmToLlvm/Base.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/Simplify/Monad.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/JS/JStg/Monad.hs
- compiler/GHC/Platform/Reg.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Stg/EnforceEpt.hs
- compiler/GHC/Stg/Pipeline.hs
- compiler/GHC/StgToCmm/ExtCode.hs
- compiler/GHC/StgToCmm/Monad.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Unique.hs
- compiler/GHC/Types/Unique/DSM.hs
- compiler/GHC/Types/Unique/Supply.hs
Changes:
=====================================
compiler/GHC/Builtin/Uniques.hs
=====================================
@@ -121,7 +121,7 @@ mkSumTyConUnique arity =
assertPpr (arity <= 0x3f) (ppr arity) $
-- 0x3f since we only have 6 bits to encode the
-- alternative
- mkUniqueInt 'z' (arity `shiftL` 8 .|. 0xfc)
+ mkUniqueInt SumTag (arity `shiftL` 8 .|. 0xfc)
-- | Inverse of 'mkSumTyConUnique'
isSumTyConUnique :: Unique -> Maybe Arity
@@ -137,7 +137,7 @@ mkSumDataConUnique alt arity
| alt >= arity
= panic ("mkSumDataConUnique: " ++ show alt ++ " >= " ++ show arity)
| otherwise
- = mkUniqueInt 'z' (arity `shiftL` 8 + alt `shiftL` 2) {- skip the tycon -}
+ = mkUniqueInt SumTag (arity `shiftL` 8 + alt `shiftL` 2) {- skip the tycon -}
getUnboxedSumName :: Int -> Name
getUnboxedSumName n
@@ -224,17 +224,17 @@ selector Uniques takes inspiration from the encoding for unboxed sum Uniques.
-}
mkCTupleTyConUnique :: Arity -> Unique
-mkCTupleTyConUnique a = mkUniqueInt 'k' (2*a)
+mkCTupleTyConUnique a = mkUniqueInt CTupleTag (2*a)
mkCTupleDataConUnique :: Arity -> Unique
-mkCTupleDataConUnique a = mkUniqueInt 'm' (3*a)
+mkCTupleDataConUnique a = mkUniqueInt CTupleDataTag (3*a)
mkCTupleSelIdUnique :: ConTagZ -> Arity -> Unique
mkCTupleSelIdUnique sc_pos arity
| sc_pos >= arity
= panic ("mkCTupleSelIdUnique: " ++ show sc_pos ++ " >= " ++ show arity)
| otherwise
- = mkUniqueInt 'j' (arity `shiftL` cTupleSelIdArityBits + sc_pos)
+ = mkUniqueInt CTupleSelTag (arity `shiftL` cTupleSelIdArityBits + sc_pos)
-- | Inverse of 'mkCTupleTyConUnique'
isCTupleTyConUnique :: Unique -> Maybe Arity
@@ -288,12 +288,12 @@ cTupleSelIdPosBitmask = 0xff
-- Normal tuples
mkTupleDataConUnique :: Boxity -> Arity -> Unique
-mkTupleDataConUnique Boxed a = mkUniqueInt '7' (3*a) -- may be used in C labels
-mkTupleDataConUnique Unboxed a = mkUniqueInt '8' (3*a)
+mkTupleDataConUnique Boxed a = mkUniqueInt BoxedTupleDataTag (3*a) -- may be used in C labels
+mkTupleDataConUnique Unboxed a = mkUniqueInt UnboxedTupleDataTag (3*a)
mkTupleTyConUnique :: Boxity -> Arity -> Unique
-mkTupleTyConUnique Boxed a = mkUniqueInt '4' (2*a)
-mkTupleTyConUnique Unboxed a = mkUniqueInt '5' (2*a)
+mkTupleTyConUnique Boxed a = mkUniqueInt BoxedTupleTyConTag (2*a)
+mkTupleTyConUnique Unboxed a = mkUniqueInt UnboxedTupleTyConTag (2*a)
-- | Inverse of 'mkTupleTyConUnique'
isTupleTyConUnique :: Unique -> Maybe (Boxity, Arity)
@@ -397,50 +397,50 @@ mkPrimOpIdUnique :: Int -> Unique
mkPrimOpWrapperUnique :: Int -> Unique
mkPreludeMiscIdUnique :: Int -> Unique
-mkAlphaTyVarUnique i = mkUniqueInt '1' i
-mkPreludeClassUnique i = mkUniqueInt '2' i
+mkAlphaTyVarUnique i = mkUniqueInt AlphaTyVarTag i
+mkPreludeClassUnique i = mkUniqueInt PreludeClassTag i
--------------------------------------------------
-mkPrimOpIdUnique op = mkUniqueInt '9' (2*op)
-mkPrimOpWrapperUnique op = mkUniqueInt '9' (2*op+1)
-mkPreludeMiscIdUnique i = mkUniqueInt '0' i
+mkPrimOpIdUnique op = mkUniqueInt PrimOpTag (2*op)
+mkPrimOpWrapperUnique op = mkUniqueInt PrimOpTag (2*op+1)
+mkPreludeMiscIdUnique i = mkUniqueInt PreludeMiscIdTag i
mkPseudoUniqueE, mkBuiltinUnique :: Int -> Unique
-mkBuiltinUnique i = mkUniqueInt 'B' i
-mkPseudoUniqueE i = mkUniqueInt 'E' i -- used in NCG spiller to create spill VirtualRegs
+mkBuiltinUnique i = mkUniqueInt BuiltinTag i
+mkPseudoUniqueE i = mkUniqueInt PseudoTag i -- used in NCG spiller to create spill VirtualRegs
mkRegSingleUnique, mkRegPairUnique, mkRegSubUnique, mkRegClassUnique :: Int -> Unique
-mkRegSingleUnique = mkUniqueInt 'R'
-mkRegSubUnique = mkUniqueInt 'S'
-mkRegPairUnique = mkUniqueInt 'P'
-mkRegClassUnique = mkUniqueInt 'L'
+mkRegSingleUnique = mkUniqueInt RegSingleTag
+mkRegSubUnique = mkUniqueInt RegSubTag
+mkRegPairUnique = mkUniqueInt RegPairTag
+mkRegClassUnique = mkUniqueInt RegClassTag
mkCostCentreUnique :: Int -> Unique
-mkCostCentreUnique = mkUniqueInt 'C'
+mkCostCentreUnique = mkUniqueInt CostCentreTag
varNSUnique, dataNSUnique, tvNSUnique, tcNSUnique :: Unique
-varNSUnique = mkUnique 'i' 0
-dataNSUnique = mkUnique 'd' 0
-tvNSUnique = mkUnique 'v' 0
-tcNSUnique = mkUnique 'c' 0
+varNSUnique = mkUnique VarNSTag 0
+dataNSUnique = mkUnique DataNSTag 0
+tvNSUnique = mkUnique TvNSTag 0
+tcNSUnique = mkUnique TcNSTag 0
mkFldNSUnique :: FastString -> Unique
-mkFldNSUnique fs = mkUniqueInt 'f' (uniqueOfFS fs)
+mkFldNSUnique fs = mkUniqueInt FldNSTag (uniqueOfFS fs)
isFldNSUnique :: Unique -> Bool
isFldNSUnique uniq = case unpkUnique uniq of
(tag, _) -> tag == 'f'
initExitJoinUnique :: Unique
-initExitJoinUnique = mkUnique 's' 0
+initExitJoinUnique = mkUnique SimplTag 0
--------------------------------------------------
-- Wired-in type constructor keys occupy *two* slots:
-- See Note [Related uniques for wired-in things]
mkPreludeTyConUnique :: Int -> Unique
-mkPreludeTyConUnique i = mkUniqueInt '3' (2*i)
+mkPreludeTyConUnique i = mkUniqueInt PreludeTyConTag (2*i)
tyConRepNameUnique :: Unique -> Unique
tyConRepNameUnique u = incrUnique u
@@ -450,7 +450,7 @@ tyConRepNameUnique u = incrUnique u
-- See Note [Related uniques for wired-in things]
mkPreludeDataConUnique :: Int -> Unique
-mkPreludeDataConUnique i = mkUniqueInt '6' (3*i) -- Must be alphabetic
+mkPreludeDataConUnique i = mkUniqueInt PreludeDataConTag (3*i) -- Must be alphabetic
dataConTyRepNameUnique, dataConWorkerUnique :: Unique -> Unique
dataConWorkerUnique u = incrUnique u
@@ -476,7 +476,7 @@ dataConTyRepNameUnique u = stepUnique u 2
-- A little delicate!
mkBoxingTyConUnique :: Int -> Unique
-mkBoxingTyConUnique i = mkUniqueInt 'b' (5*i)
+mkBoxingTyConUnique i = mkUniqueInt BoxingTyConTag (5*i)
boxingDataConUnique :: Unique -> Unique
boxingDataConUnique u = stepUnique u 2
=====================================
compiler/GHC/Cmm/Info.hs
=====================================
@@ -68,7 +68,7 @@ cmmToRawCmm :: Logger -> Profile -> CgStream CmmGroupSRTs a
-> IO (CgStream RawCmmGroup a)
cmmToRawCmm logger profile cmms
= do { let do_one :: [CmmDeclSRTs] -> UniqDSMT IO [RawCmmDecl]
- do_one cmm = setTagUDSMT 'i' $ do
+ do_one cmm = setTagUDSMT IfaceTag $ do
-- NB. strictness fixes a space leak. DO NOT REMOVE.
withTimingSilent logger (text "Cmm -> Raw Cmm") (\x -> seqList x ()) $ do
liftUniqDSM $
=====================================
compiler/GHC/Cmm/Pipeline.hs
=====================================
@@ -107,7 +107,7 @@ cpsTop logger platform cfg dus proc =
-- TODO(#25273): Use the deterministic UniqDSM (ie `runUniqueDSM`) instead
-- of UniqSM (see `initUs_`) to guarantee deterministic objects
-- when doing thread sanitization.
- us <- mkSplitUniqSupply 'u'
+ us <- mkSplitUniqSupply TsanTag
return $ initUs_ us $
annotateTSAN platform g
else return g
=====================================
compiler/GHC/Cmm/UniqueRenamer.hs
=====================================
@@ -85,7 +85,7 @@ renameDetUniq uq = do
Nothing -> do
new_w <- gets supply -- New deterministic unique in this `DetRnM`
let --(_tag, _) = unpkUnique uq
- det_uniq = mkUnique 'Q' new_w
+ det_uniq = mkUnique UniqueRenamerTag new_w
modify (\DetUniqFM{mapping, supply} ->
-- Update supply and mapping
DetUniqFM
=====================================
compiler/GHC/CmmToLlvm/Base.hs
=====================================
@@ -281,7 +281,7 @@ data LlvmEnv = LlvmEnv
, envConfig :: !LlvmCgConfig -- ^ Configuration for LLVM code gen
, envLogger :: !Logger -- ^ Logger
, envOutput :: BufHandle -- ^ Output buffer
- , envTag :: !Char -- ^ Tag for creating unique values
+ , envTag :: !UniqueTag -- ^ Tag for creating unique values
, envFreshMeta :: MetaId -- ^ Supply of fresh metadata IDs
, envUniqMeta :: UniqFM Unique MetaId -- ^ Global metadata nodes
, envFunMap :: LlvmEnvMap -- ^ Global functions so far, with type
@@ -344,7 +344,7 @@ runLlvm logger cfg ver out us m = do
, envConfig = cfg
, envLogger = logger
, envOutput = out
- , envTag = 'n'
+ , envTag = LlvmCodeGenTag
, envFreshMeta = MetaId 0
, envUniqMeta = emptyUFM
}
=====================================
compiler/GHC/Core/Opt/Monad.hs
=====================================
@@ -123,7 +123,7 @@ data CoreReader = CoreReader {
cr_name_ppr_ctx :: NamePprCtx,
cr_loc :: SrcSpan, -- Use this for log/error messages so they
-- are at least tagged with the right source file
- cr_uniq_tag :: !Char -- Tag for creating unique values
+ cr_uniq_tag :: !UniqueTag -- Tag for creating unique values
}
-- Note: CoreWriter used to be defined with data, rather than newtype. If it
@@ -182,7 +182,7 @@ instance MonadUnique CoreM where
runCoreM :: HscEnv
-> RuleBase
- -> Char -- ^ Mask
+ -> UniqueTag -- ^ Mask
-> Module
-> NamePprCtx
-> SrcSpan
@@ -267,7 +267,7 @@ getSrcSpanM = read cr_loc
addSimplCount :: SimplCount -> CoreM ()
addSimplCount count = write (CoreWriter { cw_simpl_count = count })
-getUniqTag :: CoreM Char
+getUniqTag :: CoreM UniqueTag
getUniqTag = read cr_uniq_tag
-- Convenience accessors for useful fields of HscEnv
=====================================
compiler/GHC/Core/Opt/Pipeline.hs
=====================================
@@ -59,6 +59,7 @@ import GHC.Types.Basic
import GHC.Types.Demand ( zapDmdEnvSig )
import GHC.Types.Name.Ppr
import GHC.Types.Var ( Var )
+import GHC.Types.Unique.Supply ( UniqueTag(..) )
import Control.Monad
import qualified GHC.LanguageExtensions as LangExt
@@ -78,7 +79,7 @@ core2core hsc_env guts@(ModGuts { mg_module = mod
, mg_rdr_env = rdr_env })
= do { hpt_rule_base <- home_pkg_rules
; let builtin_passes = getCoreToDo dflags hpt_rule_base extra_vars
- uniq_tag = 's'
+ uniq_tag = SimplTag
; (guts2, stats) <- runCoreM hsc_env hpt_rule_base uniq_tag mod
name_ppr_ctx loc $
=====================================
compiler/GHC/Core/Opt/Simplify/Monad.hs
=====================================
@@ -180,13 +180,9 @@ traceSmpl herald doc
************************************************************************
-}
--- See Note [Uniques for wired-in prelude things and known tags] in GHC.Builtin.Uniques
-simplTag :: Char
-simplTag = 's'
-
instance MonadUnique SimplM where
- getUniqueSupplyM = liftIO $ mkSplitUniqSupply simplTag
- getUniqueM = liftIO $ uniqFromTag simplTag
+ getUniqueSupplyM = liftIO $ mkSplitUniqSupply SimplTag
+ getUniqueM = liftIO $ uniqFromTag SimplTag
instance HasLogger SimplM where
getLogger = gets st_logger
=====================================
compiler/GHC/CoreToStg/Prep.hs
=====================================
@@ -251,7 +251,7 @@ corePrepPgm logger cp_cfg pgm_cfg
(\a -> a `seqList` ()) $ do
let initialCorePrepEnv = mkInitialCorePrepEnv cp_cfg
- us <- mkSplitUniqSupply 's'
+ us <- mkSplitUniqSupply StgTag
let implicit_binds = mkDataConWorkers
(cpPgm_generateDebugInfo pgm_cfg)
@@ -271,7 +271,7 @@ corePrepPgm logger cp_cfg pgm_cfg
corePrepExpr :: Logger -> CorePrepConfig -> CoreExpr -> IO CoreExpr
corePrepExpr logger config expr = do
withTiming logger (text "CorePrep [expr]") (\e -> e `seq` ()) $ do
- us <- mkSplitUniqSupply 's'
+ us <- mkSplitUniqSupply StgTag
let initialCorePrepEnv = mkInitialCorePrepEnv config
let new_expr = initUs_ us (cpeBodyNF initialCorePrepEnv expr)
putDumpFileMaybe logger Opt_D_dump_prep "CorePrep" FormatCore (ppr new_expr)
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -249,7 +249,7 @@ import GHC.Types.Name.Cache ( newNameCache )
import GHC.Types.Name.Reader
import GHC.Types.Name.Ppr
import GHC.Types.TyThing
-import GHC.Types.Unique.Supply (uniqFromTag)
+import GHC.Types.Unique.Supply ( uniqFromTag, UniqueTag(BcoTag) )
import GHC.Types.Unique.Set
import GHC.Utils.Fingerprint ( Fingerprint )
@@ -2728,7 +2728,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do
--
-- The id has to be exported for the JS backend. This isn't required for the
-- byte-code interpreter but it does no harm to always do it.
- u <- uniqFromTag 'I'
+ u <- uniqFromTag BcoTag
let binding_name = mkSystemVarName u (fsLit ("BCO_toplevel"))
let binding_id = mkExportedVanillaId binding_name (exprType simpl_expr)
=====================================
compiler/GHC/HsToCore/Monad.hs
=====================================
@@ -308,7 +308,7 @@ lookupCompleteMatch type_env hsc_env (CompleteMatch { cmConLikes = nms, cmResult
runDs :: HscEnv -> (DsGblEnv, DsLclEnv) -> DsM a -> IO (Messages DsMessage, Maybe a)
runDs hsc_env (ds_gbl, ds_lcl) thing_inside
- = do { res <- initTcRnIf 'd' hsc_env ds_gbl ds_lcl
+ = do { res <- initTcRnIf DsTag hsc_env ds_gbl ds_lcl
(tryM thing_inside)
; msgs <- readIORef (ds_msgs ds_gbl)
; let final_res
=====================================
compiler/GHC/Iface/Rename.hs
=====================================
@@ -34,6 +34,7 @@ import GHC.Types.Var
import GHC.Types.Basic
import GHC.Types.Name
import GHC.Types.Name.Shape
+import GHC.Types.Unique.Supply
import GHC.Utils.Outputable
import GHC.Utils.Misc
@@ -194,7 +195,7 @@ initRnIface hsc_env iface insts nsubst do_this = do
sh_if_errs = errs_var
}
-- Modeled off of 'initTc'
- res <- initTcRnIf 'c' hsc_env env () $ tryM do_this
+ res <- initTcRnIf RnIfaceTag hsc_env env () $ tryM do_this
msgs <- readIORef errs_var
case res of
Left _ -> return (Left msgs)
=====================================
compiler/GHC/JS/JStg/Monad.hs
=====================================
@@ -76,7 +76,7 @@ initJSMState tag supply = JEnv { prefix = tag
, ids = supply
}
initJSM :: IO JEnv
-initJSM = do supply <- mkSplitUniqSupply 'j'
+initJSM = do supply <- mkSplitUniqSupply JsTag
return (initJSMState "js" supply)
update_stream :: UniqSupply -> JSM ()
=====================================
compiler/GHC/Platform/Reg.hs
=====================================
@@ -130,7 +130,7 @@ getHiVirtualRegFromLo :: VirtualReg -> VirtualReg
getHiVirtualRegFromLo reg
= case reg of
-- makes a pseudo-unique with tag 'H'
- VirtualRegI u -> VirtualRegHi (newTagUnique u 'H')
+ VirtualRegI u -> VirtualRegHi (newTagUnique u VirtualRegTag)
_ -> panic "Reg.getHiVirtualRegFromLo"
getHiVRegFromLo :: Reg -> Reg
=====================================
compiler/GHC/Runtime/Eval.hs
=====================================
@@ -613,7 +613,7 @@ bindLocalsAtBreakpoint hsc_env apStack_fhv span (Just ibi) = do
debugTraceMsg (hsc_logger hsc_env) 1 $
text "Warning: _result has been evaluated, some bindings have been lost"
- us <- mkSplitUniqSupply 'I' -- Dodgy; will give the same uniques every time
+ us <- mkSplitUniqSupply BcoTag -- Dodgy; will give the same uniques every time
let tv_subst = newTyVars us free_tvs
(filtered_ids, occs'') = unzip -- again, sync the occ-names
[ (id, occ) | (id, Just _hv, occ) <- zip3 ids mb_hValues occs' ]
=====================================
compiler/GHC/Stg/EnforceEpt.hs
=====================================
@@ -17,7 +17,7 @@ import GHC.Types.Name
import GHC.Stg.Syntax
import GHC.Types.Basic ( CbvMark (..) )
import GHC.Types.Demand (isDeadEndAppSig)
-import GHC.Types.Unique.Supply (mkSplitUniqSupply)
+import GHC.Types.Unique.Supply (mkSplitUniqSupply, UniqueTag(StgTag))
import GHC.Types.RepType (dataConRuntimeRepStrictness)
import GHC.Core (AltCon(..))
import Data.List (mapAccumL)
@@ -326,7 +326,7 @@ enforceEpt ppr_opts !for_bytecode logger this_mod stg_binds = do
let export_tag_info = collectExportInfo stg_binds_w_tags
-- Rewrite STG to uphold the strict field invariant
- us_t <- mkSplitUniqSupply 't'
+ us_t <- mkSplitUniqSupply StgTag
let rewritten_binds = {-# SCC "StgEptRewrite" #-} rewriteTopBinds this_mod us_t stg_binds_w_tags :: [TgStgTopBinding]
return (rewritten_binds,export_tag_info)
=====================================
compiler/GHC/Stg/Pipeline.hs
=====================================
@@ -62,7 +62,7 @@ data StgPipelineOpts = StgPipelineOpts
-- -fexternal-dynamic-refs flag. See GHC.Stg.Utils.allowTopLevelConApp.
}
-newtype StgM a = StgM { _unStgM :: ReaderT Char IO a }
+newtype StgM a = StgM { _unStgM :: ReaderT UniqueTag IO a }
deriving (Functor, Applicative, Monad, MonadIO)
instance MonadUnique StgM where
@@ -71,7 +71,7 @@ instance MonadUnique StgM where
getUniqueM = StgM $ do { tag <- ask
; liftIO $! uniqFromTag tag}
-runStgM :: Char -> StgM a -> IO a
+runStgM :: UniqueTag -> StgM a -> IO a
runStgM mask (StgM m) = runReaderT m mask
stg2stg :: Logger
@@ -85,7 +85,7 @@ stg2stg logger extra_vars opts this_mod binds
; stg_linter False "StgFromCore" binds
; showPass logger "Stg2Stg"
-- Do the main business!
- ; binds' <- runStgM 'g' $
+ ; binds' <- runStgM StgPTag $
foldM (do_stg_pass this_mod) binds (stgPipeline_phases opts)
-- Dependency sort the program as last thing. The program needs to be
=====================================
compiler/GHC/StgToCmm/ExtCode.hs
=====================================
@@ -203,7 +203,7 @@ lookupLabel name = do
return $
case lookupUFM env name of
Just (LabelN l) -> l
- _other -> mkBlockId (newTagUnique (getUnique name) 'L')
+ _other -> mkBlockId (newTagUnique (getUnique name) BlockIdTag)
-- | Lookup the location of a named variable.
=====================================
compiler/GHC/StgToCmm/Monad.hs
=====================================
@@ -174,7 +174,7 @@ instance DSM.MonadGetUnique FCode where
getUniqueM = GHC.Types.Unique.Supply.getUniqueM
initC :: IO CgState
-initC = do { uniqs <- mkSplitUniqSupply 'c'
+initC = do { uniqs <- mkSplitUniqSupply CmmTag
; return (initCgState uniqs) }
runC :: StgToCmmConfig -> FCodeState -> CgState -> FCode a -> (a, CgState)
=====================================
compiler/GHC/Tc/Types.hs
=====================================
@@ -158,6 +158,7 @@ import GHC.Types.TypeEnv
import GHC.Types.SourceFile
import GHC.Types.SrcLoc
import GHC.Types.Unique.FM
+import GHC.Types.Unique.Supply ( UniqueTag )
import GHC.Types.Basic
import GHC.Types.CostCentre.State
@@ -285,7 +286,7 @@ data Env gbl lcl
-- Includes all info about imported things
-- BangPattern is to fix leak, see #15111
- env_ut :: {-# UNPACK #-} !Char, -- Tag for Uniques
+ env_ut :: {-# UNPACK #-} !UniqueTag, -- Tag for Uniques
env_gbl :: gbl, -- Info about things defined at the top level
-- of the module being compiled
=====================================
compiler/GHC/Tc/Types/Origin.hs
=====================================
@@ -347,7 +347,7 @@ unkSkolAnon = UnkSkol callStack
-- shares a certain 'Unique'.
mkSkolemInfo :: MonadIO m => SkolemInfoAnon -> m SkolemInfo
mkSkolemInfo sk_anon = do
- u <- liftIO $! uniqFromTag 's'
+ u <- liftIO $! uniqFromTag SkolemTag
return (SkolemInfo u sk_anon)
getSkolemInfo :: SkolemInfo -> SkolemInfoAnon
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -413,7 +413,7 @@ initTcWithGbl hsc_env gbl_env loc do_this
tcl_errs = errs_var
}
- ; maybe_res <- initTcRnIf 'a' hsc_env gbl_env lcl_env $
+ ; maybe_res <- initTcRnIf TcTag hsc_env gbl_env lcl_env $
do { r <- tryM do_this
; case r of
Right res -> return (Just res)
@@ -447,7 +447,7 @@ initTcInteractive hsc_env thing_inside
where
interactive_src_loc = mkRealSrcLoc (fsLit "<interactive>") 1 1
-initTcRnIf :: Char -- ^ Tag for unique supply
+initTcRnIf :: UniqueTag -- ^ Tag for unique supply
-> HscEnv
-> gbl -> lcl
-> TcRnIf gbl lcl a
@@ -2297,7 +2297,7 @@ initIfaceLoad hsc_env do_this
if_doc = text "initIfaceLoad",
if_rec_types = emptyKnotVars
}
- initTcRnIf 'i' (hsc_env { hsc_type_env_vars = emptyKnotVars }) gbl_env () do_this
+ initTcRnIf IfaceTag (hsc_env { hsc_type_env_vars = emptyKnotVars }) gbl_env () do_this
-- | This is used when we are doing to call 'typecheckModule' on an 'ModIface',
-- if it's part of a loop with some other modules then we need to use their
@@ -2308,7 +2308,7 @@ initIfaceLoadModule hsc_env this_mod do_this
if_doc = text "initIfaceLoadModule",
if_rec_types = readTcRef <$> knotVarsWithout this_mod (hsc_type_env_vars hsc_env)
}
- initTcRnIf 'i' hsc_env gbl_env () do_this
+ initTcRnIf IfaceTag hsc_env gbl_env () do_this
initIfaceCheck :: SDoc -> HscEnv -> IfG a -> IO a
-- Used when checking the up-to-date-ness of the old Iface
@@ -2318,7 +2318,7 @@ initIfaceCheck doc hsc_env do_this
if_doc = text "initIfaceCheck" <+> doc,
if_rec_types = readTcRef <$> hsc_type_env_vars hsc_env
}
- initTcRnIf 'i' hsc_env gbl_env () do_this
+ initTcRnIf IfaceTag hsc_env gbl_env () do_this
initIfaceLcl :: Module -> SDoc -> IsBootInterface -> IfL a -> IfM lcl a
initIfaceLcl mod loc_doc hi_boot_file thing_inside
=====================================
compiler/GHC/Types/Name/Cache.hs
=====================================
@@ -110,7 +110,7 @@ there, hyperlinks won't work as expected. Test case: haddockHtmlTest (Bug923.hs)
-- each original name; i.e. (module-name, occ-name) pair and provides
-- something of a lookup mechanism for those names.
data NameCache = NameCache
- { nsUniqChar :: {-# UNPACK #-} !Char
+ { nsUniqChar :: {-# UNPACK #-} !UniqueTag
, nsNames :: {-# UNPACK #-} !(MVar OrigNameCache)
}
@@ -143,7 +143,7 @@ extendOrigNameCache nc mod occ name
-- | Initialize a new name cache
newNameCache :: IO NameCache
-newNameCache = newNameCacheWith 'r' knownKeysOrigNameCache
+newNameCache = newNameCacheWith HscTag knownKeysOrigNameCache
-- | This is a version of `newNameCache` that lets you supply your
-- own unique tag and set of known key names. This can go wrong if the tag
@@ -151,8 +151,8 @@ newNameCache = newNameCacheWith 'r' knownKeysOrigNameCache
-- an example.
--
-- Use `newNameCache` when possible.
-newNameCacheWith :: Char -> OrigNameCache -> IO NameCache
-newNameCacheWith c nc = NameCache c <$> newMVar nc
+newNameCacheWith :: UniqueTag -> OrigNameCache -> IO NameCache
+newNameCacheWith ut nc = NameCache ut <$> newMVar nc
-- | This takes a tag for uniques to be generated and the list of knownKeyNames
-- These must be initialized properly to ensure that names generated from this
@@ -160,7 +160,7 @@ newNameCacheWith c nc = NameCache c <$> newMVar nc
--
-- Use `newNameCache` or `newNameCacheWith` instead
{-# DEPRECATED initNameCache "Use newNameCache or newNameCacheWith instead" #-}
-initNameCache :: Char -> [Name] -> IO NameCache
+initNameCache :: UniqueTag -> [Name] -> IO NameCache
initNameCache c names = newNameCacheWith c (initOrigNames names)
initOrigNames :: [Name] -> OrigNameCache
=====================================
compiler/GHC/Types/Unique.hs
=====================================
@@ -23,6 +23,7 @@ Haskell).
module GHC.Types.Unique (
-- * Main data types
Unique, Uniquable(..),
+ UniqueTag(..), uniqueTag,
uNIQUE_BITS,
-- ** Constructors, destructors and operations on 'Unique's
@@ -97,6 +98,106 @@ GHC.Builtin.Uniques. See Note [Uniques for wired-in prelude things and known tag
-- These are sometimes also referred to as \"keys\" in comments in GHC.
newtype Unique = MkUnique Word64
+data UniqueTag = PluginTag
+ | SkolemTag
+ | JsTag
+ | SimplTag
+ | StgTag
+ | CmmTag
+ | HscTag
+ | TsanTag
+ | TcTag
+ | IfaceTag
+ | RnIfaceTag
+ | DsTag
+ | StgPTag
+ | BcoTag
+ | LocalTag
+ | SumTag
+ | TupleTag
+ | CTupleTag
+ | CTupleDataTag
+ | CTupleSelTag
+ | BoxedTupleDataTag
+ | UnboxedTupleDataTag
+ | BoxedTupleTyConTag
+ | UnboxedTupleTyConTag
+ | AlphaTyVarTag
+ | PreludeClassTag
+ | PrimOpTag
+ | PreludeMiscIdTag
+ | BuiltinTag
+ | PseudoTag
+ | RegSingleTag
+ | RegSubTag
+ | RegPairTag
+ | RegClassTag
+ | CostCentreTag
+ | VarNSTag
+ | DataNSTag
+ | TvNSTag
+ | TcNSTag
+ | FldNSTag
+ | PreludeTyConTag
+ | PreludeDataConTag
+ | BoxingTyConTag
+ | VirtualRegTag
+ | LlvmCodeGenTag
+ | UniqueRenamerTag
+ | BlockIdTag
+
+uniqueTag :: UniqueTag -> Char
+uniqueTag PluginTag = 'p'
+uniqueTag JsTag = 'j'
+uniqueTag SkolemTag = 's' -- TODO: conflicts with SimplTag
+uniqueTag SimplTag = 's' -- TODO: conflicts with SkolemTag
+uniqueTag StgTag = 't'
+uniqueTag CmmTag = 'c' -- TODO: conflicts with RnIfaceTag and TcNSTag
+uniqueTag HscTag = 'r'
+uniqueTag TsanTag = 'u'
+uniqueTag TcTag = 'a'
+uniqueTag IfaceTag = 'i' -- TODO: conflicts with VarNSTag
+uniqueTag RnIfaceTag = 'c' -- TODO: conflicts with CmmTag and TcNSTag
+uniqueTag DsTag = 'd' -- TODO: conflicts with DataNSTag
+uniqueTag StgPTag = 'g'
+uniqueTag BcoTag = 'I'
+uniqueTag LocalTag = 'X'
+uniqueTag SumTag = 'z'
+uniqueTag TupleTag = 'k' -- TODO: conflicts with CTupleTag
+uniqueTag CTupleTag = 'k' -- TODO: conflicts with TupleTag
+uniqueTag CTupleDataTag = 'm'
+uniqueTag CTupleSelTag = 'j'
+uniqueTag BoxedTupleDataTag = '7'
+uniqueTag UnboxedTupleDataTag = '8'
+uniqueTag BoxedTupleTyConTag = '4'
+uniqueTag UnboxedTupleTyConTag = '5'
+uniqueTag AlphaTyVarTag = '1'
+uniqueTag PreludeClassTag = '2'
+uniqueTag PrimOpTag = '9'
+uniqueTag PreludeMiscIdTag = '0'
+uniqueTag BuiltinTag = 'B'
+uniqueTag PseudoTag = 'E'
+uniqueTag RegSingleTag = 'R'
+uniqueTag RegSubTag = 'S'
+uniqueTag RegPairTag = 'P'
+uniqueTag RegClassTag = 'L'
+uniqueTag CostCentreTag = 'C'
+uniqueTag VarNSTag = 'i' -- TODO: conflicts with IfaceTag
+uniqueTag DataNSTag = 'd' -- TODO: conflicts with DsTag
+uniqueTag TvNSTag = 'v'
+uniqueTag TcNSTag = 'c' -- TODO: conflicts with CmmTag and RnIfaceTag
+uniqueTag FldNSTag = 'f'
+uniqueTag PreludeTyConTag = '3'
+uniqueTag PreludeDataConTag = '6'
+uniqueTag BoxingTyConTag = 'b'
+uniqueTag VirtualRegTag = 'H'
+uniqueTag LlvmCodeGenTag = 'n'
+uniqueTag UniqueRenamerTag = 'Q'
+uniqueTag BlockIdTag = 'L'
+
+{-# INLINE uniqueTag #-}
+
+
{-# INLINE uNIQUE_BITS #-}
uNIQUE_BITS :: Int
uNIQUE_BITS = 64 - UNIQUE_TAG_BITS
@@ -113,7 +214,7 @@ getKey :: Unique -> Word64 -- for Var
incrUnique :: Unique -> Unique
stepUnique :: Unique -> Word64 -> Unique
-newTagUnique :: Unique -> Char -> Unique
+newTagUnique :: Unique -> UniqueTag -> Unique
mkUniqueGrimily = MkUnique
@@ -124,7 +225,7 @@ incrUnique (MkUnique i) = MkUnique (i + 1)
stepUnique (MkUnique i) n = MkUnique (i + n)
mkLocalUnique :: Word64 -> Unique
-mkLocalUnique i = mkUnique 'X' i
+mkLocalUnique i = mkUnique LocalTag i
minLocalUnique :: Unique
minLocalUnique = mkLocalUnique 0
@@ -152,15 +253,15 @@ mkTag c = intToWord64 (ord c) `shiftL` uNIQUE_BITS
-- and as long as the Char fits in 8 bits, which we assume anyway!
-mkUnique :: Char -> Word64 -> Unique -- Builds a unique from pieces
+mkUnique :: UniqueTag -> Word64 -> Unique -- Builds a unique from pieces
-- EXPORTED and used only in GHC.Builtin.Uniques
mkUnique c i
= MkUnique (tag .|. bits)
where
- tag = mkTag c
+ tag = mkTag $ uniqueTag c
bits = i .&. uniqueMask
-mkUniqueInt :: Char -> Int -> Unique
+mkUniqueInt :: UniqueTag -> Int -> Unique
mkUniqueInt c i = mkUnique c (intToWord64 i)
mkUniqueIntGrimily :: Int -> Unique
=====================================
compiler/GHC/Types/Unique/DSM.hs
=====================================
@@ -134,12 +134,13 @@ runUniqueDSM ds (UDSM f) =
DUniqResult uq us -> (uq, us)
-- | Set the tag of uniques generated from this deterministic unique supply
-newTagDUniqSupply :: Char -> DUniqSupply -> DUniqSupply
+newTagDUniqSupply :: UniqueTag -> DUniqSupply -> DUniqSupply
newTagDUniqSupply c (DUS w) = DUS $ getKey $ newTagUnique (mkUniqueGrimily w) c
-- | Get the tag uniques generated from this deterministic unique supply would have
-getTagDUniqSupply :: DUniqSupply -> Char
-getTagDUniqSupply (DUS w) = fst $ unpkUnique (mkUniqueGrimily w)
+getTagDUniqSupply :: DUniqSupply -> UniqueTag -- TODO
+getTagDUniqSupply (DUS w) = fst $ undefined -- unpkUnique (mkUniqueGrimily w)
+
-- | Get a unique from a monad that can access a unique supply.
--
@@ -201,7 +202,7 @@ instance Monad m => MonadGetUnique (UniqDSMT m) where
-- | Set the tag of the running @UniqDSMT@ supply to the given tag and run an action with it.
-- All uniques produced in the given action will use this tag, until the tag is changed
-- again.
-setTagUDSMT :: Monad m => Char {-^ Tag -} -> UniqDSMT m a -> UniqDSMT m a
+setTagUDSMT :: Monad m => UniqueTag {-^ Tag -} -> UniqDSMT m a -> UniqDSMT m a
setTagUDSMT tag (UDSMT act) = UDSMT $ \us -> do
let origtag = getTagDUniqSupply us
new_us = newTagDUniqSupply tag us
=====================================
compiler/GHC/Types/Unique/Supply.hs
=====================================
@@ -15,7 +15,8 @@ module GHC.Types.Unique.Supply (
-- ** Operations on supplies
uniqFromSupply, uniqsFromSupply, -- basic ops
- takeUniqFromSupply, uniqFromTag,
+ takeUniqFromSupply,
+ uniqFromTag, UniqueTag(..),
mkSplitUniqSupply,
splitUniqSupply, listSplitUniqSupply,
@@ -200,7 +201,7 @@ data UniqSupply
UniqSupply UniqSupply
-- when split => these two supplies
-mkSplitUniqSupply :: Char -> IO UniqSupply
+mkSplitUniqSupply :: UniqueTag -> IO UniqSupply
-- ^ Create a unique supply out of thin air.
-- The "tag" (Char) supplied is mostly cosmetic, making it easier
-- to figure out where a Unique was born. See Note [Uniques and tags].
@@ -213,11 +214,11 @@ mkSplitUniqSupply :: Char -> IO UniqSupply
-- See Note [How the unique supply works]
-- See Note [Optimising the unique supply]
-mkSplitUniqSupply c
+mkSplitUniqSupply ut
= unsafeDupableInterleaveIO (IO mk_supply)
where
- !tag = mkTag c
+ !tag = mkTag $ uniqueTag ut
-- Here comes THE MAGIC: see Note [How the unique supply works]
-- This is one of the most hammered bits in the whole compiler
@@ -279,11 +280,11 @@ initUniqSupply counter inc = do
poke ghc_unique_counter64 counter
poke ghc_unique_inc inc
-uniqFromTag :: Char -> IO Unique
+uniqFromTag :: UniqueTag -> IO Unique
uniqFromTag !tag
= do { uqNum <- genSym
; return $! mkUnique tag uqNum }
-{-# NOINLINE uniqFromTag #-} -- We'll unbox everything, but we don't want to inline it
+{-# INLINE uniqFromTag #-} -- We'll unbox everything, but we don't want to inline it
splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply)
-- ^ Build two 'UniqSupply' from a single one, each of which
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/742e29e001e25e99d4d3e3395d970d6…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/742e29e001e25e99d4d3e3395d970d6…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
12 Aug '25
Cheng Shao pushed new branch wip/sptentry-use-name at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sptentry-use-name
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/26264] compiler: Attempt to systematize Unique tags by introducing an ADT for each different tag
by Zubin (@wz1000) 12 Aug '25
by Zubin (@wz1000) 12 Aug '25
12 Aug '25
Zubin pushed to branch wip/26264 at Glasgow Haskell Compiler / GHC
Commits:
51ec3159 by Zubin Duggal at 2025-08-12T18:00:59+05:30
compiler: Attempt to systematize Unique tags by introducing an ADT for each different tag
Fixes #26264
- - - - -
22 changed files:
- compiler/GHC/Builtin/Uniques.hs
- compiler/GHC/Cmm/Pipeline.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/Simplify/Monad.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/JS/JStg/Monad.hs
- compiler/GHC/Platform/Reg.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Stg/EnforceEpt.hs
- compiler/GHC/Stg/Pipeline.hs
- compiler/GHC/StgToCmm/Monad.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Unique.hs
- compiler/GHC/Types/Unique/DSM.hs
- compiler/GHC/Types/Unique/Supply.hs
Changes:
=====================================
compiler/GHC/Builtin/Uniques.hs
=====================================
@@ -121,7 +121,7 @@ mkSumTyConUnique arity =
assertPpr (arity <= 0x3f) (ppr arity) $
-- 0x3f since we only have 6 bits to encode the
-- alternative
- mkUniqueInt 'z' (arity `shiftL` 8 .|. 0xfc)
+ mkUniqueInt SumTag (arity `shiftL` 8 .|. 0xfc)
-- | Inverse of 'mkSumTyConUnique'
isSumTyConUnique :: Unique -> Maybe Arity
@@ -137,7 +137,7 @@ mkSumDataConUnique alt arity
| alt >= arity
= panic ("mkSumDataConUnique: " ++ show alt ++ " >= " ++ show arity)
| otherwise
- = mkUniqueInt 'z' (arity `shiftL` 8 + alt `shiftL` 2) {- skip the tycon -}
+ = mkUniqueInt SumTag (arity `shiftL` 8 + alt `shiftL` 2) {- skip the tycon -}
getUnboxedSumName :: Int -> Name
getUnboxedSumName n
@@ -224,17 +224,17 @@ selector Uniques takes inspiration from the encoding for unboxed sum Uniques.
-}
mkCTupleTyConUnique :: Arity -> Unique
-mkCTupleTyConUnique a = mkUniqueInt 'k' (2*a)
+mkCTupleTyConUnique a = mkUniqueInt CTupleTag (2*a)
mkCTupleDataConUnique :: Arity -> Unique
-mkCTupleDataConUnique a = mkUniqueInt 'm' (3*a)
+mkCTupleDataConUnique a = mkUniqueInt CTupleDataTag (3*a)
mkCTupleSelIdUnique :: ConTagZ -> Arity -> Unique
mkCTupleSelIdUnique sc_pos arity
| sc_pos >= arity
= panic ("mkCTupleSelIdUnique: " ++ show sc_pos ++ " >= " ++ show arity)
| otherwise
- = mkUniqueInt 'j' (arity `shiftL` cTupleSelIdArityBits + sc_pos)
+ = mkUniqueInt CTupleSelTag (arity `shiftL` cTupleSelIdArityBits + sc_pos)
-- | Inverse of 'mkCTupleTyConUnique'
isCTupleTyConUnique :: Unique -> Maybe Arity
@@ -288,12 +288,12 @@ cTupleSelIdPosBitmask = 0xff
-- Normal tuples
mkTupleDataConUnique :: Boxity -> Arity -> Unique
-mkTupleDataConUnique Boxed a = mkUniqueInt '7' (3*a) -- may be used in C labels
-mkTupleDataConUnique Unboxed a = mkUniqueInt '8' (3*a)
+mkTupleDataConUnique Boxed a = mkUniqueInt BoxedTupleDataTag (3*a) -- may be used in C labels
+mkTupleDataConUnique Unboxed a = mkUniqueInt UnboxedTupleDataTag (3*a)
mkTupleTyConUnique :: Boxity -> Arity -> Unique
-mkTupleTyConUnique Boxed a = mkUniqueInt '4' (2*a)
-mkTupleTyConUnique Unboxed a = mkUniqueInt '5' (2*a)
+mkTupleTyConUnique Boxed a = mkUniqueInt BoxedTupleTyConTag (2*a)
+mkTupleTyConUnique Unboxed a = mkUniqueInt UnboxedTupleTyConTag (2*a)
-- | Inverse of 'mkTupleTyConUnique'
isTupleTyConUnique :: Unique -> Maybe (Boxity, Arity)
@@ -397,50 +397,50 @@ mkPrimOpIdUnique :: Int -> Unique
mkPrimOpWrapperUnique :: Int -> Unique
mkPreludeMiscIdUnique :: Int -> Unique
-mkAlphaTyVarUnique i = mkUniqueInt '1' i
-mkPreludeClassUnique i = mkUniqueInt '2' i
+mkAlphaTyVarUnique i = mkUniqueInt AlphaTyVarTag i
+mkPreludeClassUnique i = mkUniqueInt PreludeClassTag i
--------------------------------------------------
-mkPrimOpIdUnique op = mkUniqueInt '9' (2*op)
-mkPrimOpWrapperUnique op = mkUniqueInt '9' (2*op+1)
-mkPreludeMiscIdUnique i = mkUniqueInt '0' i
+mkPrimOpIdUnique op = mkUniqueInt PrimOpTag (2*op)
+mkPrimOpWrapperUnique op = mkUniqueInt PrimOpTag (2*op+1)
+mkPreludeMiscIdUnique i = mkUniqueInt PreludeMiscIdTag i
mkPseudoUniqueE, mkBuiltinUnique :: Int -> Unique
-mkBuiltinUnique i = mkUniqueInt 'B' i
-mkPseudoUniqueE i = mkUniqueInt 'E' i -- used in NCG spiller to create spill VirtualRegs
+mkBuiltinUnique i = mkUniqueInt BuiltinTag i
+mkPseudoUniqueE i = mkUniqueInt PseudoTag i -- used in NCG spiller to create spill VirtualRegs
mkRegSingleUnique, mkRegPairUnique, mkRegSubUnique, mkRegClassUnique :: Int -> Unique
-mkRegSingleUnique = mkUniqueInt 'R'
-mkRegSubUnique = mkUniqueInt 'S'
-mkRegPairUnique = mkUniqueInt 'P'
-mkRegClassUnique = mkUniqueInt 'L'
+mkRegSingleUnique = mkUniqueInt RegSingleTag
+mkRegSubUnique = mkUniqueInt RegSubTag
+mkRegPairUnique = mkUniqueInt RegPairTag
+mkRegClassUnique = mkUniqueInt RegClassTag
mkCostCentreUnique :: Int -> Unique
-mkCostCentreUnique = mkUniqueInt 'C'
+mkCostCentreUnique = mkUniqueInt CostCentreTag
varNSUnique, dataNSUnique, tvNSUnique, tcNSUnique :: Unique
-varNSUnique = mkUnique 'i' 0
-dataNSUnique = mkUnique 'd' 0
-tvNSUnique = mkUnique 'v' 0
-tcNSUnique = mkUnique 'c' 0
+varNSUnique = mkUnique VarNSTag 0
+dataNSUnique = mkUnique DataNSTag 0
+tvNSUnique = mkUnique TvNSTag 0
+tcNSUnique = mkUnique TcNSTag 0
mkFldNSUnique :: FastString -> Unique
-mkFldNSUnique fs = mkUniqueInt 'f' (uniqueOfFS fs)
+mkFldNSUnique fs = mkUniqueInt FldNSTag (uniqueOfFS fs)
isFldNSUnique :: Unique -> Bool
isFldNSUnique uniq = case unpkUnique uniq of
(tag, _) -> tag == 'f'
initExitJoinUnique :: Unique
-initExitJoinUnique = mkUnique 's' 0
+initExitJoinUnique = mkUnique SimplTag 0
--------------------------------------------------
-- Wired-in type constructor keys occupy *two* slots:
-- See Note [Related uniques for wired-in things]
mkPreludeTyConUnique :: Int -> Unique
-mkPreludeTyConUnique i = mkUniqueInt '3' (2*i)
+mkPreludeTyConUnique i = mkUniqueInt PreludeTyConTag (2*i)
tyConRepNameUnique :: Unique -> Unique
tyConRepNameUnique u = incrUnique u
@@ -450,7 +450,7 @@ tyConRepNameUnique u = incrUnique u
-- See Note [Related uniques for wired-in things]
mkPreludeDataConUnique :: Int -> Unique
-mkPreludeDataConUnique i = mkUniqueInt '6' (3*i) -- Must be alphabetic
+mkPreludeDataConUnique i = mkUniqueInt PreludeDataConTag (3*i) -- Must be alphabetic
dataConTyRepNameUnique, dataConWorkerUnique :: Unique -> Unique
dataConWorkerUnique u = incrUnique u
@@ -476,7 +476,7 @@ dataConTyRepNameUnique u = stepUnique u 2
-- A little delicate!
mkBoxingTyConUnique :: Int -> Unique
-mkBoxingTyConUnique i = mkUniqueInt 'b' (5*i)
+mkBoxingTyConUnique i = mkUniqueInt BoxingTyConTag (5*i)
boxingDataConUnique :: Unique -> Unique
boxingDataConUnique u = stepUnique u 2
=====================================
compiler/GHC/Cmm/Pipeline.hs
=====================================
@@ -107,7 +107,7 @@ cpsTop logger platform cfg dus proc =
-- TODO(#25273): Use the deterministic UniqDSM (ie `runUniqueDSM`) instead
-- of UniqSM (see `initUs_`) to guarantee deterministic objects
-- when doing thread sanitization.
- us <- mkSplitUniqSupply 'u'
+ us <- mkSplitUniqSupply TsanTag
return $ initUs_ us $
annotateTSAN platform g
else return g
=====================================
compiler/GHC/Core/Opt/Monad.hs
=====================================
@@ -123,7 +123,7 @@ data CoreReader = CoreReader {
cr_name_ppr_ctx :: NamePprCtx,
cr_loc :: SrcSpan, -- Use this for log/error messages so they
-- are at least tagged with the right source file
- cr_uniq_tag :: !Char -- Tag for creating unique values
+ cr_uniq_tag :: !UniqueTag -- Tag for creating unique values
}
-- Note: CoreWriter used to be defined with data, rather than newtype. If it
@@ -182,7 +182,7 @@ instance MonadUnique CoreM where
runCoreM :: HscEnv
-> RuleBase
- -> Char -- ^ Mask
+ -> UniqueTag -- ^ Mask
-> Module
-> NamePprCtx
-> SrcSpan
@@ -267,7 +267,7 @@ getSrcSpanM = read cr_loc
addSimplCount :: SimplCount -> CoreM ()
addSimplCount count = write (CoreWriter { cw_simpl_count = count })
-getUniqTag :: CoreM Char
+getUniqTag :: CoreM UniqueTag
getUniqTag = read cr_uniq_tag
-- Convenience accessors for useful fields of HscEnv
=====================================
compiler/GHC/Core/Opt/Pipeline.hs
=====================================
@@ -59,6 +59,7 @@ import GHC.Types.Basic
import GHC.Types.Demand ( zapDmdEnvSig )
import GHC.Types.Name.Ppr
import GHC.Types.Var ( Var )
+import GHC.Types.Unique.Supply ( UniqueTag(..) )
import Control.Monad
import qualified GHC.LanguageExtensions as LangExt
@@ -78,7 +79,7 @@ core2core hsc_env guts@(ModGuts { mg_module = mod
, mg_rdr_env = rdr_env })
= do { hpt_rule_base <- home_pkg_rules
; let builtin_passes = getCoreToDo dflags hpt_rule_base extra_vars
- uniq_tag = 's'
+ uniq_tag = SimplTag
; (guts2, stats) <- runCoreM hsc_env hpt_rule_base uniq_tag mod
name_ppr_ctx loc $
=====================================
compiler/GHC/Core/Opt/Simplify/Monad.hs
=====================================
@@ -180,13 +180,9 @@ traceSmpl herald doc
************************************************************************
-}
--- See Note [Uniques for wired-in prelude things and known tags] in GHC.Builtin.Uniques
-simplTag :: Char
-simplTag = 's'
-
instance MonadUnique SimplM where
- getUniqueSupplyM = liftIO $ mkSplitUniqSupply simplTag
- getUniqueM = liftIO $ uniqFromTag simplTag
+ getUniqueSupplyM = liftIO $ mkSplitUniqSupply SimplTag
+ getUniqueM = liftIO $ uniqFromTag SimplTag
instance HasLogger SimplM where
getLogger = gets st_logger
=====================================
compiler/GHC/CoreToStg/Prep.hs
=====================================
@@ -251,7 +251,7 @@ corePrepPgm logger cp_cfg pgm_cfg
(\a -> a `seqList` ()) $ do
let initialCorePrepEnv = mkInitialCorePrepEnv cp_cfg
- us <- mkSplitUniqSupply 's'
+ us <- mkSplitUniqSupply StgTag
let implicit_binds = mkDataConWorkers
(cpPgm_generateDebugInfo pgm_cfg)
@@ -271,7 +271,7 @@ corePrepPgm logger cp_cfg pgm_cfg
corePrepExpr :: Logger -> CorePrepConfig -> CoreExpr -> IO CoreExpr
corePrepExpr logger config expr = do
withTiming logger (text "CorePrep [expr]") (\e -> e `seq` ()) $ do
- us <- mkSplitUniqSupply 's'
+ us <- mkSplitUniqSupply StgTag
let initialCorePrepEnv = mkInitialCorePrepEnv config
let new_expr = initUs_ us (cpeBodyNF initialCorePrepEnv expr)
putDumpFileMaybe logger Opt_D_dump_prep "CorePrep" FormatCore (ppr new_expr)
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -249,7 +249,7 @@ import GHC.Types.Name.Cache ( newNameCache )
import GHC.Types.Name.Reader
import GHC.Types.Name.Ppr
import GHC.Types.TyThing
-import GHC.Types.Unique.Supply (uniqFromTag)
+import GHC.Types.Unique.Supply ( uniqFromTag, UniqueTag(BcoTag) )
import GHC.Types.Unique.Set
import GHC.Utils.Fingerprint ( Fingerprint )
@@ -2728,7 +2728,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do
--
-- The id has to be exported for the JS backend. This isn't required for the
-- byte-code interpreter but it does no harm to always do it.
- u <- uniqFromTag 'I'
+ u <- uniqFromTag BcoTag
let binding_name = mkSystemVarName u (fsLit ("BCO_toplevel"))
let binding_id = mkExportedVanillaId binding_name (exprType simpl_expr)
=====================================
compiler/GHC/HsToCore/Monad.hs
=====================================
@@ -308,7 +308,7 @@ lookupCompleteMatch type_env hsc_env (CompleteMatch { cmConLikes = nms, cmResult
runDs :: HscEnv -> (DsGblEnv, DsLclEnv) -> DsM a -> IO (Messages DsMessage, Maybe a)
runDs hsc_env (ds_gbl, ds_lcl) thing_inside
- = do { res <- initTcRnIf 'd' hsc_env ds_gbl ds_lcl
+ = do { res <- initTcRnIf DsTag hsc_env ds_gbl ds_lcl
(tryM thing_inside)
; msgs <- readIORef (ds_msgs ds_gbl)
; let final_res
=====================================
compiler/GHC/Iface/Rename.hs
=====================================
@@ -34,6 +34,7 @@ import GHC.Types.Var
import GHC.Types.Basic
import GHC.Types.Name
import GHC.Types.Name.Shape
+import GHC.Types.Unique.Supply
import GHC.Utils.Outputable
import GHC.Utils.Misc
@@ -194,7 +195,7 @@ initRnIface hsc_env iface insts nsubst do_this = do
sh_if_errs = errs_var
}
-- Modeled off of 'initTc'
- res <- initTcRnIf 'c' hsc_env env () $ tryM do_this
+ res <- initTcRnIf RnIfaceTag hsc_env env () $ tryM do_this
msgs <- readIORef errs_var
case res of
Left _ -> return (Left msgs)
=====================================
compiler/GHC/JS/JStg/Monad.hs
=====================================
@@ -76,7 +76,7 @@ initJSMState tag supply = JEnv { prefix = tag
, ids = supply
}
initJSM :: IO JEnv
-initJSM = do supply <- mkSplitUniqSupply 'j'
+initJSM = do supply <- mkSplitUniqSupply JsTag
return (initJSMState "js" supply)
update_stream :: UniqSupply -> JSM ()
=====================================
compiler/GHC/Platform/Reg.hs
=====================================
@@ -130,7 +130,7 @@ getHiVirtualRegFromLo :: VirtualReg -> VirtualReg
getHiVirtualRegFromLo reg
= case reg of
-- makes a pseudo-unique with tag 'H'
- VirtualRegI u -> VirtualRegHi (newTagUnique u 'H')
+ VirtualRegI u -> VirtualRegHi (newTagUnique u VirtualRegTag)
_ -> panic "Reg.getHiVirtualRegFromLo"
getHiVRegFromLo :: Reg -> Reg
=====================================
compiler/GHC/Runtime/Eval.hs
=====================================
@@ -613,7 +613,7 @@ bindLocalsAtBreakpoint hsc_env apStack_fhv span (Just ibi) = do
debugTraceMsg (hsc_logger hsc_env) 1 $
text "Warning: _result has been evaluated, some bindings have been lost"
- us <- mkSplitUniqSupply 'I' -- Dodgy; will give the same uniques every time
+ us <- mkSplitUniqSupply BcoTag -- Dodgy; will give the same uniques every time
let tv_subst = newTyVars us free_tvs
(filtered_ids, occs'') = unzip -- again, sync the occ-names
[ (id, occ) | (id, Just _hv, occ) <- zip3 ids mb_hValues occs' ]
=====================================
compiler/GHC/Stg/EnforceEpt.hs
=====================================
@@ -17,7 +17,7 @@ import GHC.Types.Name
import GHC.Stg.Syntax
import GHC.Types.Basic ( CbvMark (..) )
import GHC.Types.Demand (isDeadEndAppSig)
-import GHC.Types.Unique.Supply (mkSplitUniqSupply)
+import GHC.Types.Unique.Supply (mkSplitUniqSupply, UniqueTag(StgTag))
import GHC.Types.RepType (dataConRuntimeRepStrictness)
import GHC.Core (AltCon(..))
import Data.List (mapAccumL)
@@ -326,7 +326,7 @@ enforceEpt ppr_opts !for_bytecode logger this_mod stg_binds = do
let export_tag_info = collectExportInfo stg_binds_w_tags
-- Rewrite STG to uphold the strict field invariant
- us_t <- mkSplitUniqSupply 't'
+ us_t <- mkSplitUniqSupply StgTag
let rewritten_binds = {-# SCC "StgEptRewrite" #-} rewriteTopBinds this_mod us_t stg_binds_w_tags :: [TgStgTopBinding]
return (rewritten_binds,export_tag_info)
=====================================
compiler/GHC/Stg/Pipeline.hs
=====================================
@@ -62,7 +62,7 @@ data StgPipelineOpts = StgPipelineOpts
-- -fexternal-dynamic-refs flag. See GHC.Stg.Utils.allowTopLevelConApp.
}
-newtype StgM a = StgM { _unStgM :: ReaderT Char IO a }
+newtype StgM a = StgM { _unStgM :: ReaderT UniqueTag IO a }
deriving (Functor, Applicative, Monad, MonadIO)
instance MonadUnique StgM where
@@ -71,7 +71,7 @@ instance MonadUnique StgM where
getUniqueM = StgM $ do { tag <- ask
; liftIO $! uniqFromTag tag}
-runStgM :: Char -> StgM a -> IO a
+runStgM :: UniqueTag -> StgM a -> IO a
runStgM mask (StgM m) = runReaderT m mask
stg2stg :: Logger
@@ -85,7 +85,7 @@ stg2stg logger extra_vars opts this_mod binds
; stg_linter False "StgFromCore" binds
; showPass logger "Stg2Stg"
-- Do the main business!
- ; binds' <- runStgM 'g' $
+ ; binds' <- runStgM StgPTag $
foldM (do_stg_pass this_mod) binds (stgPipeline_phases opts)
-- Dependency sort the program as last thing. The program needs to be
=====================================
compiler/GHC/StgToCmm/Monad.hs
=====================================
@@ -174,7 +174,7 @@ instance DSM.MonadGetUnique FCode where
getUniqueM = GHC.Types.Unique.Supply.getUniqueM
initC :: IO CgState
-initC = do { uniqs <- mkSplitUniqSupply 'c'
+initC = do { uniqs <- mkSplitUniqSupply CmmTag
; return (initCgState uniqs) }
runC :: StgToCmmConfig -> FCodeState -> CgState -> FCode a -> (a, CgState)
=====================================
compiler/GHC/Tc/Types.hs
=====================================
@@ -158,6 +158,7 @@ import GHC.Types.TypeEnv
import GHC.Types.SourceFile
import GHC.Types.SrcLoc
import GHC.Types.Unique.FM
+import GHC.Types.Unique.Supply ( UniqueTag )
import GHC.Types.Basic
import GHC.Types.CostCentre.State
@@ -285,7 +286,7 @@ data Env gbl lcl
-- Includes all info about imported things
-- BangPattern is to fix leak, see #15111
- env_ut :: {-# UNPACK #-} !Char, -- Tag for Uniques
+ env_ut :: {-# UNPACK #-} !UniqueTag, -- Tag for Uniques
env_gbl :: gbl, -- Info about things defined at the top level
-- of the module being compiled
=====================================
compiler/GHC/Tc/Types/Origin.hs
=====================================
@@ -347,7 +347,7 @@ unkSkolAnon = UnkSkol callStack
-- shares a certain 'Unique'.
mkSkolemInfo :: MonadIO m => SkolemInfoAnon -> m SkolemInfo
mkSkolemInfo sk_anon = do
- u <- liftIO $! uniqFromTag 's'
+ u <- liftIO $! uniqFromTag SkolemTag
return (SkolemInfo u sk_anon)
getSkolemInfo :: SkolemInfo -> SkolemInfoAnon
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -413,7 +413,7 @@ initTcWithGbl hsc_env gbl_env loc do_this
tcl_errs = errs_var
}
- ; maybe_res <- initTcRnIf 'a' hsc_env gbl_env lcl_env $
+ ; maybe_res <- initTcRnIf TcTag hsc_env gbl_env lcl_env $
do { r <- tryM do_this
; case r of
Right res -> return (Just res)
@@ -447,7 +447,7 @@ initTcInteractive hsc_env thing_inside
where
interactive_src_loc = mkRealSrcLoc (fsLit "<interactive>") 1 1
-initTcRnIf :: Char -- ^ Tag for unique supply
+initTcRnIf :: UniqueTag -- ^ Tag for unique supply
-> HscEnv
-> gbl -> lcl
-> TcRnIf gbl lcl a
@@ -2297,7 +2297,7 @@ initIfaceLoad hsc_env do_this
if_doc = text "initIfaceLoad",
if_rec_types = emptyKnotVars
}
- initTcRnIf 'i' (hsc_env { hsc_type_env_vars = emptyKnotVars }) gbl_env () do_this
+ initTcRnIf IfaceTag (hsc_env { hsc_type_env_vars = emptyKnotVars }) gbl_env () do_this
-- | This is used when we are doing to call 'typecheckModule' on an 'ModIface',
-- if it's part of a loop with some other modules then we need to use their
@@ -2308,7 +2308,7 @@ initIfaceLoadModule hsc_env this_mod do_this
if_doc = text "initIfaceLoadModule",
if_rec_types = readTcRef <$> knotVarsWithout this_mod (hsc_type_env_vars hsc_env)
}
- initTcRnIf 'i' hsc_env gbl_env () do_this
+ initTcRnIf IfaceTag hsc_env gbl_env () do_this
initIfaceCheck :: SDoc -> HscEnv -> IfG a -> IO a
-- Used when checking the up-to-date-ness of the old Iface
@@ -2318,7 +2318,7 @@ initIfaceCheck doc hsc_env do_this
if_doc = text "initIfaceCheck" <+> doc,
if_rec_types = readTcRef <$> hsc_type_env_vars hsc_env
}
- initTcRnIf 'i' hsc_env gbl_env () do_this
+ initTcRnIf IfaceTag hsc_env gbl_env () do_this
initIfaceLcl :: Module -> SDoc -> IsBootInterface -> IfL a -> IfM lcl a
initIfaceLcl mod loc_doc hi_boot_file thing_inside
=====================================
compiler/GHC/Types/Name/Cache.hs
=====================================
@@ -110,7 +110,7 @@ there, hyperlinks won't work as expected. Test case: haddockHtmlTest (Bug923.hs)
-- each original name; i.e. (module-name, occ-name) pair and provides
-- something of a lookup mechanism for those names.
data NameCache = NameCache
- { nsUniqChar :: {-# UNPACK #-} !Char
+ { nsUniqChar :: {-# UNPACK #-} !UniqueTag
, nsNames :: {-# UNPACK #-} !(MVar OrigNameCache)
}
@@ -143,7 +143,7 @@ extendOrigNameCache nc mod occ name
-- | Initialize a new name cache
newNameCache :: IO NameCache
-newNameCache = newNameCacheWith 'r' knownKeysOrigNameCache
+newNameCache = newNameCacheWith HscTag knownKeysOrigNameCache
-- | This is a version of `newNameCache` that lets you supply your
-- own unique tag and set of known key names. This can go wrong if the tag
@@ -151,8 +151,8 @@ newNameCache = newNameCacheWith 'r' knownKeysOrigNameCache
-- an example.
--
-- Use `newNameCache` when possible.
-newNameCacheWith :: Char -> OrigNameCache -> IO NameCache
-newNameCacheWith c nc = NameCache c <$> newMVar nc
+newNameCacheWith :: UniqueTag -> OrigNameCache -> IO NameCache
+newNameCacheWith ut nc = NameCache ut <$> newMVar nc
-- | This takes a tag for uniques to be generated and the list of knownKeyNames
-- These must be initialized properly to ensure that names generated from this
@@ -160,7 +160,7 @@ newNameCacheWith c nc = NameCache c <$> newMVar nc
--
-- Use `newNameCache` or `newNameCacheWith` instead
{-# DEPRECATED initNameCache "Use newNameCache or newNameCacheWith instead" #-}
-initNameCache :: Char -> [Name] -> IO NameCache
+initNameCache :: UniqueTag -> [Name] -> IO NameCache
initNameCache c names = newNameCacheWith c (initOrigNames names)
initOrigNames :: [Name] -> OrigNameCache
=====================================
compiler/GHC/Types/Unique.hs
=====================================
@@ -23,6 +23,7 @@ Haskell).
module GHC.Types.Unique (
-- * Main data types
Unique, Uniquable(..),
+ UniqueTag(..), uniqueTag,
uNIQUE_BITS,
-- ** Constructors, destructors and operations on 'Unique's
@@ -97,6 +98,100 @@ GHC.Builtin.Uniques. See Note [Uniques for wired-in prelude things and known tag
-- These are sometimes also referred to as \"keys\" in comments in GHC.
newtype Unique = MkUnique Word64
+data UniqueTag = PluginTag
+ | SkolemTag
+ | JsTag
+ | SimplTag
+ | StgTag
+ | CmmTag
+ | HscTag
+ | TsanTag
+ | TcTag
+ | IfaceTag
+ | RnIfaceTag
+ | DsTag
+ | StgPTag
+ | BcoTag
+ | LocalTag
+ | SumTag
+ | TupleTag
+ | CTupleTag
+ | CTupleDataTag
+ | CTupleSelTag
+ | BoxedTupleDataTag
+ | UnboxedTupleDataTag
+ | BoxedTupleTyConTag
+ | UnboxedTupleTyConTag
+ | AlphaTyVarTag
+ | PreludeClassTag
+ | PrimOpTag
+ | PreludeMiscIdTag
+ | BuiltinTag
+ | PseudoTag
+ | RegSingleTag
+ | RegSubTag
+ | RegPairTag
+ | RegClassTag
+ | CostCentreTag
+ | VarNSTag
+ | DataNSTag
+ | TvNSTag
+ | TcNSTag
+ | FldNSTag
+ | PreludeTyConTag
+ | PreludeDataConTag
+ | BoxingTyConTag
+ | VirtualRegTag
+
+uniqueTag :: UniqueTag -> Char
+uniqueTag PluginTag = 'p'
+uniqueTag JsTag = 'j'
+uniqueTag SkolemTag = 's' -- TODO: conflicts with SimplTag
+uniqueTag SimplTag = 's' -- TODO: conflicts with SkolemTag
+uniqueTag StgTag = 't'
+uniqueTag CmmTag = 'c' -- TODO: conflicts with RnIfaceTag and TcNSTag
+uniqueTag HscTag = 'r'
+uniqueTag TsanTag = 'u'
+uniqueTag TcTag = 'a'
+uniqueTag IfaceTag = 'i' -- TODO: conflicts with VarNSTag
+uniqueTag RnIfaceTag = 'c' -- TODO: conflicts with CmmTag and TcNSTag
+uniqueTag DsTag = 'd' -- TODO: conflicts with DataNSTag
+uniqueTag StgPTag = 'g'
+uniqueTag BcoTag = 'I'
+uniqueTag LocalTag = 'X'
+uniqueTag SumTag = 'z'
+uniqueTag TupleTag = 'k' -- TODO: conflicts with CTupleTag
+uniqueTag CTupleTag = 'k' -- TODO: conflicts with TupleTag
+uniqueTag CTupleDataTag = 'm'
+uniqueTag CTupleSelTag = 'j'
+uniqueTag BoxedTupleDataTag = '7'
+uniqueTag UnboxedTupleDataTag = '8'
+uniqueTag BoxedTupleTyConTag = '4'
+uniqueTag UnboxedTupleTyConTag = '5'
+uniqueTag AlphaTyVarTag = '1'
+uniqueTag PreludeClassTag = '2'
+uniqueTag PrimOpTag = '9'
+uniqueTag PreludeMiscIdTag = '0'
+uniqueTag BuiltinTag = 'B'
+uniqueTag PseudoTag = 'E'
+uniqueTag RegSingleTag = 'R'
+uniqueTag RegSubTag = 'S'
+uniqueTag RegPairTag = 'P'
+uniqueTag RegClassTag = 'L'
+uniqueTag CostCentreTag = 'C'
+uniqueTag VarNSTag = 'i' -- TODO: conflicts with IfaceTag
+uniqueTag DataNSTag = 'd' -- TODO: conflicts with DsTag
+uniqueTag TvNSTag = 'v'
+uniqueTag TcNSTag = 'c' -- TODO: conflicts with CmmTag and RnIfaceTag
+uniqueTag FldNSTag = 'f'
+uniqueTag PreludeTyConTag = '3'
+uniqueTag PreludeDataConTag = '6'
+uniqueTag BoxingTyConTag = 'b'
+uniqueTag VirtualRegTag = 'H'
+
+{-# INLINE uniqueTag #-}
+
+
{-# INLINE uNIQUE_BITS #-}
uNIQUE_BITS :: Int
uNIQUE_BITS = 64 - UNIQUE_TAG_BITS
@@ -113,7 +208,7 @@ getKey :: Unique -> Word64 -- for Var
incrUnique :: Unique -> Unique
stepUnique :: Unique -> Word64 -> Unique
-newTagUnique :: Unique -> Char -> Unique
+newTagUnique :: Unique -> UniqueTag -> Unique
mkUniqueGrimily = MkUnique
@@ -124,7 +219,7 @@ incrUnique (MkUnique i) = MkUnique (i + 1)
stepUnique (MkUnique i) n = MkUnique (i + n)
mkLocalUnique :: Word64 -> Unique
-mkLocalUnique i = mkUnique 'X' i
+mkLocalUnique i = mkUnique LocalTag i
minLocalUnique :: Unique
minLocalUnique = mkLocalUnique 0
@@ -152,15 +247,15 @@ mkTag c = intToWord64 (ord c) `shiftL` uNIQUE_BITS
-- and as long as the Char fits in 8 bits, which we assume anyway!
-mkUnique :: Char -> Word64 -> Unique -- Builds a unique from pieces
+mkUnique :: UniqueTag -> Word64 -> Unique -- Builds a unique from pieces
-- EXPORTED and used only in GHC.Builtin.Uniques
mkUnique c i
= MkUnique (tag .|. bits)
where
- tag = mkTag c
+ tag = mkTag $ uniqueTag c
bits = i .&. uniqueMask
-mkUniqueInt :: Char -> Int -> Unique
+mkUniqueInt :: UniqueTag -> Int -> Unique
mkUniqueInt c i = mkUnique c (intToWord64 i)
mkUniqueIntGrimily :: Int -> Unique
=====================================
compiler/GHC/Types/Unique/DSM.hs
=====================================
@@ -134,12 +134,13 @@ runUniqueDSM ds (UDSM f) =
DUniqResult uq us -> (uq, us)
-- | Set the tag of uniques generated from this deterministic unique supply
-newTagDUniqSupply :: Char -> DUniqSupply -> DUniqSupply
+newTagDUniqSupply :: UniqueTag -> DUniqSupply -> DUniqSupply
newTagDUniqSupply c (DUS w) = DUS $ getKey $ newTagUnique (mkUniqueGrimily w) c
-- | Get the tag uniques generated from this deterministic unique supply would have
-getTagDUniqSupply :: DUniqSupply -> Char
-getTagDUniqSupply (DUS w) = fst $ unpkUnique (mkUniqueGrimily w)
+getTagDUniqSupply :: DUniqSupply -> UniqueTag -- TODO
+getTagDUniqSupply (DUS w) = fst $ undefined -- unpkUnique (mkUniqueGrimily w)
+
-- | Get a unique from a monad that can access a unique supply.
--
@@ -201,7 +202,7 @@ instance Monad m => MonadGetUnique (UniqDSMT m) where
-- | Set the tag of the running @UniqDSMT@ supply to the given tag and run an action with it.
-- All uniques produced in the given action will use this tag, until the tag is changed
-- again.
-setTagUDSMT :: Monad m => Char {-^ Tag -} -> UniqDSMT m a -> UniqDSMT m a
+setTagUDSMT :: Monad m => UniqueTag {-^ Tag -} -> UniqDSMT m a -> UniqDSMT m a
setTagUDSMT tag (UDSMT act) = UDSMT $ \us -> do
let origtag = getTagDUniqSupply us
new_us = newTagDUniqSupply tag us
=====================================
compiler/GHC/Types/Unique/Supply.hs
=====================================
@@ -15,7 +15,8 @@ module GHC.Types.Unique.Supply (
-- ** Operations on supplies
uniqFromSupply, uniqsFromSupply, -- basic ops
- takeUniqFromSupply, uniqFromTag,
+ takeUniqFromSupply,
+ uniqFromTag, UniqueTag(..),
mkSplitUniqSupply,
splitUniqSupply, listSplitUniqSupply,
@@ -200,7 +201,7 @@ data UniqSupply
UniqSupply UniqSupply
-- when split => these two supplies
-mkSplitUniqSupply :: Char -> IO UniqSupply
+mkSplitUniqSupply :: UniqueTag -> IO UniqSupply
-- ^ Create a unique supply out of thin air.
-- The "tag" (Char) supplied is mostly cosmetic, making it easier
-- to figure out where a Unique was born. See Note [Uniques and tags].
@@ -213,11 +214,11 @@ mkSplitUniqSupply :: Char -> IO UniqSupply
-- See Note [How the unique supply works]
-- See Note [Optimising the unique supply]
-mkSplitUniqSupply c
+mkSplitUniqSupply ut
= unsafeDupableInterleaveIO (IO mk_supply)
where
- !tag = mkTag c
+ !tag = mkTag $ uniqueTag ut
-- Here comes THE MAGIC: see Note [How the unique supply works]
-- This is one of the most hammered bits in the whole compiler
@@ -279,11 +280,11 @@ initUniqSupply counter inc = do
poke ghc_unique_counter64 counter
poke ghc_unique_inc inc
-uniqFromTag :: Char -> IO Unique
+uniqFromTag :: UniqueTag -> IO Unique
uniqFromTag !tag
= do { uqNum <- genSym
; return $! mkUnique tag uqNum }
-{-# NOINLINE uniqFromTag #-} -- We'll unbox everything, but we don't want to inline it
+{-# INLINE uniqFromTag #-} -- We'll unbox everything, but we don't want to inline it
splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply)
-- ^ Build two 'UniqSupply' from a single one, each of which
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51ec3159742c85592945b40cd654a3f…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51ec3159742c85592945b40cd654a3f…
You're receiving this email because of your account on gitlab.haskell.org.
1
0