[Git][ghc/ghc][master] Improve how we detect user type errors in types
by Marge Bot (@marge-bot) 08 Oct '25
by Marge Bot (@marge-bot) 08 Oct '25
08 Oct '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
7471eb6a by sheaf at 2025-10-07T21:39:43-04:00
Improve how we detect user type errors in types
This commit cleans up all the code responsible for detecting whether a
type contains "TypeError msg" applications nested inside it. All the
logic is now in 'userTypeError_maybe', which is always deep. Whether
it looks inside type family applications is determined by the passed-in
boolean flag:
- When deciding whether a constraint is definitely insoluble, don't
look inside type family applications, as they may still reduce -- in
which case the TypeError could disappear.
- When reporting unsolved constraints, look inside type family
applications: they had the chance to reduce but didn't, and the
custom type error might contain valuable information.
All the details are explained in Note [Custom type errors in constraints]
in GHC.Tc.Types.Constraint.
Another benefit of this change is that it allows us to get rid of the
deeply dodgy 'getUserTypeErrorMsg' function.
This commit also improves the detection of custom type errors, for
example in equality constraints:
TypeError blah ~# rhs
It used to be the case that we didn't detect the TypeError on the LHS,
because we never considered that equality constraints could be insoluble
due to the presence of custom type errors. Addressing this oversight
improves detection of redundant pattern match warnings, fixing #26400.
- - - - -
14 changed files:
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Validity.hs
- + testsuite/tests/pmcheck/should_compile/T26400.hs
- + testsuite/tests/pmcheck/should_compile/T26400.stderr
- + testsuite/tests/pmcheck/should_compile/T26400b.hs
- testsuite/tests/pmcheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T20241b.stderr
- testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr
Changes:
=====================================
compiler/GHC/Core/Predicate.hs
=====================================
@@ -217,7 +217,7 @@ in GHC.Tc.Solver.Dict.
-- See Note [Types for coercions, predicates, and evidence] in "GHC.Core.TyCo.Rep"
isEqPred :: PredType -> Bool
-- True of (s ~# t) (s ~R# t)
--- NB: but NOT true of (s ~ t) or (s ~~ t) or (Coecible s t)
+-- NB: but NOT true of (s ~ t) or (s ~~ t) or (Coercible s t)
isEqPred ty
| Just tc <- tyConAppTyCon_maybe ty
= tc `hasKey` eqPrimTyConKey || tc `hasKey` eqReprPrimTyConKey
=====================================
compiler/GHC/Core/Type.hs
=====================================
@@ -74,8 +74,7 @@ module GHC.Core.Type (
mkCastTy, mkCoercionTy, splitCastTy_maybe,
- ErrorMsgType,
- userTypeError_maybe, deepUserTypeError_maybe, pprUserTypeErrorTy,
+ ErrorMsgType, pprUserTypeErrorTy,
coAxNthLHS,
stripCoercionTy,
@@ -272,7 +271,7 @@ import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Data.FastString
-import GHC.Data.Maybe ( orElse, isJust, firstJust )
+import GHC.Data.Maybe ( orElse, isJust )
import GHC.List (build)
-- $type_classification
@@ -1223,45 +1222,6 @@ isLitTy ty
-- | A type of kind 'ErrorMessage' (from the 'GHC.TypeError' module).
type ErrorMsgType = Type
--- | Is this type a custom user error?
--- If so, give us the error message.
-userTypeError_maybe :: Type -> Maybe ErrorMsgType
-userTypeError_maybe ty
- | Just ty' <- coreView ty = userTypeError_maybe ty'
-userTypeError_maybe (TyConApp tc (_kind : msg : _))
- | tyConName tc == errorMessageTypeErrorFamName
- -- There may be more than 2 arguments, if the type error is
- -- used as a type constructor (e.g. at kind `Type -> Type`).
- = Just msg
-userTypeError_maybe _
- = Nothing
-
-deepUserTypeError_maybe :: Type -> Maybe ErrorMsgType
--- Look for custom user error, deeply inside the type
-deepUserTypeError_maybe ty
- | Just ty' <- coreView ty = userTypeError_maybe ty'
-deepUserTypeError_maybe (TyConApp tc tys)
- | tyConName tc == errorMessageTypeErrorFamName
- , _kind : msg : _ <- tys
- -- There may be more than 2 arguments, if the type error is
- -- used as a type constructor (e.g. at kind `Type -> Type`).
- = Just msg
-
- | tyConMustBeSaturated tc -- Don't go looking for user type errors
- -- inside type family arguments (see #20241).
- = foldr (firstJust . deepUserTypeError_maybe) Nothing (drop (tyConArity tc) tys)
- | otherwise
- = foldr (firstJust . deepUserTypeError_maybe) Nothing tys
-deepUserTypeError_maybe (ForAllTy _ ty) = deepUserTypeError_maybe ty
-deepUserTypeError_maybe (FunTy { ft_arg = arg, ft_res = res })
- = deepUserTypeError_maybe arg `firstJust` deepUserTypeError_maybe res
-deepUserTypeError_maybe (AppTy t1 t2)
- = deepUserTypeError_maybe t1 `firstJust` deepUserTypeError_maybe t2
-deepUserTypeError_maybe (CastTy ty _)
- = deepUserTypeError_maybe ty
-deepUserTypeError_maybe _ -- TyVarTy, CoercionTy, LitTy
- = Nothing
-
-- | Render a type corresponding to a user type error into a SDoc.
pprUserTypeErrorTy :: ErrorMsgType -> SDoc
pprUserTypeErrorTy ty =
=====================================
compiler/GHC/Tc/Errors.hs
=====================================
@@ -671,11 +671,14 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics
non_tv_eq _ _ = False
-- Catch TypeError and Unsatisfiable.
- -- Here, we want any nested TypeErrors to bubble up, so we use
- -- 'containsUserTypeError' and not 'isTopLevelUserTypeError'.
+ -- Here, we want any nested TypeErrors to bubble up, even if they are
+ -- inside type family applications, so we pass 'True' to
+ -- 'containsUserTypeError'.
--
-- See also Note [Implementation of Unsatisfiable constraints], point (F).
- is_user_type_error item _ = containsUserTypeError (errorItemPred item)
+ is_user_type_error item _ = containsUserTypeError True (errorItemPred item)
+ -- True <=> look under ty-fam apps, AppTy etc.
+ -- See (UTE2) in Note [Custom type errors in constraints].
is_implicit_lifting item _ =
case (errorItemOrigin item) of
@@ -977,6 +980,8 @@ Its implementation consists of the following:
This is the only way that "Unsatisfiable msg" constraints are reported,
which makes their behaviour much more predictable than TypeError.
+ We don't go looking for Unsatisfiable constraints deeply nested inside
+ a type like we do for TypeError.
-}
@@ -1124,12 +1129,21 @@ mkUserTypeErrorReporter ctxt
; maybeReportError ctxt (item :| []) err
; addSolverDeferredBinding err item }
+
+
mkUserTypeError :: ErrorItem -> TcSolverReportMsg
mkUserTypeError item
- | Just msg <- getUserTypeErrorMsg pty
- = UserTypeError msg
| Just msg <- isUnsatisfiableCt_maybe pty
= UnsatisfiableError msg
+ | Just msg <- userTypeError_maybe True pty
+ -- ^^^^
+ -- Look under type-family applications! We are reporting an error,
+ -- so we may as well look to see if there are any custom type errors
+ -- anywhere, as they might be helpful to the user. We gave the type
+ -- family application the chance to reduce, but it didn't.
+ --
+ -- See (UTE2) in Note [Custom type errors in constraints] in GHC.Tc.Types.Constraint.
+ = UserTypeError msg
| otherwise
= pprPanic "mkUserTypeError" (ppr item)
where
=====================================
compiler/GHC/Tc/Solver.hs
=====================================
@@ -659,20 +659,70 @@ equality constraint, but it is also important to detect custom type errors:
To see that we can't call `foo (MkT2)`, we must detect that `NotInt Int` is insoluble
because it is a custom type error.
-Failing to do so proved quite inconvenient for users, as evidence by the
+Failing to do so proved quite inconvenient for users, as evidenced by the
tickets #11503 #14141 #16377 #20180.
Test cases: T11503, T14141.
-Examples of constraints that tcCheckGivens considers insoluble:
+To do this, tcCheckGivens calls getInertInsols, which returns all Given
+constraints that are definitely insoluble. See Note [When is a constraint insoluble?].
+
+Note [When is a constraint insoluble?]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Whether a constraint is insoluble matters for accurate pattern-match
+warnings, as explained in Note [Pattern match warnings with insoluble Givens].
+
+We consider a constraint to be insoluble if it definitely cannot be solved,
+no matter what information we might further discover. For example, the following
+constraints are insoluble:
+
- Int ~ Bool,
- Coercible Float Word,
- - TypeError msg.
-
-Non-examples:
- - constraints which we know aren't satisfied,
- e.g. Show (Int -> Int) when no such instance is in scope,
- - Eq (TypeError msg),
- - C (Int ~ Bool), with @class C (c :: Constraint)@.
+ - TypeError msg
+ - TypeError msg ~ Int
+ - Unsatisfiable msg
+
+Many constraints that look like they can't be solved are in fact not reported
+as insoluble, as there might still be a possibility (no matter how remote) that
+they can still be solved:
+
+ 1: Show (Int -> Int)
+
+ Reason: even though there is no relevant instance in scope, this constraint
+ could later get solved by a new instance.
+
+ 2: C (Int ~ Bool), where C :: Constraint -> Constraint
+
+ Reason: even though 'Int ~ Bool' is insoluble, the constraint 'C (Int ~ Bool)'
+ might be soluble, e.g. if 'C' is a class and we have 'instance forall c. C c',
+ or 'C' is a type family and we have 'type instance C c = (() :: Constraint)'.
+
+ 3: Nested occurences of TypeError don't always lead to insolubility. For
+ example, none of the following constraints are definitely insoluble:
+
+ (a) F alpha (TypeError msg) -- 'F' is an arity 2 type family
+ (b) Eq (TypeError msg)
+ (c) c (TypeError msg) -- 'c' is a metavariable
+ (d) (TC alpha) (TypeError msg) -- 'TC' is an arity 1 type family
+ (e) TypeError msg ~ rhs -- (depends on rhs)
+
+ None of these constraints are definitely insoluble:
+
+ (a) Can be solved if 'F' reduces, e.g. 'alpha := Int', 'type instance F Int a = (() :: Constraint)'.
+ (b) Can be solved by 'instance forall x. Eq x'.
+ (c) Can be solved if 'c' unifies with 'C', as in example (2).
+ (d) Can be solved if 'TC alpha' reduces to 'C', as in example (2).
+ (e) If 'rhs' is a rigid type such as 'Int' or 'Maybe Char', then this
+ constraint is definitely insoluble. Otherwise, however, the constraint
+ could be soluble:
+ - rhs = G alpha, for an arity 1 type family G
+ G alpha could reduce to TypeError msg.
+ - rhs = k, for a skolem type variable k.
+ We could instantiate k to something else, and then the constraint
+ could become soluble.
+
+ For this reason, we are careful to not pull out certain occurrences of TypeError,
+ e.g. inside type family applications and class constraints.
+ See Note [Custom type errors in constraints].
-}
tcCheckGivens :: InertSet -> Bag EvVar -> TcM (Maybe InertSet)
=====================================
compiler/GHC/Tc/Solver/Monad.hs
=====================================
@@ -172,7 +172,7 @@ import GHC.Tc.Types.Origin
import GHC.Tc.Types.CtLoc
import GHC.Tc.Types.Constraint
-import GHC.Builtin.Names ( unsatisfiableClassNameKey, callStackTyConName, exceptionContextTyConName )
+import GHC.Builtin.Names ( callStackTyConName, exceptionContextTyConName )
import GHC.Core.Type
import GHC.Core.TyCo.Rep as Rep
@@ -185,6 +185,10 @@ import GHC.Core.Class
import GHC.Core.TyCon
import GHC.Core.Unify (typesAreApart)
+import GHC.LanguageExtensions as LangExt
+import GHC.Rename.Env
+import qualified GHC.Rename.Env as TcM
+
import GHC.Types.Name
import GHC.Types.TyThing
import GHC.Types.Name.Reader
@@ -199,8 +203,7 @@ import GHC.Types.ThLevelIndex (thLevelIndexFromImportLevel)
import GHC.Types.SrcLoc
import GHC.Unit.Module
-import qualified GHC.Rename.Env as TcM
-import GHC.Rename.Env
+import GHC.Unit.Module.Graph
import GHC.Utils.Outputable
import GHC.Utils.Panic
@@ -220,15 +223,13 @@ import Data.List ( mapAccumL )
import Data.List.NonEmpty ( nonEmpty )
import qualified Data.List.NonEmpty as NE
import qualified Data.Semigroup as S
-import GHC.LanguageExtensions as LangExt
+import qualified Data.Set as Set
#if defined(DEBUG)
import GHC.Types.Unique.Set (nonDetEltsUniqSet)
import GHC.Data.Graph.Directed
#endif
-import qualified Data.Set as Set
-import GHC.Unit.Module.Graph
{- *********************************************************************
* *
@@ -666,9 +667,10 @@ getInnermostGivenEqLevel = do { inert <- getInertCans
-- This consists of:
--
-- - insoluble equalities, such as @Int ~# Bool@;
--- - constraints that are top-level custom type errors, of the form
--- @TypeError msg@, but not constraints such as @Eq (TypeError msg)@
--- in which the type error is nested;
+-- - constraints that are custom type errors, of the form
+-- @TypeError msg@ or @Maybe (TypeError msg)@, but not constraints such as
+-- @F x (TypeError msg)@ in which the type error is nested under
+-- a type family application,
-- - unsatisfiable constraints, of the form @Unsatisfiable msg@.
--
-- The inclusion of Givens is important for pattern match warnings, as we
@@ -676,21 +678,26 @@ getInnermostGivenEqLevel = do { inert <- getInertCans
-- redundant (see Note [Pattern match warnings with insoluble Givens] in GHC.Tc.Solver).
getInertInsols :: TcS Cts
getInertInsols
- = do { inert <- getInertCans
- ; let insols = filterBag insolubleIrredCt (inert_irreds inert)
- unsats = findDictsByTyConKey (inert_dicts inert) unsatisfiableClassNameKey
- ; return $ fmap CDictCan unsats `unionBags` fmap CIrredCan insols }
+ -- See Note [When is a constraint insoluble?]
+ = do { inert_cts <- getInertCts
+ ; return $ filterBag insolubleCt inert_cts }
+
+getInertCts :: TcS Cts
+getInertCts
+ = do { inerts <- getInertCans
+ ; return $
+ unionManyBags
+ [ fmap CIrredCan $ inert_irreds inerts
+ , foldDicts (consBag . CDictCan) (inert_dicts inerts) emptyBag
+ , foldFunEqs (consBag . CEqCan ) (inert_funeqs inerts) emptyBag
+ , foldTyEqs (consBag . CEqCan ) (inert_eqs inerts) emptyBag
+ ] }
getInertGivens :: TcS [Ct]
-- Returns the Given constraints in the inert set
getInertGivens
- = do { inerts <- getInertCans
- ; let all_cts = foldIrreds ((:) . CIrredCan) (inert_irreds inerts)
- $ foldDicts ((:) . CDictCan) (inert_dicts inerts)
- $ foldFunEqs ((:) . CEqCan) (inert_funeqs inerts)
- $ foldTyEqs ((:) . CEqCan) (inert_eqs inerts)
- $ []
- ; return (filter isGivenCt all_cts) }
+ = do { all_cts <- getInertCts
+ ; return (filter isGivenCt $ bagToList all_cts) }
getPendingGivenScs :: TcS [Ct]
-- Find all inert Given dictionaries, or quantified constraints, such that
=====================================
compiler/GHC/Tc/Solver/Solve.hs
=====================================
@@ -471,7 +471,9 @@ findRedundantGivens (Implic { ic_info = info, ic_need = need, ic_given = givens
| otherwise = filterOut is_minimal givens
-- See #15232
- is_type_error id = isTopLevelUserTypeError (idType id)
+ is_type_error id = containsUserTypeError False (idType id)
+ -- False <=> do not look under ty-fam apps, AppTy etc.
+ -- See (UTE1) in Note [Custom type errors in constraints].
is_improving pred -- (transSuperClasses p) does not include p
= any isImprovementPred (pred : transSuperClasses pred)
=====================================
compiler/GHC/Tc/Types/Constraint.hs
=====================================
@@ -1,6 +1,7 @@
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TypeApplications #-}
-- | This module defines types and simple operations over constraints, as used
@@ -13,7 +14,7 @@ module GHC.Tc.Types.Constraint (
isPendingScDictCt, isPendingScDict, pendingScDict_maybe,
superClassesMightHelp, getPendingWantedScs,
isWantedCt, isGivenCt,
- isTopLevelUserTypeError, containsUserTypeError, getUserTypeErrorMsg,
+ userTypeError_maybe, containsUserTypeError,
isUnsatisfiableCt_maybe,
ctEvidence, updCtEvidence,
ctLoc, ctPred, ctFlavour, ctEqRel, ctOrigin,
@@ -59,7 +60,7 @@ module GHC.Tc.Types.Constraint (
addInsols, dropMisleading, addSimples, addImplics, addHoles,
addNotConcreteError, addMultiplicityCoercionError, addDelayedErrors,
tyCoVarsOfWC, tyCoVarsOfWCList,
- insolubleWantedCt, insolubleCt, insolubleIrredCt,
+ insolubleWantedCt, insolubleCt,
insolubleImplic, nonDefaultableTyVarsOfWC,
approximateWCX, approximateWC,
@@ -113,6 +114,7 @@ import GHC.Core.Coercion
import GHC.Core.Class
import GHC.Core.TyCon
import GHC.Core.TyCo.Ppr
+import GHC.Core.TyCo.Rep
import GHC.Types.Name
import GHC.Types.Var
@@ -136,16 +138,13 @@ import GHC.Utils.Constants (debugIsOn)
import GHC.Data.Bag
+import Control.Monad ( when )
import Data.Coerce
-import qualified Data.Semigroup as S
-import Control.Monad ( msum, when )
+import Data.List ( intersperse )
import Data.Maybe ( mapMaybe, isJust )
-
--- these are for CheckTyEqResult
+import GHC.Data.Maybe ( firstJust, firstJusts )
+import qualified Data.Semigroup as S
import Data.Word ( Word8 )
-import Data.List ( intersperse )
-
-
{-
************************************************************************
@@ -1198,73 +1197,53 @@ insolubleWC (WC { wc_impl = implics, wc_simple = simples, wc_errors = errors })
is_insoluble (DE_Multiplicity {}) = False
insolubleWantedCt :: Ct -> Bool
--- Definitely insoluble, in particular /excluding/ type-hole constraints
--- Namely:
--- a) an insoluble constraint as per 'insolubleIrredCt', i.e. either
--- - an insoluble equality constraint (e.g. Int ~ Bool), or
--- - a custom type error constraint, TypeError msg :: Constraint
--- b) that does not arise from a Given or a Wanted/Wanted fundep interaction
+-- | Is this a definitely insoluble Wanted constraint? Namely:
+--
+-- - a Wanted,
+-- - which is insoluble (as per 'insolubleCt'),
+-- - that does not arise from a Given or a Wanted/Wanted fundep interaction.
+--
-- See Note [Insoluble Wanteds]
insolubleWantedCt ct
- | CIrredCan ir_ct <- ct
- -- CIrredCan: see (IW1) in Note [Insoluble Wanteds]
- , IrredCt { ir_ev = ev } <- ir_ct
- , CtWanted (WantedCt { ctev_loc = loc, ctev_rewriters = rewriters }) <- ev
+ | CtWanted (WantedCt { ctev_loc = loc, ctev_rewriters = rewriters })
+ <- ctEvidence ct
-- It's a Wanted
- , insolubleIrredCt ir_ct
+ , insolubleCt ct
-- It's insoluble
, isEmptyRewriterSet rewriters
- -- It has no rewriters; see (IW2) in Note [Insoluble Wanteds]
+ -- It has no rewriters – see (IW1) in Note [Insoluble Wanteds]
, not (isGivenLoc loc)
- -- isGivenLoc: see (IW3) in Note [Insoluble Wanteds]
+ -- It doesn't arise from a Given – see (IW2) in Note [Insoluble Wanteds]
, not (isWantedWantedFunDepOrigin (ctLocOrigin loc))
- -- origin check: see (IW4) in Note [Insoluble Wanteds]
+ -- It doesn't arise from a W/W fundep interaction – see (IW3) in Note [Insoluble Wanteds]
= True
| otherwise
= False
--- | Returns True of constraints that are definitely insoluble,
--- as well as TypeError constraints.
--- Can return 'True' for Given constraints, unlike 'insolubleWantedCt'.
+-- | Returns True of constraints that are definitely insoluble, including
+-- constraints that include custom type errors, as per (1)
+-- in Note [Custom type errors in constraints].
--
--- The function is tuned for application /after/ constraint solving
--- i.e. assuming canonicalisation has been done
--- That's why it looks only for IrredCt; all insoluble constraints
--- are put into CIrredCan
+-- Can return 'True' for Given constraints, unlike 'insolubleWantedCt'.
insolubleCt :: Ct -> Bool
-insolubleCt (CIrredCan ir_ct) = insolubleIrredCt ir_ct
-insolubleCt _ = False
-
-insolubleIrredCt :: IrredCt -> Bool
--- Returns True of Irred constraints that are /definitely/ insoluble
---
--- This function is critical for accurate pattern-match overlap warnings.
--- See Note [Pattern match warnings with insoluble Givens] in GHC.Tc.Solver
---
--- Note that this does not traverse through the constraint to find
--- nested custom type errors: it only detects @TypeError msg :: Constraint@,
--- and not e.g. @Eq (TypeError msg)@.
-insolubleIrredCt (IrredCt { ir_ev = ev, ir_reason = reason })
- = isInsolubleReason reason
- || isTopLevelUserTypeError (ctEvPred ev)
- -- NB: 'isTopLevelUserTypeError' detects constraints of the form "TypeError msg"
- -- and "Unsatisfiable msg". It deliberately does not detect TypeError
- -- nested in a type (e.g. it does not use "containsUserTypeError"), as that
- -- would be too eager: the TypeError might appear inside a type family
- -- application which might later reduce, but we only want to return 'True'
- -- for constraints that are definitely insoluble.
- --
- -- For example: Num (F Int (TypeError "msg")), where F is a type family.
- --
- -- Test case: T11503, with the 'Assert' type family:
- --
- -- > type Assert :: Bool -> Constraint -> Constraint
- -- > type family Assert check errMsg where
- -- > Assert 'True _errMsg = ()
- -- > Assert _check errMsg = errMsg
+insolubleCt ct
+ | CIrredCan (IrredCt { ir_reason = reason }) <- ct
+ , isInsolubleReason reason
+ = True
+ | isJust $ isUnsatisfiableCt_maybe pred
+ = True
+ | containsUserTypeError False pred
+ -- False <=> do not look under ty-fam apps, AppTy etc.
+ -- See (UTE1) in Note [Custom type errors in constraints].
+ = True
+ | otherwise
+ = False
+ where
+ pred = ctPred ct
-- | Does this hole represent an "out of scope" error?
+--
-- See Note [Insoluble holes]
isOutOfScopeHole :: Hole -> Bool
isOutOfScopeHole (Hole { hole_occ = occ }) = not (startsWithUnderscore (occName occ))
@@ -1312,12 +1291,7 @@ Note [Insoluble Wanteds]
insolubleWantedCt returns True of a Wanted constraint that definitely
can't be solved. But not quite all such constraints; see wrinkles.
-(IW1) insolubleWantedCt is tuned for application /after/ constraint
- solving i.e. assuming canonicalisation has been done. That's why
- it looks only for IrredCt; all insoluble constraints are put into
- CIrredCan
-
-(IW2) We only treat it as insoluble if it has an empty rewriter set. (See Note
+(IW1) We only treat it as insoluble if it has an empty rewriter set. (See Note
[Wanteds rewrite Wanteds].) Otherwise #25325 happens: a Wanted constraint A
that is /not/ insoluble rewrites some other Wanted constraint B, so B has A
in its rewriter set. Now B looks insoluble. The danger is that we'll
@@ -1325,10 +1299,10 @@ can't be solved. But not quite all such constraints; see wrinkles.
reporting A because there is an insoluble B lying around. (This suppression
happens in GHC.Tc.Errors.mkErrorItem.) Solution: don't treat B as insoluble.
-(IW3) If the Wanted arises from a Given (how can that happen?), don't
+(IW2) If the Wanted arises from a Given (how can that happen?), don't
treat it as a Wanted insoluble (obviously).
-(IW4) If the Wanted came from a Wanted/Wanted fundep interaction, don't
+(IW3) If the Wanted came from a Wanted/Wanted fundep interaction, don't
treat the constraint as insoluble. See Note [Suppressing confusing errors]
in GHC.Tc.Errors
@@ -1354,71 +1328,165 @@ Yuk!
{- Note [Custom type errors in constraints]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When GHC reports a type-error about an unsolved-constraint, we check
-to see if the constraint contains any custom-type errors, and if so
-we report them. Here are some examples of constraints containing type
-errors:
-
- TypeError msg -- The actual constraint is a type error
-
- TypError msg ~ Int -- Some type was supposed to be Int, but ended up
- -- being a type error instead
-
- Eq (TypeError msg) -- A class constraint is stuck due to a type error
-
- F (TypeError msg) ~ a -- A type function failed to evaluate due to a type err
-
-It is also possible to have constraints where the type error is nested deeper,
-for example see #11990, and also:
-
- Eq (F (TypeError msg)) -- Here the type error is nested under a type-function
- -- call, which failed to evaluate because of it,
- -- and so the `Eq` constraint was unsolved.
- -- This may happen when one function calls another
- -- and the called function produced a custom type error.
-
-A good use-case is described in "Detecting the undetectable"
- https://blog.csongor.co.uk/report-stuck-families/
-which features
- type family Assert (err :: Constraint) (break :: Type -> Type) (a :: k) :: k where
- Assert _ Dummy _ = Any
- Assert _ _ k = k
-and an unsolved constraint like
- Assert (TypeError ...) (F ty1) ty1 ~ ty2
-that reports that (F ty1) remains stuck.
+A custom type error is a type family application 'TypeError msg' where
+'msg :: ErrorMessage', or an Unsatisfiable constraint.
+See Note [Custom type errors] and Note [The Unsatisfiable constraint]
+in GHC.Internal.TypeError.
+
+There are two ways in which the presence of such custom type errors inside a
+type impact GHC's behaviour:
+
+ (UTE1)
+ Constraints that contain a custom type error are considered to be
+ insoluble. This affects pattern-match warnings, as explained in
+ Note [Pattern match warnings with insoluble Givens] in GHC.Tc.Solver.
+
+ This includes examples such as:
+
+ TypeError msg -- The actual constraint is a type error
+
+ TypeError msg ~# Int -- Some type was supposed to be Int, but ended up
+ -- being a type error instead
+
+ However, we must be careful about occurrences of custom type errors
+ nested inside the constraint, as they may not make the constraint
+ insoluble. This is explained in Note [When is a constraint insoluble?]
+ in GHC.Tc.Solver. In particular:
+
+ a. Do not look inside type family applications.
+ b. Do not look inside class constraints.
+ c. Do not look inside AppTy or in arguments of a type family past its arity.
+ d. Only consider 'TypeError msg ~ rhs' to be insoluble if rhs definitely
+ cannot unify with 'TypeError msg', e.g. if 'rhs = Int' the constraint
+ is insoluble, but if 'rhs = k[sk]' then it isn't.
+
+ These subtle cases are tested in T26400b.
+
+ A good use-case for type errors nested under type family applications is
+ described in "Detecting the undetectable" (https://blog.csongor.co.uk/report-stuck-families/)
+ which features:
+ type family Assert (err :: Constraint) (break :: Type -> Type) (a :: k) :: k where
+ Assert _ Dummy _ = Any
+ Assert _ _ k = k
+ and an unsolved constraint like 'Assert (TypeError ...) (F ty1) ty1 ~ ty2'
+ which reports when (F ty1) remains stuck.
+
+ (UTE2)
+ When reporting unsolved constraints, we pull out any custom type errors
+ and report the corresponding message to the user.
+
+ Unlike in (UTE1), we do want to pull out 'TypeError' wherever it occurs
+ inside the type, including inside type-family applications. We tried to
+ solve the constraint, reduce type families etc, but the constraint
+ remained unsolved all the way till the end. Now that we are reporting the
+ error, it makes sense to pull out the 'TypeError' and report the custom
+ error message to the user, as the intention is that this message might
+ be informative.
+
+ Examples:
+
+ Num (TypeError msg) -- A class constraint is stuck due to a type error
+
+ F (TypeError msg) ~ a -- A type function failed to evaluate due to a type error
+
+ Eq (F (TypeError msg)) -- Here the type error is nested under a type-function
+ -- call, which failed to evaluate because of it,
+ -- and so the `Eq` constraint was unsolved.
+ -- This may happen when one function calls another
+ -- and the called function produced a custom type error.
+
+We use a single function, 'userTypeError_maybe', to pull out TypeError according
+to the rules of either (UTE1) or (UTE2), depending on the passed in boolean
+flag to 'userTypeError_maybe': 'False' for (UTE1) and 'True' for (UTE2).
-}
--- | A constraint is considered to be a custom type error, if it contains
--- custom type errors anywhere in it.
--- See Note [Custom type errors in constraints]
-getUserTypeErrorMsg :: PredType -> Maybe ErrorMsgType
-getUserTypeErrorMsg pred = msum $ userTypeError_maybe pred
- : map getUserTypeErrorMsg (subTys pred)
+-- | Does this type contain 'TypeError msg', either at the top-level or
+-- nested within it somewhere?
+--
+-- If so, return the error message.
+--
+-- See Note [Custom type errors in constraints].
+userTypeError_maybe
+ :: Bool -- ^ Look everywhere: inside type-family applications, class constraints, AppTys etc?
+ -> Type
+ -> Maybe ErrorMsgType
+userTypeError_maybe look_everywhere = go
where
- -- Richard thinks this function is very broken. What is subTys
- -- supposed to be doing? Why are exactly-saturated tyconapps special?
- -- What stops this from accidentally ripping apart a call to TypeError?
- subTys t = case splitAppTys t of
- (t,[]) ->
- case splitTyConApp_maybe t of
- Nothing -> []
- Just (_,ts) -> ts
- (t,ts) -> t : ts
-
--- | Is this an user error message type, i.e. either the form @TypeError err@ or
--- @Unsatisfiable err@?
-isTopLevelUserTypeError :: PredType -> Bool
-isTopLevelUserTypeError pred =
- isJust (userTypeError_maybe pred) || isJust (isUnsatisfiableCt_maybe pred)
+ go ty
+ | Just ty' <- coreView ty
+ = go ty'
+ go (TyConApp tc tys)
+ | tyConName tc == errorMessageTypeErrorFamName
+ , _kind : msg : _ <- tys
+ -- There may be more than 2 arguments, if the type error is
+ -- used as a type constructor (e.g. at kind `Type -> Type`).
+ = Just msg
+
+ -- (UTE1.d) TypeError msg ~ a is only insoluble if 'a' cannot be a type error
+ | not look_everywhere
+ , tc `hasKey` eqPrimTyConKey || tc `hasKey` eqReprPrimTyConKey
+ , [ ki1, ki2, ty1, ty2 ] <- tys
+ = if | Just msg <- go ki1
+ , isRigidTy ki2
+ -> Just msg
+ | Just msg <- go ki2
+ , isRigidTy ki1
+ -> Just msg
+ | Just msg <- go ty1
+ , isRigidTy ty2
+ -> Just msg
+ | Just msg <- go ty2
+ , isRigidTy ty1
+ -> Just msg
+ | otherwise
+ -> Nothing
+
+ -- (UTE1.a) Don't look under type family applications.
+ | tyConMustBeSaturated tc
+ , not look_everywhere
+ = Nothing
+ -- (UTE1.c) Don't even look in the arguments past the arity of the TyCon.
+
+ -- (UTE1.b) Don't look inside class constraints.
+ | isClassTyCon tc
+ , not look_everywhere
+ = foldr (firstJust . go) Nothing (drop (tyConArity tc) tys)
+ | otherwise
+ = foldr (firstJust . go) Nothing tys
+ go (ForAllTy (Bndr tv _) ty) = go (tyVarKind tv) `firstJust` go ty
+ go (FunTy { ft_mult = mult, ft_arg = arg, ft_res = res })
+ = firstJusts
+ [ go mult
+ , go (typeKind arg)
+ , go (typeKind res)
+ , go arg
+ , go res ]
+ go (AppTy t1 t2)
+ -- (UTE1.c) Don't look inside AppTy.
+ | not look_everywhere
+ = Nothing
+ | otherwise
+ = go t1 `firstJust` go t2
+ go (CastTy ty _co) = go ty
+ go (TyVarTy tv) = go (tyVarKind tv)
+ go (CoercionTy {}) = Nothing
+ go (LitTy {}) = Nothing
-- | Does this constraint contain an user error message?
--
-- That is, the type is either of the form @Unsatisfiable err@, or it contains
-- a type of the form @TypeError msg@, either at the top level or nested inside
-- the type.
-containsUserTypeError :: PredType -> Bool
-containsUserTypeError pred =
- isJust (getUserTypeErrorMsg pred) || isJust (isUnsatisfiableCt_maybe pred)
+--
+-- See Note [Custom type errors in constraints].
+containsUserTypeError
+ :: Bool -- ^ look inside type-family applications, 'AppTy', etc?
+ -> PredType
+ -> Bool
+containsUserTypeError look_in_famapps pred =
+ isJust (isUnsatisfiableCt_maybe pred)
+ ||
+ isJust (userTypeError_maybe look_in_famapps pred)
-- | Is this type an unsatisfiable constraint?
-- If so, return the error message.
=====================================
compiler/GHC/Tc/Validity.hs
=====================================
@@ -31,6 +31,7 @@ import GHC.Tc.Instance.Family
import GHC.Tc.Types.Origin
import GHC.Tc.Types.Rank
import GHC.Tc.Errors.Types
+import GHC.Tc.Types.Constraint ( userTypeError_maybe )
import GHC.Tc.Utils.Env (tcLookupId)
import GHC.Tc.Utils.TcType
import GHC.Tc.Utils.Monad
@@ -282,7 +283,12 @@ checkUserTypeError ctxt ty
| TySynCtxt {} <- ctxt -- Do not complain about TypeError on the
= return () -- RHS of type synonyms. See #20181
- | Just msg <- deepUserTypeError_maybe ty
+ | Just msg <- userTypeError_maybe False ty
+ -- ^^^^^
+ -- Don't look under type-family applications! We only want to pull out
+ -- definite errors.
+ --
+ -- See (UTE1) in Note [Custom type errors in constraints] in GHC.Tc.Types.Constraint.
= do { env0 <- liftZonkM tcInitTidyEnv
; let (env1, tidy_msg) = tidyOpenTypeX env0 msg
; failWithTcM (env1, TcRnUserTypeError tidy_msg) }
=====================================
testsuite/tests/pmcheck/should_compile/T26400.hs
=====================================
@@ -0,0 +1,37 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE StandaloneKindSignatures #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UnliftedDatatypes #-}
+
+module T26400 where
+
+import GHC.Exts ( UnliftedType )
+import GHC.TypeLits ( TypeError, ErrorMessage(..) )
+
+data N = Z | S N
+
+-- Make this type unlifted to avoid any subtleties about laziness
+type SNat :: N -> UnliftedType
+data SNat n where
+ SZ :: SNat Z
+ SS :: SNat n -> SNat (S n)
+
+type (-) :: N -> N -> N
+type family a - b where
+ n - Z = n
+ Z - S _ = TypeError ( Text "impossible" )
+ S n - S m = n - m
+
+testFn :: SNat n -> SNat m -> SNat (n - m) -> Int
+testFn SZ (SS _) SZ = 666
+testFn SZ (SS _) (SS _) = 999
+ -- [G] g1 :: n ~ Z
+ -- [G] g2 :: m ~ S m1
+ -- [G] g3 :: (n-m) ~ S m2
+ -- Use the first two givens to substitute in the third, we get:
+ -- [G] g3' :: Z - S m1 ~ S m2
+ -- Reduce the LHS using the type family
+ -- [G] g3'' :: TypeError ... ~ S m2
+ -- Hence g3'' is insoluble and the equation can never match
+testFn _ _ _ = 1
=====================================
testsuite/tests/pmcheck/should_compile/T26400.stderr
=====================================
@@ -0,0 +1,8 @@
+T26400.hs:27:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
+ Pattern match is redundant
+ In an equation for ‘testFn’: testFn SZ (SS _) SZ = ...
+
+T26400.hs:28:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
+ Pattern match is redundant
+ In an equation for ‘testFn’: testFn SZ (SS _) (SS _) = ...
+
=====================================
testsuite/tests/pmcheck/should_compile/T26400b.hs
=====================================
@@ -0,0 +1,39 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE StandaloneKindSignatures #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module T26400b where
+
+import Data.Kind
+import GHC.TypeLits ( TypeError, ErrorMessage(..) )
+
+type F :: Type -> Type -> Type
+type family F a b where
+ F Float _ = Bool
+ F _ a = a
+
+type C :: Type -> Type -> Constraint
+class C a b
+instance C () b
+
+type Boom :: Type -> Type
+type family Boom a where
+ Boom () = TypeError (Text "boom")
+
+type TF :: Type -> ( Type -> Type -> Constraint )
+type family TF a where
+ TF () = C
+
+type G :: Type -> Type -> Type
+data G a b where
+ G1 :: a -> F b (Boom a) -> G a b
+ G2 :: C a (Boom a) => a -> G a b
+ G3 :: (TF b) a (Boom a) => a -> G a b
+ G4 :: (b ~ Boom a) => G a b
+
+g :: G () b -> Int
+g (G1 {}) = 1 -- not redundant: F b (TypeError ...) can be solved if F reduces
+g (G2 {}) = 2 -- not redundant: C () (TypeError ...) is not insoluble
+g (G3 {}) = 3 -- not redundant: TF b () (TypeError ...) could reduce to C () (TypeError ...)
+g (G4 {}) = 4 -- not redundant: b ~ TypeError ... could be solved depending on instantiation of b
=====================================
testsuite/tests/pmcheck/should_compile/all.T
=====================================
@@ -123,6 +123,8 @@ test('T21761', [], compile, [overlapping_incomplete])
test('T22964', [], compile, [overlapping_incomplete])
test('T23445', [], compile, [overlapping_incomplete])
test('T24234', [], compile, [overlapping_incomplete+'-Wincomplete-uni-patterns'])
+test('T26400', [], compile, [overlapping_incomplete])
+test('T26400b', [], compile, [overlapping_incomplete])
# Series (inspired) by Luke Maranget
=====================================
testsuite/tests/typecheck/should_fail/T20241b.stderr
=====================================
@@ -1,4 +1,3 @@
-
T20241b.hs:16:8: error: [GHC-47403]
• Boom
• In the type signature:
@@ -6,11 +5,14 @@ T20241b.hs:16:8: error: [GHC-47403]
-> Type -> Constraint) IO) a =>
Proxy a -> ()
-T20241b.hs:20:8: error: [GHC-47403]
+T20241b.hs:20:8: error: [GHC-64725]
• Boom
- • In the type signature:
+ • In the ambiguity check for ‘bar’
+ To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
+ In the type signature:
bar :: ((c :: Constraint
-> Type -> Constraint) (((TypeError (Text "Boom") :: (Type -> Type)
-> Type
-> Constraint) IO) a)) a =>
Proxy a -> ()
+
=====================================
testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr
=====================================
@@ -9,11 +9,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865]
• In the first argument of ‘F’, namely ‘5’
In the newtype family instance declaration for ‘F’
-UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865]
- Expected a type,
+UnliftedNewtypesFamilyKindFail2.hs:12:31: error: [GHC-83865]
+ • Expected a type,
but ‘5’ has kind
‘GHC.Internal.Bignum.Natural.Natural’
- In the first argument of ‘F’, namely ‘5’
+ • In the first argument of ‘F’, namely ‘5’
In the type ‘(F 5)’
In the definition of data constructor ‘MkF’
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7471eb6a250ff713f9416346478f46b…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7471eb6a250ff713f9416346478f46b…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/gbc-files] Add support for generating bytecode objects
by Matthew Pickering (@mpickering) 07 Oct '25
by Matthew Pickering (@mpickering) 07 Oct '25
07 Oct '25
Matthew Pickering pushed to branch wip/gbc-files at Glasgow Haskell Compiler / GHC
Commits:
612da2fa by Matthew Pickering at 2025-10-07T16:00:49+01:00
Add support for generating bytecode objects
This commit adds the `-fwrite-byte-code` option which makes GHC emit a
`.gbc` file which contains a serialised representation of bytecode.
The bytecode can be loaded by the compiler to avoid having to
reinterpret a module when using the bytecode interpreter (for example,
in GHCi).
There are also the new options:
* -gbcdir=<DIR>: Specify the directory to place the gbc files
* -gbcsuf=<suffix>: Specify the suffix for gbc files
The option `-fbyte-code-and-object-code` now implies
`-fwrite-byte-code`.
These performance tests fail due to https://github.com/haskell/directory/issues/204
-------------------------
Metric Increase:
MultiComponentModules
MultiLayerModules
MultiComponentModulesRecomp
MultiLayerModulesRecomp
MultiLayerModulesTH_Make
MultiLayerModulesTH_OneShot
T13701
-------------------------
The bytecode serialisation part was implemented by Cheng Shao
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
- - - - -
67 changed files:
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- + compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Data/FlatBag.hs
- compiler/GHC/Data/SmallArray.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backpack.hs
- + compiler/GHC/Driver/ByteCode.hs
- compiler/GHC/Driver/Config/Finder.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Messager.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Types/SptEntry.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/Location.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Utils/Binary.hs
- compiler/ghc.cabal.in
- docs/users_guide/phases.rst
- docs/users_guide/separate_compilation.rst
- testsuite/tests/bytecode/T24634/T24634a.stdout
- testsuite/tests/bytecode/T24634/T24634b.stdout
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/driver/bytecode-object/A.hs
- + testsuite/tests/driver/bytecode-object/BytecodeForeign.c
- + testsuite/tests/driver/bytecode-object/BytecodeForeign.hs
- + testsuite/tests/driver/bytecode-object/BytecodeMain.hs
- + testsuite/tests/driver/bytecode-object/BytecodeTest.hs
- + testsuite/tests/driver/bytecode-object/Makefile
- + testsuite/tests/driver/bytecode-object/all.T
- + testsuite/tests/driver/bytecode-object/bytecode_object12.stderr
- + testsuite/tests/driver/bytecode-object/bytecode_object13.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object14.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object15.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object16.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object17.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object18.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object19.script
- + testsuite/tests/driver/bytecode-object/bytecode_object19.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object25.script
- + testsuite/tests/driver/bytecode-object/bytecode_object25.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object4.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object5.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object6.stdout
- testsuite/tests/driver/fat-iface/T22405/T22405.stdout
- testsuite/tests/driver/fat-iface/T22405/T22405b.stdout
- testsuite/tests/driver/fat-iface/fat011.stderr
- testsuite/tests/perf/compiler/Makefile
- + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithBytecodeFiles.script
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/simplStg/should_compile/T22840.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/612da2fae21b6525bac96e8c47d1f11…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/612da2fae21b6525bac96e8c47d1f11…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/26470] compiler: "role" is only a keyword when RoleAnnotations is set
by Zubin (@wz1000) 07 Oct '25
by Zubin (@wz1000) 07 Oct '25
07 Oct '25
Zubin pushed to branch wip/26470 at Glasgow Haskell Compiler / GHC
Commits:
e6bf1b2b by Zubin Duggal at 2025-10-07T20:23:04+05:30
compiler: "role" is only a keyword when RoleAnnotations is set
Fixes #26470
- - - - -
3 changed files:
- compiler/GHC/Parser/Lexer.x
- + testsuite/tests/parser/should_compile/T26470.hs
- testsuite/tests/parser/should_compile/all.T
Changes:
=====================================
compiler/GHC/Parser/Lexer.x
=====================================
@@ -1068,7 +1068,7 @@ reservedWordsFM = listToUFM $
( "mdo", ITmdo Nothing, xbit RecursiveDoBit),
-- See Note [Lexing type pseudo-keywords]
( "family", ITfamily, 0 ),
- ( "role", ITrole, 0 ),
+ ( "role", ITrole, xbit RoleAnnotationsBit ),
( "pattern", ITpattern, xbit PatternSynonymsBit),
( "static", ITstatic, xbit StaticPointersBit ),
( "stock", ITstock, 0 ),
@@ -2790,6 +2790,7 @@ data ExtBits
| RequiredTypeArgumentsBit
| MultilineStringsBit
| LevelImportsBit
+ | RoleAnnotationsBit
-- Flags that are updated once parsing starts
| InRulePragBit
@@ -2874,6 +2875,7 @@ mkParserOpts extensionFlags diag_opts
.|. RequiredTypeArgumentsBit `xoptBit` LangExt.RequiredTypeArguments
.|. MultilineStringsBit `xoptBit` LangExt.MultilineStrings
.|. LevelImportsBit `xoptBit` LangExt.ExplicitLevelImports
+ .|. RoleAnnotationsBit `xoptBit` LangExt.RoleAnnotations
optBits =
HaddockBit `setBitIf` isHaddock
.|. RawTokenStreamBit `setBitIf` rawTokStream
=====================================
testsuite/tests/parser/should_compile/T26470.hs
=====================================
@@ -0,0 +1,12 @@
+{-# LANGUAGE Haskell2010 #-}
+module T26470 where
+
+role :: Int
+role = 42
+
+f :: Int -> Int
+f role = role + 1
+
+data T = MkT { role :: String }
+
+newtype T2 role = MkT2 Int
=====================================
testsuite/tests/parser/should_compile/all.T
=====================================
@@ -208,3 +208,4 @@ test('T25258', normal, compile, [''])
test('T17045b', extra_files(["T17045"]), multimod_compile, ['-iT17045 Test', '-v0'])
test('T25900', normal, compile, [''])
test('T25900_noext', normal, compile, [''])
+test('T26470', normal, compile, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6bf1b2b0cd66653ad07e8785cb1360…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6bf1b2b0cd66653ad07e8785cb1360…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/26470] compiler: "role" is only a keyword when RoleAnnotations is set
by Zubin (@wz1000) 07 Oct '25
by Zubin (@wz1000) 07 Oct '25
07 Oct '25
Zubin pushed to branch wip/26470 at Glasgow Haskell Compiler / GHC
Commits:
ee4bac18 by Zubin Duggal at 2025-10-07T20:08:25+05:30
compiler: "role" is only a keyword when RoleAnnotations is set
Fixes #26470
- - - - -
2 changed files:
- compiler/GHC/Parser/Lexer.x
- testsuite/tests/parser/should_compile/all.T
Changes:
=====================================
compiler/GHC/Parser/Lexer.x
=====================================
@@ -1068,7 +1068,7 @@ reservedWordsFM = listToUFM $
( "mdo", ITmdo Nothing, xbit RecursiveDoBit),
-- See Note [Lexing type pseudo-keywords]
( "family", ITfamily, 0 ),
- ( "role", ITrole, 0 ),
+ ( "role", ITrole, xbit RoleAnnotationsBit ),
( "pattern", ITpattern, xbit PatternSynonymsBit),
( "static", ITstatic, xbit StaticPointersBit ),
( "stock", ITstock, 0 ),
@@ -2790,6 +2790,7 @@ data ExtBits
| RequiredTypeArgumentsBit
| MultilineStringsBit
| LevelImportsBit
+ | RoleAnnotationsBit
-- Flags that are updated once parsing starts
| InRulePragBit
@@ -2874,6 +2875,7 @@ mkParserOpts extensionFlags diag_opts
.|. RequiredTypeArgumentsBit `xoptBit` LangExt.RequiredTypeArguments
.|. MultilineStringsBit `xoptBit` LangExt.MultilineStrings
.|. LevelImportsBit `xoptBit` LangExt.ExplicitLevelImports
+ .|. RoleAnnotationsBit `xoptBit` LangExt.RoleAnnotations
optBits =
HaddockBit `setBitIf` isHaddock
.|. RawTokenStreamBit `setBitIf` rawTokStream
=====================================
testsuite/tests/parser/should_compile/all.T
=====================================
@@ -208,3 +208,4 @@ test('T25258', normal, compile, [''])
test('T17045b', extra_files(["T17045"]), multimod_compile, ['-iT17045 Test', '-v0'])
test('T25900', normal, compile, [''])
test('T25900_noext', normal, compile, [''])
+test('T26470', normal, compile, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee4bac18ad0df86d0601f849d5f5803…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee4bac18ad0df86d0601f849d5f5803…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/gbc-files] Add support for generating bytecode objects
by Matthew Pickering (@mpickering) 07 Oct '25
by Matthew Pickering (@mpickering) 07 Oct '25
07 Oct '25
Matthew Pickering pushed to branch wip/gbc-files at Glasgow Haskell Compiler / GHC
Commits:
8fc810f2 by Matthew Pickering at 2025-10-07T15:32:37+01:00
Add support for generating bytecode objects
This commit adds the `-fwrite-byte-code` option which makes GHC emit a
`.gbc` file which contains a serialised representation of bytecode.
The bytecode can be loaded by the compiler to avoid having to
reinterpret a module when using the bytecode interpreter (for example,
in GHCi).
There are also the new options:
* -gbcdir=<DIR>: Specify the directory to place the gbc files
* -gbcsuf=<suffix>: Specify the suffix for gbc files
The option `-fbyte-code-and-object-code` now implies
`-fwrite-byte-code`.
These performance tests fail due to https://github.com/haskell/directory/issues/204
-------------------------
Metric Increase:
MultiComponentModules
MultiLayerModules
MultiComponentModulesRecomp
MultiLayerModulesRecomp
MultiLayerModulesTH_Make
MultiLayerModulesTH_OneShot
T13701
-------------------------
The bytecode serialisation part was implemented by Cheng Shao
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
- - - - -
67 changed files:
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- + compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Data/FlatBag.hs
- compiler/GHC/Data/SmallArray.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backpack.hs
- + compiler/GHC/Driver/ByteCode.hs
- compiler/GHC/Driver/Config/Finder.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Messager.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Types/SptEntry.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/Location.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Utils/Binary.hs
- compiler/ghc.cabal.in
- docs/users_guide/phases.rst
- docs/users_guide/separate_compilation.rst
- testsuite/tests/bytecode/T24634/T24634a.stdout
- testsuite/tests/bytecode/T24634/T24634b.stdout
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/driver/bytecode-object/A.hs
- + testsuite/tests/driver/bytecode-object/BytecodeForeign.c
- + testsuite/tests/driver/bytecode-object/BytecodeForeign.hs
- + testsuite/tests/driver/bytecode-object/BytecodeMain.hs
- + testsuite/tests/driver/bytecode-object/BytecodeTest.hs
- + testsuite/tests/driver/bytecode-object/Makefile
- + testsuite/tests/driver/bytecode-object/all.T
- + testsuite/tests/driver/bytecode-object/bytecode_object12.stderr
- + testsuite/tests/driver/bytecode-object/bytecode_object13.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object14.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object15.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object16.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object17.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object18.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object19.script
- + testsuite/tests/driver/bytecode-object/bytecode_object19.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object25.script
- + testsuite/tests/driver/bytecode-object/bytecode_object25.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object4.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object5.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object6.stdout
- testsuite/tests/driver/fat-iface/T22405/T22405.stdout
- testsuite/tests/driver/fat-iface/T22405/T22405b.stdout
- testsuite/tests/driver/fat-iface/fat011.stderr
- testsuite/tests/perf/compiler/Makefile
- + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithBytecodeFiles.script
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/simplStg/should_compile/T22840.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8fc810f2d039adb9e17d1e03a411700…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8fc810f2d039adb9e17d1e03a411700…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Zubin pushed new branch wip/26470 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/26470
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Add a perf test for #26425
by Marge Bot (@marge-bot) 07 Oct '25
by Marge Bot (@marge-bot) 07 Oct '25
07 Oct '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
41bdb16f by Andreas Klebinger at 2025-10-06T18:04:34-04:00
Add a perf test for #26425
- - - - -
1da0c700 by Andreas Klebinger at 2025-10-06T18:05:14-04:00
Testsuite: Silence warnings about Wx-partial in concprog001
- - - - -
e56ee4c4 by sheaf at 2025-10-07T09:58:58-04:00
Improve how we detect user type errors in types
This commit cleans up all the code responsible for detecting whether a
type contains "TypeError msg" applications nested inside it. All the
logic is now in 'userTypeError_maybe', which is always deep. Whether
it looks inside type family applications is determined by the passed-in
boolean flag:
- When deciding whether a constraint is definitely insoluble, don't
look inside type family applications, as they may still reduce -- in
which case the TypeError could disappear.
- When reporting unsolved constraints, look inside type family
applications: they had the chance to reduce but didn't, and the
custom type error might contain valuable information.
All the details are explained in Note [Custom type errors in constraints]
in GHC.Tc.Types.Constraint.
Another benefit of this change is that it allows us to get rid of the
deeply dodgy 'getUserTypeErrorMsg' function.
This commit also improves the detection of custom type errors, for
example in equality constraints:
TypeError blah ~# rhs
It used to be the case that we didn't detect the TypeError on the LHS,
because we never considered that equality constraints could be insoluble
due to the presence of custom type errors. Addressing this oversight
improves detection of redundant pattern match warnings, fixing #26400.
- - - - -
742ae2b4 by Rodrigo Mesquita at 2025-10-07T09:58:59-04:00
cleanup: Drop obsolete settings from config.mk.in
These values used to be spliced into the bindist's `config.mk` s.t. when
`make` was run, the values were read and written into the bindist installation `settings` file.
However, we now carry these values to the bindist directly in the
default.target toolchain file, and `make` writes almost nothing to
`settings` now (see #26227)
The entries deleted in this MR were already unused.
Fixes #26478
- - - - -
18 changed files:
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Validity.hs
- hadrian/bindist/config.mk.in
- testsuite/tests/concurrent/prog001/all.T
- + testsuite/tests/perf/compiler/T26425.hs
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/pmcheck/should_compile/T26400.hs
- + testsuite/tests/pmcheck/should_compile/T26400.stderr
- + testsuite/tests/pmcheck/should_compile/T26400b.hs
- testsuite/tests/pmcheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T20241b.stderr
- testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr
Changes:
=====================================
compiler/GHC/Core/Predicate.hs
=====================================
@@ -217,7 +217,7 @@ in GHC.Tc.Solver.Dict.
-- See Note [Types for coercions, predicates, and evidence] in "GHC.Core.TyCo.Rep"
isEqPred :: PredType -> Bool
-- True of (s ~# t) (s ~R# t)
--- NB: but NOT true of (s ~ t) or (s ~~ t) or (Coecible s t)
+-- NB: but NOT true of (s ~ t) or (s ~~ t) or (Coercible s t)
isEqPred ty
| Just tc <- tyConAppTyCon_maybe ty
= tc `hasKey` eqPrimTyConKey || tc `hasKey` eqReprPrimTyConKey
=====================================
compiler/GHC/Core/Type.hs
=====================================
@@ -74,8 +74,7 @@ module GHC.Core.Type (
mkCastTy, mkCoercionTy, splitCastTy_maybe,
- ErrorMsgType,
- userTypeError_maybe, deepUserTypeError_maybe, pprUserTypeErrorTy,
+ ErrorMsgType, pprUserTypeErrorTy,
coAxNthLHS,
stripCoercionTy,
@@ -272,7 +271,7 @@ import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Data.FastString
-import GHC.Data.Maybe ( orElse, isJust, firstJust )
+import GHC.Data.Maybe ( orElse, isJust )
import GHC.List (build)
-- $type_classification
@@ -1223,45 +1222,6 @@ isLitTy ty
-- | A type of kind 'ErrorMessage' (from the 'GHC.TypeError' module).
type ErrorMsgType = Type
--- | Is this type a custom user error?
--- If so, give us the error message.
-userTypeError_maybe :: Type -> Maybe ErrorMsgType
-userTypeError_maybe ty
- | Just ty' <- coreView ty = userTypeError_maybe ty'
-userTypeError_maybe (TyConApp tc (_kind : msg : _))
- | tyConName tc == errorMessageTypeErrorFamName
- -- There may be more than 2 arguments, if the type error is
- -- used as a type constructor (e.g. at kind `Type -> Type`).
- = Just msg
-userTypeError_maybe _
- = Nothing
-
-deepUserTypeError_maybe :: Type -> Maybe ErrorMsgType
--- Look for custom user error, deeply inside the type
-deepUserTypeError_maybe ty
- | Just ty' <- coreView ty = userTypeError_maybe ty'
-deepUserTypeError_maybe (TyConApp tc tys)
- | tyConName tc == errorMessageTypeErrorFamName
- , _kind : msg : _ <- tys
- -- There may be more than 2 arguments, if the type error is
- -- used as a type constructor (e.g. at kind `Type -> Type`).
- = Just msg
-
- | tyConMustBeSaturated tc -- Don't go looking for user type errors
- -- inside type family arguments (see #20241).
- = foldr (firstJust . deepUserTypeError_maybe) Nothing (drop (tyConArity tc) tys)
- | otherwise
- = foldr (firstJust . deepUserTypeError_maybe) Nothing tys
-deepUserTypeError_maybe (ForAllTy _ ty) = deepUserTypeError_maybe ty
-deepUserTypeError_maybe (FunTy { ft_arg = arg, ft_res = res })
- = deepUserTypeError_maybe arg `firstJust` deepUserTypeError_maybe res
-deepUserTypeError_maybe (AppTy t1 t2)
- = deepUserTypeError_maybe t1 `firstJust` deepUserTypeError_maybe t2
-deepUserTypeError_maybe (CastTy ty _)
- = deepUserTypeError_maybe ty
-deepUserTypeError_maybe _ -- TyVarTy, CoercionTy, LitTy
- = Nothing
-
-- | Render a type corresponding to a user type error into a SDoc.
pprUserTypeErrorTy :: ErrorMsgType -> SDoc
pprUserTypeErrorTy ty =
=====================================
compiler/GHC/Tc/Errors.hs
=====================================
@@ -671,11 +671,14 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics
non_tv_eq _ _ = False
-- Catch TypeError and Unsatisfiable.
- -- Here, we want any nested TypeErrors to bubble up, so we use
- -- 'containsUserTypeError' and not 'isTopLevelUserTypeError'.
+ -- Here, we want any nested TypeErrors to bubble up, even if they are
+ -- inside type family applications, so we pass 'True' to
+ -- 'containsUserTypeError'.
--
-- See also Note [Implementation of Unsatisfiable constraints], point (F).
- is_user_type_error item _ = containsUserTypeError (errorItemPred item)
+ is_user_type_error item _ = containsUserTypeError True (errorItemPred item)
+ -- True <=> look under ty-fam apps, AppTy etc.
+ -- See (UTE2) in Note [Custom type errors in constraints].
is_implicit_lifting item _ =
case (errorItemOrigin item) of
@@ -977,6 +980,8 @@ Its implementation consists of the following:
This is the only way that "Unsatisfiable msg" constraints are reported,
which makes their behaviour much more predictable than TypeError.
+ We don't go looking for Unsatisfiable constraints deeply nested inside
+ a type like we do for TypeError.
-}
@@ -1124,12 +1129,21 @@ mkUserTypeErrorReporter ctxt
; maybeReportError ctxt (item :| []) err
; addSolverDeferredBinding err item }
+
+
mkUserTypeError :: ErrorItem -> TcSolverReportMsg
mkUserTypeError item
- | Just msg <- getUserTypeErrorMsg pty
- = UserTypeError msg
| Just msg <- isUnsatisfiableCt_maybe pty
= UnsatisfiableError msg
+ | Just msg <- userTypeError_maybe True pty
+ -- ^^^^
+ -- Look under type-family applications! We are reporting an error,
+ -- so we may as well look to see if there are any custom type errors
+ -- anywhere, as they might be helpful to the user. We gave the type
+ -- family application the chance to reduce, but it didn't.
+ --
+ -- See (UTE2) in Note [Custom type errors in constraints] in GHC.Tc.Types.Constraint.
+ = UserTypeError msg
| otherwise
= pprPanic "mkUserTypeError" (ppr item)
where
=====================================
compiler/GHC/Tc/Solver.hs
=====================================
@@ -659,20 +659,70 @@ equality constraint, but it is also important to detect custom type errors:
To see that we can't call `foo (MkT2)`, we must detect that `NotInt Int` is insoluble
because it is a custom type error.
-Failing to do so proved quite inconvenient for users, as evidence by the
+Failing to do so proved quite inconvenient for users, as evidenced by the
tickets #11503 #14141 #16377 #20180.
Test cases: T11503, T14141.
-Examples of constraints that tcCheckGivens considers insoluble:
+To do this, tcCheckGivens calls getInertInsols, which returns all Given
+constraints that are definitely insoluble. See Note [When is a constraint insoluble?].
+
+Note [When is a constraint insoluble?]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Whether a constraint is insoluble matters for accurate pattern-match
+warnings, as explained in Note [Pattern match warnings with insoluble Givens].
+
+We consider a constraint to be insoluble if it definitely cannot be solved,
+no matter what information we might further discover. For example, the following
+constraints are insoluble:
+
- Int ~ Bool,
- Coercible Float Word,
- - TypeError msg.
-
-Non-examples:
- - constraints which we know aren't satisfied,
- e.g. Show (Int -> Int) when no such instance is in scope,
- - Eq (TypeError msg),
- - C (Int ~ Bool), with @class C (c :: Constraint)@.
+ - TypeError msg
+ - TypeError msg ~ Int
+ - Unsatisfiable msg
+
+Many constraints that look like they can't be solved are in fact not reported
+as insoluble, as there might still be a possibility (no matter how remote) that
+they can still be solved:
+
+ 1: Show (Int -> Int)
+
+ Reason: even though there is no relevant instance in scope, this constraint
+ could later get solved by a new instance.
+
+ 2: C (Int ~ Bool), where C :: Constraint -> Constraint
+
+ Reason: even though 'Int ~ Bool' is insoluble, the constraint 'C (Int ~ Bool)'
+ might be soluble, e.g. if 'C' is a class and we have 'instance forall c. C c',
+ or 'C' is a type family and we have 'type instance C c = (() :: Constraint)'.
+
+ 3: Nested occurences of TypeError don't always lead to insolubility. For
+ example, none of the following constraints are definitely insoluble:
+
+ (a) F alpha (TypeError msg) -- 'F' is an arity 2 type family
+ (b) Eq (TypeError msg)
+ (c) c (TypeError msg) -- 'c' is a metavariable
+ (d) (TC alpha) (TypeError msg) -- 'TC' is an arity 1 type family
+ (e) TypeError msg ~ rhs -- (depends on rhs)
+
+ None of these constraints are definitely insoluble:
+
+ (a) Can be solved if 'F' reduces, e.g. 'alpha := Int', 'type instance F Int a = (() :: Constraint)'.
+ (b) Can be solved by 'instance forall x. Eq x'.
+ (c) Can be solved if 'c' unifies with 'C', as in example (2).
+ (d) Can be solved if 'TC alpha' reduces to 'C', as in example (2).
+ (e) If 'rhs' is a rigid type such as 'Int' or 'Maybe Char', then this
+ constraint is definitely insoluble. Otherwise, however, the constraint
+ could be soluble:
+ - rhs = G alpha, for an arity 1 type family G
+ G alpha could reduce to TypeError msg.
+ - rhs = k, for a skolem type variable k.
+ We could instantiate k to something else, and then the constraint
+ could become soluble.
+
+ For this reason, we are careful to not pull out certain occurrences of TypeError,
+ e.g. inside type family applications and class constraints.
+ See Note [Custom type errors in constraints].
-}
tcCheckGivens :: InertSet -> Bag EvVar -> TcM (Maybe InertSet)
=====================================
compiler/GHC/Tc/Solver/Monad.hs
=====================================
@@ -172,7 +172,7 @@ import GHC.Tc.Types.Origin
import GHC.Tc.Types.CtLoc
import GHC.Tc.Types.Constraint
-import GHC.Builtin.Names ( unsatisfiableClassNameKey, callStackTyConName, exceptionContextTyConName )
+import GHC.Builtin.Names ( callStackTyConName, exceptionContextTyConName )
import GHC.Core.Type
import GHC.Core.TyCo.Rep as Rep
@@ -185,6 +185,10 @@ import GHC.Core.Class
import GHC.Core.TyCon
import GHC.Core.Unify (typesAreApart)
+import GHC.LanguageExtensions as LangExt
+import GHC.Rename.Env
+import qualified GHC.Rename.Env as TcM
+
import GHC.Types.Name
import GHC.Types.TyThing
import GHC.Types.Name.Reader
@@ -199,8 +203,7 @@ import GHC.Types.ThLevelIndex (thLevelIndexFromImportLevel)
import GHC.Types.SrcLoc
import GHC.Unit.Module
-import qualified GHC.Rename.Env as TcM
-import GHC.Rename.Env
+import GHC.Unit.Module.Graph
import GHC.Utils.Outputable
import GHC.Utils.Panic
@@ -220,15 +223,13 @@ import Data.List ( mapAccumL )
import Data.List.NonEmpty ( nonEmpty )
import qualified Data.List.NonEmpty as NE
import qualified Data.Semigroup as S
-import GHC.LanguageExtensions as LangExt
+import qualified Data.Set as Set
#if defined(DEBUG)
import GHC.Types.Unique.Set (nonDetEltsUniqSet)
import GHC.Data.Graph.Directed
#endif
-import qualified Data.Set as Set
-import GHC.Unit.Module.Graph
{- *********************************************************************
* *
@@ -666,9 +667,10 @@ getInnermostGivenEqLevel = do { inert <- getInertCans
-- This consists of:
--
-- - insoluble equalities, such as @Int ~# Bool@;
--- - constraints that are top-level custom type errors, of the form
--- @TypeError msg@, but not constraints such as @Eq (TypeError msg)@
--- in which the type error is nested;
+-- - constraints that are custom type errors, of the form
+-- @TypeError msg@ or @Maybe (TypeError msg)@, but not constraints such as
+-- @F x (TypeError msg)@ in which the type error is nested under
+-- a type family application,
-- - unsatisfiable constraints, of the form @Unsatisfiable msg@.
--
-- The inclusion of Givens is important for pattern match warnings, as we
@@ -676,21 +678,26 @@ getInnermostGivenEqLevel = do { inert <- getInertCans
-- redundant (see Note [Pattern match warnings with insoluble Givens] in GHC.Tc.Solver).
getInertInsols :: TcS Cts
getInertInsols
- = do { inert <- getInertCans
- ; let insols = filterBag insolubleIrredCt (inert_irreds inert)
- unsats = findDictsByTyConKey (inert_dicts inert) unsatisfiableClassNameKey
- ; return $ fmap CDictCan unsats `unionBags` fmap CIrredCan insols }
+ -- See Note [When is a constraint insoluble?]
+ = do { inert_cts <- getInertCts
+ ; return $ filterBag insolubleCt inert_cts }
+
+getInertCts :: TcS Cts
+getInertCts
+ = do { inerts <- getInertCans
+ ; return $
+ unionManyBags
+ [ fmap CIrredCan $ inert_irreds inerts
+ , foldDicts (consBag . CDictCan) (inert_dicts inerts) emptyBag
+ , foldFunEqs (consBag . CEqCan ) (inert_funeqs inerts) emptyBag
+ , foldTyEqs (consBag . CEqCan ) (inert_eqs inerts) emptyBag
+ ] }
getInertGivens :: TcS [Ct]
-- Returns the Given constraints in the inert set
getInertGivens
- = do { inerts <- getInertCans
- ; let all_cts = foldIrreds ((:) . CIrredCan) (inert_irreds inerts)
- $ foldDicts ((:) . CDictCan) (inert_dicts inerts)
- $ foldFunEqs ((:) . CEqCan) (inert_funeqs inerts)
- $ foldTyEqs ((:) . CEqCan) (inert_eqs inerts)
- $ []
- ; return (filter isGivenCt all_cts) }
+ = do { all_cts <- getInertCts
+ ; return (filter isGivenCt $ bagToList all_cts) }
getPendingGivenScs :: TcS [Ct]
-- Find all inert Given dictionaries, or quantified constraints, such that
=====================================
compiler/GHC/Tc/Solver/Solve.hs
=====================================
@@ -471,7 +471,9 @@ findRedundantGivens (Implic { ic_info = info, ic_need = need, ic_given = givens
| otherwise = filterOut is_minimal givens
-- See #15232
- is_type_error id = isTopLevelUserTypeError (idType id)
+ is_type_error id = containsUserTypeError False (idType id)
+ -- False <=> do not look under ty-fam apps, AppTy etc.
+ -- See (UTE1) in Note [Custom type errors in constraints].
is_improving pred -- (transSuperClasses p) does not include p
= any isImprovementPred (pred : transSuperClasses pred)
=====================================
compiler/GHC/Tc/Types/Constraint.hs
=====================================
@@ -1,6 +1,7 @@
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TypeApplications #-}
-- | This module defines types and simple operations over constraints, as used
@@ -13,7 +14,7 @@ module GHC.Tc.Types.Constraint (
isPendingScDictCt, isPendingScDict, pendingScDict_maybe,
superClassesMightHelp, getPendingWantedScs,
isWantedCt, isGivenCt,
- isTopLevelUserTypeError, containsUserTypeError, getUserTypeErrorMsg,
+ userTypeError_maybe, containsUserTypeError,
isUnsatisfiableCt_maybe,
ctEvidence, updCtEvidence,
ctLoc, ctPred, ctFlavour, ctEqRel, ctOrigin,
@@ -59,7 +60,7 @@ module GHC.Tc.Types.Constraint (
addInsols, dropMisleading, addSimples, addImplics, addHoles,
addNotConcreteError, addMultiplicityCoercionError, addDelayedErrors,
tyCoVarsOfWC, tyCoVarsOfWCList,
- insolubleWantedCt, insolubleCt, insolubleIrredCt,
+ insolubleWantedCt, insolubleCt,
insolubleImplic, nonDefaultableTyVarsOfWC,
approximateWCX, approximateWC,
@@ -113,6 +114,7 @@ import GHC.Core.Coercion
import GHC.Core.Class
import GHC.Core.TyCon
import GHC.Core.TyCo.Ppr
+import GHC.Core.TyCo.Rep
import GHC.Types.Name
import GHC.Types.Var
@@ -136,16 +138,13 @@ import GHC.Utils.Constants (debugIsOn)
import GHC.Data.Bag
+import Control.Monad ( when )
import Data.Coerce
-import qualified Data.Semigroup as S
-import Control.Monad ( msum, when )
+import Data.List ( intersperse )
import Data.Maybe ( mapMaybe, isJust )
-
--- these are for CheckTyEqResult
+import GHC.Data.Maybe ( firstJust, firstJusts )
+import qualified Data.Semigroup as S
import Data.Word ( Word8 )
-import Data.List ( intersperse )
-
-
{-
************************************************************************
@@ -1198,73 +1197,53 @@ insolubleWC (WC { wc_impl = implics, wc_simple = simples, wc_errors = errors })
is_insoluble (DE_Multiplicity {}) = False
insolubleWantedCt :: Ct -> Bool
--- Definitely insoluble, in particular /excluding/ type-hole constraints
--- Namely:
--- a) an insoluble constraint as per 'insolubleIrredCt', i.e. either
--- - an insoluble equality constraint (e.g. Int ~ Bool), or
--- - a custom type error constraint, TypeError msg :: Constraint
--- b) that does not arise from a Given or a Wanted/Wanted fundep interaction
+-- | Is this a definitely insoluble Wanted constraint? Namely:
+--
+-- - a Wanted,
+-- - which is insoluble (as per 'insolubleCt'),
+-- - that does not arise from a Given or a Wanted/Wanted fundep interaction.
+--
-- See Note [Insoluble Wanteds]
insolubleWantedCt ct
- | CIrredCan ir_ct <- ct
- -- CIrredCan: see (IW1) in Note [Insoluble Wanteds]
- , IrredCt { ir_ev = ev } <- ir_ct
- , CtWanted (WantedCt { ctev_loc = loc, ctev_rewriters = rewriters }) <- ev
+ | CtWanted (WantedCt { ctev_loc = loc, ctev_rewriters = rewriters })
+ <- ctEvidence ct
-- It's a Wanted
- , insolubleIrredCt ir_ct
+ , insolubleCt ct
-- It's insoluble
, isEmptyRewriterSet rewriters
- -- It has no rewriters; see (IW2) in Note [Insoluble Wanteds]
+ -- It has no rewriters – see (IW1) in Note [Insoluble Wanteds]
, not (isGivenLoc loc)
- -- isGivenLoc: see (IW3) in Note [Insoluble Wanteds]
+ -- It doesn't arise from a Given – see (IW2) in Note [Insoluble Wanteds]
, not (isWantedWantedFunDepOrigin (ctLocOrigin loc))
- -- origin check: see (IW4) in Note [Insoluble Wanteds]
+ -- It doesn't arise from a W/W fundep interaction – see (IW3) in Note [Insoluble Wanteds]
= True
| otherwise
= False
--- | Returns True of constraints that are definitely insoluble,
--- as well as TypeError constraints.
--- Can return 'True' for Given constraints, unlike 'insolubleWantedCt'.
+-- | Returns True of constraints that are definitely insoluble, including
+-- constraints that include custom type errors, as per (1)
+-- in Note [Custom type errors in constraints].
--
--- The function is tuned for application /after/ constraint solving
--- i.e. assuming canonicalisation has been done
--- That's why it looks only for IrredCt; all insoluble constraints
--- are put into CIrredCan
+-- Can return 'True' for Given constraints, unlike 'insolubleWantedCt'.
insolubleCt :: Ct -> Bool
-insolubleCt (CIrredCan ir_ct) = insolubleIrredCt ir_ct
-insolubleCt _ = False
-
-insolubleIrredCt :: IrredCt -> Bool
--- Returns True of Irred constraints that are /definitely/ insoluble
---
--- This function is critical for accurate pattern-match overlap warnings.
--- See Note [Pattern match warnings with insoluble Givens] in GHC.Tc.Solver
---
--- Note that this does not traverse through the constraint to find
--- nested custom type errors: it only detects @TypeError msg :: Constraint@,
--- and not e.g. @Eq (TypeError msg)@.
-insolubleIrredCt (IrredCt { ir_ev = ev, ir_reason = reason })
- = isInsolubleReason reason
- || isTopLevelUserTypeError (ctEvPred ev)
- -- NB: 'isTopLevelUserTypeError' detects constraints of the form "TypeError msg"
- -- and "Unsatisfiable msg". It deliberately does not detect TypeError
- -- nested in a type (e.g. it does not use "containsUserTypeError"), as that
- -- would be too eager: the TypeError might appear inside a type family
- -- application which might later reduce, but we only want to return 'True'
- -- for constraints that are definitely insoluble.
- --
- -- For example: Num (F Int (TypeError "msg")), where F is a type family.
- --
- -- Test case: T11503, with the 'Assert' type family:
- --
- -- > type Assert :: Bool -> Constraint -> Constraint
- -- > type family Assert check errMsg where
- -- > Assert 'True _errMsg = ()
- -- > Assert _check errMsg = errMsg
+insolubleCt ct
+ | CIrredCan (IrredCt { ir_reason = reason }) <- ct
+ , isInsolubleReason reason
+ = True
+ | isJust $ isUnsatisfiableCt_maybe pred
+ = True
+ | containsUserTypeError False pred
+ -- False <=> do not look under ty-fam apps, AppTy etc.
+ -- See (UTE1) in Note [Custom type errors in constraints].
+ = True
+ | otherwise
+ = False
+ where
+ pred = ctPred ct
-- | Does this hole represent an "out of scope" error?
+--
-- See Note [Insoluble holes]
isOutOfScopeHole :: Hole -> Bool
isOutOfScopeHole (Hole { hole_occ = occ }) = not (startsWithUnderscore (occName occ))
@@ -1312,12 +1291,7 @@ Note [Insoluble Wanteds]
insolubleWantedCt returns True of a Wanted constraint that definitely
can't be solved. But not quite all such constraints; see wrinkles.
-(IW1) insolubleWantedCt is tuned for application /after/ constraint
- solving i.e. assuming canonicalisation has been done. That's why
- it looks only for IrredCt; all insoluble constraints are put into
- CIrredCan
-
-(IW2) We only treat it as insoluble if it has an empty rewriter set. (See Note
+(IW1) We only treat it as insoluble if it has an empty rewriter set. (See Note
[Wanteds rewrite Wanteds].) Otherwise #25325 happens: a Wanted constraint A
that is /not/ insoluble rewrites some other Wanted constraint B, so B has A
in its rewriter set. Now B looks insoluble. The danger is that we'll
@@ -1325,10 +1299,10 @@ can't be solved. But not quite all such constraints; see wrinkles.
reporting A because there is an insoluble B lying around. (This suppression
happens in GHC.Tc.Errors.mkErrorItem.) Solution: don't treat B as insoluble.
-(IW3) If the Wanted arises from a Given (how can that happen?), don't
+(IW2) If the Wanted arises from a Given (how can that happen?), don't
treat it as a Wanted insoluble (obviously).
-(IW4) If the Wanted came from a Wanted/Wanted fundep interaction, don't
+(IW3) If the Wanted came from a Wanted/Wanted fundep interaction, don't
treat the constraint as insoluble. See Note [Suppressing confusing errors]
in GHC.Tc.Errors
@@ -1354,71 +1328,165 @@ Yuk!
{- Note [Custom type errors in constraints]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When GHC reports a type-error about an unsolved-constraint, we check
-to see if the constraint contains any custom-type errors, and if so
-we report them. Here are some examples of constraints containing type
-errors:
-
- TypeError msg -- The actual constraint is a type error
-
- TypError msg ~ Int -- Some type was supposed to be Int, but ended up
- -- being a type error instead
-
- Eq (TypeError msg) -- A class constraint is stuck due to a type error
-
- F (TypeError msg) ~ a -- A type function failed to evaluate due to a type err
-
-It is also possible to have constraints where the type error is nested deeper,
-for example see #11990, and also:
-
- Eq (F (TypeError msg)) -- Here the type error is nested under a type-function
- -- call, which failed to evaluate because of it,
- -- and so the `Eq` constraint was unsolved.
- -- This may happen when one function calls another
- -- and the called function produced a custom type error.
-
-A good use-case is described in "Detecting the undetectable"
- https://blog.csongor.co.uk/report-stuck-families/
-which features
- type family Assert (err :: Constraint) (break :: Type -> Type) (a :: k) :: k where
- Assert _ Dummy _ = Any
- Assert _ _ k = k
-and an unsolved constraint like
- Assert (TypeError ...) (F ty1) ty1 ~ ty2
-that reports that (F ty1) remains stuck.
+A custom type error is a type family application 'TypeError msg' where
+'msg :: ErrorMessage', or an Unsatisfiable constraint.
+See Note [Custom type errors] and Note [The Unsatisfiable constraint]
+in GHC.Internal.TypeError.
+
+There are two ways in which the presence of such custom type errors inside a
+type impact GHC's behaviour:
+
+ (UTE1)
+ Constraints that contain a custom type error are considered to be
+ insoluble. This affects pattern-match warnings, as explained in
+ Note [Pattern match warnings with insoluble Givens] in GHC.Tc.Solver.
+
+ This includes examples such as:
+
+ TypeError msg -- The actual constraint is a type error
+
+ TypeError msg ~# Int -- Some type was supposed to be Int, but ended up
+ -- being a type error instead
+
+ However, we must be careful about occurrences of custom type errors
+ nested inside the constraint, as they may not make the constraint
+ insoluble. This is explained in Note [When is a constraint insoluble?]
+ in GHC.Tc.Solver. In particular:
+
+ a. Do not look inside type family applications.
+ b. Do not look inside class constraints.
+ c. Do not look inside AppTy or in arguments of a type family past its arity.
+ d. Only consider 'TypeError msg ~ rhs' to be insoluble if rhs definitely
+ cannot unify with 'TypeError msg', e.g. if 'rhs = Int' the constraint
+ is insoluble, but if 'rhs = k[sk]' then it isn't.
+
+ These subtle cases are tested in T26400b.
+
+ A good use-case for type errors nested under type family applications is
+ described in "Detecting the undetectable" (https://blog.csongor.co.uk/report-stuck-families/)
+ which features:
+ type family Assert (err :: Constraint) (break :: Type -> Type) (a :: k) :: k where
+ Assert _ Dummy _ = Any
+ Assert _ _ k = k
+ and an unsolved constraint like 'Assert (TypeError ...) (F ty1) ty1 ~ ty2'
+ which reports when (F ty1) remains stuck.
+
+ (UTE2)
+ When reporting unsolved constraints, we pull out any custom type errors
+ and report the corresponding message to the user.
+
+ Unlike in (UTE1), we do want to pull out 'TypeError' wherever it occurs
+ inside the type, including inside type-family applications. We tried to
+ solve the constraint, reduce type families etc, but the constraint
+ remained unsolved all the way till the end. Now that we are reporting the
+ error, it makes sense to pull out the 'TypeError' and report the custom
+ error message to the user, as the intention is that this message might
+ be informative.
+
+ Examples:
+
+ Num (TypeError msg) -- A class constraint is stuck due to a type error
+
+ F (TypeError msg) ~ a -- A type function failed to evaluate due to a type error
+
+ Eq (F (TypeError msg)) -- Here the type error is nested under a type-function
+ -- call, which failed to evaluate because of it,
+ -- and so the `Eq` constraint was unsolved.
+ -- This may happen when one function calls another
+ -- and the called function produced a custom type error.
+
+We use a single function, 'userTypeError_maybe', to pull out TypeError according
+to the rules of either (UTE1) or (UTE2), depending on the passed in boolean
+flag to 'userTypeError_maybe': 'False' for (UTE1) and 'True' for (UTE2).
-}
--- | A constraint is considered to be a custom type error, if it contains
--- custom type errors anywhere in it.
--- See Note [Custom type errors in constraints]
-getUserTypeErrorMsg :: PredType -> Maybe ErrorMsgType
-getUserTypeErrorMsg pred = msum $ userTypeError_maybe pred
- : map getUserTypeErrorMsg (subTys pred)
+-- | Does this type contain 'TypeError msg', either at the top-level or
+-- nested within it somewhere?
+--
+-- If so, return the error message.
+--
+-- See Note [Custom type errors in constraints].
+userTypeError_maybe
+ :: Bool -- ^ Look everywhere: inside type-family applications, class constraints, AppTys etc?
+ -> Type
+ -> Maybe ErrorMsgType
+userTypeError_maybe look_everywhere = go
where
- -- Richard thinks this function is very broken. What is subTys
- -- supposed to be doing? Why are exactly-saturated tyconapps special?
- -- What stops this from accidentally ripping apart a call to TypeError?
- subTys t = case splitAppTys t of
- (t,[]) ->
- case splitTyConApp_maybe t of
- Nothing -> []
- Just (_,ts) -> ts
- (t,ts) -> t : ts
-
--- | Is this an user error message type, i.e. either the form @TypeError err@ or
--- @Unsatisfiable err@?
-isTopLevelUserTypeError :: PredType -> Bool
-isTopLevelUserTypeError pred =
- isJust (userTypeError_maybe pred) || isJust (isUnsatisfiableCt_maybe pred)
+ go ty
+ | Just ty' <- coreView ty
+ = go ty'
+ go (TyConApp tc tys)
+ | tyConName tc == errorMessageTypeErrorFamName
+ , _kind : msg : _ <- tys
+ -- There may be more than 2 arguments, if the type error is
+ -- used as a type constructor (e.g. at kind `Type -> Type`).
+ = Just msg
+
+ -- (UTE1.d) TypeError msg ~ a is only insoluble if 'a' cannot be a type error
+ | not look_everywhere
+ , tc `hasKey` eqPrimTyConKey || tc `hasKey` eqReprPrimTyConKey
+ , [ ki1, ki2, ty1, ty2 ] <- tys
+ = if | Just msg <- go ki1
+ , isRigidTy ki2
+ -> Just msg
+ | Just msg <- go ki2
+ , isRigidTy ki1
+ -> Just msg
+ | Just msg <- go ty1
+ , isRigidTy ty2
+ -> Just msg
+ | Just msg <- go ty2
+ , isRigidTy ty1
+ -> Just msg
+ | otherwise
+ -> Nothing
+
+ -- (UTE1.a) Don't look under type family applications.
+ | tyConMustBeSaturated tc
+ , not look_everywhere
+ = Nothing
+ -- (UTE1.c) Don't even look in the arguments past the arity of the TyCon.
+
+ -- (UTE1.b) Don't look inside class constraints.
+ | isClassTyCon tc
+ , not look_everywhere
+ = foldr (firstJust . go) Nothing (drop (tyConArity tc) tys)
+ | otherwise
+ = foldr (firstJust . go) Nothing tys
+ go (ForAllTy (Bndr tv _) ty) = go (tyVarKind tv) `firstJust` go ty
+ go (FunTy { ft_mult = mult, ft_arg = arg, ft_res = res })
+ = firstJusts
+ [ go mult
+ , go (typeKind arg)
+ , go (typeKind res)
+ , go arg
+ , go res ]
+ go (AppTy t1 t2)
+ -- (UTE1.c) Don't look inside AppTy.
+ | not look_everywhere
+ = Nothing
+ | otherwise
+ = go t1 `firstJust` go t2
+ go (CastTy ty _co) = go ty
+ go (TyVarTy tv) = go (tyVarKind tv)
+ go (CoercionTy {}) = Nothing
+ go (LitTy {}) = Nothing
-- | Does this constraint contain an user error message?
--
-- That is, the type is either of the form @Unsatisfiable err@, or it contains
-- a type of the form @TypeError msg@, either at the top level or nested inside
-- the type.
-containsUserTypeError :: PredType -> Bool
-containsUserTypeError pred =
- isJust (getUserTypeErrorMsg pred) || isJust (isUnsatisfiableCt_maybe pred)
+--
+-- See Note [Custom type errors in constraints].
+containsUserTypeError
+ :: Bool -- ^ look inside type-family applications, 'AppTy', etc?
+ -> PredType
+ -> Bool
+containsUserTypeError look_in_famapps pred =
+ isJust (isUnsatisfiableCt_maybe pred)
+ ||
+ isJust (userTypeError_maybe look_in_famapps pred)
-- | Is this type an unsatisfiable constraint?
-- If so, return the error message.
=====================================
compiler/GHC/Tc/Validity.hs
=====================================
@@ -31,6 +31,7 @@ import GHC.Tc.Instance.Family
import GHC.Tc.Types.Origin
import GHC.Tc.Types.Rank
import GHC.Tc.Errors.Types
+import GHC.Tc.Types.Constraint ( userTypeError_maybe )
import GHC.Tc.Utils.Env (tcLookupId)
import GHC.Tc.Utils.TcType
import GHC.Tc.Utils.Monad
@@ -282,7 +283,12 @@ checkUserTypeError ctxt ty
| TySynCtxt {} <- ctxt -- Do not complain about TypeError on the
= return () -- RHS of type synonyms. See #20181
- | Just msg <- deepUserTypeError_maybe ty
+ | Just msg <- userTypeError_maybe False ty
+ -- ^^^^^
+ -- Don't look under type-family applications! We only want to pull out
+ -- definite errors.
+ --
+ -- See (UTE1) in Note [Custom type errors in constraints] in GHC.Tc.Types.Constraint.
= do { env0 <- liftZonkM tcInitTidyEnv
; let (env1, tidy_msg) = tidyOpenTypeX env0 msg
; failWithTcM (env1, TcRnUserTypeError tidy_msg) }
=====================================
hadrian/bindist/config.mk.in
=====================================
@@ -174,34 +174,3 @@ UseLibffiForAdjustors=@UseLibffiForAdjustors@
# rts/Libdw.c:set_initial_registers()
UseLibdw=$(strip $(if $(filter $(TargetArch_CPP),i386 x86_64 s390x),@UseLibdw@,NO))
-#-----------------------------------------------------------------------------
-# Settings
-
-# We are in the process of moving the settings file from being entirely
-# generated by configure, to generated being by the build system. Many of these
-# might become redundant.
-# See Note [tooldir: How GHC finds mingw on Windows]
-
-LdHasFilelist = @LdHasFilelist@
-MergeObjsSupportsResponseFiles = @MergeObjsSupportsResponseFiles@
-LdHasBuildId = @LdHasBuildId@
-LdHasFilelist = @LdHasFilelist@
-LdIsGNULd = @LdIsGNULd@
-LdHasNoCompactUnwind = @LdHasNoCompactUnwind@
-LdHasSingleModule = @LdHasSingleModule@
-ArArgs = @ArArgs@
-ArSupportsAtFile = @ArSupportsAtFile@
-ArSupportsDashL = @ArSupportsDashL@
-HaskellHostOs = @HaskellHostOs@
-HaskellHostArch = @HaskellHostArch@
-HaskellTargetOs = @HaskellTargetOs@
-HaskellTargetArch = @HaskellTargetArch@
-TargetWordSize = @TargetWordSize@
-TargetWordBigEndian = @TargetWordBigEndian@
-TargetHasGnuNonexecStack = @TargetHasGnuNonexecStack@
-TargetHasIdentDirective = @TargetHasIdentDirective@
-TargetHasSubsectionsViaSymbols = @TargetHasSubsectionsViaSymbols@
-TargetHasLibm = @TargetHasLibm@
-TablesNextToCode = @TablesNextToCode@
-LeadingUnderscore = @LeadingUnderscore@
-LlvmTarget = @LlvmTarget@
=====================================
testsuite/tests/concurrent/prog001/all.T
=====================================
@@ -16,4 +16,4 @@ test('concprog001', [extra_files(['Arithmetic.hs', 'Converter.hs', 'Mult.hs', 'S
when(fast(), skip), only_ways(['threaded2']),
fragile(16604),
run_timeout_multiplier(2)],
- multimod_compile_and_run, ['Mult', ''])
+ multimod_compile_and_run, ['Mult', '-Wno-x-partial'])
=====================================
testsuite/tests/perf/compiler/T26425.hs
=====================================
@@ -0,0 +1,664 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Reproducer (strToInt) where
+
+import qualified Data.Text as T
+
+{- This program results in a nested chain of join points and cases which tests
+ primarily OccAnal and Unfolding performance.
+-}
+
+strToInt :: T.Text -> Maybe Int
+strToInt txt = case txt of
+ "0" -> Just 0
+ "1" -> Just 1
+ "2" -> Just 2
+ "3" -> Just 3
+ "4" -> Just 4
+ "5" -> Just 5
+ "6" -> Just 6
+ "7" -> Just 7
+ "8" -> Just 8
+ "9" -> Just 9
+ "10" -> Just 10
+ "11" -> Just 11
+ "12" -> Just 12
+ "13" -> Just 13
+ "14" -> Just 14
+ "15" -> Just 15
+ "16" -> Just 16
+ "17" -> Just 17
+ "18" -> Just 18
+ "19" -> Just 19
+ "20" -> Just 20
+ "21" -> Just 21
+ "22" -> Just 22
+ "23" -> Just 23
+ "24" -> Just 24
+ "25" -> Just 25
+ "26" -> Just 26
+ "27" -> Just 27
+ "28" -> Just 28
+ "29" -> Just 29
+ "30" -> Just 30
+ "31" -> Just 31
+ "32" -> Just 32
+ "33" -> Just 33
+ "34" -> Just 34
+ "35" -> Just 35
+ "36" -> Just 36
+ "37" -> Just 37
+ "38" -> Just 38
+ "39" -> Just 39
+ "40" -> Just 40
+ "41" -> Just 41
+ "42" -> Just 42
+ "43" -> Just 43
+ "44" -> Just 44
+ "45" -> Just 45
+ "46" -> Just 46
+ "47" -> Just 47
+ "48" -> Just 48
+ "49" -> Just 49
+ "50" -> Just 50
+ "51" -> Just 51
+ "52" -> Just 52
+ "53" -> Just 53
+ "54" -> Just 54
+ "55" -> Just 55
+ "56" -> Just 56
+ "57" -> Just 57
+ "58" -> Just 58
+ "59" -> Just 59
+ "60" -> Just 60
+ "61" -> Just 61
+ "62" -> Just 62
+ "63" -> Just 63
+ "64" -> Just 64
+ "65" -> Just 65
+ "66" -> Just 66
+ "67" -> Just 67
+ "68" -> Just 68
+ "69" -> Just 69
+ "70" -> Just 70
+ "71" -> Just 71
+ "72" -> Just 72
+ "73" -> Just 73
+ "74" -> Just 74
+ "75" -> Just 75
+ "76" -> Just 76
+ "77" -> Just 77
+ "78" -> Just 78
+ "79" -> Just 79
+ "80" -> Just 80
+ "81" -> Just 81
+ "82" -> Just 82
+ "83" -> Just 83
+ "84" -> Just 84
+ "85" -> Just 85
+ "86" -> Just 86
+ "87" -> Just 87
+ "88" -> Just 88
+ "89" -> Just 89
+ "90" -> Just 90
+ "91" -> Just 91
+ "92" -> Just 92
+ "93" -> Just 93
+ "94" -> Just 94
+ "95" -> Just 95
+ "96" -> Just 96
+ "97" -> Just 97
+ "98" -> Just 98
+ "99" -> Just 99
+ "100" -> Just 100
+ "101" -> Just 101
+ "102" -> Just 102
+ "103" -> Just 103
+ "104" -> Just 104
+ "105" -> Just 105
+ "106" -> Just 106
+ "107" -> Just 107
+ "108" -> Just 108
+ "109" -> Just 109
+ "110" -> Just 110
+ "111" -> Just 111
+ "112" -> Just 112
+ "113" -> Just 113
+ "114" -> Just 114
+ "115" -> Just 115
+ "116" -> Just 116
+ "117" -> Just 117
+ "118" -> Just 118
+ "119" -> Just 119
+ "120" -> Just 120
+ "121" -> Just 121
+ "122" -> Just 122
+ "123" -> Just 123
+ "124" -> Just 124
+ "125" -> Just 125
+ "126" -> Just 126
+ "127" -> Just 127
+ "128" -> Just 128
+ "129" -> Just 129
+ "130" -> Just 130
+ "131" -> Just 131
+ "132" -> Just 132
+ "133" -> Just 133
+ "134" -> Just 134
+ "135" -> Just 135
+ "136" -> Just 136
+ "137" -> Just 137
+ "138" -> Just 138
+ "139" -> Just 139
+ "140" -> Just 140
+ "141" -> Just 141
+ "142" -> Just 142
+ "143" -> Just 143
+ "144" -> Just 144
+ "145" -> Just 145
+ "146" -> Just 146
+ "147" -> Just 147
+ "148" -> Just 148
+ "149" -> Just 149
+ "150" -> Just 150
+ "151" -> Just 151
+ "152" -> Just 152
+ "153" -> Just 153
+ "154" -> Just 154
+ "155" -> Just 155
+ "156" -> Just 156
+ "157" -> Just 157
+ "158" -> Just 158
+ "159" -> Just 159
+ "160" -> Just 160
+ "161" -> Just 161
+ "162" -> Just 162
+ "163" -> Just 163
+ "164" -> Just 164
+ "165" -> Just 165
+ "166" -> Just 166
+ "167" -> Just 167
+ "168" -> Just 168
+ "169" -> Just 169
+ "170" -> Just 170
+ "171" -> Just 171
+ "172" -> Just 172
+ "173" -> Just 173
+ "174" -> Just 174
+ "175" -> Just 175
+ "176" -> Just 176
+ "177" -> Just 177
+ "178" -> Just 178
+ "179" -> Just 179
+ "180" -> Just 180
+ "181" -> Just 181
+ "182" -> Just 182
+ "183" -> Just 183
+ "184" -> Just 184
+ "185" -> Just 185
+ "186" -> Just 186
+ "187" -> Just 187
+ "188" -> Just 188
+ "189" -> Just 189
+ "190" -> Just 190
+ "191" -> Just 191
+ "192" -> Just 192
+ "193" -> Just 193
+ "194" -> Just 194
+ "195" -> Just 195
+ "196" -> Just 196
+ "197" -> Just 197
+ "198" -> Just 198
+ "199" -> Just 199
+ "200" -> Just 200
+ "201" -> Just 201
+ "202" -> Just 202
+ "203" -> Just 203
+ "204" -> Just 204
+ "205" -> Just 205
+ "206" -> Just 206
+ "207" -> Just 207
+ "208" -> Just 208
+ "209" -> Just 209
+ "210" -> Just 210
+ "211" -> Just 211
+ "212" -> Just 212
+ "213" -> Just 213
+ "214" -> Just 214
+ "215" -> Just 215
+ "216" -> Just 216
+ "217" -> Just 217
+ "218" -> Just 218
+ "219" -> Just 219
+ "220" -> Just 220
+ "221" -> Just 221
+ "222" -> Just 222
+ "223" -> Just 223
+ "224" -> Just 224
+ "225" -> Just 225
+ "226" -> Just 226
+ "227" -> Just 227
+ "228" -> Just 228
+ "229" -> Just 229
+ "230" -> Just 230
+ "231" -> Just 231
+ "232" -> Just 232
+ "233" -> Just 233
+ "234" -> Just 234
+ "235" -> Just 235
+ "236" -> Just 236
+ "237" -> Just 237
+ "238" -> Just 238
+ "239" -> Just 239
+ "240" -> Just 240
+ "241" -> Just 241
+ "242" -> Just 242
+ "243" -> Just 243
+ "244" -> Just 244
+ "245" -> Just 245
+ "246" -> Just 246
+ "247" -> Just 247
+ "248" -> Just 248
+ "249" -> Just 249
+ "250" -> Just 250
+ "251" -> Just 251
+ "252" -> Just 252
+ "253" -> Just 253
+ "254" -> Just 254
+ "255" -> Just 255
+ "256" -> Just 256
+ "257" -> Just 257
+ "258" -> Just 258
+ "259" -> Just 259
+ "260" -> Just 260
+ "261" -> Just 261
+ "262" -> Just 262
+ "263" -> Just 263
+ "264" -> Just 264
+ "265" -> Just 265
+ "266" -> Just 266
+ "267" -> Just 267
+ "268" -> Just 268
+ "269" -> Just 269
+ "270" -> Just 270
+ "271" -> Just 271
+ "272" -> Just 272
+ "273" -> Just 273
+ "274" -> Just 274
+ "275" -> Just 275
+ "276" -> Just 276
+ "277" -> Just 277
+ "278" -> Just 278
+ "279" -> Just 279
+ "280" -> Just 280
+ "281" -> Just 281
+ "282" -> Just 282
+ "283" -> Just 283
+ "284" -> Just 284
+ "285" -> Just 285
+ "286" -> Just 286
+ "287" -> Just 287
+ "288" -> Just 288
+ "289" -> Just 289
+ "290" -> Just 290
+ "291" -> Just 291
+ "292" -> Just 292
+ "293" -> Just 293
+ "294" -> Just 294
+ "295" -> Just 295
+ "296" -> Just 296
+ "297" -> Just 297
+ "298" -> Just 298
+ "299" -> Just 299
+ "300" -> Just 300
+ "301" -> Just 301
+ "302" -> Just 302
+ "303" -> Just 303
+ "304" -> Just 304
+ "305" -> Just 305
+ "306" -> Just 306
+ "307" -> Just 307
+ "308" -> Just 308
+ "309" -> Just 309
+ "310" -> Just 310
+ "311" -> Just 311
+ "312" -> Just 312
+ "313" -> Just 313
+ "314" -> Just 314
+ "315" -> Just 315
+ "316" -> Just 316
+ "317" -> Just 317
+ "318" -> Just 318
+ "319" -> Just 319
+ "320" -> Just 320
+ "321" -> Just 321
+ "322" -> Just 322
+ "323" -> Just 323
+ "324" -> Just 324
+ "325" -> Just 325
+ "326" -> Just 326
+ "327" -> Just 327
+ "328" -> Just 328
+ "329" -> Just 329
+ "330" -> Just 330
+ "331" -> Just 331
+ "332" -> Just 332
+ "333" -> Just 333
+ "334" -> Just 334
+ "335" -> Just 335
+ "336" -> Just 336
+ "337" -> Just 337
+ "338" -> Just 338
+ "339" -> Just 339
+ "340" -> Just 340
+ "341" -> Just 341
+ "342" -> Just 342
+ "343" -> Just 343
+ "344" -> Just 344
+ "345" -> Just 345
+ "346" -> Just 346
+ "347" -> Just 347
+ "348" -> Just 348
+ "349" -> Just 349
+ "350" -> Just 350
+ "351" -> Just 351
+ "352" -> Just 352
+ "353" -> Just 353
+ "354" -> Just 354
+ "355" -> Just 355
+ "356" -> Just 356
+ "357" -> Just 357
+ "358" -> Just 358
+ "359" -> Just 359
+ "360" -> Just 360
+ "361" -> Just 361
+ "362" -> Just 362
+ "363" -> Just 363
+ "364" -> Just 364
+ "365" -> Just 365
+ "366" -> Just 366
+ "367" -> Just 367
+ "368" -> Just 368
+ "369" -> Just 369
+ "370" -> Just 370
+ "371" -> Just 371
+ "372" -> Just 372
+ "373" -> Just 373
+ "374" -> Just 374
+ "375" -> Just 375
+ "376" -> Just 376
+ "377" -> Just 377
+ "378" -> Just 378
+ "379" -> Just 379
+ "380" -> Just 380
+ "381" -> Just 381
+ "382" -> Just 382
+ "383" -> Just 383
+ "384" -> Just 384
+ "385" -> Just 385
+ "386" -> Just 386
+ "387" -> Just 387
+ "388" -> Just 388
+ "389" -> Just 389
+ "390" -> Just 390
+ "391" -> Just 391
+ "392" -> Just 392
+ "393" -> Just 393
+ "394" -> Just 394
+ "395" -> Just 395
+ "396" -> Just 396
+ "397" -> Just 397
+ "398" -> Just 398
+ "399" -> Just 399
+ "400" -> Just 400
+ "401" -> Just 401
+ "402" -> Just 402
+ "403" -> Just 403
+ "404" -> Just 404
+ "405" -> Just 405
+ "406" -> Just 406
+ "407" -> Just 407
+ "408" -> Just 408
+ "409" -> Just 409
+ "410" -> Just 410
+ "411" -> Just 411
+ "412" -> Just 412
+ "413" -> Just 413
+ "414" -> Just 414
+ "415" -> Just 415
+ "416" -> Just 416
+ "417" -> Just 417
+ "418" -> Just 418
+ "419" -> Just 419
+ "420" -> Just 420
+ "421" -> Just 421
+ "422" -> Just 422
+ "423" -> Just 423
+ "424" -> Just 424
+ "425" -> Just 425
+ "426" -> Just 426
+ "427" -> Just 427
+ "428" -> Just 428
+ "429" -> Just 429
+ "430" -> Just 430
+ "431" -> Just 431
+ "432" -> Just 432
+ "433" -> Just 433
+ "434" -> Just 434
+ "435" -> Just 435
+ "436" -> Just 436
+ "437" -> Just 437
+ "438" -> Just 438
+ "439" -> Just 439
+ "440" -> Just 440
+ "441" -> Just 441
+ "442" -> Just 442
+ "443" -> Just 443
+ "444" -> Just 444
+ "445" -> Just 445
+ "446" -> Just 446
+ "447" -> Just 447
+ "448" -> Just 448
+ "449" -> Just 449
+ "450" -> Just 450
+ "451" -> Just 451
+ "452" -> Just 452
+ "453" -> Just 453
+ "454" -> Just 454
+ "455" -> Just 455
+ "456" -> Just 456
+ "457" -> Just 457
+ "458" -> Just 458
+ "459" -> Just 459
+ "460" -> Just 460
+ "461" -> Just 461
+ "462" -> Just 462
+ "463" -> Just 463
+ "464" -> Just 464
+ "465" -> Just 465
+ "466" -> Just 466
+ "467" -> Just 467
+ "468" -> Just 468
+ "469" -> Just 469
+ "470" -> Just 470
+ "471" -> Just 471
+ "472" -> Just 472
+ "473" -> Just 473
+ "474" -> Just 474
+ "475" -> Just 475
+ "476" -> Just 476
+ "477" -> Just 477
+ "478" -> Just 478
+ "479" -> Just 479
+ "480" -> Just 480
+ "481" -> Just 481
+ "482" -> Just 482
+ "483" -> Just 483
+ "484" -> Just 484
+ "485" -> Just 485
+ "486" -> Just 486
+ "487" -> Just 487
+ "488" -> Just 488
+ "489" -> Just 489
+ "490" -> Just 490
+ "491" -> Just 491
+ "492" -> Just 492
+ "493" -> Just 493
+ "494" -> Just 494
+ "495" -> Just 495
+ "496" -> Just 496
+ "497" -> Just 497
+ "498" -> Just 498
+ "499" -> Just 499
+ "500" -> Just 500
+ "501" -> Just 501
+ "502" -> Just 502
+ "503" -> Just 503
+ "504" -> Just 504
+ "505" -> Just 505
+ "506" -> Just 506
+ "507" -> Just 507
+ "508" -> Just 508
+ "509" -> Just 509
+ "510" -> Just 510
+ "511" -> Just 511
+ "512" -> Just 512
+ "513" -> Just 513
+ "514" -> Just 514
+ "515" -> Just 515
+ "516" -> Just 516
+ "517" -> Just 517
+ "518" -> Just 518
+ "519" -> Just 519
+ "520" -> Just 520
+ "521" -> Just 521
+ "522" -> Just 522
+ "523" -> Just 523
+ "524" -> Just 524
+ "525" -> Just 525
+ "526" -> Just 526
+ "527" -> Just 527
+ "528" -> Just 528
+ "529" -> Just 529
+ "530" -> Just 530
+ "531" -> Just 531
+ "532" -> Just 532
+ "533" -> Just 533
+ "534" -> Just 534
+ "535" -> Just 535
+ "536" -> Just 536
+ "537" -> Just 537
+ "538" -> Just 538
+ "539" -> Just 539
+ "540" -> Just 540
+ "541" -> Just 541
+ "542" -> Just 542
+ "543" -> Just 543
+ "544" -> Just 544
+ "545" -> Just 545
+ "546" -> Just 546
+ "547" -> Just 547
+ "548" -> Just 548
+ "549" -> Just 549
+ "550" -> Just 550
+ "551" -> Just 551
+ "552" -> Just 552
+ "553" -> Just 553
+ "554" -> Just 554
+ "555" -> Just 555
+ "556" -> Just 556
+ "557" -> Just 557
+ "558" -> Just 558
+ "559" -> Just 559
+ "560" -> Just 560
+ "561" -> Just 561
+ "562" -> Just 562
+ "563" -> Just 563
+ "564" -> Just 564
+ "565" -> Just 565
+ "566" -> Just 566
+ "567" -> Just 567
+ "568" -> Just 568
+ "569" -> Just 569
+ "570" -> Just 570
+ "571" -> Just 571
+ "572" -> Just 572
+ "573" -> Just 573
+ "574" -> Just 574
+ "575" -> Just 575
+ "576" -> Just 576
+ "577" -> Just 577
+ "578" -> Just 578
+ "579" -> Just 579
+ "580" -> Just 580
+ "581" -> Just 581
+ "582" -> Just 582
+ "583" -> Just 583
+ "584" -> Just 584
+ "585" -> Just 585
+ "586" -> Just 586
+ "587" -> Just 587
+ "588" -> Just 588
+ "589" -> Just 589
+ "590" -> Just 590
+ "591" -> Just 591
+ "592" -> Just 592
+ "593" -> Just 593
+ "594" -> Just 594
+ "595" -> Just 595
+ "596" -> Just 596
+ "597" -> Just 597
+ "598" -> Just 598
+ "599" -> Just 599
+ "600" -> Just 600
+ "601" -> Just 601
+ "602" -> Just 602
+ "603" -> Just 603
+ "604" -> Just 604
+ "605" -> Just 605
+ "606" -> Just 606
+ "607" -> Just 607
+ "608" -> Just 608
+ "609" -> Just 609
+ "610" -> Just 610
+ "611" -> Just 611
+ "612" -> Just 612
+ "613" -> Just 613
+ "614" -> Just 614
+ "615" -> Just 615
+ "616" -> Just 616
+ "617" -> Just 617
+ "618" -> Just 618
+ "619" -> Just 619
+ "620" -> Just 620
+ "621" -> Just 621
+ "622" -> Just 622
+ "623" -> Just 623
+ "624" -> Just 624
+ "625" -> Just 625
+ "626" -> Just 626
+ "627" -> Just 627
+ "628" -> Just 628
+ "629" -> Just 629
+ "630" -> Just 630
+ "631" -> Just 631
+ "632" -> Just 632
+ "633" -> Just 633
+ "634" -> Just 634
+ "635" -> Just 635
+ "636" -> Just 636
+ "637" -> Just 637
+ "638" -> Just 638
+ "639" -> Just 639
+ "640" -> Just 640
+ "641" -> Just 641
+ "642" -> Just 642
+ "643" -> Just 643
+ "644" -> Just 644
+ "645" -> Just 645
+ "646" -> Just 646
+ "647" -> Just 647
+ "648" -> Just 648
+ "649" -> Just 649
+ "650" -> Just 650
+ _ -> Nothing
=====================================
testsuite/tests/perf/compiler/all.T
=====================================
@@ -792,3 +792,8 @@ test('interpreter_steplocal',
],
ghci_script,
['interpreter_steplocal.script'])
+
+test ('T26425',
+ [ collect_compiler_stats('all',5) ],
+ compile,
+ ['-O'])
=====================================
testsuite/tests/pmcheck/should_compile/T26400.hs
=====================================
@@ -0,0 +1,37 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE StandaloneKindSignatures #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UnliftedDatatypes #-}
+
+module T26400 where
+
+import GHC.Exts ( UnliftedType )
+import GHC.TypeLits ( TypeError, ErrorMessage(..) )
+
+data N = Z | S N
+
+-- Make this type unlifted to avoid any subtleties about laziness
+type SNat :: N -> UnliftedType
+data SNat n where
+ SZ :: SNat Z
+ SS :: SNat n -> SNat (S n)
+
+type (-) :: N -> N -> N
+type family a - b where
+ n - Z = n
+ Z - S _ = TypeError ( Text "impossible" )
+ S n - S m = n - m
+
+testFn :: SNat n -> SNat m -> SNat (n - m) -> Int
+testFn SZ (SS _) SZ = 666
+testFn SZ (SS _) (SS _) = 999
+ -- [G] g1 :: n ~ Z
+ -- [G] g2 :: m ~ S m1
+ -- [G] g3 :: (n-m) ~ S m2
+ -- Use the first two givens to substitute in the third, we get:
+ -- [G] g3' :: Z - S m1 ~ S m2
+ -- Reduce the LHS using the type family
+ -- [G] g3'' :: TypeError ... ~ S m2
+ -- Hence g3'' is insoluble and the equation can never match
+testFn _ _ _ = 1
=====================================
testsuite/tests/pmcheck/should_compile/T26400.stderr
=====================================
@@ -0,0 +1,8 @@
+T26400.hs:27:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
+ Pattern match is redundant
+ In an equation for ‘testFn’: testFn SZ (SS _) SZ = ...
+
+T26400.hs:28:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
+ Pattern match is redundant
+ In an equation for ‘testFn’: testFn SZ (SS _) (SS _) = ...
+
=====================================
testsuite/tests/pmcheck/should_compile/T26400b.hs
=====================================
@@ -0,0 +1,39 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE StandaloneKindSignatures #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module T26400b where
+
+import Data.Kind
+import GHC.TypeLits ( TypeError, ErrorMessage(..) )
+
+type F :: Type -> Type -> Type
+type family F a b where
+ F Float _ = Bool
+ F _ a = a
+
+type C :: Type -> Type -> Constraint
+class C a b
+instance C () b
+
+type Boom :: Type -> Type
+type family Boom a where
+ Boom () = TypeError (Text "boom")
+
+type TF :: Type -> ( Type -> Type -> Constraint )
+type family TF a where
+ TF () = C
+
+type G :: Type -> Type -> Type
+data G a b where
+ G1 :: a -> F b (Boom a) -> G a b
+ G2 :: C a (Boom a) => a -> G a b
+ G3 :: (TF b) a (Boom a) => a -> G a b
+ G4 :: (b ~ Boom a) => G a b
+
+g :: G () b -> Int
+g (G1 {}) = 1 -- not redundant: F b (TypeError ...) can be solved if F reduces
+g (G2 {}) = 2 -- not redundant: C () (TypeError ...) is not insoluble
+g (G3 {}) = 3 -- not redundant: TF b () (TypeError ...) could reduce to C () (TypeError ...)
+g (G4 {}) = 4 -- not redundant: b ~ TypeError ... could be solved depending on instantiation of b
=====================================
testsuite/tests/pmcheck/should_compile/all.T
=====================================
@@ -123,6 +123,8 @@ test('T21761', [], compile, [overlapping_incomplete])
test('T22964', [], compile, [overlapping_incomplete])
test('T23445', [], compile, [overlapping_incomplete])
test('T24234', [], compile, [overlapping_incomplete+'-Wincomplete-uni-patterns'])
+test('T26400', [], compile, [overlapping_incomplete])
+test('T26400b', [], compile, [overlapping_incomplete])
# Series (inspired) by Luke Maranget
=====================================
testsuite/tests/typecheck/should_fail/T20241b.stderr
=====================================
@@ -1,4 +1,3 @@
-
T20241b.hs:16:8: error: [GHC-47403]
• Boom
• In the type signature:
@@ -6,11 +5,14 @@ T20241b.hs:16:8: error: [GHC-47403]
-> Type -> Constraint) IO) a =>
Proxy a -> ()
-T20241b.hs:20:8: error: [GHC-47403]
+T20241b.hs:20:8: error: [GHC-64725]
• Boom
- • In the type signature:
+ • In the ambiguity check for ‘bar’
+ To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
+ In the type signature:
bar :: ((c :: Constraint
-> Type -> Constraint) (((TypeError (Text "Boom") :: (Type -> Type)
-> Type
-> Constraint) IO) a)) a =>
Proxy a -> ()
+
=====================================
testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr
=====================================
@@ -9,11 +9,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865]
• In the first argument of ‘F’, namely ‘5’
In the newtype family instance declaration for ‘F’
-UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865]
- Expected a type,
+UnliftedNewtypesFamilyKindFail2.hs:12:31: error: [GHC-83865]
+ • Expected a type,
but ‘5’ has kind
‘GHC.Internal.Bignum.Natural.Natural’
- In the first argument of ‘F’, namely ‘5’
+ • In the first argument of ‘F’, namely ‘5’
In the type ‘(F 5)’
In the definition of data constructor ‘MkF’
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/64f8ecd611661e91057be7b5e36a6e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/64f8ecd611661e91057be7b5e36a6e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26053] 208 commits: configure: Allow use of LLVM 20
by Ben Gamari (@bgamari) 07 Oct '25
by Ben Gamari (@bgamari) 07 Oct '25
07 Oct '25
Ben Gamari pushed to branch wip/T26053 at Glasgow Haskell Compiler / GHC
Commits:
ca03226d by Ben Gamari at 2025-08-18T13:43:20+00:00
configure: Allow use of LLVM 20
- - - - -
783cd7d6 by Cheng Shao at 2025-08-18T20:13:14-04:00
compiler: use `UniqMap` instead of `Map` for `BCEnv` in bytecode compiler
The bytecode compiler maintains a `BCEnv` which was previously `Map Id
StackDepth`. Given `Id` is `Uniquable`, we might as well use `UniqMap`
here as a more efficient data structure, hence this patch.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
58e46da9 by fendor at 2025-08-18T20:13:56-04:00
rts: Strip lower three bits when hashing Word instead of lower eight bits
- - - - -
45dbfa23 by Cheng Shao at 2025-08-18T20:14:37-04:00
libffi: update to 3.5.2
Bumps libffi submodule.
- - - - -
54be78ef by Ben Gamari at 2025-08-19T16:28:05-04:00
testsuite: Fix T20006b
This test is supposed to fail for non-threaded ways yet it
was previously marked as only failing in `normal`.
Fix this.
- - - - -
f4bac607 by Simon Peyton Jones at 2025-08-19T16:28:47-04:00
Take yet more care with reporting redundant constraints
This small patch fixes #25992, which relates to reporting redundant
constraints on default-method declarations.
See (TRC5) in Note [Tracking redundant constraints]
- - - - -
ab130fec by fendor at 2025-08-19T16:29:29-04:00
Bump dependencies of hadrian-bootstrap-gen to use GHC 9.6.7
- - - - -
6d02ac6f by fendor at 2025-08-19T16:29:29-04:00
Bump required GHC version for test-bootstrap jobs to 9.10.1
Include test-bootstrap job for GHC 9.12.2.
Update hadrian bootstrap plans use GHC 9.10 and 9.12
Remove older GHC bootstrap configurations.
We require at least GHC 9.10.1 to build GHC.
Adds plans for:
* 9.10.1
* 9.10.2
* 9.12.1
* 9.12.2
- - - - -
9e857171 by Brandon Chinn at 2025-08-20T11:47:46-04:00
Don't warn unused-imports with used generated imports
Fixes #21730
* The old notion of "implicit" import has been renamed to "generated". See Note [Generated imports] in GHC.Hs.ImpExp.
* ImportMap now keeps track of generated and user-written imports separately. This avoids the fake SrcSpan we used to give the implicit Prelude import, and the hack that went with it.
* -ddump-minimal-imports now considers generated imports (but still only
warns on + prints user-written imports)
* bestImport considers generated imports to take priority over user-written imports.
- - - - -
9fb3bad4 by Ben Gamari at 2025-08-20T11:48:31-04:00
mailmap: Use ben(a)well-typed.com more liberally
Nearly all of this work was done while working for Well-Typed.
- - - - -
774fec37 by Ben Gamari at 2025-08-20T11:49:15-04:00
Add primop to annotate the call stack with arbitrary data
We introduce a new primop `annotateStack#` which allows us to push
arbitrary data onto the call-stack.
This allows us to extract the data later when decoding the stack, for
example when an exception is thrown, showing more information to the
user without having to annotate the full call-stack with `HasCallStack`
constraints.
A new stack frame value is introduced `AnnFrame`, which consists of
nothing but a generic payload.
The primop has a small wrapper API that allows users to annotate their
call-stack in programs.
There is a pure API and an IO-based one. The former is a little bit
dubious, as it affects the evaluation of a program, so use with care.
The latter is "safe", as it doesn't change the evaluation of the
program.
The stack annotation mechanism is similarly implemented to the
`ExceptionAnnotation` and `Exception`, there is a typeclass to indicate
something can be pushed onto the call-stack and all values are wrapped
in the existential `SomeStackAnnotation`, which recover the type of the
annotation payload.
There is currently no builtin way to show the stack annotations when
`Backtraces` are displayed (i.e., when showing stack traces to the user),
which we will address in a follow-up MR.
-------------------------
Metric Increase:
ghc_experimental_so
-------------------------
We increase the size of the package, so this is not unreasonable.
Co-Authored-By: fendor <fendor(a)posteo.de>
Co-Authored-By: Ben Gamari <bgamari.foss(a)gmail.com>
- - - - -
fdfa3892 by Ben Gamari at 2025-08-20T11:49:57-04:00
testsuite: Add regression test for #24606
- - - - -
39b2e382 by Cheng Shao at 2025-08-20T11:50:40-04:00
compiler: only use `Name` instead of `Id` in `SptEntry`
As a part of #26298, this patch refactors `SptEntry` to only carry a
`Name` instead of `Id`: we do not care about extra information like
caffyness or type at all in any static pointer related codegen logic.
This is necessary to make `SptEntry` serializable, as a part of the
grand plan of serializable bytecode.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
276f8ea8 by Vekhir -- at 2025-08-20T11:51:35-04:00
Bump Cabal dependency
- - - - -
0b9c7437 by Zubin Duggal at 2025-08-20T11:52:18-04:00
ci: Teach ci.sh to fetch FreeBSD artifacts from ghcup unofficial bindists and bootstrap compiler on FreeBSD to 9.10.1
Also refactor fetch_ghc logic in ci.sh, renaming the GHC_VERSION enviorment configuration variable to FETCH_GHC_VERSION,
making it clear that it is intended for use on platforms like Windows and FreeBSD where we don't want to use the GHC
excecutable from the platform environment and instead need to download and install GHC-$FETCH_GHC_VERSION from a release
bindist.
Fixes #26296
- - - - -
b2914797 by Cheng Shao at 2025-08-20T11:53:00-04:00
driver: use UniqSet for hiddenModules in DynFlags/FinderOpts
This patch replaces Set ModuleName with UniqSet ModuleName in
DynFlags.hiddenModules and FinderOpts.finder_hiddenModules for
improved efficiency.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
0335d899 by Cheng Shao at 2025-08-20T11:53:00-04:00
driver: use UniqMap ModuleName in the finder
This patch replaces Map ModuleName with UniqMap ModuleName in the
finder for improved efficiency.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
91f4faaa by Cheng Shao at 2025-08-20T11:53:43-04:00
configure: check python3 version and require minimal 3.7
Since !9515, the testsuite driver requires python3 version to be at
least 3.7, though this has never been checked by configure logic. This
patch implements the version check. Fixes #23234.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
df4ee9b4 by Cheng Shao at 2025-08-20T11:54:25-04:00
compiler: use zero cost coerce in GHC.CmmToAsm.CFG.loopInfo
This patch refactors GHC.CmmToAsm.CFG.loopInfo to use zero cost coerce
and thus addresses the TODO. For coerce to work, constructors of
Label/LabelMap/LabelSet from GHC.Cmm.Dataflow.Label are exposed,
though I believe it's a worthy tradeoff to avoid unnecessary runtime
cost without using unsafeCoerce, since the latter could be a landmine
for future refactoring.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
ccda188d by Simon Peyton Jones at 2025-08-20T11:55:07-04:00
Start with empty inerts in shortcut solving
When short-cut solving we were starting with an inert set that had
unsolved Wanteds. This caused an infinite loop (#26314), because a
typechecker plugin kept being given that unsolved Wanted.
It's better just to start with an empty inert set
- - - - -
c8882ed7 by Ben Gamari at 2025-08-20T11:55:49-04:00
configure: Bump minimal bootstrap GHC version to 9.8
- - - - -
f0a19d74 by fendor at 2025-08-20T19:55:00-04:00
Remove deprecated functions from the ghci package
- - - - -
ebeb991b by fendor at 2025-08-20T19:55:00-04:00
base: Remove unstable heap representation details from GHC.Exts
- - - - -
e368e247 by Rodrigo Mesquita at 2025-08-20T19:55:42-04:00
bytecode: Use 32bits for breakpoint index
Fixes #26325
- - - - -
42724462 by Simon Hengel at 2025-08-21T17:52:11-04:00
Serialize wired-in names as external names when creating HIE files
Note that the domain of de-serialized names stays the same.
Specifically, for known-key names, before `lookupKnownKeyName` was used,
while now this is handled by `lookupOrigNameCache` which captures the
same range provided that the OrigNameCache has been initialized with
`knownKeyNames` (which is the case by default).
(fixes #26238)
- - - - -
6a43f8ec by Cheng Shao at 2025-08-21T17:52:52-04:00
compiler: fix closure C type in SPT init code
This patch fixes the closure C type in SPT init code to StgClosure,
instead of the previously incorrect StgPtr. Having an incorrect C type
makes SPT init code not compatible with other foreign stub generation
logic, which may also emit their own extern declarations for the same
closure symbols and thus will clash with the incorrect prototypes in
SPT init code.
- - - - -
5b5d9d47 by Ben Gamari at 2025-08-25T14:29:35-04:00
Revert "STM: don't create a transaction in the rhs of catchRetry# (#26028)"
This reverts commit 0a5836891ca29836a24c306d2a364c2e4b5377fd
- - - - -
10f06163 by Cheng Shao at 2025-08-25T14:30:16-04:00
wasm: ensure setKeepCAFs() is called in ghci
This patch is a critical bugfix for #26106, see comment and linked
issue for details.
- - - - -
bedc1004 by Cheng Shao at 2025-08-26T09:31:18-04:00
compiler: use zero cost coerce in hoopl setElems/mapToList
This patch is a follow-up of !14680 and changes setElems/mapToList in
GHC/Cmm/Dataflow/Label to use coerce instead of mapping mkHooplLabel
over the keys.
- - - - -
13250d97 by Ryan Scott at 2025-08-26T09:31:59-04:00
Reject infix promoted data constructors without DataKinds
In the rename, make sure to apply the same `DataKinds` checks for both
`HsTyVar` (for prefix promoted data constructors) and `HsOpTy` (for infix
promoted data constructors) alike.
Fixes #26318.
- - - - -
37655c46 by Teo Camarasu at 2025-08-26T15:24:51-04:00
tests: disable T22859 under LLVM
This test was failing under the LLVM backend since the allocations
differ from the NCG.
Resolves #26282
- - - - -
2cbba9d6 by Teo Camarasu at 2025-08-26T15:25:33-04:00
base-exports: update version numbers
As the version of the compiler has been bumped, a lot of the embedded
version numbers will need to be updated if we ever run this test with
`--test-accept` so let's just update them now, and keep future diffs
clean.
- - - - -
f9f2ffcf by Alexandre Esteves at 2025-08-27T07:19:14-04:00
Import new name for 'utimbuf' on windows to fix #26337
Fixes an `-Wincompatible-pointer-types` instance that turns into an error on
recent toolchains and surfaced as such on nixpkgs when doing linux->ucrt cross.
This long-standing warning has been present at least since 9.4:
```
C:\GitLabRunner\builds\0\1709189\tmp\ghc16652_0\ghc_4.c:26:115: error:
warning: incompatible pointer types passing 'struct utimbuf *' to parameter of type 'struct _utimbuf *' [-Wincompatible-pointer-types]
|
26 | HsInt32 ghczuwrapperZC9ZCbaseZCSystemziPosixziInternalsZCzuutime(char* a1, struct utimbuf* a2) {return _utime(a1, a2);}
| ^
HsInt32 ghczuwrapperZC9ZCbaseZCSystemziPosixziInternalsZCzuutime(char* a1, struct utimbuf* a2) {return _utime(a1, a2);}
^~
C:\GitLabRunner\builds\0\1709189\_build\stage0\lib\..\..\mingw\x86_64-w64-mingw32\include\sys\utime.h:109:72: error:
note: passing argument to parameter '_Utimbuf' here
|
109 | __CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) {
| ^
__CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) {
```
- - - - -
ae89f000 by Hassan Al-Awwadi at 2025-08-27T07:19:56-04:00
Adds the fucnction addDependentDirectory to Q, resolving issue #26148.
This function adds a new directory to the list of things a module depends upon. That means that when the contents of the directory change, the recompilation checker will notice this and the module will be recompiled. Documentation has also been added for addDependentFunction and addDependentDirectory in the user guide.
- - - - -
00478944 by Simon Peyton Jones at 2025-08-27T16:48:30+01:00
Comments only
- - - - -
a7884589 by Simon Peyton Jones at 2025-08-28T11:08:23+01:00
Type-family occurs check in unification
The occurs check in `GHC.Core.Unify.uVarOrFam` was inadequate in dealing
with type families.
Better now. See Note [The occurs check in the Core unifier].
As I did this I realised that the whole apartness thing is trickier than I
thought: see the new Note [Shortcomings of the apartness test]
- - - - -
8adfc222 by sheaf at 2025-08-28T19:47:17-04:00
Fix orientation in HsWrapper composition (<.>)
This commit fixes the order in which WpCast HsWrappers are composed,
fixing a bug introduced in commit 56b32c5a2d5d7cad89a12f4d74dc940e086069d1.
Fixes #26350
- - - - -
eb2ab1e2 by Oleg Grenrus at 2025-08-29T11:00:53-04:00
Generalise thNameToGhcName by adding HasHscEnv
There were multiple single monad-specific `getHscEnv` across codebase.
HasHscEnv is modelled on HasDynFlags.
My first idea was to simply add thNameToGhcNameHsc and
thNameToGhcNameTc, but those would been exactly the same
as thNameToGhcName already.
Also add an usage example to thNameToGhcName and mention that it's
recommended way of looking up names in GHC plugins
- - - - -
2d575a7f by fendor at 2025-08-29T11:01:36-04:00
configure: Bump minimal bootstrap GHC version to 9.10
- - - - -
716274a5 by Simon Peyton Jones at 2025-08-29T17:27:12-04:00
Fix deep subsumption again
This commit fixed #26255:
commit 56b32c5a2d5d7cad89a12f4d74dc940e086069d1
Author: sheaf <sam.derbyshire(a)gmail.com>
Date: Mon Aug 11 15:50:47 2025 +0200
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.
But alas it still wasn't quite right for view patterns: #26331
This MR does a generalisation to fix it. A bit of a sledgehammer to crack
a nut, but nice.
* Add a field `ir_inst :: InferInstFlag` to `InferResult`, where
```
data InferInstFlag = IIF_Sigma | IIF_ShallowRho | IIF_DeepRho
```
* The flag says exactly how much `fillInferResult` should instantiate
before filling the hole.
* We can also use this to replace the previous very ad-hoc `tcInferSigma`
that was used to implement GHCi's `:type` command.
- - - - -
27206c5e by sheaf at 2025-08-29T17:28:14-04:00
Back-compat for TH SpecialiseP data-con of Pragma
This commit improves the backwards-compatibility story for the
SpecialiseP constructor of the Template Haskell 'Pragma' datatype.
Instead of keeping the constructor but deprecating it, this commit makes
it into a bundled pattern synonym of the Pragma datatype. We no longer
deprecate it; it's useful for handling old-form specialise pragmas.
- - - - -
26dbcf61 by fendor at 2025-08-30T05:10:08-04:00
Move stack decoding logic from ghc-heap to ghc-internal
The stack decoding logic in `ghc-heap` is more sophisticated than the one
currently employed in `CloneStack`. We want to use the stack decoding
implementation from `ghc-heap` in `base`.
We cannot simply depend on `ghc-heap` in `base` due do bootstrapping
issues.
Thus, we move the code that is necessary to implement stack decoding to
`ghc-internal`. This is the right location, as we don't want to add a
new API to `base`.
Moving the stack decoding logic and re-exposing it in ghc-heap is
insufficient, though, as we have a dependency cycle between.
* ghc-heap depends on stage1:ghc-internal
* stage0:ghc depends on stage0:ghc-heap
To fix this, we remove ghc-heap from the set of `stage0` dependencies.
This is not entirely straight-forward, as a couple of boot dependencies,
such as `ghci` depend on `ghc-heap`.
Luckily, the boot compiler of GHC is now >=9.10, so we can migrate `ghci`
to use `ghc-internal` instead of `ghc-heap`, which already exports the
relevant modules.
However, we cannot 100% remove ghc's dependency on `ghc-heap`, since
when we compile `stage0:ghc`, `stage1:ghc-internal` is not yet
available.
Thus, when we compile with the boot-compiler, we still depend on an
older version of `ghc-heap`, and only use the modules from `ghc-internal`,
if the `ghc-internal` version is recent enough.
-------------------------
Metric Increase:
T24602_perf_size
T25046_perf_size_gzip
T25046_perf_size_unicode
T25046_perf_size_unicode_gzip
size_hello_artifact
size_hello_artifact_gzip
size_hello_unicode
size_hello_unicode_gzip
-------------------------
These metric increases are unfortunate, they are most likely caused by
the larger (literally in terms of lines of code) stack decoder implementation
that are now linked into hello-word binaries.
On linux, it is almost a 10% increase, which is considerable.
- - - - -
bd80bb70 by fendor at 2025-08-30T05:10:08-04:00
Implement `decode` in terms of `decodeStackWithIpe`
Uses the more efficient stack decoder implementation.
- - - - -
24441165 by fendor at 2025-08-30T05:10:08-04:00
Remove stg_decodeStackzh
- - - - -
fb9cc882 by Simon Peyton Jones at 2025-08-30T05:10:51-04:00
Fix a long standing bug in the coercion optimiser
We were mis-optimising ForAllCo, leading to #26345
Part of the poblem was the tricky tower of abstractions leading to
the dreadful
GHC.Core.TyCo.Subst.substForAllCoTyVarBndrUsing
This function was serving two masters: regular substitution, but also
coercion optimsation. So tricky was it that it did so wrong.
In this MR I locate all the fancy footwork for coercion optimisation
in GHC.Core.Coercion.Opt, where it belongs. That leaves substitution
free to be much simpler.
- - - - -
6c78de2d by Sylvain Henry at 2025-09-01T08:46:19-04:00
Driver: substitute virtual Prim module in --make mode too
When we build ghc-internal with --make (e.g. with cabal-install), we
need to be careful to substitute the virtual interface file for
GHC.Internal.Prim:
- after code generation (we generate code for an empty module, so we get
an empty interface)
- when we try to reload its .hi file
- - - - -
26e0db16 by fendor at 2025-09-01T08:47:01-04:00
Expose Stack Annotation frames in IPE backtraces by default
When decoding the Haskell-native call stack and displaying the IPE information
for the stack frames, we print the `StackAnnotation` of the `AnnFrame` by default.
This means, when an exception is thrown, any intermediate stack annotations will
be displayed in the `IPE Backtrace`.
Example backtrace:
```
Exception: ghc-internal:GHC.Internal.Exception.ErrorCall:
Oh no!
IPE backtrace:
annotateCallStackIO, called at app/Main.hs:48:10 in backtrace-0.1.0.0-inplace-server:Main
annotateCallStackIO, called at app/Main.hs:46:13 in backtrace-0.1.0.0-inplace-server:Main
Main.handler (app/Main.hs:(46,1)-(49,30))
Main.liftIO (src/Servant/Server/Internal/Handler.hs:30:36-42)
Servant.Server.Internal.Delayed.runHandler' (src/Servant/Server/Internal/Handler.hs:27:31-41)
Control.Monad.Trans.Resource.runResourceT (./Control/Monad/Trans/Resource.hs:(192,14)-(197,18))
Network.Wai.Handler.Warp.HTTP1.processRequest (./Network/Wai/Handler/Warp/HTTP1.hs:195:20-22)
Network.Wai.Handler.Warp.HTTP1.processRequest (./Network/Wai/Handler/Warp/HTTP1.hs:(195,5)-(203,31))
Network.Wai.Handler.Warp.HTTP1.http1server.loop (./Network/Wai/Handler/Warp/HTTP1.hs:(141,9)-(157,42))
HasCallStack backtrace:
error, called at app/Main.hs:48:32 in backtrace-0.1.0.0-inplace-server:Main
```
The first two entries have been added by `annotateCallStackIO`, defined in `annotateCallStackIO`.
- - - - -
a1567efd by Sylvain Henry at 2025-09-01T23:01:35-04:00
RTS: rely less on Hadrian for flag setting (#25843)
Hadrian used to pass -Dfoo command-line flags directly to build the rts.
We can replace most of these flags with CPP based on cabal flags.
It makes building boot libraries with cabal-install simpler (cf #25843).
- - - - -
ca5b0283 by Sergey Vinokurov at 2025-09-01T23:02:23-04:00
Remove unnecessary irrefutable patterns from Bifunctor instances for tuples
Implementation of https://github.com/haskell/core-libraries-committee/issues/339
Metric Decrease:
mhu-perf
- - - - -
2da84b7a by sheaf at 2025-09-01T23:03:23-04:00
Only use active rules when simplifying rule RHSs
When we are simplifying the RHS of a rule, we make sure to only apply
rewrites from rules that are active throughout the original rule's
range of active phases.
For example, if a rule is always active, we only fire rules that are
themselves always active when simplifying the RHS. Ditto for inline
activations.
This is achieved by setting the simplifier phase to a range of phases,
using the new SimplPhaseRange constructor. Then:
1. When simplifying the RHS of a rule, or of a stable unfolding,
we set the simplifier phase to a range of phases, computed from
the activation of the RULE/unfolding activation, using the
function 'phaseFromActivation'.
The details are explained in Note [What is active in the RHS of a RULE?]
in GHC.Core.Opt.Simplify.Utils.
2. The activation check for other rules and inlinings is then:
does the activation of the other rule/inlining cover the whole
phase range set in sm_phase? This continues to use the 'isActive'
function, which now accounts for phase ranges.
On the way, this commit also moves the exact-print SourceText annotation
from the Activation datatype to the ActivationAnn type. This keeps the
main Activation datatype free of any extra cruft.
Fixes #26323
- - - - -
79816cc4 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
cleanup: Move dehydrateCgBreakInfo to Stg2Bc
This no longer has anything to do with Core.
- - - - -
53da94ff by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
rts/Disassembler: Fix spacing of BRK_FUN
- - - - -
08c0cf85 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Fix bciPtr in Step-out
We need to use `BCO_NEXT` to move bciPtr to ix=1, because ix=0 points to
the instruction itself!
I do not understand how this didn't crash before.
- - - - -
e7e021fa by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Allow BRK_FUNs to head case continuation BCOs
When we start executing a BCO, we may want to yield to the scheduler:
this may be triggered by a heap/stack check, context switch, or a
breakpoint. To yield, we need to put the stack in a state such that
when execution is resumed we are back to where we yielded from.
Previously, a BKR_FUN could only head a function BCO because we only
knew how to construct a valid stack for yielding from one -- simply add
`apply_interp_info` + the BCO to resume executing. This is valid because
the stack at the start of run_BCO is headed by that BCO's arguments.
However, in case continuation BCOs (as per Note [Case continuation BCOs]),
we couldn't easily reconstruct a valid stack that could be resumed
because we dropped too soon the stack frames regarding the value
returned (stg_ret) and received (stg_ctoi) by that continuation.
This is especially tricky because of the variable type and size return
frames (e.g. pointer ret_p/ctoi_R1p vs a tuple ret_t/ctoi_t2).
The trick to being able to yield from a BRK_FUN at the start of a case
cont BCO is to stop removing the ret frame headers eagerly and instead
keep them until the BCO starts executing. The new layout at the start of
a case cont. BCO is described by the new Note [Stack layout when entering run_BCO].
Now, we keep the ret_* and ctoi_* frames when entering run_BCO.
A BRK_FUN is then executed if found, and the stack is yielded as-is with
the preserved ret and ctoi frames.
Then, a case cont BCO's instructions always SLIDE off the headers of the
ret and ctoi frames, in StgToByteCode.doCase, turning a stack like
| .... |
+---------------+
| fv2 |
+---------------+
| fv1 |
+---------------+
| BCO |
+---------------+
| stg_ctoi_ret_ |
+---------------+
| retval |
+---------------+
| stg_ret_..... |
+---------------+
into
| .... |
+---------------+
| fv2 |
+---------------+
| fv1 |
+---------------+
| retval |
+---------------+
for the remainder of the BCO.
Moreover, this more uniform approach of keeping the ret and ctoi frames
means we need less ad-hoc logic concerning the variable size of
ret_tuple vs ret_p/np frames in the code generator and interpreter:
Always keep the return to cont. stack intact at the start of run_BCO,
and the statically generated instructions will take care of adjusting
it.
Unlocks BRK_FUNs at the start of case cont. BCOs which will enable a
better user-facing step-out (#26042) which is free of the bugs the
current BRK_ALTS implementation suffers from (namely, using BRK_FUN
rather than BRK_ALTS in a case cont. means we'll never accidentally end
up in a breakpoint "deeper" than the continuation, because we stop at
the case cont itself rather than on the first breakpoint we evaluate
after it).
- - - - -
ade3c1e6 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
BRK_FUN with InternalBreakLocs for code-generation time breakpoints
At the start of a case continuation BCO, place a BRK_FUN.
This BRK_FUN uses the new "internal breakpoint location" -- allowing us
to come up with a valid source location for this breakpoint that is not associated with a source-level tick.
For case continuation BCOs, we use the last tick seen before it as the
source location. The reasoning is described in Note [Debugger: Stepout internal break locs].
Note how T26042c, which was broken because it displayed the incorrect
behavior of the previous step out when we'd end up at a deeper level
than the one from which we initiated step-out, is now fixed.
As of this commit, BRK_ALTS is now dead code and is thus dropped.
Note [Debugger: Stepout internal break locs]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Step-out tells the interpreter to run until the current function
returns to where it was called from, and stop there.
This is achieved by enabling the BRK_FUN found on the first RET_BCO
frame on the stack (See [Note Debugger: Step-out]).
Case continuation BCOs (which select an alternative branch) must
therefore be headed by a BRK_FUN. An example:
f x = case g x of <--- end up here
1 -> ...
2 -> ...
g y = ... <--- step out from here
- `g` will return a value to the case continuation BCO in `f`
- The case continuation BCO will receive the value returned from g
- Match on it and push the alternative continuation for that branch
- And then enter that alternative.
If we step-out of `g`, the first RET_BCO on the stack is the case
continuation of `f` -- execution should stop at its start, before
selecting an alternative. (One might ask, "why not enable the breakpoint
in the alternative instead?", because the alternative continuation is
only pushed to the stack *after* it is selected by the case cont. BCO)
However, the case cont. BCO is not associated with any source-level
tick, it is merely the glue code which selects alternatives which do
have source level ticks. Therefore, we have to come up at code
generation time with a breakpoint location ('InternalBreakLoc') to
display to the user when it is stopped there.
Our solution is to use the last tick seen just before reaching the case
continuation. This is robust because a case continuation will thus
always have a relevant breakpoint location:
- The source location will be the last source-relevant expression
executed before the continuation is pushed
- So the source location will point to the thing you've just stepped
out of
- Doing :step-local from there will put you on the selected
alternative (which at the source level may also be the e.g. next
line in a do-block)
Examples, using angle brackets (<<...>>) to denote the breakpoint span:
f x = case <<g x>> {- step in here -} of
1 -> ...
2 -> ...>
g y = <<...>> <--- step out from here
...
f x = <<case g x of <--- end up here, whole case highlighted
1 -> ...
2 -> ...>>
doing :step-local ...
f x = case g x of
1 -> <<...>> <--- stop in the alternative
2 -> ...
A second example based on T26042d2, where the source is a do-block IO
action, optimised to a chain of `case expressions`.
main = do
putStrLn "hello1"
<<f>> <--- step-in here
putStrLn "hello3"
putStrLn "hello4"
f = do
<<putStrLn "hello2.1">> <--- step-out from here
putStrLn "hello2.2"
...
main = do
putStrLn "hello1"
<<f>> <--- end up here again, the previously executed expression
putStrLn "hello3"
putStrLn "hello4"
doing step/step-local ...
main = do
putStrLn "hello1"
f
<<putStrLn "hello3">> <--- straight to the next line
putStrLn "hello4"
Finishes #26042
- - - - -
c66910c0 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Re-use the last BreakpointId whole in step-out
Previously, to come up with a location to stop at for `:stepout`, we
would store the location of the last BreakpointId surrounding the
continuation, as described by Note [Debugger: Stepout internal break locs].
However, re-using just the location from the last source breakpoint
isn't sufficient to provide the necessary information in the break
location. Specifically, it wouldn't bind any variables at that location.
Really, there is no reason not to re-use the last breakpoint wholesale,
and re-use all the information we had there. Step-out should behave just
as if we had stopped at the call, but s.t. continuing will not
re-execute the call.
This commit updates the CgBreakInfo to always store a BreakpointId, be
it the original one or the one we're emulating (for step-out).
It makes variable bindings on :stepout work
- - - - -
e4abed7b by sheaf at 2025-09-02T12:20:40-04:00
Revert accidental changes to hie.yaml
- - - - -
003b715b by meooow25 at 2025-09-02T23:48:51+02:00
Adjust the strictness of Data.List.iterate'
* Don't force the next element in advance when generating a (:).
* Force the first element to WHNF like every other element.
Now every element in the output list is forced to WHNF when the (:)
containing it is forced.
CLC proposal:
https://github.com/haskell/core-libraries-committee/issues/335
- - - - -
b2f6aad0 by Simon Hengel at 2025-09-03T04:36:10-04:00
Refactoring: More consistently use logOutput, logInfo, fatalErrorMsg
- - - - -
60a16db7 by Rodrigo Mesquita at 2025-09-03T10:55:50+01:00
bytecode: Don't PUSH_L 0; SLIDE 1 1
While looking through bytecode I noticed a quite common unfortunate
pattern:
...
PUSH_L 0
SLIDE 1 1
We do this often by generically constructing a tail call from a function
atom that may be somewhere arbitrary on the stack.
However, for the special case that the function can be found directly on
top of the stack, as part of the arguments, it's plain redundant to push
then slide it.
In this commit we add a small optimisation to the generation of
tailcalls in bytecode. Simply: lookahead for the function in the stack.
If it is the first thing on the stack and it is part of the arguments
which would be dropped as we entered the tail call, then don't push then
slide it.
In a simple example (T26042b), this already produced a drastic
improvement in generated code (left is old, right is with this patch):
```diff
3c3
< 2025-07-29 10:14:02.081277 UTC
---
> 2025-07-29 10:50:36.560949 UTC
160,161c160
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
164,165d162
< PUSH_L 0
< SLIDE 1 1
175,176c172
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
179,180d174
< PUSH_L 0
< SLIDE 1 1
206,207d199
< PUSH_L 0
< SLIDE 1 1
210,211d201
< PUSH_L 0
< SLIDE 1 1
214,215d203
< PUSH_L 0
< SLIDE 1 1
218,219d205
< PUSH_L 0
< SLIDE 1 1
222,223d207
< PUSH_L 0
< SLIDE 1 1
...
600,601c566
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
604,605d568
< PUSH_L 0
< SLIDE 1 1
632,633d594
< PUSH_L 0
< SLIDE 1 1
636,637d596
< PUSH_L 0
< SLIDE 1 1
640,641d598
< PUSH_L 0
< SLIDE 1 1
644,645d600
< PUSH_L 0
< SLIDE 1 1
648,649d602
< PUSH_L 0
< SLIDE 1 1
652,653d604
< PUSH_L 0
< SLIDE 1 1
656,657d606
< PUSH_L 0
< SLIDE 1 1
660,661d608
< PUSH_L 0
< SLIDE 1 1
664,665d610
< PUSH_L 0
< SLIDE 1 1
```
I also compiled lib:Cabal to bytecode and counted the number of bytecode
lines with `find dist-newstyle -name "*.dump-BCOs" -exec wc {} +`:
with unoptimized core:
1190689 lines (before) - 1172891 lines (now)
= 17798 less redundant instructions (-1.5% lines)
with optimized core:
1924818 lines (before) - 1864836 lines (now)
= 59982 less redundant instructions (-3.1% lines)
- - - - -
8b2c72c0 by L0neGamer at 2025-09-04T06:32:03-04:00
Add Control.Monad.thenM and Control.Applicative.thenA
- - - - -
39e1b7cb by Teo Camarasu at 2025-09-04T06:32:46-04:00
ghc-internal: invert dependency of GHC.Internal.TH.Syntax on Data.Data
This means that Data.Data no longer blocks building TH.Syntax, which
allows greater parallelism in our builds.
We move the Data.Data.Data instances to Data.Data. Quasi depends on
Data.Data for one of its methods, so,
we split the Quasi/Q, etc definition out of GHC.Internal.TH.Syntax
into its own module. This has the added benefit of splitting up this
quite large module.
Previously TH.Syntax was a bottleneck when compiling ghc-internal. Now
it is less of a bottle-neck and is also slightly quicker to
compile (since it no longer contains these instances) at the cost of
making Data.Data slightly more expensive to compile.
TH.Lift which depends on TH.Syntax can also compile quicker and no
longer blocks ghc-internal finishing to compile.
Resolves #26217
-------------------------
Metric Decrease:
MultiLayerModulesTH_OneShot
T13253
T21839c
T24471
Metric Increase:
T12227
-------------------------
- - - - -
bdf82fd2 by Teo Camarasu at 2025-09-04T06:32:46-04:00
compiler: delete unused names in Builtins.Names.TH
returnQ and bindQ are no longer used in the compiler.
There was also a very old comment that referred to them that I have modernized
- - - - -
41a448e5 by Ben Gamari at 2025-09-04T19:21:43-04:00
hadrian: Pass lib & include directories to ghc `Setup configure`
- - - - -
46bb9a79 by Ben Gamari at 2025-09-04T19:21:44-04:00
rts/IPE: Fix compilation when zstd is enabled
This was broken by the refactoring undertaken in
c80dd91c0bf6ac034f0c592f16c548b9408a8481.
Closes #26312.
- - - - -
138a6e34 by sheaf at 2025-09-04T19:22:46-04:00
Make mkCast assertion a bit clearer
This commit changes the assertion message that gets printed when one
calls mkCast with a coercion whose kind does not match the type of the
inner expression. I always found the assertion message a bit confusing,
as it didn't clearly state what exactly was the error.
- - - - -
9d626be1 by sheaf at 2025-09-04T19:22:46-04:00
Simplifier/rules: fix mistakes in Notes & comments
- - - - -
94b62aa7 by Simon Peyton Jones at 2025-09-08T03:37:14-04:00
Refactor ForAllCo
This is a pure refactor, addressing #26389.
It arranges that the kind coercion in a ForAllCo is a MCoercion, rather
than a plain Coercion, thus removing redundancy in the common case.
See (FC8) in Note [ForAllCo]
It's a nice cleanup.
- - - - -
624afa4a by sheaf at 2025-09-08T03:38:05-04:00
Use tcMkScaledFunTys in matchExpectedFunTys
We should use tcMkScaledFunTys rather than mkScaledFunTys in
GHC.Tc.Utils.Unify.matchExpectedFunTys, as the latter crashes
when the kind of the result type is a bare metavariable.
We know the result is always Type-like, so we don't need scaledFunTys
to try to rediscover that from the kind.
Fixes #26277
- - - - -
0975d2b6 by sheaf at 2025-09-08T03:38:54-04:00
Revert "Remove hptAllFamInstances usage during upsweep"
This reverts commit 3bf6720eff5e86e673568e756161e6d6150eb440.
- - - - -
0cf34176 by soulomoon at 2025-09-08T03:38:54-04:00
Family consistency checks: add test for #26154
This commit adds the test T26154, to make sure that GHC doesn't crash
when performing type family consistency checks. This test case
was extracted from Agda.
Fixes #26154
- - - - -
ba210d98 by Simon Peyton Jones at 2025-09-08T16:26:36+01:00
Report solid equality errors before custom errors
This MR fixes #26255 by
* Reporting solid equality errors like
Int ~ Bool
before "custom type errors". See comments in `report1` in
`reportWanteds`
* Suppressing errors that arise from superclasses of
Wanteds. See (SCE1) in Note [Suppressing confusing errors]
More details in #26255.
- - - - -
b6249140 by Simon Peyton Jones at 2025-09-10T10:42:38-04:00
Fix a scoping error in Specialise
This small patch fixes #26329, which triggered a scoping error.
Test is in T21391, with -fpolymorphic-specialisation enabled
- - - - -
45305ab8 by sheaf at 2025-09-10T10:43:29-04:00
Make rationalTo{Float,Double} inline in phase 0
We hold off on inlining these until phase 0 to allow constant-folding
rules to fire. However, once we get to phase 0, we should inline them,
e.g. to expose unboxing opportunities.
See CLC proposal #356.
- - - - -
0959d4bc by Andreas Klebinger at 2025-09-10T10:44:12-04:00
Add regression test for #26056
- - - - -
dc79593d by sheaf at 2025-09-10T10:45:01-04:00
Deep subsumption: unify mults without tcEqMult
As seen in #26332, we may well end up with a non-reflexive multiplicity
coercion when doing deep subsumption. We should do the same thing that
we do without deep subsumption: unify the multiplicities normally,
without requiring that the coercion is reflexive (which is what
'tcEqMult' was doing).
Fixes #26332
- - - - -
4bfe2269 by sheaf at 2025-09-10T10:45:50-04:00
lint-codes: fixup MSYS drive letter on Windows
This change ensures that System.Directory.listDirectory doesn't trip up
on an MSYS-style path like '/c/Foo' when trying to list all testsuite
stdout/stderr files as required for testing coverage of GHC diagnostic
codes in the testsuite.
Fixes #25178
- - - - -
56540775 by Ben Gamari at 2025-09-10T10:46:32-04:00
gitlab-ci: Disable split sections on FreeBSD
Due to #26303.
- - - - -
1537784b by Moritz Angermann at 2025-09-10T10:47:13-04:00
Improve mach-o relocation information
This change adds more information about the symbol and addresses
we try to relocate in the linker. This significantly helps when
deubbging relocation issues reported by users.
- - - - -
4e67855b by Moritz Angermann at 2025-09-10T10:47:54-04:00
test.mk expect GhcLeadingUnderscore, not LeadingUnderscore (in line with the other Ghc prefixed variables.
- - - - -
c1cdd265 by Moritz Angermann at 2025-09-10T10:48:35-04:00
testsuite: Fix broken exec_signals_child.c
There is no signal 0. The signal mask is 1-32.
- - - - -
99ac335c by Moritz Angermann at 2025-09-10T10:49:15-04:00
testsuite: clarify Windows/Darwin locale rationale for skipping T6037 T2507 T8959a
- - - - -
0e8fa77a by Moritz Angermann at 2025-09-10T10:49:56-04:00
Skip broken tests on macOS (due to leading underscore not handled properly in the expected output.)
- - - - -
28570c59 by Zubin Duggal at 2025-09-10T10:50:37-04:00
docs(sphinx): fix links to reverse flags when using the :ghc-flag:`-fno-<flag>` syntax
This solution is rather hacky and I suspect there is a better way to do this but I don't know
enough about Sphinx to do better.
Fixes #26352
- - - - -
d17257ed by Cheng Shao at 2025-09-10T17:01:27+02:00
rel-eng: update alpine images to 3.22
This patch is a part of #25876 and updates alpine images to 3.22,
while still retaining 3.12 for x86_64 fully_static bindists.
-------------------------
Metric Decrease:
MultiComponentModulesRecomp
-------------------------
- - - - -
db3276bb by Sylvain Henry at 2025-09-11T11:27:28-04:00
T16180: indicate that the stack isn't executable
- - - - -
11eeeba7 by Sylvain Henry at 2025-09-11T11:27:28-04:00
Fix some tests (statically linked GHC vs libc)
When GHC is linked statically, the stdout C global variable that GHC uses
isn't shared with the stdout C global variable used by loaded code.
As a consequence, the latter must be explicitly flushed because GHC
won't flush it before exiting.
- - - - -
80a07571 by Sylvain Henry at 2025-09-11T11:28:18-04:00
Testsuite: fix debug_rts detection
Running the testsuite without Hadrian should set config.debug_rts
correctly too.
- - - - -
62ae97de by Duncan Coutts at 2025-09-12T13:23:33-04:00
Handle heap allocation failure in I/O primops
The current I/O managers do not use allocateMightFail, but future ones
will. To support this properly we need to be able to return to the
primop with a failure. We simply use a bool return value.
Currently however, we will just throw an exception rather than calling
the GC because that's what all the other primops do too.
For the general issue of primops invoking GC and retrying, see
https://gitlab.haskell.org/ghc/ghc/-/issues/24105
- - - - -
cb9093f5 by Duncan Coutts at 2025-09-12T13:23:33-04:00
Move (and rename) scheduleStartSignalHandlers into RtsSignals.h
Previously it was a local helper (static) function in Schedule.c.
Rename it to startPendingSignalHandlers and deifine it as an inline
header function in RtsSignals.h. So it should still be fast.
Each (new style) I/O manager is going to need to do the same, so eliminating
the duplication now makes sense.
- - - - -
9736d44a by Duncan Coutts at 2025-09-12T13:23:33-04:00
Reduce detail in printThreadBlockage I/O blocking cases
The printThreadBlockage is used in debug tracing output.
For the cases BlockedOn{Read,Write,Delay} the output previously included
the fd that was being waited on, and the delay target wake time.
Superficially this sounds useful, but it's clearly not that useful
because it was already wrong for the Win32 non-threaded I/O manager. In
that situation it will print garbage (the async_result pointer, cast to
a fd or a time).
So given that it apparently never mattered that the information was
accurate, then it's hardly a big jump to say it doesn't matter if it is
present at all.
A good reason to remove it is that otherwise we have to make a new
API and a per-I/O manager implementation to fetch the information. And
for some I/O manager implementations, this information is not available.
It is not available in the win32 non-threaded I/O manager. And for some
future Linux ones, there is no need for the fd to be stored, so storing
it would be just extra space used for very little gain.
So the simplest thing is to just remove the detail.
- - - - -
bc0f2d5d by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add TimeoutQueue.{c,h} and corresponding tests
A data structure used to efficiently manage a collection of timeouts.
It is a priority queue based on absolute expiry time. It uses 64bit
high-precision Time for the keys. The values are normal closures which
allows for example using MVars for unblocking.
It is common in many applications for timeouts to be created and then
deleted or altered before they expire. Thus the choice of data structure
for timeouts should support this efficiently. The implementation choice
here is a leftist heap with the extra feature that it supports deleting
arbitrary elements, provided the caller retain a pointer to the element.
While the deleteMin operation takes O(log n) time, as in all heap
structures, the delete operation for arbitrary elements /typically/
takes O(1), and only O(log n) in the worst case. In practice, when
managing thousands of timeouts it can be a factor of 10 faster to delete
a random timeout queue element than to remove the minimum element. This
supports the common use case.
The plan is to use it in some of the RTS-side I/O managers to support
their timer functionality. In this use case the heap value will be an
MVar used for each timeout to unblock waiting threads.
- - - - -
d1679c9d by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add ClosureTable.{c,h} and corresponding tests
A table of pointers to closures on the GC heap with stable indexes.
It provides O(1) alloc, free and lookup. The table can be expanded
using a simple doubling strategy: in which case allocation is typically
O(1) and occasionally O(n) for overall amortised O(1). No shrinking is
used.
The table itself is heap allocated, and points to other heap objects.
As such it's necessary to use markClosureTable to ensure the table is
used as a GC root to keep the table entries alive, and maintain proper
pointers to them as the GC moves heap objects about.
It is designed to be allocated and accesses exclusively from a single
capability, enabling it to work without any locking. It is thus similar
to the StablePtr table, but per-capability which removes the need for
locking. It _should_ also provide lower GC pause times with the
non-moving GC by spending only O(1) time in markClosureTable, vs O(n)
for markStablePtrTable.
The plan is to use it in some of the I/O managers to keep track of
in-flight I/O operations (but not timers). This allows the tracking
info to be kept on the (unpinned) GC heap, and shared with Haskell
code, and by putting a pointer to the tracking information in a table,
the index remains stable and can be passed via foreign code (like the
kernel).
- - - - -
78cb8dd5 by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add the StgAsyncIOOp closure type
This is intended to be used by multiple I/O managers to help with
tracking in-flight I/O operations.
It is called asynchronous because from the point of view of the RTS we
have many such operations in progress at once. From the point of view of
a Haskell thread of course it can look synchronous.
- - - - -
a2839896 by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add StgAsyncIOOp and StgTimeoutQueue to tso->block_info
These will be used by new I/O managers, for threads blocked on I/O or
timeouts.
- - - - -
fdc2451c by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add a new I/O manager based on poll()
This is a proof of concept I/O manager, to show how to add new ones
neatly, using the ClosureTable and TimeoutQueue infrastructure.
It uses the old unix poll() API, so it is of course limited in
performance by that, but it should have the benefit of wide
compatibility. Also we neatly avoid a name clash with the existing
select() I/O manager.
Compared to the select() I/O manager:
1. beause it uses poll() it is not limited to 1024 file descriptors
(but it's still O(n) so don't expect great performance);
2. it should have much faster threadDelay (when using it in lots of
threads at once) because it's based on the new TimeoutQueue which is
O(log n) rather than O(n).
Some of the code related to timers/timouts is put into a shared module
rts/posix/Timeout.{h,c} since it is intended to be shared with other
similar I/O managers.
- - - - -
6c273b76 by Duncan Coutts at 2025-09-12T13:23:34-04:00
Document the I/O managers in the user guide
and note the new poll I/O manager in the release notes.
- - - - -
824fab74 by Duncan Coutts at 2025-09-12T13:23:34-04:00
Use the poll() I/O manager by default
That is, for the non-threaded RTS, prefer the poll I/O manager over the
legacy select() one, if both can be enabled.
This patch is primarily for CI testing, so we should probably remove
this patch before merging. We can change defaults later after wider
testing and feedback.
- - - - -
39392532 by Luite Stegeman at 2025-09-12T13:24:16-04:00
Support larger unboxed sums
Change known constructor encoding for sums in interfaces to use
11 bits for both the arity and the alternative (up from 8 and 6,
respectively)
- - - - -
2af12e21 by Luite Stegeman at 2025-09-12T13:24:16-04:00
Decompose padding smallest-first in Cmm toplevel data constructors
This makes each individual padding value aligned
- - - - -
418fa78f by Luite Stegeman at 2025-09-12T13:24:16-04:00
Use slots smaller than word as tag for smaller unboxed sums
This packs unboxed sums more efficiently by allowing
Word8, Word16 and Word32 for the tag field if the number of
constructors is small enough
- - - - -
8d7e912f by Rodrigo Mesquita at 2025-09-12T17:57:24-04:00
ghc-toolchain: Use ByteOrder rather than new Endianness
Don't introduce a duplicate datatype when the previous one is equivalent
and already used elsewhere. This avoids unnecessary translation between
the two.
- - - - -
7d378476 by Rodrigo Mesquita at 2025-09-12T17:57:24-04:00
Read Toolchain.Target files rather than 'settings'
This commit makes GHC read `lib/targets/default.target`, a file with a
serialized value of `ghc-toolchain`'s `GHC.Toolchain.Target`.
Moreover, it removes all the now-redundant entries from `lib/settings`
that are configured as part of a `Target` but were being written into
`settings`.
This makes it easier to support multiple targets from the same compiler
(aka runtime retargetability). `ghc-toolchain` can be re-run many times
standalone to produce a `Target` description for different targets, and,
in the future, GHC will be able to pick at runtime amongst different
`Target` files.
This commit only makes it read the default `Target` configured in-tree
or configured when installing the bindist.
The remaining bits of `settings` need to be moved to `Target` in follow
up commits, but ultimately they all should be moved since they are
per-target relevant.
Fixes #24212
On Windows, the constant overhead of parsing a slightly more complex
data structure causes some small-allocation tests to wiggle around 1 to
2 extra MB (1-2% in these cases).
-------------------------
Metric Increase:
MultiLayerModulesTH_OneShot
T10421
T10547
T12234
T12425
T13035
T18140
T18923
T9198
TcPlugin_RewritePerf
-------------------------
- - - - -
e0780a16 by Rodrigo Mesquita at 2025-09-12T17:57:24-04:00
ghc-toolchain: Move TgtHasLibm to per-Target file
TargetHasLibm is now part of the per-target configuration
Towards #26227
- - - - -
8235dd8c by Rodrigo Mesquita at 2025-09-12T17:57:24-04:00
ghc-toolchain: Move UseLibdw to per-Target file
To support DWARF unwinding, the RTS must be built with the -f+libdw flag
and with the -DUSE_LIBDW macro definition. These flags are passed on
build by Hadrian when --enable-dwarf-unwinding is specified at configure
time.
Whether the RTS was built with support for DWARF is a per-target
property, and as such, it was moved to the per-target
GHC.Toolchain.Target.Target file.
Additionally, we keep in the target file the include and library paths
for finding libdw, since libdw should be checked at configure time (be
it by configure, or ghc-toolchain, that libdw is properly available).
Preserving the user-given include paths for libdw facilitates in the
future building the RTS on demand for a given target (if we didn't keep
that user input, we couldn't)
Towards #26227
- - - - -
d5ecf2e8 by Rodrigo Mesquita at 2025-09-12T17:57:25-04:00
ghc-toolchain: Make "Support SMP" a query on a Toolchain.Target
"Support SMP" is merely a function of target, so we can represent it as
such in `ghc-toolchain`.
Hadrian queries the Target using this predicate to determine how to
build GHC, and GHC queries the Target similarly to report under --info
whether it "Support SMP"
Towards #26227
- - - - -
e07b031a by Rodrigo Mesquita at 2025-09-12T17:57:25-04:00
ghc-toolchain: Make "tgt rts linker only supports shared libs" function on Target
Just like with "Support SMP", "target RTS linker only supports shared
libraries" is a predicate on a `Target` so we can just compute it when
necessary from the given `Target`.
Towards #26227
- - - - -
14123ee6 by Simon Peyton Jones at 2025-09-12T17:58:07-04:00
Solve forall-constraints via an implication, again
In this earlier commit:
commit 953fd8f1dc080f1c56e3a60b4b7157456949be29
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Jul 21 10:06:43 2025 +0100
Solve forall-constraints immediately, or not at all
I used a all-or-nothing strategy for quantified constraints
(aka forall-constraints). But alas that fell foul of #26315,
and #26376.
So this MR goes back to solving a quantified constraint by
turning it into an implication; UNLESS we are simplifying
constraints from a SPECIALISE pragma, in which case the
all-or-nothing strategy is great. See:
Note [Solving a Wanted forall-constraint]
Other stuff in this MR:
* TcSMode becomes a record of flags, rather than an enumeration
type; much nicer.
* Some fancy footwork to avoid error messages worsening again
(The above MR made them better; we want to retain that.)
See `GHC.Tc.Errors.Ppr.pprQCOriginExtra`.
-------------------------
Metric Decrease:
T24471
-------------------------
- - - - -
e6c192e2 by Simon Peyton Jones at 2025-09-12T17:58:07-04:00
Add a test case for #26396
...same bug ast #26315
- - - - -
8f3d80ff by Luite Stegeman at 2025-09-13T08:43:09+02:00
Use mkVirtHeapOffsets for reconstructing terms in RTTI
This makes mkVirtHeapOffsets the single source of truth for
finding field offsets in closures.
- - - - -
eb389338 by Luite Stegeman at 2025-09-13T08:43:09+02:00
Sort non-pointer fields by size for more efficient packing
This sorts non-pointer fields in mkVirtHeapOffsets, always
storing the largest field first. The relative order of
equally sized fields remains unchanged.
This reduces wasted padding/alignment space in closures with
differently sized fields.
- - - - -
99b233f4 by Alison at 2025-09-13T16:51:04-04:00
ghc-heap: Fix race condition with profiling builds
Apply the same fix from Closures.hs (64fd0fac83) to Heap.hs by adding
empty imports to make way-dependent dependencies visible to `ghc -M`.
Fixes #15197, #26407
- - - - -
77deaa7a by Cheng Shao at 2025-09-14T21:29:45-04:00
hadrian: build in-tree gmp with -fvisibility=hidden
When hadrian builds in-tree gmp, it should build the shared objects
with -fvisibility=hidden. The gmp symbols are only used by bignum
logic in ghc-internal and shouldn't be exported by the ghc-internal
shared library. We should always strive to keep shared library symbol
table lean, which benefits platforms with slow dynamic linker or even
hard limits about how many symbols can be exported (e.g. macos dyld,
win32 dll and wasm dyld).
- - - - -
42a18960 by Cheng Shao at 2025-09-14T21:30:26-04:00
Revert "wasm: add brotli compression for ghci browser mode"
This reverts commit 731217ce68a1093b5f9e26a07d5bd2cdade2b352.
Benchmarks show non-negligible overhead when browser runs on the same
host, which is the majority of actual use cases.
- - - - -
e6755b9f by Cheng Shao at 2025-09-14T21:30:26-04:00
wasm: remove etag logic in ghci browser mode web server
This commit removes the etag logic in dyld script's ghci browser mode
web server. It was meant to support caching logic of wasm shared
libraries, but even if the port is manually specified to make caching
even relevant, for localhost the extra overhead around etag logic is
simply not worth it according to benchmarks.
- - - - -
ac5859b9 by sheaf at 2025-09-16T14:58:38-04:00
Add 'Outputable Natural' instance
This commit adds an Outputable instance for the Natural natural-number type,
as well as a "natural :: Natural -> SDoc" function that mirrors the existing
"integer" function.
- - - - -
d48ebc23 by Cheng Shao at 2025-09-16T14:59:18-04:00
autoconf: emit warning instead of error for FIND_PYTHON logic
This patch makes FIND_PYTHON logic emit warning instead of error, so
when the user doesn't expect to run the testsuite driver (especially
when installing a bindist), python would not be mandatory. Fixes #26347.
- - - - -
54b5950e by Sylvain Henry at 2025-09-17T04:45:18-04:00
Print fully qualified unit names in name mismatch
It's more user-friendly to directly print the right thing instead of
requiring the user to retry with the additional `-dppr-debug` flag.
- - - - -
403cb665 by Ben Gamari at 2025-09-17T04:46:00-04:00
configure: Fix consistency between distrib and source CC check
Previously distrib/configure.ac did not
include `cc`.
Closes #26394.
- - - - -
2dcd4cb9 by Oleg Grenrus at 2025-09-17T04:46:41-04:00
Use isPrint in showUnique
The comment say
```
-- Avoid emitting non-printable characters in pretty uniques. See #25989.
```
so let the code do exactly that.
There are tags (at least : and 0 .. 9) which weren't in A .. z range.
- - - - -
e5dd754b by Oleg Grenrus at 2025-09-17T04:46:42-04:00
Shorten in-module links in hyperlinked source
Instead of href="This.Module#ident" to just "#ident"
- - - - -
63189b2c by Oleg Grenrus at 2025-09-17T04:46:42-04:00
Use showUnique in internalAnchorIdent
Showing the key of Unique as a number is generally not a great idea.
GHC Unique has a tag in high bits, so the raw number is unnecessarily
big.
So now we have
```html
<a href="#l-rvgK"><span class="hs-identifier hs-var hs-var">bar</span></a>
```
instead of
```html
<a href="#local-6989586621679015689"><span class="hs-identifier hs-var hs-var">bar</span></a>
```
Together with previous changes of shorter intra-module links the effect
on compressed files is not huge, that is expected as we simply remove
repetitive contents which pack well.
```
12_694_206 Agda-2.9.0-docs-orig.tar.gz
12_566_065 Agda-2.9.0-docs.tar.gz
```
However when unpacked, the difference can be significant,
e.g. Agda's largest module source got 5% reduction:
```
14_230_117 Agda.Syntax.Parser.Parser.html
13_422_109 Agda.Syntax.Parser.Parser.html
```
The whole hyperlinked source code directory got similar reduction
```
121M Agda-2.9.0-docs-orig/src
114M Agda-2.9.0-docs/src
```
For the reference, sources are about 2/3 of the generated haddocks
```
178M Agda-2.9.0-docs-old
172M Agda-2.9.0-docs
```
so we get around 3.5% size reduction overall. Not bad for a small local
changes.
- - - - -
6f63f57b by Stefan Schulze Frielinghaus at 2025-09-17T04:47:22-04:00
rts: Fix alignment for gen_workspace #26334
After a0fa4941903272c48b050d24e93eec819eff51bd bootstrap is broken on
s390x and errors out with
rts/sm/GCThread.h:207:5: error:
error: alignment of array elements is greater than element size
207 | gen_workspace gens[];
| ^~~~~~~~~~~~~
The alignment constraint is applied via the attribute to the type
gen_workspace and leaves the underlying type struct gen_workspace_
untouched. On Aarch64, x86, and s390x the struct has a size of 128
bytes. On Aarch64 and x86 the alignments of 128 and 64 are divisors of
the size, respectively, which is why the type is a viable member type
for an array. However, on s390x, the alignment is 256 and therefore is
not a divisor of the size and hence cannot be used for arrays.
Basically I see two fixes here. Either decrease the alignment
requirement on s390x, or by applying the alignment constraint on the
struct itself. The former might affect performance as noted in
a0fa4941903272c48b050d24e93eec819eff51bd. The latter introduces padding
bits whenever necessary in order to ensure that
sizeof(gen_workspace[N])==N*sizeof(gen_workspace) holds which is done by
this patch.
- - - - -
06d25623 by Cheng Shao at 2025-09-17T19:32:27-04:00
ghci: add :shell command
This patch adds a new :shell command to ghci which works similarly to
:!, except it guarantees to run the command via sh -c. On POSIX hosts
the behavior is identical to :!, but on Windows it uses the msys2
shell instead of system cmd.exe shell. This is convenient when writing
simple ghci scripts that run simple POSIX commands, and the behavior
can be expected to be coherent on both Windows and POSIX.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
186054f7 by Cheng Shao at 2025-09-17T19:32:27-04:00
testsuite: remove legacy :shell trick
This commit makes use of the built-in :shell functionality in ghci in
the test cases, and remove the legacy :shell trick.
- - - - -
0a3a4aa3 by Cheng Shao at 2025-09-17T19:32:27-04:00
docs: document :shell in ghci
This commit documents the :shell command in ghci.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
a4ff12bb by Cheng Shao at 2025-09-17T19:33:09-04:00
ghc-internal: fix codepages program
codepages was not properly updated during the base -> ghc-internal
migration, this commit fixes it.
- - - - -
7e094def by Cheng Shao at 2025-09-17T19:33:09-04:00
ghc-internal: relax ucd2haskell cabal upper bounds
This commit relaxes ucd2haskell cabal upper bounds to make it runnable
via ghc 9.12/9.14.
- - - - -
7077c9f7 by Cheng Shao at 2025-09-17T19:33:09-04:00
ghc-internal: update to unicode 17.0.0
This commit updates the generated code in ghc-internal to match
unicode 17.0.0.
- - - - -
cef8938f by sheaf at 2025-09-17T19:34:09-04:00
Bad record update msg: allow out-of-scope datacons
This commit ensures that, when we encounter an invalid record update
(because no constructor exists which contains all of the record fields
mentioned in the record update), we graciously handle the situation in
which the constructors themselves are not in scope. In that case,
instead of looking up the constructors in the GlobalRdrEnv, directly
look up their GREInfo using the lookupGREInfo function.
Fixes #26391
- - - - -
a2d9d7c2 by sheaf at 2025-09-17T19:34:09-04:00
Improve Notes about disambiguating record updates
This commit updates the notes [Disambiguating record updates] and
[Type-directed record disambiguation], in particular adding more
information about the deprecation status of type-directed disambiguation
of record updates.
- - - - -
de44e69e by sheaf at 2025-09-19T05:16:51-04:00
Enable TcM plugins in initTc
This commit ensures that we run typechecker plugins and defaulting
plugins whenever we call initTc.
In particular, this ensures that the pattern-match checker, which calls
'initTcDsForSolver' which calls 'initTc', runs with typechecker plugins
enabled. This matters for situations like:
merge :: Vec n a -> Vec n a -> Vec (2 * n) a
merge Nil Nil = Nil
merge (a <: as) (b <: bs) = a :< (b <: merge as bs)
in which we need the typechecker plugin to run in order to tell us that
the Givens would be inconsistent in the additional equation
merge (_ <: _) Nil
and thus that the equation is not needed.
Fixes #26395
- - - - -
2c378ad2 by Cheng Shao at 2025-09-19T05:17:33-04:00
rel-eng: update fedora image to 42
This patch is a part of #25876 and updates fedora image to 42.
- - - - -
0a9d9ffc by Sylvain Henry at 2025-09-19T13:12:14-04:00
Fix output of T14999 (#23685)
Fix output of T14999 to:
- take into account the +1 offset to DW_AT_low_pc (see Note [Info Offset])
- always use Intel's syntax to force consistency: it was reported that
sometimes GDB prints `jmpq` instead of `jmp` with the AT&T syntax
- - - - -
1480872a by Vladislav Zavialov at 2025-09-19T13:12:54-04:00
Fix PREP_MAYBE_LIBRARY in prep_target_file.m4
This change fixes a configure error introduced in:
commit 8235dd8c4945db9cb03e3be3c388d729d576ed1e
ghc-toolchain: Move UseLibdw to per-Target file
Now the build no longer fails with:
acghc-toolchain: Failed to read a valid Target value from hadrian/cfg/default.target
- - - - -
d1d9e39e by Ben Gamari at 2025-09-19T18:24:52-04:00
StgToByteCode: Don't assume that data con workers are nullary
Previously StgToByteCode assumed that all data-con workers were of a
nullary representation. This is not a valid assumption, as seen
in #23210, where an unsaturated application of a unary data
constructor's worker resulted in invalid bytecode. Sadly, I have not yet
been able to reduce a minimal testcase for this.
Fixes #23210.
- - - - -
3eeecd50 by Ben Gamari at 2025-09-19T18:24:53-04:00
testsuite: Mark T23146* as unbroken
- - - - -
2e73f342 by sheaf at 2025-09-19T18:24:53-04:00
Add test for #26216
- - - - -
c2efb912 by Sven Tennie at 2025-09-19T18:25:36-04:00
Generate correct test header
This increases convenience when copying & pasting...
- - - - -
d2fb811e by Sven Tennie at 2025-09-19T18:25:36-04:00
foundation test: Fix shift amount (#26248)
Shift primops' results are only defined for shift amounts of 0 to word
size - 1. The approach is similar to testing div-like operations (which
have a constraint regarding zero operands.)
This was partly vibe coded (https://github.com/supersven/ghc/pull/1) but
then heavily refactored.
- - - - -
a62ce115 by Andreas Klebinger at 2025-09-19T18:26:18-04:00
Tweak jspace test
I've given it a longer timeout, and tweaked the test file generation
to speed it up a bit. Hopefully that is enough to make it constentily pass.
Last but not least it now also always uses three threads.
- - - - -
0f034942 by Cheng Shao at 2025-09-19T18:26:59-04:00
rts: remove obsolete CC_SUPPORTS_TLS logic
This patch removes obsolete CC_SUPPORTS_TLS logic throughout the rts,
given __thread is now uniformly supported by C toolchains of all
platforms we currently support.
- - - - -
ef705655 by Cheng Shao at 2025-09-19T18:27:41-04:00
rts: remove obsolete HAS_VISIBILITY_HIDDEN logic
This patch removes obsolete HAS_VISIBILITY_HIDDEN logic throughout the
rts, given __attribute__((visibility("hidden"))) is uniformly
supported by C toolchains of all platforms we currently support.
- - - - -
9fdc1f7d by Cheng Shao at 2025-09-19T18:28:21-04:00
rts: remove -O3 pragma hack in Hash.c
This patch removes an obsolete gcc pragma to specify -O3 in Hash.c.
Hadrian already passes the right flag.
- - - - -
b8cfa8f7 by Cheng Shao at 2025-09-19T18:29:01-04:00
rts: remove obsolete COMPILING_WINDOWS_DLL logic
This patch removes obsolete COMPILING_WINDOWS_DLL logic throughout the
rts. They were once used for compiling to win32 DLLs, but we haven't
been able to compile Haskell units to win32 DLLs for many years now,
due to PE format's restriction of no more than 65536 exported symbols
in a single DLL.
- - - - -
bb760611 by Cheng Shao at 2025-09-19T18:29:42-04:00
wasm: bump browser_wasi_shim to 0.4.2
This patch bumps the browser_wasi_shim dependency of wasm dyld script
to 0.4.2.
- - - - -
8b0940db by Cheng Shao at 2025-09-20T06:48:05-04:00
compiler: move Binary instance of Map to GHC.Utils.Binary
This patch moves `Binary` instance of `Map` from `haddock-api` to
`GHC.Utils.Binary`. This also allows us to remove a redundant instance
defined for `NameEntityInfo`, which is a type synonym for `Map`.
- - - - -
4a8fed75 by Vladislav Zavialov at 2025-09-20T06:48:47-04:00
Fix keyword in ExplicitNamespaces error message (#26418)
Consider this module header and the resulting error:
{-# LANGUAGE NoExplicitNamespaces #-}
module T26418 (data HeadC) where
-- error: [GHC-47007]
-- Illegal keyword 'type'
Previously, the error message would mention 'type' (as shown above),
even though the user wrote 'data'. This has now been fixed.
The error location has also been corrected: it is now reported at the
keyword position rather than at the position of the associated
import/export item.
- - - - -
867c2675 by Cheng Shao at 2025-09-20T06:49:28-04:00
wasm: fix dyld handling for forward declared GOT.func items
This patch fixes wasm shared linker's handling of forward declared
GOT.func items, see linked issue for details. Also adds T26430 test to
witness the fix. Fixes #26430.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
e7df6cc0 by Simon Peyton Jones at 2025-09-23T14:34:39-04:00
Improve pretty printer for HsExpr
Given a very deeply-nested application, it just kept printing
deeper and deeper. This small change makes it cut off.
Test is in #26330, but we also get a dramatic decrease in compile
time for perf/compiler/InstanceMatching:
InstanceMatching 4,086,884,584 1,181,767,232 -71.1% GOOD
Why? Because before we got a GIGANTIC error message that took
ages to pretty-print; now we get this much more civilised message
(I have removed some whitespace.)
Match.hs:1007:1: error:
• No instance for ‘Show (F001 a)’ arising from a use of ‘showsPrec’
• In the second argument of ‘showString’, namely
‘(showsPrec
11 b1
(GHC.Internal.Show.showSpace
(showsPrec
11 b2
(GHC.Internal.Show.showSpace
(showsPrec
11 b3
(GHC.Internal.Show.showSpace
(showsPrec
11 b4
(GHC.Internal.Show.showSpace
(showsPrec
11 b5
(GHC.Internal.Show.showSpace
(showsPrec
11 b6
(GHC.Internal.Show.showSpace (showsPrec ...)))))))))))))’
-----------------------
The main payload is
* At the start of `pprExpr`
* In the defn of `pprApp`
A little bit of refactoring:
* It turned out that we were setting the default cut-off depth to a
fixed value in two places, so changing one didn't change the other.
See defaultSDocDepth and defaultSDocCols
* I refactored `pprDeeperList` a bit so I could understand it better.
Because the depth calculation has changed, there are lots of small
error message wibbles.
Metric Decrease:
InstanceMatching
- - - - -
209f0158 by Simon Peyton Jones at 2025-09-23T14:34:39-04:00
Use Outputable.ellipsis rather than text "..."
- - - - -
64bb0e37 by Sylvain Henry at 2025-09-23T14:35:56-04:00
deriveConstants: automatically pass -fcommon CC flag (#26393)
By mistake we tried to use deriveConstants without passing
`--gcc-flag -fcommon` (which Hadrian does) and it failed.
This patch:
1. adds parsing support for constants stored in the .bss section (i.e.
when -fcommon isn't passed)
2. enables passing `-fcommon` automatically to the C compiler because
Windows requires this for subtle reasons
3. Documents the subtle reasons
(1) isn't strictly necessary because we always do (2) but it does no
harm and it is still useful if the CC flags ever contain -fno-common
- - - - -
afcdf92f by Oleg Grenrus at 2025-09-23T14:36:41-04:00
Don't wrap spaces in <span>s
Doing similar comparison as in 63189b2ceca07edf4e179f4180ca60d470c62cb3
With this change the gzipped documentation is now 2% smaller (previously 1%)
12_694_206 Agda-2.9.0-docs-orig.tar.gz
12_436_829 Agda-2.9.0-docs.tar.gz
Unzipped docs are 5% smaller (previously 3%)
178M Agda-2.9.0-docs-orig
169M Agda-2.9.0-docs
Individual hyperlinked sources are around 7-10% smaller (previously 5%)
(`Parser` module is generated by happy and has relatively little whitespace)
14_230_117 Agda.Syntax.Parser.Parser.html
13_220_758 Agda.Syntax.Parser.Parser.html
Agda's hyperlinked sources are 9% smaller now:
121M Agda-2.9.0-docs-orig/src
110M Agda-2.9.0-docs/src
- - - - -
67de53a6 by Cheng Shao at 2025-09-23T14:37:31-04:00
rts: remove obsolete __GNUC__ related logic
This patch removes obsolete `__GNUC__` related logic, given on any
currently supported platform and toolchain, `__GNUC__ >= 4` is
universally true. Also pulls some other weeds and most notably, use
`__builtin___clear_cache` for clang as well, since clang has supported
this gcc intrinsic since 2014, see
https://github.com/llvm/llvm-project/commit/c491a8d4577052bc6b3b4c72a7db6a7….
- - - - -
c4d32493 by Sven Tennie at 2025-09-23T20:40:57-04:00
RV64: Fix: Add missing truncation to MO_S_Shr (#26248)
Sub-double word (<W64) registers need to be truncated after the
operation.
- - - - -
41dce477 by Sven Tennie at 2025-09-23T20:40:57-04:00
RV64: Cleanup shift emitting cases/code
Remove overlapping cases to make the shift logic easier to understand.
- - - - -
0a601c30 by Alex Washburn at 2025-09-23T20:41:41-04:00
Correcting LLVM linking of Intel BMI intrinsics pdep{8,16} and pext{8,16}.
This patch fixes #26065.
The LLVM interface does not expose bindings to:
- llvm.x86.bmi.pdep.8
- llvm.x86.bmi.pdep.16
- llvm.x86.bmi.pext.8
- llvm.x86.bmi.pext.16
So calls are instead made to llvm.x86.bmi.{pdep,pext}.32 in these cases,
with pre/post-operation truncation to constrain the logical value range.
- - - - -
89e8ff3d by Peng Fan at 2025-09-23T20:42:37-04:00
NCG/LA64: Implement MO_BSwap and MO_BRev with bit-manipulation Instructions
- - - - -
50f6be09 by Sylvain Henry at 2025-09-23T20:43:29-04:00
Allow Core plugins to access unoptimized Core (#23337)
Make the first simple optimization pass after desugaring a real CoreToDo
pass. This allows CorePlugins to decide whether they want to be executed
before or after this pass.
- - - - -
30ef0aac by Simon Hengel at 2025-09-23T20:44:12-04:00
docs: Fix typo in scoped_type_variables.rst
- - - - -
f8919262 by Cheng Shao at 2025-09-23T20:44:54-04:00
ghci: fix bootstrapping with 9.12.3-rc1 and above
This patch fixes bootstrapping GHC with 9.12.3-rc1 and above. ghci
defines `Binary` instance for `HalfWord` in `ghc-heap`, which is a
proper `newtype` in 9.14 and starting from 9.12.3. Given we don't
build `ghc-heap` in stage0, we need to fix this predicate so that it
corresponds to the boot ghc versions that contain the right version of
`ghc-heap`.
- - - - -
a7f15858 by sheaf at 2025-09-24T09:49:53-04:00
User's guide: clarify optimisation of INLINABLE unfoldings
This updates the user's guide section on INLINABLE pragmas to explain how
the unfoldings of inlineable functions are optimised. The user's guide incorrectly
stated that the RHS was not optimised at all, but this is not true. Instead, GHC
is careful about phase control to optmise the RHS while retaining the guarantee
that GHC behaves as if the original RHS had been written.
- - - - -
495886d9 by Rodrigo Mesquita at 2025-09-24T09:50:35-04:00
cleanup: Delete historical artifact of COMPILING_WINDOWS_DLL
Namely, drop the obsolete
- DLL_IMPORT_RTS
- DLL_IMPORT_DATA_VAR
- DLL_IMPORT_DATA_VARNAME
- DLL_IMPORT_DATA_REF
These macros were not doing anything and placed inconsistently
Looking at the git logs reveal these macros were used to support
dynamic libraries on Win32, a feature that was dropped
in b8cfa8f741729ef123569fb321c4b2ab4a1a941c
This allows us to get rid of the rts/DLL.h file too.
- - - - -
5ae89054 by Sylvain Henry at 2025-09-24T17:07:00-04:00
Allow disabling builtin rules (#20298)
Add a way to disable built-in rules programmatically and with a debug flag.
I also took the opportunity to add a debug flag to disable bignum rules,
which was only possible programmatically (e.g. in a plugin).
- - - - -
135242ca by Rodrigo Mesquita at 2025-09-24T17:07:44-04:00
Don't use build CFLAGS and friends as target settings
In the GHC in tree configure, `CFLAGS`, `CXXFLAGS`, and similar tool
configuration flags apply to the BUILD phase of the compiler, i.e. to
the tools run to compile GHC itself.
Notably, they should /not/ be carried over to the Target settings, i.e.
these flags should /not/ apply to the tool which GHC invokes at runtime.
Fixes #25637
- - - - -
b418408b by Irene Knapp at 2025-09-25T09:47:54-04:00
Document etymology of "bind" as the name for `>>=`
It took me twenty years of contemplation to realize why it's called that.
I therefore feel that it may not be obvious to beginners.
- - - - -
e9c5e46f by Brandon Chinn at 2025-09-25T09:48:36-04:00
Fix tabs in string gaps (#26415)
Tabs in string gaps were broken in bb030d0d because previously, string gaps were manually parsed, but now it's lexed by the usual Alex grammar and post-processed after successful lexing.
It broke because of a discrepancy between GHC's lexer grammar and the Haskell Report. The Haskell Report includes tabs in whitechar:
whitechar → newline | vertab | space | tab | uniWhite
$whitechar used to include tabs until 18 years ago, when it was removed in order to exclude tabs from $white_no_nl in order to warn on tabs: 6e202120. In this MR, I'm adding \t back into $whitechar, and explicitly excluding \t from the $white_no_nl+ rule ignoring all whitespace in source code, which more accurately colocates the "ignore all whitespace except tabs, which is handled in the next line" logic.
As a side effect of this MR, tabs are now allowed in pragmas; currently, a pragma written as {-# \t LANGUAGE ... #-} is interpreted as the tab character being the pragma name, and GHC warns "Unrecognized pragma". With this change, tabs are ignored as whitespace, which more closely matches the Report anyway.
- - - - -
8bf5b309 by Cheng Shao at 2025-09-25T09:49:18-04:00
wasm: remove the --no-turbo-fast-api-calls hack from dynamic linker shebang
This patch removes the `--no-turbo-fast-api-calls` hack from the dyld
script shebang; it was used to workaround v8 fast call coredumps in
nodejs and no longer needed, and comes with a performance penalty,
hence the removal.
- - - - -
c1cab0c3 by Sylvain Henry at 2025-09-26T10:36:30-04:00
Revert "Add necessary flag for js linking"
This reverts commit 84f68e2231b2eddb2e1dc4e90af394ef0f2e803f.
This commit didn't have the expected effect. See discussion in #26290.
Instead we export HEAP8 and HEAPU8 from rts/js/mem.js
- - - - -
0a434a80 by Sylvain Henry at 2025-09-26T10:36:30-04:00
JS: export HEAPU8 (#26290)
This is now required by newer Emscripten versions.
- - - - -
b10296a9 by Andreas Klebinger at 2025-09-26T10:37:11-04:00
sizeExpr: Improve Tick handling.
When determining if we scrutinize a function argument we
now properly look through ticks. Fixes #26444.
- - - - -
d9e2a9a7 by mniip at 2025-09-26T16:00:50-04:00
rts: Refactor parsing of -h flags
We have a nontrivial amount of heap profiling flags available in the
non-profiled runtime, so it makes sense to reuse the parsing code
between the profiled and the non-profiled runtime, only restricting
which flags are allowed.
- - - - -
089e45aa by mniip at 2025-09-26T16:00:50-04:00
rts: Fix parsing of -h options with braces
When the "filter by" -h options were introduced in
bc210f7d267e8351ccb66972f4b3a650eb9338bb, the braces were mandatory.
Then in 3c22fb21fb18e27ce8d941069a6915fce584a526, the braces were made
optional. Then in d1ce35d2271ac8b79cb5e37677b1a989749e611c the brace
syntax stopped working, and no one seems to have noticed.
- - - - -
423f1472 by mniip at 2025-09-26T16:00:50-04:00
rts: add -hT<type> and -hi<table id> heap filtering options (#26361)
They are available in non-profiled builds.
Along the way fixed a bug where combining -he<era> and -hr<retainer>
would ignore whether the retainer matches or not.
- - - - -
4cda4785 by mniip at 2025-09-26T16:00:50-04:00
docs: Document -hT<type> and -hi<addr>
- - - - -
982ad30f by mniip at 2025-09-26T16:00:50-04:00
rts: Refactor dumping the heap census
Always do the printing of the total size right next to where the bucket
label is printed. This prevents accidentally printing a label without
the corresponding amount.
Fixed a bug where exactly this happened for -hi profile and the 0x0
(uncategorized) info table.
There is now also much more symmetry between fprintf(hp_file,...) and
the corresponding traceHeapProfSampleString.
- - - - -
8cbe006a by Cheng Shao at 2025-09-26T16:01:34-04:00
hadrian: fix GHC.Platform.Host generation for cross stage1
This patch fixes incorrectly GHC.Platform.Host generation logic for
cross stage1 in hadrian (#26449). Also adds T26449 test case to
witness the fix.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
0ddd0fdc by soulomoon at 2025-09-28T19:24:10-04:00
Remove hptAllInstances usage during upsweep
Previously, during the upsweep phase when
checking safe imports, we were loading the module
interface with runTcInteractive, which in turn calls
hptAllInstances. This accesses non-below modules
from the home package table.
Change the implementation of checkSafeImports
to use initTcWithGbl and loadSysInterface to load the
module interface, since we already have TcGblEnv at hand.
This eliminates the unnecessary use of runTcInteractive
and hptAllInstances during the upsweep phase.
- - - - -
e05c496c by Ben Gamari at 2025-09-28T19:24:59-04:00
base: Update changelog to reflect timing of IOPort# removal
This change will make 9.14 afterall.
- - - - -
bdc9d130 by Cheng Shao at 2025-09-28T19:25:45-04:00
rts: fix wasm JSFFI initialization constructor code
This commit fixes wasm JSFFI initialization constructor code so that
the constructor is self-contained and avoids invoking a fake
__main_argc_argv function. The previous approach of reusing
__main_void logic in wasi-libc saves a tiny bit of code, at the
expense of link-time trouble whenever GHC links a wasm module without
-no-hs-main, in which case the driver-generated main function would
clash with the definition here, resulting in a linker error. It's
simply better to avoid messing with the main function, and it would
additionally allow linking wasm32-wasi command modules that does make
use of synchronous JSFFI.
- - - - -
5d59fc8f by Cheng Shao at 2025-09-28T19:26:27-04:00
rts: provide stub implementations of ExecPage functions for wasm
This patch provides stub implementations of ExecPage functions for
wasm. They are never actually invoked at runtime for any non-TNTC
platform, yet they can cause link-time errors of missing symbols when
the GHCi.InfoTable module gets linked into the final wasm module (e.g.
a GHC API program).
- - - - -
a4d664c7 by Cheng Shao at 2025-09-29T17:29:22+02:00
compiler/ghci: replace the LoadDLL message with LoadDLLs
As a part of #25407, this commit changes the LoadDLL message to
LoadDLLs, which takes a list of DLL paths to load and returns the list
of remote pointer handles. The wasm dyld is refactored to take
advantage of LoadDLLs and harvest background parallelism. On other
platforms, LoadDLLs is based on a fallback codepath that does
sequential loading.
The driver is not actually emitting singular LoadDLLs message with
multiple DLLs yet, this is left in subsequent commits.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
c7fc4bae by Cheng Shao at 2025-09-29T17:29:22+02:00
driver: separate downsweep/upsweep phase in loadPackages'
This commit refactors GHC.Linker.Loader.loadPackages' to be separated
into downsweep/upsweep phases:
- The downsweep phase performs dependency analysis and generates a
list of topologically sorted packages to load
- The upsweep phase sequentially loads these packages by calling
loadPackage
This is a necessary refactoring to make it possible to make loading of
DLLs concurrent.
- - - - -
ab180104 by Cheng Shao at 2025-09-29T17:57:19+02:00
driver: emit single LoadDLLs message to load multiple DLLs
This commit refactors the driver so that it emits a single LoadDLLs
message to load multiple DLLs in GHC.Linker.Loader.loadPackages'.
Closes #25407.
-------------------------
Metric Increase:
MultiLayerModulesTH_OneShot
TcPlugin_RewritePerf
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
9c304ec0 by Sean D. Gillespie at 2025-09-29T19:57:07-04:00
Fix SIZED_BIN_OP_TY_INT casts in RTS interpreter
Correct `SIZED_BIN_OP_TY_INT` cast to integer. Previously, it cast
its second operand as its parameter `ty`. This does not currently
cause any issues, since we are only using it for bit shifts.
Fixes #26287
- - - - -
a1de535f by Luite Stegeman at 2025-09-30T18:40:28-04:00
rts: Fix lost wakeups in threadPaused for threads blocked on black holes
The lazy blackholing code in threadPaused could overwrite closures
that were already eagerly blackholed, and as such wouldn't have a
marked update frame. If the black hole was overwritten by its
original owner, this would lead to an undetected collision, and
the contents of any existing blocking queue being lost.
This adds a check for eagerly blackholed closures and avoids
overwriting their contents.
Fixes #26324
- - - - -
b7e21e49 by Luite Stegeman at 2025-09-30T18:40:28-04:00
rts: push the correct update frame in stg_AP_STACK
The frame contains an eager black hole (__stg_EAGER_BLACKHOLE_info) so
we should push an stg_bh_upd_frame_info instead of an stg_upd_frame_info.
- - - - -
02a7c18a by Cheng Shao at 2025-09-30T18:41:27-04:00
ghci: fix lookupSymbolInDLL behavior on wasm
This patch fixes lookupSymbolInDLL behavior on wasm to return Nothing
instead of throwing. On wasm, we only have lookupSymbol, and the
driver would attempt to call lookupSymbolInDLL first before falling
back to lookupSymbol, so lookupSymbolInDLL needs to return Nothing
gracefully for the fallback behavior to work.
- - - - -
aa0ca5e3 by Cheng Shao at 2025-09-30T18:41:27-04:00
hadrian/compiler: enable internal-interpreter for ghc library in wasm stage1
This commit enables the internal-interpreter flag for ghc library in
wasm stage1, as well as other minor adjustments to make it actually
possible to launch a ghc api session that makes use of the internal
interpreter. Closes #26431 #25400.
- - - - -
69503668 by Cheng Shao at 2025-09-30T18:41:27-04:00
testsuite: add T26431 test case
This commit adds T26431 to testsuite/tests/ghci-wasm which goes
through the complete bytecode compilation/linking/running pipeline in
wasm, so to witness that the ghc shared library in wasm have full
support for internal-interpreter.
- - - - -
e9445c01 by Matthew Pickering at 2025-09-30T18:42:23-04:00
driver: Load bytecode static pointer entries during linking
Previously the entries were loaded too eagerly, during upsweep, but we
should delay loading them until we know that the relevant bytecode
object is demanded.
Towards #25230
- - - - -
b8307eab by Cheng Shao at 2025-09-30T18:43:14-04:00
autoconf/ghc-toolchain: remove obsolete C99 check
This patch removes obsolete c99 check from autoconf/ghc-toolchain. For
all toolchain & platform combination we support, gnu11 or above is
already supported without any -std flag required, and our RTS already
required C11 quite a few years ago, so the C99 check is completely
pointless.
- - - - -
9c293544 by Simon Peyton Jones at 2025-10-01T09:36:10+01:00
Fix buglet in GHC.Core.Unify.uVarOrFam
We were failing to match two totally-equal types!
This led to #26457.
- - - - -
554487a7 by Rodrigo Mesquita at 2025-10-01T23:04:43-04:00
cleanup: Drop obsolete comment about HsConDetails
HsConDetails used to have an argument representing the type of the
tyargs in a list:
data HsConDetails tyarg arg rec
= PrefixCon [tyarg] [arg]
This datatype was shared across 3 synonyms: HsConPatDetails,
HsConDeclH98Details, HsPatSynDetails. In the latter two cases, `tyarg`
was instanced to `Void` meaning the list was always empty for these
cases.
In 7b84c58867edca57a45945a20a9391724db6d9e4, this was refactored such
that HsConDetails no longer needs a type of tyargs by construction. The
first case now represents the type arguments in the args type itself,
with something like:
ConPat "MkE" [InvisP tp1, InvisP tp2, p1, p2]
So the deleted comment really is just obsolete.
Fixes #26461
- - - - -
6992ac09 by Cheng Shao at 2025-10-02T07:27:55-04:00
testsuite: remove unused expected output files
This patch removes unused expected output files in the testsuites on
platforms that we no longer support.
- - - - -
39eaaaba by Ben Gamari at 2025-10-02T07:28:45-04:00
rts: Dynamically initialize built-in closures
To resolve #26166 we need to eliminate references to undefined symbols
in the runtime system. One such source of these is the runtime's
static references to `I#` and `C#` due the `stg_INTLIKE` and
`stg_CHARLIKE` arrays.
To avoid this we make these dynamic, initializing them during RTS
start-up.
- - - - -
c254c54b by Cheng Shao at 2025-10-02T07:29:33-04:00
compiler: only invoke keepCAFsForGHCi if internal-interpreter is enabled
This patch makes the ghc library only invoke keepCAFsForGHCi if
internal-interpreter is enabled. For cases when it's not (e.g. the
host build of a cross ghc), this avoids unnecessarily retaining all
CAFs in the heap. Also fixes the type signature of c_keepCAFsForGHCi
to match the C ABI.
- - - - -
c9ec4d43 by Simon Hengel at 2025-10-02T18:42:20-04:00
Update copyright in documentation
- - - - -
da9633a9 by Matthew Pickering at 2025-10-02T18:43:04-04:00
loader: Unify loadDecls and loadModuleLinkables functions
These two functions nearly did the same thing. I have refactored them so
that `loadDecls` now calls `loadModuleLinkables`.
Fixes #26459
- - - - -
5db98d80 by Simon Hengel at 2025-10-02T18:43:53-04:00
Fix typo
- - - - -
1275d360 by Matthew Pickering at 2025-10-03T06:05:56-04:00
testsuite: Use ghci_ways to set ways in PackedDataCon/UnboxedTuples/UnliftedDataTypeInterp tests
These tests reimplemented the logic from `valid_way` in order to
determine what ways to run. It's easier to use this combination of
`only_ways` and `extra_ways` to only run in GHCi ways and always run in
GHCi ways.
- - - - -
c06b534b by Matthew Pickering at 2025-10-03T06:06:40-04:00
Rename interpreterBackend to bytecodeBackend
This is preparation for creating bytecode files.
The "interpreter" is one way in which we can run bytecode objects. It is
more accurate to describe that the backend produces bytecode, rather
than the means by which the code will eventually run.
The "interpreterBackend" binding is left as a deprecated alias.
- - - - -
41bdb16f by Andreas Klebinger at 2025-10-06T18:04:34-04:00
Add a perf test for #26425
- - - - -
1da0c700 by Andreas Klebinger at 2025-10-06T18:05:14-04:00
Testsuite: Silence warnings about Wx-partial in concprog001
- - - - -
9ddcc2cc by Ben Gamari at 2025-10-07T09:41:17-04:00
rts/nonmoving: Fix comment spelling
- - - - -
cd90f943 by Ben Gamari at 2025-10-07T09:41:17-04:00
rts/nonmoving: Use atomic operations to update bd->flags
- - - - -
bf9a4a56 by Ben Gamari at 2025-10-07T09:41:18-04:00
nonmoving: Use get_itbl instead of explicit loads
This is cleaner and also fixes unnecessary (and unsound) use of
`volatile`.
- - - - -
4bccbe6d by Ben Gamari at 2025-10-07T09:41:18-04:00
rts/Scav: Handle WHITEHOLEs in scavenge_one
`scavenge_one`, used to scavenge mutable list entries, may encounter
`WHITEHOLE`s when the non-moving GC is in use via two paths:
1. when an MVAR is being marked concurrently
2. when the object belongs to a chain of selectors being short-cutted.
Fixes #26204.
- - - - -
813 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- .mailmap
- compiler/GHC.hs
- compiler/GHC/Builtin/Names/TH.hs
- compiler/GHC/Builtin/Uniques.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Cmm/Utils.hs
- compiler/GHC/CmmToAsm/CFG.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/LA64/Instr.hs
- compiler/GHC/CmmToAsm/LA64/Ppr.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion.hs-boot
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/Pipeline/Types.hs
- compiler/GHC/Core/Opt/Simplify.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Inline.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Reduction.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Rules/Config.hs
- compiler/GHC/Core/TyCo/Compare.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/TyCo/Tidy.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unfold.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Data/IOEnv.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backend/Internal.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Config/Core/Opt/Simplify.hs
- compiler/GHC/Driver/Config/Core/Rules.hs
- compiler/GHC/Driver/Config/Finder.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Env/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc/Ppr.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Pmc/Types.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Errors/Ppr.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Ext/Binary.hs
- compiler/GHC/Iface/Ext/Types.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Types.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/MacOS.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Llvm/Ppr.hs
- compiler/GHC/Llvm/Types.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/Lexer/String.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/Types.hs
- compiler/GHC/Plugins.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/Settings.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/Stg/Unarise.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/DataCon.hs
- compiler/GHC/StgToCmm/Layout.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/StgToJS/StaticPtr.hs
- compiler/GHC/SysTools/BaseDir.hs
- compiler/GHC/Tc/Deriv/Generics.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/Bind.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Gen/Splice.hs-boot
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Types/TH.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/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/SptEntry.hs
- compiler/GHC/Types/Unique.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Home/Graph.hs
- compiler/GHC/Unit/Home/PackageTable.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/Ppr.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/cbits/keepCAFsForGHCi.c
- compiler/ghc.cabal.in
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/conf.py
- docs/users_guide/debugging.rst
- docs/users_guide/extending_ghc.rst
- docs/users_guide/exts/pragmas.rst
- docs/users_guide/exts/scoped_type_variables.rst
- docs/users_guide/flags.py
- docs/users_guide/ghci.rst
- docs/users_guide/profiling.rst
- docs/users_guide/runtime_control.rst
- docs/users_guide/separate_compilation.rst
- ghc/GHCi/UI.hs
- ghc/Main.hs
- hadrian/bindist/Makefile
- hadrian/bindist/config.mk.in
- hadrian/bootstrap/generate_bootstrap_plans
- hadrian/bootstrap/hadrian-bootstrap-gen.cabal
- hadrian/bootstrap/plan-9_10_1.json
- hadrian/bootstrap/plan-9_6_5.json → hadrian/bootstrap/plan-9_10_2.json
- hadrian/bootstrap/plan-9_6_6.json → hadrian/bootstrap/plan-9_12_1.json
- hadrian/bootstrap/plan-9_6_4.json → hadrian/bootstrap/plan-9_12_2.json
- − hadrian/bootstrap/plan-9_6_1.json
- − hadrian/bootstrap/plan-9_6_2.json
- − hadrian/bootstrap/plan-9_6_3.json
- − hadrian/bootstrap/plan-9_8_1.json
- − hadrian/bootstrap/plan-9_8_2.json
- hadrian/bootstrap/plan-bootstrap-9_10_1.json
- hadrian/bootstrap/plan-bootstrap-9_6_5.json → hadrian/bootstrap/plan-bootstrap-9_10_2.json
- hadrian/bootstrap/plan-bootstrap-9_6_6.json → hadrian/bootstrap/plan-bootstrap-9_12_1.json
- hadrian/bootstrap/plan-bootstrap-9_8_1.json → hadrian/bootstrap/plan-bootstrap-9_12_2.json
- − hadrian/bootstrap/plan-bootstrap-9_6_1.json
- − hadrian/bootstrap/plan-bootstrap-9_6_2.json
- − hadrian/bootstrap/plan-bootstrap-9_6_3.json
- − hadrian/bootstrap/plan-bootstrap-9_6_4.json
- − hadrian/bootstrap/plan-bootstrap-9_8_2.json
- hadrian/bootstrap/src/Main.hs
- hadrian/cfg/default.host.target.in
- hadrian/cfg/default.target.in
- hadrian/cfg/system.config.in
- hadrian/hadrian.cabal
- hadrian/src/Base.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Oracles/TestSettings.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/ToolArgs.hs
- hadrian/src/Settings/Builders/DeriveConstants.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- libffi-tarballs
- libraries/base/changelog.md
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Monad.hs
- libraries/base/src/Data/Array/Byte.hs
- libraries/base/src/Data/Bifunctor.hs
- libraries/base/src/Data/Fixed.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/RTS/Flags.hs
- libraries/base/src/GHC/Stack/CloneStack.hs
- libraries/base/tests/unicode002.stdout
- libraries/base/tests/unicode003.stdout
- + libraries/ghc-boot-th/GHC/Boot/TH/Monad.hs
- libraries/ghc-boot-th/GHC/Boot/TH/Ppr.hs
- libraries/ghc-boot-th/ghc-boot-th.cabal.in
- libraries/ghc-boot/GHC/Settings/Utils.hs
- libraries/ghc-boot/ghc-boot.cabal.in
- libraries/ghc-experimental/ghc-experimental.cabal.in
- + libraries/ghc-experimental/src/GHC/Stack/Annotation/Experimental.hs
- libraries/ghc-heap/GHC/Exts/Heap.hs
- libraries/ghc-heap/GHC/Exts/Heap/ClosureTypes.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- + libraries/ghc-heap/GHC/Exts/Heap/Constants.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hs
- libraries/ghc-heap/GHC/Exts/Heap/ProfInfo/Types.hs
- libraries/ghc-heap/GHC/Exts/Stack.hs
- + libraries/ghc-heap/GHC/Exts/Stack/Constants.hs
- libraries/ghc-heap/GHC/Exts/Stack/Decode.hs
- libraries/ghc-heap/ghc-heap.cabal.in
- libraries/ghc-heap/cbits/HeapPrim.cmm → libraries/ghc-internal/cbits/HeapPrim.cmm
- libraries/ghc-heap/cbits/Stack.cmm → libraries/ghc-internal/cbits/Stack.cmm
- libraries/ghc-internal/cbits/StackCloningDecoding.cmm
- libraries/ghc-heap/cbits/Stack_c.c → libraries/ghc-internal/cbits/Stack_c.c
- libraries/ghc-internal/cbits/atomic.c
- libraries/ghc-internal/cbits/ctz.c
- libraries/ghc-internal/codepages/MakeTable.hs
- libraries/ghc-internal/codepages/Makefile
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/jsbits/base.js
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/ClosureTypes.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- + libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-heap/GHC/Exts/Heap/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/Constants.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable/Types.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTableProf.hsc
- + libraries/ghc-internal/src/GHC/Internal/Heap/ProfInfo/Types.hs
- libraries/ghc-internal/src/GHC/Internal/List.hs
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
- libraries/ghc-internal/src/GHC/Internal/ResponseFile.hs
- + libraries/ghc-internal/src/GHC/Internal/Stack/Annotation.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/CloneStack.hs
- libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Stack/Constants.hsc
- + libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- + libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/DerivedCoreProperties.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/GeneralCategory.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleLowerCaseMapping.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleTitleCaseMapping.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleUpperCaseMapping.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Version.hs
- + libraries/ghc-internal/tests/stack-annotation/Makefile
- + libraries/ghc-internal/tests/stack-annotation/TestUtils.hs
- + libraries/ghc-internal/tests/stack-annotation/all.T
- + libraries/ghc-internal/tests/stack-annotation/ann_frame001.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame001.stdout
- + libraries/ghc-internal/tests/stack-annotation/ann_frame002.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame002.stdout
- + libraries/ghc-internal/tests/stack-annotation/ann_frame003.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame003.stdout
- + libraries/ghc-internal/tests/stack-annotation/ann_frame004.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame004.stdout
- libraries/ghc-internal/tools/ucd2haskell/ucd.sh
- libraries/ghc-internal/tools/ucd2haskell/ucd2haskell.cabal
- libraries/ghc-internal/tools/ucd2haskell/unicode_version
- libraries/ghci/GHCi/CreateBCO.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/ObjLink.hs
- libraries/ghci/GHCi/Run.hs
- libraries/ghci/GHCi/TH.hs
- libraries/ghci/ghci.cabal.in
- libraries/template-haskell/Language/Haskell/TH/Lib.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- libraries/template-haskell/changelog.md
- linters/lint-codes/LintCodes/Coverage.hs
- m4/find_python.m4
- m4/fp_cmm_cpp_cmd_with_args.m4
- m4/fp_find_libdw.m4
- − m4/fp_set_cflags_c99.m4
- − m4/fp_settings.m4
- m4/fp_setup_windows_toolchain.m4
- − m4/fp_visibility_hidden.m4
- m4/fptools_set_c_ld_flags.m4
- m4/ghc_toolchain.m4
- m4/prep_target_file.m4
- + m4/subst_tooldir.m4
- mk/hsc2hs.in
- rts/Apply.cmm
- rts/BeginPrivate.h
- + rts/BuiltinClosures.c
- + rts/BuiltinClosures.h
- rts/CloneStack.c
- rts/CloneStack.h
- rts/ClosureFlags.c
- + rts/ClosureTable.c
- + rts/ClosureTable.h
- rts/Disassembler.c
- rts/EndPrivate.h
- rts/ExecPage.c
- rts/Hash.c
- rts/IOManager.c
- rts/IOManager.h
- rts/IOManagerInternals.h
- rts/IPE.c
- rts/Interpreter.c
- rts/LdvProfile.c
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/Printer.c
- rts/ProfHeap.c
- rts/Profiling.c
- rts/RaiseAsync.c
- rts/RetainerProfile.c
- rts/RetainerSet.c
- − rts/RtsDllMain.c
- − rts/RtsDllMain.h
- rts/RtsFlags.c
- rts/RtsMessages.c
- rts/RtsSignals.h
- rts/RtsStartup.c
- rts/RtsSymbols.c
- rts/RtsUtils.c
- rts/STM.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/Task.c
- rts/Task.h
- rts/ThreadPaused.c
- rts/Threads.c
- + rts/TimeoutQueue.c
- + rts/TimeoutQueue.h
- rts/Trace.c
- rts/TraverseHeap.c
- rts/configure.ac
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/Stg.h
- rts/include/rts/Bytecodes.h
- rts/include/rts/Constants.h
- rts/include/rts/Flags.h
- rts/include/rts/NonMoving.h
- rts/include/rts/OSThreads.h
- rts/include/rts/StableName.h
- rts/include/rts/StablePtr.h
- rts/include/rts/Types.h
- rts/include/rts/storage/Block.h
- rts/include/rts/storage/ClosureTypes.h
- rts/include/rts/storage/Closures.h
- rts/include/rts/storage/TSO.h
- − rts/include/stg/DLL.h
- rts/include/stg/MiscClosures.h
- rts/js/mem.js
- rts/js/profiling.js
- rts/linker/MachO.c
- rts/posix/OSThreads.c
- + rts/posix/Poll.c
- + rts/posix/Poll.h
- + rts/posix/Timeout.c
- + rts/posix/Timeout.h
- rts/rts.cabal
- rts/sm/BlockAlloc.c
- rts/sm/Compact.c
- rts/sm/Evac.c
- rts/sm/Evac.h
- rts/sm/GCTDecl.h
- rts/sm/GCThread.h
- rts/sm/NonMoving.c
- rts/sm/NonMovingMark.c
- rts/sm/Sanity.c
- rts/sm/Scav.c
- rts/sm/Storage.c
- rts/wasm/JSFFI.c
- rts/win32/OSThreads.c
- testsuite/.gitignore
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/ghc-config/ghc-config.hs
- testsuite/mk/test.mk
- testsuite/tests/arrows/gadt/T17423.stderr
- testsuite/tests/backpack/should_fail/bkpfail11.stderr
- testsuite/tests/backpack/should_fail/bkpfail43.stderr
- + testsuite/tests/bytecode/T26216.hs
- + testsuite/tests/bytecode/T26216.script
- + testsuite/tests/bytecode/T26216.stdout
- + testsuite/tests/bytecode/T26216_aux.hs
- testsuite/tests/bytecode/all.T
- testsuite/tests/codeGen/should_compile/Makefile
- testsuite/tests/codeGen/should_compile/T14999.stdout
- + testsuite/tests/codeGen/should_compile/T20298a.hs
- + testsuite/tests/codeGen/should_compile/T20298a.stderr
- + testsuite/tests/codeGen/should_compile/T20298b.hs
- + testsuite/tests/codeGen/should_compile/T20298b.stderr
- + testsuite/tests/codeGen/should_compile/T20298c.hs
- + testsuite/tests/codeGen/should_compile/T20298c.stderr
- testsuite/tests/codeGen/should_compile/T25166.stdout → testsuite/tests/codeGen/should_compile/T25166.stdout-ws-32
- + testsuite/tests/codeGen/should_compile/T25166.stdout-ws-64
- testsuite/tests/codeGen/should_compile/all.T
- testsuite/tests/codeGen/should_run/T13825-unit.hs
- testsuite/tests/codeGen/should_run/T23146/all.T
- testsuite/tests/concurrent/prog001/all.T
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/cross/should_run/T26449.hs
- + testsuite/tests/cross/should_run/all.T
- testsuite/tests/deriving/should_compile/T14682.stderr
- + testsuite/tests/deriving/should_compile/T26396.hs
- testsuite/tests/deriving/should_compile/all.T
- testsuite/tests/deriving/should_compile/drv-empty-data.stderr
- testsuite/tests/deriving/should_fail/T12768.stderr
- testsuite/tests/deriving/should_fail/T1496.stderr
- testsuite/tests/deriving/should_fail/T21302.stderr
- testsuite/tests/deriving/should_fail/T22696b.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/T5313.hs
- testsuite/tests/driver/all.T
- testsuite/tests/driver/j-space/Makefile
- testsuite/tests/driver/j-space/all.T
- testsuite/tests/driver/j-space/genJspace
- + testsuite/tests/driver/make-prim/GHC/Internal/Prim.hs
- + testsuite/tests/driver/make-prim/Makefile
- + testsuite/tests/driver/make-prim/Test.hs
- + testsuite/tests/driver/make-prim/Test2.hs
- + testsuite/tests/driver/make-prim/all.T
- testsuite/tests/driver/multipleHomeUnits/all.T
- testsuite/tests/ffi/should_run/T1288_c.c
- testsuite/tests/ffi/should_run/T1288_ghci_c.c
- testsuite/tests/ffi/should_run/T2276_c.c
- testsuite/tests/ffi/should_run/T2276_ghci_c.c
- testsuite/tests/gadt/T12468.stderr
- testsuite/tests/ghc-api/T10052/T10052.hs
- testsuite/tests/ghc-api/T20757.hs
- testsuite/tests/ghc-api/T8639_api.hs
- testsuite/tests/ghc-api/apirecomp001/myghc.hs
- testsuite/tests/ghc-api/settings-escape/T24265.hs
- testsuite/tests/ghc-api/settings-escape/T24265.stderr
- + testsuite/tests/ghc-api/settings-escape/ghc-install-folder/lib with spaces/targets/.gitkeep
- testsuite/tests/ghc-e/should_fail/T24172.stderr
- + testsuite/tests/ghci-wasm/Makefile
- + testsuite/tests/ghci-wasm/T26430.hs
- + testsuite/tests/ghci-wasm/T26430A.c
- + testsuite/tests/ghci-wasm/T26430B.c
- + testsuite/tests/ghci-wasm/T26431.hs
- + testsuite/tests/ghci-wasm/T26431.stdout
- + testsuite/tests/ghci-wasm/all.T
- testsuite/tests/ghci.debugger/scripts/T26042b.script
- testsuite/tests/ghci.debugger/scripts/T26042b.stdout
- testsuite/tests/ghci.debugger/scripts/T26042c.script
- testsuite/tests/ghci.debugger/scripts/T26042c.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042d2.hs
- + testsuite/tests/ghci.debugger/scripts/T26042d2.script
- + testsuite/tests/ghci.debugger/scripts/T26042d2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042e.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f.script
- testsuite/tests/ghci.debugger/scripts/T26042f1.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042g.stdout
- testsuite/tests/ghci.debugger/scripts/all.T
- testsuite/tests/ghci.debugger/scripts/break022/all.T
- testsuite/tests/ghci.debugger/scripts/break022/break022.script
- testsuite/tests/ghci.debugger/scripts/break023/all.T
- testsuite/tests/ghci.debugger/scripts/break023/break023.script
- testsuite/tests/ghci/linking/dyn/T3372.hs
- testsuite/tests/ghci/prog001/prog001.T
- testsuite/tests/ghci/prog001/prog001.script
- testsuite/tests/ghci/prog002/prog002.T
- testsuite/tests/ghci/prog002/prog002.script
- testsuite/tests/ghci/prog003/prog003.T
- testsuite/tests/ghci/prog003/prog003.script
- testsuite/tests/ghci/prog005/prog005.T
- testsuite/tests/ghci/prog005/prog005.script
- testsuite/tests/ghci/prog010/all.T
- testsuite/tests/ghci/prog010/ghci.prog010.script
- testsuite/tests/ghci/prog012/all.T
- testsuite/tests/ghci/prog012/prog012.script
- testsuite/tests/ghci/recompTHghci/all.T
- testsuite/tests/ghci/recompTHghci/recompTHghci.script
- testsuite/tests/ghci/scripts/T18330.script
- testsuite/tests/ghci/scripts/T18330.stdout
- testsuite/tests/ghci/scripts/T1914.script
- testsuite/tests/ghci/scripts/T20587.script
- testsuite/tests/ghci/scripts/T6106.script
- testsuite/tests/ghci/scripts/T7388.hs
- testsuite/tests/ghci/scripts/T7388.script
- testsuite/tests/ghci/scripts/T8353.script
- testsuite/tests/ghci/scripts/T8353.stderr
- testsuite/tests/ghci/scripts/all.T
- testsuite/tests/ghci/scripts/ghci038.script
- testsuite/tests/ghci/scripts/ghci038.stdout
- testsuite/tests/ghci/scripts/ghci058.script
- testsuite/tests/ghci/scripts/ghci063.script
- − testsuite/tests/ghci/shell.hs
- testsuite/tests/ghci/should_run/PackedDataCon/packeddatacon.T
- testsuite/tests/ghci/should_run/UnboxedTuples/unboxedtuples.T
- testsuite/tests/ghci/should_run/UnliftedDataTypeInterp/unlifteddatatypeinterp.T
- testsuite/tests/impredicative/T17332.stderr
- testsuite/tests/indexed-types/should_compile/PushedInAsGivens.stderr
- testsuite/tests/indexed-types/should_fail/T26176.stderr
- testsuite/tests/indexed-types/should_fail/T2693.stderr
- testsuite/tests/indexed-types/should_fail/T4093b.stderr
- testsuite/tests/indexed-types/should_fail/T8518.stderr
- testsuite/tests/indexed-types/should_fail/T9662.stderr
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/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/linear/should_compile/T26332.hs
- testsuite/tests/linear/should_compile/all.T
- testsuite/tests/linear/should_fail/Linear17.stderr
- testsuite/tests/linear/should_fail/LinearLet7.stderr
- + testsuite/tests/llvm/should_run/T26065.hs
- + testsuite/tests/llvm/should_run/T26065.stdout
- testsuite/tests/llvm/should_run/all.T
- − testsuite/tests/module/T21752.stderr
- testsuite/tests/module/mod150.stderr
- testsuite/tests/module/mod151.stderr
- testsuite/tests/module/mod152.stderr
- testsuite/tests/module/mod153.stderr
- testsuite/tests/numeric/should_run/foundation.hs
- testsuite/tests/overloadedrecflds/should_fail/T18999_NoDisambiguateRecordFields.stderr
- + testsuite/tests/overloadedrecflds/should_fail/T26391.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26391.stderr
- testsuite/tests/overloadedrecflds/should_fail/all.T
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T19082.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail10.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail11.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail13.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- testsuite/tests/parser/should_fail/T16270h.stderr
- + testsuite/tests/parser/should_fail/T26418.hs
- + testsuite/tests/parser/should_fail/T26418.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/parser/should_run/T26415.hs
- + testsuite/tests/parser/should_run/T26415.stdout
- testsuite/tests/parser/should_run/all.T
- testsuite/tests/partial-sigs/should_compile/T21719.stderr
- + testsuite/tests/patsyn/should_compile/T26331.hs
- + testsuite/tests/patsyn/should_compile/T26331a.hs
- testsuite/tests/patsyn/should_compile/all.T
- testsuite/tests/perf/compiler/MultiLayerModulesDefsGhci.script
- + testsuite/tests/perf/compiler/T26425.hs
- testsuite/tests/perf/compiler/T4007.stdout
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/perf/compiler/hard_hole_fits.stderr
- testsuite/tests/plugins/Makefile
- + testsuite/tests/plugins/T21730-plugin/Makefile
- + testsuite/tests/plugins/T21730-plugin/Setup.hs
- + testsuite/tests/plugins/T21730-plugin/T21730-plugin.cabal
- + testsuite/tests/plugins/T21730-plugin/T21730_Plugin.hs
- + testsuite/tests/plugins/T21730.hs
- testsuite/tests/plugins/all.T
- testsuite/tests/plugins/annotation-plugin/SayAnnNames.hs
- testsuite/tests/plugins/late-plugin/LatePlugin.hs
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/plugins/simple-plugin/Simple/ReplacePlugin.hs
- testsuite/tests/polykinds/T13393.stderr
- − testsuite/tests/process/process010.stdout-i386-unknown-solaris2
- + testsuite/tests/profiling/should_compile/T26056.hs
- testsuite/tests/profiling/should_compile/all.T
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/quantified-constraints/T19690.stderr
- testsuite/tests/quantified-constraints/T19921.stderr
- testsuite/tests/quantified-constraints/T21006.stderr
- testsuite/tests/quotes/LiftErrMsg.stderr
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/quotes/LiftErrMsgTyped.stderr
- testsuite/tests/rename/should_compile/T22513d.stderr
- testsuite/tests/rename/should_compile/T22513e.stderr
- testsuite/tests/rename/should_compile/T22513f.stderr
- testsuite/tests/rename/should_compile/T22513g.stderr
- testsuite/tests/rename/should_compile/T22513h.stderr
- testsuite/tests/rename/should_compile/T22513i.stderr
- testsuite/tests/rename/should_compile/rn039.ghc.stderr
- testsuite/tests/rename/should_fail/T15487.stderr
- testsuite/tests/rename/should_fail/T18740a.stderr
- testsuite/tests/rename/should_fail/rnfail044.stderr
- testsuite/tests/rep-poly/T12709.stderr
- testsuite/tests/roles/should_fail/RolesIArray.stderr
- + testsuite/tests/rts/ClosureTable.hs
- + testsuite/tests/rts/ClosureTable_c.c
- + testsuite/tests/rts/TimeoutQueue.c
- + testsuite/tests/rts/TimeoutQueue.stdout
- testsuite/tests/rts/all.T
- testsuite/tests/rts/exec_signals_child.c
- testsuite/tests/rts/flags/all.T
- − testsuite/tests/rts/linker/T11223/T11223_link_order_a_b_2_fail.stderr-ws-32-mingw32
- − testsuite/tests/rts/linker/T11223/T11223_simple_duplicate_lib.stderr-ws-32-mingw32
- testsuite/tests/rts/linker/T11223/all.T
- testsuite/tests/rts/linker/T2615.hs
- − testsuite/tests/rts/outofmem.stderr-i386-apple-darwin
- − testsuite/tests/rts/outofmem.stderr-i386-unknown-mingw32
- − testsuite/tests/rts/outofmem.stderr-powerpc-apple-darwin
- testsuite/tests/safeHaskell/flags/SafeFlags17.stderr
- testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs
- testsuite/tests/simplCore/should_compile/DsSpecPragmas.stderr
- testsuite/tests/simplCore/should_compile/OpaqueNoCastWW.stderr
- testsuite/tests/simplCore/should_compile/T15056.stderr
- testsuite/tests/simplCore/should_compile/T15445.stderr
- + testsuite/tests/simplCore/should_compile/T24606.hs
- + testsuite/tests/simplCore/should_compile/T26323b.hs
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_compile/simpl017.stderr
- + testsuite/tests/simplCore/should_run/T26323.hs
- + testsuite/tests/simplCore/should_run/T26323.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/splice-imports/SI29.stderr
- + testsuite/tests/tcplugins/T26395.hs
- + testsuite/tests/tcplugins/T26395.stderr
- + testsuite/tests/tcplugins/T26395_Plugin.hs
- testsuite/tests/tcplugins/all.T
- testsuite/tests/th/Makefile
- testsuite/tests/th/T10267.stderr
- testsuite/tests/th/T10945.stderr
- testsuite/tests/th/T11452.stderr
- testsuite/tests/th/T14627.stderr
- testsuite/tests/th/T15321.stderr
- testsuite/tests/th/T16180.hs
- testsuite/tests/th/T7276.stderr
- + testsuite/tests/th/TH_Depends_Dir.hs
- + testsuite/tests/th/TH_Depends_Dir.stdout
- + testsuite/tests/th/TH_Depends_Dir_External.hs
- testsuite/tests/th/TH_NestedSplicesFail3.stderr
- testsuite/tests/th/TH_NestedSplicesFail4.stderr
- testsuite/tests/th/TH_StaticPointers02.stderr
- testsuite/tests/th/all.T
- testsuite/tests/typecheck/should_compile/T11339.stderr
- testsuite/tests/typecheck/should_compile/T13050.stderr
- testsuite/tests/typecheck/should_compile/T14273.stderr
- testsuite/tests/typecheck/should_compile/T14434.hs
- testsuite/tests/typecheck/should_compile/T14590.stderr
- testsuite/tests/typecheck/should_compile/T25180.stderr
- + testsuite/tests/typecheck/should_compile/T25992a.hs
- + testsuite/tests/typecheck/should_compile/T26154.hs
- + testsuite/tests/typecheck/should_compile/T26154_A.hs
- + testsuite/tests/typecheck/should_compile/T26154_B.hs
- + testsuite/tests/typecheck/should_compile/T26154_B.hs-boot
- + testsuite/tests/typecheck/should_compile/T26154_Other.hs
- + testsuite/tests/typecheck/should_compile/T26277.hs
- + testsuite/tests/typecheck/should_compile/T26345.hs
- + testsuite/tests/typecheck/should_compile/T26346.hs
- + testsuite/tests/typecheck/should_compile/T26350.hs
- + testsuite/tests/typecheck/should_compile/T26358.hs
- + testsuite/tests/typecheck/should_compile/T26376.hs
- + testsuite/tests/typecheck/should_compile/T26457.hs
- testsuite/tests/typecheck/should_compile/T9497a.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/refinement_hole_fits.stderr
- testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr
- testsuite/tests/typecheck/should_fail/DoExpansion3.stderr
- testsuite/tests/typecheck/should_fail/T12177.stderr
- testsuite/tests/typecheck/should_fail/T14884.stderr
- testsuite/tests/typecheck/should_fail/T15801.stderr
- testsuite/tests/typecheck/should_fail/T18851.hs
- testsuite/tests/typecheck/should_fail/T19627.stderr
- testsuite/tests/typecheck/should_fail/T20666.stderr
- testsuite/tests/typecheck/should_fail/T20666a.stderr
- testsuite/tests/typecheck/should_fail/T20666b.stderr
- testsuite/tests/typecheck/should_fail/T21130.stderr
- testsuite/tests/typecheck/should_fail/T22707.stderr
- testsuite/tests/typecheck/should_fail/T22912.stderr
- testsuite/tests/typecheck/should_fail/T23427.stderr
- testsuite/tests/typecheck/should_fail/T23739b.stderr
- testsuite/tests/typecheck/should_fail/T23739c.stderr
- testsuite/tests/typecheck/should_fail/T24064.stderr
- + testsuite/tests/typecheck/should_fail/T26255a.hs
- + testsuite/tests/typecheck/should_fail/T26255a.stderr
- + testsuite/tests/typecheck/should_fail/T26255b.hs
- + testsuite/tests/typecheck/should_fail/T26255b.stderr
- + testsuite/tests/typecheck/should_fail/T26255c.hs
- + testsuite/tests/typecheck/should_fail/T26255c.stderr
- + testsuite/tests/typecheck/should_fail/T26318.hs
- + testsuite/tests/typecheck/should_fail/T26318.stderr
- + testsuite/tests/typecheck/should_fail/T26330.hs
- + testsuite/tests/typecheck/should_fail/T26330.stderr
- testsuite/tests/typecheck/should_fail/T8142.stderr
- testsuite/tests/typecheck/should_fail/T8603.stderr
- testsuite/tests/typecheck/should_fail/T9497d.stderr
- testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail037.stderr
- testsuite/tests/typecheck/should_fail/tcfail128.stderr
- testsuite/tests/typecheck/should_fail/tcfail153.stderr
- testsuite/tests/typecheck/should_fail/tcfail168.stderr
- testsuite/tests/typecheck/should_fail/tcfail177.stderr
- testsuite/tests/typecheck/should_fail/tcfail185.stderr
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
- testsuite/tests/typecheck/should_run/Typeable1.stderr
- + testsuite/tests/unboxedsums/UbxSumUnpackedSize.hs
- + testsuite/tests/unboxedsums/UbxSumUnpackedSize.stdout
- + testsuite/tests/unboxedsums/UbxSumUnpackedSize.stdout-ws-32
- testsuite/tests/unboxedsums/all.T
- testsuite/tests/unboxedsums/unboxedsums_unit_tests.hs
- testsuite/tests/vdq-rta/should_fail/T23738_fail_pun.stderr
- utils/check-exact/ExactPrint.hs
- utils/deriveConstants/Main.hs
- utils/genprimopcode/Main.hs
- utils/genprimopcode/Syntax.hs
- utils/ghc-pkg/Main.hs
- utils/ghc-pkg/ghc-pkg.cabal.in
- utils/ghc-toolchain/exe/Main.hs
- utils/ghc-toolchain/ghc-toolchain.cabal
- + utils/ghc-toolchain/src/GHC/Toolchain/Library.hs
- utils/ghc-toolchain/src/GHC/Toolchain/PlatformDetails.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Target.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cxx.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Renderer.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Utils.hs
- utils/haddock/haddock-api/src/Haddock/InterfaceFile.hs
- utils/haddock/hypsrc-test/Main.hs
- utils/haddock/hypsrc-test/ref/src/Bug1091.html
- utils/haddock/hypsrc-test/ref/src/CPP.html
- utils/haddock/hypsrc-test/ref/src/Classes.html
- utils/haddock/hypsrc-test/ref/src/Constructors.html
- utils/haddock/hypsrc-test/ref/src/Identifiers.html
- utils/haddock/hypsrc-test/ref/src/LinkingIdentifiers.html
- utils/haddock/hypsrc-test/ref/src/Literals.html
- utils/haddock/hypsrc-test/ref/src/Operators.html
- utils/haddock/hypsrc-test/ref/src/Polymorphism.html
- utils/haddock/hypsrc-test/ref/src/PositionPragmas.html
- utils/haddock/hypsrc-test/ref/src/Quasiquoter.html
- utils/haddock/hypsrc-test/ref/src/Records.html
- utils/haddock/hypsrc-test/ref/src/TemplateHaskellQuasiquotes.html
- utils/haddock/hypsrc-test/ref/src/TemplateHaskellSplices.html
- utils/haddock/hypsrc-test/ref/src/Types.html
- utils/haddock/hypsrc-test/ref/src/UsingQuasiquotes.html
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a84b4bae6673cd601e5038acda4877…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a84b4bae6673cd601e5038acda4877…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/bytecode-library] 3 commits: Normalise testsuite output for package tests
by Matthew Pickering (@mpickering) 07 Oct '25
by Matthew Pickering (@mpickering) 07 Oct '25
07 Oct '25
Matthew Pickering pushed to branch wip/bytecode-library at Glasgow Haskell Compiler / GHC
Commits:
dbc55a0f by Matthew Pickering at 2025-10-07T11:28:32+01:00
Normalise testsuite output for package tests
- - - - -
4421c478 by Matthew Pickering at 2025-10-07T14:21:38+01:00
Use LinkingHomePackage, for now, this is broken but only for bytecode libraries
- - - - -
2cbf543c by Matthew Pickering at 2025-10-07T14:30:53+01:00
Accept new output for T9930fail
- - - - -
7 changed files:
- compiler/GHC/Linker/Loader.hs
- testsuite/tests/cabal/all.T
- testsuite/tests/cabal/pkg_bytecode.stderr
- testsuite/tests/cabal/pkg_bytecode.stdout
- testsuite/tests/cabal/pkg_bytecode_foreign.stderr
- testsuite/tests/cabal/pkg_bytecode_foreign.stdout
- testsuite/tests/ghc-e/should_fail/T9930fail.stderr
Changes:
=====================================
compiler/GHC/Linker/Loader.hs
=====================================
@@ -931,7 +931,8 @@ dynLoadObjs interp hsc_env pls@LoaderState{..} objs = do
-- Loading bytecode for mypkg
--- -l mypkg
-- This thinks we are creating shared library for main but we actually are for mypkg
- linkDynLib LinkingForInterpreter logger tmpfs dflags2 unit_env objs (pprTraceIt "test" (map loaded_pkg_uid $ eltsUDFM pkgs_loaded))
+ -- MP: LinkingForInterpreter is broken here for tests, recompPluginPackage
+ linkDynLib LinkingHomePackage logger tmpfs dflags2 unit_env objs (map loaded_pkg_uid $ eltsUDFM pkgs_loaded)
-- if we got this far, extend the lifetime of the library file
changeTempFilesLifetime tmpfs TFL_GhcSession [soFile]
=====================================
testsuite/tests/cabal/all.T
=====================================
@@ -35,9 +35,13 @@ test('ghcpkg06', [extra_files(['test.pkg', 'testdup.pkg'])], makefile_test, [])
test('ghcpkg07', [extra_files(['test.pkg', 'test7a.pkg', 'test7b.pkg'])], makefile_test, [])
-test('pkg_bytecode', [extra_files(['bytecode.pkg', 'Bytecode.hs', "bytecode.script"]), copy_files], makefile_test, [])
+test('pkg_bytecode', [extra_files(['bytecode.pkg', 'Bytecode.hs', "bytecode.script"])
+ , normalise_errmsg_fun(normaliseDynlibNames, ignore_warnings)
+ , copy_files], makefile_test, [])
-test('pkg_bytecode_foreign', [extra_files(['bytecode_foreign.pkg', "BytecodeForeign.hs", "BytecodeForeign.c", "bytecode_foreign.script"]), copy_files], makefile_test, [])
+test('pkg_bytecode_foreign', [extra_files(['bytecode_foreign.pkg', "BytecodeForeign.hs", "BytecodeForeign.c", "bytecode_foreign.script"])
+ , normalise_errmsg_fun(normaliseDynlibNames, ignore_warnings)
+ , copy_files], makefile_test, [])
# Test that we *can* compile a module that also belongs to a package
# (this was disallowed in GHC 6.4 and earlier)
=====================================
testsuite/tests/cabal/pkg_bytecode.stderr
=====================================
@@ -1,9 +1 @@
-testpkg-1.2.3.4: cannot find any of ["libtestpkg-1.2.3.4-XXX.a","libtestpkg-1.2.3.4-XXX_p.a","libtestpkg-1.2.3.4-XXX-ghc9.15.20250811.so","libtestpkg-1.2.3.4-XXX_p-ghc9.15.20250811.so","libtestpkg-1.2.3.4-XXX-ghc9.15.20250811.dylib","libtestpkg-1.2.3.4-XXX_p-ghc9.15.20250811.dylib","testpkg-1.2.3.4-XXX-ghc9.15.20250811.dll","testpkg-1.2.3.4-XXX_p-ghc9.15.20250811.dll"] on library path (ignoring)
-hs_classifieds
- [BytecodeLibrary ./outdir/testpkg-1.2.3.4-XXX.bytecode]
-hs_classifieds
- [DLLPath /home/matt/ghc-bytecode/_build/stage1/lib/../lib/x86_64-linux-ghc-9.15.20250811/libHSghc-internal-9.1500.0-inplace-ghc9.15.20250811.so]
-hs_classifieds
- [DLLPath /home/matt/ghc-bytecode/_build/stage1/lib/../lib/x86_64-linux-ghc-9.15.20250811/libHSghc-prim-0.13.1-inplace-ghc9.15.20250811.so]
-hs_classifieds
- [DLLPath /home/matt/ghc-bytecode/_build/stage1/lib/../lib/x86_64-linux-ghc-9.15.20250811/libHSbase-4.22.0.0-inplace-ghc9.15.20250811.so]
+testpkg-1.2.3.4: cannot find any of ["libtestpkg-1.2.3.4-XXX.a","libtestpkg-1.2.3.4-XXX_p.a","libtestpkg-1.2.3.4-XXX-ghc9.15.20251003.so","libtestpkg-1.2.3.4-XXX_p-ghc9.15.20251003.so","libtestpkg-1.2.3.4-XXX-ghc9.15.20251003.dylib","libtestpkg-1.2.3.4-XXX_p-ghc9.15.20251003.dylib","testpkg-1.2.3.4-XXX-ghc9.15.20251003.dll","testpkg-1.2.3.4-XXX_p-ghc9.15.20251003.dll"] on library path (ignoring)
=====================================
testsuite/tests/cabal/pkg_bytecode.stdout
=====================================
@@ -1,6 +1,4 @@
-[1 of 2] Compiling Bytecode ( Bytecode.hs, interpreted )
+[1 of 2] Compiling Bytecode ( Bytecode.hs, Bytecode.gbc )
[2 of 2] Linking testpkg-1.2.3.4-XXX.bytecode
Reading package info from "bytecode.pkg" ... done.
-GHCi, version 9.15.20250811: https://www.haskell.org/ghc/ :? for help
-ghci> ghci> "bytecode from a package"
-ghci> Leaving GHCi.
+"bytecode from a package"
=====================================
testsuite/tests/cabal/pkg_bytecode_foreign.stderr
=====================================
@@ -1,15 +1 @@
-hs_classifieds
- [DLLPath /home/matt/ghc-bytecode/_build/stage1/lib/../lib/x86_64-linux-ghc-9.15.20250811/libHSghc-internal-9.1500.0-inplace-ghc9.15.20250811.so]
-hs_classifieds
- [DLLPath /home/matt/ghc-bytecode/_build/stage1/lib/../lib/x86_64-linux-ghc-9.15.20250811/libHSghc-prim-0.13.1-inplace-ghc9.15.20250811.so]
-hs_classifieds
- [DLLPath /home/matt/ghc-bytecode/_build/stage1/lib/../lib/x86_64-linux-ghc-9.15.20250811/libHSbase-4.22.0.0-inplace-ghc9.15.20250811.so]
-testpkg-1.2.3.4: cannot find any of ["libtestpkg-1.2.3.4-XXX.a","libtestpkg-1.2.3.4-XXX_p.a","libtestpkg-1.2.3.4-XXX-ghc9.15.20250811.so","libtestpkg-1.2.3.4-XXX_p-ghc9.15.20250811.so","libtestpkg-1.2.3.4-XXX-ghc9.15.20250811.dylib","libtestpkg-1.2.3.4-XXX_p-ghc9.15.20250811.dylib","testpkg-1.2.3.4-XXX-ghc9.15.20250811.dll","testpkg-1.2.3.4-XXX_p-ghc9.15.20250811.dll"] on library path (ignoring)
-hs_classifieds
- [BytecodeLibrary ./outdir/testpkg-1.2.3.4-XXX.bytecode]
-hs_classifieds
- [DLLPath /home/matt/ghc-bytecode/_build/stage1/lib/../lib/x86_64-linux-ghc-9.15.20250811/libHSghc-internal-9.1500.0-inplace-ghc9.15.20250811.so]
-hs_classifieds
- [DLLPath /home/matt/ghc-bytecode/_build/stage1/lib/../lib/x86_64-linux-ghc-9.15.20250811/libHSghc-prim-0.13.1-inplace-ghc9.15.20250811.so]
-hs_classifieds
- [DLLPath /home/matt/ghc-bytecode/_build/stage1/lib/../lib/x86_64-linux-ghc-9.15.20250811/libHSbase-4.22.0.0-inplace-ghc9.15.20250811.so]
+testpkg-1.2.3.4: cannot find any of ["libtestpkg-1.2.3.4-XXX.a","libtestpkg-1.2.3.4-XXX_p.a","libtestpkg-1.2.3.4-XXX-ghc9.15.20251003.so","libtestpkg-1.2.3.4-XXX_p-ghc9.15.20251003.so","libtestpkg-1.2.3.4-XXX-ghc9.15.20251003.dylib","libtestpkg-1.2.3.4-XXX_p-ghc9.15.20251003.dylib","testpkg-1.2.3.4-XXX-ghc9.15.20251003.dll","testpkg-1.2.3.4-XXX_p-ghc9.15.20251003.dll"] on library path (ignoring)
=====================================
testsuite/tests/cabal/pkg_bytecode_foreign.stdout
=====================================
@@ -1,7 +1,5 @@
-[1 of 2] Compiling BytecodeForeign ( BytecodeForeign.hs, interpreted )
+[1 of 2] Compiling BytecodeForeign ( BytecodeForeign.hs, BytecodeForeign.gbc )
[2 of 2] Linking testpkg-1.2.3.4-XXX.bytecode
Reading package info from "bytecode_foreign.pkg" ... done.
-GHCi, version 9.15.20250811: https://www.haskell.org/ghc/ :? for help
-ghci> ghci> 8
+8
42
-ghci> Leaving GHCi.
=====================================
testsuite/tests/ghc-e/should_fail/T9930fail.stderr
=====================================
@@ -1,11 +1,4 @@
-ghc: Uncaught exception ghc-9.13-inplace:GHC.Utils.Panic.GhcException:
-
-default output name would overwrite the input file; must specify -o explicitly
+<no location info>: error:
+ default output name would overwrite the input file; must specify -o explicitly
Usage: For basic information, try the `--help' option.
-While handling default output name would overwrite the input file; must specify -o explicitly
- | Usage: For basic information, try the `--help' option.
-
-HasCallStack backtrace:
- bracket, called at compiler/GHC/Driver/MakeAction.hs:2955:3 in ghc-9.13-inplace:GHC.Driver.MakeAction
-
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b186de5fcc0d8da289a05d4e2870d8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b186de5fcc0d8da289a05d4e2870d8…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fendor/t23703] Allow per constructor refinement of distinct-constructor-tables
by Hannes Siebenhandl (@fendor) 07 Oct '25
by Hannes Siebenhandl (@fendor) 07 Oct '25
07 Oct '25
Hannes Siebenhandl pushed to branch wip/fendor/t23703 at Glasgow Haskell Compiler / GHC
Commits:
b54fce32 by Finley McIlwaine at 2025-10-07T14:43:26+02:00
Allow per constructor refinement of distinct-constructor-tables
Introduce `-fno-distinct-constructor-tables`. A distinct constructor table
configuration is built from the combination of flags given, in order. For
example, to only generate distinct constructor tables for a few specific
constructors and no others, just pass
`-fdistinct-constructor-tables-only=C1,...,CN`.
This flag can be supplied multiple times to extend the set of
constructors to generate a distinct info table for.
You can disable generation of distinct constructor tables for all
configurations by passing `-fno-distinct-constructor-tables`.
The various configurations of these flags is included in the `DynFlags`
fingerprints, which should result in the expected recompilation logic.
Adds a test that checks for distinct tables for various given or omitted
constructors.
Updates CountDepsAst and CountDepsParser tests to account for new dependencies.
Fixes #23703
- - - - -
29 changed files:
- compiler/GHC/Driver/Config/Stg/Debug.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Iface/Flags.hs
- compiler/GHC/Iface/Recomp/Flags.hs
- compiler/GHC/Stg/Debug.hs
- + compiler/GHC/Stg/Debug/Types.hs
- compiler/ghc.cabal.in
- docs/users_guide/debug-info.rst
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/rts/ipe/distinct-tables/Main.hs
- + testsuite/tests/rts/ipe/distinct-tables/Makefile
- + testsuite/tests/rts/ipe/distinct-tables/X.hs
- + testsuite/tests/rts/ipe/distinct-tables/all.T
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables01.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables02.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables03.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables04.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables05.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables06.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables07.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables08.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables09.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables10.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables11.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables12.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables13.stdout
Changes:
=====================================
compiler/GHC/Driver/Config/Stg/Debug.hs
=====================================
@@ -10,5 +10,5 @@ import GHC.Driver.DynFlags
initStgDebugOpts :: DynFlags -> StgDebugOpts
initStgDebugOpts dflags = StgDebugOpts
{ stgDebug_infoTableMap = gopt Opt_InfoTableMap dflags
- , stgDebug_distinctConstructorTables = gopt Opt_DistinctConstructorTables dflags
+ , stgDebug_distinctConstructorTables = distinctConstructorTables dflags
}
=====================================
compiler/GHC/Driver/DynFlags.hs
=====================================
@@ -117,6 +117,7 @@ import GHC.Types.SrcLoc
import GHC.Unit.Module
import GHC.Unit.Module.Warnings
import GHC.Utils.CliOption
+import GHC.Stg.Debug.Types (StgDebugDctConfig(..))
import GHC.SysTools.Terminal ( stderrSupportsAnsiColors )
import GHC.UniqueSubdir (uniqueSubdir)
import GHC.Utils.Outputable
@@ -134,6 +135,7 @@ import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Except (ExceptT)
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.Writer (WriterT)
+import qualified Data.Set as Set
import Data.Word
import System.IO
import System.IO.Error (catchIOError)
@@ -142,7 +144,6 @@ import System.FilePath (normalise, (</>))
import System.Directory
import GHC.Foreign (withCString, peekCString)
-import qualified Data.Set as Set
import GHC.Types.Unique.Set
import qualified GHC.LanguageExtensions as LangExt
@@ -479,7 +480,11 @@ data DynFlags = DynFlags {
-- 'Int' because it can be used to test uniques in decreasing order.
-- | Temporary: CFG Edge weights for fast iterations
- cfgWeights :: Weights
+ cfgWeights :: Weights,
+
+ -- | Configuration specifying which constructor names we should create
+ -- distinct info tables for
+ distinctConstructorTables :: StgDebugDctConfig
}
class HasDynFlags m where
@@ -742,7 +747,9 @@ defaultDynFlags mySettings =
reverseErrors = False,
maxErrors = Nothing,
- cfgWeights = defaultWeights
+ cfgWeights = defaultWeights,
+
+ distinctConstructorTables = None
}
type FatalMessager = String -> IO ()
=====================================
compiler/GHC/Driver/Flags.hs
=====================================
@@ -595,7 +595,6 @@ data GeneralFlag
| Opt_NoBuiltinRules
| Opt_NoBignumRules
- | Opt_DistinctConstructorTables
| Opt_InfoTableMap
| Opt_InfoTableMapWithFallback
| Opt_InfoTableMapWithStack
@@ -986,7 +985,6 @@ codeGenFlags = EnumSet.fromList
, Opt_DoTagInferenceChecks
-- Flags that affect debugging information
- , Opt_DistinctConstructorTables
, Opt_InfoTableMap
, Opt_InfoTableMapWithStack
, Opt_InfoTableMapWithFallback
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -277,6 +277,7 @@ import GHC.CmmToAsm.CFG.Weight
import GHC.Core.Opt.CallerCC
import GHC.Parser (parseIdentifier)
import GHC.Parser.Lexer (mkParserOpts, initParserState, P(..), ParseResult(..))
+import GHC.Stg.Debug.Types
import GHC.SysTools.BaseDir ( expandToolDir, expandTopDir )
@@ -1916,6 +1917,13 @@ dynamic_flags_deps = [
-- Caller-CC
, make_ord_flag defGhcFlag "fprof-callers"
(HasArg setCallerCcFilters)
+ , make_ord_flag defGhcFlag "fdistinct-constructor-tables"
+ (noArg enableDistinctConstructorTables)
+ , make_ord_flag defGhcFlag "fno-distinct-constructor-tables"
+ (noArg disableDistinctConstructorTables)
+ , make_ord_flag defGhcFlag "fdistinct-constructor-tables-only"
+ (Prefix onlyDistinctConstructorTables)
+
------ Compiler flags -----------------------------------------------
, make_ord_flag defGhcFlag "fasm" (NoArg (setObjBackend ncgBackend))
@@ -2617,7 +2625,6 @@ fFlagsDeps = [
flagSpec "cmm-thread-sanitizer" Opt_CmmThreadSanitizer,
flagSpec "split-sections" Opt_SplitSections,
flagSpec "break-points" Opt_InsertBreakpoints,
- flagSpec "distinct-constructor-tables" Opt_DistinctConstructorTables,
flagSpec "info-table-map" Opt_InfoTableMap,
flagSpec "info-table-map-with-stack" Opt_InfoTableMapWithStack,
flagSpec "info-table-map-with-fallback" Opt_InfoTableMapWithFallback
@@ -3215,6 +3222,41 @@ setCallerCcFilters arg =
Right filt -> upd $ \d -> d { callerCcFilters = filt : callerCcFilters d }
Left err -> addErr err
+enableDistinctConstructorTables :: DynFlags -> DynFlags
+enableDistinctConstructorTables d =
+ d { distinctConstructorTables = All
+ }
+
+disableDistinctConstructorTables :: DynFlags -> DynFlags
+disableDistinctConstructorTables d =
+ d { distinctConstructorTables = None
+ }
+
+onlyDistinctConstructorTables :: String -> DynP ()
+onlyDistinctConstructorTables arg = do
+ let cs = parseDistinctConstructorTablesArg arg
+ upd $ \d ->
+ d { distinctConstructorTables =
+ (distinctConstructorTables d) `dctConfigOnly` cs
+ }
+
+-- | Parse a string of comma-separated constructor names into a 'Set' of
+-- 'String's with one entry per constructor.
+parseDistinctConstructorTablesArg :: String -> Set.Set String
+parseDistinctConstructorTablesArg =
+ -- Ensure we insert the last constructor name built by the fold, if not
+ -- empty
+ uncurry insertNonEmpty
+ . foldr go ("", Set.empty)
+ where
+ go :: Char -> (String, Set.Set String) -> (String, Set.Set String)
+ go ',' (cur, acc) = ("", Set.insert cur acc)
+ go c (cur, acc) = (c : cur, acc)
+
+ insertNonEmpty :: String -> Set.Set String -> Set.Set String
+ insertNonEmpty "" = id
+ insertNonEmpty cs = Set.insert cs
+
setMainIs :: String -> DynP ()
setMainIs arg = parse parse_main_f arg
where
=====================================
compiler/GHC/Iface/Flags.hs
=====================================
@@ -6,12 +6,15 @@ module GHC.Iface.Flags (
, IfaceExtension(..)
, IfaceLanguage(..)
, IfaceCppOptions(..)
+ , IfaceCodeGen(..)
+ , IfaceDistinctConstructorConfig(..)
, pprIfaceDynFlags
, missingExtraFlagInfo
) where
import GHC.Prelude
+import qualified Data.Set as Set
import GHC.Utils.Outputable
import Control.DeepSeq
import GHC.Utils.Fingerprint
@@ -22,6 +25,7 @@ import GHC.Types.SafeHaskell
import GHC.Core.Opt.CallerCC.Types
import qualified GHC.LanguageExtensions as LangExt
+import GHC.Stg.Debug.Types
-- The part of DynFlags which recompilation information needs
data IfaceDynFlags = IfaceDynFlags
@@ -35,7 +39,7 @@ data IfaceDynFlags = IfaceDynFlags
, ifacePaths :: [String]
, ifaceProf :: Maybe IfaceProfAuto
, ifaceTicky :: [IfaceGeneralFlag]
- , ifaceCodeGen :: [IfaceGeneralFlag]
+ , ifaceCodeGen :: IfaceCodeGen
, ifaceFatIface :: Bool
, ifaceDebugLevel :: Int
, ifaceCallerCCFilters :: [CallerCcFilter]
@@ -58,7 +62,7 @@ pprIfaceDynFlags (IfaceDynFlags a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14)
, text "ticky:"
, nest 2 $ vcat (map ppr a10)
, text "codegen:"
- , nest 2 $ vcat (map ppr a11)
+ , nest 2 $ ppr a11
, text "fat-iface:" <+> ppr a12
, text "debug-level:" <+> ppr a13
, text "caller-cc-filters:" <+> ppr a14
@@ -191,4 +195,60 @@ instance Outputable IfaceCppOptions where
, text "signature:"
, nest 2 $ parens (ppr fp) <+> ppr (map (text @SDoc) wos)
- ]
\ No newline at end of file
+ ]
+
+data IfaceCodeGen = IfaceCodeGen
+ { ifaceCodeGenFlags :: [IfaceGeneralFlag]
+ , ifaceCodeGenDistinctConstructorTables :: IfaceDistinctConstructorConfig
+ }
+
+instance NFData IfaceCodeGen where
+ rnf (IfaceCodeGen flags distinctCnstrTables) =
+ rnf flags `seq` rnf distinctCnstrTables
+
+instance Binary IfaceCodeGen where
+ put_ bh (IfaceCodeGen flags distinctCnstrTables) = do
+ put_ bh flags
+ put_ bh distinctCnstrTables
+
+ get bh =
+ IfaceCodeGen <$> get bh <*> get bh
+
+instance Outputable IfaceCodeGen where
+ ppr (IfaceCodeGen flags distinctCnstrTables) =
+ vcat
+ [ text "flags:"
+ , nest 2 $ ppr flags
+ , text "distinct constructor tables:"
+ , nest 2 $ ppr distinctCnstrTables
+ ]
+
+newtype IfaceDistinctConstructorConfig = IfaceDistinctConstructorConfig StgDebugDctConfig
+
+instance NFData IfaceDistinctConstructorConfig where
+ rnf (IfaceDistinctConstructorConfig cnf) = case cnf of
+ All -> ()
+ (Only v) -> rnf v
+ None -> ()
+
+instance Outputable IfaceDistinctConstructorConfig where
+ ppr (IfaceDistinctConstructorConfig cnf) = case cnf of
+ All -> text "all"
+ (Only v) -> text "only" <+> brackets (hcat $ fmap text $ Set.toList v)
+ None -> text "none"
+
+instance Binary IfaceDistinctConstructorConfig where
+ put_ bh (IfaceDistinctConstructorConfig cnf) = case cnf of
+ All -> putByte bh 0
+ (Only cs) -> do
+ putByte bh 1
+ put_ bh cs
+ None -> putByte bh 2
+
+ get bh = do
+ h <- getByte bh
+ IfaceDistinctConstructorConfig <$>
+ case h of
+ 0 -> pure All
+ 1 -> Only <$> get bh
+ _ -> pure None
=====================================
compiler/GHC/Iface/Recomp/Flags.hs
=====================================
@@ -91,12 +91,30 @@ fingerprintDynFlags hsc_env this_mod nameio =
mapMaybe (\f -> (if f `gopt` dflags then Just (IfaceGeneralFlag f) else Nothing)) [Opt_Ticky, Opt_Ticky_Allocd, Opt_Ticky_LNE, Opt_Ticky_Dyn_Thunk, Opt_Ticky_Tag]
-- Other flags which affect code generation
- codegen = mapMaybe (\f -> (if f `gopt` dflags then Just (IfaceGeneralFlag f) else Nothing)) (EnumSet.toList codeGenFlags)
+ codegen = IfaceCodeGen
+ { ifaceCodeGenFlags = mapMaybe (\f -> (if f `gopt` dflags then Just (IfaceGeneralFlag f) else Nothing)) (EnumSet.toList codeGenFlags)
+ , ifaceCodeGenDistinctConstructorTables = IfaceDistinctConstructorConfig distinctConstructorTables
+ }
-- Did we include core for all bindings?
fat_iface = gopt Opt_WriteIfSimplifiedCore dflags
- f = IfaceDynFlags mainis safeHs lang exts cpp js cmm paths prof ticky codegen fat_iface debugLevel callerCcFilters
+ f = IfaceDynFlags
+ { ifaceMainIs = mainis
+ , ifaceSafeMode = safeHs
+ , ifaceLang = lang
+ , ifaceExts = exts
+ , ifaceCppOptions = cpp
+ , ifaceJsOptions = js
+ , ifaceCmmOptions = cmm
+ , ifacePaths = paths
+ , ifaceProf = prof
+ , ifaceTicky = ticky
+ , ifaceCodeGen = codegen
+ , ifaceFatIface = fat_iface
+ , ifaceDebugLevel = debugLevel
+ , ifaceCallerCCFilters = callerCcFilters
+ }
in (computeFingerprint nameio f, f)
=====================================
compiler/GHC/Stg/Debug.hs
=====================================
@@ -1,9 +1,11 @@
-{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE TupleSections #-}
-- This module contains functions which implement
-- the -finfo-table-map and -fdistinct-constructor-tables flags
module GHC.Stg.Debug
( StgDebugOpts(..)
+ , StgDebugDctConfig(..)
+ , dctConfigOnly
, collectDebugInformation
) where
@@ -17,11 +19,13 @@ import GHC.Types.Tickish
import GHC.Core.DataCon
import GHC.Types.IPE
import GHC.Unit.Module
-import GHC.Types.Name ( getName, getOccName, occNameFS, nameSrcSpan)
+import GHC.Types.Name ( getName, getOccName, occNameFS, nameSrcSpan, occName, occNameString)
import GHC.Data.FastString
+import GHC.Stg.Debug.Types
import Control.Monad (when)
import Control.Monad.Trans.Reader
+import qualified Data.Set as Set
import GHC.Utils.Monad.State.Strict
import Control.Monad.Trans.Class
import GHC.Types.SrcLoc
@@ -29,13 +33,6 @@ import Control.Applicative
import qualified Data.List.NonEmpty as NE
import Data.List.NonEmpty (NonEmpty(..))
-data SpanWithLabel = SpanWithLabel RealSrcSpan LexicalFastString
-
-data StgDebugOpts = StgDebugOpts
- { stgDebug_infoTableMap :: !Bool
- , stgDebug_distinctConstructorTables :: !Bool
- }
-
data R = R { rOpts :: StgDebugOpts, rModLocation :: ModLocation, rSpan :: Maybe SpanWithLabel }
type M a = ReaderT R (State InfoTableProvMap) a
@@ -164,10 +161,11 @@ numberDataCon dc _ | isUnboxedTupleDataCon dc = return NoNumber
numberDataCon dc _ | isUnboxedSumDataCon dc = return NoNumber
numberDataCon dc ts = do
opts <- asks rOpts
- if stgDebug_distinctConstructorTables opts then do
- -- -fdistinct-constructor-tables is enabled. Add an entry to the data
- -- constructor map for this occurrence of the data constructor with a unique
- -- number and a src span
+ if shouldMakeDistinctTable opts dc then do
+ -- -fdistinct-constructor-tables is enabled and we do want to make distinct
+ -- tables for this constructor. Add an entry to the data constructor map for
+ -- this occurrence of the data constructor with a unique number and a src
+ -- span
env <- lift get
mcc <- asks rSpan
let
@@ -192,7 +190,8 @@ numberDataCon dc ts = do
Nothing -> NoNumber
Just (_, res) -> Numbered (fst (NE.head res))
else do
- -- -fdistinct-constructor-tables is not enabled
+ -- -fdistinct-constructor-tables is not enabled, or we do not want to make
+ -- distinct tables for this specific constructor
return NoNumber
selectTick :: [StgTickish] -> Maybe (RealSrcSpan, LexicalFastString)
@@ -202,6 +201,19 @@ selectTick = foldl' go Nothing
go _ (SourceNote rss d) = Just (rss, d)
go acc _ = acc
+-- | Descide whether a distinct info table should be made for a usage of a data
+-- constructor. We only want to do this if -fdistinct-constructor-tables was
+-- given and this constructor name was given, or no constructor names were
+-- given.
+shouldMakeDistinctTable :: StgDebugOpts -> DataCon -> Bool
+shouldMakeDistinctTable StgDebugOpts{stgDebug_distinctConstructorTables} dc =
+ case stgDebug_distinctConstructorTables of
+ All -> True
+ Only these -> Set.member dcStr these
+ None -> False
+ where
+ dcStr = occNameString . occName $ dataConName dc
+
{-
Note [Mapping Info Tables to Source Positions]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Stg/Debug/Types.hs
=====================================
@@ -0,0 +1,53 @@
+module GHC.Stg.Debug.Types where
+
+import GHC.Prelude
+
+import GHC.Data.FastString
+import GHC.Types.SrcLoc
+
+import Data.Set (Set)
+import qualified Data.Set as Set
+
+data SpanWithLabel = SpanWithLabel RealSrcSpan LexicalFastString
+
+data StgDebugOpts = StgDebugOpts
+ { stgDebug_infoTableMap :: !Bool
+ , stgDebug_distinctConstructorTables :: !StgDebugDctConfig
+ }
+
+-- | Configuration describing which constructors should be given distinct info
+-- tables for each usage.
+data StgDebugDctConfig =
+ -- | Create distinct constructor tables for each usage of any data
+ -- constructor.
+ --
+ -- This is the behavior if just @-fdistinct-constructor-tables@ is supplied.
+ All
+
+ -- | Create distinct constructor tables for each usage of only these data
+ -- constructors.
+ --
+ -- This is the behavior if @-fdistinct-constructor-tables-only=C1,...,CN@ is
+ -- supplied.
+ | Only !(Set String)
+
+ -- | Do not create distinct constructor tables for any data constructor.
+ --
+ -- This is the behavior if @-fno-distinct-constructor-tables@ is given.
+ | None
+
+-- | Given a distinct constructor tables configuration and a set of constructor
+-- names that we want to generate distinct info tables for, create a new
+-- configuration which includes those constructors.
+--
+-- If the given set is empty, that means the user has entered
+-- @-fdistinct-constructor-tables@ with no constructor names specified, and
+-- therefore we consider that an 'All' configuration.
+dctConfigOnly :: StgDebugDctConfig -> Set String -> StgDebugDctConfig
+dctConfigOnly cfg cs
+ | Set.null cs = All
+ | otherwise =
+ case cfg of
+ All -> Only cs
+ Only cs' -> Only $ Set.union cs' cs
+ None -> Only cs
=====================================
compiler/ghc.cabal.in
=====================================
@@ -739,6 +739,7 @@ Library
GHC.Stg.EnforceEpt.Rewrite
GHC.Stg.EnforceEpt.TagSig
GHC.Stg.EnforceEpt.Types
+ GHC.Stg.Debug.Types
GHC.Stg.FVs
GHC.Stg.Lift
GHC.Stg.Lift.Analysis
=====================================
docs/users_guide/debug-info.rst
=====================================
@@ -368,7 +368,8 @@ to a source location. This lookup table is generated by using the ``-finfo-table
an info table to an approximate source position of where that
info table statically originated from. If you
also want more precise information about constructor info tables then you
- should also use :ghc-flag:`-fdistinct-constructor-tables`.
+ should also use :ghc-flag:`-fdistinct-constructor-tables
+ <-fdistinct-constructor-tables>`.
The :ghc-flag:`-finfo-table-map` flag will increase the binary size by quite
a lot, depending on how big your project is. For compiling a project the
@@ -467,6 +468,35 @@ to a source location. This lookup table is generated by using the ``-finfo-table
each info table will correspond to the usage of a data constructor rather
than the data constructor itself.
+.. ghc-flag:: -fno-distinct-constructor-tables
+ :shortdesc: Avoid generating a fresh info table for each usage of a data
+ constructor.
+ :type: dynamic
+ :category: debugging
+
+ :since: 9.16
+
+ Disable generation of distinct info tables for all constructors.
+
+.. ghc-flag:: -fdistinct-constructor-tables-only=⟨cs⟩
+ :shortdesc: Generate a fresh info table for each usage
+ of a data constructor.
+ :type: dynamic
+ :category: debugging
+
+ :since: 9.16
+
+ The entries in the info table map resulting from
+ :ghc-flag:`-fdistinct-constructor-tables` flag may significantly
+ increase the size of executables. However, generating distinct info tables
+ for *every* usage of *every* data constructor often results in more
+ information than necessary. Instead, we would like to generate these
+ distinct tables for some specific constructors. To do this, the names of the
+ constructors we are interested in may be supplied to this flag in a
+ comma-separated list.
+
+ For example, to only generate distinct info tables for the ``Just`` and
+ ``Right`` constructors, use ``-fdistinct-constructor-tables-only=Just,Right``.
Querying the Info Table Map
---------------------------
=====================================
testsuite/tests/count-deps/CountDepsAst.stdout
=====================================
@@ -123,6 +123,7 @@ GHC.Runtime.Heap.Layout
GHC.Settings
GHC.Settings.Config
GHC.Settings.Constants
+GHC.Stg.Debug.Types
GHC.Stg.EnforceEpt.TagSig
GHC.StgToCmm.Types
GHC.SysTools.Terminal
=====================================
testsuite/tests/count-deps/CountDepsParser.stdout
=====================================
@@ -142,6 +142,7 @@ GHC.Runtime.Heap.Layout
GHC.Settings
GHC.Settings.Config
GHC.Settings.Constants
+GHC.Stg.Debug.Types
GHC.Stg.EnforceEpt.TagSig
GHC.StgToCmm.Types
GHC.SysTools.Terminal
=====================================
testsuite/tests/rts/ipe/distinct-tables/Main.hs
=====================================
@@ -0,0 +1,37 @@
+module Main where
+
+import GHC.InfoProv
+import qualified X
+
+main = do
+ printIp =<< whereFrom cafA1
+ printIp =<< whereFrom cafA2
+ printIp =<< whereFrom cafB1
+ printIp =<< whereFrom cafB2
+ printIp =<< whereFrom cafC1
+ printIp =<< whereFrom cafC2
+ printIp =<< whereFrom (ACon ())
+ printIp =<< whereFrom cafXA
+ printIp =<< whereFrom X.cafXA1
+ printIp =<< whereFrom X.cafXA2
+ printIp =<< whereFrom (X.ACon ())
+ printIp =<< whereFrom (BCon cafA1)
+ printIp =<< whereFrom (CCon (cafA1, BCon (ACon ())))
+ where
+ -- Get rid of the src file path since it makes test output difficult to diff
+ -- on Windows
+ printIp = print . stripIpSrc
+ stripIpSrc (Just ip) = ip { ipSrcFile = "" }
+
+data A = ACon ()
+data B = BCon A
+data C = CCon (A, B)
+
+cafA1 = ACon ()
+cafA2 = ACon ()
+cafB1 = BCon cafA1
+cafB2 = BCon cafA2
+cafC1 = CCon (cafA1, cafB1)
+cafC2 = CCon (cafA2, cafB2)
+
+cafXA = X.ACon ()
=====================================
testsuite/tests/rts/ipe/distinct-tables/Makefile
=====================================
@@ -0,0 +1,66 @@
+TOP=../../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+# This test runs ghc with various combinations of
+# -f{no-}distinct-constructor-tables for different constructors and checks that
+# whereFrom finds (or fails to find) their provenance appropriately.
+
+distinct_tables01:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables-only=ACon Main.hs
+ ./Main
+
+distinct_tables02:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables-only=BCon Main.hs
+ ./Main
+
+distinct_tables03:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables-only=CCon Main.hs
+ ./Main
+
+distinct_tables04:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables-only=ACon,BCon Main.hs
+ ./Main
+
+distinct_tables05:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables-only=ACon -fdistinct-constructor-tables-only=BCon -fdistinct-constructor-tables-only=CCon Main.hs
+ ./Main
+
+distinct_tables06:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables-only=ACon -fno-distinct-constructor-tables Main.hs
+ ./Main
+
+distinct_tables07:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables -fdistinct-constructor-tables-only=ACon -fno-distinct-constructor-tables Main.hs
+ ./Main
+
+distinct_tables08:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fno-distinct-constructor-tables Main.hs
+ ./Main
+
+distinct_tables09:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fno-distinct-constructor-tables -fdistinct-constructor-tables-only=ACon Main.hs
+ ./Main
+
+distinct_tables10:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables Main.hs
+ ./Main
+
+# Recompilation tests
+distinct_tables11:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables Main.hs
+ ./Main
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables -fdistinct-constructor-tables-only=ACon Main.hs
+ ./Main
+
+distinct_tables12:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fno-distinct-constructor-tables Main.hs
+ ./Main
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables Main.hs
+ ./Main
+
+distinct_tables13:
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables Main.hs
+ ./Main
+ "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -finfo-table-map -fdistinct-constructor-tables -fdistinct-constructor-tables-only=ACon Main.hs
+ ./Main
=====================================
testsuite/tests/rts/ipe/distinct-tables/X.hs
=====================================
@@ -0,0 +1,7 @@
+module X where
+
+-- A type with the same constructor name as 'Main.ACon'
+data X = ACon ()
+
+cafXA1 = ACon ()
+cafXA2 = ACon ()
=====================================
testsuite/tests/rts/ipe/distinct-tables/all.T
=====================================
@@ -0,0 +1,13 @@
+test('distinct_tables01', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables02', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables03', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables04', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables05', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables06', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables07', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables08', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables09', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables10', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables11', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables12', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
+test('distinct_tables13', [extra_files(['Main.hs', 'X.hs',])], makefile_test, [])
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables01.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables02.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables03.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "34:1-27"}
+InfoProv {ipName = "CCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "35:1-27"}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_Main_3_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "19:34-38"}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables04.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables05.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "34:1-27"}
+InfoProv {ipName = "CCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "35:1-27"}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_Main_3_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "19:34-38"}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables06.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables07.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables08.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables09.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables10.stdout
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "34:1-27"}
+InfoProv {ipName = "CCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "35:1-27"}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_Main_3_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "19:34-38"}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables11.stdout
=====================================
@@ -0,0 +1,26 @@
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "34:1-27"}
+InfoProv {ipName = "CCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "35:1-27"}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_Main_3_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "19:34-38"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables12.stdout
=====================================
@@ -0,0 +1,26 @@
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "34:1-27"}
+InfoProv {ipName = "CCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "35:1-27"}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_Main_3_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "19:34-38"}
=====================================
testsuite/tests/rts/ipe/distinct-tables/distinct_tables13.stdout
=====================================
@@ -0,0 +1,26 @@
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "cafB2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "34:1-27"}
+InfoProv {ipName = "CCon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "cafC2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "35:1-27"}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "B", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_Main_3_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "C", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "19:34-38"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA1", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "cafA2", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_4_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "A", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA1", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_2_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "cafXA2", ipUnitId = "main", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "X", ipLabel = "main", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = CONSTR_1_0, ipTyDesc = "", ipLabel = "", ipUnitId = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b54fce328838356fe626e539c95a378…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b54fce328838356fe626e539c95a378…
You're receiving this email because of your account on gitlab.haskell.org.
1
0