Implement Explicit Level Imports for Template Haskell
This commit introduces the `ExplicitLevelImports` and `ImplicitStagePersistence` language extensions as proposed in GHC Proposal #682. Key Features ------------ - `ExplicitLevelImports` adds two new import modifiers - `splice` and `quote` - allowing precise control over the level at which imported identifiers are available - `ImplicitStagePersistence` (enabled by default) preserves existing path-based cross-stage persistence behavior - `NoImplicitStagePersistence` disables implicit cross-stage persistence, requiring explicit level imports Benefits -------- - Improved compilation performance by reducing unnecessary code generation - Enhanced IDE experience with faster feedback in `-fno-code` mode - Better dependency tracking by distinguishing compile-time and runtime dependencies - Foundation for future cross-compilation improvements This implementation enables the separation of modules needed at compile-time from those needed at runtime, allowing for more efficient compilation pipelines and clearer code organization in projects using Template Haskell. Implementation Notes -------------------- The level which a name is availble at is stored in the 'GRE', in the normal GlobalRdrEnv. The function `greLevels` returns the levels which a specific GRE is imported at. The level information for a 'Name' is computed by `getCurrentAndBindLevel`. The level validity is checked by `checkCrossLevelLifting`. Instances are checked by `checkWellLevelledDFun`, which computes the level an instance by calling `checkWellLevelledInstanceWhat`, which sees what is available at by looking at the module graph. Modifications to downsweep -------------------------- Code generation is now only enabled for modules which are needed at compile time. See the Note [-fno-code mode] for more information. Uniform error messages for level errors --------------------------------------- All error messages to do with levels are now reported uniformly using the `TcRnBadlyStaged` constructor. Error messages are uniformly reported in terms of levels. 0 - top-level 1 - quote level -1 - splice level The only level hard-coded into the compiler is the top-level in GHC.Types.ThLevelIndex.topLevelIndex. Uniformly refer to levels and stages ------------------------------------ There was much confusion about levels vs stages in the compiler. A level is a semantic concept, used by the typechecker to ensure a program can be evaluated in a well-staged manner. A stage is an operational construct, program evaluation proceeds in stages. Deprecate -Wbadly-staged-types ------------------------------ `-Wbadly-staged-types` is deprecated in favour of `-Wbadly-levelled-types`. Lift derivation changed ----------------------- Derived lift instances will now not generate code with expression quotations. Before: ``` data A = A Int deriving Lift => lift (A x) = [| A $(lift x) |] ``` After: ``` lift (A x) = conE 'A `appE` (lift x) ``` This is because if you attempt to derive `Lift` in a module where `NoImplicitStagePersistence` is enabled, you would get an infinite loop where a constructor was attempted to be persisted using the instance you are currently defining. GHC API Changes --------------- The ModuleGraph now contains additional information about the type of the edges (normal, quote or splice) between modules. This is abstracted using the `ModuleGraphEdge` data type. Fixes #25828 ------------------------- Metric Increase: MultiLayerModulesTH_Make -------------------------
Showing
- compiler/GHC.hs 2 additions, 1 deletioncompiler/GHC.hs
- compiler/GHC/Data/Graph/Directed/Reachability.hs 19 additions, 12 deletionscompiler/GHC/Data/Graph/Directed/Reachability.hs
- compiler/GHC/Driver/Backpack.hs 11 additions, 10 deletionscompiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Downsweep.hs 376 additions, 240 deletionscompiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs 8 additions, 3 deletionscompiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs 7 additions, 3 deletionscompiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Make.hs 1 addition, 2 deletionscompiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeFile.hs 6 additions, 5 deletionscompiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline.hs 3 additions, 1 deletioncompiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs 2 additions, 2 deletionscompiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs 3 additions, 1 deletioncompiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/ImpExp.hs 17 additions, 10 deletionscompiler/GHC/Hs/ImpExp.hs
- compiler/GHC/Iface/Recomp.hs 29 additions, 23 deletionscompiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Tidy.hs 4 additions, 1 deletioncompiler/GHC/Iface/Tidy.hs
- compiler/GHC/Parser.y 40 additions, 17 deletionscompiler/GHC/Parser.y
- compiler/GHC/Parser/Errors/Ppr.hs 4 additions, 0 deletionscompiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs 3 additions, 0 deletionscompiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/Header.hs 13 additions, 5 deletionscompiler/GHC/Parser/Header.hs
- compiler/GHC/Parser/Lexer.x 8 additions, 1 deletioncompiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs 49 additions, 5 deletionscompiler/GHC/Parser/PostProcess.hs
Loading
Please register or sign in to comment