
#10419: Refactor LoadIface to distinguish getting a ModIface versus loading into EPT -------------------------------------+------------------------------------- Reporter: ezyang | Owner: ezyang Type: task | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.11 (Type checker) | Operating System: Unknown/Multiple Keywords: | Type of failure: None/Unknown Architecture: | Blocked By: Unknown/Multiple | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- At the moment, making a call to `loadSysInterface` (or the related interfaces) has two effects: 1. You get a `ModIface` 2. The declarations/instances/etc of the interface are type-checked and loaded into the EPT In fact, users of these functions rarely want both of these; they either only want the `ModIface`, or only want to load up the declarations. Here is a survey I did, where `I` indicates a `ModIface` was wanted, `D` indicates we wanted to load the declarations, and `ID` means both were wanted; {{{ RnSplice loadInterfaceForName: D rnBracket: deprecation checking of identifiers in brackets () RnEnv loadInterfaceForName I warnIfDeprecated: deprecation checking of GlobalRdrElt (mi_warn_fun) I lookupFixityRn: fixity lookup (mi_fix_fun) loadSrcInterface_maybe ID lookupQualifiedNameGHCi: implicit import RnNames loadSrcInterface ID rnImportDecl: source import! $$$$$ I printMinimalImports: minimal import calculation (mi_exports) DsMonad loadInterface I loadModule: load and return exported entities (like a source import but for Module) special case for Data.Array.Parallel DynamicLoading loadPluginInterface D forceLoadModuleInterfaces: what. Linker loadInterface I getLinkDeps: poke the dependencies (mi_boot, mi_deps) loadUserInterface I random ass thing to check if it's a sigof XXX (mi_sig_of) MkIface loadInterface I? needInterface: utility checkModUsage: given the usage information from the old hi, determine if recompilation is required (hashes only) FamInst loadSysInterface D getFamInsts: load instance into EPS and return it TcDeriv loadInterfaceForName I getDataConFixityFun: looks at mi_fix_fn TcRnDriver loadSysInterface I tcRnSignature: signature renaming hack D loadUnqualIfaces: for accurate available instance reporting loadModuleInterfaces D tcRnImports: load orphans loadModuleInterface getModuleInterface: load a 'Module' (GHCi) D hscCheckSafe' (HscMain, mi_trust, mi_trust_pkg, mi_deps) ID getPackageModuleInfo (contains interface) loadSrcInterface D runTcInteractive: mi_deps/dep_orphs, pull in orphans from interactive context ic_imports TcSplice loadInterfaceForModule I reifyModule: mi_usages only }}} It's well worth noting that for most `Name`s, it is NOT NECESSARY, since when we pull on it with `loadDecl`, the interface will get loaded in. Consequently, I think some of the cases where we're loading interfaces are unnecessary, e.g. the case in `rnBracket`. The primary cases are dealing with orphan imports; there are multiple sites which redo this logic, and it should all be centralized in one place. So here is the concrete proposal: * Add a new function for taking a `ModIface` and loading it into the EPT. * Change the rest of the existing `loadXXXInterface` functions to NOT load declarations. We'll actually typecheck the interface file when we pull on the `Name` in question during type checking. * Introduce a new function to `LoadIface` for loading orphans (i.e. what to do when a source level import occurs). Have `lookupQualifiedNameGHCi`, `rnImportDecl`, `tcRnImports` and `runTcInteractive` use this function. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10419 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler