Simon Peyton Jones pushed to branch wip/spj-reinstallable-base2 at Glasgow Haskell Compiler / GHC
Commits:
-
50ba27b5
by Simon Peyton Jones at 2026-05-11T13:24:29+01:00
9 changed files:
- compiler/GHC/Builtin.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Tc/Instance/Typeable.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Types/LclEnv.hs
- compiler/GHC/Tc/Utils/Env.hs
Changes:
| ... | ... | @@ -243,10 +243,10 @@ How known-occ entities work |
| 243 | 243 | tcLookupKnownOccTyCon :: KnownOcc -> TcM TyCon
|
| 244 | 244 | dsLookupKnownOccTyCon :: KnownOcc -> DsM TyCon
|
| 245 | 245 | |
| 246 | - The first thing we do is to get the `KnownNameSource`, via `getKnownKeySource`.
|
|
| 246 | + The first thing we do is to get the `KnownEntitySource`, via `getKnownKeySource`.
|
|
| 247 | 247 | There are then two cases, covered in the following sections.
|
| 248 | 248 | |
| 249 | -* Known-occ lookup (normal case: KNS_FromModule)
|
|
| 249 | +* Known-occ lookup (normal case: KES_FromModule)
|
|
| 250 | 250 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 251 | 251 | In normal client code, suppose the desugarer calls
|
| 252 | 252 | dsLookupKnownKeyTyCon rationalTyConKey
|
| ... | ... | @@ -267,7 +267,7 @@ How known-occ entities work |
| 267 | 267 | Now it can simply look up `rationalTyConKey` in the `eps_known_keys`. Easy!
|
| 268 | 268 | See `GHC.Iface.Load.lookupKnownKeyThing` and `lookupKnownOccThing`.
|
| 269 | 269 | |
| 270 | -* Known-occ lookup (base case: KNS_InScope)
|
|
| 270 | +* Known-occ lookup (base case: KES_InScope)
|
|
| 271 | 271 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 272 | 272 | We can't follow the above plan when compiling modules in `base` or `ghc-internal` because
|
| 273 | 273 | GHC.Essentials has not yet been compiled! Instead, we use (roughly) whatever is in
|
| ... | ... | @@ -277,7 +277,7 @@ How known-occ entities work |
| 277 | 277 | |
| 278 | 278 | * We switch on -frebindable-known-names
|
| 279 | 279 | |
| 280 | - * That ensures that we pass `KNS_InScope gbl_rdr_env` to `lookupKnownKeyThing`
|
|
| 280 | + * That ensures that we pass `KES_InScope gbl_rdr_env` to `lookupKnownKeyThing`
|
|
| 281 | 281 | |
| 282 | 282 | * Suppose we are looking up the known-occ entity "wombat". The key function is
|
| 283 | 283 | `lookupKnownGRE`:
|
| ... | ... | @@ -366,6 +366,16 @@ Wrinkles |
| 366 | 366 | Alternative: export all wired-in entities from GHC.Essentials. But that
|
| 367 | 367 | would simply bloat the interface for no good reason.
|
| 368 | 368 | |
| 369 | +(KN4) In a KES_InScope record we keep, for the module being compiled
|
|
| 370 | + ke_rdr_env :: GlobalRdrEnv
|
|
| 371 | + ke_gbl_type_env :: TypeEnv
|
|
| 372 | + ke_lcl_type_env :: TcTypeEnv
|
|
| 373 | + We need the latter two to support `tcLookupKnownOccId` and friends. We need both
|
|
| 374 | + the global `TypeEnv` and the local `TcTypeEnv` because during typechecking we
|
|
| 375 | + keeps types and classes in the global type envt, but `Id`s in the local type envt.
|
|
| 376 | + (Ids move to the global type env during zonking; see `zonkTopDecls`.)
|
|
| 377 | + |
|
| 378 | + |
|
| 369 | 379 | Note [Recipe for adding a known-occ name]
|
| 370 | 380 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 371 | 381 | To make `wombat` into a known-occ name, you do the following:
|
| ... | ... | @@ -572,15 +572,16 @@ mkNamePprCtxDs = ds_name_ppr_ctx <$> getGblEnv |
| 572 | 572 | * *
|
| 573 | 573 | ********************************************************************* -}
|
| 574 | 574 | |
| 575 | -dsGetKnownKeySource :: DsM KnownNameSource
|
|
| 575 | +dsGetKnownKeySource :: DsM KnownEntitySource
|
|
| 576 | 576 | dsGetKnownKeySource
|
| 577 | 577 | = do { rebindable_path <- goptM Opt_RebindableKnownNames
|
| 578 | 578 | ; if rebindable_path
|
| 579 | 579 | then do { env <- getGblEnv
|
| 580 | - ; return (KNS_InScope (ds_mod env)
|
|
| 581 | - (ds_gbl_rdr_env env)
|
|
| 582 | - (ds_type_env env)) }
|
|
| 583 | - else return KNS_FromModule }
|
|
| 580 | + ; return (KES_InScope { ke_mod = ds_mod env
|
|
| 581 | + , ke_rdr_env = ds_gbl_rdr_env env
|
|
| 582 | + , ke_gbl_type_env = ds_type_env env
|
|
| 583 | + , ke_lcl_type_env = emptyNameEnv }) }
|
|
| 584 | + else return KES_FromModule }
|
|
| 584 | 585 | |
| 585 | 586 | --------------------------------------
|
| 586 | 587 | -- Lookups for known-occ things
|
| ... | ... | @@ -20,7 +20,7 @@ module GHC.Iface.Load ( |
| 20 | 20 | loadGlobalName,
|
| 21 | 21 | |
| 22 | 22 | -- Known-occ things
|
| 23 | - KnownNameSource(..),
|
|
| 23 | + KnownEntitySource(..),
|
|
| 24 | 24 | lookupKnownKeyThing, lookupKnownKeyName,
|
| 25 | 25 | lookupKnownOccThing, lookupKnownOccName,
|
| 26 | 26 | loadKnownKeyOccMaps, lookupKnownGRE,
|
| ... | ... | @@ -155,24 +155,28 @@ import qualified GHC.Unit.Home.Graph as HUG |
| 155 | 155 | * *
|
| 156 | 156 | ********************************************************************* -}
|
| 157 | 157 | |
| 158 | -data KnownNameSource
|
|
| 159 | - = KNS_InScope Module GlobalRdrEnv TypeEnv
|
|
| 160 | - -- ^ Look up the known-occ name in this GlobalRdrEnv, which
|
|
| 161 | - -- is the top-level scope of the current module.
|
|
| 158 | +data KnownEntitySource -- See Note [Overview of known entities]
|
|
| 159 | + = KES_InScope { ke_mod :: Module
|
|
| 160 | + , ke_rdr_env :: GlobalRdrEnv
|
|
| 161 | + , ke_gbl_type_env :: TypeEnv
|
|
| 162 | + , ke_lcl_type_env :: TcTypeEnv }
|
|
| 163 | + -- ^ Look up the known-occ name in this GlobalRdrEnv/Type, which
|
|
| 164 | + -- reflect the top-level scope of the current module.
|
|
| 162 | 165 | -- This happens when -frebindable-known-name is set, usually when
|
| 163 | - -- we are compiling `ghc-internal` or `base`
|
|
| 166 | + -- we are compiling `ghc-internal` or `base`
|
|
| 167 | + -- Why both global and local type env? See (KN4) in Note [Overview of known entities]
|
|
| 164 | 168 | |
| 165 | - | KNS_FromModule
|
|
| 169 | + | KES_FromModule
|
|
| 166 | 170 | -- ^ Look up the known-occ name in the export list of GHC.Essentials
|
| 167 | 171 | -- This is the "normal path", and happens when -frebindable-known-names
|
| 168 | 172 | -- is /not/ set
|
| 169 | 173 | |
| 170 | -instance Outputable KnownNameSource where
|
|
| 171 | - ppr KNS_FromModule = text "FromModule"
|
|
| 172 | - ppr (KNS_InScope _ rdr_env _) = text "InScope" <> braces (ppr rdr_env)
|
|
| 174 | +instance Outputable KnownEntitySource where
|
|
| 175 | + ppr KES_FromModule = text "FromModule"
|
|
| 176 | + ppr (KES_InScope { ke_rdr_env = rdr_env }) = text "InScope" <> braces (ppr rdr_env)
|
|
| 173 | 177 | |
| 174 | 178 | lookupKnownKeyThing :: HasDebugCallStack
|
| 175 | - => KnownKey -> KnownNameSource
|
|
| 179 | + => KnownKey -> KnownEntitySource
|
|
| 176 | 180 | -> IfM lcl (MaybeErr IfaceMessage TyThing)
|
| 177 | 181 | lookupKnownKeyThing key kk_ns
|
| 178 | 182 | = do { mb_name <- lookupKnownKeyName key kk_ns
|
| ... | ... | @@ -181,13 +185,13 @@ lookupKnownKeyThing key kk_ns |
| 181 | 185 | Succeeded name -> lookupKnownName kk_ns name }
|
| 182 | 186 | |
| 183 | 187 | lookupKnownKeyName :: HasDebugCallStack
|
| 184 | - => KnownKey -> KnownNameSource
|
|
| 188 | + => KnownKey -> KnownEntitySource
|
|
| 185 | 189 | -> IfM lcl (MaybeErr IfaceMessage Name)
|
| 186 | -lookupKnownKeyName key KNS_FromModule
|
|
| 190 | +lookupKnownKeyName key KES_FromModule
|
|
| 187 | 191 | = do { (kk_map, _) <- loadKnownKeyOccMaps
|
| 188 | 192 | ; return $ lookupKnownKeysMap kk_map key }
|
| 189 | 193 | |
| 190 | -lookupKnownKeyName key (KNS_InScope _ gbl_rdr_env _)
|
|
| 194 | +lookupKnownKeyName key (KES_InScope { ke_rdr_env = gbl_rdr_env })
|
|
| 191 | 195 | -- Just gbl_rdr_env: we have -frebindable-known-names on, and
|
| 192 | 196 | -- here is the top-level GlobalRdrEnv
|
| 193 | 197 | -- Look up the /un-qualified/ known-key OccName in the GlobalRdrEnv
|
| ... | ... | @@ -224,7 +228,7 @@ lookupKnownGRE rdr_env occ |
| 224 | 228 | gres = lookupGRE rdr_env (LookupOccName occ SameNameSpace)
|
| 225 | 229 | |
| 226 | 230 | lookupKnownOccThing :: HasDebugCallStack
|
| 227 | - => KnownOcc -> KnownNameSource
|
|
| 231 | + => KnownOcc -> KnownEntitySource
|
|
| 228 | 232 | -> IfM lcl (MaybeErr IfaceMessage TyThing)
|
| 229 | 233 | lookupKnownOccThing occ kk_ns
|
| 230 | 234 | = do { mb_name <- lookupKnownOccName occ kk_ns
|
| ... | ... | @@ -233,15 +237,15 @@ lookupKnownOccThing occ kk_ns |
| 233 | 237 | Succeeded name -> lookupKnownName kk_ns name }
|
| 234 | 238 | |
| 235 | 239 | lookupKnownOccName :: HasDebugCallStack
|
| 236 | - => KnownOcc -> KnownNameSource
|
|
| 240 | + => KnownOcc -> KnownEntitySource
|
|
| 237 | 241 | -> IfM lcl (MaybeErr IfaceMessage Name)
|
| 238 | -lookupKnownOccName occ KNS_FromModule
|
|
| 242 | +lookupKnownOccName occ KES_FromModule
|
|
| 239 | 243 | = do { (_, occ_map) <- loadKnownKeyOccMaps
|
| 240 | 244 | ; case lookupOccEnv occ_map occ of
|
| 241 | 245 | Just name -> return (Succeeded name)
|
| 242 | 246 | Nothing -> return (Failed (MissingKnownKey3 occ)) }
|
| 243 | 247 | |
| 244 | -lookupKnownOccName occ (KNS_InScope _ gbl_rdr_env _)
|
|
| 248 | +lookupKnownOccName occ (KES_InScope { ke_rdr_env = gbl_rdr_env })
|
|
| 245 | 249 | -- Just gbl_rdr_env: we have -frebindable-known-names on, and
|
| 246 | 250 | -- here is the top-level GlobalRdrEnv
|
| 247 | 251 | -- Look up the /un-qualified/ known-occ OccName in the GlobalRdrEnv
|
| ... | ... | @@ -254,20 +258,22 @@ lookupKnownOccName occ (KNS_InScope _ gbl_rdr_env _) |
| 254 | 258 | Failed err -> return (Failed err)
|
| 255 | 259 | |
| 256 | 260 | lookupKnownName :: HasDebugCallStack
|
| 257 | - => KnownNameSource -> Name
|
|
| 261 | + => KnownEntitySource -> Name
|
|
| 258 | 262 | -> IfM lcl (MaybeErr IfaceMessage TyThing)
|
| 259 | 263 | -- Go from a known Name to its TyThing
|
| 260 | --- If we are in KNS_InScope, look up in the current module's type environment
|
|
| 264 | +-- If we are in KES_InScope, look up in the current module's type environment
|
|
| 261 | 265 | -- in case it is defined right here in this module rather than imported
|
| 262 | 266 | lookupKnownName kk_ns name
|
| 263 | 267 | = case kk_ns of
|
| 264 | - KNS_InScope this_mod _ type_env
|
|
| 268 | + KES_InScope { ke_mod = this_mod, ke_gbl_type_env = type_env, ke_lcl_type_env = lcl_type_env }
|
|
| 265 | 269 | | name_mod == this_mod
|
| 266 | - -> case lookupTypeEnv type_env name of
|
|
| 267 | - Just thing -> return (Succeeded thing)
|
|
| 268 | - Nothing -> pprPanic "lookupKnownName" (ppr name $$ ppr type_env)
|
|
| 269 | - -- We found the name in the GlobalRdrEnv, but it's
|
|
| 270 | - -- not in the type env. That's a compiler error
|
|
| 270 | + -> case lookupNameEnv lcl_type_env name of
|
|
| 271 | + Just (ATcId { tct_id = id }) -> return (Succeeded (AnId id))
|
|
| 272 | + _ -> case lookupTypeEnv type_env name of
|
|
| 273 | + Just thing -> return (Succeeded thing)
|
|
| 274 | + Nothing -> pprPanic "lookupKnownName" (ppr name $$ ppr type_env)
|
|
| 275 | + -- We found the name in the GlobalRdrEnv, but it's
|
|
| 276 | + -- not in the type env. That's a compiler error
|
|
| 271 | 277 | |
| 272 | 278 | _ -> loadGlobalName name name_mod
|
| 273 | 279 | where
|
| ... | ... | @@ -983,7 +983,7 @@ mk_top_id (IfGblTopBndr gbl_name) |
| 983 | 983 | -- rather than the current module so we need this special case.
|
| 984 | 984 | -- See some similar logic in `GHC.Rename.Env`.
|
| 985 | 985 | | Just rOOT_MAIN == nameModule_maybe gbl_name
|
| 986 | - = lookupKnownOccThing ioTyConOcc KNS_FromModule >>= \case
|
|
| 986 | + = lookupKnownOccThing ioTyConOcc KES_FromModule >>= \case
|
|
| 987 | 987 | Failed err -> failIfM (pprDiagnostic err)
|
| 988 | 988 | Succeeded ioTyThing -> do
|
| 989 | 989 | ATyCon ioTyCon <- pure ioTyThing
|
| ... | ... | @@ -1041,16 +1041,16 @@ rnLookupKnownOccName occ |
| 1041 | 1041 | Succeeded name -> return name }
|
| 1042 | 1042 | |
| 1043 | 1043 | lookup_known_occ :: HasDebugCallStack
|
| 1044 | - => KnownNameSource -> KnownOcc
|
|
| 1044 | + => KnownEntitySource -> KnownOcc
|
|
| 1045 | 1045 | -> RnM (MaybeErr IfaceMessage Name)
|
| 1046 | -lookup_known_occ KNS_FromModule occ
|
|
| 1046 | +lookup_known_occ KES_FromModule occ
|
|
| 1047 | 1047 | = do { (_, occ_map) <- initIfaceTcRn loadKnownKeyOccMaps
|
| 1048 | 1048 | ; case lookupOccEnv occ_map occ of
|
| 1049 | 1049 | Just name -> return (Succeeded name)
|
| 1050 | 1050 | Nothing -> return (Failed (MissingKnownKey3 occ)) }
|
| 1051 | 1051 | |
| 1052 | -lookup_known_occ (KNS_InScope _ gbl_rdr_env _) occ
|
|
| 1053 | - = case lookupKnownGRE gbl_rdr_env occ of
|
|
| 1052 | +lookup_known_occ (KES_InScope { ke_rdr_env = rdr_env }) occ
|
|
| 1053 | + = case lookupKnownGRE rdr_env occ of
|
|
| 1054 | 1054 | Succeeded gre -> do { addUsedGRE NoDeprecationWarnings gre
|
| 1055 | 1055 | ; let name = greName gre
|
| 1056 | 1056 | ; traceIf $ hang (text "lookupKnownKeyOcc NoImplicitKnownKeyNames")
|
| ... | ... | @@ -22,7 +22,6 @@ import GHC.Tc.Utils.TcType |
| 22 | 22 | import GHC.Iface.Env( newGlobalBinder )
|
| 23 | 23 | |
| 24 | 24 | import GHC.Builtin.Modules( gHC_TYPES, gHC_PRIM )
|
| 25 | -import GHC.Builtin.KnownKeys
|
|
| 26 | 25 | import GHC.Builtin.KnownOccs
|
| 27 | 26 | import GHC.Builtin.WiredIn.Prim ( primTyCons )
|
| 28 | 27 | import GHC.Builtin.WiredIn.Types
|
| ... | ... | @@ -645,12 +644,12 @@ liftTc = KindRepM . lift |
| 645 | 644 | -- | We generate `KindRep`s for a few common kinds, so that they
|
| 646 | 645 | -- can be reused across modules.
|
| 647 | 646 | -- These definitions are generated in `ghc-prim:GHC.Types`.
|
| 648 | -builtInKindReps :: [(Kind, Name)]
|
|
| 647 | +builtInKindReps :: [(Kind, KnownOcc)]
|
|
| 649 | 648 | builtInKindReps =
|
| 650 | - [ (star, starKindRepName)
|
|
| 651 | - , (constraintKind, constraintKindRepName)
|
|
| 652 | - , (mkVisFunTyMany star star, starArrStarKindRepName)
|
|
| 653 | - , (mkVisFunTysMany [star, star] star, starArrStarArrStarKindRepName)
|
|
| 649 | + [ (star, mkVarOcc "krepStar")
|
|
| 650 | + , (constraintKind, mkVarOcc "krepConstraint")
|
|
| 651 | + , (mkVisFunTyMany star star, mkVarOcc "krepStarArr")
|
|
| 652 | + , (mkVisFunTysMany [star, star] star, mkVarOcc "krepStarArrStarArr")
|
|
| 654 | 653 | ]
|
| 655 | 654 | where
|
| 656 | 655 | star = liftedTypeKind
|
| ... | ... | @@ -658,8 +657,8 @@ builtInKindReps = |
| 658 | 657 | initialKindRepEnv :: TcRn KindRepEnv
|
| 659 | 658 | initialKindRepEnv = foldlM add_kind_rep emptyTypeMap builtInKindReps
|
| 660 | 659 | where
|
| 661 | - add_kind_rep acc (k,n) = do
|
|
| 662 | - id <- tcLookupId n
|
|
| 660 | + add_kind_rep acc (k,occ) = do
|
|
| 661 | + id <- tcLookupKnownOccId occ
|
|
| 663 | 662 | return $! extendTypeMap acc k (id, Nothing)
|
| 664 | 663 | -- The TypeMap looks through type synonyms
|
| 665 | 664 |
| ... | ... | @@ -578,7 +578,7 @@ tcRnSrcDecls explicit_mod_hdr export_ies decls |
| 578 | 578 | ; return (tcg_env `addEvBinds` ev_binds) }
|
| 579 | 579 | |
| 580 | 580 | -- Emit Typeable bindings
|
| 581 | - ; tcg_env <- setGblEnv tcg_env $
|
|
| 581 | + ; tcg_env <- restoreEnvs (tcg_env, tcl_env) $
|
|
| 582 | 582 | mkTypeableBinds
|
| 583 | 583 | |
| 584 | 584 | ; traceTc "Tc9" empty
|
| ... | ... | @@ -122,7 +122,8 @@ data TcLclCtxt |
| 122 | 122 | tcl_arrow_ctxt :: ArrowCtxt, -- Arrow-notation context
|
| 123 | 123 | |
| 124 | 124 | tcl_env :: TcTypeEnv -- The local type environment:
|
| 125 | - -- Ids and TyVars defined in this module
|
|
| 125 | + -- Ids and TyVars defined in this module
|
|
| 126 | + -- They move to the TcGbl env during zonkTopDecls
|
|
| 126 | 127 | }
|
| 127 | 128 | |
| 128 | 129 | getLclEnvThLevel :: TcLclEnv -> ThLevel
|
| ... | ... | @@ -517,19 +517,21 @@ tcMetaTy tc_name |
| 517 | 517 | = do { t <- tcLookupTyCon tc_name
|
| 518 | 518 | ; return (mkTyConTy t) }
|
| 519 | 519 | |
| 520 | -getKnownKeySource :: TcRn KnownNameSource
|
|
| 520 | +getKnownKeySource :: TcRn KnownEntitySource
|
|
| 521 | 521 | -- Used by both renamer and typechecker and renamer
|
| 522 | 522 | getKnownKeySource
|
| 523 | 523 | = do { rebindable_path <- goptM Opt_RebindableKnownNames
|
| 524 | 524 | ; if rebindable_path
|
| 525 | - then do { env <- getGblEnv
|
|
| 526 | - ; return (KNS_InScope (tcg_mod env)
|
|
| 527 | - (tcg_rdr_env env)
|
|
| 528 | - (tcg_type_env env)) }
|
|
| 529 | - else return KNS_FromModule }
|
|
| 525 | + then do { gbl_env <- getGblEnv
|
|
| 526 | + ; lcl_type_env <- getLclTypeEnv
|
|
| 527 | + ; return (KES_InScope { ke_mod = tcg_mod gbl_env
|
|
| 528 | + , ke_rdr_env = tcg_rdr_env gbl_env
|
|
| 529 | + , ke_gbl_type_env = tcg_type_env gbl_env
|
|
| 530 | + , ke_lcl_type_env = lcl_type_env }) }
|
|
| 531 | + else return KES_FromModule }
|
|
| 530 | 532 | |
| 531 | 533 | tcrn_wrapper :: HasDebugCallStack
|
| 532 | - => (KnownNameSource -> IfG (MaybeErr IfaceMessage a)) -> TcRn a
|
|
| 534 | + => (KnownEntitySource -> IfG (MaybeErr IfaceMessage a)) -> TcRn a
|
|
| 533 | 535 | tcrn_wrapper do_the_lookup
|
| 534 | 536 | = do { kk_source <- getKnownKeySource
|
| 535 | 537 | ; mb_res <- initIfaceTcRn (do_the_lookup kk_source)
|