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