Confusing error when hs-boot abstract data implemented using synonym
This example is a little goofy (that's why I've marked it low priority), but here goes:
-- A.hs-boot
module A where
data T
f :: T -> T
-- B.hs
module B(f) where
import {-# SOURCE #-} A
-- A.hs
module A(T, f) where
import qualified B
type T = Int
f :: T -> T
f x = B.f x
When compiled, we get a very interesting error:
ezyang@sabre:~$ ghc-head --make A.hs -fforce-recomp
[1 of 3] Compiling A[boot] ( A.hs-boot, A.o-boot )
[2 of 3] Compiling B ( B.hs, B.o )
[3 of 3] Compiling A ( A.hs, A.o )
A.hs-boot:2:1: error:
Type constructor ‘T’ has conflicting definitions in the module
and its hs-boot file
Main module: type T = Int
Boot file: abstract T
|
2 | data T
| ^^^^^^
A.hs-boot:3:1: error:
Identifier ‘f’ has conflicting definitions in the module
and its hs-boot file
Main module: f :: T -> T
Boot file: f :: T -> T
The two types are different
|
3 | f :: T -> T
| ^^^^^^^^^^^
The first error is legitimate, but the second is puzzling. I believe the problem has to do with the fact that when we load the hs-boot file for checking, we knot-tie it against itself. Thus, the T referenced in "Boot file" is the one WITHOUT the type synonym unfolding, while the main module *does* have the type synonym unfolding.
Pretty-printing is horribly confusing in these situations, so it would be nice if we could give some better guidance here.
Trac metadata
Trac field | Value |
---|---|
Version | 8.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | low |
Resolution | Unresolved |
Component | Compiler (Type checker) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |