-tyConUnique :: TyCon -> Unique
-tyConUnique FunTyCon = funTyConKey
-tyConUnique (DataTyCon uniq _ _ _ _ _ _ _) = uniq
-tyConUnique (TupleTyCon uniq _ _) = uniq
-tyConUnique (PrimTyCon uniq _ _) = uniq
-tyConUnique (SynTyCon uniq _ _ _ _ _) = uniq
-tyConUnique (SpecTyCon _ _ ) = panic "tyConUnique:SpecTyCon"
-
-tyConArity :: TyCon -> Arity
-tyConArity FunTyCon = 2
-tyConArity (DataTyCon _ _ _ tvs _ _ _ _) = length tvs
-tyConArity (TupleTyCon _ _ arity) = arity
-tyConArity (PrimTyCon _ _ _) = 0 -- ??
-tyConArity (SpecTyCon _ _) = 0
-tyConArity (SynTyCon _ _ _ arity _ _) = arity
-
-synTyConArity :: TyCon -> Maybe Arity -- Nothing <=> not a syn tycon
-synTyConArity (SynTyCon _ _ _ arity _ _) = Just arity
-synTyConArity _ = Nothing
+isFunTyCon :: TyCon -> Bool
+isFunTyCon (FunTyCon {}) = True
+isFunTyCon _ = False
+
+isAbstractTyCon :: TyCon -> Bool
+isAbstractTyCon (AlgTyCon { algTcRhs = AbstractTyCon }) = True
+isAbstractTyCon _ = False
+
+makeTyConAbstract :: TyCon -> TyCon
+makeTyConAbstract tc@(AlgTyCon {}) = tc { algTcRhs = AbstractTyCon }
+makeTyConAbstract tc = pprPanic "makeTyConAbstract" (ppr tc)
+
+isPrimTyCon :: TyCon -> Bool
+isPrimTyCon (PrimTyCon {}) = True
+isPrimTyCon _ = False
+
+isUnLiftedTyCon :: TyCon -> Bool
+isUnLiftedTyCon (PrimTyCon {isUnLifted = is_unlifted}) = is_unlifted
+isUnLiftedTyCon (TupleTyCon {tyConBoxed = boxity}) = not (isBoxed boxity)
+isUnLiftedTyCon _ = False
+
+-- isAlgTyCon returns True for both @data@ and @newtype@
+isAlgTyCon :: TyCon -> Bool
+isAlgTyCon (AlgTyCon {}) = True
+isAlgTyCon (TupleTyCon {}) = True
+isAlgTyCon other = False
+
+isDataTyCon :: TyCon -> Bool
+-- isDataTyCon returns True for data types that are represented by
+-- heap-allocated constructors.
+-- These are srcutinised by Core-level @case@ expressions, and they
+-- get info tables allocated for them.
+-- True for all @data@ types
+-- False for newtypes
+-- unboxed tuples
+isDataTyCon tc@(AlgTyCon {algTcRhs = rhs})
+ = case rhs of
+ DataTyCon {} -> True
+ NewTyCon {} -> False
+ AbstractTyCon -> pprPanic "isDataTyCon" (ppr tc)
+
+isDataTyCon (TupleTyCon {tyConBoxed = boxity}) = isBoxed boxity
+isDataTyCon other = False
+
+isNewTyCon :: TyCon -> Bool
+isNewTyCon (AlgTyCon {algTcRhs = NewTyCon {}}) = True
+isNewTyCon other = False
+
+isProductTyCon :: TyCon -> Bool
+-- A "product" tycon
+-- has *one* constructor,
+-- is *not* existential
+-- but
+-- may be DataType or NewType,
+-- may be unboxed or not,
+-- may be recursive or not
+isProductTyCon tc@(AlgTyCon {}) = case algTcRhs tc of
+ DataTyCon{ data_cons = [data_con] }
+ -> isVanillaDataCon data_con
+ NewTyCon {} -> True
+ other -> False
+isProductTyCon (TupleTyCon {}) = True
+isProductTyCon other = False
+
+isSynTyCon :: TyCon -> Bool
+isSynTyCon (SynTyCon {}) = True
+isSynTyCon _ = False
+
+isEnumerationTyCon :: TyCon -> Bool
+isEnumerationTyCon (AlgTyCon {algTcRhs = DataTyCon { is_enum = res }}) = res
+isEnumerationTyCon other = False
+
+isTupleTyCon :: TyCon -> Bool
+-- The unit tycon didn't used to be classed as a tuple tycon
+-- but I thought that was silly so I've undone it
+-- If it can't be for some reason, it should be a AlgTyCon
+--
+-- NB: when compiling Data.Tuple, the tycons won't reply True to
+-- isTupleTyCon, becuase they are built as AlgTyCons. However they
+-- get spat into the interface file as tuple tycons, so I don't think
+-- it matters.
+isTupleTyCon (TupleTyCon {}) = True
+isTupleTyCon other = False
+
+isUnboxedTupleTyCon :: TyCon -> Bool
+isUnboxedTupleTyCon (TupleTyCon {tyConBoxed = boxity}) = not (isBoxed boxity)
+isUnboxedTupleTyCon other = False
+
+isBoxedTupleTyCon :: TyCon -> Bool
+isBoxedTupleTyCon (TupleTyCon {tyConBoxed = boxity}) = isBoxed boxity
+isBoxedTupleTyCon other = False
+
+tupleTyConBoxity tc = tyConBoxed tc
+
+isRecursiveTyCon :: TyCon -> Bool
+isRecursiveTyCon (AlgTyCon {algTcRec = Recursive}) = True
+isRecursiveTyCon other = False
+
+isHiBootTyCon :: TyCon -> Bool
+-- Used for knot-tying in hi-boot files
+isHiBootTyCon (AlgTyCon {algTcRhs = AbstractTyCon}) = True
+isHiBootTyCon other = False
+
+isForeignTyCon :: TyCon -> Bool
+-- isForeignTyCon identifies foreign-imported type constructors
+isForeignTyCon (PrimTyCon {tyConExtName = Just _}) = True
+isForeignTyCon other = False