Fix #16500: look for interface files in -hidir flag in OneShot mode
authorPhuong Trinh <lolotp@fb.com>
Sat, 30 Mar 2019 19:00:12 +0000 (19:00 +0000)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Mon, 8 Apr 2019 18:35:43 +0000 (14:35 -0400)
We are currently ignoring options set in the hiDir field of hsc_dflags
when looking for interface files while compiling in OneShot mode. This
is inconsistent with the behaviour of other directory redirecting fields
(such as objectDir or hieDir). It is also inconsistent with the
behaviour of compilation in CompManager mode (a.k.a `ghc --make`) which
looks for interface files in the directory set in hidir flag. This
changes Finder.hs so that we use the value of hiDir while looking for
interface in OneShot mode.

compiler/main/Finder.hs
docs/users_guide/separate_compilation.rst
testsuite/tests/driver/T16500/A.hs [new file with mode: 0644]
testsuite/tests/driver/T16500/B.hs [new file with mode: 0644]
testsuite/tests/driver/T16500/Makefile [new file with mode: 0644]
testsuite/tests/driver/T16500/T16500.stdout [new file with mode: 0644]
testsuite/tests/driver/T16500/all.T [new file with mode: 0644]

index 2db0a5e..dc0c87f 100644 (file)
@@ -313,8 +313,10 @@ findInstalledHomeModule hsc_env mod_name =
       , ("lhsig",  mkHomeModLocationSearched dflags mod_name "lhsig")
       ]
 
-     hi_exts = [ (hisuf,                mkHiOnlyModLocation dflags hisuf)
-               , (addBootSuffix hisuf,  mkHiOnlyModLocation dflags hisuf)
+     -- we use mkHomeModHiOnlyLocation instead of mkHiOnlyModLocation so that
+     -- when hiDir field is set in dflags, we know to look there (see #16500)
+     hi_exts = [ (hisuf,                mkHomeModHiOnlyLocation dflags mod_name)
+               , (addBootSuffix hisuf,  mkHomeModHiOnlyLocation dflags mod_name)
                ]
 
         -- In compilation manager modes, we look for source files in the home
@@ -489,6 +491,15 @@ mkHomeModLocation2 dflags mod src_basename ext = do
                         ml_obj_file  = obj_fn,
                         ml_hie_file  = hie_fn })
 
+mkHomeModHiOnlyLocation :: DynFlags
+                        -> ModuleName
+                        -> FilePath
+                        -> BaseName
+                        -> IO ModLocation
+mkHomeModHiOnlyLocation dflags mod path basename = do
+   loc <- mkHomeModLocation2 dflags mod (path </> basename) ""
+   return loc { ml_hs_file = Nothing }
+
 mkHiOnlyModLocation :: DynFlags -> Suffix -> FilePath -> String
                     -> IO ModLocation
 mkHiOnlyModLocation dflags hisuf path basename
index 1c5e34a..d591736 100644 (file)
@@ -260,6 +260,9 @@ Redirecting the compilation output(s)
     example, they would still be put in ``parse/Foo.hi``,
     ``parse/Bar.hi``, and ``gurgle/Bumble.hi``.
 
+    Please also note that when doing incremental compilation, this directory is
+    where GHC looks into to find object files from previous builds.
+
 .. ghc-flag:: -ohi ⟨file⟩
     :shortdesc: set the filename in which to put the interface
     :type: dynamic
@@ -288,6 +291,10 @@ Redirecting the compilation output(s)
     Redirects all generated interface files into ⟨dir⟩, instead of the
     default.
 
+    Please also note that when doing incremental compilation (by ``ghc --make``
+    or ``ghc -c``), this directory is where GHC looks into to find interface
+    files.
+
 .. ghc-flag:: -hiedir ⟨dir⟩
     :shortdesc: set directory for extended interface files
     :type: dynamic
@@ -296,6 +303,10 @@ Redirecting the compilation output(s)
     Redirects all generated extended interface files into ⟨dir⟩, instead of
     the default.
 
+    Please also note that when doing incremental compilation (by ``ghc --make``
+    or ``ghc -c``), this directory is where GHC looks into to find extended
+    interface files.
+
 .. ghc-flag:: -stubdir ⟨dir⟩
     :shortdesc: redirect FFI stub files
     :type: dynamic
diff --git a/testsuite/tests/driver/T16500/A.hs b/testsuite/tests/driver/T16500/A.hs
new file mode 100644 (file)
index 0000000..9e76b58
--- /dev/null
@@ -0,0 +1,4 @@
+module A (message) where
+
+message :: String
+message = "Hello!!"
diff --git a/testsuite/tests/driver/T16500/B.hs b/testsuite/tests/driver/T16500/B.hs
new file mode 100644 (file)
index 0000000..71de4f0
--- /dev/null
@@ -0,0 +1,7 @@
+module B where
+
+import A (message)
+
+main :: IO ()
+main = do
+    putStrLn message
diff --git a/testsuite/tests/driver/T16500/Makefile b/testsuite/tests/driver/T16500/Makefile
new file mode 100644 (file)
index 0000000..7cec0cc
--- /dev/null
@@ -0,0 +1,12 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+T16500:
+       $(RM) -rf interfaces objects
+       $(RM) A.hi
+       mkdir -p interfaces
+       mkdir -p objects
+       "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -c A.hs -iinterfaces -hidir interfaces -odir objects
+       touch A.hi
+       "$(TEST_HC)" $(TEST_HC_OPTS) -v0 -c B.hs -iinterfaces -hidir interfaces -odir objects
diff --git a/testsuite/tests/driver/T16500/T16500.stdout b/testsuite/tests/driver/T16500/T16500.stdout
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/tests/driver/T16500/all.T b/testsuite/tests/driver/T16500/all.T
new file mode 100644 (file)
index 0000000..ef57f7f
--- /dev/null
@@ -0,0 +1 @@
+test('T16500', [extra_files(['A.hs','B.hs',]),], run_command, ['$MAKE -s --no-print-directory T16500'])