@@ -45,6 +45,8 @@ import qualified GHC.LanguageExtensions as LangExt
4545import Control.Monad.Extra
4646import Control.Monad.Except
4747import Control.Monad.Trans.Except
48+import Data.Function
49+import Data.Ord
4850import qualified Data.Text as T
4951import Data.IORef
5052import Data.List.Extra
@@ -149,7 +151,12 @@ mkTcModuleResult tcm = do
149151-- | Setup the environment that GHC needs according to our
150152-- best understanding (!)
151153setupEnv :: GhcMonad m => [TcModuleResult] -> m ()
152−setupEnv tms = do
154+setupEnv tmsIn = do
155+ -- if both a .hs-boot file and a .hs file appear here, we want to make sure that the .hs file
156+ -- takes precedence, so put the .hs-boot file earlier in the list
157+ let isSourceFile = (==HsBootFile) . ms_hsc_src . pm_mod_summary . tm_parsed_module . tmrModule
158+ tms = sortBy (compare `on` Down . isSourceFile) tmsIn
159+
153160 session <- getSession
154161
155162 let mss = map (pm_mod_summary . tm_parsed_module . tmrModule) tms
@@ -191,24 +198,17 @@ loadModuleHome tmr = modifySession $ \e ->
191198-- name and its imports.
192199getImportsParsed :: DynFlags ->
193200 GHC.ParsedSource ->
194− Either [FileDiagnostic] (GHC.ModuleName, [(Maybe FastString, Located GHC.ModuleName)])
201+ Either [FileDiagnostic] (GHC.ModuleName, [(Bool, (Maybe FastString, Located GHC.ModuleName))])
195202getImportsParsed dflags (L loc parsed) = do
196203 let modName = maybe (GHC.mkModuleName "Main") GHC.unLoc $ GHC.hsmodName parsed
197204
198− -- refuse source imports
199− let srcImports = filter (ideclSource . GHC.unLoc) $ GHC.hsmodImports parsed
200− when (not $ null srcImports) $ Left $
201− concat
202− [ diagFromString "imports" mloc ("Illegal source import of " <> GHC.moduleNameString (GHC.unLoc $ GHC.ideclName i))
203− | L mloc i <- srcImports ]
204−
205205 -- most of these corner cases are also present in https://hackage.haskell.org/package/ghc-8.6.1/docs/src/HeaderInfo.html#getImports
206206 -- but we want to avoid parsing the module twice
207207 let implicit_prelude = xopt GHC.ImplicitPrelude dflags
208208 implicit_imports = Hdr.mkPrelImports modName loc implicit_prelude $ GHC.hsmodImports parsed
209209
210210 -- filter out imports that come from packages
211− return (modName, [(fmap sl_fs $ ideclPkgQual i, ideclName i)
211+ return (modName, [(ideclSource i, (fmap sl_fs $ ideclPkgQual i, ideclName i))
212212 | i <- map GHC.unLoc $ implicit_imports ++ GHC.hsmodImports parsed
213213 , GHC.moduleNameString (GHC.unLoc $ ideclName i) /= "GHC.Prim"
214214 ])
@@ -227,10 +227,10 @@ getModSummaryFromBuffer fp contents dflags parsed = do
227227
228228 let modLoc = ModLocation
229229 { ml_hs_file = Just fp
230− , ml_hi_file = replaceExtension fp "hi"
231− , ml_obj_file = replaceExtension fp "o"
230+ , ml_hi_file = derivedFile "hi"
231+ , ml_obj_file = derivedFile "o"
232232#ifndef GHC_STABLE
233− , ml_hie_file = replaceExtension fp "hie"
233+ , ml_hie_file = derivedFile "hie"
234234#endif
235235 -- This does not consider the dflags configuration
236236 -- (-osuf and -hisuf, object and hi dir.s).
@@ -245,21 +245,27 @@ getModSummaryFromBuffer fp contents dflags parsed = do
245245 -- To avoid silent issues where something is not processed because the date
246246 -- has not changed, we make sure that things blow up if they depend on the
247247 -- date.
248− , ms_textual_imps = imports
248+ , ms_textual_imps = [imp | (False, imp) <- imports]
249249 , ms_hspp_file = fp
250250 , ms_hspp_opts = dflags
251251 , ms_hspp_buf = Just contents
252252
253253 -- defaults:
254− , ms_hsc_src = HsSrcFile
254+ , ms_hsc_src = sourceType
255255 , ms_obj_date = Nothing
256256 , ms_iface_date = Nothing
257257#ifndef GHC_STABLE
258258 , ms_hie_date = Nothing
259259#endif
260− , ms_srcimps = [] -- source imports are not allowed
260+ , ms_srcimps = [imp | (True, imp) <- imports]
261261 , ms_parsed_mod = Nothing
262262 }
263+ where
264+ (sourceType, derivedFile) =
265+ let (stem, ext) = splitExtension fp in
266+ if "-boot" `isSuffixOf` ext
267+ then (HsBootFile, \newExt -> stem <.> newExt ++ "-boot")
268+ else (HsSrcFile , \newExt -> stem <.> newExt)
263269
264270-- | Run CPP on a file
265271runCpp :: DynFlags -> FilePath -> Maybe SB.StringBuffer -> IO SB.StringBuffer