Simon Peyton Jones pushed to branch wip/spj-reinstallable-base2 at Glasgow Haskell Compiler / GHC
Commits:
-
eae15e45
by Simon Peyton Jones at 2026-04-17T12:55:28+01:00
13 changed files:
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Env/Types.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Types.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Tc/Instance/Typeable.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Monad.hs
Changes:
| ... | ... | @@ -178,16 +178,16 @@ configured via command-line flags (in `GHC.setTopSessionDynFlags`). |
| 178 | 178 | |
| 179 | 179 | -- Note [hsc_type_env_var hack]
|
| 180 | 180 | -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 181 | --- hsc_type_env_var is used to initialize tcg_type_env_var, and
|
|
| 181 | +-- hsc_type_env_var is used to initialize tcg_knot_vars, and
|
|
| 182 | 182 | -- eventually it is the mutable variable that is queried from
|
| 183 | 183 | -- if_rec_types to get a TypeEnv. So, clearly, it's something
|
| 184 | 184 | -- related to knot-tying (see Note [Tying the knot]).
|
| 185 | 185 | -- hsc_type_env_var is used in two places: initTcRn (where
|
| 186 | --- it initializes tcg_type_env_var) and initIfaceCheck
|
|
| 186 | +-- it initializes tcg_knot_vars) and initIfaceCheck
|
|
| 187 | 187 | -- (where it initializes if_rec_types).
|
| 188 | 188 | --
|
| 189 | 189 | -- But why do we need a way to feed a mutable variable in? Why
|
| 190 | --- can't we just initialize tcg_type_env_var when we start
|
|
| 190 | +-- can't we just initialize tcg_knot_vars when we start
|
|
| 191 | 191 | -- typechecking? The problem is we need to knot-tie the
|
| 192 | 192 | -- EPS, and we may start adding things to the EPS before type
|
| 193 | 193 | -- checking starts.
|
| ... | ... | @@ -83,8 +83,8 @@ data HscEnv |
| 83 | 83 | |
| 84 | 84 | hsc_type_env_vars :: KnotVars (IORef TypeEnv)
|
| 85 | 85 | -- ^ Used for one-shot compilation only, to initialise
|
| 86 | - -- the 'IfGblEnv'. See 'GHC.Tc.Utils.tcg_type_env_var' for
|
|
| 87 | - -- 'GHC.Tc.Utils.TcGblEnv'. See also Note [hsc_type_env_var hack]
|
|
| 86 | + -- the 'IfGblEnv'. See 'tcg_knot_vars' in 'GHC.Tc.Utils.TcGblEnv'.
|
|
| 87 | + -- See also Note [hsc_type_env_var hack]
|
|
| 88 | 88 | |
| 89 | 89 | , hsc_interp :: Maybe Interp
|
| 90 | 90 | -- ^ target code interpreter (if any) to use for TH and GHCi.
|
| ... | ... | @@ -731,7 +731,7 @@ runHscPhase pipe_env hsc_env0 input_fn src_flavour = do |
| 731 | 731 | mg <- downsweepThunk hsc_env mod_summary
|
| 732 | 732 | |
| 733 | 733 | -- Need to set the knot-tying mutable variable for interface
|
| 734 | - -- files. See GHC.Tc.Utils.TcGblEnv.tcg_type_env_var.
|
|
| 734 | + -- files. See GHC.Tc.Utils.TcGblEnv.tcg_knot_vars
|
|
| 735 | 735 | -- See also Note [hsc_type_env_var hack]
|
| 736 | 736 | type_env_var <- newIORef emptyNameEnv
|
| 737 | 737 | let hsc_env' =
|
| ... | ... | @@ -578,8 +578,10 @@ dsGetKnownKeySource :: DsM KnownKeyNameSource |
| 578 | 578 | dsGetKnownKeySource
|
| 579 | 579 | = do { rebindable_path <- goptM Opt_RebindableKnownKeyNames
|
| 580 | 580 | ; if rebindable_path
|
| 581 | - then do { rdr_env <- dsGetGlobalRdrEnv
|
|
| 582 | - ; return (KKNS_InScope rdr_env) }
|
|
| 581 | + then do { env <- getGblEnv
|
|
| 582 | + ; return (KKNS_InScope (ds_mod env)
|
|
| 583 | + (ds_gbl_rdr_env env)
|
|
| 584 | + (ds_type_env env)) }
|
|
| 583 | 585 | else return KKNS_FromModule }
|
| 584 | 586 | |
| 585 | 587 | --------------------------------------
|
| ... | ... | @@ -59,12 +59,14 @@ presumably include source-file location information: |
| 59 | 59 | data DsGblEnv
|
| 60 | 60 | = DsGblEnv
|
| 61 | 61 | { ds_mod :: Module -- For SCC profiling
|
| 62 | - , ds_fam_inst_env :: FamInstEnv -- Like tcg_fam_inst_env
|
|
| 63 | 62 | , ds_gbl_rdr_env :: GlobalRdrEnv
|
| 64 | 63 | -- The GlobalRdrEnv is needed for the following reasons:
|
| 65 | 64 | -- - to know what newtype constructors are in scope
|
| 66 | 65 | -- - to check whether all members of a COMPLETE pragma are in scope
|
| 67 | 66 | -- - when looking up know-key names
|
| 67 | + , ds_fam_inst_env :: FamInstEnv -- Like tcg_fam_inst_env
|
|
| 68 | + , ds_type_env :: TypeEnv -- Like tcg_type_enb
|
|
| 69 | + |
|
| 68 | 70 | , ds_name_ppr_ctx :: NamePprCtx
|
| 69 | 71 | , ds_msgs :: IORef (Messages DsMessage) -- Diagnostic messages
|
| 70 | 72 | , ds_if_env :: (IfGblEnv, IfLclEnv) -- Used for looking up global,
|
| ... | ... | @@ -155,7 +155,7 @@ import qualified GHC.Unit.Home.Graph as HUG |
| 155 | 155 | ********************************************************************* -}
|
| 156 | 156 | |
| 157 | 157 | data KnownKeyNameSource
|
| 158 | - = KKNS_InScope GlobalRdrEnv
|
|
| 158 | + = KKNS_InScope Module GlobalRdrEnv TypeEnv
|
|
| 159 | 159 | -- Look up the known-key name in this GlobalRdrEnv, which
|
| 160 | 160 | -- is the top-level scope of the current module.
|
| 161 | 161 | -- This happens when -frebindable-known-key-name is set, usually when
|
| ... | ... | @@ -167,17 +167,17 @@ data KnownKeyNameSource |
| 167 | 167 | -- is /not/ set
|
| 168 | 168 | |
| 169 | 169 | instance Outputable KnownKeyNameSource where
|
| 170 | - ppr KKNS_FromModule = text "FromModule"
|
|
| 171 | - ppr (KKNS_InScope env) = text "InScope" <> braces (ppr env)
|
|
| 170 | + ppr KKNS_FromModule = text "FromModule"
|
|
| 171 | + ppr (KKNS_InScope mod rdr_env type_env) = text "InScope" <> braces (ppr rdr_env)
|
|
| 172 | 172 | |
| 173 | 173 | lookupKnownKeyThing :: HasDebugCallStack
|
| 174 | 174 | => KnownKey -> KnownKeyNameSource
|
| 175 | 175 | -> IfM lcl (MaybeErr IfaceMessage TyThing)
|
| 176 | -lookupKnownKeyThing key mb_gbl_rdr_env
|
|
| 177 | - = do { mb_name <- lookupKnownKeyName key mb_gbl_rdr_env
|
|
| 176 | +lookupKnownKeyThing key kk_ns
|
|
| 177 | + = do { mb_name <- lookupKnownKeyName key kk_ns
|
|
| 178 | 178 | ; case mb_name of
|
| 179 | 179 | Failed err -> return (Failed err)
|
| 180 | - Succeeded name -> lookupGlobalName name }
|
|
| 180 | + Succeeded name -> lookupKnownName kk_ns name }
|
|
| 181 | 181 | |
| 182 | 182 | lookupKnownKeyName :: HasDebugCallStack
|
| 183 | 183 | => KnownKey -> KnownKeyNameSource
|
| ... | ... | @@ -199,7 +199,7 @@ lookupKnownKeyName key KKNS_FromModule |
| 199 | 199 | | otherwise
|
| 200 | 200 | -> return (Failed (MissingKnownKey1 key)) }
|
| 201 | 201 | |
| 202 | -lookupKnownKeyName key (KKNS_InScope gbl_rdr_env)
|
|
| 202 | +lookupKnownKeyName key (KKNS_InScope _ gbl_rdr_env _)
|
|
| 203 | 203 | -- Just gbl_rdr_env: we have -frebindable-known-key-names on, and
|
| 204 | 204 | -- here is the top-level GlobalRdrEnv
|
| 205 | 205 | -- Look up the /un-qualified/ known-key OccName in the GlobalRdrEnv
|
| ... | ... | @@ -238,11 +238,11 @@ lookupKnownGRE rdr_env occ |
| 238 | 238 | lookupKnownOccThing :: HasDebugCallStack
|
| 239 | 239 | => KnownOcc -> KnownKeyNameSource
|
| 240 | 240 | -> IfM lcl (MaybeErr IfaceMessage TyThing)
|
| 241 | -lookupKnownOccThing occ mb_gbl_rdr_env
|
|
| 242 | - = do { mb_name <- lookupKnownOccName occ mb_gbl_rdr_env
|
|
| 241 | +lookupKnownOccThing occ kk_ns
|
|
| 242 | + = do { mb_name <- lookupKnownOccName occ kk_ns
|
|
| 243 | 243 | ; case mb_name of
|
| 244 | 244 | Failed err -> return (Failed err)
|
| 245 | - Succeeded name -> lookupGlobalName name }
|
|
| 245 | + Succeeded name -> lookupKnownName kk_ns name }
|
|
| 246 | 246 | |
| 247 | 247 | lookupKnownOccName :: HasDebugCallStack
|
| 248 | 248 | => KnownOcc -> KnownKeyNameSource
|
| ... | ... | @@ -253,7 +253,7 @@ lookupKnownOccName occ KKNS_FromModule |
| 253 | 253 | Just name -> return (Succeeded name)
|
| 254 | 254 | Nothing -> return (Failed (MissingKnownKey3 occ)) }
|
| 255 | 255 | |
| 256 | -lookupKnownOccName occ (KKNS_InScope gbl_rdr_env)
|
|
| 256 | +lookupKnownOccName occ (KKNS_InScope _ gbl_rdr_env _)
|
|
| 257 | 257 | -- Just gbl_rdr_env: we have -frebindable-known-key-names on, and
|
| 258 | 258 | -- here is the top-level GlobalRdrEnv
|
| 259 | 259 | -- Look up the /un-qualified/ known-key OccName in the GlobalRdrEnv
|
| ... | ... | @@ -265,6 +265,24 @@ lookupKnownOccName occ (KKNS_InScope gbl_rdr_env) |
| 265 | 265 | ; return (Succeeded name) }
|
| 266 | 266 | Failed err -> return (Failed err)
|
| 267 | 267 | |
| 268 | +lookupKnownName :: HasDebugCallStack
|
|
| 269 | + => KnownKeyNameSource -> Name
|
|
| 270 | + -> IfM lcl (MaybeErr IfaceMessage TyThing)
|
|
| 271 | +-- Go from a known Name to its TyThing
|
|
| 272 | +-- If we are in KKNS_InScope, look up in the current module's type environment
|
|
| 273 | +-- in case it is defined right here in this module rather than imported
|
|
| 274 | +lookupKnownName kk_ns name
|
|
| 275 | + = case kk_ns of
|
|
| 276 | + KKNS_InScope this_mod _ type_env
|
|
| 277 | + | name_mod == this_mod
|
|
| 278 | + -> case lookupTypeEnv type_env name of
|
|
| 279 | + Just thing -> return (Succeeded thing)
|
|
| 280 | + Nothing -> return (Failed ...)
|
|
| 281 | + |
|
| 282 | + _ -> loadGlobalName name name_mod
|
|
| 283 | + where
|
|
| 284 | + name_mod = nameModule name
|
|
| 285 | + |
|
| 268 | 286 | loadKnownKeyOccMaps :: IfM lcl KnownKeyNameMaps
|
| 269 | 287 | loadKnownKeyOccMaps
|
| 270 | 288 | = do { eps <- getEps
|
| ... | ... | @@ -331,16 +349,12 @@ checkKnownKeyNamesIface known_key_names_occ_map |
| 331 | 349 | * *
|
| 332 | 350 | ********************************************************************* -}
|
| 333 | 351 | |
| 334 | -lookupGlobalName :: HasDebugCallStack
|
|
| 335 | - => Name -> IfM lcl (MaybeErr IfaceMessage TyThing)
|
|
| 336 | --- Only works for External Names that have a Module
|
|
| 337 | -lookupGlobalName name = loadGlobalName name (nameModule name)
|
|
| 338 | - |
|
| 339 | 352 | loadGlobalName :: forall lcl.
|
| 340 | 353 | HasDebugCallStack
|
| 341 | 354 | => Name
|
| 342 | 355 | -> Module -- Use this for non-External Names (maybe Backpack-related?)
|
| 343 | 356 | -> IfM lcl (MaybeErr IfaceMessage TyThing)
|
| 357 | +-- Only works for External Names that have a Module
|
|
| 344 | 358 | loadGlobalName name mod
|
| 345 | 359 | = do { env <- getGblEnv
|
| 346 | 360 | ; case lookupKnotVars (if_rec_types env) mod of
|
| ... | ... | @@ -357,7 +371,7 @@ loadGlobalName name mod |
| 357 | 371 | ; via_external }
|
| 358 | 372 | }
|
| 359 | 373 | |
| 360 | - _ -> do { traceIf (text "loadGlobalName4" <+> ppr name)
|
|
| 374 | + _ -> do { traceIf (text "loadGlobalName4" <+> ppr name $$ ppr (if_rec_types env) $$ text "stack" <+> callStackDoc)
|
|
| 361 | 375 | ; via_external } }
|
| 362 | 376 | where
|
| 363 | 377 | via_external = do { hsc_env <- getTopEnv
|
| ... | ... | @@ -1049,7 +1049,7 @@ lookup_known_occ KKNS_FromModule occ |
| 1049 | 1049 | Just name -> return (Succeeded name)
|
| 1050 | 1050 | Nothing -> return (Failed (MissingKnownKey3 occ)) }
|
| 1051 | 1051 | |
| 1052 | -lookup_known_occ (KKNS_InScope gbl_rdr_env) occ
|
|
| 1052 | +lookup_known_occ (KKNS_InScope _ gbl_rdr_env _) occ
|
|
| 1053 | 1053 | = case lookupKnownGRE gbl_rdr_env occ of
|
| 1054 | 1054 | Succeeded gre -> do { addUsedGRE NoDeprecationWarnings gre
|
| 1055 | 1055 | ; let name = greName gre
|
| ... | ... | @@ -51,6 +51,7 @@ import GHC.Driver.DynFlags |
| 51 | 51 | import GHC.Utils.Fingerprint(Fingerprint(..), fingerprintString, fingerprintFingerprints)
|
| 52 | 52 | import GHC.Utils.Outputable
|
| 53 | 53 | import GHC.Utils.Panic
|
| 54 | +import GHC.Utils.Misc
|
|
| 54 | 55 | import GHC.Data.FastString ( FastString, mkFastString, fsLit )
|
| 55 | 56 | |
| 56 | 57 | import Control.Monad.Trans.State.Strict
|
| ... | ... | @@ -316,7 +317,7 @@ We use it in: |
| 316 | 317 | -- 'tcRnSrcDecls'.
|
| 317 | 318 | --
|
| 318 | 319 | -- See Note [Grand plan for Typeable] in "GHC.Tc.Instance.Typeable".
|
| 319 | -mkTypeableBinds :: TcM TcGblEnv
|
|
| 320 | +mkTypeableBinds :: HasDebugCallStack => TcM TcGblEnv
|
|
| 320 | 321 | mkTypeableBinds
|
| 321 | 322 | = do { dflags <- getDynFlags
|
| 322 | 323 | ; tcg_env <- getGblEnv
|
| ... | ... | @@ -324,6 +325,8 @@ mkTypeableBinds |
| 324 | 325 | tycons_that_need = filter tc_needs_typeable (tcg_tcs tcg_env)
|
| 325 | 326 | -- These tycons will need some typeable bindings
|
| 326 | 327 | |
| 328 | + ; traceTc "mkTypableBinds" (ppr this_mod $$ ppr tycons_that_need $$ callStackDoc)
|
|
| 329 | + |
|
| 327 | 330 | -- Stop now if we don't need any typable bindings
|
| 328 | 331 | -- See (GPT8) in Note [Grand plan for Typeable]
|
| 329 | 332 | ; if no_typeable_binds_needed dflags this_mod tycons_that_need
|
| ... | ... | @@ -332,13 +332,17 @@ tcRnModuleTcRnM hsc_env mod_sum |
| 332 | 332 | ; whenM (goptM Opt_DoCoreLinting) $
|
| 333 | 333 | lintGblEnv (hsc_logger hsc_env) (hsc_dflags hsc_env) tcg_env
|
| 334 | 334 | |
| 335 | + -- Sync the knot-tied type environment before checking
|
|
| 336 | + -- the M.hi-boot interface, if any
|
|
| 337 | + ; syncTypeEnvKnotVars tcg_env
|
|
| 338 | + |
|
| 335 | 339 | ; setGblEnv tcg_env
|
| 336 | 340 | $ do { -- Compare hi-boot iface (if any) with the real thing
|
| 337 | 341 | -- Must be done after processing the exports
|
| 338 | 342 | tcg_env <- checkHiBootIface tcg_env boot_info
|
| 339 | 343 | ; -- The new type env is already available to stuff
|
| 340 | - -- slurped from interface files, via
|
|
| 341 | - -- GHC.Tc.Utils.Env.setGlobalTypeEnv. It's important that this
|
|
| 344 | + -- slurped from interface files, via syncTypeEnvKnotVars,
|
|
| 345 | + -- itself called by tcRnSrcDecls. It's important that this
|
|
| 342 | 346 | -- includes the stuff in checkHiBootIface,
|
| 343 | 347 | -- because the latter might add new bindings for
|
| 344 | 348 | -- boot_dfuns, which may be mentioned in imported
|
| ... | ... | @@ -553,6 +557,7 @@ tcRnSrcDecls :: Bool -- False => no 'module M(..) where' header at all |
| 553 | 557 | tcRnSrcDecls explicit_mod_hdr export_ies decls
|
| 554 | 558 | = do { -- Do all the declarations
|
| 555 | 559 | ; (tcg_env, tcl_env, lie) <- tc_rn_src_decls decls
|
| 560 | + ; traceTc "tcRnSrcDecls" (ppr (tcg_type_env tcg_env))
|
|
| 556 | 561 | |
| 557 | 562 | ------ Simplify constraints ---------
|
| 558 | 563 | --
|
| ... | ... | @@ -570,7 +575,13 @@ tcRnSrcDecls explicit_mod_hdr export_ies decls |
| 570 | 575 | ; ev_binds <- simplifyTop (lie `andWC` lie_main)
|
| 571 | 576 | ; return (tcg_env `addEvBinds` ev_binds) }
|
| 572 | 577 | |
| 578 | + -- Update the knot-tied type environment to include everything
|
|
| 579 | + -- bound in this module. Do this now because when compiling GHC.Internal.Types,
|
|
| 580 | + -- mkTypeableBinds needs to "see" the definition of `Module`
|
|
| 581 | + ; syncTypeEnvKnotVars tcg_env
|
|
| 582 | + |
|
| 573 | 583 | -- Emit Typeable bindings
|
| 584 | + ; traceTc "Before mkTypeableBinds" (ppr (tcg_type_env tcg_env))
|
|
| 574 | 585 | ; tcg_env <- setGblEnv tcg_env $
|
| 575 | 586 | mkTypeableBinds
|
| 576 | 587 | |
| ... | ... | @@ -643,15 +654,15 @@ tcRnSrcDecls explicit_mod_hdr export_ies decls |
| 643 | 654 | -- to the previous tcg_env
|
| 644 | 655 | |
| 645 | 656 | ; tcg_env' = tcg_env
|
| 646 | - { tcg_binds = binds' ++ binds_mf
|
|
| 657 | + { tcg_type_env = final_type_env
|
|
| 658 | + , tcg_binds = binds' ++ binds_mf
|
|
| 647 | 659 | , tcg_ev_binds = ev_binds' `unionBags` ev_binds_mf
|
| 648 | 660 | , tcg_imp_specs = imp_specs' ++ imp_specs_mf
|
| 649 | 661 | , tcg_rules = rules' ++ rules_mf
|
| 650 | 662 | , tcg_fords = fords' ++ fords_mf
|
| 651 | 663 | , tcg_patsyns = pat_syns' ++ patsyns_mf } } ;
|
| 652 | 664 | |
| 653 | - ; setGlobalTypeEnv tcg_env' final_type_env
|
|
| 654 | - }
|
|
| 665 | + ; return tcg_env' }
|
|
| 655 | 666 | |
| 656 | 667 | zonkTcGblEnv :: TcGblEnv
|
| 657 | 668 | -> TcM (TypeEnv, Bag EvBind, LHsBinds GhcTc,
|
| ... | ... | @@ -710,6 +721,7 @@ tc_rn_src_decls ds |
| 710 | 721 | ; (tcg_env, rn_decls) <- rnTopSrcDecls first_group
|
| 711 | 722 | -- rnTopSrcDecls fails if there are any errors
|
| 712 | 723 | |
| 724 | + ; traceRn "tc_rn_src_decls 77" empty
|
|
| 713 | 725 | -- Get TH-generated top-level declarations and make sure they don't
|
| 714 | 726 | -- contain any splices since we don't handle that at the moment
|
| 715 | 727 | --
|
| ... | ... | @@ -730,8 +742,8 @@ tc_rn_src_decls ds |
| 730 | 742 | AddTopDeclsUnexpectedDeclarationSplice
|
| 731 | 743 | }
|
| 732 | 744 | -- Rename TH-generated top-level declarations
|
| 733 | - ; (tcg_env, th_rn_decls) <- setGblEnv tcg_env
|
|
| 734 | - $ rnTopSrcDecls th_group
|
|
| 745 | + ; (tcg_env, th_rn_decls) <- setGblEnv tcg_env
|
|
| 746 | + $ rnTopSrcDecls th_group
|
|
| 735 | 747 | |
| 736 | 748 | -- Dump generated top-level declarations
|
| 737 | 749 | ; let msg = "top-level declarations added with 'addTopDecls'"
|
| ... | ... | @@ -747,6 +759,7 @@ tc_rn_src_decls ds |
| 747 | 759 | -- NB: set the env **before** captureTopConstraints so that error messages
|
| 748 | 760 | -- get reported w.r.t. the right GlobalRdrEnv. It is for this reason that
|
| 749 | 761 | -- the captureTopConstraints must go here, not in tcRnSrcDecls.
|
| 762 | + ; traceRn "about to typechecke decls" (ppr rn_decls)
|
|
| 750 | 763 | ; ((tcg_env, tcl_env), lie1) <- setGblEnv tcg_env $
|
| 751 | 764 | captureTopConstraints $
|
| 752 | 765 | tcTopSrcDecls rn_decls
|
| ... | ... | @@ -834,10 +847,11 @@ tcRnHsBootDecls boot_or_sig decls |
| 834 | 847 | ; let { type_env0 = tcg_type_env gbl_env
|
| 835 | 848 | ; type_env1 = extendTypeEnvWithIds type_env0 val_ids
|
| 836 | 849 | ; type_env2 = extendTypeEnvWithIds type_env1 dfun_ids
|
| 837 | - ; dfun_ids = map iDFunId inst_infos
|
|
| 850 | + ; dfun_ids = map iDFunId inst_infos
|
|
| 851 | + ; gbl_env' = gbl_env { tcg_type_env = type_env2 }
|
|
| 838 | 852 | }
|
| 839 | 853 | |
| 840 | - ; setGlobalTypeEnv gbl_env type_env2
|
|
| 854 | + ; return gbl_env'
|
|
| 841 | 855 | }}}
|
| 842 | 856 | ; traceTc "boot" (ppr lie); return gbl_env }
|
| 843 | 857 | |
| ... | ... | @@ -875,20 +889,14 @@ checkHiBootIface tcg_env boot_info |
| 875 | 889 | --
|
| 876 | 890 | -- to (a) the type envt, and (b) the top-level bindings
|
| 877 | 891 | ; let boot_impedance_bds = map fst imp_prs
|
| 878 | - type_env' = extendTypeEnvWithIds local_type_env boot_impedance_bds
|
|
| 892 | + !type_env' = extendTypeEnvWithIds local_type_env boot_impedance_bds
|
|
| 879 | 893 | impedance_binds = [ mkVarBind boot_id (nlHsVar id)
|
| 880 | 894 | | (boot_id, id) <- imp_prs ]
|
| 881 | 895 | tcg_env_w_binds
|
| 882 | - = tcg_env { tcg_binds = binds ++ impedance_binds }
|
|
| 896 | + = tcg_env { tcg_type_env = type_env'
|
|
| 897 | + , tcg_binds = binds ++ impedance_binds }
|
|
| 883 | 898 | |
| 884 | - ; type_env' `seq`
|
|
| 885 | - -- Why the seq? Without, we will put a TypeEnv thunk in
|
|
| 886 | - -- tcg_type_env_var. That thunk will eventually get
|
|
| 887 | - -- forced if we are typechecking interfaces, but that
|
|
| 888 | - -- is no good if we are trying to typecheck the very
|
|
| 889 | - -- DFun we were going to put in.
|
|
| 890 | - -- TODO: Maybe setGlobalTypeEnv should be strict.
|
|
| 891 | - setGlobalTypeEnv tcg_env_w_binds type_env' }
|
|
| 899 | + ; return tcg_env_w_binds }
|
|
| 892 | 900 | |
| 893 | 901 | {- Note [DFun impedance matching]
|
| 894 | 902 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -978,7 +986,7 @@ This most works well, but there is one problem: DFuns! We do not want |
| 978 | 986 | to look at the mb_insts of the ModDetails in SelfBootInfo, because a
|
| 979 | 987 | dfun in one of those ClsInsts is gotten (in GHC.IfaceToCore.tcIfaceInst) by a
|
| 980 | 988 | (lazily evaluated) lookup in the if_rec_types. We could extend the
|
| 981 | -type env, do a setGloblaTypeEnv etc; but that all seems very indirect.
|
|
| 989 | +type env, do a syncTypeEnvKnotVars etc; but that all seems very indirect.
|
|
| 982 | 990 | It is much more directly simply to extract the DFunIds from the
|
| 983 | 991 | md_types of the SelfBootInfo.
|
| 984 | 992 |
| ... | ... | @@ -487,7 +487,7 @@ data TcGblEnv |
| 487 | 487 | -- NB: for what "things in this module" means, see
|
| 488 | 488 | -- Note [The interactive package] in "GHC.Runtime.Context"
|
| 489 | 489 | |
| 490 | - tcg_type_env_var :: KnotVars (IORef TypeEnv),
|
|
| 490 | + tcg_knot_vars :: KnotVars (IORef TypeEnv),
|
|
| 491 | 491 | -- Used only to initialise the interface-file
|
| 492 | 492 | -- typechecker in initIfaceTcRn, so that it can see stuff
|
| 493 | 493 | -- bound in this module when dealing with hi-boot recursions
|
| ... | ... | @@ -739,7 +739,7 @@ mergeSignatures |
| 739 | 739 | , rdr_elt <- lookupGRE rdr_env (LookupOccName occ AllRelevantGREs) ]
|
| 740 | 740 | |
| 741 | 741 | -- STEP 5: Typecheck the interfaces
|
| 742 | - let type_env_var = tcg_type_env_var tcg_env
|
|
| 742 | + let knot_type_env = tcg_knot_vars tcg_env
|
|
| 743 | 743 | |
| 744 | 744 | -- typecheckIfacesForMerging does two things:
|
| 745 | 745 | -- 1. It merges the all of the ifaces together, and typechecks the
|
| ... | ... | @@ -748,7 +748,7 @@ mergeSignatures |
| 748 | 748 | -- resolving to the merged type_env from (1).
|
| 749 | 749 | -- See typecheckIfacesForMerging for more details.
|
| 750 | 750 | (type_env, detailss) <- initIfaceTcRn $
|
| 751 | - typecheckIfacesForMerging inner_mod ifaces type_env_var
|
|
| 751 | + typecheckIfacesForMerging inner_mod ifaces knot_type_env
|
|
| 752 | 752 | let infos = zip ifaces detailss
|
| 753 | 753 | |
| 754 | 754 | -- Test for cycles
|
| ... | ... | @@ -764,7 +764,7 @@ mergeSignatures |
| 764 | 764 | -- NB: Why do we set tcg_tcs/tcg_patsyns/tcg_type_env directly,
|
| 765 | 765 | -- rather than use tcExtendGlobalEnv (the normal method to add newly
|
| 766 | 766 | -- defined types to TcGblEnv?) tcExtendGlobalEnv adds these
|
| 767 | - -- TyThings to 'tcg_type_env_var', which is consulted when
|
|
| 767 | + -- TyThings to 'tcg_knot_vars', which is consulted when
|
|
| 768 | 768 | -- we read in interfaces to tie the knot. But *these TyThings themselves
|
| 769 | 769 | -- come from interface*, so that would result in deadlock. Don't
|
| 770 | 770 | -- update it!
|
| ... | ... | @@ -16,7 +16,7 @@ module GHC.Tc.Utils.Env( |
| 16 | 16 | |
| 17 | 17 | -- Global environment
|
| 18 | 18 | tcExtendGlobalEnv, tcExtendTyConEnv,
|
| 19 | - tcExtendGlobalEnvImplicit, setGlobalTypeEnv,
|
|
| 19 | + tcExtendGlobalEnvImplicit, syncTypeEnvKnotVars,
|
|
| 20 | 20 | tcExtendGlobalValEnv, tcTyThBinders,
|
| 21 | 21 | tcLookupLocatedGlobal, tcLookupGlobal, tcLookupGlobalOnly,
|
| 22 | 22 | tcLookupTyCon, tcLookupClass,
|
| ... | ... | @@ -515,8 +515,10 @@ getKnownKeySource :: TcRn KnownKeyNameSource |
| 515 | 515 | getKnownKeySource
|
| 516 | 516 | = do { rebindable_path <- goptM Opt_RebindableKnownKeyNames
|
| 517 | 517 | ; if rebindable_path
|
| 518 | - then do { rdr_env <- getGlobalRdrEnv
|
|
| 519 | - ; return (KKNS_InScope rdr_env) }
|
|
| 518 | + then do { env <- getGlobalEnv
|
|
| 519 | + ; return (KKNS_InScope (tcg_mod env)
|
|
| 520 | + (tcg_rdr_env env)
|
|
| 521 | + (tcg_type_env env)) }
|
|
| 520 | 522 | else return KKNS_FromModule }
|
| 521 | 523 | |
| 522 | 524 | tcrn_wrapper :: HasDebugCallStack
|
| ... | ... | @@ -606,16 +608,21 @@ get_id do_the_lookup |
| 606 | 608 | ************************************************************************
|
| 607 | 609 | -}
|
| 608 | 610 | |
| 609 | -setGlobalTypeEnv :: TcGblEnv -> TypeEnv -> TcM TcGblEnv
|
|
| 610 | --- Use this to update the global type env
|
|
| 611 | --- It updates both * the normal tcg_type_env field
|
|
| 612 | --- * the tcg_type_env_var field seen by interface files
|
|
| 613 | -setGlobalTypeEnv tcg_env new_type_env
|
|
| 614 | - = do { -- Sync the type-envt variable seen by interface files
|
|
| 615 | - ; case lookupKnotVars (tcg_type_env_var tcg_env) (tcg_mod tcg_env) of
|
|
| 616 | - Just tcg_env_var -> writeMutVar tcg_env_var new_type_env
|
|
| 617 | - Nothing -> return ()
|
|
| 618 | - ; return (tcg_env { tcg_type_env = new_type_env }) }
|
|
| 611 | +syncTypeEnvKnotVars :: TcGblEnv -> TcM ()
|
|
| 612 | +-- Use this to sync the tcg_knot_vars with the current type env
|
|
| 613 | +-- so that interface-file and known-key/occ lookups will find the
|
|
| 614 | +-- current bindings
|
|
| 615 | +--
|
|
| 616 | +-- Why the "!" before writing it into the variable? Without, we will put
|
|
| 617 | +-- a TypeEnv thunk into the knot-tied variable. That thunk will eventually get
|
|
| 618 | +-- forced if we are typechecking interfaces, but that is no good if we are
|
|
| 619 | +-- trying to typecheck the very DFun we were going to put in.
|
|
| 620 | +syncTypeEnvKnotVars tcg_env
|
|
| 621 | + = case lookupKnotVars (tcg_knot_vars tcg_env) (tcg_mod tcg_env) of
|
|
| 622 | + Just tcg_env_var -> do { let !type_env = tcg_type_env tcg_env
|
|
| 623 | + -- Why the "!"? See comment on the function
|
|
| 624 | + ; writeMutVar tcg_env_var type_env }
|
|
| 625 | + Nothing -> return ()
|
|
| 619 | 626 | |
| 620 | 627 | |
| 621 | 628 | tcExtendGlobalEnvImplicit :: [TyThing] -> TcM r -> TcM r
|
| ... | ... | @@ -623,8 +630,9 @@ tcExtendGlobalEnvImplicit :: [TyThing] -> TcM r -> TcM r |
| 623 | 630 | -- Do not extend tcg_tcs, tcg_patsyns etc
|
| 624 | 631 | tcExtendGlobalEnvImplicit things thing_inside
|
| 625 | 632 | = do { tcg_env <- getGblEnv
|
| 626 | - ; let ge' = extendTypeEnvList (tcg_type_env tcg_env) things
|
|
| 627 | - ; tcg_env' <- setGlobalTypeEnv tcg_env ge'
|
|
| 633 | + ; let !type_env' = extendTypeEnvList (tcg_type_env tcg_env) things
|
|
| 634 | + tcg_env' = tcg_env { tcg_type_env = type_env' }
|
|
| 635 | + ; syncTypeEnvKnotVars tcg_env'
|
|
| 628 | 636 | ; setGblEnv tcg_env' thing_inside }
|
| 629 | 637 | |
| 630 | 638 | tcExtendGlobalEnv :: [TyThing] -> TcM r -> TcM r
|
| ... | ... | @@ -677,8 +685,8 @@ tcExtendRecEnv gbl_stuff thing_inside |
| 677 | 685 | = do { tcg_env <- getGblEnv
|
| 678 | 686 | ; let ge' = extendNameEnvList (tcg_type_env tcg_env) gbl_stuff
|
| 679 | 687 | tcg_env' = tcg_env { tcg_type_env = ge' }
|
| 680 | - -- No need for setGlobalTypeEnv (which side-effects the
|
|
| 681 | - -- tcg_type_env_var); tcExtendRecEnv is used just
|
|
| 688 | + -- No need for syncTypeEnvKnotVars (which side-effects the
|
|
| 689 | + -- tcg_knot_vars); tcExtendRecEnv is used just
|
|
| 682 | 690 | -- when kind-check a group of type/class decls. It would
|
| 683 | 691 | -- in any case be wrong for an interface-file decl to end up
|
| 684 | 692 | -- with a TcTyCon in it!
|
| ... | ... | @@ -353,7 +353,7 @@ initTcGblEnv hsc_env hsc_src keep_rn_syntax mod loc = |
| 353 | 353 | , tcg_default = emptyDefaultEnv
|
| 354 | 354 | , tcg_default_exports = emptyDefaultEnv
|
| 355 | 355 | , tcg_type_env = emptyNameEnv
|
| 356 | - , tcg_type_env_var = hsc_type_env_vars hsc_env
|
|
| 356 | + , tcg_knot_vars = hsc_type_env_vars hsc_env
|
|
| 357 | 357 | , tcg_inst_env = emptyInstEnv
|
| 358 | 358 | , tcg_fam_inst_env = emptyFamInstEnv
|
| 359 | 359 | , tcg_ann_env = emptyAnnEnv
|
| ... | ... | @@ -2404,7 +2404,7 @@ initIfaceTcRn thing_inside |
| 2404 | 2404 | ; hsc_env <- getTopEnv
|
| 2405 | 2405 | -- bangs to avoid leaking the envs (#19356)
|
| 2406 | 2406 | ; let !mhome_unit = hsc_home_unit_maybe hsc_env
|
| 2407 | - !knot_vars = tcg_type_env_var tcg_env
|
|
| 2407 | + !knot_vars = tcg_knot_vars tcg_env
|
|
| 2408 | 2408 | -- When we are instantiating a signature,
|
| 2409 | 2409 | -- we DEFINITELY do not want to knot tie.
|
| 2410 | 2410 | is_instantiate = fromMaybe False (isHomeUnitInstantiating <$> mhome_unit)
|