[Git][ghc/ghc][wip/spj-reinstallable-base2] Onward
Simon Peyton Jones pushed to branch wip/spj-reinstallable-base2 at Glasgow Haskell Compiler / GHC Commits: 3dc8d56d by Simon Peyton Jones at 2026-04-14T00:35:11+01:00 Onward This version bootstraps. And the documentation in GHC.Builtin is much better - - - - - 18 changed files: - compiler/GHC/Builtin.hs - compiler/GHC/Builtin/KnownKeys.hs - compiler/GHC/Builtin/KnownOccs.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Deriv/Generics.hs - libraries/base/src/Control/Applicative.hs - libraries/base/src/Data/Fixed.hs - libraries/base/src/Data/Semigroup.hs - libraries/base/src/GHC/KnownKeyNames.hs - libraries/ghc-internal/src/GHC/Internal/Base.hs - libraries/ghc-internal/src/GHC/Internal/Heap/Closures.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/Syntax.hs Changes: ===================================== compiler/GHC/Builtin.hs ===================================== @@ -93,6 +93,18 @@ import Data.Maybe {- Note [Overview of known-key entities] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +There are three kinds of entities that GHC knows something about. + * known-occ entities + * known-key entities + * wired-in entities +It is pretty easy, cheap, and robust to add a new known-occ entity; but GHC +does not know much about it. In contrast, it is expensive and relatively +fragile to add a new wired-in entity; but in exchange GHC knows a lot about +it. Known-key entities are in the middle. Use the cheapest one that does +what you need! + +Here are more details. + A "wired-in" entity: * Its Unique, OccName * Its defining module @@ -103,7 +115,7 @@ A "wired-in" entity: knowledge precisely reflects the code in the library. A "known-key" entity: - * Its Unique and OccName are baked into GHC + * Its Unique and OccName are baked into GHC. Its Unique is called a KnownKey. * It is exported by base:GHC.KnownKeyNames * But that's all that GHC knows about it In particular, GHC does /not/ know in which module the entity is defined. @@ -115,7 +127,7 @@ A "known-key" entity: to GHC. It's not hard. A "known-occ" entity: - * Its OccName is baked into GHC + * Its OccName is baked into GHC -- we call it a KnownOcc * It is exported by base:GHC.KnownKeyNames * But that's all that GHC knows about it In particular, GHC does /not/ know in which module the entity is defined, @@ -127,13 +139,15 @@ A "known-occ" entity: It is significantly easier to add a known-occ entity to GHC than a known-key entity, so we use known-occ entities whenever we can. + Every known-key entity is also a known-occ entity, but not vice versa. + When do we use each of these? -* We use a wired-in entity when we must. E.g. `boolTy` uses the wired-in TyCon - `boolTyCon`. We want a static `boolTy` so we can use it in `mkIfThenElse`, - which is a pure function with no monad in sight. +* WIRED-IN. We use a wired-in entity when we want a statically-defined Type or TyCon. + E.g. `boolTy` uses the wired-in TyCon `boolTyCon`. We want a static `boolTy` so + we can use it in `mkIfThenElse`, which is a pure function with no monad in sight. -* We use a known-key entity when we want a fast test to say, for example, +* KNOWN-KEY. We use a known-key entity when we want a fast test to say, for example, "are you /the/ Typeable class?", not some other class that happens to be called "Typeable". It checks this using cls `hasKnownKey` typeableClassKey @@ -142,76 +156,73 @@ When do we use each of these? where GHC.Builtin.KnownKeys.typeableClassKey is the statically chosen unique for `Typeable`. See `GHC.Tc.Instance.Class.matchGlobalInst` -* We use a known-occ entity when we just want to refer to the thing in, say, - the code generated for a `deriving` clause. - - - - -* Very similarly, see `GHC.Tc.Deriv.Utils.stockSideConditions`, which checks if a + Very similarly, see `GHC.Tc.Deriv.Utils.stockSideConditions`, which checks if a class is suitable for stock deriving. -Here is why GHC might want to refer to a known-occ entity: - -* When desugaring a Template Haskell quotation, in GHC.HsToCore.Quote, GHC - must generate Core that mentions a myriad of functions defined in - ghc-internal:GHC.Internal.TH.Lib, such as `varE`, `conE`, `funD`, etc etc. - They don't need a fixed /unique/, but we still need to find them, so we use - their /OccName/. They are "known-occ" entities. - - To do the lookup it uses - dsLookupKnownOccId :: KnownOcc -> DsM TyThing - -* When dealing with `deriving` clauses, GHC generates (LHsBinds GhcPs) bindings, - and then renames and typechecks them. These bindings refer to a myriad of - identifiers, such as `(==)`, `(>)`, `inRange`, and so on. Again GHC does not - need to know a statically-known unique for them, but it does need to find them - so it uses known - -* When desugaring, the desugarer wants to refer to a particular - class, type, or function. It does this via (e.g.) - dsLookupKnownOccTyCon :: KnownOcc -> DsM TyCon - or - dsLookupKnownKeyTyCon :: KnownKey -> DsM TyCon - It doesn't really matter which we use. - -* In a very similar way, for type-class defauting GHC has built-in defaulting behaviour - for Num, IsString, etc. It gets hold of these classes via their known key, via - tcLookupKnownKeyClass :: KnownKey -> TcM Class - See GHC.Tc.Gen.Default.tcDefaultDecls + * For type-class defauting GHC has built-in defaulting behaviour + for Num, IsString, etc. It gets hold of these classes via their known key, via + tcLookupKnownKeyClass :: KnownKey -> TcM Class + See GHC.Tc.Gen.Default.tcDefaultDecls. + +* KNOWN_OCC. We use a known-occ entity when we just want to /refer/ to the thing in, + say, the code generated for a `deriving` clause. Here is why GHC might want to + refer to a known-occ entity: + + * When desugaring a Template Haskell quotation, in GHC.HsToCore.Quote, GHC + must generate Core that mentions a myriad of functions defined in + ghc-internal:GHC.Internal.TH.Lib, such as `varE`, `conE`, `funD`, etc etc. + They don't need a fixed /unique/, but we still need to find them, so we use + their /OccName/. They are "known-occ" entities. + + To do the lookup it uses + dsLookupKnownOccId :: KnownOcc -> DsM TyThing + + * When dealing with `deriving` clauses, GHC generates (LHsBinds GhcPs) bindings, + and then renames and typechecks them. These bindings refer to a myriad of + identifiers, such as `(==)`, `(>)`, `inRange`, and so on. Again GHC does not + need to know a statically-known unique for them, but it does need to find them + so it uses known + + * When desugaring, the desugarer wants to refer to a particular + class, type, or function. It does this via (e.g.) + dsLookupKnownOccTyCon :: KnownOcc -> DsM TyCon + or + dsLookupKnownKeyTyCon :: KnownKey -> DsM TyCon + It doesn't really matter which we use. To implement all this, here are the moving parts: +* INVARIANT (KnownEntityInvariant): It is a requirement that all known-key and known-occ + entities have distinct OccNames. We could have multiple name-spaces, but in practice + this is not an onerous restriction. But see Note [Tricky known-occ cases] in + GHC.Builtin.KnownOccs for some awkward cases. + * Each known-key name has a /statically-chosen/ unique, fixed in GHC.Builtin.KnownKeys. e.g. eqClassKey :: KnownKey eqClassKey = mkPreludeClassUnique 3 * All the known-key names are gathered in one table: - knownKeyTable :: [(OccName, KnownKey)] + knownKeyTable :: [(KnownOcc, KnownKey)] knownKeyTable = [ (mkTcOcc "Rational", rationalTyConKey) , (mkTcOcc "Eq", eqClassKey) ... etc ... ] - INVARIANT (KnownKeyInvariant): It is a requirement that all known-key names - have distinct OccNames. (We could have multiple name-spaces, but in practice - this is not an onerous restriction.) - -* Because of (KnownKeyInvariant) we can turn that table into two mappings: +* Because of (KnownEntityInvariant) we can turn that table into two mappings: knownKeyOccMap :: OccEnv KnownKey knownKeyOccMap = mkOccEnv knownKeyTable - knownKeyUniqMap :: UniqFM KnownKey OccName + knownKeyUniqMap :: UniqFM KnownKey KnownOcc -* A new module `base:GHC.KnownKeyNames` exports all the known-key names. +* A special module `base:GHC.KnownKeyNames` exports all the known-key names. There is nothing special about this module except that GHC knows its name and can import it. In effect, the `mi_exports` of `GHC/KnownKeyNames.hi` tells GHC where each known-key name is defined. - This is one reason for (KnownKeyInvariant): an export list cannot have two + This is a big reason for (KnownEntityInvaroiant): an export list cannot have two entities with the same OccName. * There are three flags that control the treatment of known-key names: @@ -220,17 +231,25 @@ To implement all this, here are the moving parts: -fexclude-known-key-define=wombat See wrinkle (KKN2) Details in the following bullets. -* Known-key name lookup (normal case: KKNS_FromModule) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - In normal client code, suppose the desugarer calls `dsLookupKnownKeyTyCon` - on `rationalTyConKey`. Then, in `loadKnownKeyOccMap` +* Known-key or known-occ lookup (normal case: KKNS_FromModule) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + In normal client code, suppose the desugarer calls + dsLookupKnownKeyTyCon rationalTyConKey + or + dsLookupKnownOccTyCon rationalTyConOcc + + Then, in `loadKnownKeyOccMaps` * GHC imports GHC.KnownKeyNames, i.e. looks for `GHC/KnownKeyNames.hi` - * Assuming this is successful, GHC usees its `mi_exports` to builds a mapping - `KnownKeyNameMap` from each known-key unique to the Name of the entity. - * It stashes this map in the `eps_known_keys` field of the ExternalPackageState + + * Assuming this is successful, GHC uses its `mi_exports` to build `KnownKeyNameMaps`, + which has (a) a map from the KnownKey of each known-key entity to its Name + (b) a map from the KnownOcc of each known-occ entity to its Name + + * It stashes these maps in the `eps_known_keys` field of the ExternalPackageState so that it doesn't need to repeat the exercise. - Now it can simplhy look up `rationalTyConKey` in the `eps_known_keys`. Easy! - See `dsLookupKnownKeyName`. + + Now it can simply look up `rationalTyConKey` in the `eps_known_keys`. Easy! + See `GHC.Iface.Load.lookupKnownKeyThing` and `lookupKnownOccThing`. * Known-key name lookup (base case: KKNS_InScope) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -238,14 +257,26 @@ To implement all this, here are the moving parts: GHC.KnownKeyNames has not yet been compiled! Instead, we use whatever is in scope with the desired `OccName`, rather like `-XRebindableSyntax`. - See the `KnownKeyNameSource` argument to `lookupKnownKeyName`. When compiling modules + See the `KnownKeyNameSource` argument to `lookupKnownOccThing`. When compiling modules in `ghc-internal` or `base`: + * We switch on -frebindable-known-key-names - * That ensures that we pass `KKNS_InScope` to `lookupKnownKeyName` - * The latter now looks in the GlobalRdrEnv it is passed. - This does mean that in `base` and `ghc-internal` we occasionally need an extra import - to bring into scope some entities that are needed by `dsLookupKnownKeyTyCon` etc. + * That ensures that we pass `KKNS_InScope gbl_rdr_env` to `lookupKnownKeyThing` + + * Suppose we are looking up the known-occ entity `wombat`. The key function is + `lookupKnownGRE`: + * First we look in the `gbl_rdr_env` for the qualified name `Rebindable.wombat`. + If we find a unique hit, choose it. + * Otherwise we look in `gbl_rdr_env` for the /unqualified/ name `wombat`. + If we find a unique hit, choose it. + + This plan means that we can have an unrelated local binding for `wombat` and still + not get confused provided we import Rebindable.wombat. + + This does mean that in `base` and `ghc-internal` we need quite a few extra imports that + look like import GHC.InternalNum as Rebindable + or import qualified GHC.Internal.Num as Rebindable See also wrinkle (KKN1) * Defining known-key names @@ -267,8 +298,13 @@ To implement all this, here are the moving parts: Wrinkles -(KKN1) We need some special treatment of unused-import warnings. - See (UI1) in Note [Unused imports] in GHC.Rename.Names +(KKN1) An import declaration may look entirely unused, if it is there solely to + bring a known-occ name into scope for the desugarer. Why? Becuase we only generate + usage information, to drive unused-import warnings, in the renamer and typechecker. + Not, currently, the desugarer. + + So we simply suppress an unused-import-decl warning if it has a "as Rebindable" + qualifier. See (UI1) in Note [Unused imports] in GHC.Rename.Names (KKN2) The flag `-fdefines-known-key-names` is module-wide. But what if that module happens to define an entity that /isn't/ a known-key entity, but /does/ share the @@ -284,7 +320,7 @@ Wrinkles So we compile GHC.Internal.Data.Foldable with -fexclude-known-key-define=toList -(KKN3) You don't need need to export the wired-in entities from GHC.KnownKeyNames +(KKN3) You don't need need to export wired-in entities from GHC.KnownKeyNames because we (should) never look up a wired-in name via its key. That is, `GHC.Iface.Load.lookupKnownKeyName` should never be called on the key of a wired-in name. @@ -292,8 +328,6 @@ Wrinkles Alternative: export all wired-in entities from GHC.KnownKeyNames. But that would simply bloat the interface for no good reason. -(KKN4) Typeable binds early in tc - Note [Recipe for adding a known-occ name] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To make `wombat` into a known-occ name, you must ensure that: @@ -302,12 +336,15 @@ To make `wombat` into a known-occ name, you must ensure that: * In any module in `base` or `ghc-internal` (which are compiled with -frebindable-known-key-names), in which `wombat` is needed, you must ensure - that `wombat` is in scope by saying `import M( wombat )`. + that `wombat` is in scope by saying `import M( wombat )`, or + import qualified M as Rebindable( wombat ) + + Using the `as Rebindable` qualifier will suppress any unused-import-decl warnings. - You do not need to import the module in which `wombat` is /defined/, although - you may. It is enough simply to bring `wombat` in scope by importing a - module that re-exports. You can even import `GHC.KnownKeyNames`, if that does - not create a module loop! + You do not need to import the precise module in which `wombat` is /defined/, + although you may. It is enough simply to bring `wombat` in scope by importing a + module that re-exports it. You can even import `GHC.KnownKeyNames`, if doing so + does not create a module loop! Note [Recipe for adding a known-key name] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -329,17 +366,9 @@ To make `wombat` into a known-key name, you must ensure that: entry for `wombat` (mkVarOcc "wombat", wombatKey) -* In any module in `base` or `ghc-internal` (which are compiled with - -frebindable-known-key-names), you must ensure that `wombat` is in scope - by saying `import M( wombat )`. - - If you just say `import M` you may get a "unused import" warning; that - warning is suppressed for known-key names if you import `wombat` by name. - - You do not need to import the module in which `wombat` is /defined/, although - you may. It is enough simply to bring `wombat` in scope by importing a - module that re-exports. You can even import `GHC.KnownKeyNames`, if that does - not create a module loop! +* Just like known-occ names, above in any module in `base` or `ghc-internal` (which + are compiled with -frebindable-known-key-names), you must ensure that `wombat` is + in scope by saying `import M( wombat )`. -} allKnownOccs :: OccSet ===================================== compiler/GHC/Builtin/KnownKeys.hs ===================================== @@ -219,7 +219,6 @@ knownKeyTable -- Class Functor , (mkTcOcc "Functor", functorClassKey) , (mkVarOcc "fmap", fmapClassOpKey) - , (mkVarOcc "map", mapIdKey) -- Class Monad, MonadFix, MonadZip , (mkTcOcc "Monad", monadClassKey) @@ -254,7 +253,6 @@ knownKeyTable , (mkVarOcc "dataToTag#", dataToTagClassOpKey) -- Lists - , (mkVarOcc "foldr", foldrIdKey) , (mkVarOcc "build", buildIdKey) -- Records ===================================== compiler/GHC/Builtin/KnownOccs.hs ===================================== @@ -43,6 +43,49 @@ mechanisms: to make an ExactOcc RdrName for the thing. We use the latter for known-key things, merely to avoid duplicating knowledge of the KnownOcc +Note [Tricky known-occ cases] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A few known-occ entities are a bit tricky, because ghc-internal has distinct +entities that share the same occ-name. For these, we must be careful to +have the correct one in scope when looking up a known-occ name. + +* Data types involving Fixity. We have + module GHC.Internal.Data.Data where + data Fixity = Infix | Prefix + module GHC.Internal.Generics where + data Fixity = Prefix | Infix Associativity Int + module GHC.Internal.TH.Syntax where + data Fixity = Fixity Int FixityDirection + + Of these, Fixity(Infix,Prefix) from GHC.Internal.Data.Data are the + known-occ entities, used in derived Data instances; the other are not. + +* `prec`: we have + module GHC.Internal.Text.ParserCombinators.ReadPrec where + prec :: Prec -> ReadPrec a -> ReadPrec a + module GHC.Internal.Generics where + prec :: Fixity -> Int + + Of these, the former is the known-occ entity, used in the derived instances + for Read. The latter is not. + +* `foldr`: we have + module GHC.Internal.Data.Foldable where + class Foldable t where + foldr :: (a -> b -> b) -> b -> t a -> b + module GHC.Internal.Base where + foldr :: (a -> b -> b) -> b -> [a] -> b + + This one is particularly annoying because + * We need the Foldable `foldr` to be known-occ so we can refer to it in + derived Foldable instances + * We need the list `foldr` to be known-occ so we can refer to it when + desugaring list comprehensions. + + So we define an alias + module GHC.Internal.Base where + foldrList = foldr + make `foldrList` known-occ, and refer to that in desugaring list comprehensions. -} @@ -107,8 +150,10 @@ rightDataConOcc = mkDataOcc "Right" voidTyConOcc = mkTcOcc "Void" rationalTyConOcc = mkTcOcc "Rational" -composeIdOcc :: KnownOcc -composeIdOcc = mkVarOcc "." +composeIdOcc, mapIdOcc, foldrListIdOcc :: KnownOcc +composeIdOcc = mkVarOcc "." +mapIdOcc = mkVarOcc "map" +foldrListIdOcc = mkVarOcc "foldrList" fromStaticPtrClassOpOcc :: KnownOcc fromStaticPtrClassOpOcc = mkVarOcc "fromStaticPtr" @@ -128,16 +173,9 @@ enumFromToClassOpOcc = mkVarOcc "enumFromTo" enumFromThenToClassOpOcc = mkVarOcc "enumFromThenTo" -- Class Typeable, and functions for constructing `Typeable` dictionaries -someTypeRepTyConOcc - , someTypeRepDataConOcc - , mkTrConOcc - , mkTrAppCheckedOcc - , mkTrFunOcc - , typeRepIdOcc - , typeNatTypeRepOcc - , typeSymbolTypeRepOcc - , typeCharTypeRepOcc - :: KnownOcc +someTypeRepTyConOcc, someTypeRepDataConOcc, mkTrConOcc, mkTrAppCheckedOcc + , mkTrFunOcc, typeRepIdOcc, typeNatTypeRepOcc, typeSymbolTypeRepOcc + , typeCharTypeRepOcc :: KnownOcc someTypeRepTyConOcc = mkTcOcc "SomeTypeRep" someTypeRepDataConOcc = mkDataOcc "SomeTypeRep" typeRepIdOcc = mkVarOcc "typeRep#" @@ -148,21 +186,14 @@ typeNatTypeRepOcc = mkVarOcc "typeNatTypeRep" typeSymbolTypeRepOcc = mkVarOcc "typeSymbolTypeRep" typeCharTypeRepOcc = mkVarOcc "typeCharTypeRep" -typeLitSymbolDataConOcc - , typeLitNatDataConOcc - , typeLitCharDataConOcc - :: KnownOcc +typeLitSymbolDataConOcc, typeLitNatDataConOcc, typeLitCharDataConOcc :: KnownOcc typeLitSymbolDataConOcc = mkDataOcc "TypeLitSymbol" typeLitNatDataConOcc = mkDataOcc "TypeLitNat" typeLitCharDataConOcc = mkDataOcc "TypeLitChar" -trModuleTyConOcc - , trModuleDataConOcc - , trNameSDataConOcc - , trTyConTyConOcc - , trTyConDataConOcc - :: KnownOcc +trModuleTyConOcc, trModuleDataConOcc, trNameSDataConOcc + , trTyConTyConOcc, trTyConDataConOcc :: KnownOcc trModuleTyConOcc = mkTcOcc "Module" trModuleDataConOcc = mkDataOcc "Module" trNameSDataConOcc = mkDataOcc "TrNameS" @@ -170,14 +201,8 @@ trTyConTyConOcc = mkTcOcc "TyCon" trTyConDataConOcc = mkDataOcc "TyCon" -- Typeable representation types -kindRepTyConOcc - , kindRepTyConAppDataConOcc - , kindRepVarDataConOcc - , kindRepAppDataConOcc - , kindRepFunDataConOcc - , kindRepTYPEDataConOcc - , kindRepTypeLitSDataConOcc - :: KnownOcc +kindRepTyConOcc, kindRepTyConAppDataConOcc, kindRepVarDataConOcc, kindRepAppDataConOcc + , kindRepFunDataConOcc, kindRepTYPEDataConOcc, kindRepTypeLitSDataConOcc :: KnownOcc kindRepTyConOcc = mkTcOcc "KindRep" kindRepTyConAppDataConOcc = mkDataOcc "KindRepTyConApp" kindRepVarDataConOcc = mkDataOcc "KindRepVar" @@ -210,20 +235,20 @@ main_RDR_Unqual = mkUnqual varName (fsLit "main") -- We definitely don't want an Orig RdrName, because -- main might, in principle, be imported into module Main - error_RDR :: RdrName error_RDR = knownVarOccRdrName "error" toDyn_RDR :: RdrName toDyn_RDR = knownVarOccRdrName "toDyn" -compose_RDR :: RdrName +compose_RDR, map_RDR :: RdrName compose_RDR = knownOccRdrName composeIdOcc +map_RDR = knownOccRdrName mapIdOcc appE_RDR, lift_RDR, liftTyped_RDR :: RdrName -appE_RDR = knownVarOccRdrName "appE" -lift_RDR = knownVarOccRdrName "lift" -liftTyped_RDR = knownVarOccRdrName "liftTyped" +appE_RDR = knownVarOccRdrName "appE" +lift_RDR = knownVarOccRdrName "lift" +liftTyped_RDR = knownVarOccRdrName "liftTyped" enumFrom_RDR, enumFromTo_RDR, enumFromThen_RDR, enumFromThenTo_RDR :: RdrName enumFrom_RDR = knownOccRdrName enumFromClassOpOcc @@ -420,10 +445,9 @@ ltTag_RDR = nameRdrName ordLTDataConName eqTag_RDR = nameRdrName ordEQDataConName gtTag_RDR = nameRdrName ordGTDataConName -map_RDR, fmap_RDR, replace_RDR, pure_RDR, ap_RDR, liftA2_RDR, foldable_foldr_RDR, +fmap_RDR, replace_RDR, pure_RDR, ap_RDR, liftA2_RDR, foldable_foldr_RDR, foldMap_RDR, null_RDR, all_RDR, traverse_RDR, mempty_RDR, mappend_RDR :: RdrName -map_RDR = knownKeyRdrName mapIdKey fmap_RDR = knownKeyRdrName fmapClassOpKey pure_RDR = knownKeyRdrName pureAClassOpKey ap_RDR = knownKeyRdrName apAClassOpKey ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -37,6 +37,7 @@ import GHC.Driver.DynFlags import GHC.Tc.Utils.TcType import GHC.Builtin.KnownKeys +import GHC.Builtin.KnownOccs import GHC.Builtin.Types import GHC.Builtin.Types.Prim( alphaTyVar ) @@ -129,7 +130,7 @@ dsTransStmt (TransStmt { trS_form = form, trS_stmts = stmts, trS_bndrs = binderM -- Create an unzip function for the appropriate arity and element types and find "map" unzip_stuff' <- mkUnzipBind form from_bndrs_tys - map_id <- dsLookupKnownKeyId mapIdKey + map_id <- dsLookupKnownOccId mapIdOcc -- Generate the expressions to build the grouped list let -- First we apply the grouping function to the inner list @@ -682,7 +683,7 @@ mkFoldrExpr :: Type -- ^ Element type of the list -> CoreExpr -- ^ List expression being folded acress -> DsM CoreExpr mkFoldrExpr elt_ty result_ty c n list = do - foldr_id <- dsLookupKnownKeyId foldrIdKey + foldr_id <- dsLookupKnownOccId foldrListIdOcc return (Var foldr_id `App` Type elt_ty `App` Type result_ty `App` c ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -116,7 +116,7 @@ import GHC.Types.SafeHaskell import GHC.Types.TypeEnv import GHC.Types.Unique.DSet import GHC.Types.Unique.Map( listToUniqMap ) -import GHC.Types.Unique.FM( UniqFM, listToUFM, lookupUFM ) +import GHC.Types.Unique.FM( UniqFM, listToUFM, lookupUFM, elemUFM ) import GHC.Types.SrcLoc import GHC.Types.TyThing import GHC.Types.PkgQual @@ -284,9 +284,12 @@ loadKnownKeyOccMaps cannotFindModule hsc_env kNOWN_KEY_NAMES fr } ; let kk_map :: UniqFM KnownKey Name + -- Domain is just the KnownKeys in the knownKeyTable kk_map = listToUFM [ (getUnique nm, nm) | avail <- mi_exports iface - , nm <- availNames avail ] + , nm <- availNames avail + , let uniq = getUnique nm + , uniq `elemUFM` knownKeyUniqMap ] occ_map :: OccEnv Name occ_map = mkOccEnv [ (nameOccName nm, nm) | avail <- mi_exports iface ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -2029,14 +2029,6 @@ findImportUsage imports used_gres | used = acc -{- ToDo: delete this - -- -frebindable-known-key-names is on, and `n` is a known-key name - -- Then don't warn about an unused import. - -- See (UI2) in Note [Unused imports] - | rebindable_known_key_names - , isKnownKeyName n || nameOccName n `elemOccSet` allKnownOccs - = acc --} | otherwise = UnusedNames (acc_ns `extendNameSet` n) acc_wcs acc_fs where @@ -2210,6 +2202,7 @@ warnUnusedImport :: GlobalRdrEnv -> ImportDeclUsage -> RnM () warnUnusedImport rdr_env (L loc decl, used, unused, unused_wcs) -- Do not warn for 'import M()' + -- See (UI1) in Note [Unused imports] | Just (Exactly, _) <- ideclImportList decl , null unused = return () @@ -2221,8 +2214,7 @@ warnUnusedImport rdr_env (L loc decl, used, unused, unused_wcs) = return () -- Do not warn about import X as Rebindable - -- See Note [Overview of known-key entities] - -- ToDo: write wrinkle + -- See (UI2) in Note [Unused imports] | Just (L _ mod) <- ideclAs decl , mod == rEBINDABLE_MOD_NAME = return () @@ -2405,21 +2397,13 @@ and neither `a` nor `b` is used, we report the entire import decl as unused. We check this by looking at the names that it brings into scope scope; if there are no ununused names, don't report. -This neatly takes into account two things: - (UI1) We don't want to complain about `import M()`, because that is often used to bring - M's /instances/ into scope. - -(UI2) In base:Data.Enum we see - import GHC.Internal.Num( Num ) -- For -frebindable-known-key-names (defaulting) - 'Num' is not mentioned explicity but the import is still required; see KKNS_InScope - in Note [Overview of known-key entities] in GHC.Builtin - - We don't want this import reported at an unused. So `findImportUsage`, when looking - at `import M( x )`, we do /not/ record `x` as "unused" (regardless of whether it is - mentioned in M if - (a) -frebindable-known-key-names is on, and - (b) `x` is a known-key name + M's /instances/ into scope. That is neatly dealt with by the "no unused names" + criterion. + +(UI2) We don't report a decl as unused if it has an `as Rebindable` qualifier. + See (KKN1) in Note [Overview of known-key entities] in GHC.Builtin + Note [Printing minimal imports] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Deriv/Functor.hs ===================================== @@ -1066,7 +1066,7 @@ gen_Traversable_binds loc dit@(DerivInstTys{ dit_rep_tc = tycon where data_cons = getPossibleDataCons tycon tycon_args - traverse_name = L (noAnnSrcSpan loc) traverse_RDR + traverse_name = mkMethBinder loc traverse_RDR -- See Note [EmptyDataDecls with Functor, Foldable, and Traversable] traverse_bind = mkRdrFunBindEC 2 (nlHsApp pure_Expr) ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -2152,14 +2152,11 @@ nlHsCompose :: LHsExpr GhcPs -> LHsExpr GhcPs -> LHsExpr GhcPs nlHsCompose x y = compose_RDR `nlHsApps` [x, y] mkMethBinder :: SrcSpan -> RdrName -> LocatedN RdrName --- The binder for a class method `op` in in an instance decl --- can be /unqualified/, thus --- instance C Int where --- op = ... -- The "op" can be unqualied --- because the renamer looks in the class to find it. Having it --- unqualified reduces the need for it to be in scope -mkMethBinder loc op_rdr - = L (noAnnSrcSpan loc ) (mkRdrUnqual (rdrNameOcc op_rdr)) +-- The binder for a class method `op` in in an `derived` instance decl +-- should be an Exact RdrName, so that the derived instance works even when +-- that method name is not in scope in this module. (Usually, a method must +-- be in scope for you to define it in an instance decl.) +mkMethBinder loc op_rdr = L (noAnnSrcSpan loc ) op_rdr -- | Make a function binding. If no equations are given, produce a function -- with the given arity that produces a stock error. ===================================== compiler/GHC/Tc/Deriv/Generics.hs ===================================== @@ -352,14 +352,14 @@ gk2gkDC Gen1 dc tc_args = Gen1_DC $ assert (isTyVarTy last_dc_inst_univ) mkBindsRep :: DynFlags -> GenericKind -> SrcSpan -> DerivInstTys -> (LHsBinds GhcPs, [LSig GhcPs]) mkBindsRep dflags gk loc dit@(DerivInstTys{dit_rep_tc = tycon}) = (binds, sigs) where - binds = [mkRdrFunBind (mkMethBinder loc' from01_RDR) [from_eqn]] + binds = [mkRdrFunBind from01_bndr [from_eqn]] ++ - [mkRdrFunBind (mkMethBinder loc' to01_RDR) [to_eqn]] + [mkRdrFunBind to01_bndr [to_eqn]] -- See Note [Generics performance tricks] sigs = if gopt Opt_InlineGenericsAggressively dflags || (gopt Opt_InlineGenerics dflags && inlining_useful) - then [inline1 from01_RDR, inline1 to01_RDR] + then [inline1 from01_bndr, inline1 to01_bndr] else [] where inlining_useful @@ -373,7 +373,7 @@ mkBindsRep dflags gk loc dit@(DerivInstTys{dit_rep_tc = tycon}) = (binds, sigs) cons = length datacons max_fields = maximum $ 0 :| map dataConSourceArity datacons - inline1 f = L loc'' . InlineSig noAnn (L loc' f) + inline1 f = L loc'' . InlineSig noAnn f $ alwaysInlinePragma `setInlinePragmaActivation` activeAfter (Phase 1) -- The topmost M1 (the datatype metadata) has the exact same type @@ -386,10 +386,11 @@ mkBindsRep dflags gk loc dit@(DerivInstTys{dit_rep_tc = tycon}) = (binds, sigs) from_matches = [mkHsCaseAlt pat rhs | (pat,rhs) <- from_alts] to_matches = [mkHsCaseAlt pat rhs | (pat,rhs) <- to_alts ] - loc' = noAnnSrcSpan loc loc'' = noAnnSrcSpan loc datacons = tyConDataCons tycon + from01_bndr = mkMethBinder loc from01_RDR + to01_bndr = mkMethBinder loc to01_RDR (from01_RDR, to01_RDR) = case gk of Gen0 -> (from_RDR, to_RDR) Gen1 -> (from1_RDR, to1_RDR) ===================================== libraries/base/src/Control/Applicative.hs ===================================== @@ -63,10 +63,13 @@ import GHC.Internal.Data.Functor ((<$>)) import GHC.Internal.Data.Functor.Const (Const(..)) import GHC.Internal.Data.Typeable (Typeable) import GHC.Internal.Data.Data (Data) - +import GHC.Generics( Generic, Generic1 ) import GHC.Internal.Functor.ZipList (ZipList(..)) -import GHC.Generics -import qualified GHC.KnownKeyNames as Rebindable + +import qualified GHC.Internal.Data.Data as Rebindable +import qualified GHC.Internal.Data.Typeable.Internal as Rebindable +import qualified GHC.Num as Rebindable +import qualified GHC.Generics as Rebindable hiding( Fixity(..) ) -- $setup -- >>> import Prelude ===================================== libraries/base/src/Data/Fixed.hs ===================================== @@ -93,7 +93,7 @@ import Prelude import GHC.Internal.Data.Data import GHC.Internal.TypeLits (KnownNat, natVal) import GHC.Internal.Read -import GHC.Internal.Text.ParserCombinators.ReadPrec( ReadPrec, pfail ) +import GHC.Internal.Text.ParserCombinators.ReadPrec( ReadPrec ) import GHC.Internal.Text.Read.Lex import qualified GHC.Internal.TH.Monad as TH import qualified GHC.Internal.TH.Lift as TH ===================================== libraries/base/src/Data/Semigroup.hs ===================================== @@ -121,7 +121,8 @@ import GHC.Internal.Data.Traversable import GHC.Internal.Data.Semigroup.Internal import GHC.Internal.Control.Monad.Fix import GHC.Internal.Data.Data -import GHC.Generics +import GHC.Generics( Generic, Generic1 ) +import qualified GHC.Generics as Rebindable hiding( Fixity(..) ) import qualified GHC.Internal.List as List import qualified GHC.KnownKeyNames as Rebindable ===================================== libraries/base/src/GHC/KnownKeyNames.hs ===================================== @@ -14,16 +14,16 @@ module GHC.KnownKeyNames ( Eq(..), Ord(..) -- With their methods , Show, Read - -- Foldable/Traversable with their methods - , Foldable, foldMap, null, all - , Traversable, traverse + -- Foldable/Traversable with those methods need for deriving + , Foldable(foldr, foldMap, null), all + , Traversable(traverse) , Functor, fmap, (<$) , Monad, (>>), (>>=), return, fail, guard, mfix, join , Alternative -- Misc - , (.), (&&), not, map, foldr, build + , (.), (&&), not, foldrList, build, map , seq# -- Applicative @@ -47,7 +47,7 @@ module GHC.KnownKeyNames , Ix, range, inRange, index, unsafeIndex, unsafeRangeSize -- Data - , Data + , Data, Fixity(Prefix,Infix) , gfoldl, gunfold, toConstr, dataTypeOf, dataCast1, dataCast2 , mkConstrTag, Constr, mkDataType, DataType, constrIndex @@ -59,9 +59,8 @@ module GHC.KnownKeyNames , Generic(..), Generic1(..) , Datatype(..), Constructor(..), Selector(..) , U1(..), Par1(..), Rec1(..), K1(..), M1(..) - , (:+:)(L1, R1), (:*:)((:*:)) - , Comp1(..) - , UAddr(..), UChar(..), UDouble(..), UFloat(..), UInt(..), UWord(..) + , (:+:)(L1, R1), (:*:)((:*:)), (:.:)(Comp1, unComp1) + , UAddr, UChar, UDouble, UFloat, UInt, UWord -- DataToTag , DataToTag @@ -196,7 +195,7 @@ module GHC.KnownKeyNames , Clause, clause ) where -import GHC.Internal.Base +import GHC.Internal.Base hiding( foldr ) import GHC.Internal.Show import GHC.Internal.Read import GHC.Internal.Num @@ -209,7 +208,7 @@ import GHC.Internal.Data.Dynamic( toDyn ) import GHC.Internal.Data.Data import GHC.Internal.Data.String( fromString ) import GHC.Internal.Data.Either( Either(..) ) -import GHC.Internal.Data.Foldable( Foldable, foldMap, null, all ) +import GHC.Internal.Data.Foldable( Foldable(..), null, all ) import GHC.Internal.Data.Traversable( Traversable, traverse ) import GHC.Internal.Float( RealFloat ) import GHC.Internal.IO( seq# ) @@ -226,8 +225,6 @@ import qualified GHC.Internal.IsList as IL import GHC.Internal.Err( error ) import GHC.Internal.Int( Int8(I8#), Int16(I16#), Int32(I32#), Int64(I64#) ) import GHC.Internal.Word( Word8(W8#), Word16(W16#), Word32(W32#), Word64(W64#) ) -import GHC.Internal.Text.ParserCombinators.ReadPrec( step, reset, prec, pfail, (+++) ) -import GHC.Internal.Text.Read.Lex( Lexeme(Punc, Ident, Symbol) ) import GHC.Internal.Unsafe.Coerce( UnsafeEquality(..), unsafeEqualityProof ) @@ -236,11 +233,18 @@ import GHC.Internal.StaticPtr.Internal( makeStatic ) import GHC.Internal.Data.Typeable( gcast1, gcast2 ) import GHC.Internal.Data.Typeable.Internal as TR -import GHC.Internal.Generics +import GHC.Internal.Generics( Generic(..), Generic1(..), Datatype(..) + , Constructor(..), Selector(..) + , U1(..), Par1(..), Rec1(..), K1(..), M1(..) + , (:+:)(..), (:*:)(..), (:.:)(..) + , UAddr, UChar, UDouble + , UFloat, UInt, UWord + ) import GHC.Internal.Bignum.BigNat -import GHC.Internal.TH.Syntax as TH -import GHC.Internal.TH.Lib hiding( InjectivityAnn, Role ) +import GHC.Internal.TH.Syntax as TH hiding( Fixity(..) ) + -- hiding(Fixity) see Note [Tricky known-occ cases] in GHC.Builtin.KnownOccs +import GHC.Internal.TH.Lib import GHC.Internal.TH.Lift import GHC.Internal.TH.Monad ===================================== libraries/ghc-internal/src/GHC/Internal/Base.hs ===================================== @@ -1819,6 +1819,12 @@ foldr k z = go go [] = z go (y:ys) = y `k` go ys + +foldrList :: (a -> b -> b) -> b -> [a] -> b +-- An alias for `foldr`, used only internally +-- See Note [Tricky known-occ cases] in GHC.Builtin.KnownOccs +foldrList = foldr + -- | A list producer that can be fused with 'foldr'. -- This function is merely -- ===================================== libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs ===================================== @@ -83,7 +83,8 @@ import GHC.Internal.Numeric import GHC.Internal.Ptr import GHC.Internal.Unsafe.Coerce import GHC.Internal.Stack (HasCallStack) -import qualified GHC.Internal.Data.Foldable as Rebindable +import qualified GHC.Internal.Data.Foldable as Rebindable +import qualified GHC.Internal.Data.Traversable as Rebindable ------------------------------------------------------------------------ -- Boxes ===================================== libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs ===================================== @@ -19,10 +19,8 @@ -- is safe to break things. module GHC.Internal.TH.Lib where - -import GHC.Internal.TH.Syntax hiding (Role, InjectivityAnn) +import GHC.Internal.TH.Syntax import GHC.Internal.TH.Monad -import qualified GHC.Internal.TH.Syntax as TH #ifdef BOOTSTRAP_TH import Control.Applicative(liftA, Applicative(..)) @@ -94,10 +92,6 @@ type PatSynArgsQ = Q PatSynArgs type FamilyResultSigQ = Q FamilyResultSig type DerivStrategyQ = Q DerivStrategy --- must be defined here for DsMeta to find it -type Role = TH.Role -type InjectivityAnn = TH.InjectivityAnn - type TyVarBndrUnit = TyVarBndr () type TyVarBndrSpec = TyVarBndr Specificity type TyVarBndrVis = TyVarBndr BndrVis @@ -974,7 +968,7 @@ tyVarSig = fmap TyVarSig -- * Injectivity annotation injectivityAnn :: Name -> [Name] -> InjectivityAnn -injectivityAnn = TH.InjectivityAnn +injectivityAnn = InjectivityAnn ------------------------------------------------------------------------------- -- * Role ===================================== libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs ===================================== @@ -33,7 +33,7 @@ import GHC.Internal.Base as Rebindable hiding( Type ) import GHC.Internal.TH.Syntax import GHC.Internal.TH.Monad import qualified GHC.Internal.TH.Lib as Lib (litE) -import GHC.Internal.TH.Lib hiding( InjectivityAnn, Role ) +import GHC.Internal.TH.Lib -- For known-key names -- See wrinkle (W4) of Note [Tracking dependencies on primitives] ===================================== libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs ===================================== @@ -42,7 +42,6 @@ import GHC.Ptr ( Ptr, plusPtr ) import GHC.Generics ( Generic ) #else -- Compiling with stage1 compiler -import qualified GHC.Internal.Base as Rebindable import GHC.Internal.Base hiding( Type, Module ) import GHC.Internal.Data.Traversable import GHC.Internal.Err (error) @@ -61,7 +60,9 @@ import GHC.Internal.Num import GHC.Internal.IO.Unsafe import GHC.Internal.List (dropWhile, break, replicate, reverse, last) import GHC.Internal.Unicode -import qualified GHC.Internal.Generics as Rebindable hiding( prec ) +import qualified GHC.Internal.Base as Rebindable hiding( foldr ) +import qualified GHC.Internal.Data.Foldable as Rebindable +import qualified GHC.Internal.Generics as Rebindable hiding( prec ) #endif import GHC.Internal.ForeignSrcLang import GHC.Internal.LanguageExtensions View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3dc8d56d948b146a847f15c8015bb8e6... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3dc8d56d948b146a847f15c8015bb8e6... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Simon Peyton Jones (@simonpj)