HORIZON HASKELLDocslts/ghc-10.0.x8174fa42026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8174fa4 · 2026-10-11

Reading the package config, and processing cmdline args

10 declarations
datadata UnitState
#

The UnitState contains a plethora of information local to a single HomeUnitEnv.

It stores module visibilities, unit trust for SafeHaskell, available units for error messages, explicit unit dependencies and knows how to instantiate backpack signature and holes on demand.

A HomeUnitEnv should rarely/never have to look into the UnitIndex, all external unit related information is stored in the UnitState.

Constructors

  • UnitState
    • unitInfoMap :: UnitInfoMap

      A mapping of Unit to UnitInfo. This list is adjusted so that only valid units are here. UnitInfo reflects what was stored *on disk*, except for the trusted flag, which is adjusted at runtime. (In particular, some units in this map may have the exposed flag be False.)

      All values are shared with UnitIndex.globalUnits. See Note [Sharing UnitInfos across the UnitEnv] for details.

    • trustedUnits :: !TrustOverlay

      Set of units that we trust.

      Local overlay of UnitInfo. This avoids modifying the UnitInfo directly, potentially saving a lot of duplication.

      We keep this in WHNF as it is relatively cheap but could easily retain references to bigger structures.

    • packageNameMap :: UniqFM PackageName UnitId

      A mapping of PackageName to UnitId. If several units have the same package name (e.g. different instantiations), then we return one of them... This is used when users refer to packages in Backpack includes. And also to resolve package qualifiers with the PackageImports extension.

    • preloadUnits :: [UnitId]

      The units we're going to link in eagerly. This list should be in reverse dependency order; that is, a unit is always mentioned before the units it depends on.

    • explicitUnits :: [(Unit, Maybe PackageArg)]

      Units which we explicitly depend on (from a command line flag). We'll use this to generate version macros and the unused packages warning. The original flag which was used to bring the unit into scope is recorded for the -Wunused-packages warning.

    • homeUnitDepends :: Set UnitId
    • moduleNameProvidersMap :: !ModuleNameProvidersMap

      This is a full map from ModuleName to all modules which may possibly be providing it. These providers may be hidden (but we'll still want to report them in error messages), or it may be an ambiguous import.

    • pluginModuleNameProvidersMap :: !ModuleNameProvidersMap

      A map, like moduleNameProvidersMap, but controlling plugin visibility.

    • requirementContext :: UniqMap ModuleName [InstantiatedModule]

      A map saying, for each requirement, what interfaces must be merged together when we use them. For example, if our dependencies are p[A=<A>] and q[A=<A>,B=r[C=<A>]:B], then the interfaces to merge for A are p[A=<A>]:A, q[A=<A>,B=r[C=<A>]:B]:A and r[C=<A>]:C.

      There's an entry in this map for each hole in our home library.

    • allowVirtualUnits :: !Bool

      Indicate if we can instantiate units on-the-fly.

      This should only be true when we are type-checking an indefinite unit. See Note [About units] in GHC.Unit.

Read the unit database files, and sets up various internal tables of unit information, according to the unit-related flags on the command-line (-package, -hide-package etc.)

initUnits can be called again subsequently after updating the packageFlags and packageDBFlags fields of the DynFlags, and it will update the unitState in DynFlags.

Also, see Note [Sharing UnitInfos across the UnitEnv] for implementation details.

Return the path of a package database from a PkgDbRef. Return Nothing when the user database filepath is expected but the latter doesn't exist.

NB: This logic is reimplemented in Cabal, so if you change it, make sure you update Cabal. (Or, better yet, dump it in the compiler info so Cabal can use the info.)

valuelistUnitInfo :: UnitState -> [UnitInfo]
#

Get a list of entries from the unit database. NB: be careful with this function, although all units in this map are "visible", this does not imply that the exposed-modules of the unit are available (they may have been thinned or renamed).

Overlays over the unit set

6 declarations
newtypenewtype TrustOverlay
#

The TrustOverlay stores user overwrites of the on-disk unitIsTrusted status.

The user can overwrite this value via flags such as -distrust-all-packages. We do not modify the UnitInfo directory, but rather store this user selection in the TrustOverlay.

This allows us to share the UnitInfo completely and saves us memory.

Querying the package config

27 declarations

A more specialized interface, which doesn't require a UnitState (so it can be used while we're initializing DynFlags)

Parameters: * a boolean specifying whether or not to look for on-the-fly renamed interfaces * a UnitInfoMap

Find the unit we know about with the given package name (e.g. foo), if any (NB: there might be a locally defined unit name which overrides this) This function is unsafe to use in general because it doesn't respect package visibility.

datadata LookupResult
#

The result of performing a lookup

Constructors

datadata ModuleOrigin
#

Given a module name, there may be multiple ways it came into scope, possibly simultaneously. This data type tracks all the possible ways it could have come into scope. Warning: don't use the record functions, they're partial!

Constructors

  • ModHidden

    Module is hidden, and thus never will be available for import. (But maybe the user didn't realize), so we'll still keep track of these modules.)

  • ModUnusable !UnusableUnit

    Module is unavailable because the unit is unusable.

  • ModOrigin

    Module is public, and could have come from some places.

    • fromOrigUnit :: Maybe Bool

      Just False means that this module is in someone's exported-modules list, but that package is hidden; Just True means that it is available; Nothing means neither applies.

    • fromExposedReexport :: [UnitInfo]

      Is the module available from a reexport of an exposed package? There could be multiple.

    • fromHiddenReexport :: [UnitInfo]

      Is the module available from a reexport of a hidden package?

    • fromPackageFlag :: Bool

      Did the module export come from a package flag? (ToDo: track more information.

Instances3Semigroup, Monoid, Outputable
datadata UnusableUnitReason
#

The reason why a unit is unusable.

Constructors

  • IgnoredWithFlag

    We ignored it explicitly using -ignore-package.

  • BrokenDependencies [UnitId]

    This unit transitively depends on a unit that was never present in any of the provided databases.

  • CyclicDependencies [UnitId]

    This unit transitively depends on a unit involved in a cycle. Note that the list of UnitId reports the direct dependencies of this unit that (transitively) depended on the cycle, and not the actual cycle itself (which we report separately at high verbosity.)

  • IgnoredDependencies [UnitId]

    This unit transitively depends on a unit which was ignored.

  • ShadowedDependencies [UnitId]

    This unit transitively depends on a unit which was shadowed by an ABI-incompatible unit.

Instances1Outputable

Module hole substitution

7 declarations

Substitutes holes in a Module. NOT suitable for being called directly on a nameModule, see Note [Representation of module/name variables]. p[A=<A>]:B maps to p[A=q():A]:B with A=q():A; similarly, <A> maps to q():A.

Pretty-printing

8 declarations

Show simplified unit info.

The idea is to only print package id, and any information that might be different from the package databases (exposure, trust)

Pretty-print a UnitId for the user.

Cabal packages may contain several components (programs, libraries, etc.). As far as GHC is concerned, installed package components ("units") are identified by an opaque UnitId string provided by Cabal. As the string contains a hash, we don't want to display it to users so GHC queries the database to retrieve some infos about the original source package (name, version, component name).

Instead we want to display: packagename-version[:componentname]

Component name is only displayed if it isn't the default library

To do this we need to query a unit database.

Utils

2 declarations