Skip to content

Commit 476e87e

Browse files
hsyl20GHC GitLab CI
authored andcommitted
Driver: substitute virtual Prim module in --make mode too
When we build ghc-internal with --make (e.g. with cabal-install), we need to be careful to substitute the virtual interface file for GHC.Internal.Prim: - after code generation (we generate code for an empty module, so we get an empty interface) - when we try to reload its .hi file
1 parent 6c178d8 commit 476e87e

File tree

8 files changed

+86
-75
lines changed

8 files changed

+86
-75
lines changed

compiler/GHC/Driver/Downsweep.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ loopFixedModule key loc done = do
519519
-- part of the compiler.
520520
lookupIfaceByModuleHsc hsc_env (mnkToModule key) >>= \case
521521
Just iface -> return (M.Succeeded iface)
522-
Nothing -> readIface (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule key) (ml_hi_file loc)
522+
Nothing -> readIface (hsc_hooks hsc_env) (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule key) (ml_hi_file loc)
523523
case read_result of
524524
M.Succeeded iface -> do
525525
-- Computer information about this node

compiler/GHC/Driver/Main.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ hscDesugarAndSimplify summary (FrontendTypecheck tc_result) tc_warnings mb_old_h
12991299
-- when compiling gHC_PRIM without generating code (e.g. with
13001300
-- Haddock), we still want the virtual interface in the cache
13011301
if ms_mod summary == gHC_PRIM
1302-
then return $ HscUpdate (getGhcPrimIface hsc_env)
1302+
then return $ HscUpdate (getGhcPrimIface (hsc_hooks hsc_env))
13031303
else return $ HscUpdate iface
13041304

13051305

@@ -1314,7 +1314,7 @@ hscDesugarAndSimplify summary (FrontendTypecheck tc_result) tc_warnings mb_old_h
13141314
-- when compiling gHC_PRIM without generating code (e.g. with
13151315
-- Haddock), we still want the virtual interface in the cache
13161316
if ms_mod summary == gHC_PRIM
1317-
then return $ HscUpdate (getGhcPrimIface hsc_env)
1317+
then return $ HscUpdate (getGhcPrimIface (hsc_hooks hsc_env))
13181318
else return $ HscUpdate iface
13191319

13201320
{-

compiler/GHC/Driver/Make.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1616,7 +1616,7 @@ executeCompileNode k n !old_hmi hug mrehydrate_mods mni = do
16161616
executeCompileNodeFixed hsc_env MakeEnv{diag_wrapper, env_messager} mod loc =
16171617
wrapAction diag_wrapper hsc_env $ do
16181618
forM_ env_messager $ \hscMessage -> hscMessage hsc_env (k, n) UpToDate (ModuleNode [] (ModuleNodeFixed mod loc))
1619-
read_result <- readIface (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule mod) (ml_hi_file loc)
1619+
read_result <- readIface (hsc_hooks hsc_env) (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule mod) (ml_hi_file loc)
16201620
case read_result of
16211621
M.Failed interface_err ->
16221622
let mn = mnkModuleName mod

compiler/GHC/Driver/Pipeline.hs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ module GHC.Driver.Pipeline (
4444

4545

4646
import GHC.Prelude
47+
import GHC.Builtin.Names
4748

4849
import GHC.Platform
4950

@@ -91,6 +92,7 @@ import GHC.Data.StringBuffer ( hPutStringBuffer )
9192
import GHC.Data.Maybe ( expectJust )
9293

9394
import GHC.Iface.Make ( mkFullIface )
95+
import GHC.Iface.Load ( getGhcPrimIface )
9496
import GHC.Runtime.Loader ( initializePlugins )
9597

9698

@@ -819,7 +821,13 @@ hscGenBackendPipeline pipe_env hsc_env mod_sum result = do
819821
let !linkable = Linkable part_time (ms_mod mod_sum) (NE.singleton (DotO final_object ModuleObject))
820822
-- Add the object linkable to the potential bytecode linkable which was generated in HscBackend.
821823
return (mlinkable { homeMod_object = Just linkable })
822-
return (miface, final_linkable)
824+
825+
-- when building ghc-internal with --make (e.g. with cabal-install), we want
826+
-- the virtual interface for gHC_PRIM in the cache, not the empty one.
827+
let miface_final
828+
| ms_mod mod_sum == gHC_PRIM = getGhcPrimIface (hsc_hooks hsc_env)
829+
| otherwise = miface
830+
return (miface_final, final_linkable)
823831

824832
asPipeline :: P m => Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> m (Maybe ObjFile)
825833
asPipeline use_cpp pipe_env hsc_env location input_fn =

compiler/GHC/Iface/Load.hs

Lines changed: 67 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,7 @@ findAndReadIface hsc_env doc_str mod wanted_mod hi_boot_file = do
895895
mhome_unit = hsc_home_unit_maybe hsc_env
896896
dflags = hsc_dflags hsc_env
897897
logger = hsc_logger hsc_env
898+
hooks = hsc_hooks hsc_env
898899

899900

900901
trace_if logger (sep [hsep [text "Reading",
@@ -905,59 +906,51 @@ findAndReadIface hsc_env doc_str mod wanted_mod hi_boot_file = do
905906
ppr mod <> semi],
906907
nest 4 (text "reason:" <+> doc_str)])
907908

908-
-- Check for GHC.Prim, and return its static interface
909-
-- See Note [GHC.Prim] in primops.txt.pp.
910-
-- TODO: make this check a function
911-
if mod `installedModuleEq` gHC_PRIM
912-
then do
913-
let iface = getGhcPrimIface hsc_env
914-
return (Succeeded (iface, panic "GHC.Prim ModLocation (findAndReadIface)"))
915-
else do
916-
-- Look for the file
917-
mb_found <- liftIO (findExactModule hsc_env mod hi_boot_file)
918-
case mb_found of
919-
InstalledFound loc -> do
920-
-- See Note [Home module load error]
921-
if HUG.memberHugUnitId (moduleUnit mod) (hsc_HUG hsc_env)
922-
&& not (isOneShot (ghcMode dflags))
923-
then return (Failed (HomeModError mod loc))
924-
else do
925-
r <- read_file logger name_cache unit_state dflags wanted_mod (ml_hi_file loc)
926-
case r of
927-
Failed err
928-
-> return (Failed $ BadIfaceFile err)
929-
Succeeded (iface,_fp)
930-
-> do
931-
r2 <- load_dynamic_too_maybe logger name_cache unit_state
932-
(setDynamicNow dflags) wanted_mod
933-
iface loc
934-
case r2 of
935-
Failed sdoc -> return (Failed sdoc)
936-
Succeeded {} -> return $ Succeeded (iface, loc)
937-
err -> do
938-
trace_if logger (text "...not found")
939-
return $ Failed $ cannotFindInterface
940-
unit_state
941-
mhome_unit
942-
profile
943-
(moduleName mod)
944-
err
909+
-- Look for the file
910+
mb_found <- liftIO (findExactModule hsc_env mod hi_boot_file)
911+
case mb_found of
912+
InstalledFound loc -> do
913+
-- See Note [Home module load error]
914+
if HUG.memberHugUnitId (moduleUnit mod) (hsc_HUG hsc_env)
915+
&& not (isOneShot (ghcMode dflags))
916+
then return (Failed (HomeModError mod loc))
917+
else do
918+
r <- read_file hooks logger name_cache unit_state dflags wanted_mod (ml_hi_file loc)
919+
case r of
920+
Failed err
921+
-> return (Failed $ BadIfaceFile err)
922+
Succeeded (iface,_fp)
923+
-> do
924+
r2 <- load_dynamic_too_maybe hooks logger name_cache unit_state
925+
(setDynamicNow dflags) wanted_mod
926+
iface loc
927+
case r2 of
928+
Failed sdoc -> return (Failed sdoc)
929+
Succeeded {} -> return $ Succeeded (iface, loc)
930+
err -> do
931+
trace_if logger (text "...not found")
932+
return $ Failed $ cannotFindInterface
933+
unit_state
934+
mhome_unit
935+
profile
936+
(moduleName mod)
937+
err
945938

946939
-- | Check if we need to try the dynamic interface for -dynamic-too
947-
load_dynamic_too_maybe :: Logger -> NameCache -> UnitState -> DynFlags
940+
load_dynamic_too_maybe :: Hooks -> Logger -> NameCache -> UnitState -> DynFlags
948941
-> Module -> ModIface -> ModLocation
949942
-> IO (MaybeErr MissingInterfaceError ())
950-
load_dynamic_too_maybe logger name_cache unit_state dflags wanted_mod iface loc
943+
load_dynamic_too_maybe hooks logger name_cache unit_state dflags wanted_mod iface loc
951944
-- Indefinite interfaces are ALWAYS non-dynamic.
952945
| not (moduleIsDefinite (mi_module iface)) = return (Succeeded ())
953-
| gopt Opt_BuildDynamicToo dflags = load_dynamic_too logger name_cache unit_state dflags wanted_mod iface loc
946+
| gopt Opt_BuildDynamicToo dflags = load_dynamic_too hooks logger name_cache unit_state dflags wanted_mod iface loc
954947
| otherwise = return (Succeeded ())
955948

956-
load_dynamic_too :: Logger -> NameCache -> UnitState -> DynFlags
949+
load_dynamic_too :: Hooks -> Logger -> NameCache -> UnitState -> DynFlags
957950
-> Module -> ModIface -> ModLocation
958951
-> IO (MaybeErr MissingInterfaceError ())
959-
load_dynamic_too logger name_cache unit_state dflags wanted_mod iface loc = do
960-
read_file logger name_cache unit_state dflags wanted_mod (ml_dyn_hi_file loc) >>= \case
952+
load_dynamic_too hooks logger name_cache unit_state dflags wanted_mod iface loc = do
953+
read_file hooks logger name_cache unit_state dflags wanted_mod (ml_dyn_hi_file loc) >>= \case
961954
Succeeded (dynIface, _)
962955
| mi_mod_hash iface == mi_mod_hash dynIface
963956
-> return (Succeeded ())
@@ -971,10 +964,10 @@ load_dynamic_too logger name_cache unit_state dflags wanted_mod iface loc = do
971964

972965

973966

974-
read_file :: Logger -> NameCache -> UnitState -> DynFlags
967+
read_file :: Hooks -> Logger -> NameCache -> UnitState -> DynFlags
975968
-> Module -> FilePath
976969
-> IO (MaybeErr ReadInterfaceError (ModIface, FilePath))
977-
read_file logger name_cache unit_state dflags wanted_mod file_path = do
970+
read_file hooks logger name_cache unit_state dflags wanted_mod file_path = do
978971

979972
-- Figure out what is recorded in mi_module. If this is
980973
-- a fully definite interface, it'll match exactly, but
@@ -985,7 +978,7 @@ read_file logger name_cache unit_state dflags wanted_mod file_path = do
985978
(_, Just indef_mod) ->
986979
instModuleToModule unit_state
987980
(uninstantiateInstantiatedModule indef_mod)
988-
read_result <- readIface logger dflags name_cache wanted_mod' file_path
981+
read_result <- readIface hooks logger dflags name_cache wanted_mod' file_path
989982
case read_result of
990983
Failed err -> return (Failed err)
991984
Succeeded iface -> return (Succeeded (iface, file_path))
@@ -1012,29 +1005,37 @@ flagsToIfCompression dflags
10121005
-- Failed err <=> file not found, or unreadable, or illegible
10131006
-- Succeeded iface <=> successfully found and parsed
10141007
readIface
1015-
:: Logger
1008+
:: Hooks
1009+
-> Logger
10161010
-> DynFlags
10171011
-> NameCache
10181012
-> Module
10191013
-> FilePath
10201014
-> IO (MaybeErr ReadInterfaceError ModIface)
1021-
readIface logger dflags name_cache wanted_mod file_path = do
1015+
readIface hooks logger dflags name_cache wanted_mod file_path = do
10221016
trace_if logger (text "readIFace" <+> text file_path)
1023-
let profile = targetProfile dflags
1024-
res <- tryMost $ readBinIface profile name_cache CheckHiWay QuietBinIFace file_path
1025-
case res of
1026-
Right iface
1027-
-- NB: This check is NOT just a sanity check, it is
1028-
-- critical for correctness of recompilation checking
1029-
-- (it lets us tell when -this-unit-id has changed.)
1030-
| wanted_mod == actual_mod
1031-
-> return (Succeeded iface)
1032-
| otherwise -> return (Failed err)
1033-
where
1034-
actual_mod = mi_module iface
1035-
err = HiModuleNameMismatchWarn file_path wanted_mod actual_mod
1036-
1037-
Left exn -> return (Failed (ExceptionOccurred file_path exn))
1017+
-- Check for GHC.Prim, and return its static interface
1018+
-- See Note [GHC.Prim] in primops.txt.pp.
1019+
if wanted_mod == gHC_PRIM
1020+
then do
1021+
-- TODO: should we check for the existence of the file?
1022+
return (Succeeded (getGhcPrimIface hooks))
1023+
else do
1024+
let profile = targetProfile dflags
1025+
res <- tryMost $ readBinIface profile name_cache CheckHiWay QuietBinIFace file_path
1026+
case res of
1027+
Right iface
1028+
-- NB: This check is NOT just a sanity check, it is
1029+
-- critical for correctness of recompilation checking
1030+
-- (it lets us tell when -this-unit-id has changed.)
1031+
| wanted_mod == actual_mod
1032+
-> return (Succeeded iface)
1033+
| otherwise -> return (Failed err)
1034+
where
1035+
actual_mod = mi_module iface
1036+
err = HiModuleNameMismatchWarn file_path wanted_mod actual_mod
1037+
1038+
Left exn -> return (Failed (ExceptionOccurred file_path exn))
10381039

10391040
{-
10401041
*********************************************************
@@ -1245,8 +1246,8 @@ instance Outputable WhereFrom where
12451246
-- This is a helper function that takes into account the hook allowing ghc-prim
12461247
-- interface to be extended via the ghc-api. Afaik it was introduced for GHCJS
12471248
-- so that it can add its own primitive types.
1248-
getGhcPrimIface :: HscEnv -> ModIface
1249-
getGhcPrimIface hsc_env =
1250-
case ghcPrimIfaceHook (hsc_hooks hsc_env) of
1249+
getGhcPrimIface :: Hooks -> ModIface
1250+
getGhcPrimIface hooks =
1251+
case ghcPrimIfaceHook hooks of
12511252
Nothing -> ghcPrimIface
12521253
Just h -> h

compiler/GHC/Iface/Make.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ mkFullIface hsc_env partial_iface mb_stg_infos mb_cmm_infos stubs foreign_files
156156
putDumpFileMaybe (hsc_logger hsc_env) Opt_D_dump_hi "FINAL INTERFACE" FormatText
157157
(pprModIface unit_state full_iface)
158158
final_iface <- shareIface (hsc_NC hsc_env) (flagsToIfCompression $ hsc_dflags hsc_env) full_iface
159-
return final_iface
159+
return $ final_iface
160160

161161
-- | Compress an 'ModIface' and share as many values as possible, depending on the 'CompressionIFace' level.
162162
-- See Note [Sharing of ModIface].

compiler/GHC/Iface/Recomp.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ check_old_iface hsc_env mod_summary maybe_iface
304304

305305
loadIface read_dflags iface_path = do
306306
let ncu = hsc_NC hsc_env
307-
read_result <- readIface logger read_dflags ncu (ms_mod mod_summary) iface_path
307+
read_result <- readIface (hsc_hooks hsc_env) logger read_dflags ncu (ms_mod mod_summary) iface_path
308308
case read_result of
309309
Failed err -> do
310310
let msg = readInterfaceErrorDiagnostic err

compiler/GHC/Unit/Module/ModIface.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module GHC.Unit.Module.ModIface
4343
, mi_hash_fn
4444
)
4545
, pattern ModIface
46+
, get_mi_mod_info
4647
, set_mi_mod_info
4748
, set_mi_module
4849
, set_mi_sig_of
@@ -978,6 +979,9 @@ completePublicModIface decls abi_hashes cache partial = partial
978979
, mi_caches_ = cache
979980
}
980981

982+
get_mi_mod_info :: ModIface_ phase -> IfaceModInfo
983+
get_mi_mod_info iface = mi_mod_info_ iface
984+
981985
set_mi_mod_info :: IfaceModInfo -> ModIface_ phase -> ModIface_ phase
982986
set_mi_mod_info val iface = clear_mi_hi_bytes $ iface { mi_mod_info_ = val }
983987

@@ -1083,8 +1087,6 @@ set_mi_mod_info_field :: (IfaceModInfo -> IfaceModInfo) -> ModIface_ phase -> Mo
10831087
set_mi_mod_info_field f iface = clear_mi_hi_bytes $ iface { mi_mod_info_ = f (mi_mod_info_ iface) }
10841088

10851089

1086-
1087-
10881090
-- | Invalidate any byte array buffer we might have.
10891091
clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase
10901092
clear_mi_hi_bytes iface = iface

0 commit comments

Comments
 (0)