PageRenderTime 26ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/ghc-7.0.4/compiler/typecheck/FamInst.lhs

http://picorec.googlecode.com/
Haskell | 212 lines | 149 code | 35 blank | 28 comment | 6 complexity | 3b00772d92ba1201454e6adbcb2a9a5b MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. The @FamInst@ type: family instance heads
  2. \begin{code}
  3. module FamInst (
  4. checkFamInstConsistency, tcExtendLocalFamInstEnv, tcGetFamInstEnvs
  5. ) where
  6. import HscTypes
  7. import FamInstEnv
  8. import TcMType
  9. import TcRnMonad
  10. import TyCon
  11. import Name
  12. import Module
  13. import SrcLoc
  14. import Outputable
  15. import UniqFM
  16. import FastString
  17. import Maybes
  18. import Control.Monad
  19. import Data.Map (Map)
  20. import qualified Data.Map as Map
  21. \end{code}
  22. %************************************************************************
  23. %* *
  24. Optimised overlap checking for family instances
  25. %* *
  26. %************************************************************************
  27. For any two family instance modules that we import directly or indirectly, we
  28. check whether the instances in the two modules are consistent, *unless* we can
  29. be certain that the instances of the two modules have already been checked for
  30. consistency during the compilation of modules that we import.
  31. Why do we need to check? Consider
  32. module X1 where module X2 where
  33. data T1 data T2
  34. type instance F T1 b = Int type instance F a T2 = Char
  35. f1 :: F T1 a -> Int f2 :: Char -> F a T2
  36. f1 x = x f2 x = x
  37. Now if we import both X1 and X2 we could make (f2 . f1) :: Int -> Char.
  38. Notice that neither instance is an orphan.
  39. How do we know which pairs of modules have already been checked? Any pair of
  40. modules where both modules occur in the `HscTypes.dep_finsts' set (of the
  41. `HscTypes.Dependencies') of one of our directly imported modules must have
  42. already been checked. Everything else, we check now. (So that we can be
  43. certain that the modules in our `HscTypes.dep_finsts' are consistent.)
  44. \begin{code}
  45. -- The optimisation of overlap tests is based on determining pairs of modules
  46. -- whose family instances need to be checked for consistency.
  47. --
  48. data ModulePair = ModulePair Module Module
  49. -- canonical order of the components of a module pair
  50. --
  51. canon :: ModulePair -> (Module, Module)
  52. canon (ModulePair m1 m2) | m1 < m2 = (m1, m2)
  53. | otherwise = (m2, m1)
  54. instance Eq ModulePair where
  55. mp1 == mp2 = canon mp1 == canon mp2
  56. instance Ord ModulePair where
  57. mp1 `compare` mp2 = canon mp1 `compare` canon mp2
  58. -- Sets of module pairs
  59. --
  60. type ModulePairSet = Map ModulePair ()
  61. listToSet :: [ModulePair] -> ModulePairSet
  62. listToSet l = Map.fromList (zip l (repeat ()))
  63. checkFamInstConsistency :: [Module] -> [Module] -> TcM ()
  64. checkFamInstConsistency famInstMods directlyImpMods
  65. = do { dflags <- getDOpts
  66. ; (eps, hpt) <- getEpsAndHpt
  67. ; let { -- Fetch the iface of a given module. Must succeed as
  68. -- all imported modules must already have been loaded.
  69. modIface mod =
  70. case lookupIfaceByModule dflags hpt (eps_PIT eps) mod of
  71. Nothing -> panic "FamInst.checkFamInstConsistency"
  72. Just iface -> iface
  73. ; hmiModule = mi_module . hm_iface
  74. ; hmiFamInstEnv = mkFamInstEnv . md_fam_insts . hm_details
  75. ; mkFamInstEnv = extendFamInstEnvList emptyFamInstEnv
  76. ; hptModInsts = [ (hmiModule hmi, hmiFamInstEnv hmi)
  77. | hmi <- eltsUFM hpt]
  78. ; modInstsEnv = eps_mod_fam_inst_env eps -- external modules
  79. `extendModuleEnvList` -- plus
  80. hptModInsts -- home package modules
  81. ; groups = map (dep_finsts . mi_deps . modIface)
  82. directlyImpMods
  83. ; okPairs = listToSet $ concatMap allPairs groups
  84. -- instances of okPairs are consistent
  85. ; criticalPairs = listToSet $ allPairs famInstMods
  86. -- all pairs that we need to consider
  87. ; toCheckPairs = Map.keys $ criticalPairs `Map.difference` okPairs
  88. -- the difference gives us the pairs we need to check now
  89. }
  90. ; mapM_ (check modInstsEnv) toCheckPairs
  91. }
  92. where
  93. allPairs [] = []
  94. allPairs (m:ms) = map (ModulePair m) ms ++ allPairs ms
  95. -- The modules are guaranteed to be in the environment, as they are either
  96. -- already loaded in the EPS or they are in the HPT.
  97. --
  98. check modInstsEnv (ModulePair m1 m2)
  99. = let { instEnv1 = (expectJust "checkFamInstConsistency") . lookupModuleEnv modInstsEnv $ m1
  100. ; instEnv2 = (expectJust "checkFamInstConsistency") . lookupModuleEnv modInstsEnv $ m2
  101. ; insts1 = famInstEnvElts instEnv1
  102. }
  103. in
  104. mapM_ (checkForConflicts (emptyFamInstEnv, instEnv2)) insts1
  105. \end{code}
  106. %************************************************************************
  107. %* *
  108. Extending the family instance environment
  109. %* *
  110. %************************************************************************
  111. \begin{code}
  112. -- Add new locally-defined family instances
  113. tcExtendLocalFamInstEnv :: [FamInst] -> TcM a -> TcM a
  114. tcExtendLocalFamInstEnv fam_insts thing_inside
  115. = do { env <- getGblEnv
  116. ; inst_env' <- foldlM addLocalFamInst (tcg_fam_inst_env env) fam_insts
  117. ; let env' = env { tcg_fam_insts = fam_insts ++ tcg_fam_insts env,
  118. tcg_fam_inst_env = inst_env' }
  119. ; setGblEnv env' thing_inside
  120. }
  121. -- Check that the proposed new instance is OK,
  122. -- and then add it to the home inst env
  123. addLocalFamInst :: FamInstEnv -> FamInst -> TcM FamInstEnv
  124. addLocalFamInst home_fie famInst
  125. = do { -- Load imported instances, so that we report
  126. -- overlaps correctly
  127. ; eps <- getEps
  128. ; let inst_envs = (eps_fam_inst_env eps, home_fie)
  129. -- Check for conflicting instance decls
  130. ; checkForConflicts inst_envs famInst
  131. -- OK, now extend the envt
  132. ; return (extendFamInstEnv home_fie famInst)
  133. }
  134. \end{code}
  135. %************************************************************************
  136. %* *
  137. Checking an instance against conflicts with an instance env
  138. %* *
  139. %************************************************************************
  140. Check whether a single family instance conflicts with those in two instance
  141. environments (one for the EPS and one for the HPT).
  142. \begin{code}
  143. checkForConflicts :: (FamInstEnv, FamInstEnv) -> FamInst -> TcM ()
  144. checkForConflicts inst_envs famInst
  145. = do { -- To instantiate the family instance type, extend the instance
  146. -- envt with completely fresh template variables
  147. -- This is important because the template variables must
  148. -- not overlap with anything in the things being looked up
  149. -- (since we do unification).
  150. -- We use tcInstSkolType because we don't want to allocate
  151. -- fresh *meta* type variables.
  152. ; skol_tvs <- tcInstSkolTyVars (tyConTyVars (famInstTyCon famInst))
  153. ; let conflicts = lookupFamInstEnvConflicts inst_envs famInst skol_tvs
  154. ; unless (null conflicts) $
  155. conflictInstErr famInst (fst (head conflicts))
  156. }
  157. where
  158. conflictInstErr :: FamInst -> FamInst -> TcRn ()
  159. conflictInstErr famInst conflictingFamInst
  160. = addFamInstLoc famInst $
  161. addErr (hang (ptext (sLit "Conflicting family instance declarations:"))
  162. 2 (pprFamInsts [famInst, conflictingFamInst]))
  163. addFamInstLoc :: FamInst -> TcRn a -> TcRn a
  164. addFamInstLoc famInst thing_inside
  165. = setSrcSpan (mkSrcSpan loc loc) thing_inside
  166. where
  167. loc = getSrcLoc famInst
  168. \end{code}
  169. \begin{code}
  170. tcGetFamInstEnvs :: TcM (FamInstEnv, FamInstEnv)
  171. -- Gets both the external-package inst-env
  172. -- and the home-pkg inst env (includes module being compiled)
  173. tcGetFamInstEnvs
  174. = do { eps <- getEps; env <- getGblEnv
  175. ; return (eps_fam_inst_env eps, tcg_fam_inst_env env)
  176. }
  177. \end{code}