one-shot compilation + TH doesn't see instances that is seen in batch mode
Haskell prime and Haskell98 both states that instances are always seen if there is any chain of imports leading from the current module to the instance.
The ghc manual contains a discussion why this specification is too performance heavy to näively implement and contains the definition of orphanness and an algorithm to reproduce the specification with better performance.
http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/separate-compilation.html#orphan-modules
Unfortunately this cleverness breaks template haskell. Namely, if:
Class.hs
contains a class,NonOrphan.hs
contains a data that implements the class,Importer.hs
just importsNonOrphan.hs
,Main.hs
importsImporter.hs
,Main.hs
reifies the class;
then:
- one-shot compilation's reify doesn't see the instance,
- batch compilation's reify sees the instance.
This ambiguity is shown in the attached tgz.
Furthermore if NonOrphan.hs
is in a separate package, then of course even batch compilation mode wouldn't reify the instance correctly. In that case there is no disambiguity between one-shot and batch, simply both is missing the info.
I propose to solve this by enforcing a loading of all the interface files for every import transitively for the current module, when we meet an open type family or class reification request in template haskell's reify handler in TcSplice.hs
.
So I propose to keep the optimization of orphan instances and use it 99.9% of the time. We would only ever go on the quest of reading interface files for every import transitively when the user tries to reify something where we have to return an instance list. This means that TH compilations that reify types will get a little bit slower in exchange of being correct and unambiguous. Compilation time in cases when TH reification is not used will not change.
I volunteer to prepare the patch, but would like to hear others first.
So, any opinions, alternative ideas?
Trac metadata
Trac field | Value |
---|---|
Version | 7.6.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Template Haskell |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |