[Git][ghc/ghc][master] 3 commits: Improvements to type/data family handling
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1b4a622f by sheaf at 2026-09-17T02:39:13-04:00 Improvements to type/data family handling This commit makes several improvements to the treatment of type and data families in GHC: - We consistently use "type family" instead of "type synonym family" to avoid a confusion with type synonyms. For example: - OpenSynFamilyTyCon ==> OpenTypeFamilyTyCon - ClosedSynFamilyTyCon => ClosedTypeFamilyTyCon - Various functions that were specific to data families have been renamed to make this clear. For example: - tyConFamInst_maybe ==> tyConDataFamInst_maybe - isFamInstTyCon ==> isDataFamInstTyCon - 'FamTyConFlav' has been refactored so that all closed type families share a single 'ClosedTypeFamilyTyCon' constructor. The corresponding 'IfaceFamTyConFlav' type was updated similarly. This is then used to tidy up the implementation of GHC.Core.FamInstEnv.reduceTyFamApp_maybe. - - - - - c5aa9098 by sheaf at 2026-09-17T02:39:13-04:00 Small refactor of lookupFamInstEnv This commit reworks the code for looking up family instances in GHC.Core.FamInstEnv, reducing duplication a little bit. No change in behaviour. - - - - - a3ad4588 by sheaf at 2026-09-17T02:39:14-04:00 Use a type family for boxing unboxed types This commit overhauls the way in which unboxed types are boxed, as per the updated Note [Boxing constructors] in GHC.Builtin.WiredIn.Types.Box. The main change is to allow boxing to be parametrised by representation, e.g. making 'Box ty' a valid type. We achieve this by implementing 'Box' using a closed type family: newtype Box (a :: TYPE r) = Box (BoxTF r) type BoxTF :: RuntimeRep -> Type type family BoxTF r where BoxTF IntRep = BoxInt BoxTF Int8Rep = BoxInt8 BoxTF WordRep = BoxWord BoxTF LiftedRep = Any @Type BoxTF (TupleRep [r1, r2]) = (BoxTF r1, BoxTF r2) ... BoxTF (SumRep rs) = BoxSum rs This new design solves the following problems: - It allows boxing a type whose 'RuntimeRep' has not yet been determined (e.g. because we only learn the 'RuntimeRep' after constraint solving). That is, 'Box @r a' is a perfectly valid type even if 'r' is an unfilled metavariable. This is a requirement to fix #25065 (in which we need to box a type whose 'RuntimeRep' is only filled in during constraint solving). - It handles boxing of unboxed tuples and unboxed sums, via recursive boxing. See Note [Boxing TupleRep and SumRep] in GHC.Builtin.WiredIn.Types.Box. 'Box', 'BoxTF' and all of the boxing data constructors are defined in a new 'ghc-internal' module, 'GHC.Internal.Box'. This module contains nothing but wired-in declarations, and GHC never loads its interface on account of a wired-in thing (GHC.Builtin.Modules.isWiredInOnlyModule); see Note [Loading instances for wired-in things] in GHC.Iface.Load. The individual boxing data constructors are deliberately left as an internal implementation detail, and not exported. The intended API is via the two new magic 'Id's: box :: forall {r} (a :: TYPE r). a -> Box a unbox :: forall {r} (a :: TYPE r). Box a -> a exported from 'GHC.PrimOps' (in 'ghc-experimental'). The old boxing data types (IntBox, WordBox, FloatBox, DoubleBox, DictBox) are no longer exported from base (CLC proposal #421). We use this new design to consistently desugar: - parallel comprehensions (GHC.HsToCore.ListComp.{deListComp,dsMcStmt}) - then/group/using statements (GHC.HsToCore.ListComp.{dsTransStmt,dsMcStmt}) - recursive do blocks (mdo/rec) (GHC.HsToCore.Expr.dsDo) - arrows (GHC.HsToCore.Arrows) by consistently using 'box'/'unbox' to deal with unboxed types being put into big tuples. We also adapt 'GHC.Tc.Gen.Match.{tcMcStmt,tcDoStmt}' to create fresh /representation-polymorphic/ type variables for the binders that we are going to put into a big tuple (previously, GHC only allowed lifted types in that position). These desugaring of box and unbox is explained in Note [Desugaring box & unbox] in GHC.Core.Make.Box. Roughly speaking, the desugaring looks like: box @r @ty e ==> K e unbox @r @ty e ==> case e of K x -> x where 'K' is the boxing data constructor at RuntimeRep 'r'. It's slightly more complicated than that in practice: we first need to insert a cast (see Note [The canonical type of a RuntimeRep]) using the new 'CanonicalProv' 'UnivCoProvenance', and unboxed tuples/sums need recursive logic explained in Note [box/unbox for unboxed tuples and sums], including a specific 'BoxSum' datatypes for unboxed sum (which also needed a wired-in type-level list indexing type family (!!)). The desugaring happens in two ways: - Occurrences of 'box'/'unbox' emitted by the typechecker are eliminated in the 'ds_app_var' case of GHC.HsToCore.Expr. - Other code that needs to box/unbox emits the appropriate code inline. This includes the big tuple machinery of GHC.Core.Make used by the desugarer (GHC.HsToCore.{Utils,Binds,Arrows,ListComp}) as well as the float-out pass (GHC.Core.Opt.SetLevels). Core Lint checks that no occurrence of 'box'/'unbox' survives desugaring. On the way, we overhaul the litany of big tuple functions by introducing data BigTupleLayout = BoxedElements | BareElements to distinguish the two kinds of "big tuples" that GHC routinely deals with; for example 'mkBigCoreVarTupSolo' becomes 'mkBigCoreVarTup BareElements'. All of this code is moved to the new module GHC.Core.Make.BigTuple. Fixes #20864 #22336 #22473 #25065 #27331 ------------------------- Metric Decrease: T9872a ------------------------- - - - - - 103 changed files: - + changelog.d/boxing-family - + changelog.d/clc-421 - compiler/GHC/Builtin.hs - compiler/GHC/Builtin/KnownKeys.hs - compiler/GHC/Builtin/Modules.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/WiredIn/Ids.hs - compiler/GHC/Builtin/WiredIn/Prim.hs - compiler/GHC/Builtin/WiredIn/TypeLits.hs - compiler/GHC/Builtin/WiredIn/Types.hs - + compiler/GHC/Builtin/WiredIn/Types/Box.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - + compiler/GHC/Core/Make/BigTuple.hs - + compiler/GHC/Core/Make/Box.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/AddImplicitBinds.hs - compiler/GHC/Driver/Main/Compile.hs - compiler/GHC/Driver/Main/Passes.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Deriv/Generics.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Instance/Typeable.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/FunDeps.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Types/CompleteMatch.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Types/TyThing.hs - compiler/GHC/Types/TyThing/Ppr.hs - compiler/GHC/Types/Unique.hs - compiler/ghc.cabal.in - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/ghc-internal.cabal.in - libraries/ghc-internal/include/RtsIfaceSymbols.h - + libraries/ghc-internal/src/GHC/Internal/Box.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/TypeNats.hs - libraries/ghc-internal/src/GHC/Internal/Types.hs - linters/lint-codes/LintCodes/Static.hs - rts/Prelude.h - rts/include/rts/RtsToHsIface.h - rts/sm/Evac.c - testsuite/tests/arrows/should_run/all.T - + testsuite/tests/arrows/should_run/arrowrun005.hs - + testsuite/tests/arrows/should_run/arrowrun005.stdout - testsuite/tests/count-deps/CountDepsParser.stdout - + testsuite/tests/deSugar/should_compile/T25065a.hs - testsuite/tests/deSugar/should_compile/all.T - + testsuite/tests/deSugar/should_run/T20864.hs - + testsuite/tests/deSugar/should_run/T20864.stdout - + testsuite/tests/deSugar/should_run/T25065b.hs - + testsuite/tests/deSugar/should_run/T25065b.stdout - testsuite/tests/deSugar/should_run/all.T - + testsuite/tests/indexed-types/should_run/T27331.hs - + testsuite/tests/indexed-types/should_run/T27331.stdout - + testsuite/tests/indexed-types/should_run/T27331b.hs - + testsuite/tests/indexed-types/should_run/T27331b.stdout - + testsuite/tests/indexed-types/should_run/T27331b_Plugin.hs - testsuite/tests/indexed-types/should_run/all.T - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 - testsuite/tests/interface-stability/ghc-prim-exports.stdout - testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32 - testsuite/tests/linters/notes.stdout - utils/haddock/haddock-api/src/Haddock/Convert.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2d57026995cd8065004764f6ef3b18... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2d57026995cd8065004764f6ef3b18... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
participants (1)
-
Marge Bot (@marge-bot)