summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2021-07-05 14:16:35 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-07-21 02:45:39 -0400
commit9eb1641e0ef10a7887e794d4d114c9a18a2fd265 (patch)
tree2974508390083775e3bf2c4efcc2113a4c07a2c3
parentd706fd0432925caf62673a55237a005e22bc4450 (diff)
downloadhaskell-9eb1641e0ef10a7887e794d4d114c9a18a2fd265.tar.gz
driver: Fix recompilation for modules importing GHC.Prim
The GHC.Prim module is quite special as there is no interface file, therefore it doesn't appear in ms_textual_imports, but the ghc-prim package does appear in the direct package dependencies. This confused the recompilation checking which couldn't find any modules from ghc-prim and concluded that the package was no longer a dependency. The fix is to keep track of whether GHC.Prim is imported separately in the relevant places. Fixes #20084
-rw-r--r--compiler/GHC/Driver/Backpack.hs7
-rw-r--r--compiler/GHC/Driver/Make.hs4
-rw-r--r--compiler/GHC/Driver/Pipeline/Execute.hs7
-rw-r--r--compiler/GHC/Iface/Recomp.hs12
-rw-r--r--compiler/GHC/Parser/Header.hs15
-rw-r--r--compiler/GHC/Unit/Module/ModSummary.hs3
-rw-r--r--testsuite/tests/driver/Makefile7
-rw-r--r--testsuite/tests/driver/T20084.hs3
-rw-r--r--testsuite/tests/driver/T20084.stdout1
-rw-r--r--testsuite/tests/driver/all.T1
10 files changed, 45 insertions, 15 deletions
diff --git a/compiler/GHC/Driver/Backpack.hs b/compiler/GHC/Driver/Backpack.hs
index 2190bdd753..8581865dbf 100644
--- a/compiler/GHC/Driver/Backpack.hs
+++ b/compiler/GHC/Driver/Backpack.hs
@@ -769,6 +769,7 @@ summariseRequirement pn mod_name = do
ms_hie_date = hie_timestamp,
ms_srcimps = [],
ms_textual_imps = extra_sig_imports,
+ ms_ghc_prim_import = False,
ms_parsed_mod = Just (HsParsedModule {
hpm_module = L loc (HsModule {
hsmodAnn = noAnn,
@@ -854,8 +855,9 @@ hsModuleToModSummary pn hsc_src modname
let (src_idecls, ord_idecls) = partition ((== IsBoot) . ideclSource . unLoc) imps
-- GHC.Prim doesn't exist physically, so don't go looking for it.
- ordinary_imps = filter ((/= moduleName gHC_PRIM) . unLoc . ideclName . unLoc)
- ord_idecls
+ (ordinary_imps, ghc_prim_import)
+ = partition ((/= moduleName gHC_PRIM) . unLoc . ideclName . unLoc)
+ ord_idecls
implicit_prelude = xopt LangExt.ImplicitPrelude dflags
implicit_imports = mkPrelImports modname loc
@@ -884,6 +886,7 @@ hsModuleToModSummary pn hsc_src modname
ms_hspp_opts = dflags,
ms_hspp_buf = Nothing,
ms_srcimps = map convImport src_idecls,
+ ms_ghc_prim_import = not (null ghc_prim_import),
ms_textual_imps = normal_imports
-- We have to do something special here:
-- due to merging, requirements may end up with
diff --git a/compiler/GHC/Driver/Make.hs b/compiler/GHC/Driver/Make.hs
index aef6953a30..51fb469828 100644
--- a/compiler/GHC/Driver/Make.hs
+++ b/compiler/GHC/Driver/Make.hs
@@ -2538,6 +2538,7 @@ makeNewModSummary hsc_env MakeNewModSummary{..} = do
, ms_hspp_buf = Just pi_hspp_buf
, ms_parsed_mod = Nothing
, ms_srcimps = pi_srcimps
+ , ms_ghc_prim_import = pi_ghc_prim_import
, ms_textual_imps =
pi_theimps ++
extra_sig_imports ++
@@ -2556,6 +2557,7 @@ data PreprocessedImports
{ pi_local_dflags :: DynFlags
, pi_srcimps :: [(Maybe FastString, Located ModuleName)]
, pi_theimps :: [(Maybe FastString, Located ModuleName)]
+ , pi_ghc_prim_import :: Bool
, pi_hspp_fn :: FilePath
, pi_hspp_buf :: StringBuffer
, pi_mod_name_loc :: SrcSpan
@@ -2575,7 +2577,7 @@ getPreprocessedImports hsc_env src_fn mb_phase maybe_buf = do
(pi_local_dflags, pi_hspp_fn)
<- ExceptT $ preprocess hsc_env src_fn (fst <$> maybe_buf) mb_phase
pi_hspp_buf <- liftIO $ hGetStringBuffer pi_hspp_fn
- (pi_srcimps, pi_theimps, L pi_mod_name_loc pi_mod_name)
+ (pi_srcimps, pi_theimps, pi_ghc_prim_import, L pi_mod_name_loc pi_mod_name)
<- ExceptT $ do
let imp_prelude = xopt LangExt.ImplicitPrelude pi_local_dflags
popts = initParserOpts pi_local_dflags
diff --git a/compiler/GHC/Driver/Pipeline/Execute.hs b/compiler/GHC/Driver/Pipeline/Execute.hs
index 57d491104e..022e8ce1a1 100644
--- a/compiler/GHC/Driver/Pipeline/Execute.hs
+++ b/compiler/GHC/Driver/Pipeline/Execute.hs
@@ -632,15 +632,15 @@ runHscPhase pipe_env hsc_env0 input_fn src_flavour = do
-- gather the imports and module name
- (hspp_buf,mod_name,imps,src_imps) <- do
+ (hspp_buf,mod_name,imps,src_imps, ghc_prim_imp) <- do
buf <- hGetStringBuffer input_fn
let imp_prelude = xopt LangExt.ImplicitPrelude dflags
popts = initParserOpts dflags
eimps <- getImports popts imp_prelude buf input_fn (basename <.> suff)
case eimps of
Left errs -> throwErrors (GhcPsMessage <$> errs)
- Right (src_imps,imps,L _ mod_name) -> return
- (Just buf, mod_name, imps, src_imps)
+ Right (src_imps,imps, ghc_prim_imp, L _ mod_name) -> return
+ (Just buf, mod_name, imps, src_imps, ghc_prim_imp)
-- Take -o into account if present
-- Very like -ohi, but we must *only* do this if we aren't linking
@@ -679,6 +679,7 @@ runHscPhase pipe_env hsc_env0 input_fn src_flavour = do
ms_parsed_mod = Nothing,
ms_iface_date = hi_date,
ms_hie_date = hie_date,
+ ms_ghc_prim_import = ghc_prim_imp,
ms_textual_imps = imps,
ms_srcimps = src_imps }
diff --git a/compiler/GHC/Iface/Recomp.hs b/compiler/GHC/Iface/Recomp.hs
index 59c31ad566..72341ba147 100644
--- a/compiler/GHC/Iface/Recomp.hs
+++ b/compiler/GHC/Iface/Recomp.hs
@@ -452,11 +452,11 @@ checkMergedSignatures hsc_env mod_summary iface = do
checkDependencies :: HscEnv -> ModSummary -> ModIface -> IfG RecompileRequired
checkDependencies hsc_env summary iface
= do
- res <- liftIO $ fmap sequence $ traverse (\(mb_pkg, L _ mod) ->
+ res <- liftIO $ traverse (\(mb_pkg, L _ mod) ->
let reason = moduleNameString mod ++ " changed"
in classify reason <$> findImportedModule fc units home_unit dflags mod (mb_pkg))
(ms_imps summary ++ ms_srcimps summary)
- case res of
+ case sequence (res ++ [Right (fake_ghc_prim_import)| ms_ghc_prim_import summary]) of
Left recomp -> return recomp
Right es -> do
let (hs, ps) = partitionEithers es
@@ -475,9 +475,15 @@ checkDependencies hsc_env summary iface
prev_dep_pkgs = sort (dep_direct_pkgs (mi_deps iface))
bkpk_units = map (("Signature",) . indefUnit . instUnitInstanceOf . moduleUnit) (requirementMerges units (moduleName (mi_module iface)))
-
implicit_deps = map ("Implicit",) (implicitPackageDeps dflags)
+ -- GHC.Prim is very special and doesn't appear in ms_textual_imps but
+ -- ghc-prim will appear in the package dependencies still. In order to not confuse
+ -- the recompilation logic we need to not forget we imported GHC.Prim.
+ fake_ghc_prim_import = if homeUnitId home_unit == primUnitId
+ then Left (mkModuleName "GHC.Prim")
+ else Right ("GHC.Prim", primUnitId)
+
classify _ (Found _ mod)
| isHomeUnit home_unit (moduleUnit mod) = Right (Left (moduleName mod))
diff --git a/compiler/GHC/Parser/Header.hs b/compiler/GHC/Parser/Header.hs
index 65e09bfeff..68468d89eb 100644
--- a/compiler/GHC/Parser/Header.hs
+++ b/compiler/GHC/Parser/Header.hs
@@ -75,6 +75,7 @@ getImports :: ParserOpts -- ^ Parser options
(Messages PsMessage)
([(Maybe FastString, Located ModuleName)],
[(Maybe FastString, Located ModuleName)],
+ Bool, -- Is GHC.Prim imported or not
Located ModuleName))
-- ^ The source imports and normal imports (with optional package
-- names from -XPackageImports), and the module name.
@@ -100,17 +101,19 @@ getImports popts implicit_prelude buf filename source_filename = do
(src_idecls, ord_idecls) = partition ((== IsBoot) . ideclSource . unLoc) imps
-- GHC.Prim doesn't exist physically, so don't go looking for it.
- ordinary_imps = filter ((/= moduleName gHC_PRIM) . unLoc
- . ideclName . unLoc)
- ord_idecls
+ (ordinary_imps, ghc_prim_import)
+ = partition ((/= moduleName gHC_PRIM) . unLoc
+ . ideclName . unLoc)
+ ord_idecls
implicit_imports = mkPrelImports (unLoc mod) main_loc
implicit_prelude imps
convImport (L _ i) = (fmap sl_fs (ideclPkgQual i), ideclName i)
in
- return (map convImport src_idecls,
- map convImport (implicit_imports ++ ordinary_imps),
- mod)
+ return (map convImport src_idecls
+ , map convImport (implicit_imports ++ ordinary_imps)
+ , not (null ghc_prim_import)
+ , mod)
mkPrelImports :: ModuleName
-> SrcSpan -- Attribute the "import Prelude" to this location
diff --git a/compiler/GHC/Unit/Module/ModSummary.hs b/compiler/GHC/Unit/Module/ModSummary.hs
index 339afd4564..d36636e340 100644
--- a/compiler/GHC/Unit/Module/ModSummary.hs
+++ b/compiler/GHC/Unit/Module/ModSummary.hs
@@ -90,6 +90,8 @@ data ModSummary
-- ^ Source imports of the module
ms_textual_imps :: [(Maybe FastString, Located ModuleName)],
-- ^ Non-source imports of the module from the module *text*
+ ms_ghc_prim_import :: Bool,
+ -- ^ Whether the special module GHC.Prim was imported explicitliy
ms_parsed_mod :: Maybe HsParsedModule,
-- ^ The parsed, nonrenamed source, if we have it. This is also
-- used to support "inline module syntax" in Backpack files.
@@ -111,6 +113,7 @@ ms_installed_mod = fst . getModuleInstantiation . ms_mod
ms_mod_name :: ModSummary -> ModuleName
ms_mod_name = moduleName . ms_mod
+-- | Textual imports, plus plugin imports but not SOURCE imports.
ms_imps :: ModSummary -> [(Maybe FastString, Located ModuleName)]
ms_imps ms =
ms_textual_imps ms ++
diff --git a/testsuite/tests/driver/Makefile b/testsuite/tests/driver/Makefile
index 9f7716a4fe..f58fdbee4f 100644
--- a/testsuite/tests/driver/Makefile
+++ b/testsuite/tests/driver/Makefile
@@ -726,3 +726,10 @@ T14923:
"$(TEST_HC)" $(TEST_HC_OPTS) -c Foo.hs;
# And this should not
"$(TEST_HC)" $(TEST_HC_OPTS) -c Foo.hs;
+
+T20084:
+ # Compile
+ "$(TEST_HC)" $(TEST_HC_OPTS) T20084.hs
+ # Don't compile
+ "$(TEST_HC)" $(TEST_HC_OPTS) T20084.hs
+
diff --git a/testsuite/tests/driver/T20084.hs b/testsuite/tests/driver/T20084.hs
new file mode 100644
index 0000000000..7025a11064
--- /dev/null
+++ b/testsuite/tests/driver/T20084.hs
@@ -0,0 +1,3 @@
+module T20084 where
+
+import GHC.Prim
diff --git a/testsuite/tests/driver/T20084.stdout b/testsuite/tests/driver/T20084.stdout
new file mode 100644
index 0000000000..04cef7e49d
--- /dev/null
+++ b/testsuite/tests/driver/T20084.stdout
@@ -0,0 +1 @@
+[1 of 1] Compiling T20084 ( T20084.hs, T20084.o )
diff --git a/testsuite/tests/driver/all.T b/testsuite/tests/driver/all.T
index 2afd735fe0..6f45e1ec21 100644
--- a/testsuite/tests/driver/all.T
+++ b/testsuite/tests/driver/all.T
@@ -292,3 +292,4 @@ test('T18369', normal, compile, ['-O'])
test('FullGHCVersion', normal, compile_and_run, ['-package ghc-boot'])
test('OneShotTH', normal, makefile_test, [])
test('T17481', normal, makefile_test, [])
+test('T20084', normal, makefile_test, [])