Hannes Siebenhandl pushed to branch wip/fendor/external-unit-db-cache at Glasgow Haskell Compiler / GHC

Commits:

23 changed files:

Changes:

  • compiler/GHC.hs
    ... ... @@ -671,7 +671,7 @@ setUnitDynFlagsNoCheck uid dflags1 = do
    671 671
       logger <- getLogger
    
    672 672
       hsc_env <- getSession
    
    673 673
     
    
    674
    -  (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (hsc_unit_index hsc_env) (hscEUDC hsc_env) (hsc_all_home_unit_ids hsc_env)
    
    674
    +  (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (hscUIC hsc_env) (hscEUDC hsc_env) (hsc_all_home_unit_ids hsc_env)
    
    675 675
       updated_dflags <- liftIO $ updatePlatformConstants dflags1 mconstants
    
    676 676
     
    
    677 677
       let upd hue =
    
    ... ... @@ -760,7 +760,7 @@ setProgramDynFlags_ invalidate_needed dflags = do
    760 760
                   old_hpt = homeUnitEnv_hpt homeUnitEnv
    
    761 761
                   home_units = HUG.allUnits (ue_home_unit_graph old_unit_env)
    
    762 762
     
    
    763
    -          (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_unit_index old_unit_env) (ue_eud old_unit_env) home_units
    
    763
    +          (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_uic old_unit_env) (ue_eud old_unit_env) home_units
    
    764 764
     
    
    765 765
               updated_dflags <- liftIO $ updatePlatformConstants dflags0 mconstants
    
    766 766
               pure HomeUnitEnv
    
    ... ... @@ -779,7 +779,7 @@ setProgramDynFlags_ invalidate_needed dflags = do
    779 779
                   , ue_module_graph    = ue_module_graph old_unit_env
    
    780 780
                   , ue_eps             = ue_eps old_unit_env
    
    781 781
                   , ue_eud             = ue_eud old_unit_env
    
    782
    -              , ue_unit_index      = ue_unit_index old_unit_env
    
    782
    +              , ue_uic      = ue_uic old_unit_env
    
    783 783
                   }
    
    784 784
             modifySession $ \h -> hscSetFlags dflags1 h{ hsc_unit_env = unit_env }
    
    785 785
         else modifySession (hscSetFlags dflags0)
    
    ... ... @@ -838,7 +838,7 @@ setProgramHUG_ invalidate_needed new_hug0 = do
    838 838
                 , ue_eps             = ue_eps unit_env0
    
    839 839
                 , ue_module_graph    = ue_module_graph unit_env0
    
    840 840
                 , ue_eud             = ue_eud unit_env0
    
    841
    -            , ue_unit_index      = ue_unit_index unit_env0
    
    841
    +            , ue_uic      = ue_uic unit_env0
    
    842 842
                 }
    
    843 843
           modifySession $ \h ->
    
    844 844
             -- hscSetFlags takes care of updating the logger as well.
    
    ... ... @@ -886,7 +886,7 @@ setProgramHUG_ invalidate_needed new_hug0 = do
    886 886
               old_hpt = homeUnitEnv_hpt homeUnitEnv
    
    887 887
               home_units = HUG.allUnits (ue_home_unit_graph unit_env)
    
    888 888
     
    
    889
    -      (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_unit_index unit_env) (ue_eud unit_env) home_units
    
    889
    +      (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_uic unit_env) (ue_eud unit_env) home_units
    
    890 890
     
    
    891 891
           updated_dflags <- liftIO $ updatePlatformConstants dflags mconstants
    
    892 892
           pure HomeUnitEnv
    

  • compiler/GHC/Driver/Backpack.hs
    ... ... @@ -451,7 +451,7 @@ addUnit u = do
    451 451
               { packageDBFlags = packageDBFlags dflags0 ++ [PackageDB (PkgDbPath (unitDatabasePath newdb))]
    
    452 452
               }
    
    453 453
     
    
    454
    -    (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (ue_unit_index old_unit_env) eud (hsc_all_home_unit_ids hsc_env)
    
    454
    +    (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (ue_uic old_unit_env) eud (hsc_all_home_unit_ids hsc_env)
    
    455 455
     
    
    456 456
     
    
    457 457
         -- update platform constants
    
    ... ... @@ -469,7 +469,7 @@ addUnit u = do
    469 469
               , ue_eps       = ue_eps old_unit_env
    
    470 470
               , ue_module_graph = ue_module_graph old_unit_env
    
    471 471
               , ue_eud       = ue_eud old_unit_env
    
    472
    -          , ue_unit_index = ue_unit_index old_unit_env
    
    472
    +          , ue_uic = ue_uic old_unit_env
    
    473 473
               }
    
    474 474
         setSession $ hscSetFlags dflags $ hsc_env { hsc_unit_env = unit_env }
    
    475 475
     
    

  • compiler/GHC/Driver/Env.hs
    ... ... @@ -14,7 +14,7 @@ module GHC.Driver.Env
    14 14
        , hsc_HUG
    
    15 15
        , hsc_all_home_unit_ids
    
    16 16
        , hscUnitIndex
    
    17
    -   , hsc_unit_index
    
    17
    +   , hscUIC
    
    18 18
        , hscUpdateLoggerFlags
    
    19 19
        , hscUpdateHUG
    
    20 20
        , hscInsertHPT
    
    ... ... @@ -94,6 +94,7 @@ import GHC.Builtin.Names
    94 94
     import Data.IORef
    
    95 95
     import qualified Data.Set as Set
    
    96 96
     import GHC.Unit.External.Database (ExternalUnitDatabaseCache, readExternalUnitDatabases, ExternalUnitDatabases)
    
    97
    +import GHC.Unit.External.Index
    
    97 98
     
    
    98 99
     runHsc :: HscEnv -> Hsc a -> IO a
    
    99 100
     runHsc hsc_env hsc = do
    
    ... ... @@ -233,10 +234,10 @@ hscEUDC :: HscEnv -> ExternalUnitDatabaseCache UnitId
    233 234
     hscEUDC hsc_env = ue_eud (hsc_unit_env hsc_env)
    
    234 235
     
    
    235 236
     hscUnitIndex :: HscEnv -> IO UnitIndex
    
    236
    -hscUnitIndex hsc_env = readIORef $ ue_unit_index (hsc_unit_env hsc_env)
    
    237
    +hscUnitIndex hsc_env = ueUI (hsc_unit_env hsc_env)
    
    237 238
     
    
    238
    -hsc_unit_index :: HscEnv -> IORef UnitIndex
    
    239
    -hsc_unit_index hsc_env = ue_unit_index (hsc_unit_env hsc_env)
    
    239
    +hscUIC :: HscEnv -> UnitIndexCache
    
    240
    +hscUIC hsc_env = ue_uic (hsc_unit_env hsc_env)
    
    240 241
     
    
    241 242
     --------------------------------------------------------------------------------
    
    242 243
     -- * Queries on Transitive Closure
    

  • compiler/GHC/Driver/Session/Units.hs
    ... ... @@ -131,7 +131,7 @@ initMulti unitArgsFiles lintDynFlagsAndSrcs = do
    131 131
       home_unit_graph <- forM initial_home_graph $ \homeUnitEnv -> do
    
    132 132
         let hue_flags = homeUnitEnv_dflags homeUnitEnv
    
    133 133
             dflags = homeUnitEnv_dflags homeUnitEnv
    
    134
    -    (unit_state,home_unit,mconstants) <- liftIO $ State.initUnits logger hue_flags (hsc_unit_index hsc_env) (hscEUDC hsc_env) home_units
    
    134
    +    (unit_state,home_unit,mconstants) <- liftIO $ State.initUnits logger hue_flags (hscUIC hsc_env) (hscEUDC hsc_env) home_units
    
    135 135
     
    
    136 136
         updated_dflags <- liftIO $ updatePlatformConstants dflags mconstants
    
    137 137
         emptyHpt <- liftIO $ emptyHomePackageTable
    

  • compiler/GHC/Unit/Env.hs
    ... ... @@ -40,6 +40,8 @@ module GHC.Unit.Env
    40 40
         ( UnitEnv (..)
    
    41 41
         , initUnitEnv
    
    42 42
         , ueEPS -- Not really needed, get directly type families and rule base!
    
    43
    +    , ueEUD
    
    44
    +    , ueUI
    
    43 45
         , updateHug
    
    44 46
         -- * Unit Env helper functions
    
    45 47
         , ue_currentHomeUnitEnv
    
    ... ... @@ -110,6 +112,7 @@ import qualified Data.Set as Set
    110 112
     
    
    111 113
     import GHC.Unit.External
    
    112 114
     import GHC.Unit.External.Database
    
    115
    +import GHC.Unit.External.Index
    
    113 116
     import GHC.Unit.State
    
    114 117
     import GHC.Unit.Home
    
    115 118
     import GHC.Unit.Types
    
    ... ... @@ -131,7 +134,6 @@ import GHC.Types.Annotations
    131 134
     import GHC.Types.CompleteMatch
    
    132 135
     import GHC.Core.InstEnv
    
    133 136
     import GHC.Core.FamInstEnv
    
    134
    -import Data.IORef
    
    135 137
     
    
    136 138
     --------------------------------------------------------------------------------
    
    137 139
     -- The hard queries
    
    ... ... @@ -177,19 +179,28 @@ data UnitEnv = UnitEnv
    177 179
             -- ^ GHC name/version (used for dynamic library suffix)
    
    178 180
     
    
    179 181
         , ue_eud :: {-# UNPACK #-} !(ExternalUnitDatabaseCache UnitId)
    
    180
    -        -- TODO: @fendor Docs
    
    181
    -    , ue_unit_index :: {-# UNPACK #-} !(IORef UnitIndex)
    
    182
    -        -- TODO: @fendor Docs
    
    182
    +        -- ^ Global cache of already read package databases
    
    183
    +
    
    184
    +    , ue_uic :: {-# UNPACK #-} !UnitIndexCache
    
    185
    +        -- ^ Index of already processed 'UnitInfo's.
    
    186
    +        -- Shares state over all 'UnitState' in the 'HomeUnitGraph'.
    
    183 187
         }
    
    184 188
     
    
    185 189
     ueEPS :: UnitEnv -> IO ExternalPackageState
    
    186 190
     ueEPS = eucEPS . ue_eps
    
    187 191
     
    
    192
    +ueEUD :: UnitEnv -> IO (ExternalUnitDatabases UnitId)
    
    193
    +ueEUD = readExternalUnitDatabases . ue_eud
    
    194
    +
    
    195
    +ueUI :: UnitEnv -> IO UnitIndex
    
    196
    +ueUI = readUnitIndex . ue_uic
    
    197
    +
    
    198
    +
    
    188 199
     initUnitEnv :: UnitId -> HomeUnitGraph -> GhcNameVersion -> Platform -> IO UnitEnv
    
    189 200
     initUnitEnv cur_unit hug namever platform = do
    
    190 201
       eps <- initExternalUnitCache
    
    191 202
       eud <- initExternalUnitDatabaseCache
    
    192
    -  unit_index <- newIORef (initUnitIndex)
    
    203
    +  uic <- initUnitIndexCache
    
    193 204
       return $ UnitEnv
    
    194 205
         { ue_eps             = eps
    
    195 206
         , ue_home_unit_graph = hug
    
    ... ... @@ -198,7 +209,7 @@ initUnitEnv cur_unit hug namever platform = do
    198 209
         , ue_platform        = platform
    
    199 210
         , ue_namever         = namever
    
    200 211
         , ue_eud             = eud
    
    201
    -    , ue_unit_index      = unit_index
    
    212
    +    , ue_uic      = uic
    
    202 213
         }
    
    203 214
     
    
    204 215
     updateHug :: (HomeUnitGraph -> HomeUnitGraph) -> UnitEnv -> UnitEnv
    

  • compiler/GHC/Unit/External/Database.hs
    1 1
     module GHC.Unit.External.Database (
    
    2
    -  -- *
    
    2
    +  -- * Mutable cache for 'ExternalUnitDatabases'
    
    3 3
       ExternalUnitDatabaseCache (..),
    
    4 4
       initExternalUnitDatabaseCache,
    
    5 5
       readExternalUnitDatabases,
    
    6 6
       readExternalUnitDatabase,
    
    7 7
       cacheExternalUnitDatabase,
    
    8 8
       clearExternalUnitDatabaseCache,
    
    9
    -  -- *
    
    9
    +  -- * 'ExternalUnitDatabases'
    
    10 10
       ExternalUnitDatabases,
    
    11 11
       emptyExternalUnitDatabases,
    
    12 12
       insertExternalUnitDatabases,
    
    13 13
       deleteExternalUnitDatabases,
    
    14 14
       lookupExternalUnitDatabases,
    
    15
    -  -- *
    
    15
    +  -- * 'UnitDatabase'
    
    16 16
       UnitDatabase (..),
    
    17
    +  mergeDatabases,
    
    18
    +  UnitPrecedenceMap,
    
    19
    +  sortByPreference,
    
    20
    +  compareByPreference,
    
    21
    +  -- * Reading packages from disk.
    
    22
    +  UnitDbConfig(..),
    
    23
    +  readOrGetUnitDatabase,
    
    24
    +  readUnitDatabases,
    
    25
    +  readUnitDatabase,
    
    26
    +  getUnitDbRefs,
    
    27
    +  resolveUnitDatabase,
    
    17 28
     ) where
    
    18 29
     
    
    19 30
     import GHC.Prelude
    
    20 31
     
    
    21
    -import GHC.Data.OsPath
    
    32
    +import GHC.Data.Maybe
    
    33
    +import GHC.Data.OsPath (OsPath)
    
    34
    +import GHC.Data.OsPath qualified as OsPath
    
    35
    +import GHC.Data.ShortText qualified as ST
    
    36
    +import GHC.Driver.DynFlags
    
    37
    +import GHC.Platform.ArchOS
    
    38
    +import GHC.Types.Unique.Map
    
    39
    +import GHC.Unit.Database
    
    22 40
     import GHC.Unit.Info
    
    23
    -import GHC.Utils.Outputable
    
    41
    +import GHC.Unit.Types
    
    42
    +import GHC.Utils.Error
    
    43
    +import GHC.Utils.Exception
    
    44
    +import GHC.Utils.Logger
    
    45
    +import GHC.Utils.Misc
    
    46
    +import GHC.Utils.Outputable as Outputable
    
    47
    +import GHC.Utils.Panic
    
    24 48
     
    
    25
    -import Data.IORef (IORef)
    
    49
    +import Control.Monad
    
    50
    +import Data.Char
    
    51
    +import Data.IORef
    
    26 52
     import Data.IORef qualified as IORef
    
    27
    -import Data.Map.Strict
    
    53
    +import Data.List (sortBy)
    
    54
    +import Data.Map.Strict (Map)
    
    28 55
     import Data.Map.Strict qualified as Map
    
    56
    +import Data.Ord
    
    57
    +import Data.Set (Set)
    
    58
    +import Data.Set qualified as Set
    
    59
    +import System.Directory
    
    60
    +import System.Environment (getEnv)
    
    61
    +import System.FilePath as FilePath
    
    29 62
     
    
    30 63
     -- ----------------------------------------------------------------------------
    
    31 64
     -- ExternalUnitDatabaseCache
    
    ... ... @@ -102,3 +135,273 @@ data UnitDatabase unit = UnitDatabase
    102 135
     
    
    103 136
     instance (Outputable u) => Outputable (UnitDatabase u) where
    
    104 137
       ppr (UnitDatabase fp _u) = text "DB:" <+> ppr fp
    
    138
    +
    
    139
    +-- ----------------------------------------------------------------------------
    
    140
    +--
    
    141
    +-- Merging databases
    
    142
    +--
    
    143
    +
    
    144
    +-- | For each unit, a mapping from uid -> i indicates that this
    
    145
    +-- unit was brought into GHC by the ith @-package-db@ flag on
    
    146
    +-- the command line.  We use this mapping to make sure we prefer
    
    147
    +-- units that were defined later on the command line, if there
    
    148
    +-- is an ambiguity.
    
    149
    +type UnitPrecedenceMap = UniqMap UnitId Int
    
    150
    +
    
    151
    +-- | Given a list of databases, merge them together, where
    
    152
    +-- units with the same unit id in later databases override
    
    153
    +-- earlier ones.  This does NOT check if the resulting database
    
    154
    +-- makes sense (that's done by 'validateDatabase').
    
    155
    +mergeDatabases :: Logger -> [UnitDatabase UnitId]
    
    156
    +               -> IO (UnitInfoMap, UnitPrecedenceMap)
    
    157
    +mergeDatabases logger = foldM merge (emptyUniqMap, emptyUniqMap) . zip [1..]
    
    158
    +  where
    
    159
    +    merge (pkg_map, prec_map) (i, UnitDatabase db_path db) = do
    
    160
    +      debugTraceMsg logger 2 $
    
    161
    +          text "loading package database" <+> ppr db_path
    
    162
    +      when (logVerbAtLeast logger 2) $
    
    163
    +        forM_ (Set.toList override_set) $ \pkg ->
    
    164
    +            debugTraceMsg logger 2 $
    
    165
    +                text "package" <+> ppr pkg <+>
    
    166
    +                text "overrides a previously defined package"
    
    167
    +      return (pkg_map', prec_map')
    
    168
    +     where
    
    169
    +      db_map = mk_pkg_map db
    
    170
    +      mk_pkg_map = listToUniqMap . map (\p -> (unitId p, p))
    
    171
    +
    
    172
    +      -- The set of UnitIds which appear in both db and pkgs.  These are the
    
    173
    +      -- ones that get overridden.  Compute this just to give some
    
    174
    +      -- helpful debug messages at -v2
    
    175
    +      override_set :: Set UnitId
    
    176
    +      override_set = Set.intersection (nonDetUniqMapToKeySet db_map)
    
    177
    +                                      (nonDetUniqMapToKeySet pkg_map)
    
    178
    +
    
    179
    +      -- Now merge the sets together (NB: in case of duplicate,
    
    180
    +      -- first argument preferred)
    
    181
    +      pkg_map' :: UnitInfoMap
    
    182
    +      pkg_map' = pkg_map `plusUniqMap` db_map
    
    183
    +
    
    184
    +      prec_map' :: UnitPrecedenceMap
    
    185
    +      prec_map' = prec_map `plusUniqMap` (mapUniqMap (const i) db_map)
    
    186
    +
    
    187
    +-- | This sorts a list of packages, putting "preferred" packages first.
    
    188
    +-- See 'compareByPreference' for the semantics of "preference".
    
    189
    +sortByPreference :: UnitPrecedenceMap -> [UnitInfo] -> [UnitInfo]
    
    190
    +sortByPreference prec_map = sortBy (flip (compareByPreference prec_map))
    
    191
    +
    
    192
    +-- | Returns 'GT' if @pkg@ should be preferred over @pkg'@ when picking
    
    193
    +-- which should be "active".  Here is the order of preference:
    
    194
    +--
    
    195
    +--      1. First, prefer the latest version
    
    196
    +--      2. If the versions are the same, prefer the package that
    
    197
    +--      came in the latest package database.
    
    198
    +--
    
    199
    +-- Pursuant to #12518, we could change this policy to, for example, remove
    
    200
    +-- the version preference, meaning that we would always prefer the units
    
    201
    +-- in later unit database.
    
    202
    +compareByPreference
    
    203
    +    :: UnitPrecedenceMap
    
    204
    +    -> UnitInfo
    
    205
    +    -> UnitInfo
    
    206
    +    -> Ordering
    
    207
    +compareByPreference prec_map pkg pkg'
    
    208
    +  = case comparing unitPackageVersion pkg pkg' of
    
    209
    +        GT -> GT
    
    210
    +        EQ | Just prec  <- lookupUniqMap prec_map (unitId pkg)
    
    211
    +           , Just prec' <- lookupUniqMap prec_map (unitId pkg')
    
    212
    +           -- Prefer the unit from the later DB flag (i.e., higher
    
    213
    +           -- precedence)
    
    214
    +           -> compare prec prec'
    
    215
    +           | otherwise
    
    216
    +           -> EQ
    
    217
    +        LT -> LT
    
    218
    +
    
    219
    +-- -----------------------------------------------------------------------------
    
    220
    +-- Reading the unit database(s)
    
    221
    +
    
    222
    +data UnitDbConfig = UnitDbConfig
    
    223
    +  { unitDbConfigFlagsDB :: [PackageDBFlag]
    
    224
    +  , unitDbConfigProgramName :: String
    
    225
    +  , unitDbConfigDBName :: FilePath
    
    226
    +  , unitDbConfigPlatformArchOS :: ArchOS
    
    227
    +  , unitDbConfigGlobalDB :: FilePath
    
    228
    +  , unitDbConfigGHCDir :: FilePath
    
    229
    +  }
    
    230
    +
    
    231
    +readUnitDatabases :: Logger -> ExternalUnitDatabaseCache UnitId -> UnitDbConfig -> IO [UnitDatabase UnitId]
    
    232
    +readUnitDatabases logger db_cache cfg = do
    
    233
    +  conf_refs <- getUnitDbRefs cfg
    
    234
    +  confs     <- liftM catMaybes $ mapM (resolveUnitDatabase cfg) conf_refs
    
    235
    +  mapM (readOrGetUnitDatabase logger db_cache cfg) confs
    
    236
    +
    
    237
    +
    
    238
    +getUnitDbRefs :: UnitDbConfig -> IO [PkgDbRef]
    
    239
    +getUnitDbRefs cfg = do
    
    240
    +  let system_conf_refs = [UserPkgDb, GlobalPkgDb]
    
    241
    +
    
    242
    +  e_pkg_path <- tryIO (getEnv $ map toUpper (unitDbConfigProgramName cfg) ++ "_PACKAGE_PATH")
    
    243
    +  let base_conf_refs = case e_pkg_path of
    
    244
    +        Left _ -> system_conf_refs
    
    245
    +        Right path
    
    246
    +         | Just (xs, x) <- snocView path, isSearchPathSeparator x
    
    247
    +         -> map PkgDbPath (OsPath.splitSearchPath (OsPath.unsafeEncodeUtf xs)) ++ system_conf_refs
    
    248
    +         | otherwise
    
    249
    +         -> map PkgDbPath (OsPath.splitSearchPath (OsPath.unsafeEncodeUtf path))
    
    250
    +
    
    251
    +  -- Apply the package DB-related flags from the command line to get the
    
    252
    +  -- final list of package DBs.
    
    253
    +  --
    
    254
    +  -- Notes on ordering:
    
    255
    +  --  * The list of flags is reversed (later ones first)
    
    256
    +  --  * We work with the package DB list in "left shadows right" order
    
    257
    +  --  * and finally reverse it at the end, to get "right shadows left"
    
    258
    +  --
    
    259
    +  return $ reverse (foldr doFlag base_conf_refs (unitDbConfigFlagsDB cfg))
    
    260
    + where
    
    261
    +  doFlag (PackageDB p) dbs = p : dbs
    
    262
    +  doFlag NoUserPackageDB dbs = filter isNotUser dbs
    
    263
    +  doFlag NoGlobalPackageDB dbs = filter isNotGlobal dbs
    
    264
    +  doFlag ClearPackageDBs _ = []
    
    265
    +
    
    266
    +  isNotUser UserPkgDb = False
    
    267
    +  isNotUser _ = True
    
    268
    +
    
    269
    +  isNotGlobal GlobalPkgDb = False
    
    270
    +  isNotGlobal _ = True
    
    271
    +
    
    272
    +-- | Return the path of a package database from a 'PkgDbRef'. Return 'Nothing'
    
    273
    +-- when the user database filepath is expected but the latter doesn't exist.
    
    274
    +--
    
    275
    +-- NB: This logic is reimplemented in Cabal, so if you change it,
    
    276
    +-- make sure you update Cabal. (Or, better yet, dump it in the
    
    277
    +-- compiler info so Cabal can use the info.)
    
    278
    +resolveUnitDatabase :: UnitDbConfig -> PkgDbRef -> IO (Maybe OsPath)
    
    279
    +resolveUnitDatabase cfg GlobalPkgDb = return $ Just $ OsPath.unsafeEncodeUtf $ unitDbConfigGlobalDB cfg
    
    280
    +resolveUnitDatabase cfg UserPkgDb = runMaybeT $ do
    
    281
    +  dir <- versionedAppDir (unitDbConfigProgramName cfg) (unitDbConfigPlatformArchOS cfg)
    
    282
    +  let pkgconf = dir </> unitDbConfigDBName cfg
    
    283
    +  exist <- tryMaybeT $ doesDirectoryExist pkgconf
    
    284
    +  if exist then return (OsPath.unsafeEncodeUtf pkgconf) else mzero
    
    285
    +resolveUnitDatabase _ (PkgDbPath name) = return $ Just name
    
    286
    +
    
    287
    +-- | Get the cached 'UnitDatabase' or read the 'UnitDatabase' at the given location.
    
    288
    +readOrGetUnitDatabase :: Logger -> ExternalUnitDatabaseCache UnitId -> UnitDbConfig -> OsPath -> IO (UnitDatabase UnitId)
    
    289
    +readOrGetUnitDatabase logger db_cache cfg conf_file =
    
    290
    +  readExternalUnitDatabase db_cache conf_file >>= \ case
    
    291
    +    Nothing -> do
    
    292
    +      new_db <- readUnitDatabase logger cfg conf_file
    
    293
    +      cacheExternalUnitDatabase db_cache new_db
    
    294
    +      pure new_db
    
    295
    +    Just db ->
    
    296
    +      pure db
    
    297
    +
    
    298
    +-- | Read the 'UnitDatabase' at the given location.
    
    299
    +readUnitDatabase :: Logger -> UnitDbConfig -> OsPath -> IO (UnitDatabase UnitId)
    
    300
    +readUnitDatabase logger cfg conf_file = do
    
    301
    +  isdir <- OsPath.doesDirectoryExist conf_file
    
    302
    +
    
    303
    +  proto_pkg_configs <-
    
    304
    +    if isdir
    
    305
    +       then readDirStyleUnitInfo conf_file
    
    306
    +       else do
    
    307
    +            isfile <- OsPath.doesFileExist conf_file
    
    308
    +            if isfile
    
    309
    +               then do
    
    310
    +                 mpkgs <- tryReadOldFileStyleUnitInfo
    
    311
    +                 case mpkgs of
    
    312
    +                   Just pkgs -> return pkgs
    
    313
    +                   Nothing   -> throwGhcExceptionIO $ InstallationError $
    
    314
    +                      "ghc no longer supports single-file style package " ++
    
    315
    +                      "databases (" ++ show conf_file ++
    
    316
    +                      ") use 'ghc-pkg init' to create the database with " ++
    
    317
    +                      "the correct format."
    
    318
    +               else throwGhcExceptionIO $ InstallationError $
    
    319
    +                      "can't find a package database at " ++ show conf_file
    
    320
    +
    
    321
    +  let
    
    322
    +      -- Fix #16360: remove trailing slash from conf_file before calculating pkgroot
    
    323
    +      conf_file' = OsPath.dropTrailingPathSeparator conf_file
    
    324
    +      top_dir = OsPath.unsafeEncodeUtf (unitDbConfigGHCDir cfg)
    
    325
    +      pkgroot = OsPath.takeDirectory conf_file'
    
    326
    +      pkg_configs1 = map (mungeUnitInfo top_dir pkgroot . mapUnitInfo (\(UnitKey x) -> UnitId x) . mkUnitKeyInfo)
    
    327
    +                         proto_pkg_configs
    
    328
    +  --
    
    329
    +  pkg_configs2 <- traverse evaluateUnitInfo pkg_configs1
    
    330
    +  return $ pkg_configs2 `seqList` UnitDatabase conf_file' pkg_configs2
    
    331
    +  where
    
    332
    +    readDirStyleUnitInfo :: OsPath -> IO [DbUnitInfo]
    
    333
    +    readDirStyleUnitInfo conf_dir = do
    
    334
    +      let filename = conf_dir OsPath.</> (OsPath.unsafeEncodeUtf "package.cache")
    
    335
    +      cache_exists <- OsPath.doesFileExist filename
    
    336
    +      if cache_exists
    
    337
    +        then do
    
    338
    +          debugTraceMsg logger 2 $ text "Using binary package database:" <+> ppr filename
    
    339
    +          readPackageDbForGhc filename
    
    340
    +        else do
    
    341
    +          -- If there is no package.cache file, we check if the database is not
    
    342
    +          -- empty by inspecting if the directory contains any .conf file. If it
    
    343
    +          -- does, something is wrong and we fail. Otherwise we assume that the
    
    344
    +          -- database is empty.
    
    345
    +          debugTraceMsg logger 2 $ text "There is no package.cache in"
    
    346
    +                      <+> ppr conf_dir
    
    347
    +                       <> text ", checking if the database is empty"
    
    348
    +          db_empty <- all (not . OsPath.isSuffixOf (OsPath.unsafeEncodeUtf ".conf"))
    
    349
    +                   <$> OsPath.getDirectoryContents conf_dir
    
    350
    +          if db_empty
    
    351
    +            then do
    
    352
    +              debugTraceMsg logger 3 $ text "There are no .conf files in"
    
    353
    +                          <+> ppr conf_dir <> text ", treating"
    
    354
    +                          <+> text "package database as empty"
    
    355
    +              return []
    
    356
    +            else
    
    357
    +              throwGhcExceptionIO $ InstallationError $
    
    358
    +                "there is no package.cache in " ++ show conf_dir ++
    
    359
    +                " even though package database is not empty"
    
    360
    +
    
    361
    +
    
    362
    +    -- Single-file style package dbs have been deprecated for some time, but
    
    363
    +    -- it turns out that Cabal was using them in one place. So this is a
    
    364
    +    -- workaround to allow older Cabal versions to use this newer ghc.
    
    365
    +    -- We check if the file db contains just "[]" and if so, we look for a new
    
    366
    +    -- dir-style db in conf_file.d/, ie in a dir next to the given file.
    
    367
    +    -- We cannot just replace the file with a new dir style since Cabal still
    
    368
    +    -- assumes it's a file and tries to overwrite with 'writeFile'.
    
    369
    +    -- ghc-pkg also cooperates with this workaround.
    
    370
    +    tryReadOldFileStyleUnitInfo = do
    
    371
    +      content <- readFile (OsPath.unsafeDecodeUtf conf_file) `catchIO` \_ -> return ""
    
    372
    +      if take 2 content == "[]"
    
    373
    +        then do
    
    374
    +          let conf_dir = conf_file OsPath.<.> OsPath.unsafeEncodeUtf "d"
    
    375
    +          direxists <- OsPath.doesDirectoryExist conf_dir
    
    376
    +          if direxists
    
    377
    +             then do debugTraceMsg logger 2 (text "Ignoring old file-style db and trying:" <+> ppr conf_dir)
    
    378
    +                     liftM Just (readDirStyleUnitInfo conf_dir)
    
    379
    +             else return (Just []) -- ghc-pkg will create it when it's updated
    
    380
    +        else return Nothing
    
    381
    +
    
    382
    +mungeUnitInfo :: OsPath -> OsPath
    
    383
    +                   -> UnitInfo -> UnitInfo
    
    384
    +mungeUnitInfo top_dir pkgroot =
    
    385
    +    mungeBytecodeLibFields
    
    386
    +  . mungeLibDirFields
    
    387
    +  . mungeUnitInfoPaths (ST.pack (OsPath.unsafeDecodeUtf top_dir)) (ST.pack (OsPath.unsafeDecodeUtf pkgroot))
    
    388
    +
    
    389
    +mungeLibDirFields :: UnitInfo -> UnitInfo
    
    390
    +mungeLibDirFields pkg =
    
    391
    +    pkg {
    
    392
    +      unitLibraryDynDirs = case unitLibraryDynDirs pkg of
    
    393
    +         [] -> unitLibraryDirs pkg
    
    394
    +         ds -> ds
    
    395
    +      , unitLibraryDirsStatic = case unitLibraryDirsStatic pkg of
    
    396
    +         [] -> unitLibraryDirs pkg
    
    397
    +         ds -> ds
    
    398
    +    }
    
    399
    +
    
    400
    +-- | Default to using library-dirs if bytecode library dirs is not explicitly set.
    
    401
    +mungeBytecodeLibFields :: UnitInfo -> UnitInfo
    
    402
    +mungeBytecodeLibFields pkg =
    
    403
    +    pkg {
    
    404
    +      unitLibraryBytecodeDirs = case unitLibraryBytecodeDirs pkg of
    
    405
    +         [] -> unitLibraryDirs pkg
    
    406
    +         ds -> ds
    
    407
    +    }

  • compiler/GHC/Unit/External/Index.hs
    1
    +module GHC.Unit.External.Index (
    
    2
    +  -- * The 'UnitIndexCache'.
    
    3
    +  -- A mutable wrapper around 'UnitIndex'
    
    4
    +  UnitIndexCache(..),
    
    5
    +  initUnitIndexCache,
    
    6
    +  readUnitIndex,
    
    7
    +  modifyUnitIndexCache,
    
    8
    +  clearUnitIndexCache,
    
    9
    +  -- * 'UnitIndex'
    
    10
    +  UnitIndex,
    
    11
    +  emptyUnitIndex,
    
    12
    +  wiringMap,
    
    13
    +  unwiringMap,
    
    14
    +  globalUnits,
    
    15
    +  setWireMap,
    
    16
    +  wireMapExists,
    
    17
    +  addUnitInfoMap,
    
    18
    +  -- * 'GlobalUnitInfoMap'
    
    19
    +  GlobalUnitInfoMap,
    
    20
    +  lookupGlobalUnitInfoMap,
    
    21
    +  emptyGlobalUnitInfoMap,
    
    22
    +  mkGlobalUnitInfoMap,
    
    23
    +  -- * 'GlobalUnitKey'
    
    24
    +  GlobalUnitKey,
    
    25
    +  UnitAbiHash,
    
    26
    +  mkGlobalUnitKey,
    
    27
    +  globalUnitKeyFromUnitInfo,
    
    28
    +  -- * Wired-in units
    
    29
    +  unwireUnit,
    
    30
    +  updateWiredInUnits,
    
    31
    +  updateWiredInUnitsInUnitInfo,
    
    32
    +  updateWiredInUnitIdInModule,
    
    33
    +) where
    
    34
    +
    
    35
    +import GHC.Prelude
    
    36
    +
    
    37
    +import GHC.Data.ShortText qualified as ST
    
    38
    +import GHC.Types.Unique.Map
    
    39
    +import GHC.Unit.Database
    
    40
    +import GHC.Unit.External.Wired
    
    41
    +import GHC.Unit.Info
    
    42
    +import GHC.Unit.Types
    
    43
    +
    
    44
    +import Data.IORef (IORef)
    
    45
    +import Data.IORef qualified as IORef
    
    46
    +import Data.Map.Strict (Map)
    
    47
    +import Data.Map.Strict qualified as Map
    
    48
    +
    
    49
    +-- ----------------------------------------------------------------------------
    
    50
    +-- UnitIndex
    
    51
    +-- ----------------------------------------------------------------------------
    
    52
    +
    
    53
    +newtype UnitIndexCache = UnitIndexCache
    
    54
    +  { uic_index :: IORef UnitIndex
    
    55
    +  }
    
    56
    +
    
    57
    +initUnitIndexCache :: IO UnitIndexCache
    
    58
    +initUnitIndexCache =
    
    59
    +  UnitIndexCache <$> IORef.newIORef emptyUnitIndex
    
    60
    +
    
    61
    +readUnitIndex :: UnitIndexCache -> IO UnitIndex
    
    62
    +readUnitIndex eudc =
    
    63
    +  IORef.readIORef (uic_index eudc)
    
    64
    +
    
    65
    +modifyUnitIndexCache :: UnitIndexCache -> (UnitIndex -> UnitIndex) -> IO ()
    
    66
    +modifyUnitIndexCache eudc f =
    
    67
    +  IORef.modifyIORef' (uic_index eudc) f
    
    68
    +
    
    69
    +clearUnitIndexCache :: UnitIndexCache -> IO ()
    
    70
    +clearUnitIndexCache eudc =
    
    71
    +  modifyUnitIndexCache eudc (const emptyUnitIndex)
    
    72
    +
    
    73
    +data UnitIndex = UnitIndex
    
    74
    +  { ui_wireMap :: !WireMap
    
    75
    +    -- ^ A mapping from database unit keys to wired in unit ids.
    
    76
    +  , ui_unwireMap :: !UnwireMap
    
    77
    +    -- ^ A mapping from wired in unit ids to unit keys from the database.
    
    78
    +  , ui_unitInfoMap :: !GlobalUnitInfoMap
    
    79
    +    -- ^ TODO @fendor: document
    
    80
    +  }
    
    81
    +
    
    82
    +wiringMap :: UnitIndex -> WireMap
    
    83
    +wiringMap = ui_wireMap
    
    84
    +
    
    85
    +unwiringMap :: UnitIndex -> UnwireMap
    
    86
    +unwiringMap = ui_unwireMap
    
    87
    +
    
    88
    +globalUnits :: UnitIndex -> GlobalUnitInfoMap
    
    89
    +globalUnits = ui_unitInfoMap
    
    90
    +
    
    91
    +emptyUnitIndex :: UnitIndex
    
    92
    +emptyUnitIndex = UnitIndex
    
    93
    +  { ui_wireMap = emptyWireMap
    
    94
    +  , ui_unwireMap = emptyUnwireMap
    
    95
    +  , ui_unitInfoMap = emptyGlobalUnitInfoMap
    
    96
    +  }
    
    97
    +
    
    98
    +setWireMap :: WireMap -> UnitIndex -> UnitIndex
    
    99
    +setWireMap wired_map unit_index =
    
    100
    +  unit_index
    
    101
    +    { ui_wireMap = wired_map
    
    102
    +    , ui_unwireMap = unwiringMapFromWireMap wired_map
    
    103
    +    }
    
    104
    +
    
    105
    +wireMapExists :: UnitIndex -> Bool
    
    106
    +wireMapExists unit_index =
    
    107
    +  not $ isWireMapEmpty (ui_wireMap unit_index)
    
    108
    +
    
    109
    +addUnitInfoMap :: UnitInfoMap -> UnitIndex -> UnitIndex
    
    110
    +addUnitInfoMap unit_info_map unit_index =
    
    111
    +  unit_index
    
    112
    +    { ui_unitInfoMap =
    
    113
    +        -- Order should not matter, either it is exactly the same 'UnitInfo',
    
    114
    +        -- or a new one.
    
    115
    +        GlobalUnitInfoMap $ plusUniqMap_C Map.union newEntriesMap oldMap
    
    116
    +    }
    
    117
    +  where
    
    118
    +    GlobalUnitInfoMap newEntriesMap = mkGlobalUnitInfoMap $ nonDetUniqMapToList unit_info_map
    
    119
    +    GlobalUnitInfoMap oldMap = ui_unitInfoMap unit_index
    
    120
    +
    
    121
    +-- ----------------------------------------------------------------------------
    
    122
    +-- GlobalUnitInfoMap
    
    123
    +-- ----------------------------------------------------------------------------
    
    124
    +
    
    125
    +type UnitAbiHash = ST.ShortText
    
    126
    +
    
    127
    +-- | A
    
    128
    +newtype GlobalUnitInfoMap = GlobalUnitInfoMap (UniqMap UnitId (Map UnitAbiHash UnitInfo))
    
    129
    +
    
    130
    +lookupGlobalUnitInfoMap :: GlobalUnitKey -> GlobalUnitInfoMap -> Maybe UnitInfo
    
    131
    +lookupGlobalUnitInfoMap (GlobalUnitKey uid abiHash) (GlobalUnitInfoMap globalMap) =
    
    132
    +  case lookupUniqMap globalMap uid of
    
    133
    +    Nothing -> Nothing
    
    134
    +    Just sameUnitId -> Map.lookup abiHash sameUnitId
    
    135
    +
    
    136
    +mkGlobalUnitInfoMap :: [(UnitId, UnitInfo)] -> GlobalUnitInfoMap
    
    137
    +mkGlobalUnitInfoMap unitInfos =
    
    138
    +  GlobalUnitInfoMap $ listToUniqMap_C Map.union (map mkEntry unitInfos)
    
    139
    + where
    
    140
    +  mkEntry (uid, v) = (uid, Map.singleton (unitAbiHash v) v)
    
    141
    +
    
    142
    +emptyGlobalUnitInfoMap :: GlobalUnitInfoMap
    
    143
    +emptyGlobalUnitInfoMap = GlobalUnitInfoMap emptyUniqMap
    
    144
    +
    
    145
    +-- ----------------------------------------------------------------------------
    
    146
    +-- GlobalUnitKey
    
    147
    +-- ----------------------------------------------------------------------------
    
    148
    +
    
    149
    +-- | A 'GlobalUnitKey' is a key that can globally identify a 'UnitInfo', not just
    
    150
    +-- in the 'UnitInfoMap'.
    
    151
    +data GlobalUnitKey =
    
    152
    +  GlobalUnitKey
    
    153
    +    !UnitId -- ^ Unit Id of the 'UnitInfo'
    
    154
    +    !UnitAbiHash -- ^ ABI hash of the 'UnitInfo'
    
    155
    +
    
    156
    +globalUnitKeyFromUnitInfo :: UnitInfo -> GlobalUnitKey
    
    157
    +globalUnitKeyFromUnitInfo ui = mkGlobalUnitKey (unitId ui) (unitAbiHash ui)
    
    158
    +
    
    159
    +mkGlobalUnitKey :: UnitId -> UnitAbiHash -> GlobalUnitKey
    
    160
    +mkGlobalUnitKey = GlobalUnitKey
    
    161
    +
    
    162
    +-- -----------------------------------------------------------------------------
    
    163
    +-- Wired-in units
    
    164
    +--
    
    165
    +-- See Note [Wired-in units] in GHC.Unit.Types
    
    166
    +
    
    167
    +-- | Given a wired-in 'Unit', "unwire" it into the 'Unit'
    
    168
    +-- that it was recorded as in the package database.
    
    169
    +unwireUnit :: UnitIndex -> Unit -> Unit
    
    170
    +unwireUnit state uid@(RealUnit (Definite def_uid)) =
    
    171
    +    maybe uid (RealUnit . Definite) (lookupUnwireMap def_uid (unwiringMap state))
    
    172
    +unwireUnit _ uid = uid
    
    173
    +
    
    174
    +updateWiredInUnits :: WireMap -> GlobalUnitInfoMap -> [UnitInfo] -> [Either UnitInfo UnitInfo]
    
    175
    +updateWiredInUnits wiredInMap knownInfos pkgs =
    
    176
    +  map (updateWiredInUnitsInUnitInfo wiredInMap knownInfos) pkgs
    
    177
    +
    
    178
    +updateWiredInUnitsInUnitInfo :: WireMap -> GlobalUnitInfoMap -> UnitInfo -> Either UnitInfo UnitInfo
    
    179
    +updateWiredInUnitsInUnitInfo wiredInMap knownInfos pkg =
    
    180
    +  let
    
    181
    +    upd_wired_in_pkg wiredInUnitId pkg =
    
    182
    +      pkg { unitId         = wiredInUnitId
    
    183
    +          , unitInstanceOf = wiredInUnitId
    
    184
    +              -- every non instantiated unit is an instance of
    
    185
    +              -- itself (required by Backpack...)
    
    186
    +              --
    
    187
    +              -- See Note [About units] in GHC.Unit
    
    188
    +          }
    
    189
    +
    
    190
    +    upd_deps pkg = pkg {
    
    191
    +          unitDepends = map (upd_wired_in wiredInMap) (unitDepends pkg),
    
    192
    +          unitExposedModules
    
    193
    +            = map (\(k,v) -> (k, fmap (updateWiredInUnitIdInModule wiredInMap) v))
    
    194
    +                  (unitExposedModules pkg)
    
    195
    +        }
    
    196
    +  in
    
    197
    +    case lookupWireMap (unitId pkg) wiredInMap of
    
    198
    +      Just wiredIn ->
    
    199
    +        case lookupGlobalUnitInfoMap (mkGlobalUnitKey wiredIn (unitAbiHash pkg)) knownInfos of
    
    200
    +          Just ui ->
    
    201
    +            Right ui
    
    202
    +          Nothing ->
    
    203
    +            let
    
    204
    +              updated_pkg = upd_deps $ upd_wired_in_pkg wiredIn pkg
    
    205
    +            in
    
    206
    +              Left $ seqUnitInfo updated_pkg updated_pkg
    
    207
    +      Nothing -> case lookupGlobalUnitInfoMap (globalUnitKeyFromUnitInfo pkg) knownInfos of
    
    208
    +        Just ui ->
    
    209
    +          Right ui
    
    210
    +        Nothing ->
    
    211
    +          let
    
    212
    +            updated_pkg = upd_deps pkg
    
    213
    +          in
    
    214
    +            Left $ seqUnitInfo updated_pkg updated_pkg
    
    215
    +
    
    216
    +-- Helper functions for rewiring Module and Unit.  These
    
    217
    +-- rewrite Units of modules in wired-in packages to the form known to the
    
    218
    +-- compiler, as described in Note [Wired-in units] in GHC.Unit.Types.
    
    219
    +--
    
    220
    +-- For instance, base-4.9.0.0 will be rewritten to just base, to match
    
    221
    +-- what appears in GHC.Builtin.Names.
    
    222
    +
    
    223
    +updateWiredInUnitIdInModule :: WireMap -> Module -> Module
    
    224
    +updateWiredInUnitIdInModule wiredInMap (Module uid m) = Module (upd_wired_in_uid wiredInMap uid) m
    
    225
    +
    
    226
    +upd_wired_in_uid :: WireMap -> Unit -> Unit
    
    227
    +upd_wired_in_uid wiredInMap u = case u of
    
    228
    +   HoleUnit -> HoleUnit
    
    229
    +   RealUnit (Definite uid) -> RealUnit (Definite (upd_wired_in wiredInMap uid))
    
    230
    +   VirtUnit indef_uid ->
    
    231
    +      VirtUnit $ mkInstantiatedUnit
    
    232
    +        (instUnitInstanceOf indef_uid)
    
    233
    +        (map (\(x,y) -> (x,updateWiredInUnitIdInModule wiredInMap y)) (instUnitInsts indef_uid))
    
    234
    +
    
    235
    +upd_wired_in :: WireMap -> UnitId -> UnitId
    
    236
    +upd_wired_in wiredInMap key
    
    237
    +    | Just key' <- lookupWireMap key wiredInMap = key'
    
    238
    +    | otherwise = key

  • compiler/GHC/Unit/External/ModuleOrigin.hs
    1
    +module GHC.Unit.External.ModuleOrigin (
    
    2
    +  ModuleOrigin(..),
    
    3
    +  fromExposedModules,
    
    4
    +  fromReexportedModules,
    
    5
    +  fromFlag,
    
    6
    +  originVisible,
    
    7
    +  originEmpty,
    
    8
    +) where
    
    9
    +
    
    10
    +import GHC.Prelude
    
    11
    +import GHC.Unit.External.Validate
    
    12
    +import GHC.Unit.Info
    
    13
    +import GHC.Utils.Outputable
    
    14
    +import GHC.Utils.Panic
    
    15
    +import qualified Data.Semigroup as Semigroup
    
    16
    +
    
    17
    +-- | Given a module name, there may be multiple ways it came into scope,
    
    18
    +-- possibly simultaneously.  This data type tracks all the possible ways
    
    19
    +-- it could have come into scope.  Warning: don't use the record functions,
    
    20
    +-- they're partial!
    
    21
    +data ModuleOrigin =
    
    22
    +    -- | Module is hidden, and thus never will be available for import.
    
    23
    +    -- (But maybe the user didn't realize), so we'll still keep track
    
    24
    +    -- of these modules.)
    
    25
    +    ModHidden
    
    26
    +
    
    27
    +    -- | Module is unavailable because the unit is unusable.
    
    28
    +  | ModUnusable !UnusableUnit
    
    29
    +
    
    30
    +    -- | Module is public, and could have come from some places.
    
    31
    +  | ModOrigin {
    
    32
    +        -- | @Just False@ means that this module is in
    
    33
    +        -- someone's @exported-modules@ list, but that package is hidden;
    
    34
    +        -- @Just True@ means that it is available; @Nothing@ means neither
    
    35
    +        -- applies.
    
    36
    +        fromOrigUnit :: Maybe Bool
    
    37
    +        -- | Is the module available from a reexport of an exposed package?
    
    38
    +        -- There could be multiple.
    
    39
    +      , fromExposedReexport :: [UnitInfo]
    
    40
    +        -- | Is the module available from a reexport of a hidden package?
    
    41
    +      , fromHiddenReexport :: [UnitInfo]
    
    42
    +        -- | Did the module export come from a package flag? (ToDo: track
    
    43
    +        -- more information.
    
    44
    +      , fromPackageFlag :: Bool
    
    45
    +      }
    
    46
    +
    
    47
    +instance Outputable ModuleOrigin where
    
    48
    +    ppr ModHidden = text "hidden module"
    
    49
    +    ppr (ModUnusable _) = text "unusable module"
    
    50
    +    ppr (ModOrigin e res rhs f) = sep (punctuate comma (
    
    51
    +        (case e of
    
    52
    +            Nothing -> []
    
    53
    +            Just False -> [text "hidden package"]
    
    54
    +            Just True -> [text "exposed package"]) ++
    
    55
    +        (if null res
    
    56
    +            then []
    
    57
    +            else [text "reexport by" <+>
    
    58
    +                    sep (map (ppr . mkUnit) res)]) ++
    
    59
    +        (if null rhs
    
    60
    +            then []
    
    61
    +            else [text "hidden reexport by" <+>
    
    62
    +                    sep (map (ppr . mkUnit) rhs)]) ++
    
    63
    +        (if f then [text "package flag"] else [])
    
    64
    +        ))
    
    65
    +
    
    66
    +-- | Smart constructor for a module which is in @exposed-modules@.  Takes
    
    67
    +-- as an argument whether or not the defining package is exposed.
    
    68
    +fromExposedModules :: Bool -> ModuleOrigin
    
    69
    +fromExposedModules e = ModOrigin (Just e) [] [] False
    
    70
    +
    
    71
    +-- | Smart constructor for a module which is in @reexported-modules@.  Takes
    
    72
    +-- as an argument whether or not the reexporting package is exposed, and
    
    73
    +-- also its 'UnitInfo'.
    
    74
    +fromReexportedModules :: Bool -> UnitInfo -> ModuleOrigin
    
    75
    +fromReexportedModules True pkg = ModOrigin Nothing [pkg] [] False
    
    76
    +fromReexportedModules False pkg = ModOrigin Nothing [] [pkg] False
    
    77
    +
    
    78
    +-- | Smart constructor for a module which was bound by a package flag.
    
    79
    +fromFlag :: ModuleOrigin
    
    80
    +fromFlag = ModOrigin Nothing [] [] True
    
    81
    +
    
    82
    +instance Semigroup ModuleOrigin where
    
    83
    +    x@(ModOrigin e res rhs f) <> y@(ModOrigin e' res' rhs' f') =
    
    84
    +        ModOrigin (g e e') (res ++ res') (rhs ++ rhs') (f || f')
    
    85
    +      where g (Just b) (Just b')
    
    86
    +                | b == b'   = Just b
    
    87
    +                | otherwise = pprPanic "ModOrigin: package both exposed/hidden" $
    
    88
    +                    text "x: " <> ppr x $$ text "y: " <> ppr y
    
    89
    +            g Nothing x = x
    
    90
    +            g x Nothing = x
    
    91
    +
    
    92
    +    x <> y = pprPanic "ModOrigin: module origin mismatch" $
    
    93
    +                 text "x: " <> ppr x $$ text "y: " <> ppr y
    
    94
    +
    
    95
    +instance Monoid ModuleOrigin where
    
    96
    +    mempty = ModOrigin Nothing [] [] False
    
    97
    +    mappend = (Semigroup.<>)
    
    98
    +
    
    99
    +-- | Is the name from the import actually visible? (i.e. does it cause
    
    100
    +-- ambiguity, or is it only relevant when we're making suggestions?)
    
    101
    +originVisible :: ModuleOrigin -> Bool
    
    102
    +originVisible ModHidden = False
    
    103
    +originVisible (ModUnusable _) = False
    
    104
    +originVisible (ModOrigin b res _ f) = b == Just True || not (null res) || f
    
    105
    +
    
    106
    +-- | Are there actually no providers for this module?  This will never occur
    
    107
    +-- except when we're filtering based on package imports.
    
    108
    +originEmpty :: ModuleOrigin -> Bool
    
    109
    +originEmpty (ModOrigin Nothing [] [] False) = True
    
    110
    +originEmpty _ = False

  • compiler/GHC/Unit/External/Providers.hs
    1
    +module GHC.Unit.External.Providers (
    
    2
    +  ModuleNameProvidersMap,
    
    3
    +  pprModuleMap,
    
    4
    +  mkModuleNameProvidersMap,
    
    5
    +  mkUnusableModuleNameProvidersMap,
    
    6
    +) where
    
    7
    +
    
    8
    +import GHC.Prelude
    
    9
    +
    
    10
    +import GHC.Data.Maybe
    
    11
    +import GHC.Types.Unique
    
    12
    +import GHC.Types.Unique.FM
    
    13
    +import GHC.Types.Unique.Map
    
    14
    +import GHC.Unit.External.ModuleOrigin
    
    15
    +import GHC.Unit.External.Query
    
    16
    +import GHC.Unit.External.Validate
    
    17
    +import GHC.Unit.External.Visibility
    
    18
    +import GHC.Unit.Info
    
    19
    +import GHC.Unit.Module
    
    20
    +import GHC.Utils.Error
    
    21
    +import GHC.Utils.Logger
    
    22
    +import GHC.Utils.Outputable
    
    23
    +import GHC.Utils.Panic
    
    24
    +
    
    25
    +-- | Map from 'ModuleName' to a set of module providers (i.e. a 'Module' and
    
    26
    +-- its 'ModuleOrigin').
    
    27
    +--
    
    28
    +-- NB: the set is in fact a 'Map Module ModuleOrigin', probably to keep only one
    
    29
    +-- origin for a given 'Module'
    
    30
    +
    
    31
    +type ModuleNameProvidersMap =
    
    32
    +    UniqMap ModuleName (UniqMap Module ModuleOrigin)
    
    33
    +
    
    34
    +-- | Show the mapping of modules to where they come from.
    
    35
    +pprModuleMap :: ModuleNameProvidersMap -> SDoc
    
    36
    +pprModuleMap mod_map =
    
    37
    +  vcat (map pprLine (nonDetUniqMapToList mod_map))
    
    38
    +    where
    
    39
    +      pprLine (m,e) = ppr m $$ nest 50 (vcat (map (pprEntry m) (nonDetUniqMapToList e)))
    
    40
    +      pprEntry :: Outputable a => ModuleName -> (Module, a) -> SDoc
    
    41
    +      pprEntry m (m',o)
    
    42
    +        | m == moduleName m' = ppr (moduleUnit m') <+> parens (ppr o)
    
    43
    +        | otherwise = ppr m' <+> parens (ppr o)
    
    44
    +
    
    45
    +-- -----------------------------------------------------------------------------
    
    46
    +-- | Makes the mapping from ModuleName to package info
    
    47
    +
    
    48
    +-- Slight irritation: we proceed by leafing through everything
    
    49
    +-- in the installed package database, which makes handling indefinite
    
    50
    +-- packages a bit bothersome.
    
    51
    +
    
    52
    +mkModuleNameProvidersMap
    
    53
    +  :: Logger
    
    54
    +  -> Bool
    
    55
    +  -> UnitInfoMap
    
    56
    +  -> VisibilityMap
    
    57
    +  -> ModuleNameProvidersMap
    
    58
    +mkModuleNameProvidersMap logger allowVirtualUnits pkg_map vis_map =
    
    59
    +    -- What should we fold on?  Both situations are awkward:
    
    60
    +    --
    
    61
    +    --    * Folding on the visibility map means that we won't create
    
    62
    +    --      entries for packages that aren't mentioned in vis_map
    
    63
    +    --      (e.g., hidden packages, causing #14717)
    
    64
    +    --
    
    65
    +    --    * Folding on pkg_map is awkward because if we have an
    
    66
    +    --      Backpack instantiation, we need to possibly add a
    
    67
    +    --      package from pkg_map multiple times to the actual
    
    68
    +    --      ModuleNameProvidersMap.  Also, we don't really want
    
    69
    +    --      definite package instantiations to show up in the
    
    70
    +    --      list of possibilities.
    
    71
    +    --
    
    72
    +    -- So what will we do instead?  We'll extend vis_map with
    
    73
    +    -- entries for every definite (for non-Backpack) and
    
    74
    +    -- indefinite (for Backpack) package, so that we get the
    
    75
    +    -- hidden entries we need.
    
    76
    +    nonDetFoldUniqMap extend_modmap emptyMap vis_map_extended
    
    77
    + where
    
    78
    +  vis_map_extended = {- preferred -} default_vis `plusUniqMap` vis_map
    
    79
    +
    
    80
    +  default_vis = listToUniqMap
    
    81
    +                  [ (mkUnit pkg, mempty)
    
    82
    +                  | (_, pkg) <- nonDetUniqMapToList pkg_map
    
    83
    +                  -- Exclude specific instantiations of an indefinite
    
    84
    +                  -- package
    
    85
    +                  , unitIsIndefinite pkg || null (unitInstantiations pkg)
    
    86
    +                  ]
    
    87
    +
    
    88
    +  emptyMap = emptyUniqMap
    
    89
    +  setOrigins m os = fmap (const os) m
    
    90
    +  extend_modmap (uid, UnitVisibility { uv_expose_all = b, uv_renamings = rns }) modmap
    
    91
    +    = addListTo modmap theBindings
    
    92
    +   where
    
    93
    +    pkg = unit_lookup uid
    
    94
    +
    
    95
    +    theBindings :: [(ModuleName, UniqMap Module ModuleOrigin)]
    
    96
    +    theBindings = newBindings b rns
    
    97
    +
    
    98
    +    newBindings :: Bool
    
    99
    +                -> [(ModuleName, ModuleName)]
    
    100
    +                -> [(ModuleName, UniqMap Module ModuleOrigin)]
    
    101
    +    newBindings e rns  = es e ++ hiddens ++ map rnBinding rns
    
    102
    +
    
    103
    +    rnBinding :: (ModuleName, ModuleName)
    
    104
    +              -> (ModuleName, UniqMap Module ModuleOrigin)
    
    105
    +    rnBinding (orig, new) = (new, setOrigins origEntry fromFlag)
    
    106
    +     where origEntry = case lookupUFM esmap orig of
    
    107
    +            Just r -> r
    
    108
    +            Nothing -> throwGhcException (CmdLineError (renderWithContext
    
    109
    +                        (log_default_user_context (logFlags logger))
    
    110
    +                        (text "package flag: could not find module name" <+>
    
    111
    +                            ppr orig <+> text "in package" <+> ppr pk)))
    
    112
    +
    
    113
    +    es :: Bool -> [(ModuleName, UniqMap Module ModuleOrigin)]
    
    114
    +    es e = do
    
    115
    +     (m, exposedReexport) <- exposed_mods
    
    116
    +     let (pk', m', origin') =
    
    117
    +          case exposedReexport of
    
    118
    +           Nothing -> (pk, m, fromExposedModules e)
    
    119
    +           Just (Module pk' m') ->
    
    120
    +              (pk', m', fromReexportedModules e pkg)
    
    121
    +     return (m, mkModMap pk' m' origin')
    
    122
    +
    
    123
    +    esmap :: UniqFM ModuleName (UniqMap Module ModuleOrigin)
    
    124
    +    esmap = listToUFM (es False) -- parameter here doesn't matter, orig will
    
    125
    +                                 -- be overwritten
    
    126
    +
    
    127
    +    hiddens = [(m, mkModMap pk m ModHidden) | m <- hidden_mods]
    
    128
    +
    
    129
    +    pk = mkUnit pkg
    
    130
    +    unit_lookup uid = lookupUnit' allowVirtualUnits pkg_map uid
    
    131
    +                        `orElse` pprPanic "unit_lookup" (ppr uid)
    
    132
    +
    
    133
    +    exposed_mods = unitExposedModules pkg
    
    134
    +    hidden_mods  = unitHiddenModules pkg
    
    135
    +
    
    136
    +-- | Make a 'ModuleNameProvidersMap' covering a set of unusable packages.
    
    137
    +mkUnusableModuleNameProvidersMap :: UnusableUnits -> ModuleNameProvidersMap
    
    138
    +mkUnusableModuleNameProvidersMap unusables =
    
    139
    +    nonDetFoldUniqMap extend_modmap emptyUniqMap unusables
    
    140
    + where
    
    141
    +    extend_modmap (_uid, (unit_info, reason)) modmap = addListTo modmap bindings
    
    142
    +      where bindings :: [(ModuleName, UniqMap Module ModuleOrigin)]
    
    143
    +            bindings = exposed ++ hidden
    
    144
    +
    
    145
    +            origin_reexport =  ModUnusable (UnusableUnit unit reason True)
    
    146
    +            origin_normal   =  ModUnusable (UnusableUnit unit reason False)
    
    147
    +            unit = mkUnit unit_info
    
    148
    +
    
    149
    +            exposed = map get_exposed exposed_mods
    
    150
    +            hidden = [(m, mkModMap unit m origin_normal) | m <- hidden_mods]
    
    151
    +
    
    152
    +            -- with re-exports, c:Foo can be reexported from two (or more)
    
    153
    +            -- unusable packages:
    
    154
    +            --  Foo -> a:Foo (unusable reason A) -> c:Foo
    
    155
    +            --      -> b:Foo (unusable reason B) -> c:Foo
    
    156
    +            --
    
    157
    +            -- We must be careful to not record the following (#21097):
    
    158
    +            --  Foo -> c:Foo (unusable reason A)
    
    159
    +            --      -> c:Foo (unusable reason B)
    
    160
    +            -- But:
    
    161
    +            --  Foo -> a:Foo (unusable reason A)
    
    162
    +            --      -> b:Foo (unusable reason B)
    
    163
    +            --
    
    164
    +            get_exposed (mod, Just _) = (mod, mkModMap unit mod origin_reexport)
    
    165
    +            get_exposed (mod, _) = (mod, mkModMap unit mod origin_normal)
    
    166
    +              -- in the reexport case, we create a virtual module that doesn't
    
    167
    +              -- exist but we don't care as it's only used as a key in the map.
    
    168
    +
    
    169
    +            exposed_mods = unitExposedModules unit_info
    
    170
    +            hidden_mods  = unitHiddenModules  unit_info
    
    171
    +
    
    172
    +-- | Add a list of key/value pairs to a nested map.
    
    173
    +--
    
    174
    +-- The outer map is processed with 'Data.Map.Strict' to prevent memory leaks
    
    175
    +-- when reloading modules in GHCi (see #4029). This ensures that each
    
    176
    +-- value is forced before installing into the map.
    
    177
    +addListTo :: (Monoid a, Ord k1, Ord k2, Uniquable k1, Uniquable k2)
    
    178
    +          => UniqMap k1 (UniqMap k2 a)
    
    179
    +          -> [(k1, UniqMap k2 a)]
    
    180
    +          -> UniqMap k1 (UniqMap k2 a)
    
    181
    +addListTo = foldl' merge
    
    182
    +  where merge m (k, v) = addToUniqMap_C (plusUniqMap_C mappend) m k v
    
    183
    +
    
    184
    +-- | Create a singleton module mapping
    
    185
    +mkModMap :: Unit -> ModuleName -> ModuleOrigin -> UniqMap Module ModuleOrigin
    
    186
    +mkModMap pkg mod = unitUniqMap (mkModule pkg mod)

  • compiler/GHC/Unit/External/Query.hs
    1
    +module GHC.Unit.External.Query (
    
    2
    +  -- * Query the 'UnitInfoMap'
    
    3
    +  lookupUnit',
    
    4
    +  lookupUnitId',
    
    5
    +) where
    
    6
    +
    
    7
    +import GHC.Prelude
    
    8
    +
    
    9
    +import GHC.Types.Unique.Map
    
    10
    +import GHC.Unit.External.Substitution
    
    11
    +import GHC.Unit.Info
    
    12
    +import GHC.Unit.Module
    
    13
    +
    
    14
    +-- | A more specialized interface, which doesn't require a 'UnitState' (so it
    
    15
    +-- can be used while we're initializing 'DynFlags')
    
    16
    +--
    
    17
    +-- Parameters:
    
    18
    +--    * a boolean specifying whether or not to look for on-the-fly renamed interfaces
    
    19
    +--    * a 'UnitInfoMap'
    
    20
    +lookupUnit' :: Bool -> UnitInfoMap -> Unit -> Maybe UnitInfo
    
    21
    +lookupUnit' allowOnTheFlyInst pkg_map u = case u of
    
    22
    +   HoleUnit   -> error "Hole unit"
    
    23
    +   RealUnit i -> lookupUniqMap pkg_map (unDefinite i)
    
    24
    +   VirtUnit i
    
    25
    +      | allowOnTheFlyInst
    
    26
    +      -> -- lookup UnitInfo of the indefinite unit to be instantiated and
    
    27
    +         -- instantiate it on-the-fly
    
    28
    +         fmap (renameUnitInfo pkg_map (instUnitInsts i))
    
    29
    +           (lookupUniqMap pkg_map (instUnitInstanceOf i))
    
    30
    +
    
    31
    +      | otherwise
    
    32
    +      -> -- lookup UnitInfo by virtual UnitId. This is used to find indefinite
    
    33
    +         -- units. Even if they are real, installed units, they can't use the
    
    34
    +         -- `RealUnit` constructor (it is reserved for definite units) so we use
    
    35
    +         -- the `VirtUnit` constructor.
    
    36
    +         lookupUniqMap pkg_map (virtualUnitId i)
    
    37
    +
    
    38
    +
    
    39
    +-- | Find the unit we know about with the given unit id, if any
    
    40
    +lookupUnitId' :: UnitInfoMap -> UnitId -> Maybe UnitInfo
    
    41
    +lookupUnitId' db uid = lookupUniqMap db uid

  • compiler/GHC/Unit/External/Substitution.hs
    1
    +module GHC.Unit.External.Substitution (
    
    2
    +  -- * Substitution and module renaming
    
    3
    +  ShHoleSubst,
    
    4
    +  renameHoleModule',
    
    5
    +  renameHoleUnit',
    
    6
    +  renameUnitInfo,
    
    7
    +) where
    
    8
    +
    
    9
    +import GHC.Prelude
    
    10
    +
    
    11
    +import GHC.Unit.Module
    
    12
    +import GHC.Unit.Info
    
    13
    +import GHC.Types.Unique.FM
    
    14
    +import GHC.Types.Unique.DFM
    
    15
    +import GHC.Types.Unique.DSet
    
    16
    +
    
    17
    +-- -----------------------------------------------------------------------------
    
    18
    +-- Module renaming
    
    19
    +
    
    20
    +-- | Substitution on module variables, mapping module names to module
    
    21
    +-- identifiers.
    
    22
    +type ShHoleSubst = ModuleNameEnv Module
    
    23
    +
    
    24
    +-- | Rename a 'UnitInfo' according to some module instantiation.
    
    25
    +renameUnitInfo :: UnitInfoMap -> [(ModuleName, Module)] -> UnitInfo -> UnitInfo
    
    26
    +renameUnitInfo pkg_map insts conf =
    
    27
    +    let hsubst = listToUFM insts
    
    28
    +        smod  = renameHoleModule' pkg_map hsubst
    
    29
    +        new_insts = map (\(k,v) -> (k,smod v)) (unitInstantiations conf)
    
    30
    +    in conf {
    
    31
    +        unitInstantiations = new_insts,
    
    32
    +        unitExposedModules = map (\(mod_name, mb_mod) -> (mod_name, fmap smod mb_mod))
    
    33
    +                             (unitExposedModules conf)
    
    34
    +    }
    
    35
    +
    
    36
    +
    
    37
    +-- | Like 'renameHoleModule', but requires only 'UnitInfoMap'
    
    38
    +-- so it can be used by "GHC.Unit.State".
    
    39
    +renameHoleModule' :: UnitInfoMap -> ShHoleSubst -> Module -> Module
    
    40
    +renameHoleModule' pkg_map env m
    
    41
    +  | not (isHoleModule m) =
    
    42
    +        let uid = renameHoleUnit' pkg_map env (moduleUnit m)
    
    43
    +        in mkModule uid (moduleName m)
    
    44
    +  | Just m' <- lookupUFM env (moduleName m) = m'
    
    45
    +  -- NB m = <Blah>, that's what's in scope.
    
    46
    +  | otherwise = m
    
    47
    +
    
    48
    +-- | Like 'renameHoleUnit', but requires only 'UnitInfoMap'
    
    49
    +-- so it can be used by "GHC.Unit.State".
    
    50
    +renameHoleUnit' :: UnitInfoMap -> ShHoleSubst -> Unit -> Unit
    
    51
    +renameHoleUnit' pkg_map env uid =
    
    52
    +    case uid of
    
    53
    +      (VirtUnit
    
    54
    +        InstantiatedUnit{ instUnitInstanceOf = cid
    
    55
    +                        , instUnitInsts      = insts
    
    56
    +                        , instUnitHoles      = fh })
    
    57
    +          -> if isNullUFM (intersectUFM_C const (udfmToUfm (getUniqDSet fh)) env)
    
    58
    +                then uid
    
    59
    +                else mkVirtUnit cid
    
    60
    +                          (map (\(k,v) -> (k, renameHoleModule' pkg_map env v)) insts)
    
    61
    +      _ -> uid

  • compiler/GHC/Unit/External/Validate.hs
    1
    +module GHC.Unit.External.Validate (
    
    2
    +  -- * Validation of unit databases
    
    3
    +  validateDatabase,
    
    4
    +  reportUnusable,
    
    5
    +  UnusableUnits,
    
    6
    +  UnusableUnit(..),
    
    7
    +  UnusableUnitReason(..),
    
    8
    +  pprReason,
    
    9
    +  -- * Package resolver
    
    10
    +  findPackages,
    
    11
    +  selectPackages,
    
    12
    +  -- * Unit database closure validation
    
    13
    +  UnitErr(..),
    
    14
    +  mayThrowUnitErr,
    
    15
    +  closeUnitDeps,
    
    16
    +  closeUnitDeps',
    
    17
    +  -- * Utils
    
    18
    +  ignoreUnits,
    
    19
    +  pprFlag,
    
    20
    +) where
    
    21
    +
    
    22
    +import GHC.Prelude
    
    23
    +
    
    24
    +import Control.Monad
    
    25
    +import Data.Graph (SCC (..), stronglyConnComp)
    
    26
    +import Data.List (partition)
    
    27
    +import GHC.Data.Maybe
    
    28
    +import GHC.Driver.DynFlags
    
    29
    +import GHC.Types.Unique.Map
    
    30
    +import GHC.Unit.External.Database
    
    31
    +import GHC.Unit.External.Query
    
    32
    +import GHC.Unit.External.Substitution
    
    33
    +import GHC.Unit.Info
    
    34
    +import GHC.Unit.Types
    
    35
    +import GHC.Utils.Error
    
    36
    +import GHC.Utils.Logger
    
    37
    +import GHC.Utils.Outputable
    
    38
    +import GHC.Utils.Outputable qualified as Outputable
    
    39
    +import GHC.Utils.Panic
    
    40
    +
    
    41
    +-- -----------------------------------------------------------------------------
    
    42
    +-- Database validation
    
    43
    +
    
    44
    +-- | Validates a database, removing unusable units from it
    
    45
    +-- (this includes removing units that the user has explicitly
    
    46
    +-- ignored.)  Our general strategy:
    
    47
    +--
    
    48
    +-- 1. Remove all broken units (dangling dependencies)
    
    49
    +-- 2. Remove all units that are cyclic
    
    50
    +-- 3. Apply ignore flags
    
    51
    +-- 4. Remove all units which have deps with mismatching ABIs
    
    52
    +--
    
    53
    +validateDatabase :: [IgnorePackageFlag] -> UnitInfoMap
    
    54
    +                 -> (UnitInfoMap, UnusableUnits, [SCC UnitInfo])
    
    55
    +validateDatabase flagsIgnored pkg_map1 =
    
    56
    +    (pkg_map5, unusable, sccs)
    
    57
    +  where
    
    58
    +    ignore_flags = reverse flagsIgnored -- (unitConfigFlagsIgnored cfg)
    
    59
    +
    
    60
    +    -- Compute the reverse dependency index
    
    61
    +    index = reverseDeps pkg_map1
    
    62
    +
    
    63
    +    -- Helper function
    
    64
    +    mk_unusable mk_err dep_matcher m uids =
    
    65
    +      listToUniqMap [ (unitId pkg, (pkg, mk_err (dep_matcher m pkg)))
    
    66
    +                    | pkg <- uids
    
    67
    +                    ]
    
    68
    +
    
    69
    +    -- Find broken units
    
    70
    +    directly_broken = filter (not . null . depsNotAvailable pkg_map1)
    
    71
    +                             (nonDetEltsUniqMap pkg_map1)
    
    72
    +    (pkg_map2, broken) = removeUnits (map unitId directly_broken) index pkg_map1
    
    73
    +    unusable_broken = mk_unusable BrokenDependencies depsNotAvailable pkg_map2 broken
    
    74
    +
    
    75
    +    -- Find recursive units
    
    76
    +    sccs = stronglyConnComp [ (pkg, unitId pkg, unitDepends pkg)
    
    77
    +                            | pkg <- nonDetEltsUniqMap pkg_map2 ]
    
    78
    +    getCyclicSCC (CyclicSCC vs) = map unitId vs
    
    79
    +    getCyclicSCC (AcyclicSCC _) = []
    
    80
    +    (pkg_map3, cyclic) = removeUnits (concatMap getCyclicSCC sccs) index pkg_map2
    
    81
    +    unusable_cyclic = mk_unusable CyclicDependencies depsNotAvailable pkg_map3 cyclic
    
    82
    +
    
    83
    +    -- Apply ignore flags
    
    84
    +    directly_ignored = ignoreUnits ignore_flags (nonDetEltsUniqMap pkg_map3)
    
    85
    +    (pkg_map4, ignored) = removeUnits (nonDetKeysUniqMap directly_ignored) index pkg_map3
    
    86
    +    unusable_ignored = mk_unusable IgnoredDependencies depsNotAvailable pkg_map4 ignored
    
    87
    +
    
    88
    +    -- Knock out units whose dependencies don't agree with ABI
    
    89
    +    -- (i.e., got invalidated due to shadowing)
    
    90
    +    directly_shadowed = filter (not . null . depsAbiMismatch pkg_map4)
    
    91
    +                               (nonDetEltsUniqMap pkg_map4)
    
    92
    +    (pkg_map5, shadowed) = removeUnits (map unitId directly_shadowed) index pkg_map4
    
    93
    +    unusable_shadowed = mk_unusable ShadowedDependencies depsAbiMismatch pkg_map5 shadowed
    
    94
    +
    
    95
    +    -- combine all unusables. The order is important for shadowing.
    
    96
    +    -- plusUniqMapList folds using plusUFM which is right biased (opposite of
    
    97
    +    -- Data.Map.union) so the head of the list should be the least preferred
    
    98
    +    unusable = plusUniqMapList [ unusable_shadowed
    
    99
    +                               , unusable_cyclic
    
    100
    +                               , unusable_broken
    
    101
    +                               , unusable_ignored
    
    102
    +                               , directly_ignored
    
    103
    +                               ]
    
    104
    +
    
    105
    +
    
    106
    +type UnusableUnits = UniqMap UnitId (UnitInfo, UnusableUnitReason)
    
    107
    +
    
    108
    +-- | A unusable unit module origin
    
    109
    +data UnusableUnit = UnusableUnit
    
    110
    +  { uuUnit        :: !Unit               -- ^ Unusable unit
    
    111
    +  , uuReason      :: !UnusableUnitReason -- ^ Reason
    
    112
    +  , uuIsReexport  :: !Bool               -- ^ Is the "module" a reexport?
    
    113
    +  }
    
    114
    +
    
    115
    +-- | The reason why a unit is unusable.
    
    116
    +data UnusableUnitReason
    
    117
    +  = -- | We ignored it explicitly using @-ignore-package@.
    
    118
    +    IgnoredWithFlag
    
    119
    +    -- | This unit transitively depends on a unit that was never present
    
    120
    +    -- in any of the provided databases.
    
    121
    +  | BrokenDependencies   [UnitId]
    
    122
    +    -- | This unit transitively depends on a unit involved in a cycle.
    
    123
    +    -- Note that the list of 'UnitId' reports the direct dependencies
    
    124
    +    -- of this unit that (transitively) depended on the cycle, and not
    
    125
    +    -- the actual cycle itself (which we report separately at high verbosity.)
    
    126
    +  | CyclicDependencies   [UnitId]
    
    127
    +    -- | This unit transitively depends on a unit which was ignored.
    
    128
    +  | IgnoredDependencies  [UnitId]
    
    129
    +    -- | This unit transitively depends on a unit which was
    
    130
    +    -- shadowed by an ABI-incompatible unit.
    
    131
    +  | ShadowedDependencies [UnitId]
    
    132
    +
    
    133
    +instance Outputable UnusableUnitReason where
    
    134
    +    ppr IgnoredWithFlag = text "[ignored with flag]"
    
    135
    +    ppr (BrokenDependencies uids)   = brackets (text "broken" <+> ppr uids)
    
    136
    +    ppr (CyclicDependencies uids)   = brackets (text "cyclic" <+> ppr uids)
    
    137
    +    ppr (IgnoredDependencies uids)  = brackets (text "ignored" <+> ppr uids)
    
    138
    +    ppr (ShadowedDependencies uids) = brackets (text "shadowed" <+> ppr uids)
    
    139
    +
    
    140
    +pprReason :: SDoc -> UnusableUnitReason -> SDoc
    
    141
    +pprReason pref reason = case reason of
    
    142
    +  IgnoredWithFlag ->
    
    143
    +      pref <+> text "ignored due to an -ignore-package flag"
    
    144
    +  BrokenDependencies deps ->
    
    145
    +      pref <+> text "unusable due to missing dependencies:" $$
    
    146
    +        nest 2 (hsep (map ppr deps))
    
    147
    +  CyclicDependencies deps ->
    
    148
    +      pref <+> text "unusable due to cyclic dependencies:" $$
    
    149
    +        nest 2 (hsep (map ppr deps))
    
    150
    +  IgnoredDependencies deps ->
    
    151
    +      pref <+> text ("unusable because the -ignore-package flag was used to " ++
    
    152
    +                     "ignore at least one of its dependencies:") $$
    
    153
    +        nest 2 (hsep (map ppr deps))
    
    154
    +  ShadowedDependencies deps ->
    
    155
    +      pref <+> text "unusable due to shadowed dependencies:" $$
    
    156
    +        nest 2 (hsep (map ppr deps))
    
    157
    +
    
    158
    +reportUnusable :: Logger -> UnusableUnits -> IO ()
    
    159
    +reportUnusable logger pkgs = when (logVerbAtLeast logger 2) $ mapM_ report (nonDetUniqMapToList pkgs)
    
    160
    +  where
    
    161
    +    report (ipid, (_, reason)) =
    
    162
    +       debugTraceMsg logger 2 $
    
    163
    +         pprReason
    
    164
    +           (text "package" <+> ppr ipid <+> text "is") reason
    
    165
    +
    
    166
    +-- -----------------------------------------------------------------------------
    
    167
    +-- Package Finding
    
    168
    +
    
    169
    +-- | Like 'selectPackages', but doesn't return a list of unmatched
    
    170
    +-- packages.  Furthermore, any packages it returns are *renamed*
    
    171
    +-- if the 'UnitArg' has a renaming associated with it.
    
    172
    +findPackages :: UnitPrecedenceMap
    
    173
    +             -> UnitInfoMap
    
    174
    +             -> PackageArg -> [UnitInfo]
    
    175
    +             -> UnusableUnits
    
    176
    +             -> Either [(UnitInfo, UnusableUnitReason)]
    
    177
    +                [UnitInfo]
    
    178
    +findPackages prec_map pkg_map arg pkgs unusable
    
    179
    +  = let ps = mapMaybe (finder arg) pkgs
    
    180
    +    in if null ps
    
    181
    +        then Left (mapMaybe (\(x,y) -> finder arg x >>= \x' -> return (x',y))
    
    182
    +                            (nonDetEltsUniqMap unusable))
    
    183
    +        else Right (sortByPreference prec_map ps)
    
    184
    +  where
    
    185
    +    finder (PackageArg str) p
    
    186
    +      = if matchingStr str p
    
    187
    +          then Just p
    
    188
    +          else Nothing
    
    189
    +    finder (UnitIdArg uid) p
    
    190
    +      = case uid of
    
    191
    +          RealUnit (Definite iuid)
    
    192
    +            | iuid == unitId p
    
    193
    +            -> Just p
    
    194
    +          VirtUnit inst
    
    195
    +            | instUnitInstanceOf inst == unitId p
    
    196
    +            -> Just (renameUnitInfo pkg_map (instUnitInsts inst) p)
    
    197
    +          _ -> Nothing
    
    198
    +
    
    199
    +selectPackages :: UnitPrecedenceMap -> PackageArg -> [UnitInfo]
    
    200
    +               -> UnusableUnits
    
    201
    +               -> Either [(UnitInfo, UnusableUnitReason)]
    
    202
    +                  ([UnitInfo], [UnitInfo])
    
    203
    +selectPackages prec_map arg pkgs unusable
    
    204
    +  = let matches = matching arg
    
    205
    +        (ps,rest) = partition matches pkgs
    
    206
    +    in if null ps
    
    207
    +        then Left (filter (matches.fst) (nonDetEltsUniqMap unusable))
    
    208
    +        else Right (sortByPreference prec_map ps, rest)
    
    209
    +
    
    210
    +-- -----------------------------------------------------------------------------
    
    211
    +-- Ignore units
    
    212
    +
    
    213
    +ignoreUnits :: [IgnorePackageFlag] -> [UnitInfo] -> UnusableUnits
    
    214
    +ignoreUnits flags pkgs = listToUniqMap (concatMap doit flags)
    
    215
    +  where
    
    216
    +  doit (IgnorePackage str) =
    
    217
    +     case partition (matchingStr str) pkgs of
    
    218
    +         (ps, _) -> [ (unitId p, (p, IgnoredWithFlag))
    
    219
    +                    | p <- ps ]
    
    220
    +        -- missing unit is not an error for -ignore-package,
    
    221
    +        -- because a common usage is to -ignore-package P as
    
    222
    +        -- a preventative measure just in case P exists.
    
    223
    +
    
    224
    +-- A package named on the command line can either include the
    
    225
    +-- version, or just the name if it is unambiguous.
    
    226
    +matchingStr :: String -> UnitInfo -> Bool
    
    227
    +matchingStr str p
    
    228
    +        =  str == unitPackageIdString p
    
    229
    +        || str == unitPackageNameString p
    
    230
    +
    
    231
    +matchingId :: UnitId -> UnitInfo -> Bool
    
    232
    +matchingId uid p = uid == unitId p
    
    233
    +
    
    234
    +matching :: PackageArg -> UnitInfo -> Bool
    
    235
    +matching (PackageArg str) = matchingStr str
    
    236
    +matching (UnitIdArg (RealUnit (Definite uid))) = matchingId uid
    
    237
    +matching (UnitIdArg _)  = \_ -> False -- TODO: warn in this case
    
    238
    +
    
    239
    +-- ----------------------------------------------------------------------------
    
    240
    +--
    
    241
    +-- Closures
    
    242
    +--
    
    243
    +
    
    244
    +
    
    245
    +-- | Takes a list of UnitIds (and their "parent" dependency, used for error
    
    246
    +-- messages), and returns the list with dependencies included, in reverse
    
    247
    +-- dependency order (a units appears before those it depends on).
    
    248
    +closeUnitDeps :: UnitInfoMap -> [(UnitId,Maybe UnitId)] -> MaybeErr UnitErr [UnitId]
    
    249
    +closeUnitDeps pkg_map ps = closeUnitDeps' pkg_map [] ps
    
    250
    +
    
    251
    +-- | Similar to closeUnitDeps but takes a list of already loaded units as an
    
    252
    +-- additional argument.
    
    253
    +closeUnitDeps' :: UnitInfoMap -> [UnitId] -> [(UnitId,Maybe UnitId)] -> MaybeErr UnitErr [UnitId]
    
    254
    +closeUnitDeps' pkg_map current_ids ps = foldM (uncurry . add_unit pkg_map) current_ids ps
    
    255
    +
    
    256
    +-- | Add a UnitId and those it depends on (recursively) to the given list of
    
    257
    +-- UnitIds if they are not already in it. Return a list in reverse dependency
    
    258
    +-- order (a unit appears before those it depends on).
    
    259
    +--
    
    260
    +-- The UnitId is looked up in the given UnitInfoMap (to find its dependencies).
    
    261
    +-- It it's not found, the optional parent unit is used to return a more precise
    
    262
    +-- error message ("dependency of <PARENT>").
    
    263
    +add_unit :: UnitInfoMap
    
    264
    +            -> [UnitId]
    
    265
    +            -> UnitId
    
    266
    +            -> Maybe UnitId
    
    267
    +            -> MaybeErr UnitErr [UnitId]
    
    268
    +add_unit pkg_map ps p mb_parent
    
    269
    +  | p `elem` ps = return ps     -- Check if we've already added this unit
    
    270
    +  | otherwise   = case lookupUnitId' pkg_map p of
    
    271
    +      Nothing   -> Failed (CloseUnitErr p mb_parent)
    
    272
    +      Just info -> do
    
    273
    +         -- Add the unit's dependents also
    
    274
    +         ps' <- foldM add_unit_key ps (unitDepends info)
    
    275
    +         return (p : ps')
    
    276
    +        where
    
    277
    +          add_unit_key xs key
    
    278
    +            = add_unit pkg_map xs key (Just p)
    
    279
    +data UnitErr
    
    280
    +  = CloseUnitErr !UnitId !(Maybe UnitId)
    
    281
    +  | PackageFlagErr !PackageFlag ![(UnitInfo,UnusableUnitReason)]
    
    282
    +  | TrustFlagErr   !TrustFlag   ![(UnitInfo,UnusableUnitReason)]
    
    283
    +
    
    284
    +mayThrowUnitErr :: MaybeErr UnitErr a -> IO a
    
    285
    +mayThrowUnitErr = \case
    
    286
    +    Failed e    -> throwGhcExceptionIO
    
    287
    +                    $ CmdLineError
    
    288
    +                    $ renderWithContext defaultSDocContext
    
    289
    +                    $ withPprStyle defaultUserStyle
    
    290
    +                    $ ppr e
    
    291
    +    Succeeded a -> return a
    
    292
    +
    
    293
    +instance Outputable UnitErr where
    
    294
    +    ppr = \case
    
    295
    +        CloseUnitErr p mb_parent
    
    296
    +            -> (text "unknown unit:" <+> ppr p)
    
    297
    +               <> case mb_parent of
    
    298
    +                     Nothing     -> Outputable.empty
    
    299
    +                     Just parent -> space <> parens (text "dependency of"
    
    300
    +                                              <+> ftext (unitIdFS parent))
    
    301
    +        PackageFlagErr flag reasons
    
    302
    +            -> flag_err (pprFlag flag) reasons
    
    303
    +
    
    304
    +        TrustFlagErr flag reasons
    
    305
    +            -> flag_err (pprTrustFlag flag) reasons
    
    306
    +      where
    
    307
    +        flag_err flag_doc reasons =
    
    308
    +            text "cannot satisfy "
    
    309
    +            <> flag_doc
    
    310
    +            <> (if null reasons then Outputable.empty else text ": ")
    
    311
    +            $$ nest 4 (vcat (map ppr_reason reasons) $$
    
    312
    +                      text "(use -v for more information)")
    
    313
    +
    
    314
    +        ppr_reason (p, reason) =
    
    315
    +            pprReason (ppr (unitId p) <+> text "is") reason
    
    316
    +
    
    317
    +
    
    318
    +pprFlag :: PackageFlag -> SDoc
    
    319
    +pprFlag flag = case flag of
    
    320
    +    HidePackage p   -> text "-hide-package " <> text p
    
    321
    +    ExposePackage doc _ _ -> text doc
    
    322
    +
    
    323
    +pprTrustFlag :: TrustFlag -> SDoc
    
    324
    +pprTrustFlag flag = case flag of
    
    325
    +    TrustPackage p    -> text "-trust " <> text p
    
    326
    +    DistrustPackage p -> text "-distrust " <> text p
    
    327
    +
    
    328
    +-- ----------------------------------------------------------------------------
    
    329
    +--
    
    330
    +-- Utilities on the database
    
    331
    +--
    
    332
    +
    
    333
    +-- | A reverse dependency index, mapping an 'UnitId' to
    
    334
    +-- the 'UnitId's which have a dependency on it.
    
    335
    +type RevIndex = UniqMap UnitId [UnitId]
    
    336
    +
    
    337
    +-- | Compute the reverse dependency index of a unit database.
    
    338
    +reverseDeps :: UnitInfoMap -> RevIndex
    
    339
    +reverseDeps db = nonDetFoldUniqMap go emptyUniqMap db
    
    340
    +  where
    
    341
    +    go :: (UnitId, UnitInfo) -> RevIndex -> RevIndex
    
    342
    +    go (_uid, pkg) r = foldl' (go' (unitId pkg)) r (unitDepends pkg)
    
    343
    +    go' from r to = addToUniqMap_C (++) r to [from]
    
    344
    +
    
    345
    +-- | Given a list of 'UnitId's to remove, a database,
    
    346
    +-- and a reverse dependency index (as computed by 'reverseDeps'),
    
    347
    +-- remove those units, plus any units which depend on them.
    
    348
    +-- Returns the pruned database, as well as a list of 'UnitInfo's
    
    349
    +-- that was removed.
    
    350
    +removeUnits :: [UnitId] -> RevIndex
    
    351
    +               -> UnitInfoMap
    
    352
    +               -> (UnitInfoMap, [UnitInfo])
    
    353
    +removeUnits uids index m = go uids (m,[])
    
    354
    +  where
    
    355
    +    go [] (m,pkgs) = (m,pkgs)
    
    356
    +    go (uid:uids) (m,pkgs)
    
    357
    +        | Just pkg <- lookupUniqMap m uid
    
    358
    +        = case lookupUniqMap index uid of
    
    359
    +            Nothing    -> go uids (delFromUniqMap m uid, pkg:pkgs)
    
    360
    +            Just rdeps -> go (rdeps ++ uids) (delFromUniqMap m uid, pkg:pkgs)
    
    361
    +        | otherwise
    
    362
    +        = go uids (m,pkgs)
    
    363
    +
    
    364
    +-- | Given a 'UnitInfo' from some 'UnitInfoMap', return all entries in 'depends'
    
    365
    +-- which correspond to units that do not exist in the index.
    
    366
    +depsNotAvailable :: UnitInfoMap
    
    367
    +                 -> UnitInfo
    
    368
    +                 -> [UnitId]
    
    369
    +depsNotAvailable pkg_map pkg = filter (not . (`elemUniqMap` pkg_map)) (unitDepends pkg)
    
    370
    +
    
    371
    +-- | Given a 'UnitInfo' from some 'UnitInfoMap' return all entries in
    
    372
    +-- 'unitAbiDepends' which correspond to units that do not exist, OR have
    
    373
    +-- mismatching ABIs.
    
    374
    +depsAbiMismatch :: UnitInfoMap
    
    375
    +                -> UnitInfo
    
    376
    +                -> [UnitId]
    
    377
    +depsAbiMismatch pkg_map pkg = map fst . filter (not . abiMatch) $ unitAbiDepends pkg
    
    378
    +  where
    
    379
    +    abiMatch (dep_uid, abi)
    
    380
    +        | Just dep_pkg <- lookupUniqMap pkg_map dep_uid
    
    381
    +        = unitAbiHash dep_pkg == abi
    
    382
    +        | otherwise
    
    383
    +        = False

  • compiler/GHC/Unit/External/Visibility.hs
    1
    +module GHC.Unit.External.Visibility (
    
    2
    +  VisibilityMap,
    
    3
    +  UnitVisibility(..),
    
    4
    +) where
    
    5
    +
    
    6
    +import GHC.Prelude
    
    7
    +
    
    8
    +import GHC.Data.FastString
    
    9
    +import GHC.Driver.DynFlags
    
    10
    +import GHC.Types.Unique.Map
    
    11
    +import GHC.Unit.Module
    
    12
    +import GHC.Utils.Outputable as Outputable
    
    13
    +
    
    14
    +import Control.Applicative
    
    15
    +import Data.Monoid (First (..))
    
    16
    +import Data.Semigroup qualified as Semigroup
    
    17
    +import Data.Set (Set)
    
    18
    +import Data.Set qualified as Set
    
    19
    +
    
    20
    +-- | 'UniqFM' map from 'Unit' to a 'UnitVisibility'.
    
    21
    +type VisibilityMap = UniqMap Unit UnitVisibility
    
    22
    +
    
    23
    +-- | 'UnitVisibility' records the various aspects of visibility of a particular
    
    24
    +-- 'Unit'.
    
    25
    +data UnitVisibility = UnitVisibility
    
    26
    +    { uv_expose_all :: Bool
    
    27
    +      --  ^ Should all modules in exposed-modules should be dumped into scope?
    
    28
    +    , uv_renamings :: [(ModuleName, ModuleName)]
    
    29
    +      -- ^ Any custom renamings that should bring extra 'ModuleName's into
    
    30
    +      -- scope.
    
    31
    +    , uv_package_name :: First FastString
    
    32
    +      -- ^ The package name associated with the 'Unit'.  This is used
    
    33
    +      -- to implement legacy behavior where @-package foo-0.1@ implicitly
    
    34
    +      -- hides any packages named @foo@
    
    35
    +    , uv_requirements :: UniqMap ModuleName (Set InstantiatedModule)
    
    36
    +      -- ^ The signatures which are contributed to the requirements context
    
    37
    +      -- from this unit ID.
    
    38
    +    , uv_explicit :: Maybe PackageArg
    
    39
    +      -- ^ Whether or not this unit was explicitly brought into scope,
    
    40
    +      -- as opposed to implicitly via the 'exposed' fields in the
    
    41
    +      -- package database (when @-hide-all-packages@ is not passed.)
    
    42
    +    }
    
    43
    +
    
    44
    +instance Outputable UnitVisibility where
    
    45
    +    ppr (UnitVisibility {
    
    46
    +        uv_expose_all = b,
    
    47
    +        uv_renamings = rns,
    
    48
    +        uv_package_name = First mb_pn,
    
    49
    +        uv_requirements = reqs,
    
    50
    +        uv_explicit = explicit
    
    51
    +    }) = ppr (b, rns, mb_pn, reqs, explicit)
    
    52
    +
    
    53
    +instance Semigroup UnitVisibility where
    
    54
    +    uv1 <> uv2
    
    55
    +        = UnitVisibility
    
    56
    +          { uv_expose_all = uv_expose_all uv1 || uv_expose_all uv2
    
    57
    +          , uv_renamings = uv_renamings uv1 ++ uv_renamings uv2
    
    58
    +          , uv_package_name = mappend (uv_package_name uv1) (uv_package_name uv2)
    
    59
    +          , uv_requirements = plusUniqMap_C Set.union (uv_requirements uv2) (uv_requirements uv1)
    
    60
    +          , uv_explicit = uv_explicit uv1 <|> uv_explicit uv2
    
    61
    +          }
    
    62
    +
    
    63
    +instance Monoid UnitVisibility where
    
    64
    +    mempty = UnitVisibility
    
    65
    +             { uv_expose_all = False
    
    66
    +             , uv_renamings = []
    
    67
    +             , uv_package_name = First Nothing
    
    68
    +             , uv_requirements = emptyUniqMap
    
    69
    +             , uv_explicit = Nothing
    
    70
    +             }
    
    71
    +    mappend = (Semigroup.<>)
    
    72
    +

  • compiler/GHC/Unit/External/Wired.hs
    1
    +module GHC.Unit.External.Wired (
    
    2
    +  -- * 'WireMap'
    
    3
    +  WireMap,
    
    4
    +  emptyWireMap,
    
    5
    +  isWireMapEmpty,
    
    6
    +  lookupWireMap,
    
    7
    +  listWireMap,
    
    8
    +  -- * 'UnwireMap'
    
    9
    +  UnwireMap,
    
    10
    +  emptyUnwireMap,
    
    11
    +  lookupUnwireMap,
    
    12
    +  unwiringMapFromWireMap,
    
    13
    +  -- * Creating 'WireMap'
    
    14
    +  findWiredInUnits,
    
    15
    +) where
    
    16
    +
    
    17
    +import GHC.Prelude
    
    18
    +
    
    19
    +import GHC.Unit.External.Database
    
    20
    +import GHC.Unit.External.Visibility
    
    21
    +
    
    22
    +import GHC.Data.Maybe
    
    23
    +import GHC.Types.Unique.Map
    
    24
    +import GHC.Unit.Database
    
    25
    +import GHC.Unit.Info
    
    26
    +import GHC.Unit.Types
    
    27
    +import GHC.Utils.Error
    
    28
    +import GHC.Utils.Logger
    
    29
    +import GHC.Utils.Outputable as Outputable
    
    30
    +
    
    31
    +-- | The 'WireMap' records the mapping from the 'UnitId' of on-disk 'UnitInfo'
    
    32
    +-- to the 'UnitId' of the 'wiredInMap'.
    
    33
    +--
    
    34
    +-- See 'wiredInUnitIds' for the set of wired-in units.
    
    35
    +--
    
    36
    +newtype WireMap =
    
    37
    +  WireMap (UniqMap UnitId UnitId)
    
    38
    +
    
    39
    +emptyWireMap :: WireMap
    
    40
    +emptyWireMap = WireMap emptyUniqMap
    
    41
    +
    
    42
    +isWireMapEmpty :: WireMap -> Bool
    
    43
    +isWireMapEmpty (WireMap wmap) = isNullUniqMap wmap
    
    44
    +
    
    45
    +lookupWireMap :: UnitId -> WireMap -> Maybe UnitId
    
    46
    +lookupWireMap uid (WireMap wmap) = lookupUniqMap wmap uid
    
    47
    +
    
    48
    +listWireMap :: WireMap -> [(UnitId, UnitId)]
    
    49
    +listWireMap (WireMap wmap) = nonDetUniqMapToList wmap
    
    50
    +
    
    51
    +-- | The reverse of 'WireMap'.
    
    52
    +-- Records the mapping from the wired-in 'UnitId' to the on-disk 'UnitId'.
    
    53
    +newtype UnwireMap =
    
    54
    +  UnwireMap (UniqMap UnitId UnitId)
    
    55
    +
    
    56
    +emptyUnwireMap :: UnwireMap
    
    57
    +emptyUnwireMap = UnwireMap emptyUniqMap
    
    58
    +
    
    59
    +unwiringMapFromWireMap :: WireMap -> UnwireMap
    
    60
    +unwiringMapFromWireMap (WireMap wired_map) =
    
    61
    +  UnwireMap $ listToUniqMap [ (v,k) | (k,v) <- nonDetUniqMapToList wired_map ]
    
    62
    +
    
    63
    +lookupUnwireMap :: UnitId -> UnwireMap -> Maybe UnitId
    
    64
    +lookupUnwireMap uid (UnwireMap wmap) = lookupUniqMap wmap uid
    
    65
    +
    
    66
    +-- -----------------------------------------------------------------------------
    
    67
    +-- Wired-in units
    
    68
    +--
    
    69
    +-- See Note [Wired-in units] in GHC.Unit.Types
    
    70
    +
    
    71
    +findWiredInUnits
    
    72
    +   :: Logger
    
    73
    +   -> UnitPrecedenceMap
    
    74
    +   -> [UnitInfo]           -- database
    
    75
    +   -> VisibilityMap             -- info on what units are visible
    
    76
    +                                -- for wired in selection
    
    77
    +   -> IO WireMap   -- map from unit id to wired identity
    
    78
    +findWiredInUnits logger prec_map pkgs vis_map = do
    
    79
    +  -- Now we must find our wired-in units, and rename them to
    
    80
    +  -- their canonical names (eg. base-1.0 ==> base), as described
    
    81
    +  -- in Note [Wired-in units] in GHC.Unit.Types
    
    82
    +  let
    
    83
    +        matches :: UnitInfo -> UnitId -> Bool
    
    84
    +        pc `matches` pid = unitPackageName pc == PackageName (unitIdFS pid)
    
    85
    +
    
    86
    +        -- find which package corresponds to each wired-in package
    
    87
    +        -- delete any other packages with the same name
    
    88
    +        -- update the package and any dependencies to point to the new
    
    89
    +        -- one.
    
    90
    +        --
    
    91
    +        -- When choosing which package to map to a wired-in package
    
    92
    +        -- name, we try to pick the latest version of exposed packages.
    
    93
    +        -- However, if there are no exposed wired in packages available
    
    94
    +        -- (e.g. -hide-all-packages was used), we can't bail: we *have*
    
    95
    +        -- to assign a package for the wired-in package: so we try again
    
    96
    +        -- with hidden packages included to (and pick the latest
    
    97
    +        -- version).
    
    98
    +        --
    
    99
    +        -- You can also override the default choice by using -ignore-package:
    
    100
    +        -- this works even when there is no exposed wired in package
    
    101
    +        -- available.
    
    102
    +        --
    
    103
    +        findWiredInUnit :: [UnitInfo] -> UnitId -> IO (Maybe (UnitId, UnitInfo))
    
    104
    +        findWiredInUnit pkgs wired_pkg = firstJustsM [try all_exposed_ps, try all_ps, notfound]
    
    105
    +          where
    
    106
    +                all_ps = [ p | p <- pkgs, p `matches` wired_pkg ]
    
    107
    +                all_exposed_ps = [ p | p <- all_ps, (mkUnit p) `elemUniqMap` vis_map ]
    
    108
    +
    
    109
    +                try ps = case sortByPreference prec_map ps of
    
    110
    +                    p:_ -> Just <$> pick p
    
    111
    +                    _ -> pure Nothing
    
    112
    +
    
    113
    +                notfound = do
    
    114
    +                          debugTraceMsg logger 2 $
    
    115
    +                            text "wired-in package "
    
    116
    +                                 <> ftext (unitIdFS wired_pkg)
    
    117
    +                                 <> text " not found."
    
    118
    +                          return Nothing
    
    119
    +                pick :: UnitInfo -> IO (UnitId, UnitInfo)
    
    120
    +                pick pkg = do
    
    121
    +                        debugTraceMsg logger 2 $
    
    122
    +                            text "wired-in package "
    
    123
    +                                 <> ftext (unitIdFS wired_pkg)
    
    124
    +                                 <> text " mapped to "
    
    125
    +                                 <> ppr (unitId pkg)
    
    126
    +                        return (wired_pkg, pkg)
    
    127
    +
    
    128
    +
    
    129
    +  mb_wired_in_pkgs <- mapM (findWiredInUnit pkgs) wiredInUnitIds
    
    130
    +  let
    
    131
    +        wired_in_pkgs = catMaybes mb_wired_in_pkgs
    
    132
    +
    
    133
    +        wiredInMap :: UniqMap UnitId UnitId
    
    134
    +        wiredInMap = listToUniqMap
    
    135
    +          [ (unitId realUnitInfo, wiredInUnitId)
    
    136
    +          | (wiredInUnitId, realUnitInfo) <- wired_in_pkgs
    
    137
    +          , not (unitIsIndefinite realUnitInfo)
    
    138
    +          ]
    
    139
    +
    
    140
    +  return $ WireMap wiredInMap

  • compiler/GHC/Unit/Info.hs
    ... ... @@ -5,11 +5,14 @@ module GHC.Unit.Info
    5 5
        ( GenericUnitInfo (..)
    
    6 6
        , GenUnitInfo
    
    7 7
        , UnitInfo
    
    8
    +   , UnitInfoMap
    
    8 9
        , UnitKey (..)
    
    9 10
        , UnitKeyInfo
    
    10 11
        , mkUnitKeyInfo
    
    11 12
        , mapUnitInfo
    
    12 13
        , mkUnitPprInfo
    
    14
    +   , evaluateUnitInfo
    
    15
    +   , seqUnitInfo
    
    13 16
     
    
    14 17
        , mkUnit
    
    15 18
     
    
    ... ... @@ -53,6 +56,8 @@ import Data.Containers.ListUtils (nubOrd)
    53 56
     import Data.Version
    
    54 57
     import Data.Bifunctor
    
    55 58
     import Data.List (isPrefixOf, stripPrefix)
    
    59
    +import GHC.Types.Unique.Map
    
    60
    +import Control.Exception (evaluate)
    
    56 61
     
    
    57 62
     
    
    58 63
     -- | Information about an installed unit
    
    ... ... @@ -73,6 +78,9 @@ type UnitKeyInfo = GenUnitInfo UnitKey
    73 78
     -- UnitId)
    
    74 79
     type UnitInfo    = GenUnitInfo UnitId
    
    75 80
     
    
    81
    +-- TODO @fendor
    
    82
    +type UnitInfoMap = UniqMap UnitId UnitInfo
    
    83
    +
    
    76 84
     -- | Convert a DbUnitInfo (read from a package database) into `UnitKeyInfo`
    
    77 85
     mkUnitKeyInfo :: DbUnitInfo -> UnitKeyInfo
    
    78 86
     mkUnitKeyInfo = mapGenericUnitInfo
    
    ... ... @@ -250,3 +258,21 @@ unitHsLibs namever ways0 p = map (mkDynName . addSuffix . ST.unpack) (unitLibrar
    250 258
     
    
    251 259
             expandTag t | null t = ""
    
    252 260
                         | otherwise = '_':t
    
    261
    +
    
    262
    +evaluateUnitInfo :: UnitInfo -> IO UnitInfo
    
    263
    +evaluateUnitInfo ui = evaluate (seqUnitInfo ui ui)
    
    264
    +
    
    265
    +seqUnitInfo :: UnitInfo -> b -> b
    
    266
    +seqUnitInfo ui b =
    
    267
    +  unitImportDirs ui `seqList`
    
    268
    +  unitIncludeDirs ui `seqList`
    
    269
    +  unitLibraryDirs ui `seqList`
    
    270
    +  unitLibraryBytecodeDirs ui `seqList`
    
    271
    +  unitExtDepFrameworkDirs ui `seq`
    
    272
    +  unitHaddockInterfaces ui `seq`
    
    273
    +  unitHaddockHTMLs ui `seqList`
    
    274
    +  unitLibraryDynDirs ui `seqList`
    
    275
    +  unitLibraryDirsStatic ui `seqList`
    
    276
    +  unitDepends ui `seqList`
    
    277
    +  unitExposedModules ui `seqList`
    
    278
    +  b

  • compiler/GHC/Unit/State.hs
    ... ... @@ -4,14 +4,6 @@
    4 4
     -- | Unit manipulation
    
    5 5
     module GHC.Unit.State (
    
    6 6
             module GHC.Unit.Info,
    
    7
    -
    
    8
    -        UnitIndex(..),
    
    9
    -        initUnitIndex,
    
    10
    -        setWireMap,
    
    11
    -        isWireMapEmpty,
    
    12
    -        addUnitInfoMap,
    
    13
    -        -- lookupUnitInfoMap,
    
    14
    -
    
    15 7
             -- * Reading the package config, and processing cmdline args
    
    16 8
             UnitState(..),
    
    17 9
             UnitDatabase (..),
    
    ... ... @@ -26,7 +18,6 @@ module GHC.Unit.State (
    26 18
             listUnitInfo,
    
    27 19
     
    
    28 20
             -- * Querying the package config
    
    29
    -        UnitInfoMap,
    
    30 21
             lookupUnit,
    
    31 22
             lookupUnit',
    
    32 23
             unsafeLookupUnit,
    
    ... ... @@ -90,50 +81,45 @@ import GHC.Platform
    90 81
     import GHC.Platform.Ways
    
    91 82
     
    
    92 83
     import GHC.Unit.Database
    
    84
    +import GHC.Unit.Home
    
    93 85
     import GHC.Unit.Info
    
    94
    -import GHC.Unit.Ppr
    
    95
    -import GHC.Unit.Types
    
    96 86
     import GHC.Unit.Module
    
    97
    -import GHC.Unit.Home
    
    87
    +import GHC.Unit.Ppr
    
    98 88
     
    
    99
    -import GHC.Types.Unique.FM
    
    89
    +import GHC.Unit.External.Database
    
    90
    +import GHC.Unit.External.Index
    
    91
    +import GHC.Unit.External.ModuleOrigin
    
    92
    +import GHC.Unit.External.Providers
    
    93
    +import GHC.Unit.External.Query
    
    94
    +import GHC.Unit.External.Substitution
    
    95
    +import GHC.Unit.External.Validate
    
    96
    +import GHC.Unit.External.Visibility
    
    97
    +import GHC.Unit.External.Wired
    
    98
    +
    
    99
    +import GHC.Types.PkgQual
    
    100 100
     import GHC.Types.Unique.DFM
    
    101
    -import GHC.Types.Unique.DSet
    
    101
    +import GHC.Types.Unique.FM
    
    102 102
     import GHC.Types.Unique.Map
    
    103
    -import GHC.Types.Unique
    
    104
    -import GHC.Types.PkgQual
    
    103
    +import GHC.Types.Unique.Set
    
    105 104
     
    
    106
    -import GHC.Utils.Misc
    
    107
    -import GHC.Utils.Panic
    
    108
    -import GHC.Utils.Outputable as Outputable
    
    109
    -import GHC.Data.Maybe
    
    110
    -
    
    111
    -import System.Environment ( getEnv )
    
    112 105
     import GHC.Data.FastString
    
    113
    -import GHC.Data.OsPath ( OsPath )
    
    114
    -import qualified GHC.Data.OsPath as OsPath
    
    115
    -import qualified GHC.Data.ShortText as ST
    
    116
    -import GHC.Utils.Logger
    
    106
    +import GHC.Data.Maybe
    
    107
    +import GHC.Data.OsPath qualified as OsPath
    
    108
    +import GHC.Data.ShortText qualified as ST
    
    117 109
     import GHC.Utils.Error
    
    118
    -import GHC.Utils.Exception
    
    110
    +import GHC.Utils.Logger
    
    111
    +import GHC.Utils.Misc
    
    112
    +import GHC.Utils.Outputable as Outputable
    
    113
    +import GHC.Utils.Panic
    
    119 114
     
    
    120
    -import System.Directory
    
    121
    -import System.FilePath as FilePath
    
    122 115
     import Control.Monad
    
    123 116
     import Data.Containers.ListUtils (nubOrd)
    
    124
    -import Data.Graph (stronglyConnComp, SCC(..))
    
    125
    -import Data.Char ( toUpper )
    
    126
    -import Data.List ( intersperse, partition, sortBy, sortOn, sort )
    
    127
    -import Data.Set (Set)
    
    128
    -import Data.Monoid (First(..))
    
    129
    -import qualified Data.Semigroup as Semigroup
    
    130
    -import qualified Data.Set as Set
    
    131
    -import Control.Applicative
    
    132
    -import GHC.Unit.External.Database
    
    133
    -import Data.IORef
    
    134 117
     import Data.Either (partitionEithers)
    
    135
    -import Data.Map.Strict (Map)
    
    136
    -import qualified Data.Map.Strict as Map
    
    118
    +import Data.Graph (SCC (..))
    
    119
    +import Data.List (intersperse, partition, sort, sortOn)
    
    120
    +import Data.Monoid (First (..))
    
    121
    +import Data.Set (Set)
    
    122
    +import Data.Set qualified as Set
    
    137 123
     
    
    138 124
     -- ---------------------------------------------------------------------------
    
    139 125
     -- The Unit state
    
    ... ... @@ -179,162 +165,6 @@ import qualified Data.Map.Strict as Map
    179 165
     -- When compiling A, we record in B's Module value whether it's
    
    180 166
     -- in a different DLL, by setting the DLL flag.
    
    181 167
     
    
    182
    --- | Given a module name, there may be multiple ways it came into scope,
    
    183
    --- possibly simultaneously.  This data type tracks all the possible ways
    
    184
    --- it could have come into scope.  Warning: don't use the record functions,
    
    185
    --- they're partial!
    
    186
    -data ModuleOrigin =
    
    187
    -    -- | Module is hidden, and thus never will be available for import.
    
    188
    -    -- (But maybe the user didn't realize), so we'll still keep track
    
    189
    -    -- of these modules.)
    
    190
    -    ModHidden
    
    191
    -
    
    192
    -    -- | Module is unavailable because the unit is unusable.
    
    193
    -  | ModUnusable !UnusableUnit
    
    194
    -
    
    195
    -    -- | Module is public, and could have come from some places.
    
    196
    -  | ModOrigin {
    
    197
    -        -- | @Just False@ means that this module is in
    
    198
    -        -- someone's @exported-modules@ list, but that package is hidden;
    
    199
    -        -- @Just True@ means that it is available; @Nothing@ means neither
    
    200
    -        -- applies.
    
    201
    -        fromOrigUnit :: Maybe Bool
    
    202
    -        -- | Is the module available from a reexport of an exposed package?
    
    203
    -        -- There could be multiple.
    
    204
    -      , fromExposedReexport :: [UnitInfo]
    
    205
    -        -- | Is the module available from a reexport of a hidden package?
    
    206
    -      , fromHiddenReexport :: [UnitInfo]
    
    207
    -        -- | Did the module export come from a package flag? (ToDo: track
    
    208
    -        -- more information.
    
    209
    -      , fromPackageFlag :: Bool
    
    210
    -      }
    
    211
    -
    
    212
    --- | A unusable unit module origin
    
    213
    -data UnusableUnit = UnusableUnit
    
    214
    -  { uuUnit        :: !Unit               -- ^ Unusable unit
    
    215
    -  , uuReason      :: !UnusableUnitReason -- ^ Reason
    
    216
    -  , uuIsReexport  :: !Bool               -- ^ Is the "module" a reexport?
    
    217
    -  }
    
    218
    -
    
    219
    -instance Outputable ModuleOrigin where
    
    220
    -    ppr ModHidden = text "hidden module"
    
    221
    -    ppr (ModUnusable _) = text "unusable module"
    
    222
    -    ppr (ModOrigin e res rhs f) = sep (punctuate comma (
    
    223
    -        (case e of
    
    224
    -            Nothing -> []
    
    225
    -            Just False -> [text "hidden package"]
    
    226
    -            Just True -> [text "exposed package"]) ++
    
    227
    -        (if null res
    
    228
    -            then []
    
    229
    -            else [text "reexport by" <+>
    
    230
    -                    sep (map (ppr . mkUnit) res)]) ++
    
    231
    -        (if null rhs
    
    232
    -            then []
    
    233
    -            else [text "hidden reexport by" <+>
    
    234
    -                    sep (map (ppr . mkUnit) rhs)]) ++
    
    235
    -        (if f then [text "package flag"] else [])
    
    236
    -        ))
    
    237
    -
    
    238
    --- | Smart constructor for a module which is in @exposed-modules@.  Takes
    
    239
    --- as an argument whether or not the defining package is exposed.
    
    240
    -fromExposedModules :: Bool -> ModuleOrigin
    
    241
    -fromExposedModules e = ModOrigin (Just e) [] [] False
    
    242
    -
    
    243
    --- | Smart constructor for a module which is in @reexported-modules@.  Takes
    
    244
    --- as an argument whether or not the reexporting package is exposed, and
    
    245
    --- also its 'UnitInfo'.
    
    246
    -fromReexportedModules :: Bool -> UnitInfo -> ModuleOrigin
    
    247
    -fromReexportedModules True pkg = ModOrigin Nothing [pkg] [] False
    
    248
    -fromReexportedModules False pkg = ModOrigin Nothing [] [pkg] False
    
    249
    -
    
    250
    --- | Smart constructor for a module which was bound by a package flag.
    
    251
    -fromFlag :: ModuleOrigin
    
    252
    -fromFlag = ModOrigin Nothing [] [] True
    
    253
    -
    
    254
    -instance Semigroup ModuleOrigin where
    
    255
    -    x@(ModOrigin e res rhs f) <> y@(ModOrigin e' res' rhs' f') =
    
    256
    -        ModOrigin (g e e') (res ++ res') (rhs ++ rhs') (f || f')
    
    257
    -      where g (Just b) (Just b')
    
    258
    -                | b == b'   = Just b
    
    259
    -                | otherwise = pprPanic "ModOrigin: package both exposed/hidden" $
    
    260
    -                    text "x: " <> ppr x $$ text "y: " <> ppr y
    
    261
    -            g Nothing x = x
    
    262
    -            g x Nothing = x
    
    263
    -
    
    264
    -    x <> y = pprPanic "ModOrigin: module origin mismatch" $
    
    265
    -                 text "x: " <> ppr x $$ text "y: " <> ppr y
    
    266
    -
    
    267
    -instance Monoid ModuleOrigin where
    
    268
    -    mempty = ModOrigin Nothing [] [] False
    
    269
    -    mappend = (Semigroup.<>)
    
    270
    -
    
    271
    --- | Is the name from the import actually visible? (i.e. does it cause
    
    272
    --- ambiguity, or is it only relevant when we're making suggestions?)
    
    273
    -originVisible :: ModuleOrigin -> Bool
    
    274
    -originVisible ModHidden = False
    
    275
    -originVisible (ModUnusable _) = False
    
    276
    -originVisible (ModOrigin b res _ f) = b == Just True || not (null res) || f
    
    277
    -
    
    278
    --- | Are there actually no providers for this module?  This will never occur
    
    279
    --- except when we're filtering based on package imports.
    
    280
    -originEmpty :: ModuleOrigin -> Bool
    
    281
    -originEmpty (ModOrigin Nothing [] [] False) = True
    
    282
    -originEmpty _ = False
    
    283
    -
    
    284
    --- | 'UniqFM' map from 'Unit' to a 'UnitVisibility'.
    
    285
    -type VisibilityMap = UniqMap Unit UnitVisibility
    
    286
    -
    
    287
    --- | 'UnitVisibility' records the various aspects of visibility of a particular
    
    288
    --- 'Unit'.
    
    289
    -data UnitVisibility = UnitVisibility
    
    290
    -    { uv_expose_all :: Bool
    
    291
    -      --  ^ Should all modules in exposed-modules should be dumped into scope?
    
    292
    -    , uv_renamings :: [(ModuleName, ModuleName)]
    
    293
    -      -- ^ Any custom renamings that should bring extra 'ModuleName's into
    
    294
    -      -- scope.
    
    295
    -    , uv_package_name :: First FastString
    
    296
    -      -- ^ The package name associated with the 'Unit'.  This is used
    
    297
    -      -- to implement legacy behavior where @-package foo-0.1@ implicitly
    
    298
    -      -- hides any packages named @foo@
    
    299
    -    , uv_requirements :: UniqMap ModuleName (Set InstantiatedModule)
    
    300
    -      -- ^ The signatures which are contributed to the requirements context
    
    301
    -      -- from this unit ID.
    
    302
    -    , uv_explicit :: Maybe PackageArg
    
    303
    -      -- ^ Whether or not this unit was explicitly brought into scope,
    
    304
    -      -- as opposed to implicitly via the 'exposed' fields in the
    
    305
    -      -- package database (when @-hide-all-packages@ is not passed.)
    
    306
    -    }
    
    307
    -
    
    308
    -instance Outputable UnitVisibility where
    
    309
    -    ppr (UnitVisibility {
    
    310
    -        uv_expose_all = b,
    
    311
    -        uv_renamings = rns,
    
    312
    -        uv_package_name = First mb_pn,
    
    313
    -        uv_requirements = reqs,
    
    314
    -        uv_explicit = explicit
    
    315
    -    }) = ppr (b, rns, mb_pn, reqs, explicit)
    
    316
    -
    
    317
    -instance Semigroup UnitVisibility where
    
    318
    -    uv1 <> uv2
    
    319
    -        = UnitVisibility
    
    320
    -          { uv_expose_all = uv_expose_all uv1 || uv_expose_all uv2
    
    321
    -          , uv_renamings = uv_renamings uv1 ++ uv_renamings uv2
    
    322
    -          , uv_package_name = mappend (uv_package_name uv1) (uv_package_name uv2)
    
    323
    -          , uv_requirements = plusUniqMap_C Set.union (uv_requirements uv2) (uv_requirements uv1)
    
    324
    -          , uv_explicit = uv_explicit uv1 <|> uv_explicit uv2
    
    325
    -          }
    
    326
    -
    
    327
    -instance Monoid UnitVisibility where
    
    328
    -    mempty = UnitVisibility
    
    329
    -             { uv_expose_all = False
    
    330
    -             , uv_renamings = []
    
    331
    -             , uv_package_name = First Nothing
    
    332
    -             , uv_requirements = emptyUniqMap
    
    333
    -             , uv_explicit = Nothing
    
    334
    -             }
    
    335
    -    mappend = (Semigroup.<>)
    
    336
    -
    
    337
    -
    
    338 168
     -- | Unit configuration
    
    339 169
     data UnitConfig = UnitConfig
    
    340 170
        { unitConfigPlatformArchOS :: !ArchOS        -- ^ Platform arch and OS
    
    ... ... @@ -358,8 +188,6 @@ data UnitConfig = UnitConfig
    358 188
        , unitConfigHideAll        :: !Bool     -- ^ Hide all units by default
    
    359 189
        , unitConfigHideAllPlugins :: !Bool     -- ^ Hide all plugins units by default
    
    360 190
     
    
    361
    -   , unitConfigDBCache      :: !(ExternalUnitDatabaseCache UnitId)
    
    362
    -
    
    363 191
        -- command-line flags
    
    364 192
        , unitConfigFlagsDB      :: [PackageDBFlag]     -- ^ Unit databases flags
    
    365 193
        , unitConfigFlagsExposed :: [PackageFlag]       -- ^ Exposed units
    
    ... ... @@ -369,8 +197,8 @@ data UnitConfig = UnitConfig
    369 197
        , unitConfigHomeUnits    :: Set.Set UnitId
    
    370 198
        }
    
    371 199
     
    
    372
    -initUnitConfig :: DynFlags -> ExternalUnitDatabaseCache UnitId -> Set.Set UnitId -> UnitConfig
    
    373
    -initUnitConfig dflags cached_dbs home_units =
    
    200
    +initUnitConfig :: DynFlags -> Set.Set UnitId -> UnitConfig
    
    201
    +initUnitConfig dflags home_units =
    
    374 202
        let !hu_id             = homeUnitId_ dflags
    
    375 203
            !hu_instanceof     = homeUnitInstanceOf_ dflags
    
    376 204
            !hu_instantiations = homeUnitInstantiations_ dflags
    
    ... ... @@ -407,7 +235,6 @@ initUnitConfig dflags cached_dbs home_units =
    407 235
           , unitConfigHideAll        = gopt Opt_HideAllPackages dflags
    
    408 236
           , unitConfigHideAllPlugins = gopt Opt_HideAllPluginPackages dflags
    
    409 237
     
    
    410
    -      , unitConfigDBCache      = cached_dbs
    
    411 238
           , unitConfigFlagsDB      = map (offsetPackageDb (workingDirectory dflags)) $ packageDBFlags dflags
    
    412 239
           , unitConfigFlagsExposed = packageFlags dflags
    
    413 240
           , unitConfigFlagsIgnored = ignorePackageFlags dflags
    
    ... ... @@ -422,77 +249,6 @@ initUnitConfig dflags cached_dbs home_units =
    422 249
         offsetPackageDb (Just offset) (PackageDB (PkgDbPath p)) | OsPath.isRelative p = PackageDB (PkgDbPath (OsPath.unsafeEncodeUtf offset OsPath.</> p))
    
    423 250
         offsetPackageDb _ p = p
    
    424 251
     
    
    425
    -
    
    426
    --- | Map from 'ModuleName' to a set of module providers (i.e. a 'Module' and
    
    427
    --- its 'ModuleOrigin').
    
    428
    ---
    
    429
    --- NB: the set is in fact a 'Map Module ModuleOrigin', probably to keep only one
    
    430
    --- origin for a given 'Module'
    
    431
    -
    
    432
    -type ModuleNameProvidersMap =
    
    433
    -    UniqMap ModuleName (UniqMap Module ModuleOrigin)
    
    434
    -
    
    435
    -data GlobalUnitKey =
    
    436
    -  GlobalUnitKey
    
    437
    -    !UnitId -- ^ Unit Id of the 'UnitInfo'
    
    438
    -    !ST.ShortText
    
    439
    -
    
    440
    -globalUnitKeyFromUnitInfo :: UnitInfo -> GlobalUnitKey
    
    441
    -globalUnitKeyFromUnitInfo ui = GlobalUnitKey (unitId ui) (unitAbiHash ui)
    
    442
    -
    
    443
    -type GlobalUnitInfoMap = UniqMap UnitId (Map ST.ShortText UnitInfo)
    
    444
    -
    
    445
    -lookupGlobalUnitInfoMap :: GlobalUnitKey -> GlobalUnitInfoMap -> Maybe UnitInfo
    
    446
    -lookupGlobalUnitInfoMap (GlobalUnitKey uid abiHash) globalMap =
    
    447
    -  case lookupUniqMap globalMap uid of
    
    448
    -    Nothing -> Nothing
    
    449
    -    Just sameUnitId -> Map.lookup abiHash sameUnitId
    
    450
    -
    
    451
    -mkGlobalUnitInfoMap :: [(UnitId, UnitInfo)] -> GlobalUnitInfoMap
    
    452
    -mkGlobalUnitInfoMap unitInfos =
    
    453
    -  listToUniqMap_C Map.union . map (\(uid, v) -> (uid, Map.singleton (unitAbiHash v) v)) $ unitInfos
    
    454
    -
    
    455
    -
    
    456
    -data UnitIndex = UnitIndex
    
    457
    -  { ui_wireMap :: !WiringMap
    
    458
    -  -- ^ TODO @fendor: document global property
    
    459
    -  , ui_unwireMap :: !UnwiringMap
    
    460
    -  -- ^ TODO @fendor: document global property
    
    461
    -  , ui_unitInfoMap :: !GlobalUnitInfoMap
    
    462
    -  -- ^ TODO @fendor: document
    
    463
    -  }
    
    464
    -
    
    465
    -initUnitIndex :: UnitIndex
    
    466
    -initUnitIndex = UnitIndex
    
    467
    -  { ui_wireMap = emptyUniqMap
    
    468
    -  , ui_unwireMap = emptyUniqMap
    
    469
    -  , ui_unitInfoMap = emptyUniqMap
    
    470
    -  }
    
    471
    -
    
    472
    -setWireMap :: WiringMap -> UnitIndex -> UnitIndex
    
    473
    -setWireMap wired_map unit_index =
    
    474
    -  unit_index
    
    475
    -    { ui_wireMap = wired_map
    
    476
    -    , ui_unwireMap = listToUniqMap [ (v,k) | (k,v) <- nonDetUniqMapToList wired_map ]
    
    477
    -    }
    
    478
    -
    
    479
    -isWireMapEmpty :: UnitIndex -> Bool
    
    480
    -isWireMapEmpty unit_index =
    
    481
    -  isNullUniqMap (ui_wireMap unit_index)
    
    482
    -
    
    483
    -addUnitInfoMap :: UnitInfoMap -> UnitIndex -> UnitIndex
    
    484
    -addUnitInfoMap unit_info_map unit_index =
    
    485
    -  unit_index
    
    486
    -    { ui_unitInfoMap = plusUniqMap_C Map.union globalMap (ui_unitInfoMap unit_index)
    
    487
    -    }
    
    488
    -  where
    
    489
    -    globalMap :: GlobalUnitInfoMap
    
    490
    -    globalMap = mkGlobalUnitInfoMap $ nonDetUniqMapToList unit_info_map
    
    491
    -
    
    492
    --- lookupUnitInfoMap :: UnitIndex -> UnitId -> Maybe UnitInfo
    
    493
    --- lookupUnitInfoMap unit_index unit_id =
    
    494
    ---   lookupUniqMap (ui_unitInfoMap unit_index) unit_id
    
    495
    -
    
    496 252
     data UnitState = UnitState {
    
    497 253
       -- | A mapping of 'Unit' to 'UnitInfo'.  This list is adjusted
    
    498 254
       -- so that only valid units are here.  'UnitInfo' reflects
    
    ... ... @@ -500,12 +256,18 @@ data UnitState = UnitState {
    500 256
       -- is adjusted at runtime.  (In particular, some units in this map
    
    501 257
       -- may have the 'exposed' flag be 'False'.)
    
    502 258
       --
    
    503
    -  -- TODO @fendor: All values are shared with 'UnitIndex.ui_unitInfoMap'.
    
    259
    +  -- All values are shared with 'UnitIndex'.'globalUnits'.
    
    504 260
       unitInfoMap :: UnitInfoMap,
    
    505 261
     
    
    506
    -  -- | Local overlay for the unit info so that sharing is more accurate
    
    507
    -  trustedUnits :: Set.Set UnitId, -- TODO @fendor: UniqSet
    
    508
    -  distrustedUnits :: Set.Set UnitId, -- TODO @fendor: UniqSet
    
    262
    +  -- | Set of units that we trust.
    
    263
    +  --
    
    264
    +  -- Local overlay of 'UnitInfo'.
    
    265
    +  trustedUnits :: UniqSet UnitId,
    
    266
    +
    
    267
    +  -- | Set of units that we distrust.
    
    268
    +  --
    
    269
    +  -- Local overlay of 'UnitInfo'.
    
    270
    +  distrustedUnits :: UniqSet UnitId,
    
    509 271
     
    
    510 272
       -- | A mapping of 'PackageName' to 'UnitId'. If several units have the same
    
    511 273
       -- package name (e.g. different instantiations), then we return one of them...
    
    ... ... @@ -513,12 +275,6 @@ data UnitState = UnitState {
    513 275
       -- And also to resolve package qualifiers with the PackageImports extension.
    
    514 276
       packageNameMap            :: UniqFM PackageName UnitId,
    
    515 277
     
    
    516
    -  -- -- | A mapping from database unit keys to wired in unit ids.
    
    517
    -  -- wireMap :: WiringMap,
    
    518
    -
    
    519
    -  -- -- | A mapping from wired in unit ids to unit keys from the database.
    
    520
    -  -- unwireMap :: UnwiringMap,
    
    521
    -
    
    522 278
       -- | The units we're going to link in eagerly.  This list
    
    523 279
       -- should be in reverse dependency order; that is, a unit
    
    524 280
       -- is always mentioned before the units it depends on.
    
    ... ... @@ -559,8 +315,8 @@ data UnitState = UnitState {
    559 315
     emptyUnitState :: UnitState
    
    560 316
     emptyUnitState = UnitState {
    
    561 317
         unitInfoMap    = emptyUniqMap,
    
    562
    -    trustedUnits   = Set.empty,
    
    563
    -    distrustedUnits = Set.empty,
    
    318
    +    trustedUnits   = emptyUniqSet,
    
    319
    +    distrustedUnits = emptyUniqSet,
    
    564 320
         packageNameMap = emptyUFM,
    
    565 321
         -- wireMap        = emptyUniqMap,
    
    566 322
         -- unwireMap      = emptyUniqMap,
    
    ... ... @@ -573,45 +329,14 @@ emptyUnitState = UnitState {
    573 329
         allowVirtualUnits = False
    
    574 330
         }
    
    575 331
     
    
    576
    -type UnitInfoMap = UniqMap UnitId UnitInfo
    
    577
    -
    
    578 332
     -- | Find the unit we know about with the given unit, if any
    
    579 333
     lookupUnit :: UnitState -> Unit -> Maybe UnitInfo
    
    580 334
     lookupUnit pkgs = lookupUnit' (allowVirtualUnits pkgs) (unitInfoMap pkgs)
    
    581 335
     
    
    582
    --- | A more specialized interface, which doesn't require a 'UnitState' (so it
    
    583
    --- can be used while we're initializing 'DynFlags')
    
    584
    ---
    
    585
    --- Parameters:
    
    586
    ---    * a boolean specifying whether or not to look for on-the-fly renamed interfaces
    
    587
    ---    * a 'UnitInfoMap'
    
    588
    -lookupUnit' :: Bool -> UnitInfoMap -> Unit -> Maybe UnitInfo
    
    589
    -lookupUnit' allowOnTheFlyInst pkg_map u = case u of
    
    590
    -   HoleUnit   -> error "Hole unit"
    
    591
    -   RealUnit i -> lookupUniqMap pkg_map (unDefinite i)
    
    592
    -   VirtUnit i
    
    593
    -      | allowOnTheFlyInst
    
    594
    -      -> -- lookup UnitInfo of the indefinite unit to be instantiated and
    
    595
    -         -- instantiate it on-the-fly
    
    596
    -         fmap (renameUnitInfo pkg_map (instUnitInsts i))
    
    597
    -           (lookupUniqMap pkg_map (instUnitInstanceOf i))
    
    598
    -
    
    599
    -      | otherwise
    
    600
    -      -> -- lookup UnitInfo by virtual UnitId. This is used to find indefinite
    
    601
    -         -- units. Even if they are real, installed units, they can't use the
    
    602
    -         -- `RealUnit` constructor (it is reserved for definite units) so we use
    
    603
    -         -- the `VirtUnit` constructor.
    
    604
    -         lookupUniqMap pkg_map (virtualUnitId i)
    
    605
    -
    
    606 336
     -- | Find the unit we know about with the given unit id, if any
    
    607 337
     lookupUnitId :: UnitState -> UnitId -> Maybe UnitInfo
    
    608 338
     lookupUnitId state uid = lookupUnitId' (unitInfoMap state) uid
    
    609 339
     
    
    610
    --- | Find the unit we know about with the given unit id, if any
    
    611
    -lookupUnitId' :: UnitInfoMap -> UnitId -> Maybe UnitInfo
    
    612
    -lookupUnitId' db uid = lookupUniqMap db uid
    
    613
    -
    
    614
    -
    
    615 340
     -- | Looks up the given unit in the unit state, panicking if it is not found
    
    616 341
     unsafeLookupUnit :: HasDebugCallStack => UnitState -> Unit -> UnitInfo
    
    617 342
     unsafeLookupUnit state u = case lookupUnit state u of
    
    ... ... @@ -691,20 +416,21 @@ mkUnitInfoMap infos = foldl' add emptyUniqMap infos
    691 416
     listUnitInfo :: UnitState -> [UnitInfo]
    
    692 417
     listUnitInfo state = nonDetEltsUniqMap (unitInfoMap state)
    
    693 418
     
    
    694
    -isUnitTrusted :: HasDebugCallStack => UnitState -> Unit -> Bool
    
    695
    -isUnitTrusted ue u =
    
    696
    -     Set.member (toUnitId u) (trustedUnits ue) && (Set.notMember (toUnitId u) (distrustedUnits ue))
    
    697
    -  || unitIsTrusted (unsafeLookupUnit ue u)
    
    698
    -
    
    419
    +-- | Do we trust the 'UnitInfo' for the given 'UnitId'?
    
    699 420
     isUnitIdTrusted :: HasDebugCallStack => UnitState -> UnitId -> Bool
    
    700 421
     isUnitIdTrusted ue u =
    
    701
    -     Set.member u (trustedUnits ue) && (Set.notMember u (distrustedUnits ue))
    
    422
    +     elementOfUniqSet u (trustedUnits ue) && (not $ elementOfUniqSet u (distrustedUnits ue))
    
    702 423
       || unitIsTrusted (unsafeLookupUnitId ue u)
    
    703 424
     
    
    425
    +-- | Do we trust the 'UnitInfo' for the given 'Unit'?
    
    426
    +isUnitTrusted :: HasDebugCallStack => UnitState -> Unit -> Bool
    
    427
    +isUnitTrusted ue u =
    
    428
    +  isUnitIdTrusted ue (toUnitId u)
    
    429
    +
    
    430
    +-- | Do we trust the given 'UnitInfo'?
    
    704 431
     isUnitInfoTrusted :: HasDebugCallStack => UnitState -> UnitInfo -> Bool
    
    705 432
     isUnitInfoTrusted ue unit_info =
    
    706
    -     Set.member (unitId unit_info) (trustedUnits ue) && (Set.notMember (unitId unit_info) (distrustedUnits ue))
    
    707
    -  || unitIsTrusted unit_info
    
    433
    +  isUnitIdTrusted ue (unitId unit_info)
    
    708 434
     
    
    709 435
     -- ----------------------------------------------------------------------------
    
    710 436
     -- Loading the unit db files and building up the unit state
    
    ... ... @@ -714,22 +440,22 @@ isUnitInfoTrusted ue unit_info =
    714 440
     -- command-line (@-package@, @-hide-package@ etc.)
    
    715 441
     --
    
    716 442
     -- 'initUnits' can be called again subsequently after updating the
    
    717
    --- 'packageFlags' field of the 'DynFlags', and it will update the
    
    718
    --- 'unitState' in 'DynFlags'.
    
    719
    -initUnits :: Logger -> DynFlags -> IORef UnitIndex -> ExternalUnitDatabaseCache UnitId -> Set.Set UnitId -> IO (UnitState, HomeUnit, Maybe PlatformConstants)
    
    443
    +-- 'packageFlags' and 'packageDBFlags' fields of the 'DynFlags', and it will
    
    444
    +-- update the 'unitState' in 'DynFlags'.
    
    445
    +initUnits :: Logger -> DynFlags -> UnitIndexCache -> ExternalUnitDatabaseCache UnitId -> Set.Set UnitId -> IO (UnitState, HomeUnit, Maybe PlatformConstants)
    
    720 446
     initUnits logger dflags unit_index cached_dbs home_units = do
    
    721 447
     
    
    722 448
       let forceUnitInfoMap state = unitInfoMap state `seq` ()
    
    723 449
     
    
    724 450
       unit_state <- withTiming logger (text "initializing unit database")
    
    725 451
                        forceUnitInfoMap
    
    726
    -                 $ mkUnitState logger unit_index (initUnitConfig dflags cached_dbs home_units)
    
    452
    +                 $ mkUnitState logger unit_index cached_dbs (initUnitConfig dflags  home_units)
    
    727 453
     
    
    728 454
       putDumpFileMaybe logger Opt_D_dump_mod_map "Module Map"
    
    729 455
         FormatText (updSDocContext (\ctx -> ctx {sdocLineLength = 200})
    
    730 456
                     $ pprModuleMap (moduleNameProvidersMap unit_state))
    
    731 457
     
    
    732
    -  wireMap <- ui_wireMap <$> readIORef unit_index
    
    458
    +  wireMap <- wiringMap <$> readUnitIndex unit_index
    
    733 459
     
    
    734 460
       let home_unit = mkHomeUnit wireMap
    
    735 461
                                  (homeUnitId_ dflags)
    
    ... ... @@ -756,7 +482,7 @@ initUnits logger dflags unit_index cached_dbs home_units = do
    756 482
       return (unit_state,home_unit,mconstants)
    
    757 483
     
    
    758 484
     mkHomeUnit
    
    759
    -    :: WiringMap
    
    485
    +    :: WireMap
    
    760 486
         -> UnitId                 -- ^ Home unit id
    
    761 487
         -> Maybe UnitId           -- ^ Home unit instance of
    
    762 488
         -> [(ModuleName, Module)] -- ^ Home unit instantiations
    
    ... ... @@ -765,7 +491,7 @@ mkHomeUnit wmap hu_id hu_instanceof hu_instantiations_ =
    765 491
         let
    
    766 492
             -- Some wired units can be used to instantiate the home unit. We need to
    
    767 493
             -- replace their unit keys with their wired unit ids.
    
    768
    -        hu_instantiations = map (fmap (upd_wired_in_mod wmap)) hu_instantiations_
    
    494
    +        hu_instantiations = map (fmap (updateWiredInUnitIdInModule wmap)) hu_instantiations_
    
    769 495
         in case (hu_instanceof, hu_instantiations) of
    
    770 496
           (Nothing,[]) -> DefiniteHomeUnit hu_id Nothing
    
    771 497
           (Nothing, _) -> throwGhcException $ CmdLineError ("Use of -instantiated-with requires -this-component-id")
    
    ... ... @@ -782,205 +508,6 @@ mkHomeUnit wmap hu_id hu_instanceof hu_instantiations_ =
    782 508
              | otherwise
    
    783 509
              -> DefiniteHomeUnit hu_id (Just (u, is))
    
    784 510
     
    
    785
    --- -----------------------------------------------------------------------------
    
    786
    --- Reading the unit database(s)
    
    787
    -
    
    788
    -readUnitDatabases :: Logger -> UnitConfig -> IO [UnitDatabase UnitId]
    
    789
    -readUnitDatabases logger cfg = do
    
    790
    -  conf_refs <- getUnitDbRefs cfg
    
    791
    -  confs     <- liftM catMaybes $ mapM (resolveUnitDatabase cfg) conf_refs
    
    792
    -  mapM (readOrGetUnitDatabase logger cfg) confs
    
    793
    -
    
    794
    -
    
    795
    -getUnitDbRefs :: UnitConfig -> IO [PkgDbRef]
    
    796
    -getUnitDbRefs cfg = do
    
    797
    -  let system_conf_refs = [UserPkgDb, GlobalPkgDb]
    
    798
    -
    
    799
    -  e_pkg_path <- tryIO (getEnv $ map toUpper (unitConfigProgramName cfg) ++ "_PACKAGE_PATH")
    
    800
    -  let base_conf_refs = case e_pkg_path of
    
    801
    -        Left _ -> system_conf_refs
    
    802
    -        Right path
    
    803
    -         | Just (xs, x) <- snocView path, isSearchPathSeparator x
    
    804
    -         -> map PkgDbPath (OsPath.splitSearchPath (OsPath.unsafeEncodeUtf xs)) ++ system_conf_refs
    
    805
    -         | otherwise
    
    806
    -         -> map PkgDbPath (OsPath.splitSearchPath (OsPath.unsafeEncodeUtf path))
    
    807
    -
    
    808
    -  -- Apply the package DB-related flags from the command line to get the
    
    809
    -  -- final list of package DBs.
    
    810
    -  --
    
    811
    -  -- Notes on ordering:
    
    812
    -  --  * The list of flags is reversed (later ones first)
    
    813
    -  --  * We work with the package DB list in "left shadows right" order
    
    814
    -  --  * and finally reverse it at the end, to get "right shadows left"
    
    815
    -  --
    
    816
    -  return $ reverse (foldr doFlag base_conf_refs (unitConfigFlagsDB cfg))
    
    817
    - where
    
    818
    -  doFlag (PackageDB p) dbs = p : dbs
    
    819
    -  doFlag NoUserPackageDB dbs = filter isNotUser dbs
    
    820
    -  doFlag NoGlobalPackageDB dbs = filter isNotGlobal dbs
    
    821
    -  doFlag ClearPackageDBs _ = []
    
    822
    -
    
    823
    -  isNotUser UserPkgDb = False
    
    824
    -  isNotUser _ = True
    
    825
    -
    
    826
    -  isNotGlobal GlobalPkgDb = False
    
    827
    -  isNotGlobal _ = True
    
    828
    -
    
    829
    --- | Return the path of a package database from a 'PkgDbRef'. Return 'Nothing'
    
    830
    --- when the user database filepath is expected but the latter doesn't exist.
    
    831
    ---
    
    832
    --- NB: This logic is reimplemented in Cabal, so if you change it,
    
    833
    --- make sure you update Cabal. (Or, better yet, dump it in the
    
    834
    --- compiler info so Cabal can use the info.)
    
    835
    -resolveUnitDatabase :: UnitConfig -> PkgDbRef -> IO (Maybe OsPath)
    
    836
    -resolveUnitDatabase cfg GlobalPkgDb = return $ Just $ OsPath.unsafeEncodeUtf $ unitConfigGlobalDB cfg
    
    837
    -resolveUnitDatabase cfg UserPkgDb = runMaybeT $ do
    
    838
    -  dir <- versionedAppDir (unitConfigProgramName cfg) (unitConfigPlatformArchOS cfg)
    
    839
    -  let pkgconf = dir </> unitConfigDBName cfg
    
    840
    -  exist <- tryMaybeT $ doesDirectoryExist pkgconf
    
    841
    -  if exist then return (OsPath.unsafeEncodeUtf pkgconf) else mzero
    
    842
    -resolveUnitDatabase _ (PkgDbPath name) = return $ Just name
    
    843
    -
    
    844
    --- | Get the cached 'UnitDatabase' or read the 'UnitDatabase' at the given location.
    
    845
    -readOrGetUnitDatabase :: Logger -> UnitConfig -> OsPath -> IO (UnitDatabase UnitId)
    
    846
    -readOrGetUnitDatabase logger cfg conf_file =
    
    847
    -  readExternalUnitDatabase (unitConfigDBCache cfg) conf_file >>= \ case
    
    848
    -    Nothing -> do
    
    849
    -      new_db <- readUnitDatabase logger cfg conf_file
    
    850
    -      cacheExternalUnitDatabase (unitConfigDBCache cfg) new_db
    
    851
    -      pure new_db
    
    852
    -    Just db ->
    
    853
    -      pure db
    
    854
    -
    
    855
    --- | Read the 'UnitDatabase' at the given location.
    
    856
    -readUnitDatabase :: Logger -> UnitConfig -> OsPath -> IO (UnitDatabase UnitId)
    
    857
    -readUnitDatabase logger cfg conf_file = do
    
    858
    -  isdir <- OsPath.doesDirectoryExist conf_file
    
    859
    -
    
    860
    -  proto_pkg_configs <-
    
    861
    -    if isdir
    
    862
    -       then readDirStyleUnitInfo conf_file
    
    863
    -       else do
    
    864
    -            isfile <- OsPath.doesFileExist conf_file
    
    865
    -            if isfile
    
    866
    -               then do
    
    867
    -                 mpkgs <- tryReadOldFileStyleUnitInfo
    
    868
    -                 case mpkgs of
    
    869
    -                   Just pkgs -> return pkgs
    
    870
    -                   Nothing   -> throwGhcExceptionIO $ InstallationError $
    
    871
    -                      "ghc no longer supports single-file style package " ++
    
    872
    -                      "databases (" ++ show conf_file ++
    
    873
    -                      ") use 'ghc-pkg init' to create the database with " ++
    
    874
    -                      "the correct format."
    
    875
    -               else throwGhcExceptionIO $ InstallationError $
    
    876
    -                      "can't find a package database at " ++ show conf_file
    
    877
    -
    
    878
    -  let
    
    879
    -      -- Fix #16360: remove trailing slash from conf_file before calculating pkgroot
    
    880
    -      conf_file' = OsPath.dropTrailingPathSeparator conf_file
    
    881
    -      top_dir = OsPath.unsafeEncodeUtf (unitConfigGHCDir cfg)
    
    882
    -      pkgroot = OsPath.takeDirectory conf_file'
    
    883
    -      pkg_configs1 = map (mungeUnitInfo top_dir pkgroot . mapUnitInfo (\(UnitKey x) -> UnitId x) . mkUnitKeyInfo)
    
    884
    -                         proto_pkg_configs
    
    885
    -  --
    
    886
    -  pkg_configs2 <- traverse evaluateUnitInfo pkg_configs1
    
    887
    -  return $ pkg_configs2 `seqList` UnitDatabase conf_file' pkg_configs2
    
    888
    -  where
    
    889
    -    readDirStyleUnitInfo :: OsPath -> IO [DbUnitInfo]
    
    890
    -    readDirStyleUnitInfo conf_dir = do
    
    891
    -      let filename = conf_dir OsPath.</> (OsPath.unsafeEncodeUtf "package.cache")
    
    892
    -      cache_exists <- OsPath.doesFileExist filename
    
    893
    -      if cache_exists
    
    894
    -        then do
    
    895
    -          debugTraceMsg logger 2 $ text "Using binary package database:" <+> ppr filename
    
    896
    -          readPackageDbForGhc filename
    
    897
    -        else do
    
    898
    -          -- If there is no package.cache file, we check if the database is not
    
    899
    -          -- empty by inspecting if the directory contains any .conf file. If it
    
    900
    -          -- does, something is wrong and we fail. Otherwise we assume that the
    
    901
    -          -- database is empty.
    
    902
    -          debugTraceMsg logger 2 $ text "There is no package.cache in"
    
    903
    -                      <+> ppr conf_dir
    
    904
    -                       <> text ", checking if the database is empty"
    
    905
    -          db_empty <- all (not . OsPath.isSuffixOf (OsPath.unsafeEncodeUtf ".conf"))
    
    906
    -                   <$> OsPath.getDirectoryContents conf_dir
    
    907
    -          if db_empty
    
    908
    -            then do
    
    909
    -              debugTraceMsg logger 3 $ text "There are no .conf files in"
    
    910
    -                          <+> ppr conf_dir <> text ", treating"
    
    911
    -                          <+> text "package database as empty"
    
    912
    -              return []
    
    913
    -            else
    
    914
    -              throwGhcExceptionIO $ InstallationError $
    
    915
    -                "there is no package.cache in " ++ show conf_dir ++
    
    916
    -                " even though package database is not empty"
    
    917
    -
    
    918
    -
    
    919
    -    -- Single-file style package dbs have been deprecated for some time, but
    
    920
    -    -- it turns out that Cabal was using them in one place. So this is a
    
    921
    -    -- workaround to allow older Cabal versions to use this newer ghc.
    
    922
    -    -- We check if the file db contains just "[]" and if so, we look for a new
    
    923
    -    -- dir-style db in conf_file.d/, ie in a dir next to the given file.
    
    924
    -    -- We cannot just replace the file with a new dir style since Cabal still
    
    925
    -    -- assumes it's a file and tries to overwrite with 'writeFile'.
    
    926
    -    -- ghc-pkg also cooperates with this workaround.
    
    927
    -    tryReadOldFileStyleUnitInfo = do
    
    928
    -      content <- readFile (OsPath.unsafeDecodeUtf conf_file) `catchIO` \_ -> return ""
    
    929
    -      if take 2 content == "[]"
    
    930
    -        then do
    
    931
    -          let conf_dir = conf_file OsPath.<.> OsPath.unsafeEncodeUtf "d"
    
    932
    -          direxists <- OsPath.doesDirectoryExist conf_dir
    
    933
    -          if direxists
    
    934
    -             then do debugTraceMsg logger 2 (text "Ignoring old file-style db and trying:" <+> ppr conf_dir)
    
    935
    -                     liftM Just (readDirStyleUnitInfo conf_dir)
    
    936
    -             else return (Just []) -- ghc-pkg will create it when it's updated
    
    937
    -        else return Nothing
    
    938
    -
    
    939
    -mungeUnitInfo :: OsPath -> OsPath
    
    940
    -                   -> UnitInfo -> UnitInfo
    
    941
    -mungeUnitInfo top_dir pkgroot =
    
    942
    -    mungeBytecodeLibFields
    
    943
    -  . mungeLibDirFields
    
    944
    -  . mungeUnitInfoPaths (ST.pack (OsPath.unsafeDecodeUtf top_dir)) (ST.pack (OsPath.unsafeDecodeUtf pkgroot))
    
    945
    -
    
    946
    -mungeLibDirFields :: UnitInfo -> UnitInfo
    
    947
    -mungeLibDirFields pkg =
    
    948
    -    pkg {
    
    949
    -      unitLibraryDynDirs = case unitLibraryDynDirs pkg of
    
    950
    -         [] -> unitLibraryDirs pkg
    
    951
    -         ds -> ds
    
    952
    -      , unitLibraryDirsStatic = case unitLibraryDirsStatic pkg of
    
    953
    -         [] -> unitLibraryDirs pkg
    
    954
    -         ds -> ds
    
    955
    -    }
    
    956
    -
    
    957
    --- | Default to using library-dirs if bytecode library dirs is not explicitly set.
    
    958
    -mungeBytecodeLibFields :: UnitInfo -> UnitInfo
    
    959
    -mungeBytecodeLibFields pkg =
    
    960
    -    pkg {
    
    961
    -      unitLibraryBytecodeDirs = case unitLibraryBytecodeDirs pkg of
    
    962
    -         [] -> unitLibraryDirs pkg
    
    963
    -         ds -> ds
    
    964
    -    }
    
    965
    -
    
    966
    -seqUnitInfo :: UnitInfo -> b -> b
    
    967
    -seqUnitInfo ui b =
    
    968
    -  unitImportDirs ui `seqList`
    
    969
    -  unitIncludeDirs ui `seqList`
    
    970
    -  unitLibraryDirs ui `seqList`
    
    971
    -  unitLibraryBytecodeDirs ui `seqList`
    
    972
    -  unitExtDepFrameworkDirs ui `seq`
    
    973
    -  unitHaddockInterfaces ui `seq`
    
    974
    -  unitHaddockHTMLs ui `seqList`
    
    975
    -  unitLibraryDynDirs ui `seqList`
    
    976
    -  unitLibraryDirsStatic ui `seqList`
    
    977
    -  unitDepends ui `seqList`
    
    978
    -  unitExposedModules ui `seqList`
    
    979
    -  b
    
    980
    -
    
    981
    -evaluateUnitInfo :: UnitInfo -> IO UnitInfo
    
    982
    -evaluateUnitInfo ui = evaluate (seqUnitInfo ui ui)
    
    983
    -
    
    984 511
     -- -----------------------------------------------------------------------------
    
    985 512
     -- Modify our copy of the unit database based on trust flags,
    
    986 513
     -- -trust and -distrust.
    
    ... ... @@ -989,9 +516,9 @@ applyTrustFlag
    989 516
        :: UnitPrecedenceMap
    
    990 517
        -> UnusableUnits
    
    991 518
        -> [UnitInfo]
    
    992
    -   -> (Set.Set UnitId, Set.Set UnitId)
    
    519
    +   -> (UniqSet UnitId, UniqSet UnitId)
    
    993 520
        -> TrustFlag
    
    994
    -   -> MaybeErr UnitErr (Set.Set UnitId, Set.Set UnitId)
    
    521
    +   -> MaybeErr UnitErr (UniqSet UnitId, UniqSet UnitId)
    
    995 522
     applyTrustFlag prec_map unusable pkgs (trusted, distrusted) flag =
    
    996 523
       case flag of
    
    997 524
         -- we trust all matching packages. Maybe should only trust first one?
    
    ... ... @@ -1006,11 +533,11 @@ applyTrustFlag prec_map unusable pkgs (trusted, distrusted) flag =
    1006 533
              Left ps       -> Failed (TrustFlagErr flag ps)
    
    1007 534
              Right (ps,_) -> Succeeded (removeAll ps trusted, insertAll ps distrusted)
    
    1008 535
     
    
    1009
    -insertAll :: [UnitInfo] -> Set UnitId -> Set UnitId
    
    1010
    -insertAll elements set = foldl' (\ acc -> flip Set.insert acc . unitId) set elements
    
    536
    +insertAll :: [UnitInfo] -> UniqSet UnitId -> UniqSet UnitId
    
    537
    +insertAll elements set = foldl' (\ acc -> addOneToUniqSet acc . unitId) set elements
    
    1011 538
     
    
    1012
    -removeAll :: [UnitInfo] -> Set UnitId -> Set UnitId
    
    1013
    -removeAll elements set = foldl' (\ acc -> flip Set.delete acc . unitId) set elements
    
    539
    +removeAll :: [UnitInfo] -> UniqSet UnitId -> UniqSet UnitId
    
    540
    +removeAll elements set = foldl' (\ acc -> addOneToUniqSet acc . unitId) set elements
    
    1014 541
     
    
    1015 542
     applyPackageFlag
    
    1016 543
        :: UnitPrecedenceMap
    
    ... ... @@ -1094,267 +621,8 @@ applyPackageFlag prec_map pkg_map unusable no_hide_others pkgs vm flag =
    1094 621
              Left ps  -> Failed (PackageFlagErr flag ps)
    
    1095 622
              Right ps -> Succeeded $ foldl' delFromUniqMap vm (map mkUnit ps)
    
    1096 623
     
    
    1097
    --- | Like 'selectPackages', but doesn't return a list of unmatched
    
    1098
    --- packages.  Furthermore, any packages it returns are *renamed*
    
    1099
    --- if the 'UnitArg' has a renaming associated with it.
    
    1100
    -findPackages :: UnitPrecedenceMap
    
    1101
    -             -> UnitInfoMap
    
    1102
    -             -> PackageArg -> [UnitInfo]
    
    1103
    -             -> UnusableUnits
    
    1104
    -             -> Either [(UnitInfo, UnusableUnitReason)]
    
    1105
    -                [UnitInfo]
    
    1106
    -findPackages prec_map pkg_map arg pkgs unusable
    
    1107
    -  = let ps = mapMaybe (finder arg) pkgs
    
    1108
    -    in if null ps
    
    1109
    -        then Left (mapMaybe (\(x,y) -> finder arg x >>= \x' -> return (x',y))
    
    1110
    -                            (nonDetEltsUniqMap unusable))
    
    1111
    -        else Right (sortByPreference prec_map ps)
    
    1112
    -  where
    
    1113
    -    finder (PackageArg str) p
    
    1114
    -      = if matchingStr str p
    
    1115
    -          then Just p
    
    1116
    -          else Nothing
    
    1117
    -    finder (UnitIdArg uid) p
    
    1118
    -      = case uid of
    
    1119
    -          RealUnit (Definite iuid)
    
    1120
    -            | iuid == unitId p
    
    1121
    -            -> Just p
    
    1122
    -          VirtUnit inst
    
    1123
    -            | instUnitInstanceOf inst == unitId p
    
    1124
    -            -> Just (renameUnitInfo pkg_map (instUnitInsts inst) p)
    
    1125
    -          _ -> Nothing
    
    1126
    -
    
    1127
    -selectPackages :: UnitPrecedenceMap -> PackageArg -> [UnitInfo]
    
    1128
    -               -> UnusableUnits
    
    1129
    -               -> Either [(UnitInfo, UnusableUnitReason)]
    
    1130
    -                  ([UnitInfo], [UnitInfo])
    
    1131
    -selectPackages prec_map arg pkgs unusable
    
    1132
    -  = let matches = matching arg
    
    1133
    -        (ps,rest) = partition matches pkgs
    
    1134
    -    in if null ps
    
    1135
    -        then Left (filter (matches.fst) (nonDetEltsUniqMap unusable))
    
    1136
    -        else Right (sortByPreference prec_map ps, rest)
    
    1137
    -
    
    1138
    --- | Rename a 'UnitInfo' according to some module instantiation.
    
    1139
    -renameUnitInfo :: UnitInfoMap -> [(ModuleName, Module)] -> UnitInfo -> UnitInfo
    
    1140
    -renameUnitInfo pkg_map insts conf =
    
    1141
    -    let hsubst = listToUFM insts
    
    1142
    -        smod  = renameHoleModule' pkg_map hsubst
    
    1143
    -        new_insts = map (\(k,v) -> (k,smod v)) (unitInstantiations conf)
    
    1144
    -    in conf {
    
    1145
    -        unitInstantiations = new_insts,
    
    1146
    -        unitExposedModules = map (\(mod_name, mb_mod) -> (mod_name, fmap smod mb_mod))
    
    1147
    -                             (unitExposedModules conf)
    
    1148
    -    }
    
    1149
    -
    
    1150
    -
    
    1151
    --- A package named on the command line can either include the
    
    1152
    --- version, or just the name if it is unambiguous.
    
    1153
    -matchingStr :: String -> UnitInfo -> Bool
    
    1154
    -matchingStr str p
    
    1155
    -        =  str == unitPackageIdString p
    
    1156
    -        || str == unitPackageNameString p
    
    1157
    -
    
    1158
    -matchingId :: UnitId -> UnitInfo -> Bool
    
    1159
    -matchingId uid p = uid == unitId p
    
    1160
    -
    
    1161
    -matching :: PackageArg -> UnitInfo -> Bool
    
    1162
    -matching (PackageArg str) = matchingStr str
    
    1163
    -matching (UnitIdArg (RealUnit (Definite uid))) = matchingId uid
    
    1164
    -matching (UnitIdArg _)  = \_ -> False -- TODO: warn in this case
    
    1165
    -
    
    1166
    --- | This sorts a list of packages, putting "preferred" packages first.
    
    1167
    --- See 'compareByPreference' for the semantics of "preference".
    
    1168
    -sortByPreference :: UnitPrecedenceMap -> [UnitInfo] -> [UnitInfo]
    
    1169
    -sortByPreference prec_map = sortBy (flip (compareByPreference prec_map))
    
    1170
    -
    
    1171
    --- | Returns 'GT' if @pkg@ should be preferred over @pkg'@ when picking
    
    1172
    --- which should be "active".  Here is the order of preference:
    
    1173
    ---
    
    1174
    ---      1. First, prefer the latest version
    
    1175
    ---      2. If the versions are the same, prefer the package that
    
    1176
    ---      came in the latest package database.
    
    1177
    ---
    
    1178
    --- Pursuant to #12518, we could change this policy to, for example, remove
    
    1179
    --- the version preference, meaning that we would always prefer the units
    
    1180
    --- in later unit database.
    
    1181
    -compareByPreference
    
    1182
    -    :: UnitPrecedenceMap
    
    1183
    -    -> UnitInfo
    
    1184
    -    -> UnitInfo
    
    1185
    -    -> Ordering
    
    1186
    -compareByPreference prec_map pkg pkg'
    
    1187
    -  = case comparing unitPackageVersion pkg pkg' of
    
    1188
    -        GT -> GT
    
    1189
    -        EQ | Just prec  <- lookupUniqMap prec_map (unitId pkg)
    
    1190
    -           , Just prec' <- lookupUniqMap prec_map (unitId pkg')
    
    1191
    -           -- Prefer the unit from the later DB flag (i.e., higher
    
    1192
    -           -- precedence)
    
    1193
    -           -> compare prec prec'
    
    1194
    -           | otherwise
    
    1195
    -           -> EQ
    
    1196
    -        LT -> LT
    
    1197
    -
    
    1198
    -comparing :: Ord a => (t -> a) -> t -> t -> Ordering
    
    1199
    -comparing f a b = f a `compare` f b
    
    1200
    -
    
    1201
    -pprFlag :: PackageFlag -> SDoc
    
    1202
    -pprFlag flag = case flag of
    
    1203
    -    HidePackage p   -> text "-hide-package " <> text p
    
    1204
    -    ExposePackage doc _ _ -> text doc
    
    1205
    -
    
    1206
    -pprTrustFlag :: TrustFlag -> SDoc
    
    1207
    -pprTrustFlag flag = case flag of
    
    1208
    -    TrustPackage p    -> text "-trust " <> text p
    
    1209
    -    DistrustPackage p -> text "-distrust " <> text p
    
    1210
    -
    
    1211
    --- -----------------------------------------------------------------------------
    
    1212
    --- Wired-in units
    
    1213
    ---
    
    1214
    --- See Note [Wired-in units] in GHC.Unit.Types
    
    1215
    -
    
    1216
    -type WiringMap = UniqMap UnitId UnitId
    
    1217
    -type UnwiringMap = UniqMap UnitId UnitId
    
    1218
    -
    
    1219
    -findWiredInUnits
    
    1220
    -   :: Logger
    
    1221
    -   -> UnitPrecedenceMap
    
    1222
    -   -> [UnitInfo]           -- database
    
    1223
    -   -> VisibilityMap             -- info on what units are visible
    
    1224
    -                                -- for wired in selection
    
    1225
    -   -> IO WiringMap   -- map from unit id to wired identity
    
    1226
    -findWiredInUnits logger prec_map pkgs vis_map = do
    
    1227
    -  -- Now we must find our wired-in units, and rename them to
    
    1228
    -  -- their canonical names (eg. base-1.0 ==> base), as described
    
    1229
    -  -- in Note [Wired-in units] in GHC.Unit.Types
    
    1230
    -  let
    
    1231
    -        matches :: UnitInfo -> UnitId -> Bool
    
    1232
    -        pc `matches` pid = unitPackageName pc == PackageName (unitIdFS pid)
    
    1233
    -
    
    1234
    -        -- find which package corresponds to each wired-in package
    
    1235
    -        -- delete any other packages with the same name
    
    1236
    -        -- update the package and any dependencies to point to the new
    
    1237
    -        -- one.
    
    1238
    -        --
    
    1239
    -        -- When choosing which package to map to a wired-in package
    
    1240
    -        -- name, we try to pick the latest version of exposed packages.
    
    1241
    -        -- However, if there are no exposed wired in packages available
    
    1242
    -        -- (e.g. -hide-all-packages was used), we can't bail: we *have*
    
    1243
    -        -- to assign a package for the wired-in package: so we try again
    
    1244
    -        -- with hidden packages included to (and pick the latest
    
    1245
    -        -- version).
    
    1246
    -        --
    
    1247
    -        -- You can also override the default choice by using -ignore-package:
    
    1248
    -        -- this works even when there is no exposed wired in package
    
    1249
    -        -- available.
    
    1250
    -        --
    
    1251
    -        findWiredInUnit :: [UnitInfo] -> UnitId -> IO (Maybe (UnitId, UnitInfo))
    
    1252
    -        findWiredInUnit pkgs wired_pkg = firstJustsM [try all_exposed_ps, try all_ps, notfound]
    
    1253
    -          where
    
    1254
    -                all_ps = [ p | p <- pkgs, p `matches` wired_pkg ]
    
    1255
    -                all_exposed_ps = [ p | p <- all_ps, (mkUnit p) `elemUniqMap` vis_map ]
    
    1256
    -
    
    1257
    -                try ps = case sortByPreference prec_map ps of
    
    1258
    -                    p:_ -> Just <$> pick p
    
    1259
    -                    _ -> pure Nothing
    
    1260
    -
    
    1261
    -                notfound = do
    
    1262
    -                          debugTraceMsg logger 2 $
    
    1263
    -                            text "wired-in package "
    
    1264
    -                                 <> ftext (unitIdFS wired_pkg)
    
    1265
    -                                 <> text " not found."
    
    1266
    -                          return Nothing
    
    1267
    -                pick :: UnitInfo -> IO (UnitId, UnitInfo)
    
    1268
    -                pick pkg = do
    
    1269
    -                        debugTraceMsg logger 2 $
    
    1270
    -                            text "wired-in package "
    
    1271
    -                                 <> ftext (unitIdFS wired_pkg)
    
    1272
    -                                 <> text " mapped to "
    
    1273
    -                                 <> ppr (unitId pkg)
    
    1274
    -                        return (wired_pkg, pkg)
    
    1275
    -
    
    1276
    -
    
    1277
    -  mb_wired_in_pkgs <- mapM (findWiredInUnit pkgs) wiredInUnitIds
    
    1278
    -  let
    
    1279
    -        wired_in_pkgs = catMaybes mb_wired_in_pkgs
    
    1280
    -
    
    1281
    -        wiredInMap :: UniqMap UnitId UnitId
    
    1282
    -        wiredInMap = listToUniqMap
    
    1283
    -          [ (unitId realUnitInfo, wiredInUnitId)
    
    1284
    -          | (wiredInUnitId, realUnitInfo) <- wired_in_pkgs
    
    1285
    -          , not (unitIsIndefinite realUnitInfo)
    
    1286
    -          ]
    
    1287
    -
    
    1288
    -  return wiredInMap
    
    1289
    -
    
    1290
    -updateWiredInUnits :: WiringMap -> GlobalUnitInfoMap -> [UnitInfo] -> [Either UnitInfo UnitInfo]
    
    1291
    -updateWiredInUnits wiredInMap knownInfos pkgs =
    
    1292
    -  map (updateWiredInUnitsInUnitInfo wiredInMap knownInfos) pkgs
    
    1293
    -
    
    1294
    -updateWiredInUnitsInUnitInfo :: WiringMap -> GlobalUnitInfoMap -> UnitInfo -> Either UnitInfo UnitInfo
    
    1295
    -updateWiredInUnitsInUnitInfo wiredInMap knownInfos pkg =
    
    1296
    -  let
    
    1297
    -    upd_wired_in_pkg wiredInUnitId pkg =
    
    1298
    -      pkg { unitId         = wiredInUnitId
    
    1299
    -          , unitInstanceOf = wiredInUnitId
    
    1300
    -              -- every non instantiated unit is an instance of
    
    1301
    -              -- itself (required by Backpack...)
    
    1302
    -              --
    
    1303
    -              -- See Note [About units] in GHC.Unit
    
    1304
    -          }
    
    1305
    -
    
    1306
    -    upd_deps pkg = pkg {
    
    1307
    -          unitDepends = map (upd_wired_in wiredInMap) (unitDepends pkg),
    
    1308
    -          unitExposedModules
    
    1309
    -            = map (\(k,v) -> (k, fmap (upd_wired_in_mod wiredInMap) v))
    
    1310
    -                  (unitExposedModules pkg)
    
    1311
    -        }
    
    1312
    -  in
    
    1313
    -    case lookupUniqMap wiredInMap (unitId pkg) of
    
    1314
    -      Just wiredIn ->
    
    1315
    -        case lookupGlobalUnitInfoMap (GlobalUnitKey wiredIn (unitAbiHash pkg)) knownInfos of
    
    1316
    -          Just ui ->
    
    1317
    -            Right ui
    
    1318
    -          Nothing ->
    
    1319
    -            let
    
    1320
    -              updated_pkg = upd_deps $ upd_wired_in_pkg wiredIn pkg
    
    1321
    -            in
    
    1322
    -              Left $ seqUnitInfo updated_pkg updated_pkg
    
    1323
    -      Nothing -> case lookupGlobalUnitInfoMap (globalUnitKeyFromUnitInfo pkg) knownInfos of
    
    1324
    -        Just ui ->
    
    1325
    -          Right ui
    
    1326
    -        Nothing ->
    
    1327
    -          let
    
    1328
    -            updated_pkg = upd_deps pkg
    
    1329
    -          in
    
    1330
    -            Left $ seqUnitInfo updated_pkg updated_pkg
    
    1331
    -
    
    1332
    --- Helper functions for rewiring Module and Unit.  These
    
    1333
    --- rewrite Units of modules in wired-in packages to the form known to the
    
    1334
    --- compiler, as described in Note [Wired-in units] in GHC.Unit.Types.
    
    1335
    ---
    
    1336
    --- For instance, base-4.9.0.0 will be rewritten to just base, to match
    
    1337
    --- what appears in GHC.Builtin.Names.
    
    1338
    -
    
    1339
    -upd_wired_in_mod :: WiringMap -> Module -> Module
    
    1340
    -upd_wired_in_mod wiredInMap (Module uid m) = Module (upd_wired_in_uid wiredInMap uid) m
    
    1341
    -
    
    1342
    -upd_wired_in_uid :: WiringMap -> Unit -> Unit
    
    1343
    -upd_wired_in_uid wiredInMap u = case u of
    
    1344
    -   HoleUnit -> HoleUnit
    
    1345
    -   RealUnit (Definite uid) -> RealUnit (Definite (upd_wired_in wiredInMap uid))
    
    1346
    -   VirtUnit indef_uid ->
    
    1347
    -      VirtUnit $ mkInstantiatedUnit
    
    1348
    -        (instUnitInstanceOf indef_uid)
    
    1349
    -        (map (\(x,y) -> (x,upd_wired_in_mod wiredInMap y)) (instUnitInsts indef_uid))
    
    1350
    -
    
    1351
    -upd_wired_in :: WiringMap -> UnitId -> UnitId
    
    1352
    -upd_wired_in wiredInMap key
    
    1353
    -    | Just key' <- lookupUniqMap wiredInMap key = key'
    
    1354
    -    | otherwise = key
    
    1355
    -
    
    1356
    -updateVisibilityMap :: WiringMap -> VisibilityMap -> VisibilityMap
    
    1357
    -updateVisibilityMap wiredInMap vis_map = foldl' f vis_map (nonDetUniqMapToList wiredInMap)
    
    624
    +updateVisibilityMap :: WireMap -> VisibilityMap -> VisibilityMap
    
    625
    +updateVisibilityMap wiredInMap vis_map = foldl' f vis_map (listWireMap wiredInMap)
    
    1358 626
       where f vm (from, to) = case lookupUniqMap vis_map (RealUnit (Definite from)) of
    
    1359 627
                         Nothing -> vm
    
    1360 628
                         Just r -> addToUniqMap (delFromUniqMap vm (RealUnit (Definite from)))
    
    ... ... @@ -1362,51 +630,6 @@ updateVisibilityMap wiredInMap vis_map = foldl' f vis_map (nonDetUniqMapToList w
    1362 630
     
    
    1363 631
       -- ----------------------------------------------------------------------------
    
    1364 632
     
    
    1365
    --- | The reason why a unit is unusable.
    
    1366
    -data UnusableUnitReason
    
    1367
    -  = -- | We ignored it explicitly using @-ignore-package@.
    
    1368
    -    IgnoredWithFlag
    
    1369
    -    -- | This unit transitively depends on a unit that was never present
    
    1370
    -    -- in any of the provided databases.
    
    1371
    -  | BrokenDependencies   [UnitId]
    
    1372
    -    -- | This unit transitively depends on a unit involved in a cycle.
    
    1373
    -    -- Note that the list of 'UnitId' reports the direct dependencies
    
    1374
    -    -- of this unit that (transitively) depended on the cycle, and not
    
    1375
    -    -- the actual cycle itself (which we report separately at high verbosity.)
    
    1376
    -  | CyclicDependencies   [UnitId]
    
    1377
    -    -- | This unit transitively depends on a unit which was ignored.
    
    1378
    -  | IgnoredDependencies  [UnitId]
    
    1379
    -    -- | This unit transitively depends on a unit which was
    
    1380
    -    -- shadowed by an ABI-incompatible unit.
    
    1381
    -  | ShadowedDependencies [UnitId]
    
    1382
    -
    
    1383
    -instance Outputable UnusableUnitReason where
    
    1384
    -    ppr IgnoredWithFlag = text "[ignored with flag]"
    
    1385
    -    ppr (BrokenDependencies uids)   = brackets (text "broken" <+> ppr uids)
    
    1386
    -    ppr (CyclicDependencies uids)   = brackets (text "cyclic" <+> ppr uids)
    
    1387
    -    ppr (IgnoredDependencies uids)  = brackets (text "ignored" <+> ppr uids)
    
    1388
    -    ppr (ShadowedDependencies uids) = brackets (text "shadowed" <+> ppr uids)
    
    1389
    -
    
    1390
    -type UnusableUnits = UniqMap UnitId (UnitInfo, UnusableUnitReason)
    
    1391
    -
    
    1392
    -pprReason :: SDoc -> UnusableUnitReason -> SDoc
    
    1393
    -pprReason pref reason = case reason of
    
    1394
    -  IgnoredWithFlag ->
    
    1395
    -      pref <+> text "ignored due to an -ignore-package flag"
    
    1396
    -  BrokenDependencies deps ->
    
    1397
    -      pref <+> text "unusable due to missing dependencies:" $$
    
    1398
    -        nest 2 (hsep (map ppr deps))
    
    1399
    -  CyclicDependencies deps ->
    
    1400
    -      pref <+> text "unusable due to cyclic dependencies:" $$
    
    1401
    -        nest 2 (hsep (map ppr deps))
    
    1402
    -  IgnoredDependencies deps ->
    
    1403
    -      pref <+> text ("unusable because the -ignore-package flag was used to " ++
    
    1404
    -                     "ignore at least one of its dependencies:") $$
    
    1405
    -        nest 2 (hsep (map ppr deps))
    
    1406
    -  ShadowedDependencies deps ->
    
    1407
    -      pref <+> text "unusable due to shadowed dependencies:" $$
    
    1408
    -        nest 2 (hsep (map ppr deps))
    
    1409
    -
    
    1410 633
     reportCycles :: Logger -> [SCC UnitInfo] -> IO ()
    
    1411 634
     reportCycles logger sccs = when (logVerbAtLeast logger 2) $ mapM_ report sccs
    
    1412 635
       where
    
    ... ... @@ -1416,193 +639,6 @@ reportCycles logger sccs = when (logVerbAtLeast logger 2) $ mapM_ report sccs
    1416 639
               text "these packages are involved in a cycle:" $$
    
    1417 640
                 nest 2 (hsep (map (ppr . unitId) vs))
    
    1418 641
     
    
    1419
    -reportUnusable :: Logger -> UnusableUnits -> IO ()
    
    1420
    -reportUnusable logger pkgs = when (logVerbAtLeast logger 2) $ mapM_ report (nonDetUniqMapToList pkgs)
    
    1421
    -  where
    
    1422
    -    report (ipid, (_, reason)) =
    
    1423
    -       debugTraceMsg logger 2 $
    
    1424
    -         pprReason
    
    1425
    -           (text "package" <+> ppr ipid <+> text "is") reason
    
    1426
    -
    
    1427
    --- ----------------------------------------------------------------------------
    
    1428
    ---
    
    1429
    --- Utilities on the database
    
    1430
    ---
    
    1431
    -
    
    1432
    --- | A reverse dependency index, mapping an 'UnitId' to
    
    1433
    --- the 'UnitId's which have a dependency on it.
    
    1434
    -type RevIndex = UniqMap UnitId [UnitId]
    
    1435
    -
    
    1436
    --- | Compute the reverse dependency index of a unit database.
    
    1437
    -reverseDeps :: UnitInfoMap -> RevIndex
    
    1438
    -reverseDeps db = nonDetFoldUniqMap go emptyUniqMap db
    
    1439
    -  where
    
    1440
    -    go :: (UnitId, UnitInfo) -> RevIndex -> RevIndex
    
    1441
    -    go (_uid, pkg) r = foldl' (go' (unitId pkg)) r (unitDepends pkg)
    
    1442
    -    go' from r to = addToUniqMap_C (++) r to [from]
    
    1443
    -
    
    1444
    --- | Given a list of 'UnitId's to remove, a database,
    
    1445
    --- and a reverse dependency index (as computed by 'reverseDeps'),
    
    1446
    --- remove those units, plus any units which depend on them.
    
    1447
    --- Returns the pruned database, as well as a list of 'UnitInfo's
    
    1448
    --- that was removed.
    
    1449
    -removeUnits :: [UnitId] -> RevIndex
    
    1450
    -               -> UnitInfoMap
    
    1451
    -               -> (UnitInfoMap, [UnitInfo])
    
    1452
    -removeUnits uids index m = go uids (m,[])
    
    1453
    -  where
    
    1454
    -    go [] (m,pkgs) = (m,pkgs)
    
    1455
    -    go (uid:uids) (m,pkgs)
    
    1456
    -        | Just pkg <- lookupUniqMap m uid
    
    1457
    -        = case lookupUniqMap index uid of
    
    1458
    -            Nothing    -> go uids (delFromUniqMap m uid, pkg:pkgs)
    
    1459
    -            Just rdeps -> go (rdeps ++ uids) (delFromUniqMap m uid, pkg:pkgs)
    
    1460
    -        | otherwise
    
    1461
    -        = go uids (m,pkgs)
    
    1462
    -
    
    1463
    --- | Given a 'UnitInfo' from some 'UnitInfoMap', return all entries in 'depends'
    
    1464
    --- which correspond to units that do not exist in the index.
    
    1465
    -depsNotAvailable :: UnitInfoMap
    
    1466
    -                 -> UnitInfo
    
    1467
    -                 -> [UnitId]
    
    1468
    -depsNotAvailable pkg_map pkg = filter (not . (`elemUniqMap` pkg_map)) (unitDepends pkg)
    
    1469
    -
    
    1470
    --- | Given a 'UnitInfo' from some 'UnitInfoMap' return all entries in
    
    1471
    --- 'unitAbiDepends' which correspond to units that do not exist, OR have
    
    1472
    --- mismatching ABIs.
    
    1473
    -depsAbiMismatch :: UnitInfoMap
    
    1474
    -                -> UnitInfo
    
    1475
    -                -> [UnitId]
    
    1476
    -depsAbiMismatch pkg_map pkg = map fst . filter (not . abiMatch) $ unitAbiDepends pkg
    
    1477
    -  where
    
    1478
    -    abiMatch (dep_uid, abi)
    
    1479
    -        | Just dep_pkg <- lookupUniqMap pkg_map dep_uid
    
    1480
    -        = unitAbiHash dep_pkg == abi
    
    1481
    -        | otherwise
    
    1482
    -        = False
    
    1483
    -
    
    1484
    --- -----------------------------------------------------------------------------
    
    1485
    --- Ignore units
    
    1486
    -
    
    1487
    -ignoreUnits :: [IgnorePackageFlag] -> [UnitInfo] -> UnusableUnits
    
    1488
    -ignoreUnits flags pkgs = listToUniqMap (concatMap doit flags)
    
    1489
    -  where
    
    1490
    -  doit (IgnorePackage str) =
    
    1491
    -     case partition (matchingStr str) pkgs of
    
    1492
    -         (ps, _) -> [ (unitId p, (p, IgnoredWithFlag))
    
    1493
    -                    | p <- ps ]
    
    1494
    -        -- missing unit is not an error for -ignore-package,
    
    1495
    -        -- because a common usage is to -ignore-package P as
    
    1496
    -        -- a preventative measure just in case P exists.
    
    1497
    -
    
    1498
    --- ----------------------------------------------------------------------------
    
    1499
    ---
    
    1500
    --- Merging databases
    
    1501
    ---
    
    1502
    -
    
    1503
    --- | For each unit, a mapping from uid -> i indicates that this
    
    1504
    --- unit was brought into GHC by the ith @-package-db@ flag on
    
    1505
    --- the command line.  We use this mapping to make sure we prefer
    
    1506
    --- units that were defined later on the command line, if there
    
    1507
    --- is an ambiguity.
    
    1508
    -type UnitPrecedenceMap = UniqMap UnitId Int
    
    1509
    -
    
    1510
    --- | Given a list of databases, merge them together, where
    
    1511
    --- units with the same unit id in later databases override
    
    1512
    --- earlier ones.  This does NOT check if the resulting database
    
    1513
    --- makes sense (that's done by 'validateDatabase').
    
    1514
    -mergeDatabases :: Logger -> [UnitDatabase UnitId]
    
    1515
    -               -> IO (UnitInfoMap, UnitPrecedenceMap)
    
    1516
    -mergeDatabases logger = foldM merge (emptyUniqMap, emptyUniqMap) . zip [1..]
    
    1517
    -  where
    
    1518
    -    merge (pkg_map, prec_map) (i, UnitDatabase db_path db) = do
    
    1519
    -      debugTraceMsg logger 2 $
    
    1520
    -          text "loading package database" <+> ppr db_path
    
    1521
    -      when (logVerbAtLeast logger 2) $
    
    1522
    -        forM_ (Set.toList override_set) $ \pkg ->
    
    1523
    -            debugTraceMsg logger 2 $
    
    1524
    -                text "package" <+> ppr pkg <+>
    
    1525
    -                text "overrides a previously defined package"
    
    1526
    -      return (pkg_map', prec_map')
    
    1527
    -     where
    
    1528
    -      db_map = mk_pkg_map db
    
    1529
    -      mk_pkg_map = listToUniqMap . map (\p -> (unitId p, p))
    
    1530
    -
    
    1531
    -      -- The set of UnitIds which appear in both db and pkgs.  These are the
    
    1532
    -      -- ones that get overridden.  Compute this just to give some
    
    1533
    -      -- helpful debug messages at -v2
    
    1534
    -      override_set :: Set UnitId
    
    1535
    -      override_set = Set.intersection (nonDetUniqMapToKeySet db_map)
    
    1536
    -                                      (nonDetUniqMapToKeySet pkg_map)
    
    1537
    -
    
    1538
    -      -- Now merge the sets together (NB: in case of duplicate,
    
    1539
    -      -- first argument preferred)
    
    1540
    -      pkg_map' :: UnitInfoMap
    
    1541
    -      pkg_map' = pkg_map `plusUniqMap` db_map
    
    1542
    -
    
    1543
    -      prec_map' :: UnitPrecedenceMap
    
    1544
    -      prec_map' = prec_map `plusUniqMap` (mapUniqMap (const i) db_map)
    
    1545
    -
    
    1546
    --- | Validates a database, removing unusable units from it
    
    1547
    --- (this includes removing units that the user has explicitly
    
    1548
    --- ignored.)  Our general strategy:
    
    1549
    ---
    
    1550
    --- 1. Remove all broken units (dangling dependencies)
    
    1551
    --- 2. Remove all units that are cyclic
    
    1552
    --- 3. Apply ignore flags
    
    1553
    --- 4. Remove all units which have deps with mismatching ABIs
    
    1554
    ---
    
    1555
    -validateDatabase :: UnitConfig -> UnitInfoMap
    
    1556
    -                 -> (UnitInfoMap, UnusableUnits, [SCC UnitInfo])
    
    1557
    -validateDatabase cfg pkg_map1 =
    
    1558
    -    (pkg_map5, unusable, sccs)
    
    1559
    -  where
    
    1560
    -    ignore_flags = reverse (unitConfigFlagsIgnored cfg)
    
    1561
    -
    
    1562
    -    -- Compute the reverse dependency index
    
    1563
    -    index = reverseDeps pkg_map1
    
    1564
    -
    
    1565
    -    -- Helper function
    
    1566
    -    mk_unusable mk_err dep_matcher m uids =
    
    1567
    -      listToUniqMap [ (unitId pkg, (pkg, mk_err (dep_matcher m pkg)))
    
    1568
    -                    | pkg <- uids
    
    1569
    -                    ]
    
    1570
    -
    
    1571
    -    -- Find broken units
    
    1572
    -    directly_broken = filter (not . null . depsNotAvailable pkg_map1)
    
    1573
    -                             (nonDetEltsUniqMap pkg_map1)
    
    1574
    -    (pkg_map2, broken) = removeUnits (map unitId directly_broken) index pkg_map1
    
    1575
    -    unusable_broken = mk_unusable BrokenDependencies depsNotAvailable pkg_map2 broken
    
    1576
    -
    
    1577
    -    -- Find recursive units
    
    1578
    -    sccs = stronglyConnComp [ (pkg, unitId pkg, unitDepends pkg)
    
    1579
    -                            | pkg <- nonDetEltsUniqMap pkg_map2 ]
    
    1580
    -    getCyclicSCC (CyclicSCC vs) = map unitId vs
    
    1581
    -    getCyclicSCC (AcyclicSCC _) = []
    
    1582
    -    (pkg_map3, cyclic) = removeUnits (concatMap getCyclicSCC sccs) index pkg_map2
    
    1583
    -    unusable_cyclic = mk_unusable CyclicDependencies depsNotAvailable pkg_map3 cyclic
    
    1584
    -
    
    1585
    -    -- Apply ignore flags
    
    1586
    -    directly_ignored = ignoreUnits ignore_flags (nonDetEltsUniqMap pkg_map3)
    
    1587
    -    (pkg_map4, ignored) = removeUnits (nonDetKeysUniqMap directly_ignored) index pkg_map3
    
    1588
    -    unusable_ignored = mk_unusable IgnoredDependencies depsNotAvailable pkg_map4 ignored
    
    1589
    -
    
    1590
    -    -- Knock out units whose dependencies don't agree with ABI
    
    1591
    -    -- (i.e., got invalidated due to shadowing)
    
    1592
    -    directly_shadowed = filter (not . null . depsAbiMismatch pkg_map4)
    
    1593
    -                               (nonDetEltsUniqMap pkg_map4)
    
    1594
    -    (pkg_map5, shadowed) = removeUnits (map unitId directly_shadowed) index pkg_map4
    
    1595
    -    unusable_shadowed = mk_unusable ShadowedDependencies depsAbiMismatch pkg_map5 shadowed
    
    1596
    -
    
    1597
    -    -- combine all unusables. The order is important for shadowing.
    
    1598
    -    -- plusUniqMapList folds using plusUFM which is right biased (opposite of
    
    1599
    -    -- Data.Map.union) so the head of the list should be the least preferred
    
    1600
    -    unusable = plusUniqMapList [ unusable_shadowed
    
    1601
    -                               , unusable_cyclic
    
    1602
    -                               , unusable_broken
    
    1603
    -                               , unusable_ignored
    
    1604
    -                               , directly_ignored
    
    1605
    -                               ]
    
    1606 642
     
    
    1607 643
     -- -----------------------------------------------------------------------------
    
    1608 644
     -- When all the command-line options are in, we can process our unit
    
    ... ... @@ -1610,10 +646,11 @@ validateDatabase cfg pkg_map1 =
    1610 646
     
    
    1611 647
     mkUnitState
    
    1612 648
         :: Logger
    
    1613
    -    -> IORef UnitIndex
    
    649
    +    -> UnitIndexCache
    
    650
    +    -> ExternalUnitDatabaseCache UnitId
    
    1614 651
         -> UnitConfig
    
    1615 652
         -> IO UnitState
    
    1616
    -mkUnitState logger unit_index cfg = do
    
    653
    +mkUnitState logger unit_index_cache db_cache cfg = do
    
    1617 654
     {-
    
    1618 655
        Plan.
    
    1619 656
     
    
    ... ... @@ -1667,17 +704,17 @@ mkUnitState logger unit_index cfg = do
    1667 704
               we build a mapping saying what every in scope module name points to.
    
    1668 705
     -}
    
    1669 706
     
    
    1670
    -  raw_dbs <- readUnitDatabases logger cfg
    
    707
    +  raw_dbs <- readUnitDatabases logger db_cache (initUnitDbConfig cfg)
    
    1671 708
     
    
    1672 709
       -- distrust all units if the flag is set
    
    1673
    -  let unitsOf db = Set.fromList $ map unitId (unitDatabaseUnits db)
    
    1674
    -      allUnits = Set.unions $ map unitsOf raw_dbs
    
    710
    +  let unitsOf db = foldl' (\ acc ui -> addOneToUniqSet acc (unitId ui)) emptyUniqSet (unitDatabaseUnits db)
    
    711
    +      allUnits = unionManyUniqSets $ map unitsOf raw_dbs
    
    1675 712
     
    
    1676 713
           distrustedUnits
    
    1677 714
             | unitConfigDistrustAll cfg = allUnits
    
    1678
    -        | otherwise = Set.empty
    
    715
    +        | otherwise = emptyUniqSet
    
    1679 716
     
    
    1680
    -      trustedUnits = Set.empty
    
    717
    +      trustedUnits = emptyUniqSet
    
    1681 718
     
    
    1682 719
           dbs = raw_dbs
    
    1683 720
     
    
    ... ... @@ -1697,7 +734,7 @@ mkUnitState logger unit_index cfg = do
    1697 734
     
    
    1698 735
       -- Now that we've merged everything together, prune out unusable
    
    1699 736
       -- packages.
    
    1700
    -  let (pkg_map2, unusable, sccs) = validateDatabase cfg pkg_map1
    
    737
    +  let (pkg_map2, unusable, sccs) = validateDatabase (unitConfigFlagsIgnored cfg) pkg_map1
    
    1701 738
     
    
    1702 739
       reportCycles   logger sccs
    
    1703 740
       reportUnusable logger unusable
    
    ... ... @@ -1773,19 +810,19 @@ mkUnitState logger unit_index cfg = do
    1773 810
       -- it modifies the unit ids of wired in packages, but when we process
    
    1774 811
       -- package arguments we need to key against the old versions.
    
    1775 812
       --
    
    1776
    -  ui <- readIORef unit_index
    
    813
    +  ui <- readUnitIndex unit_index_cache
    
    1777 814
       (wired_map, pkgs2) <- do
    
    1778
    -    wireMap <- if isWireMapEmpty ui
    
    815
    +    wireMap <- if not (wireMapExists ui)
    
    1779 816
           then do
    
    1780 817
             wmap <- findWiredInUnits logger prec_map pkgs1 vis_map2
    
    1781
    -        modifyIORef' unit_index (setWireMap wmap)
    
    818
    +        modifyUnitIndexCache unit_index_cache (setWireMap wmap)
    
    1782 819
             pure wmap
    
    1783 820
           else do
    
    1784
    -        pure $ ui_wireMap ui
    
    821
    +        pure $ wiringMap ui
    
    1785 822
     
    
    1786
    -    let all_pkgs = updateWiredInUnits wireMap (ui_unitInfoMap ui) pkgs1
    
    823
    +    let all_pkgs = updateWiredInUnits wireMap (globalUnits ui) pkgs1
    
    1787 824
             (new_pkgs, _pkgs_set) = partitionEithers all_pkgs
    
    1788
    -    modifyIORef' unit_index (addUnitInfoMap $ mkUnitInfoMap new_pkgs)
    
    825
    +    modifyUnitIndexCache unit_index_cache (addUnitInfoMap $ mkUnitInfoMap new_pkgs)
    
    1789 826
         pure (wireMap, map (either id id) all_pkgs)
    
    1790 827
     
    
    1791 828
       let pkg_db = mkUnitInfoMap pkgs2
    
    ... ... @@ -1859,7 +896,7 @@ mkUnitState logger unit_index cfg = do
    1859 896
                         $ closeUnitDeps pkg_db
    
    1860 897
                         $ zip (map toUnitId preload3) (repeat Nothing)
    
    1861 898
     
    
    1862
    -  let mod_map1 = mkModuleNameProvidersMap logger cfg pkg_db vis_map
    
    899
    +  let mod_map1 = mkModuleNameProvidersMap logger (unitConfigAllowVirtual cfg) pkg_db vis_map
    
    1863 900
           mod_map2 = mkUnusableModuleNameProvidersMap unusable
    
    1864 901
           mod_map = mod_map2 `plusUniqMap` mod_map1
    
    1865 902
     
    
    ... ... @@ -1872,10 +909,8 @@ mkUnitState logger unit_index cfg = do
    1872 909
              , trustedUnits                 = trusted
    
    1873 910
              , distrustedUnits              = distrusted
    
    1874 911
              , moduleNameProvidersMap       = mod_map
    
    1875
    -         , pluginModuleNameProvidersMap = mkModuleNameProvidersMap logger cfg pkg_db plugin_vis_map
    
    912
    +         , pluginModuleNameProvidersMap = mkModuleNameProvidersMap logger (unitConfigAllowVirtual cfg) pkg_db plugin_vis_map
    
    1876 913
              , packageNameMap               = pkgname_map
    
    1877
    -        --  , wireMap                      = wired_map
    
    1878
    -        --  , unwireMap                    = listToUniqMap [ (v,k) | (k,v) <- nonDetUniqMapToList wired_map ]
    
    1879 914
              , requirementContext           = req_ctx
    
    1880 915
              , allowVirtualUnits            = unitConfigAllowVirtual cfg
    
    1881 916
              }
    
    ... ... @@ -1893,157 +928,15 @@ selectHomeUnits home_units flags = foldl' go Set.empty flags
    1893 928
         -- MP: This does not yet support thinning/renaming
    
    1894 929
         go cur _ = cur
    
    1895 930
     
    
    1896
    -
    
    1897
    --- | Given a wired-in 'Unit', "unwire" it into the 'Unit'
    
    1898
    --- that it was recorded as in the package database.
    
    1899
    -unwireUnit :: UnitIndex -> Unit -> Unit
    
    1900
    -unwireUnit state uid@(RealUnit (Definite def_uid)) =
    
    1901
    -    maybe uid (RealUnit . Definite) (lookupUniqMap (ui_unwireMap state) def_uid)
    
    1902
    -unwireUnit _ uid = uid
    
    1903
    -
    
    1904
    --- -----------------------------------------------------------------------------
    
    1905
    --- | Makes the mapping from ModuleName to package info
    
    1906
    -
    
    1907
    --- Slight irritation: we proceed by leafing through everything
    
    1908
    --- in the installed package database, which makes handling indefinite
    
    1909
    --- packages a bit bothersome.
    
    1910
    -
    
    1911
    -mkModuleNameProvidersMap
    
    1912
    -  :: Logger
    
    1913
    -  -> UnitConfig
    
    1914
    -  -> UnitInfoMap
    
    1915
    -  -> VisibilityMap
    
    1916
    -  -> ModuleNameProvidersMap
    
    1917
    -mkModuleNameProvidersMap logger cfg pkg_map vis_map =
    
    1918
    -    -- What should we fold on?  Both situations are awkward:
    
    1919
    -    --
    
    1920
    -    --    * Folding on the visibility map means that we won't create
    
    1921
    -    --      entries for packages that aren't mentioned in vis_map
    
    1922
    -    --      (e.g., hidden packages, causing #14717)
    
    1923
    -    --
    
    1924
    -    --    * Folding on pkg_map is awkward because if we have an
    
    1925
    -    --      Backpack instantiation, we need to possibly add a
    
    1926
    -    --      package from pkg_map multiple times to the actual
    
    1927
    -    --      ModuleNameProvidersMap.  Also, we don't really want
    
    1928
    -    --      definite package instantiations to show up in the
    
    1929
    -    --      list of possibilities.
    
    1930
    -    --
    
    1931
    -    -- So what will we do instead?  We'll extend vis_map with
    
    1932
    -    -- entries for every definite (for non-Backpack) and
    
    1933
    -    -- indefinite (for Backpack) package, so that we get the
    
    1934
    -    -- hidden entries we need.
    
    1935
    -    nonDetFoldUniqMap extend_modmap emptyMap vis_map_extended
    
    1936
    - where
    
    1937
    -  vis_map_extended = {- preferred -} default_vis `plusUniqMap` vis_map
    
    1938
    -
    
    1939
    -  default_vis = listToUniqMap
    
    1940
    -                  [ (mkUnit pkg, mempty)
    
    1941
    -                  | (_, pkg) <- nonDetUniqMapToList pkg_map
    
    1942
    -                  -- Exclude specific instantiations of an indefinite
    
    1943
    -                  -- package
    
    1944
    -                  , unitIsIndefinite pkg || null (unitInstantiations pkg)
    
    1945
    -                  ]
    
    1946
    -
    
    1947
    -  emptyMap = emptyUniqMap
    
    1948
    -  setOrigins m os = fmap (const os) m
    
    1949
    -  extend_modmap (uid, UnitVisibility { uv_expose_all = b, uv_renamings = rns }) modmap
    
    1950
    -    = addListTo modmap theBindings
    
    1951
    -   where
    
    1952
    -    pkg = unit_lookup uid
    
    1953
    -
    
    1954
    -    theBindings :: [(ModuleName, UniqMap Module ModuleOrigin)]
    
    1955
    -    theBindings = newBindings b rns
    
    1956
    -
    
    1957
    -    newBindings :: Bool
    
    1958
    -                -> [(ModuleName, ModuleName)]
    
    1959
    -                -> [(ModuleName, UniqMap Module ModuleOrigin)]
    
    1960
    -    newBindings e rns  = es e ++ hiddens ++ map rnBinding rns
    
    1961
    -
    
    1962
    -    rnBinding :: (ModuleName, ModuleName)
    
    1963
    -              -> (ModuleName, UniqMap Module ModuleOrigin)
    
    1964
    -    rnBinding (orig, new) = (new, setOrigins origEntry fromFlag)
    
    1965
    -     where origEntry = case lookupUFM esmap orig of
    
    1966
    -            Just r -> r
    
    1967
    -            Nothing -> throwGhcException (CmdLineError (renderWithContext
    
    1968
    -                        (log_default_user_context (logFlags logger))
    
    1969
    -                        (text "package flag: could not find module name" <+>
    
    1970
    -                            ppr orig <+> text "in package" <+> ppr pk)))
    
    1971
    -
    
    1972
    -    es :: Bool -> [(ModuleName, UniqMap Module ModuleOrigin)]
    
    1973
    -    es e = do
    
    1974
    -     (m, exposedReexport) <- exposed_mods
    
    1975
    -     let (pk', m', origin') =
    
    1976
    -          case exposedReexport of
    
    1977
    -           Nothing -> (pk, m, fromExposedModules e)
    
    1978
    -           Just (Module pk' m') ->
    
    1979
    -              (pk', m', fromReexportedModules e pkg)
    
    1980
    -     return (m, mkModMap pk' m' origin')
    
    1981
    -
    
    1982
    -    esmap :: UniqFM ModuleName (UniqMap Module ModuleOrigin)
    
    1983
    -    esmap = listToUFM (es False) -- parameter here doesn't matter, orig will
    
    1984
    -                                 -- be overwritten
    
    1985
    -
    
    1986
    -    hiddens = [(m, mkModMap pk m ModHidden) | m <- hidden_mods]
    
    1987
    -
    
    1988
    -    pk = mkUnit pkg
    
    1989
    -    unit_lookup uid = lookupUnit' (unitConfigAllowVirtual cfg) pkg_map uid
    
    1990
    -                        `orElse` pprPanic "unit_lookup" (ppr uid)
    
    1991
    -
    
    1992
    -    exposed_mods = unitExposedModules pkg
    
    1993
    -    hidden_mods  = unitHiddenModules pkg
    
    1994
    -
    
    1995
    --- | Make a 'ModuleNameProvidersMap' covering a set of unusable packages.
    
    1996
    -mkUnusableModuleNameProvidersMap :: UnusableUnits -> ModuleNameProvidersMap
    
    1997
    -mkUnusableModuleNameProvidersMap unusables =
    
    1998
    -    nonDetFoldUniqMap extend_modmap emptyUniqMap unusables
    
    1999
    - where
    
    2000
    -    extend_modmap (_uid, (unit_info, reason)) modmap = addListTo modmap bindings
    
    2001
    -      where bindings :: [(ModuleName, UniqMap Module ModuleOrigin)]
    
    2002
    -            bindings = exposed ++ hidden
    
    2003
    -
    
    2004
    -            origin_reexport =  ModUnusable (UnusableUnit unit reason True)
    
    2005
    -            origin_normal   =  ModUnusable (UnusableUnit unit reason False)
    
    2006
    -            unit = mkUnit unit_info
    
    2007
    -
    
    2008
    -            exposed = map get_exposed exposed_mods
    
    2009
    -            hidden = [(m, mkModMap unit m origin_normal) | m <- hidden_mods]
    
    2010
    -
    
    2011
    -            -- with re-exports, c:Foo can be reexported from two (or more)
    
    2012
    -            -- unusable packages:
    
    2013
    -            --  Foo -> a:Foo (unusable reason A) -> c:Foo
    
    2014
    -            --      -> b:Foo (unusable reason B) -> c:Foo
    
    2015
    -            --
    
    2016
    -            -- We must be careful to not record the following (#21097):
    
    2017
    -            --  Foo -> c:Foo (unusable reason A)
    
    2018
    -            --      -> c:Foo (unusable reason B)
    
    2019
    -            -- But:
    
    2020
    -            --  Foo -> a:Foo (unusable reason A)
    
    2021
    -            --      -> b:Foo (unusable reason B)
    
    2022
    -            --
    
    2023
    -            get_exposed (mod, Just _) = (mod, mkModMap unit mod origin_reexport)
    
    2024
    -            get_exposed (mod, _) = (mod, mkModMap unit mod origin_normal)
    
    2025
    -              -- in the reexport case, we create a virtual module that doesn't
    
    2026
    -              -- exist but we don't care as it's only used as a key in the map.
    
    2027
    -
    
    2028
    -            exposed_mods = unitExposedModules unit_info
    
    2029
    -            hidden_mods  = unitHiddenModules  unit_info
    
    2030
    -
    
    2031
    --- | Add a list of key/value pairs to a nested map.
    
    2032
    ---
    
    2033
    --- The outer map is processed with 'Data.Map.Strict' to prevent memory leaks
    
    2034
    --- when reloading modules in GHCi (see #4029). This ensures that each
    
    2035
    --- value is forced before installing into the map.
    
    2036
    -addListTo :: (Monoid a, Ord k1, Ord k2, Uniquable k1, Uniquable k2)
    
    2037
    -          => UniqMap k1 (UniqMap k2 a)
    
    2038
    -          -> [(k1, UniqMap k2 a)]
    
    2039
    -          -> UniqMap k1 (UniqMap k2 a)
    
    2040
    -addListTo = foldl' merge
    
    2041
    -  where merge m (k, v) = addToUniqMap_C (plusUniqMap_C mappend) m k v
    
    2042
    -
    
    2043
    --- | Create a singleton module mapping
    
    2044
    -mkModMap :: Unit -> ModuleName -> ModuleOrigin -> UniqMap Module ModuleOrigin
    
    2045
    -mkModMap pkg mod = unitUniqMap (mkModule pkg mod)
    
    2046
    -
    
    931
    +initUnitDbConfig :: UnitConfig -> UnitDbConfig
    
    932
    +initUnitDbConfig uc = UnitDbConfig
    
    933
    +  { unitDbConfigFlagsDB = unitConfigFlagsDB uc
    
    934
    +  , unitDbConfigProgramName = unitConfigProgramName uc
    
    935
    +  , unitDbConfigDBName = unitConfigDBName uc
    
    936
    +  , unitDbConfigPlatformArchOS = unitConfigPlatformArchOS uc
    
    937
    +  , unitDbConfigGlobalDB = unitConfigGlobalDB uc
    
    938
    +  , unitDbConfigGHCDir = unitConfigGHCDir uc
    
    939
    +  }
    
    2047 940
     
    
    2048 941
     -- -----------------------------------------------------------------------------
    
    2049 942
     -- Package Utils
    
    ... ... @@ -2185,7 +1078,7 @@ lookupModuleWithSuggestions' pkgs mod_map name mb_pn
    2185 1078
         suggestions = fuzzyLookup (moduleNameString name) all_mods
    
    2186 1079
     
    
    2187 1080
         all_mods :: [(String, ModuleSuggestion)]     -- All modules
    
    2188
    -    all_mods = sortBy (comparing fst) $
    
    1081
    +    all_mods = sortOn fst $
    
    2189 1082
             [ (moduleNameString m, suggestion)
    
    2190 1083
             | (m, e) <- nonDetUniqMapToList (moduleNameProvidersMap pkgs)
    
    2191 1084
             , suggestion <- map (getSuggestion m) (nonDetUniqMapToList e)
    
    ... ... @@ -2199,78 +1092,7 @@ listVisibleModuleNames state =
    2199 1092
         map fst (filter visible (nonDetUniqMapToList (moduleNameProvidersMap state)))
    
    2200 1093
       where visible (_, ms) = anyUniqMap originVisible ms
    
    2201 1094
     
    
    2202
    --- | Takes a list of UnitIds (and their "parent" dependency, used for error
    
    2203
    --- messages), and returns the list with dependencies included, in reverse
    
    2204
    --- dependency order (a units appears before those it depends on).
    
    2205
    -closeUnitDeps :: UnitInfoMap -> [(UnitId,Maybe UnitId)] -> MaybeErr UnitErr [UnitId]
    
    2206
    -closeUnitDeps pkg_map ps = closeUnitDeps' pkg_map [] ps
    
    2207 1095
     
    
    2208
    --- | Similar to closeUnitDeps but takes a list of already loaded units as an
    
    2209
    --- additional argument.
    
    2210
    -closeUnitDeps' :: UnitInfoMap -> [UnitId] -> [(UnitId,Maybe UnitId)] -> MaybeErr UnitErr [UnitId]
    
    2211
    -closeUnitDeps' pkg_map current_ids ps = foldM (uncurry . add_unit pkg_map) current_ids ps
    
    2212
    -
    
    2213
    --- | Add a UnitId and those it depends on (recursively) to the given list of
    
    2214
    --- UnitIds if they are not already in it. Return a list in reverse dependency
    
    2215
    --- order (a unit appears before those it depends on).
    
    2216
    ---
    
    2217
    --- The UnitId is looked up in the given UnitInfoMap (to find its dependencies).
    
    2218
    --- It it's not found, the optional parent unit is used to return a more precise
    
    2219
    --- error message ("dependency of <PARENT>").
    
    2220
    -add_unit :: UnitInfoMap
    
    2221
    -            -> [UnitId]
    
    2222
    -            -> UnitId
    
    2223
    -            -> Maybe UnitId
    
    2224
    -            -> MaybeErr UnitErr [UnitId]
    
    2225
    -add_unit pkg_map ps p mb_parent
    
    2226
    -  | p `elem` ps = return ps     -- Check if we've already added this unit
    
    2227
    -  | otherwise   = case lookupUnitId' pkg_map p of
    
    2228
    -      Nothing   -> Failed (CloseUnitErr p mb_parent)
    
    2229
    -      Just info -> do
    
    2230
    -         -- Add the unit's dependents also
    
    2231
    -         ps' <- foldM add_unit_key ps (unitDepends info)
    
    2232
    -         return (p : ps')
    
    2233
    -        where
    
    2234
    -          add_unit_key xs key
    
    2235
    -            = add_unit pkg_map xs key (Just p)
    
    2236
    -
    
    2237
    -data UnitErr
    
    2238
    -  = CloseUnitErr !UnitId !(Maybe UnitId)
    
    2239
    -  | PackageFlagErr !PackageFlag ![(UnitInfo,UnusableUnitReason)]
    
    2240
    -  | TrustFlagErr   !TrustFlag   ![(UnitInfo,UnusableUnitReason)]
    
    2241
    -
    
    2242
    -mayThrowUnitErr :: MaybeErr UnitErr a -> IO a
    
    2243
    -mayThrowUnitErr = \case
    
    2244
    -    Failed e    -> throwGhcExceptionIO
    
    2245
    -                    $ CmdLineError
    
    2246
    -                    $ renderWithContext defaultSDocContext
    
    2247
    -                    $ withPprStyle defaultUserStyle
    
    2248
    -                    $ ppr e
    
    2249
    -    Succeeded a -> return a
    
    2250
    -
    
    2251
    -instance Outputable UnitErr where
    
    2252
    -    ppr = \case
    
    2253
    -        CloseUnitErr p mb_parent
    
    2254
    -            -> (text "unknown unit:" <+> ppr p)
    
    2255
    -               <> case mb_parent of
    
    2256
    -                     Nothing     -> Outputable.empty
    
    2257
    -                     Just parent -> space <> parens (text "dependency of"
    
    2258
    -                                              <+> ftext (unitIdFS parent))
    
    2259
    -        PackageFlagErr flag reasons
    
    2260
    -            -> flag_err (pprFlag flag) reasons
    
    2261
    -
    
    2262
    -        TrustFlagErr flag reasons
    
    2263
    -            -> flag_err (pprTrustFlag flag) reasons
    
    2264
    -      where
    
    2265
    -        flag_err flag_doc reasons =
    
    2266
    -            text "cannot satisfy "
    
    2267
    -            <> flag_doc
    
    2268
    -            <> (if null reasons then Outputable.empty else text ": ")
    
    2269
    -            $$ nest 4 (vcat (map ppr_reason reasons) $$
    
    2270
    -                      text "(use -v for more information)")
    
    2271
    -
    
    2272
    -        ppr_reason (p, reason) =
    
    2273
    -            pprReason (ppr (unitId p) <+> text "is") reason
    
    2274 1096
     
    
    2275 1097
     -- | Return this list of requirement interfaces that need to be merged
    
    2276 1098
     -- to form @mod_name@, or @[]@ if this is not a requirement.
    
    ... ... @@ -2328,37 +1150,23 @@ pprUnitsSimple ue = pprUnitsWith pprIPI ue
    2328 1150
                                t = if isUnitInfoTrusted ue ipi then text "T" else text " "
    
    2329 1151
                            in e <> t <> text "  " <> ftext i
    
    2330 1152
     
    
    2331
    --- | Show the mapping of modules to where they come from.
    
    2332
    -pprModuleMap :: ModuleNameProvidersMap -> SDoc
    
    2333
    -pprModuleMap mod_map =
    
    2334
    -  vcat (map pprLine (nonDetUniqMapToList mod_map))
    
    2335
    -    where
    
    2336
    -      pprLine (m,e) = ppr m $$ nest 50 (vcat (map (pprEntry m) (nonDetUniqMapToList e)))
    
    2337
    -      pprEntry :: Outputable a => ModuleName -> (Module, a) -> SDoc
    
    2338
    -      pprEntry m (m',o)
    
    2339
    -        | m == moduleName m' = ppr (moduleUnit m') <+> parens (ppr o)
    
    2340
    -        | otherwise = ppr m' <+> parens (ppr o)
    
    1153
    +-- | Print unit-ids with UnitInfo found in the given UnitState
    
    1154
    +pprWithUnitState :: UnitState -> SDoc -> SDoc
    
    1155
    +pprWithUnitState state = updSDocContext (\ctx -> ctx
    
    1156
    +   { sdocUnitIdForUser = \fs -> pprUnitIdForUser state (UnitId fs)
    
    1157
    +   })
    
    1158
    +
    
    1159
    +-- | Print raw unit-ids, without removing the hash
    
    1160
    +pprRawUnitIds :: SDoc -> SDoc
    
    1161
    +pprRawUnitIds = updSDocContext (\ctx -> ctx { sdocUnitIdForUser = ftext })
    
    2341 1162
     
    
    2342 1163
     fsPackageName :: UnitInfo -> FastString
    
    2343 1164
     fsPackageName info = fs
    
    2344 1165
        where
    
    2345 1166
           PackageName fs = unitPackageName info
    
    2346 1167
     
    
    2347
    --- | Return a `UnitId` which either wraps the `InstantiatedUnit` unchanged.
    
    2348
    -instUnitToUnit :: InstantiatedUnit -> Unit
    
    2349
    -instUnitToUnit iuid =
    
    2350
    -    -- NB: suppose that we want to compare the instantiated
    
    2351
    -    -- unit p[H=impl:H] against p+abcd (where p+abcd
    
    2352
    -    -- happens to be the existing, installed version of
    
    2353
    -    -- p[H=impl:H].  If we *only* wrap in p[H=impl:H]
    
    2354
    -    -- VirtUnit, they won't compare equal; only
    
    2355
    -    -- after improvement will the equality hold.
    
    2356
    -    VirtUnit iuid
    
    2357
    -
    
    2358
    -
    
    2359
    --- | Substitution on module variables, mapping module names to module
    
    2360
    --- identifiers.
    
    2361
    -type ShHoleSubst = ModuleNameEnv Module
    
    1168
    +-- -----------------------------------------------------------------------------
    
    1169
    +-- Module renaming
    
    2362 1170
     
    
    2363 1171
     -- | Substitutes holes in a 'Module'.  NOT suitable for being called
    
    2364 1172
     -- directly on a 'nameModule', see Note [Representation of module/name variables].
    
    ... ... @@ -2374,44 +1182,19 @@ renameHoleModule state = renameHoleModule' (unitInfoMap state)
    2374 1182
     renameHoleUnit :: UnitState -> ShHoleSubst -> Unit -> Unit
    
    2375 1183
     renameHoleUnit state = renameHoleUnit' (unitInfoMap state)
    
    2376 1184
     
    
    2377
    --- | Like 'renameHoleModule', but requires only 'UnitInfoMap'
    
    2378
    --- so it can be used by "GHC.Unit.State".
    
    2379
    -renameHoleModule' :: UnitInfoMap -> ShHoleSubst -> Module -> Module
    
    2380
    -renameHoleModule' pkg_map env m
    
    2381
    -  | not (isHoleModule m) =
    
    2382
    -        let uid = renameHoleUnit' pkg_map env (moduleUnit m)
    
    2383
    -        in mkModule uid (moduleName m)
    
    2384
    -  | Just m' <- lookupUFM env (moduleName m) = m'
    
    2385
    -  -- NB m = <Blah>, that's what's in scope.
    
    2386
    -  | otherwise = m
    
    2387
    -
    
    2388
    --- | Like 'renameHoleUnit', but requires only 'UnitInfoMap'
    
    2389
    --- so it can be used by "GHC.Unit.State".
    
    2390
    -renameHoleUnit' :: UnitInfoMap -> ShHoleSubst -> Unit -> Unit
    
    2391
    -renameHoleUnit' pkg_map env uid =
    
    2392
    -    case uid of
    
    2393
    -      (VirtUnit
    
    2394
    -        InstantiatedUnit{ instUnitInstanceOf = cid
    
    2395
    -                        , instUnitInsts      = insts
    
    2396
    -                        , instUnitHoles      = fh })
    
    2397
    -          -> if isNullUFM (intersectUFM_C const (udfmToUfm (getUniqDSet fh)) env)
    
    2398
    -                then uid
    
    2399
    -                else mkVirtUnit cid
    
    2400
    -                          (map (\(k,v) -> (k, renameHoleModule' pkg_map env v)) insts)
    
    2401
    -      _ -> uid
    
    2402
    -
    
    2403 1185
     -- | Injects an 'InstantiatedModule' to 'Module' (see also
    
    2404 1186
     -- 'instUnitToUnit'.
    
    2405 1187
     instModuleToModule :: InstantiatedModule -> Module
    
    2406 1188
     instModuleToModule (Module iuid mod_name) =
    
    2407 1189
         mkModule (instUnitToUnit iuid) mod_name
    
    2408 1190
     
    
    2409
    --- | Print unit-ids with UnitInfo found in the given UnitState
    
    2410
    -pprWithUnitState :: UnitState -> SDoc -> SDoc
    
    2411
    -pprWithUnitState state = updSDocContext (\ctx -> ctx
    
    2412
    -   { sdocUnitIdForUser = \fs -> pprUnitIdForUser state (UnitId fs)
    
    2413
    -   })
    
    2414
    -
    
    2415
    --- | Print raw unit-ids, without removing the hash
    
    2416
    -pprRawUnitIds :: SDoc -> SDoc
    
    2417
    -pprRawUnitIds = updSDocContext (\ctx -> ctx { sdocUnitIdForUser = ftext })
    1191
    +-- | Return a `UnitId` which either wraps the `InstantiatedUnit` unchanged.
    
    1192
    +instUnitToUnit :: InstantiatedUnit -> Unit
    
    1193
    +instUnitToUnit iuid =
    
    1194
    +    -- NB: suppose that we want to compare the instantiated
    
    1195
    +    -- unit p[H=impl:H] against p+abcd (where p+abcd
    
    1196
    +    -- happens to be the existing, installed version of
    
    1197
    +    -- p[H=impl:H].  If we *only* wrap in p[H=impl:H]
    
    1198
    +    -- VirtUnit, they won't compare equal; only
    
    1199
    +    -- after improvement will the equality hold.
    
    1200
    +    VirtUnit iuid

  • compiler/GHC/Unit/State.hs-boot
    1 1
     module GHC.Unit.State where
    
    2 2
     
    
    3 3
     data UnitState
    4
    -data ModuleSuggestion
    
    5
    -data ModuleOrigin
    
    6
    -data UnusableUnit

  • compiler/GHC/Unit/Types.hs
    ... ... @@ -578,7 +578,7 @@ had used @-ignore-package@).
    578 578
     The affected packages are compiled with, e.g., @-this-unit-id base@, so that
    
    579 579
     the symbols in the object files have the unversioned unit id in their name.
    
    580 580
     
    
    581
    -Make sure you change 'GHC.Unit.State.findWiredInUnits' if you add an entry here.
    
    581
    +Make sure you change 'wiredInUnitIds' if you add an entry here.
    
    582 582
     
    
    583 583
     -}
    
    584 584
     
    
    ... ... @@ -655,7 +655,7 @@ be it either hadrian or cabal, knows exactly the unit-id it passed with -this-un
    655 655
     
    
    656 656
     Note that we also ensure the ghc's unit key matches its unit id, both when
    
    657 657
     hadrian or cabal is building ghc. This way, we no longer need to add `ghc` to
    
    658
    -the WiringMap, and that's why 'wiredInUnitIds' no longer includes
    
    658
    +the WireMap, and that's why 'wiredInUnitIds' no longer includes
    
    659 659
     'thisGhcUnitId'.
    
    660 660
     -}
    
    661 661
     
    

  • compiler/ghc.cabal.in
    ... ... @@ -968,6 +968,14 @@ Library
    968 968
             GHC.Unit.Env
    
    969 969
             GHC.Unit.External
    
    970 970
             GHC.Unit.External.Database
    
    971
    +        GHC.Unit.External.Index
    
    972
    +        GHC.Unit.External.ModuleOrigin
    
    973
    +        GHC.Unit.External.Providers
    
    974
    +        GHC.Unit.External.Query
    
    975
    +        GHC.Unit.External.Substitution
    
    976
    +        GHC.Unit.External.Validate
    
    977
    +        GHC.Unit.External.Visibility
    
    978
    +        GHC.Unit.External.Wired
    
    971 979
             GHC.Unit.Finder
    
    972 980
             GHC.Unit.Finder.Types
    
    973 981
             GHC.Unit.Home
    

  • ghc/GHCi/UI.hs
    ... ... @@ -855,7 +855,7 @@ installInteractiveHomeUnits dflags = do
    855 855
         setupHomeUnitFor :: GHC.GhcMonad m => Logger -> DynFlags -> S.Set UnitId -> m HomeUnitEnv
    
    856 856
         setupHomeUnitFor logger dflags all_home_units = do
    
    857 857
           env <- GHC.getSession
    
    858
    -      let unit_index = hsc_unit_index env
    
    858
    +      let unit_index = hscUIC env
    
    859 859
           (unit_state,home_unit,_mconstants) <-
    
    860 860
             liftIO $ initUnits logger dflags unit_index (hscEUDC env) all_home_units
    
    861 861
           hpt <- liftIO emptyHomePackageTable
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -547,7 +547,7 @@ generateConfigHs = do
    547 547
         -- See Note [GHC's Unit Id] in GHC.Unit.Types
    
    548 548
         --
    
    549 549
         -- It's crucial that the unit-id matches the unit-key -- ghc is no longer
    
    550
    -    -- part of the WiringMap, so we don't to go back and forth between the
    
    550
    +    -- part of the WireMap, so we don't to go back and forth between the
    
    551 551
         -- unit-id and the unit-key -- we take care that they are the same by using
    
    552 552
         -- 'pkgUnitId' on 'compiler' (the ghc-library package) to create the
    
    553 553
         -- unit-id in both situations.
    

  • testsuite/tests/count-deps/CountDepsParser.stdout
    ... ... @@ -227,6 +227,15 @@ GHC.Types.Var.Env
    227 227
     GHC.Types.Var.FV
    
    228 228
     GHC.Types.Var.Set
    
    229 229
     GHC.Unit
    
    230
    +GHC.Unit.External.Database
    
    231
    +GHC.Unit.External.Index
    
    232
    +GHC.Unit.External.ModuleOrigin
    
    233
    +GHC.Unit.External.Providers
    
    234
    +GHC.Unit.External.Query
    
    235
    +GHC.Unit.External.Substitution
    
    236
    +GHC.Unit.External.Validate
    
    237
    +GHC.Unit.External.Visibility
    
    238
    +GHC.Unit.External.Wired
    
    230 239
     GHC.Unit.Home
    
    231 240
     GHC.Unit.Info
    
    232 241
     GHC.Unit.Module
    

  • utils/haddock/haddock-api/src/Haddock.hs
    ... ... @@ -69,6 +69,7 @@ import GHC.Utils.Error
    69 69
     import GHC.Utils.Logger
    
    70 70
     import GHC.Types.Name.Cache
    
    71 71
     import GHC.Unit
    
    72
    +import GHC.Unit.External.Index
    
    72 73
     import GHC.Utils.Panic (handleGhcException)
    
    73 74
     import GHC.Data.FastString
    
    74 75