diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2021-07-05 14:16:35 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-07-21 02:45:39 -0400 |
commit | 9eb1641e0ef10a7887e794d4d114c9a18a2fd265 (patch) | |
tree | 2974508390083775e3bf2c4efcc2113a4c07a2c3 | |
parent | d706fd0432925caf62673a55237a005e22bc4450 (diff) | |
download | haskell-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.hs | 7 | ||||
-rw-r--r-- | compiler/GHC/Driver/Make.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/Driver/Pipeline/Execute.hs | 7 | ||||
-rw-r--r-- | compiler/GHC/Iface/Recomp.hs | 12 | ||||
-rw-r--r-- | compiler/GHC/Parser/Header.hs | 15 | ||||
-rw-r--r-- | compiler/GHC/Unit/Module/ModSummary.hs | 3 | ||||
-rw-r--r-- | testsuite/tests/driver/Makefile | 7 | ||||
-rw-r--r-- | testsuite/tests/driver/T20084.hs | 3 | ||||
-rw-r--r-- | testsuite/tests/driver/T20084.stdout | 1 | ||||
-rw-r--r-- | testsuite/tests/driver/all.T | 1 |
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, []) |