Skip to content

Commit fda63c5

Browse files
committed
Cabal uses main as the unit id of all executable packages. This confused multi component sessions.
Solution: include the hash of the options in the unit id when the unit id is called "main". Fixes #3513
1 parent ca638bd commit fda63c5

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

ghcide/session-loader/Development/IDE/Session.hs

+19-1
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,24 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
484484
packageSetup (hieYaml, cfp, opts, libDir) = do
485485
-- Parse DynFlags for the newly discovered component
486486
hscEnv <- emptyHscEnv ideNc libDir
487-
(df, targets) <- evalGhcEnv hscEnv $ setOptions opts (hsc_dflags hscEnv)
487+
(df', targets) <- evalGhcEnv hscEnv $ setOptions opts (hsc_dflags hscEnv)
488+
let df =
489+
#if MIN_VERSION_ghc(9,3,0)
490+
case unitIdString (homeUnitId_ df') of
491+
-- cabal uses main for the unit id of all executable packages
492+
-- This makes multi-component sessions confused about what
493+
-- options to use for that component.
494+
-- Solution: hash the options and use that as part of the unit id
495+
-- This works because there won't be any dependencies on the
496+
-- executable unit.
497+
"main" ->
498+
let hash = B.unpack $ B16.encode $ H.finalize $ H.updates H.init (map B.pack $ componentOptions opts)
499+
hashed_uid = Compat.toUnitId (Compat.stringToUnit ("main-"++hash))
500+
in setHomeUnitId_ hashed_uid df'
501+
#else
502+
df'
503+
#endif
504+
488505
let deps = componentDependencies opts ++ maybeToList hieYaml
489506
dep_info <- getDependencyInfo deps
490507
-- Now lookup to see whether we are combining with an existing HscEnv
@@ -499,6 +516,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
499516
-- We will modify the unitId and DynFlags used for
500517
-- compilation but these are the true source of
501518
-- information.
519+
502520
new_deps = RawComponentInfo (homeUnitId_ df) df targets cfp opts dep_info
503521
: maybe [] snd oldDeps
504522
-- Get all the unit-ids for things in this component

ghcide/src/Development/IDE/Import/FindImports.hs

+12-11
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,6 @@ locateModule env comp_info exts targetFor modName mbPkgName isSource = do
136136
#else
137137
Nothing -> do
138138
#endif
139-
-- first try to find the module as a file. If we can't find it try to find it in the package
140-
-- database.
141-
-- Here the importPaths for the current modules are added to the front of the import paths from the other components.
142-
-- This is particularly important for Paths_* modules which get generated for every component but unless you use it in
143-
-- each component will end up being found in the wrong place and cause a multi-cradle match failure.
144-
let import_paths' =
145-
#if MIN_VERSION_ghc(9,3,0)
146-
import_paths
147-
#else
148-
map snd import_paths
149-
#endif
150139

151140
mbFile <- locateModuleFile ((homeUnitId_ dflags, importPaths dflags) : other_imports) exts targetFor isSource $ unLoc modName
152141
case mbFile of
@@ -174,6 +163,18 @@ locateModule env comp_info exts targetFor modName mbPkgName isSource = do
174163
import_paths'
175164
#endif
176165

166+
-- first try to find the module as a file. If we can't find it try to find it in the package
167+
-- database.
168+
-- Here the importPaths for the current modules are added to the front of the import paths from the other components.
169+
-- This is particularly important for Paths_* modules which get generated for every component but unless you use it in
170+
-- each component will end up being found in the wrong place and cause a multi-cradle match failure.
171+
import_paths' =
172+
#if MIN_VERSION_ghc(9,3,0)
173+
import_paths
174+
#else
175+
map snd import_paths
176+
#endif
177+
177178
toModLocation uid file = liftIO $ do
178179
loc <- mkHomeModLocation dflags (unLoc modName) (fromNormalizedFilePath file)
179180
#if MIN_VERSION_ghc(9,0,0)

0 commit comments

Comments
 (0)