Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

18 changed files:

Changes:

  • .gitlab-ci.yml
    ... ... @@ -194,8 +194,9 @@ workflow:
    194 194
     # https://gitlab.com/gitlab-org/gitlab/-/issues/32837). This leads to the
    
    195 195
     # hack in this MR where by default all jobs are `interruptible: True`, but
    
    196 196
     # for pipelines we definitely want to run, there is a dummy job which
    
    197
    -# happens first, which is `interreuptible: False`. This has the effect of
    
    198
    -# dirtying the whole pipeline and
    
    197
    +# happens first, which is `interruptible: False`. This has the effect of
    
    198
    +# dirtying the whole pipeline and preventing another push to master from
    
    199
    +# cancelling it.
    
    199 200
     #
    
    200 201
     # For now, this patch solves the immediate problem of making sure nightly
    
    201 202
     # jobs are not cancelled.
    

  • changelog.d/fix-plugin-finder-multi-home-unit.md
    1
    +section: compiler
    
    2
    +synopsis: Find plugins defined in sibling home units in multiple-home-unit sessions
    
    3
    +issues: #27349
    
    4
    +mrs: !16156
    
    5
    +description: {
    
    6
    +  In a multiple-home-unit session (e.g. ``cabal repl --enable-multi-repl`` or HLS), the plugin finder now also searches the home units that the current home unit depends on, following module reexports along the way, so a ``-fplugin`` defined in (or reexported by) a sibling home unit is found and loaded instead of failing as a hidden package.
    
    7
    +}

  • compiler/.hlint.yaml
    ... ... @@ -3,6 +3,8 @@
    3 3
     ##########################
    
    4 4
     
    
    5 5
     - ignore: {}
    
    6
    +- ignore: {name: Use camelCase}
    
    7
    +- ignore: {name: Eta reduce}
    
    6 8
     - warn: {name: Unused LANGUAGE pragma}
    
    7 9
     - warn: {name: Use fewer LANGUAGE pragmas}
    
    8 10
     - warn: {name: Redundant return}
    

  • compiler/GHC/Unit/Finder.hs
    ... ... @@ -231,36 +231,14 @@ findImportedModuleNoHsc fc fopts ue home_module_name_providers_map mb_home_unit
    231 231
                               NoPackage (panic "findImportedModule: no home-unit")
    
    232 232
     
    
    233 233
         home_pkg_import :: (UnitId, FinderOpts) -> IO FindResult
    
    234
    -    home_pkg_import (uid, opts)
    
    235
    -        -- If the module is reexported, then look for it as if it was from the
    
    236
    -        -- perspective of that package which reexports it.
    
    237
    -        | Just real_mod_name
    
    238
    -              <- lookupUniqMap (finder_reexportedModules opts) mod_name
    
    239
    -            = findImportedModuleNoHsc fc opts ue home_module_name_providers_map
    
    240
    -                  (Just $ DefiniteHomeUnit uid Nothing)
    
    241
    -                  real_mod_name
    
    242
    -                  NoPkgQual
    
    243
    -        | elementOfUniqSet mod_name (finder_hiddenModules opts)
    
    244
    -            = return (mkHomeHidden uid)
    
    245
    -        | otherwise
    
    246
    -            = findHomePackageModule fc opts uid mod_name
    
    247
    -
    
    248
    -    any_home_import :: IO FindResult
    
    249
    -    any_home_import = foldr1 orIfNotFound $
    
    250
    -                      home_import :| map home_pkg_import other_fopts
    
    251
    -    -- Do not try to be smart and change this to `foldr orIfNotFound home_import
    
    252
    -    -- (map home_pkg_import other_fopts)`, as that would not be the same.
    
    253
    -    -- `home_import` is first because we need to first look within the current
    
    254
    -    -- unit before looking at the other units in order.
    
    234
    +    home_pkg_import = findHomeUnitDepModule fc ue home_module_name_providers_map mod_name
    
    255 235
     
    
    256 236
         pkg_import :: IO FindResult
    
    257 237
         pkg_import = findExposedPackageModule fc fopts unit_state mod_name mb_pkg
    
    258 238
     
    
    259 239
         unqual_import :: IO FindResult
    
    260
    -    unqual_import
    
    261
    -        = any_home_import
    
    262
    -          `orIfNotFound`
    
    263
    -          findExposedPackageModule fc fopts unit_state mod_name NoPkgQual
    
    240
    +    unqual_import = findHomeOrRegularPackageModule fc fopts ue
    
    241
    +                        home_module_name_providers_map mb_home_unit mod_name
    
    264 242
     
    
    265 243
         unit_state :: UnitState
    
    266 244
         unit_state = case mb_home_unit_id of
    
    ... ... @@ -268,22 +246,44 @@ findImportedModuleNoHsc fc fopts ue home_module_name_providers_map mb_home_unit
    268 246
             Just home_unit_id -> HUG.homeUnitEnv_units $
    
    269 247
                                  ue_findHomeUnitEnv home_unit_id ue
    
    270 248
     
    
    271
    -    home_unit_deps :: Set UnitId
    
    272
    -    home_unit_deps = homeUnitDepends unit_state
    
    249
    +    other_fopts :: [(UnitId, FinderOpts)]
    
    250
    +    other_fopts = homeUnitDepsFinderOpts ue home_module_name_providers_map
    
    251
    +                                         unit_state mod_name
    
    252
    +
    
    253
    +-- | Locate a plugin module requested by the user, for a compiler
    
    254
    +-- plugin.  This consults the same set of exposed packages as
    
    255
    +-- 'findImportedModule', unless @-hide-all-plugin-packages@ or
    
    256
    +-- @-plugin-package@ are specified.
    
    257
    +findPluginModuleNoHsc
    
    258
    +  :: FinderCache
    
    259
    +  -> FinderOpts
    
    260
    +  -> UnitEnv
    
    261
    +  -> HomeModuleNameProvidersMap
    
    262
    +  -> Maybe HomeUnit
    
    263
    +  -> ModuleName
    
    264
    +  -> IO FindResult
    
    265
    +findPluginModuleNoHsc fc fopts ue home_module_name_providers_map mb_home_unit@(Just home_unit) mod_name =
    
    266
    +    findHomeModuleAmongDeps fc fopts ue home_module_name_providers_map
    
    267
    +                            mb_home_unit mod_name
    
    268
    +    `orIfNotFound`
    
    269
    +    findExposedPluginPackageModule fc fopts unit_state mod_name
    
    270
    +  where
    
    271
    +    unit_state = HUG.homeUnitEnv_units $
    
    272
    +                 ue_findHomeUnitEnv (homeUnitId home_unit) ue
    
    273
    +findPluginModuleNoHsc fc fopts ue _ Nothing mod_name =
    
    274
    +  findExposedPluginPackageModule fc fopts (ue_homeUnitState ue) mod_name
    
    273 275
     
    
    274
    -    ranked_home_unit_deps :: [UnitId]
    
    275
    -    ranked_home_unit_deps = rankedHomeUnitDeps home_module_name_providers_map
    
    276
    -                                               mod_name
    
    277
    -                                               home_unit_deps
    
    276
    +findPluginModule :: HscEnv -> ModuleName -> IO FindResult
    
    277
    +findPluginModule hsc_env mod_name = do
    
    278
    +  let fc           = hsc_FC hsc_env
    
    279
    +      mb_home_unit = hsc_home_unit_maybe hsc_env
    
    280
    +      home_module_name_providers_map =
    
    281
    +        mgHomeModuleNameProvidersMap (hsc_mod_graph hsc_env)
    
    282
    +  findPluginModuleNoHsc fc (initFinderOpts (hsc_dflags hsc_env))
    
    283
    +    (hsc_unit_env hsc_env) home_module_name_providers_map mb_home_unit mod_name
    
    278 284
     
    
    279
    -    other_fopts :: [(UnitId, FinderOpts)]
    
    280
    -    other_fopts
    
    281
    -        = [
    
    282
    -              (uid, opts) |
    
    283
    -                  uid <- ranked_home_unit_deps,
    
    284
    -                  let opts = initFinderOpts $
    
    285
    -                             homeUnitEnv_dflags (ue_findHomeUnitEnv uid ue)
    
    286
    -          ]
    
    285
    +-- -----------------------------------------------------------------------------
    
    286
    +-- Home Module Finder Helpers
    
    287 287
     
    
    288 288
     -- | Yields the unit IDs from the given set as a list with those that refer to
    
    289 289
     -- providers of the given home module name coming first. This is to prioritize
    
    ... ... @@ -323,24 +323,93 @@ rankedHomeUnitDeps home_module_name_providers_map mod_name home_unit_deps
    323 323
         uncached_deps :: Set UnitId
    
    324 324
         uncached_deps = Set.difference home_unit_deps cached_providers
    
    325 325
     
    
    326
    --- | Locate a plugin module requested by the user, for a compiler
    
    327
    --- plugin.  This consults the same set of exposed packages as
    
    328
    --- 'findImportedModule', unless @-hide-all-plugin-packages@ or
    
    329
    --- @-plugin-package@ are specified.
    
    330
    -findPluginModuleNoHsc :: FinderCache -> FinderOpts -> UnitState -> Maybe HomeUnit -> ModuleName -> IO FindResult
    
    331
    -findPluginModuleNoHsc fc fopts units (Just home_unit) mod_name =
    
    332
    -  findHomeModule fc fopts home_unit mod_name
    
    333
    -  `orIfNotFound`
    
    334
    -  findExposedPluginPackageModule fc fopts units mod_name
    
    335
    -findPluginModuleNoHsc fc fopts units Nothing mod_name =
    
    336
    -  findExposedPluginPackageModule fc fopts units mod_name
    
    326
    +-- | The 'FinderOpts' of the home units that should be searched, sorted by
    
    327
    +-- priority order specified by 'rankedHomeUnitDeps'.
    
    328
    +homeUnitDepsFinderOpts
    
    329
    +  :: UnitEnv
    
    330
    +  -> HomeModuleNameProvidersMap
    
    331
    +  -> UnitState  -- ^ unit state of the requesting home unit
    
    332
    +  -> ModuleName
    
    333
    +  -> [(UnitId, FinderOpts)]
    
    334
    +homeUnitDepsFinderOpts ue home_module_name_providers_map unit_state mod_name =
    
    335
    +    [ (uid, initFinderOpts (ue_unitFlags uid ue))
    
    336
    +    | uid <- rankedHomeUnitDeps home_module_name_providers_map mod_name
    
    337
    +                                (homeUnitDepends unit_state)
    
    338
    +    ]
    
    339
    +
    
    340
    +-- | Search for @mod_name@ in the given home unit.
    
    341
    +findHomeUnitDepModule
    
    342
    +  :: FinderCache
    
    343
    +  -> UnitEnv
    
    344
    +  -> HomeModuleNameProvidersMap
    
    345
    +  -> ModuleName
    
    346
    +  -> (UnitId, FinderOpts)
    
    347
    +  -> IO FindResult
    
    348
    +findHomeUnitDepModule fc ue home_module_name_providers_map mod_name (uid, opts)
    
    349
    +    -- If the module is reexported, then look for it as if it was from the
    
    350
    +    -- perspective of the package which reexports it.
    
    351
    +    | Just real_mod_name
    
    352
    +          <- lookupUniqMap (finder_reexportedModules opts) mod_name
    
    353
    +        = findHomeOrRegularPackageModule fc opts ue home_module_name_providers_map
    
    354
    +              (Just $ DefiniteHomeUnit uid Nothing)
    
    355
    +              real_mod_name
    
    356
    +    | elementOfUniqSet mod_name (finder_hiddenModules opts)
    
    357
    +        = return (mkHomeHidden uid)
    
    358
    +    | otherwise
    
    359
    +        = findHomePackageModule fc opts uid mod_name
    
    360
    +
    
    361
    +-- | Search for @mod_name@ among the home units: first the current home unit,
    
    362
    +-- then the home units it depends on, in priority order, following module
    
    363
    +-- reexports along the way (see 'findHomeUnitDepModule'). Yields the first
    
    364
    +-- successful result.
    
    365
    +findHomeModuleAmongDeps
    
    366
    +  :: FinderCache
    
    367
    +  -> FinderOpts
    
    368
    +  -> UnitEnv
    
    369
    +  -> HomeModuleNameProvidersMap
    
    370
    +  -> Maybe HomeUnit
    
    371
    +  -> ModuleName
    
    372
    +  -> IO FindResult
    
    373
    +findHomeModuleAmongDeps fc fopts ue home_module_name_providers_map mb_home_unit mod_name =
    
    374
    +    foldr1 orIfNotFound (home_import :| map home_pkg_import other_fopts)
    
    375
    +    -- Do not try to be smart and change this to `foldr orIfNotFound home_import
    
    376
    +    -- (map home_pkg_import other_fopts)`, as that would not be the same.
    
    377
    +    -- `home_import` is first because we need to first look within the current
    
    378
    +    -- unit before looking at the other units in order.
    
    379
    +  where
    
    380
    +    home_import = case mb_home_unit of
    
    381
    +        Just home_unit -> findHomeModule fc fopts home_unit mod_name
    
    382
    +        Nothing        -> pure $
    
    383
    +                          NoPackage (panic "findHomeModuleAmongDeps: no home-unit")
    
    384
    +    home_pkg_import = findHomeUnitDepModule fc ue home_module_name_providers_map mod_name
    
    337 385
     
    
    338
    -findPluginModule :: HscEnv -> ModuleName -> IO FindResult
    
    339
    -findPluginModule hsc_env mod_name = do
    
    340
    -  let fc = hsc_FC hsc_env
    
    341
    -  let units = hsc_units hsc_env
    
    342
    -  let mb_home_unit = hsc_home_unit_maybe hsc_env
    
    343
    -  findPluginModuleNoHsc fc (initFinderOpts (hsc_dflags hsc_env)) units mb_home_unit mod_name
    
    386
    +    unit_state = case homeUnitId <$> mb_home_unit of
    
    387
    +        Nothing           -> ue_homeUnitState ue
    
    388
    +        Just home_unit_id -> HUG.homeUnitEnv_units $
    
    389
    +                             ue_findHomeUnitEnv home_unit_id ue
    
    390
    +    other_fopts = homeUnitDepsFinderOpts ue home_module_name_providers_map
    
    391
    +                                         unit_state mod_name
    
    392
    +
    
    393
    +-- | Search the home-unit graph and otherwise the regular exposed package
    
    394
    +-- database.
    
    395
    +findHomeOrRegularPackageModule
    
    396
    +  :: FinderCache
    
    397
    +  -> FinderOpts
    
    398
    +  -> UnitEnv
    
    399
    +  -> HomeModuleNameProvidersMap
    
    400
    +  -> Maybe HomeUnit
    
    401
    +  -> ModuleName
    
    402
    +  -> IO FindResult
    
    403
    +findHomeOrRegularPackageModule fc fopts ue home_module_name_providers_map mb_home_unit mod_name =
    
    404
    +    findHomeModuleAmongDeps fc fopts ue home_module_name_providers_map
    
    405
    +                            mb_home_unit mod_name
    
    406
    +    `orIfNotFound`
    
    407
    +    findExposedPackageModule fc fopts unit_state mod_name NoPkgQual
    
    408
    +  where
    
    409
    +    unit_state = case homeUnitId <$> mb_home_unit of
    
    410
    +        Nothing           -> ue_homeUnitState ue
    
    411
    +        Just home_unit_id -> HUG.homeUnitEnv_units $
    
    412
    +                             ue_findHomeUnitEnv home_unit_id ue
    
    344 413
     
    
    345 414
     
    
    346 415
     -- | A version of findExactModule which takes the exact parts of the HscEnv it needs
    

  • compiler/Language/Haskell/Syntax/Extension.hs
    ... ... @@ -108,7 +108,7 @@ dataConCantHappen x = case x of {}
    108 108
     -- See Note [XRec and SrcSpans in the AST]
    
    109 109
     type family XRec p a = r | r -> a
    
    110 110
     
    
    111
    -type family Anno a = b -- See Note [XRec and Anno in the AST] in GHC.Parser.Annotation
    
    111
    +type family Anno a -- See Note [XRec and Anno in the AST] in GHC.Parser.Annotation
    
    112 112
     
    
    113 113
     {-
    
    114 114
     Note [XRec and SrcSpans in the AST]
    

  • hadrian/src/Rules/Rts.hs
    ... ... @@ -25,7 +25,7 @@ buildGhcInternalImportDef target = do
    25 25
     
    
    26 26
     buildGhcInternalImportLib :: FilePath -> Action ()
    
    27 27
     buildGhcInternalImportLib target = do
    
    28
    -    let input = dropExtensions target <.> "def" -- the .def file
    
    28
    +    let input = dropExtension (dropExtension target) <.> "def" -- the .def file
    
    29 29
             output = target -- the .dll.a import lib
    
    30 30
         need [input]
    
    31 31
         runBuilder Dlltool ["-d", input, "-l", output] [input] [output]

  • testsuite/tests/driver/multipleHomeUnits/plugin01/all.T
    1
    +# A plugin (MyPlugin, in home unit plugin-0) is enabled by a module (App, in
    
    2
    +# home unit app-0) belonging to a *different* home unit in the same session.
    
    3
    +# Resolving -fplugin must search sibling home units; previously the plugin
    
    4
    +# finder only looked at the current home unit and registered external packages,
    
    5
    +# so this failed with "Could not load module 'MyPlugin' ... hidden package".
    
    6
    +#
    
    7
    +# -fbyte-code-and-object-code -fprefer-byte-code makes the plugin load as
    
    8
    +# byte-code from its (interpreted) home unit, mirroring how a multiple-home-unit
    
    9
    +# session is driven by 'cabal repl --enable-multi-repl' and HLS.
    
    10
    +test('multipleHomeUnits_plugin01',
    
    11
    +     [req_plugins, extra_files(['p/', 'q/', 'pluginunit', 'appunit'])],
    
    12
    +     multiunit_compile,
    
    13
    +     [['pluginunit', 'appunit'],
    
    14
    +      '-v0 -fbyte-code-and-object-code -fprefer-byte-code'])

  • testsuite/tests/driver/multipleHomeUnits/plugin01/appunit
    1
    +-working-dir q App -this-unit-id app-0 -this-package-name app -package-id plugin-0

  • testsuite/tests/driver/multipleHomeUnits/plugin01/p/MyPlugin.hs
    1
    +module MyPlugin (plugin) where
    
    2
    +
    
    3
    +import GHC.Plugins
    
    4
    +
    
    5
    +-- A no-op plugin: it makes no changes to the program but, to run at all, it
    
    6
    +-- must be found and loaded by the consumer module's compilation.
    
    7
    +plugin :: Plugin
    
    8
    +plugin = defaultPlugin { pluginRecompile = purePlugin }

  • testsuite/tests/driver/multipleHomeUnits/plugin01/pluginunit
    1
    +-working-dir p MyPlugin -this-unit-id plugin-0 -this-package-name plugin -package ghc

  • testsuite/tests/driver/multipleHomeUnits/plugin01/q/App.hs
    1
    +{-# OPTIONS_GHC -fplugin=MyPlugin #-}
    
    2
    +module App where
    
    3
    +
    
    4
    +-- The plugin 'MyPlugin' lives in a *sibling* home unit (plugin-0), not in a
    
    5
    +-- registered package. Resolving -fplugin must therefore search sibling home
    
    6
    +-- units, just like an ordinary import does.
    
    7
    +app :: ()
    
    8
    +app = ()

  • testsuite/tests/driver/multipleHomeUnits/plugin02/all.T
    1
    +# A plugin (MyPlugin) lives in home unit plugin-0 and is *reexported* by a
    
    2
    +# second home unit, reexport-0 (via -reexported-module). The consumer module
    
    3
    +# App, in home unit app-0, enables it with -fplugin=MyPlugin but depends only on
    
    4
    +# reexport-0, not on plugin-0 directly. Resolving -fplugin must therefore follow
    
    5
    +# the reexport through the sibling home unit, exactly as an ordinary import
    
    6
    +# does. A home-unit search that ignores reexported-modules fails with
    
    7
    +# "Could not load module 'MyPlugin' ... hidden package".
    
    8
    +#
    
    9
    +# -fbyte-code-and-object-code -fprefer-byte-code makes the plugin load as
    
    10
    +# byte-code from its (interpreted) home unit, mirroring how a multiple-home-unit
    
    11
    +# session is driven by 'cabal repl --enable-multi-repl' and HLS.
    
    12
    +test('multipleHomeUnits_plugin02',
    
    13
    +     [req_plugins, extra_files(['p/', 'q/', 'r/', 'pluginunit', 'reexportunit', 'appunit'])],
    
    14
    +     multiunit_compile,
    
    15
    +     [['pluginunit', 'reexportunit', 'appunit'],
    
    16
    +      '-v0 -fbyte-code-and-object-code -fprefer-byte-code'])

  • testsuite/tests/driver/multipleHomeUnits/plugin02/appunit
    1
    +-working-dir q App -this-unit-id app-0 -this-package-name app -package-id reexport-0

  • testsuite/tests/driver/multipleHomeUnits/plugin02/p/MyPlugin.hs
    1
    +module MyPlugin (plugin) where
    
    2
    +
    
    3
    +import GHC.Plugins
    
    4
    +
    
    5
    +-- A no-op plugin: it makes no changes to the program but, to run at all, it
    
    6
    +-- must be found and loaded by the consumer module's compilation.
    
    7
    +plugin :: Plugin
    
    8
    +plugin = defaultPlugin { pluginRecompile = purePlugin }

  • testsuite/tests/driver/multipleHomeUnits/plugin02/pluginunit
    1
    +-working-dir p MyPlugin -this-unit-id plugin-0 -this-package-name plugin -package ghc

  • testsuite/tests/driver/multipleHomeUnits/plugin02/q/App.hs
    1
    +{-# OPTIONS_GHC -fplugin=MyPlugin #-}
    
    2
    +module App where
    
    3
    +
    
    4
    +-- The plugin 'MyPlugin' lives in home unit plugin-0, but this unit (app-0)
    
    5
    +-- depends only on reexport-0, which *reexports* MyPlugin (it does not contain
    
    6
    +-- MyPlugin itself). Resolving -fplugin must therefore follow the reexport into
    
    7
    +-- the sibling home unit, exactly as an ordinary import does.
    
    8
    +app :: ()
    
    9
    +app = ()

  • testsuite/tests/driver/multipleHomeUnits/plugin02/r/RexLib.hs
    1
    +module RexLib where
    
    2
    +
    
    3
    +-- Home unit reexport-0 re-exports MyPlugin (from plugin-0) via the
    
    4
    +-- -reexported-module flag; see the 'reexportunit' arguments. This module exists
    
    5
    +-- only to make reexport-0 a non-empty home unit, mirroring a real library
    
    6
    +-- package that reexports a module from one of its dependencies.
    
    7
    +rexLib :: ()
    
    8
    +rexLib = ()

  • testsuite/tests/driver/multipleHomeUnits/plugin02/reexportunit
    1
    +-working-dir r RexLib -this-unit-id reexport-0 -this-package-name reexport -package-id plugin-0 -reexported-module MyPlugin