diff options
author | Edward Z. Yang <ezyang@cs.stanford.edu> | 2017-02-12 02:44:01 -0800 |
---|---|---|
committer | Edward Z. Yang <ezyang@cs.stanford.edu> | 2017-02-17 13:43:07 -0800 |
commit | ca543154bbf0ec36ee2654050ee67a467420449f (patch) | |
tree | 0962e9c12f0aab2631d20f80263d6a96ecbd5346 /compiler/iface/MkIface.hs | |
parent | 0e7601749d53d59df528ede996d8b54352051498 (diff) | |
download | haskell-ca543154bbf0ec36ee2654050ee67a467420449f.tar.gz |
Fix a Backpack recompilation avoidance bug when signatures change.
Summary:
Recompilation avoidance checks if -this-unit-id has changed by relying
on the "wanted module" check in readIface ("Something is amiss...").
Unfortunately, this check didn't check if the instantiation made
sense, which meant that if you changed the signatures of a Backpack
package, we'd still treat the old signatures as up-to-date.
The way I fixed this was by having findAndReadIface take in a 'Module'
representing the /actual/ module we were intending to lookup. We
convert this into the 'Module' we expect to see in 'mi_module' and
now do a more elaborate check that will also verify that instantiations
make sense.
Along the way, I robustified the logging infrastructure for
recompilation checking, and folded wrongIfaceModErr (which
was dead code) into the error message.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
Test Plan: validate
Reviewers: bgamari, austin
Subscribers: thomie, snowleopard
Differential Revision: https://phabricator.haskell.org/D3130
Diffstat (limited to 'compiler/iface/MkIface.hs')
-rw-r--r-- | compiler/iface/MkIface.hs | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/compiler/iface/MkIface.hs b/compiler/iface/MkIface.hs index aacdac9b71..acf61a7066 100644 --- a/compiler/iface/MkIface.hs +++ b/compiler/iface/MkIface.hs @@ -1103,7 +1103,8 @@ checkOldIface hsc_env mod_summary source_modified maybe_iface = do let dflags = hsc_dflags hsc_env showPass dflags $ "Checking old interface for " ++ - (showPpr dflags $ ms_mod mod_summary) + (showPpr dflags $ ms_mod mod_summary) ++ + " (use -ddump-hi-diffs for more details)" initIfaceCheck (text "checkOldIface") hsc_env $ check_old_iface hsc_env mod_summary source_modified maybe_iface @@ -1126,10 +1127,11 @@ check_old_iface hsc_env mod_summary src_modified maybe_iface loadIface = do let iface_path = msHiFilePath mod_summary - read_result <- readIface (ms_installed_mod mod_summary) iface_path + read_result <- readIface (ms_mod mod_summary) iface_path case read_result of Failed err -> do traceIf (text "FYI: cannot read old interface file:" $$ nest 4 err) + traceHiDiffs (text "Old interface file was invalid:" $$ nest 4 err) return Nothing Succeeded iface -> do traceIf (text "Read the interface file" <+> text iface_path) @@ -1187,6 +1189,11 @@ checkVersions hsc_env mod_summary iface = do { traceHiDiffs (text "Considering whether compilation is required for" <+> ppr (mi_module iface) <> colon) + -- readIface will have verified that the InstalledUnitId matches, + -- but we ALSO must make sure the instantiation matches up. See + -- test case bkpcabal04! + ; if moduleUnitId (mi_module iface) /= thisPackage (hsc_dflags hsc_env) + then return (RecompBecause "-this-unit-id changed", Nothing) else do { ; recomp <- checkFlagHash hsc_env iface ; if recompileRequired recomp then return (recomp, Nothing) else do { ; recomp <- checkMergedSignatures mod_summary iface @@ -1212,7 +1219,7 @@ checkVersions hsc_env mod_summary iface ; updateEps_ $ \eps -> eps { eps_is_boot = udfmToUfm mod_deps } ; recomp <- checkList [checkModUsage this_pkg u | u <- mi_usages iface] ; return (recomp, Just iface) - }}}}} + }}}}}} where this_pkg = thisPackage (hsc_dflags hsc_env) -- This is a bit of a hack really |