-
Notifications
You must be signed in to change notification settings - Fork 66
Description
The ghcide README says:
There is a known issue where if you have three components, such that A depends on B which depends on C then if you load A and C into the session but not B then under certain situations you can get strange errors about a type coming from two different places. See this repo for a simple reproduction of the bug.
This is because of the way multicomponent support works in ghcide. Loading A and C creates a fake package AC which results from the union of the flags and targets in A and C. So AC depends on B because A depends on B, and transitively on C because B depends on C. As a result the types in C are loaded twice, once for AC and once for B, and even if they have the same names they are not the same types, which leads to the weird errors.
To fix this, we need to load B in the session, obtaining ABC. The user can do this by opening any B file in their editor, but ideally this would be done automatically by ghcide. Unfortunately, ghcide has no way of knowing about this!
My proposal is to extend getComponentOptions to accept the set of components already loaded and produce a set of component options:
getCompilerOptions :: FilePath -> [LoadedComponent] -> Cradle a -> IO (CradleLoadResult [ComponentOptions])
This would change the example in the ghcide README as follows:
- The user opens A.hs from A in the editor,
- ghcide asks the cradle about A.hs letting it know that the current set of components is []
- hie-bios returns the component options for the set [A]
- ghcide creates and loads the component A
- The user opens C.hs from C in the editor
- ghcide asks the cradle about C.hs letting it know that the current set of components is [A]
- hie-bios returns the component options for the set [B,C]
- ghcide creates and loads the component ABC
To implement the new getCompilerOptions:
- the Stack and Cabal cradles will need to interrogate the build system to find out component dependencies
- multi cradles will need to interrogate all the single cradles, which will probably be ridiculously expensive
- Bios cradles will need to extend the protocol with the program to pass the information of the loaded components
This proposal is very much up for discussion, and note that I have not prototyped any of this so I have no idea of whether it will work.