2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1999
6 Analysis functions over data types. Specficially, detecting recursive types.
8 This stuff is only used for source-code decls; it's recorded in interface
9 files for imported data types.
14 calcClassCycles, calcSynCycles
17 #include "HsVersions.h"
37 %************************************************************************
39 Cycles in class and type synonym declarations
41 %************************************************************************
43 Checking for class-decl loops is easy, because we don't allow class decls
46 We allow type synonyms in hi-boot files, but we *trust* hi-boot files,
47 so we don't check for loops that involve them. So we only look for synonym
48 loops in the module being compiled.
50 We check for type synonym and class cycles on the *source* code.
53 a) Otherwise we'd need a special function to extract type-synonym tycons
54 from a type, whereas we have extractHsTyNames already
56 b) If we checked for type synonym loops after building the TyCon, we
57 can't do a hoistForAllTys on the type synonym rhs, (else we fall into
58 a black hole) which seems unclean. Apart from anything else, it'd mean
59 that a type-synonym rhs could have for-alls to the right of an arrow,
60 which means adding new cases to the validity checker
62 Indeed, in general, checking for cycles beforehand means we need to
63 be less careful about black holes through synonym cycles.
65 The main disadvantage is that a cycle that goes via a type synonym in an
66 .hi-boot file can lead the compiler into a loop, because it assumes that cycles
67 only occur entirely within the source code of the module being compiled.
68 But hi-boot files are trusted anyway, so this isn't much worse than (say)
71 [ NOTE ----------------------------------------------
72 If we reverse this decision, this comment came from tcTyDecl1, and should
74 -- dsHsType, not tcHsKindedType, to avoid a loop. tcHsKindedType does hoisting,
75 -- which requires looking through synonyms... and therefore goes into a loop
76 -- on (erroneously) recursive synonyms.
77 -- Solution: do not hoist synonyms, because they'll be hoisted soon enough
78 -- when they are substituted
80 We'd also need to add back in this definition
82 synTyConsOfType :: Type -> [TyCon]
83 -- Does not look through type synonyms at all
84 -- Return a list of synonym tycons
88 go :: Type -> NameEnv TyCon -- The NameEnv does duplicate elim
89 go (TyVarTy v) = emptyNameEnv
90 go (TyConApp tc tys) = go_tc tc tys
91 go (AppTy a b) = go a `plusNameEnv` go b
92 go (FunTy a b) = go a `plusNameEnv` go b
93 go (PredTy (IParam _ ty)) = go ty
94 go (PredTy (ClassP cls tys)) = go_s tys -- Ignore class
95 go (ForAllTy _ ty) = go ty
97 go_tc tc tys | isSynTyCon tc = extendNameEnv (go_s tys) (tyConName tc) tc
98 | otherwise = go_s tys
99 go_s tys = foldr (plusNameEnv . go) emptyNameEnv tys
100 ---------------------------------------- END NOTE ]
103 calcSynCycles :: [LTyClDecl Name] -> [SCC (LTyClDecl Name)]
105 = stronglyConnComp syn_edges
107 syn_edges = [ (ldecl, unLoc (tcdLName decl),
108 mk_syn_edges (tcdSynRhs decl))
109 | ldecl@(L _ decl) <- decls ]
111 mk_syn_edges rhs = [ tc | tc <- nameSetToList (extractHsTyNames rhs),
112 not (isTyVarName tc) ]
115 calcClassCycles :: [LTyClDecl Name] -> [[LTyClDecl Name]]
116 calcClassCycles decls
117 = [decls | CyclicSCC decls <- stronglyConnComp cls_edges]
119 cls_edges = [ (ldecl, unLoc (tcdLName decl),
120 mk_cls_edges (unLoc (tcdCtxt decl)))
121 | ldecl@(L _ decl) <- decls, isClassDecl decl ]
123 mk_cls_edges ctxt = [ cls | L _ (HsClassP cls _) <- ctxt ]
127 %************************************************************************
129 Deciding which type constructors are recursive
131 %************************************************************************
133 For newtypes, we label some as "recursive" such that
135 INVARIANT: there is no cycle of non-recursive newtypes
137 In any loop, only one newtype need be marked as recursive; it is
138 a "loop breaker". Labelling more than necessary as recursive is OK,
139 provided the invariant is maintained.
141 A newtype M.T is defined to be "recursive" iff
142 (a) it is declared in an hi-boot file (see RdrHsSyn.hsIfaceDecl)
143 (b) it is declared in a source file, but that source file has a
144 companion hi-boot file which declares the type
145 or (c) one can get from T's rhs to T via type
146 synonyms, or non-recursive newtypes *in M*
147 e.g. newtype T = MkT (T -> Int)
149 (a) is conservative; declarations in hi-boot files are always
150 made loop breakers. That's why in (b) we can restrict attention
151 to tycons in M, because any loops through newtypes outside M
152 will be broken by those newtypes
153 (b) ensures that a newtype is not treated as a loop breaker in one place
154 and later as a non-loop-breaker. This matters in GHCi particularly, when
155 a newtype T might be embedded in many types in the environment, and then
156 T's source module is compiled. We don't want T's recursiveness to change.
158 The "recursive" flag for algebraic data types is irrelevant (never consulted)
159 for types with more than one constructor.
161 An algebraic data type M.T is "recursive" iff
162 it has just one constructor, and
163 (a) it is declared in an hi-boot file (see RdrHsSyn.hsIfaceDecl)
164 (b) it is declared in a source file, but that source file has a
165 companion hi-boot file which declares the type
166 or (c) one can get from its arg types to T via type synonyms,
167 or by non-recursive newtypes or non-recursive product types in M
168 e.g. data T = MkT (T -> Int) Bool
169 Just like newtype in fact
171 A type synonym is recursive if one can get from its
172 right hand side back to it via type synonyms. (This is
173 reported as an error.)
175 A class is recursive if one can get from its superclasses
176 back to it. (This is an error too.)
180 A data type read from an hi-boot file will have an AbstractTyCon as its AlgTyConRhs
181 and will respond True to isHiBootTyCon. The idea is that we treat these as if one
182 could get from these types to anywhere. So when we see
185 import {-# SOURCE #-} Foo( T )
188 then we mark S as recursive, just in case. What that means is that if we see
193 then we don't need to look inside S to compute R's recursiveness. Since S is imported
194 (not from an hi-boot file), one cannot get from R back to S except via an hi-boot file,
195 and that means that some data type will be marked recursive along the way. So R is
196 unconditionly non-recursive (i.e. there'll be a loop breaker elsewhere if necessary)
198 This in turn means that we grovel through fewer interface files when computing
199 recursiveness, because we need only look at the type decls in the module being
200 compiled, plus the outer structure of directly-mentioned types.
203 calcRecFlags :: ModDetails -> [TyThing] -> (Name -> RecFlag)
204 -- The 'boot_names' are the things declared in M.hi-boot, if M is the current module.
205 -- Any type constructors in boot_names are automatically considered loop breakers
206 calcRecFlags boot_details tyclss
209 is_rec n | n `elemNameSet` rec_names = Recursive
210 | otherwise = NonRecursive
212 boot_name_set = availsToNameSet (md_exports boot_details)
213 rec_names = boot_name_set `unionNameSets`
214 nt_loop_breakers `unionNameSets`
217 all_tycons = [ tc | tycls <- tyclss,
218 -- Recursion of newtypes/data types can happen via
219 -- the class TyCon, so tyclss includes the class tycons
220 let tc = getTyCon tycls,
221 not (tyConName tc `elemNameSet` boot_name_set) ]
222 -- Remove the boot_name_set because they are going
223 -- to be loop breakers regardless.
225 -------------------------------------------------
227 -- These edge-construction loops rely on
228 -- every loop going via tyclss, the types and classes
229 -- in the module being compiled. Stuff in interface
230 -- files should be correctly marked. If not (e.g. a
231 -- type synonym in a hi-boot file) we can get an infinite
232 -- loop. We could program round this, but it'd make the code
233 -- rather less nice, so I'm not going to do that yet.
235 --------------- Newtypes ----------------------
236 new_tycons = filter isNewTyConAndNotOpen all_tycons
237 isNewTyConAndNotOpen tycon = isNewTyCon tycon && not (isOpenTyCon tycon)
238 nt_loop_breakers = mkNameSet (findLoopBreakers nt_edges)
239 is_rec_nt tc = tyConName tc `elemNameSet` nt_loop_breakers
240 -- is_rec_nt is a locally-used helper function
242 nt_edges = [(t, mk_nt_edges t) | t <- new_tycons]
244 mk_nt_edges nt -- Invariant: nt is a newtype
245 = concatMap (mk_nt_edges1 nt) (tcTyConsOfType (new_tc_rhs nt))
246 -- tyConsOfType looks through synonyms
249 | tc `elem` new_tycons = [tc] -- Loop
250 -- At this point we know that either it's a local *data* type,
251 -- or it's imported. Either way, it can't form part of a newtype cycle
254 --------------- Product types ----------------------
255 -- The "prod_tycons" are the non-newtype products
256 prod_tycons = [tc | tc <- all_tycons,
257 not (isNewTyCon tc), isProductTyCon tc]
258 prod_loop_breakers = mkNameSet (findLoopBreakers prod_edges)
260 prod_edges = [(tc, mk_prod_edges tc) | tc <- prod_tycons]
262 mk_prod_edges tc -- Invariant: tc is a product tycon
263 = concatMap (mk_prod_edges1 tc) (dataConOrigArgTys (head (tyConDataCons tc)))
265 mk_prod_edges1 ptc ty = concatMap (mk_prod_edges2 ptc) (tcTyConsOfType ty)
267 mk_prod_edges2 ptc tc
268 | tc `elem` prod_tycons = [tc] -- Local product
269 | tc `elem` new_tycons = if is_rec_nt tc -- Local newtype
271 else mk_prod_edges1 ptc (new_tc_rhs tc)
272 -- At this point we know that either it's a local non-product data type,
273 -- or it's imported. Either way, it can't form part of a cycle
276 new_tc_rhs :: TyCon -> Type
277 new_tc_rhs tc = snd (newTyConRhs tc) -- Ignore the type variables
279 getTyCon :: TyThing -> TyCon
280 getTyCon (ATyCon tc) = tc
281 getTyCon (AClass cl) = classTyCon cl
282 getTyCon _ = panic "getTyCon"
284 findLoopBreakers :: [(TyCon, [TyCon])] -> [Name]
285 -- Finds a set of tycons that cut all loops
286 findLoopBreakers deps
287 = go [(tc,tc,ds) | (tc,ds) <- deps]
290 | CyclicSCC ((tc,_,_) : edges') <- stronglyConnCompR edges,
291 name <- tyConName tc : go edges']
294 These two functions know about type representations, so they could be
295 in Type or TcType -- but they are very specialised to this module, so
296 I've chosen to put them here.
299 tcTyConsOfType :: Type -> [TyCon]
300 -- tcTyConsOfType looks through all synonyms, but not through any newtypes.
301 -- When it finds a Class, it returns the class TyCon. The reaons it's here
302 -- (not in Type.lhs) is because it is newtype-aware.
304 = nameEnvElts (go ty)
306 go :: Type -> NameEnv TyCon -- The NameEnv does duplicate elim
307 go ty | Just ty' <- tcView ty = go ty'
308 go (TyVarTy _) = emptyNameEnv
309 go (TyConApp tc tys) = go_tc tc tys
310 go (AppTy a b) = go a `plusNameEnv` go b
311 go (FunTy a b) = go a `plusNameEnv` go b
312 go (PredTy (IParam _ ty)) = go ty
313 go (PredTy (ClassP cls tys)) = go_tc (classTyCon cls) tys
314 go (ForAllTy _ ty) = go ty
315 go _ = panic "tcTyConsOfType"
317 go_tc tc tys = extendNameEnv (go_s tys) (tyConName tc) tc
318 go_s tys = foldr (plusNameEnv . go) emptyNameEnv tys