Revert "Generate Typeable info at definition sites"
[ghc.git] / compiler / types / TyCon.hs
index 2159845..465ccb1 100644 (file)
@@ -13,8 +13,8 @@ module TyCon(
         TyCon,
 
         AlgTyConRhs(..), visibleDataCons,
-        AlgTyConFlav(..), isNoParent,
-        FamTyConFlav(..), Role(..), Promoted(..), Injectivity(..),
+        TyConParent(..), isNoParent,
+        FamTyConFlav(..), Role(..), Injectivity(..),
 
         -- ** Field labels
         tyConFieldLabels, tyConFieldLabelEnv,
@@ -42,7 +42,7 @@ module TyCon(
         mightBeUnsaturatedTyCon,
         isPromotedDataCon, isPromotedTyCon,
         isPromotedDataCon_maybe, isPromotedTyCon_maybe,
-        promotableTyCon_maybe, isPromotableTyCon, promoteTyCon,
+        promotableTyCon_maybe, promoteTyCon,
 
         isDataTyCon, isProductTyCon, isDataProductTyCon_maybe,
         isEnumerationTyCon,
@@ -71,6 +71,7 @@ module TyCon(
         tyConStupidTheta,
         tyConArity,
         tyConRoles,
+        tyConParent,
         tyConFlavour,
         tyConTuple_maybe, tyConClass_maybe,
         tyConFamInst_maybe, tyConFamInstSig_maybe, tyConFamilyCoercion_maybe,
@@ -88,9 +89,6 @@ module TyCon(
         newTyConCo, newTyConCo_maybe,
         pprPromotionQuote,
 
-        -- * Runtime type representation
-        TyConRepName, tyConRepName_maybe,
-
         -- * Primitive representations of Types
         PrimRep(..), PrimElemRep(..),
         tyConPrimRep, isVoidRep, isGcPtrRep,
@@ -192,8 +190,8 @@ See also Note [Wrappers for data instance tycons] in MkId.hs
 
   Note that this is a *representational* coercion
   The R:TInt is the "representation TyCons".
-  It has an AlgTyConFlav of
-        DataFamInstTyCon T [Int] ax_ti
+  It has an AlgTyConParent of
+        FamInstTyCon T [Int] ax_ti
 
 * The axiom ax_ti may be eta-reduced; see
   Note [Eta reduction for data family axioms] in TcInstDcls
@@ -225,9 +223,9 @@ See also Note [Wrappers for data instance tycons] in MkId.hs
   data instance declaration for T (a,b), to get the result type in the
   representation; e.g.  T (a,b) --> R:TPair a b
 
-  The representation TyCon R:TList, has an AlgTyConFlav of
+  The representation TyCon R:TList, has an AlgTyConParent of
 
-        DataFamInstTyCon T [(a,b)] ax_pr
+        FamInstTyCon T [(a,b)] ax_pr
 
 * Notice that T is NOT translated to a FC type function; it just
   becomes a "data type" with no constructors, which can be coerced inot
@@ -271,7 +269,7 @@ See also Note [Wrappers for data instance tycons] in MkId.hs
 Note [Associated families and their parent class]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *Associated* families are just like *non-associated* families, except
-that they have a famTcParent field of (Just cls), which identifies the
+that they have a TyConParent of AssocFamilyTyCon, which identifies the
 parent class.
 
 However there is an important sharing relationship between
@@ -377,26 +375,15 @@ data TyCon
         tyConKind   :: Kind,     -- ^ Kind of this TyCon (full kind, not just
                                  -- the return kind)
 
-        tyConArity  :: Arity,    -- ^ Number of arguments this TyCon must
+        tyConArity  :: Arity     -- ^ Number of arguments this TyCon must
                                  -- receive to be considered saturated
                                  -- (including implicit kind variables)
-
-        tcRepName :: TyConRepName
     }
 
-  -- | Algebraic data types, from
-  --     - @data@ declararations
-  --     - @newtype@ declarations
-  --     - data instance declarations
-  --     - type instance declarations
-  --     - the TyCon generated by a class declaration
-  --     - boxed tuples
-  --     - unboxed tuples
-  --     - constraint tuples
-  -- All these constructors are lifted and boxed except unboxed tuples
-  -- which should have an 'UnboxedAlgTyCon' parent.
-  -- Data/newtype/type /families/ are handled by 'FamilyTyCon'.
-  -- See 'AlgTyConRhs' for more information.
+  -- | Algebraic type constructors, which are defined to be those
+  -- arising @data@ type and @newtype@ declarations.  All these
+  -- constructors are lifted and boxed. See 'AlgTyConRhs' for more
+  -- information.
   | AlgTyCon {
         tyConUnique  :: Unique,  -- ^ A Unique of this TyCon. Invariant:
                                  -- identical to Unique of Name stored in
@@ -453,11 +440,12 @@ data TyCon
         algTcRec    :: RecFlag,     -- ^ Tells us whether the data type is part
                                     -- of a mutually-recursive group or not
 
-        algTcParent :: AlgTyConFlav, -- ^ Gives the class or family declaration
-                                       -- 'TyCon' for derived 'TyCon's representing
-                                       -- class or family instances, respectively.
+        algTcParent :: TyConParent, -- ^ Gives the class or family declaration
+                                    -- 'TyCon' for derived 'TyCon's representing
+                                    -- class or family instances, respectively.
+                                    -- See also 'synTcParent'
 
-        tcPromoted  :: Promoted TyCon  -- ^ Promoted TyCon, if any
+        tcPromoted  :: Maybe TyCon  -- ^ Promoted TyCon, if any
     }
 
   -- | Represents type synonyms
@@ -487,8 +475,7 @@ data TyCon
                                  -- of the synonym
     }
 
-  -- | Represents families (both type and data)
-  -- Argument roles are all Nominal
+  -- | Represents type families
   | FamilyTyCon {
         tyConUnique  :: Unique,  -- ^ A Unique of this TyCon. Invariant:
                                  -- identical to Unique of Name stored in
@@ -509,7 +496,7 @@ data TyCon
                                  -- Precisely, this list scopes over:
                                  --
                                  -- 1. The 'algTcStupidTheta'
-                                 -- 2. The cached types in 'algTyConRhs.NewTyCon'
+                                 -- 2. The cached types in algTyConRhs.NewTyCon
                                  -- 3. The family instance types if present
                                  --
                                  -- Note that it does /not/ scope over the data
@@ -524,9 +511,8 @@ data TyCon
                                       -- abstract, built-in. See comments for
                                       -- FamTyConFlav
 
-        famTcParent  :: Maybe Class,  -- ^ For *associated* type/data families
-                                      -- The class in whose declaration the family is declared
-                                      -- See Note [Associated families and their parent class]
+        famTcParent  :: TyConParent,  -- ^ TyCon of enclosing class for
+                                      -- associated type families
 
         famTcInj     :: Injectivity   -- ^ is this a type family injective in
                                       -- its type variables? Nothing if no
@@ -535,7 +521,7 @@ data TyCon
 
   -- | Primitive types; cannot be defined in Haskell. This includes
   -- the usual suspects (such as @Int#@) as well as foreign-imported
-  -- types and kinds (@*@, @#@, and @?@)
+  -- types and kinds
   | PrimTyCon {
         tyConUnique   :: Unique, -- ^ A Unique of this TyCon. Invariant:
                                  -- identical to Unique of Name stored in
@@ -559,13 +545,9 @@ data TyCon
                                  -- pointers). This 'PrimRep' holds that
                                  -- information.  Only relevant if tyConKind = *
 
-        isUnLifted   :: Bool,    -- ^ Most primitive tycons are unlifted (may
+        isUnLifted   :: Bool     -- ^ Most primitive tycons are unlifted (may
                                  -- not contain bottom) but other are lifted,
                                  -- e.g. @RealWorld@
-                                 -- Only relevant if tyConKind = *
-
-        primRepName :: Maybe TyConRepName   -- Only relevant for kind TyCons
-                                            -- i.e, *, #, ?
     }
 
   -- | Represents promoted data constructor.
@@ -575,8 +557,7 @@ data TyCon
         tyConArity  :: Arity,
         tyConKind   :: Kind,   -- ^ Translated type of the data constructor
         tcRoles     :: [Role], -- ^ Roles: N for kind vars, R for type vars
-        dataCon     :: DataCon,-- ^ Corresponding data constructor
-        tcRepName   :: TyConRepName
+        dataCon     :: DataCon -- ^ Corresponding data constructor
     }
 
   -- | Represents promoted type constructor.
@@ -585,8 +566,7 @@ data TyCon
         tyConName   :: Name,   -- ^ Same Name as the type constructor
         tyConArity  :: Arity,  -- ^ n if ty_con :: * -> ... -> *  n times
         tyConKind   :: Kind,   -- ^ Always TysPrim.superKind
-        ty_con      :: TyCon,  -- ^ Corresponding type constructor
-        tcRepName   :: TyConRepName
+        ty_con      :: TyCon   -- ^ Corresponding type constructor
     }
 
   deriving Typeable
@@ -602,6 +582,20 @@ data AlgTyConRhs
       Bool      -- True  <=> It's definitely a distinct data type,
                 --           equal only to itself; ie not a newtype
                 -- False <=> Not sure
+                -- See Note [AbstractTyCon and type equality]
+
+    -- | Represents an open type family without a fixed right hand
+    -- side.  Additional instances can appear at any time.
+    --
+    -- These are introduced by either a top level declaration:
+    --
+    -- > data T a :: *
+    --
+    -- Or an associated data type declaration, within a class declaration:
+    --
+    -- > class C a b where
+    -- >   data T b :: *
+  | DataFamilyTyCon
 
     -- | Information about those 'TyCon's derived from a @data@
     -- declaration. This includes data types with no constructors at
@@ -655,15 +649,18 @@ data AlgTyConRhs
                              -- again check Trac #1072.
     }
 
--- | Isomorphic to Maybe, but used when the question is
--- whether or not something is promoted
-data Promoted a = NotPromoted | Promoted a
+{-
+Note [AbstractTyCon and type equality]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+TODO
+-}
 
 -- | Extract those 'DataCon's that we are able to learn about.  Note
 -- that visibility in this sense does not correspond to visibility in
 -- the context of any particular user program!
 visibleDataCons :: AlgTyConRhs -> [DataCon]
 visibleDataCons (AbstractTyCon {})            = []
+visibleDataCons DataFamilyTyCon {}            = []
 visibleDataCons (DataTyCon{ data_cons = cs }) = cs
 visibleDataCons (NewTyCon{ data_con = c })    = [c]
 visibleDataCons (TupleTyCon{ data_con = c })  = [c]
@@ -671,35 +668,26 @@ visibleDataCons (TupleTyCon{ data_con = c })  = [c]
 -- ^ Both type classes as well as family instances imply implicit
 -- type constructors.  These implicit type constructors refer to their parent
 -- structure (ie, the class or family from which they derive) using a type of
--- the following form.
-data AlgTyConFlav
+-- the following form.  We use 'TyConParent' for both algebraic and synonym
+-- types, but the variant 'ClassTyCon' will only be used by algebraic 'TyCon's.
+data TyConParent
   = -- | An ordinary type constructor has no parent.
-    VanillaAlgTyCon
-       TyConRepName
-
-    -- | An unboxed type constructor. Note that this carries no TyConRepName
-    -- as it is not representable.
-  | UnboxedAlgTyCon
+    NoParentTyCon
 
   -- | Type constructors representing a class dictionary.
   -- See Note [ATyCon for classes] in TypeRep
   | ClassTyCon
         Class           -- INVARIANT: the classTyCon of this Class is the
                         -- current tycon
-        TyConRepName
-
-  -- | Type constructors representing an *instance* of a *data* family.
-  -- Parameters:
-  --
-  --  1) The type family in question
-  --
-  --  2) Instance types; free variables are the 'tyConTyVars'
-  --  of the current 'TyCon' (not the family one). INVARIANT:
-  --  the number of types matches the arity of the family 'TyCon'
-  --
-  --  3) A 'CoTyCon' identifying the representation
-  --  type with the type instance family
-  | DataFamInstTyCon          -- See Note [Data type families]
+
+  -- | An *associated* type of a class.
+  | AssocFamilyTyCon
+        Class           -- The class in whose declaration the family is declared
+                        -- See Note [Associated families and their parent class]
+
+  -- | Type constructors representing an instance of a *data* family.
+  -- See Note [Data type families] and source comments for more info.
+  | FamInstTyCon          -- See Note [Data type families]
         (CoAxiom Unbranched)  -- The coercion axiom.
                -- A *Representational* coercion,
                -- of kind   T ty1 ty2   ~R   R:T a b c
@@ -720,26 +708,27 @@ data AlgTyConFlav
         -- gives a representation tycon:
         --      data R:TList a = ...
         --      axiom co a :: T [a] ~ R:TList a
-        -- with R:TList's algTcParent = DataFamInstTyCon T [a] co
-
-instance Outputable AlgTyConFlav where
-    ppr (VanillaAlgTyCon {})        = text "Vanilla ADT"
-    ppr (UnboxedAlgTyCon {})        = text "Unboxed ADT"
-    ppr (ClassTyCon cls _)          = text "Class parent" <+> ppr cls
-    ppr (DataFamInstTyCon _ tc tys) =
+        -- with R:TList's algTcParent = FamInstTyCon T [a] co
+
+instance Outputable TyConParent where
+    ppr NoParentTyCon           = text "No parent"
+    ppr (ClassTyCon cls)        = text "Class parent" <+> ppr cls
+    ppr (AssocFamilyTyCon cls)  =
+        text "Class parent (assoc. family)" <+> ppr cls
+    ppr (FamInstTyCon _ tc tys) =
         text "Family parent (family instance)" <+> ppr tc <+> sep (map ppr tys)
 
--- | Checks the invariants of a 'AlgTyConFlav' given the appropriate type class
+-- | Checks the invariants of a 'TyConParent' given the appropriate type class
 -- name, if any
-okParent :: Name -> AlgTyConFlav -> Bool
-okParent _       (VanillaAlgTyCon {})            = True
-okParent _       (UnboxedAlgTyCon)               = True
-okParent tc_name (ClassTyCon cls _)              = tc_name == tyConName (classTyCon cls)
-okParent _       (DataFamInstTyCon _ fam_tc tys) = tyConArity fam_tc == length tys
+okParent :: Name -> TyConParent -> Bool
+okParent _       NoParentTyCon               = True
+okParent tc_name (AssocFamilyTyCon cls)      = tc_name `elem` map tyConName (classATs cls)
+okParent tc_name (ClassTyCon cls)            = tc_name == tyConName (classTyCon cls)
+okParent _       (FamInstTyCon _ fam_tc tys) = tyConArity fam_tc == length tys
 
-isNoParent :: AlgTyConFlav -> Bool
-isNoParent (VanillaAlgTyCon {}) = True
-isNoParent _                   = False
+isNoParent :: TyConParent -> Bool
+isNoParent NoParentTyCon = True
+isNoParent _             = False
 
 --------------------
 
@@ -750,22 +739,8 @@ data Injectivity
 
 -- | Information pertaining to the expansion of a type synonym (@type@)
 data FamTyConFlav
-  = -- | Represents an open type family without a fixed right hand
-    -- side.  Additional instances can appear at any time.
-    --
-    -- These are introduced by either a top level declaration:
-    --
-    -- > data T a :: *
-    --
-    -- Or an associated data type declaration, within a class declaration:
-    --
-    -- > class C a b where
-    -- >   data T b :: *
-     DataFamilyTyCon
-       TyConRepName
-
-     -- | An open type synonym family  e.g. @type family F x y :: * -> *@
-   | OpenSynFamilyTyCon
+  = -- | An open type synonym family  e.g. @type family F x y :: * -> *@
+     OpenSynFamilyTyCon
 
    -- | A closed type synonym family  e.g.
    -- @type family F x where { F Int = Bool }@
@@ -903,34 +878,7 @@ so the coercion tycon CoT must have
 
 ************************************************************************
 *                                                                      *
-                 TyConRepName
-*                                                                      *
-********************************************************************* -}
-
-type TyConRepName = Name -- The Name of the top-level declaration
-                         --    $tcMaybe :: Data.Typeable.Internal.TyCon
-                         --    $tcMaybe = TyCon { tyConName = "Maybe", ... }
-
-tyConRepName_maybe :: TyCon -> Maybe TyConRepName
-tyConRepName_maybe (FunTyCon   { tcRepName = rep_nm })
-  = Just rep_nm
-tyConRepName_maybe (PrimTyCon  { primRepName = mb_rep_nm })
-  = mb_rep_nm
-tyConRepName_maybe (AlgTyCon { algTcParent = parent })
-  | VanillaAlgTyCon rep_nm <- parent = Just rep_nm
-  | ClassTyCon _ rep_nm    <- parent = Just rep_nm
-tyConRepName_maybe (FamilyTyCon { famTcFlav = DataFamilyTyCon rep_nm })
-  = Just rep_nm
-tyConRepName_maybe (PromotedDataCon { tcRepName = rep_nm })
-  = Just rep_nm
-tyConRepName_maybe (PromotedTyCon { tcRepName = rep_nm })
-  = Just rep_nm
-tyConRepName_maybe _ = Nothing
-
-
-{- *********************************************************************
-*                                                                      *
-                 PrimRep
+\subsection{PrimRep}
 *                                                                      *
 ************************************************************************
 
@@ -1114,14 +1062,13 @@ So we compromise, and move their Kind calculation to the call site.
 -- | Given the name of the function type constructor and it's kind, create the
 -- corresponding 'TyCon'. It is reccomended to use 'TypeRep.funTyCon' if you want
 -- this functionality
-mkFunTyCon :: Name -> Kind -> Name -> TyCon
-mkFunTyCon name kind rep_nm
+mkFunTyCon :: Name -> Kind -> TyCon
+mkFunTyCon name kind
   = FunTyCon {
         tyConUnique = nameUnique name,
         tyConName   = name,
         tyConKind   = kind,
-        tyConArity  = 2,
-        tcRepName   = rep_nm
+        tyConArity  = 2
     }
 
 -- | This is the making of an algebraic 'TyCon'. Notably, you have to
@@ -1137,12 +1084,11 @@ mkAlgTyCon :: Name
            -> Maybe CType       -- ^ The C type this type corresponds to
                                 --   when using the CAPI FFI
            -> [PredType]        -- ^ Stupid theta: see 'algTcStupidTheta'
-           -> AlgTyConRhs       -- ^ Information about data constructors
-           -> AlgTyConFlav      -- ^ What flavour is it?
-                                -- (e.g. vanilla, type family)
+           -> AlgTyConRhs       -- ^ Information about dat aconstructors
+           -> TyConParent
            -> RecFlag           -- ^ Is the 'TyCon' recursive?
            -> Bool              -- ^ Was the 'TyCon' declared with GADT syntax?
-           -> Promoted TyCon    -- ^ Promoted version
+           -> Maybe TyCon       -- ^ Promoted version
            -> TyCon
 mkAlgTyCon name kind tyvars roles cType stupid rhs parent is_rec gadt_syn prom_tc
   = AlgTyCon {
@@ -1164,12 +1110,11 @@ mkAlgTyCon name kind tyvars roles cType stupid rhs parent is_rec gadt_syn prom_t
 
 -- | Simpler specialization of 'mkAlgTyCon' for classes
 mkClassTyCon :: Name -> Kind -> [TyVar] -> [Role] -> AlgTyConRhs -> Class
-             -> RecFlag -> Name -> TyCon
-mkClassTyCon name kind tyvars roles rhs clas is_rec tc_rep_name
-  = mkAlgTyCon name kind tyvars roles Nothing [] rhs
-               (ClassTyCon clas tc_rep_name)
+             -> RecFlag -> TyCon
+mkClassTyCon name kind tyvars roles rhs clas is_rec
+  = mkAlgTyCon name kind tyvars roles Nothing [] rhs (ClassTyCon clas)
                is_rec False
-               NotPromoted    -- Class TyCons are not promoted
+               Nothing    -- Class TyCons are not promoted
 
 mkTupleTyCon :: Name
              -> Kind    -- ^ Kind of the resulting 'TyCon'
@@ -1177,8 +1122,8 @@ mkTupleTyCon :: Name
              -> [TyVar] -- ^ 'TyVar's scoped over: see 'tyConTyVars'
              -> DataCon
              -> TupleSort    -- ^ Whether the tuple is boxed or unboxed
-             -> Promoted TyCon  -- ^ Promoted version
-             -> AlgTyConFlav
+             -> Maybe TyCon  -- ^ Promoted version
+             -> TyConParent
              -> TyCon
 mkTupleTyCon name kind arity tyvars con sort prom_tc parent
   = AlgTyCon {
@@ -1190,8 +1135,7 @@ mkTupleTyCon name kind arity tyvars con sort prom_tc parent
         tcRoles          = replicate arity Representational,
         tyConCType       = Nothing,
         algTcStupidTheta = [],
-        algTcRhs         = TupleTyCon { data_con = con,
-                                        tup_sort = sort },
+        algTcRhs         = TupleTyCon { data_con = con, tup_sort = sort },
         algTcFields      = emptyFsEnv,
         algTcParent      = parent,
         algTcRec         = NonRecursive,
@@ -1202,21 +1146,20 @@ mkTupleTyCon name kind arity tyvars con sort prom_tc parent
 -- | Create an unlifted primitive 'TyCon', such as @Int#@
 mkPrimTyCon :: Name  -> Kind -> [Role] -> PrimRep -> TyCon
 mkPrimTyCon name kind roles rep
-  = mkPrimTyCon' name kind roles rep True Nothing
+  = mkPrimTyCon' name kind roles rep True
 
 -- | Kind constructors
-mkKindTyCon :: Name -> Kind -> Name -> TyCon
-mkKindTyCon name kind rep_nm
-  = mkPrimTyCon' name kind [] VoidRep True (Just rep_nm)
+mkKindTyCon :: Name -> Kind -> TyCon
+mkKindTyCon name kind
+  = mkPrimTyCon' name kind [] VoidRep True
 
 -- | Create a lifted primitive 'TyCon' such as @RealWorld@
 mkLiftedPrimTyCon :: Name  -> Kind -> [Role] -> PrimRep -> TyCon
 mkLiftedPrimTyCon name kind roles rep
-  = mkPrimTyCon' name kind roles rep False Nothing
+  = mkPrimTyCon' name kind roles rep False
 
-mkPrimTyCon' :: Name  -> Kind -> [Role] -> PrimRep
-             -> Bool -> Maybe TyConRepName -> TyCon
-mkPrimTyCon' name kind roles rep is_unlifted rep_nm
+mkPrimTyCon' :: Name  -> Kind -> [Role] -> PrimRep -> Bool -> TyCon
+mkPrimTyCon' name kind roles rep is_unlifted
   = PrimTyCon {
         tyConName    = name,
         tyConUnique  = nameUnique name,
@@ -1224,8 +1167,7 @@ mkPrimTyCon' name kind roles rep is_unlifted rep_nm
         tyConArity   = length roles,
         tcRoles      = roles,
         primTyConRep = rep,
-        isUnLifted   = is_unlifted,
-        primRepName  = rep_nm
+        isUnLifted   = is_unlifted
     }
 
 -- | Create a type synonym 'TyCon'
@@ -1243,7 +1185,7 @@ mkSynonymTyCon name kind tyvars roles rhs
 
 -- | Create a type family 'TyCon'
 mkFamilyTyCon:: Name -> Kind -> [TyVar] -> Maybe Name -> FamTyConFlav
-             -> Maybe Class -> Injectivity -> TyCon
+             -> TyConParent -> Injectivity -> TyCon
 mkFamilyTyCon name kind tyvars resVar flav parent inj
   = FamilyTyCon
       { tyConUnique = nameUnique name
@@ -1262,16 +1204,15 @@ mkFamilyTyCon name kind tyvars resVar flav parent inj
 -- Somewhat dodgily, we give it the same Name
 -- as the data constructor itself; when we pretty-print
 -- the TyCon we add a quote; see the Outputable TyCon instance
-mkPromotedDataCon :: DataCon -> Name -> TyConRepName -> Kind -> [Role] -> TyCon
-mkPromotedDataCon con name rep_name kind roles
+mkPromotedDataCon :: DataCon -> Name -> Unique -> Kind -> [Role] -> TyCon
+mkPromotedDataCon con name unique kind roles
   = PromotedDataCon {
-        tyConUnique = nameUnique name,
         tyConName   = name,
+        tyConUnique = unique,
         tyConArity  = arity,
         tcRoles     = roles,
         tyConKind   = kind,
-        dataCon     = con,
-        tcRepName   = rep_name
+        dataCon     = con
   }
   where
     arity = length roles
@@ -1286,11 +1227,7 @@ mkPromotedTyCon tc kind
         tyConUnique = getUnique tc,
         tyConArity  = tyConArity tc,
         tyConKind   = kind,
-        ty_con      = tc,
-        tcRepName   = case tyConRepName_maybe tc of
-                        Just rep_nm -> rep_nm
-                        Nothing     -> pprPanic "mkPromotedTyCon" (ppr tc)
-                      -- Promoted TyCons always have a TyConRepName
+        ty_con      = tc
   }
 
 isFunTyCon :: TyCon -> Bool
@@ -1347,6 +1284,7 @@ isDataTyCon (AlgTyCon {algTcRhs = rhs})
                            -> isBoxed (tupleSortBoxity sort)
         DataTyCon {}       -> True
         NewTyCon {}        -> False
+        DataFamilyTyCon {} -> False
         AbstractTyCon {}   -> False      -- We don't know, so return False
 isDataTyCon _ = False
 
@@ -1362,8 +1300,7 @@ isInjectiveTyCon (AlgTyCon {})                 Nominal          = True
 isInjectiveTyCon (AlgTyCon {algTcRhs = rhs})   Representational
   = isGenInjAlgRhs rhs
 isInjectiveTyCon (SynonymTyCon {})             _                = False
-isInjectiveTyCon (FamilyTyCon {famTcFlav = flav}) Nominal       = isDataFamFlav flav
-isInjectiveTyCon (FamilyTyCon {})              Representational = False
+isInjectiveTyCon (FamilyTyCon {})              _                = False
 isInjectiveTyCon (PrimTyCon {})                _                = True
 isInjectiveTyCon (PromotedDataCon {})          _                = True
 isInjectiveTyCon (PromotedTyCon {ty_con = tc}) r
@@ -1383,6 +1320,7 @@ isGenerativeTyCon = isInjectiveTyCon
 isGenInjAlgRhs :: AlgTyConRhs -> Bool
 isGenInjAlgRhs (TupleTyCon {})          = True
 isGenInjAlgRhs (DataTyCon {})           = True
+isGenInjAlgRhs (DataFamilyTyCon {})     = False
 isGenInjAlgRhs (AbstractTyCon distinct) = distinct
 isGenInjAlgRhs (NewTyCon {})            = False
 
@@ -1471,7 +1409,8 @@ isTypeSynonymTyCon _                 = False
 -- right hand side to which a synonym family application can expand.
 --
 
--- | True iff we can decompose (T a b c) into ((T a b) c)
+mightBeUnsaturatedTyCon :: TyCon -> Bool
+-- True iff we can decompose (T a b c) into ((T a b) c)
 --   I.e. is it injective and generative w.r.t nominal equality?
 --   That is, if (T a b) ~N d e f, is it always the case that
 --            (T ~N d), (a ~N e) and (b ~N f)?
@@ -1480,9 +1419,8 @@ isTypeSynonymTyCon _                 = False
 -- It'd be unusual to call mightBeUnsaturatedTyCon on a regular H98
 -- type synonym, because you should probably have expanded it first
 -- But regardless, it's not decomposable
-mightBeUnsaturatedTyCon :: TyCon -> Bool
 mightBeUnsaturatedTyCon (SynonymTyCon {}) = False
-mightBeUnsaturatedTyCon (FamilyTyCon  { famTcFlav = flav}) = isDataFamFlav flav
+mightBeUnsaturatedTyCon (FamilyTyCon  {}) = False
 mightBeUnsaturatedTyCon _other            = True
 
 -- | Is this an algebraic 'TyCon' declared with the GADT syntax?
@@ -1502,26 +1440,21 @@ isEnumerationTyCon _ = False
 
 -- | Is this a 'TyCon', synonym or otherwise, that defines a family?
 isFamilyTyCon :: TyCon -> Bool
-isFamilyTyCon (FamilyTyCon {}) = True
-isFamilyTyCon _                = False
+isFamilyTyCon (FamilyTyCon {})                           = True
+isFamilyTyCon (AlgTyCon {algTcRhs = DataFamilyTyCon {}}) = True
+isFamilyTyCon _                                          = False
 
 -- | Is this a 'TyCon', synonym or otherwise, that defines a family with
 -- instances?
 isOpenFamilyTyCon :: TyCon -> Bool
-isOpenFamilyTyCon (FamilyTyCon {famTcFlav = flav })
-  | OpenSynFamilyTyCon <- flav = True
-  | DataFamilyTyCon {} <- flav = True
-isOpenFamilyTyCon _            = False
+isOpenFamilyTyCon (FamilyTyCon {famTcFlav = OpenSynFamilyTyCon }) = True
+isOpenFamilyTyCon (AlgTyCon    {algTcRhs  = DataFamilyTyCon    }) = True
+isOpenFamilyTyCon _                                               = False
 
 -- | Is this a synonym 'TyCon' that can have may have further instances appear?
 isTypeFamilyTyCon :: TyCon -> Bool
-isTypeFamilyTyCon (FamilyTyCon { famTcFlav = flav }) = not (isDataFamFlav flav)
-isTypeFamilyTyCon _                                  = False
-
--- | Is this a synonym 'TyCon' that can have may have further instances appear?
-isDataFamilyTyCon :: TyCon -> Bool
-isDataFamilyTyCon (FamilyTyCon { famTcFlav = flav }) = isDataFamFlav flav
-isDataFamilyTyCon _                                  = False
+isTypeFamilyTyCon (FamilyTyCon {}) = True
+isTypeFamilyTyCon _                = False
 
 -- | Is this an open type family TyCon?
 isOpenTypeFamilyTyCon :: TyCon -> Bool
@@ -1546,9 +1479,10 @@ isBuiltInSynFamTyCon_maybe
   (FamilyTyCon {famTcFlav = BuiltInSynFamTyCon ops }) = Just ops
 isBuiltInSynFamTyCon_maybe _                          = Nothing
 
-isDataFamFlav :: FamTyConFlav -> Bool
-isDataFamFlav (DataFamilyTyCon {}) = True   -- Data family
-isDataFamFlav _                    = False  -- Type synonym family
+-- | Is this a synonym 'TyCon' that can have may have further instances appear?
+isDataFamilyTyCon :: TyCon -> Bool
+isDataFamilyTyCon (AlgTyCon {algTcRhs = DataFamilyTyCon {}}) = True
+isDataFamilyTyCon _ = False
 
 -- | Are we able to extract information 'TyVar' to class argument list
 -- mapping from a given 'TyCon'?
@@ -1556,8 +1490,9 @@ isTyConAssoc :: TyCon -> Bool
 isTyConAssoc tc = isJust (tyConAssoc_maybe tc)
 
 tyConAssoc_maybe :: TyCon -> Maybe Class
-tyConAssoc_maybe (FamilyTyCon { famTcParent = mb_cls }) = mb_cls
-tyConAssoc_maybe _                                      = Nothing
+tyConAssoc_maybe tc = case tyConParent tc of
+                        AssocFamilyTyCon cls -> Just cls
+                        _                    -> Nothing
 
 -- The unit tycon didn't used to be classed as a tuple tycon
 -- but I thought that was silly so I've undone it
@@ -1596,19 +1531,14 @@ isRecursiveTyCon :: TyCon -> Bool
 isRecursiveTyCon (AlgTyCon {algTcRec = Recursive}) = True
 isRecursiveTyCon _                                 = False
 
-promotableTyCon_maybe :: TyCon -> Promoted TyCon
+promotableTyCon_maybe :: TyCon -> Maybe TyCon
 promotableTyCon_maybe (AlgTyCon { tcPromoted = prom })   = prom
-promotableTyCon_maybe _                                  = NotPromoted
-
-isPromotableTyCon :: TyCon -> Bool
-isPromotableTyCon tc = case promotableTyCon_maybe tc of
-                         Promoted {} -> True
-                         NotPromoted -> False
+promotableTyCon_maybe _                                  = Nothing
 
 promoteTyCon :: TyCon -> TyCon
 promoteTyCon tc = case promotableTyCon_maybe tc of
-                    Promoted prom_tc -> prom_tc
-                    NotPromoted      -> pprPanic "promoteTyCon" (ppr tc)
+                    Just prom_tc -> prom_tc
+                    Nothing      -> pprPanic "promoteTyCon" (ppr tc)
 
 -- | Is this a PromotedTyCon?
 isPromotedTyCon :: TyCon -> Bool
@@ -1650,10 +1580,13 @@ isImplicitTyCon (FunTyCon {})        = True
 isImplicitTyCon (PrimTyCon {})       = True
 isImplicitTyCon (PromotedDataCon {}) = True
 isImplicitTyCon (PromotedTyCon {})   = True
-isImplicitTyCon (AlgTyCon { algTcRhs = rhs, tyConName = name })
+isImplicitTyCon (AlgTyCon { algTcRhs = rhs, algTcParent = parent, tyConName = name })
   | TupleTyCon {} <- rhs             = isWiredInName name
+  | AssocFamilyTyCon {} <- parent    = True
+  | otherwise                        = False
+isImplicitTyCon (FamilyTyCon { famTcParent = parent })
+  | AssocFamilyTyCon {} <- parent    = True
   | otherwise                        = False
-isImplicitTyCon (FamilyTyCon { famTcParent = parent }) = isJust parent
 isImplicitTyCon (SynonymTyCon {})    = False
 
 tyConCType_maybe :: TyCon -> Maybe CType
@@ -1746,6 +1679,7 @@ tyConFamilySize tc@(AlgTyCon { algTcRhs = rhs })
       DataTyCon { data_cons = cons } -> length cons
       NewTyCon {}                    -> 1
       TupleTyCon {}                  -> 1
+      DataFamilyTyCon {}             -> 0
       _                              -> pprPanic "tyConFamilySize 1" (ppr tc)
 tyConFamilySize tc = pprPanic "tyConFamilySize 2" (ppr tc)
 
@@ -1842,41 +1776,50 @@ famTyConFlav_maybe _                                = Nothing
 
 -- | Is this 'TyCon' that for a class instance?
 isClassTyCon :: TyCon -> Bool
-isClassTyCon (AlgTyCon {algTcParent = ClassTyCon {}}) = True
-isClassTyCon _                                        = False
+isClassTyCon (AlgTyCon {algTcParent = ClassTyCon _}) = True
+isClassTyCon _                                       = False
 
 -- | If this 'TyCon' is that for a class instance, return the class it is for.
 -- Otherwise returns @Nothing@
 tyConClass_maybe :: TyCon -> Maybe Class
-tyConClass_maybe (AlgTyCon {algTcParent = ClassTyCon clas _}) = Just clas
-tyConClass_maybe _                                            = Nothing
+tyConClass_maybe (AlgTyCon {algTcParent = ClassTyCon clas}) = Just clas
+tyConClass_maybe _                                          = Nothing
+
+----------------------------------------------------------------------------
+tyConParent :: TyCon -> TyConParent
+tyConParent (AlgTyCon    {algTcParent = parent}) = parent
+tyConParent (FamilyTyCon {famTcParent = parent}) = parent
+tyConParent _                                    = NoParentTyCon
 
 ----------------------------------------------------------------------------
 -- | Is this 'TyCon' that for a data family instance?
 isFamInstTyCon :: TyCon -> Bool
-isFamInstTyCon (AlgTyCon {algTcParent = DataFamInstTyCon {} })
-  = True
-isFamInstTyCon _ = False
+isFamInstTyCon tc = case tyConParent tc of
+                      FamInstTyCon {} -> True
+                      _               -> False
 
 tyConFamInstSig_maybe :: TyCon -> Maybe (TyCon, [Type], CoAxiom Unbranched)
-tyConFamInstSig_maybe (AlgTyCon {algTcParent = DataFamInstTyCon ax f ts })
-  = Just (f, ts, ax)
-tyConFamInstSig_maybe _ = Nothing
+tyConFamInstSig_maybe tc
+  = case tyConParent tc of
+      FamInstTyCon ax f ts -> Just (f, ts, ax)
+      _                    -> Nothing
 
--- | If this 'TyCon' is that of a data family instance, return the family in question
+-- | If this 'TyCon' is that of a family instance, return the family in question
 -- and the instance types. Otherwise, return @Nothing@
 tyConFamInst_maybe :: TyCon -> Maybe (TyCon, [Type])
-tyConFamInst_maybe (AlgTyCon {algTcParent = DataFamInstTyCon _ f ts })
-  = Just (f, ts)
-tyConFamInst_maybe _ = Nothing
+tyConFamInst_maybe tc
+  = case tyConParent tc of
+      FamInstTyCon _ f ts -> Just (f, ts)
+      _                   -> Nothing
 
--- | If this 'TyCon' is that of a data family instance, return a 'TyCon' which
+-- | If this 'TyCon' is that of a family instance, return a 'TyCon' which
 -- represents a coercion identifying the representation type with the type
 -- instance family.  Otherwise, return @Nothing@
 tyConFamilyCoercion_maybe :: TyCon -> Maybe (CoAxiom Unbranched)
-tyConFamilyCoercion_maybe (AlgTyCon {algTcParent = DataFamInstTyCon ax _ _ })
-  = Just ax
-tyConFamilyCoercion_maybe _ = Nothing
+tyConFamilyCoercion_maybe tc
+  = case tyConParent tc of
+      FamInstTyCon co _ _ -> Just co
+      _                   -> Nothing
 
 {-
 ************************************************************************
@@ -1912,17 +1855,16 @@ instance Outputable TyCon where
 
 tyConFlavour :: TyCon -> String
 tyConFlavour (AlgTyCon { algTcParent = parent, algTcRhs = rhs })
-  | ClassTyCon _ <- parent = "class"
+  | ClassTyCon _ <- parent = "class"
   | otherwise = case rhs of
                   TupleTyCon { tup_sort = sort }
                      | isBoxed (tupleSortBoxity sort) -> "tuple"
                      | otherwise                      -> "unboxed tuple"
                   DataTyCon {}       -> "data type"
                   NewTyCon {}        -> "newtype"
+                  DataFamilyTyCon {} -> "data family"
                   AbstractTyCon {}   -> "abstract type"
-tyConFlavour (FamilyTyCon { famTcFlav = flav })
-  | isDataFamFlav flav            = "data family"
-  | otherwise                     = "type family"
+tyConFlavour (FamilyTyCon {})     = "type family"
 tyConFlavour (SynonymTyCon {})    = "type synonym"
 tyConFlavour (FunTyCon {})        = "built-in type"
 tyConFlavour (PrimTyCon {})       = "built-in type"
@@ -1930,16 +1872,14 @@ tyConFlavour (PromotedDataCon {}) = "promoted data constructor"
 tyConFlavour (PromotedTyCon {})   = "promoted type constructor"
 
 pprPromotionQuote :: TyCon -> SDoc
--- Promoted data constructors already have a tick in their OccName
-pprPromotionQuote tc
-  = case tc of
-      PromotedDataCon {} -> char '\'' -- Always quote promoted DataCons in types
-
-      PromotedTyCon {}   -> ifPprDebug (char '\'')
-                            -- However, we don't quote TyCons in kinds, except with -dppr-debug
-                            -- e.g. type family T a :: Bool -> *
-                            -- cf Trac #5952.
-      _                  -> empty
+pprPromotionQuote (PromotedDataCon {}) = char '\''   -- Quote promoted DataCons
+                                                     -- in types
+pprPromotionQuote (PromotedTyCon {})   = ifPprDebug (char '\'')
+pprPromotionQuote _                    = empty -- However, we don't quote TyCons
+                                               -- in kinds e.g.
+                                               -- type family T a :: Bool -> *
+                                               -- cf Trac #5952.
+                                               -- Except with -dppr-debug
 
 instance NamedThing TyCon where
     getName = tyConName