files for imported data types.
\begin{code}
-{-# OPTIONS -w #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and fix
--- any warnings in the module. See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
--- for details
-
module TcTyDecls(
calcRecFlags,
calcClassCycles, calcSynCycles
import BasicTypes
import SrcLoc
import Outputable
+import Util ( isSingleton )
+import Data.List
\end{code}
\begin{code}
calcSynCycles :: [LTyClDecl Name] -> [SCC (LTyClDecl Name)]
calcSynCycles decls
- = stronglyConnComp syn_edges
+ = stronglyConnCompFromEdgedVertices syn_edges
where
syn_edges = [ (ldecl, unLoc (tcdLName decl),
mk_syn_edges (tcdSynRhs decl))
calcClassCycles :: [LTyClDecl Name] -> [[LTyClDecl Name]]
calcClassCycles decls
- = [decls | CyclicSCC decls <- stronglyConnComp cls_edges]
+ = [decls | CyclicSCC decls <- stronglyConnCompFromEdgedVertices cls_edges]
where
cls_edges = [ (ldecl, unLoc (tcdLName decl),
mk_cls_edges (unLoc (tcdCtxt decl)))
-- loop. We could program round this, but it'd make the code
-- rather less nice, so I'm not going to do that yet.
+ single_con_tycons = filter (isSingleton . tyConDataCons) all_tycons
+ -- Both newtypes and data types, with exactly one data constructor
+ (new_tycons, prod_tycons) = partition isNewTyCon single_con_tycons
+ -- NB: we do *not* call isProductTyCon because that checks
+ -- for vanilla-ness of data constructors; and that depends
+ -- on empty existential type variables; and that is figured
+ -- out by tcResultType; which uses tcMatchTy; which uses
+ -- coreView; which calls coreExpandTyCon_maybe; which uses
+ -- the recursiveness of the TyCon. Result... a black hole.
+ -- YUK YUK YUK
+
--------------- Newtypes ----------------------
- new_tycons = filter isNewTyConAndNotOpen all_tycons
- isNewTyConAndNotOpen tycon = isNewTyCon tycon && not (isOpenTyCon tycon)
nt_loop_breakers = mkNameSet (findLoopBreakers nt_edges)
is_rec_nt tc = tyConName tc `elemNameSet` nt_loop_breakers
-- is_rec_nt is a locally-used helper function
= concatMap (mk_nt_edges1 nt) (tcTyConsOfType (new_tc_rhs nt))
-- tyConsOfType looks through synonyms
- mk_nt_edges1 nt tc
+ mk_nt_edges1 _ tc
| tc `elem` new_tycons = [tc] -- Loop
-- At this point we know that either it's a local *data* type,
-- or it's imported. Either way, it can't form part of a newtype cycle
| otherwise = []
--------------- Product types ----------------------
- -- The "prod_tycons" are the non-newtype products
- prod_tycons = [tc | tc <- all_tycons,
- not (isNewTyCon tc), isProductTyCon tc]
prod_loop_breakers = mkNameSet (findLoopBreakers prod_edges)
prod_edges = [(tc, mk_prod_edges tc) | tc <- prod_tycons]
-- or it's imported. Either way, it can't form part of a cycle
| otherwise = []
+new_tc_rhs :: TyCon -> Type
new_tc_rhs tc = snd (newTyConRhs tc) -- Ignore the type variables
+getTyCon :: TyThing -> TyCon
getTyCon (ATyCon tc) = tc
getTyCon (AClass cl) = classTyCon cl
-getTyCon other = panic "getTyCon"
+getTyCon _ = panic "getTyCon"
findLoopBreakers :: [(TyCon, [TyCon])] -> [Name]
-- Finds a set of tycons that cut all loops
= go [(tc,tc,ds) | (tc,ds) <- deps]
where
go edges = [ name
- | CyclicSCC ((tc,_,_) : edges') <- stronglyConnCompR edges,
+ | CyclicSCC ((tc,_,_) : edges') <- stronglyConnCompFromEdgedVerticesR edges,
name <- tyConName tc : go edges']
\end{code}
where
go :: Type -> NameEnv TyCon -- The NameEnv does duplicate elim
go ty | Just ty' <- tcView ty = go ty'
- go (TyVarTy v) = emptyNameEnv
+ go (TyVarTy _) = emptyNameEnv
go (TyConApp tc tys) = go_tc tc tys
go (AppTy a b) = go a `plusNameEnv` go b
go (FunTy a b) = go a `plusNameEnv` go b
go (PredTy (IParam _ ty)) = go ty
go (PredTy (ClassP cls tys)) = go_tc (classTyCon cls) tys
go (ForAllTy _ ty) = go ty
- go other = panic "tcTyConsOfType"
+ go _ = panic "tcTyConsOfType"
go_tc tc tys = extendNameEnv (go_s tys) (tyConName tc) tc
go_s tys = foldr (plusNameEnv . go) emptyNameEnv tys