ghc-9.14.1: GHC/Unit/Module/Stage.hs
module GHC.Unit.Module.Stage ( ModuleStage(..)
, allStages
, nowAndFutureStages
, onlyFutureStages
, minStage
, maxStage
, zeroStage
, decModuleStage
, incModuleStage
) where
import GHC.Prelude
import GHC.Utils.Outputable
{- Note [Stage vs Level]
~~~~~~~~~~~~~~~~~~~~~~~~
Modules are compiled at a specific stage. Levels within a module are interpreted
as offsets to the specific stage at which the module is being compiled.
* A **level** is a typechecking concept. The type checker performs level checking
to ensure that the evaluation can proceed in a well-staged manner.
* A **stage** is an operational construct. The execution of the program happens
in stages.
GHC at the moment knows about two stages, a module is either compiled for
compile time (*C*) or runtime (*R*), with *C* before *R*. Then:
* The main module is compiled for `R`.
* A normal import does not shift the stage at which the dependent module is required.
* If a module `M` splice imports module `A`, then compiling `M` at stage
*R* requires compiling module `A` at stage *C*.
* If a module `N` quote imports module `B`, then compiling `N` at stage
*C* requires compiling module `B` at stage *R*.
The compiler can then choose appropiately how modules needed at `C` are compiled
and how modules needed at `R` are compiled.
For example:
* In `-fno-code` mode, `C` modules may be compiled in dynamic way, but `R` modules
are not compiled at all.
* When using a profiled GHC. `C` modules must be compiled in profiled way but `R` modules
will be compiled in static way.
Further structure as needed by cross-compilation settings may require more stages.
-}
-- The order of these constructors is important for definitions such as
-- 'futureStages'.
data ModuleStage = CompileStage | RunStage deriving (Eq, Ord, Enum, Bounded)
allStages :: [ModuleStage]
allStages = [minBound .. maxBound]
nowAndFutureStages :: ModuleStage -> [ModuleStage]
nowAndFutureStages cur_st = [cur_st .. ]
onlyFutureStages :: ModuleStage -> [ModuleStage]
onlyFutureStages cur_st | cur_st == maxBound = []
onlyFutureStages cur_st = [succ cur_st .. ]
minStage :: ModuleStage
minStage = minBound
maxStage :: ModuleStage
maxStage = maxBound
instance Outputable ModuleStage where
ppr CompileStage = text "compile"
ppr RunStage = text "run"
zeroStage :: ModuleStage
zeroStage = RunStage
decModuleStage, incModuleStage :: ModuleStage -> ModuleStage
incModuleStage RunStage = RunStage
incModuleStage CompileStage = RunStage
decModuleStage RunStage = CompileStage
decModuleStage CompileStage = RunStage