merge upstream HEAD
[ghc-hetmet.git] / compiler / types / TypeRep.lhs
index 4927dcc..1be55d7 100644 (file)
@@ -5,6 +5,10 @@
 \section[TypeRep]{Type - friends' interface}
 
 \begin{code}
+-- We expose the relevant stuff from this module via the Type module
+{-# OPTIONS_HADDOCK hide #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+
 module TypeRep (
        TyThing(..), 
        Type(..),
@@ -12,12 +16,12 @@ module TypeRep (
        
        Kind, ThetaType,                -- Synonyms
 
-       funTyCon,
+       funTyCon, funTyConName,
 
        -- Pretty-printing
        pprType, pprParendType, pprTypeApp,
        pprTyThing, pprTyThingCategory, 
-       pprPred, pprTheta, pprForAll, pprThetaArrow, pprClassPred,
+       pprPred, pprEqPred, pprTheta, pprForAll, pprThetaArrow, pprClassPred,
 
        -- Kinds
        liftedTypeKind, unliftedTypeKind, openTypeKind,
@@ -50,7 +54,6 @@ import {-# SOURCE #-} DataCon( DataCon, dataConName )
 -- friends:
 import Var
 import Name
-import OccName
 import BasicTypes
 import TyCon
 import Class
@@ -59,57 +62,10 @@ import Class
 import PrelNames
 import Outputable
 import FastString
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection{Type Classifications}
-%*                                                                     *
-%************************************************************************
-
-A type is
-
-       *unboxed*       iff its representation is other than a pointer
-                       Unboxed types are also unlifted.
-
-       *lifted*        A type is lifted iff it has bottom as an element.
-                       Closures always have lifted types:  i.e. any
-                       let-bound identifier in Core must have a lifted
-                       type.  Operationally, a lifted object is one that
-                       can be entered.
-
-                       Only lifted types may be unified with a type variable.
-
-       *algebraic*     A type with one or more constructors, whether declared
-                       with "data" or "newtype".   
-                       An algebraic type is one that can be deconstructed
-                       with a case expression.  
-                       *NOT* the same as lifted types,  because we also 
-                       include unboxed tuples in this classification.
-
-       *data*          A type declared with "data".  Also boxed tuples.
-
-       *primitive*     iff it is a built-in type that can't be expressed
-                       in Haskell.
-
-Currently, all primitive types are unlifted, but that's not necessarily
-the case.  (E.g. Int could be primitive.)
-
-Some primitive types are unboxed, such as Int#, whereas some are boxed
-but unlifted (such as ByteArray#).  The only primitive types that we
-classify as algebraic are the unboxed tuples.
-
-examples of type classifications:
-
-Type           primitive       boxed           lifted          algebraic    
------------------------------------------------------------------------------
-Int#,          Yes             No              No              No
-ByteArray#     Yes             Yes             No              No
-(# a, b #)     Yes             No              No              Yes
-(  a, b  )     No              Yes             Yes             Yes
-[a]            No              Yes             Yes             Yes
-
 
+-- libraries
+import Data.Data hiding ( TyCon )
+\end{code}
 
        ----------------------
        A note about newtypes
@@ -162,73 +118,92 @@ to cut all loops.  The other members of the loop may be marked 'non-recursive'.
 
 
 \begin{code}
+-- | The key representation of types within the compiler
 data Type
-  = TyVarTy TyVar      
+  = TyVarTy TyVar      -- ^ Vanilla type variable
 
   | AppTy
-       Type            -- Function is *not* a TyConApp
-       Type            -- It must be another AppTy, or TyVarTy
-
-  | TyConApp           -- Application of a TyCon, including newtypes *and* synonyms
-       TyCon           --  *Invariant* saturated appliations of FunTyCon and
-                       --      synonyms have their own constructors, below.
-                       -- However, *unsaturated* FunTyCons do appear as TyConApps.  
-                       -- 
-       [Type]          -- Might not be saturated.
-                       -- Even type synonyms are not necessarily saturated;
-                       -- for example unsaturated type synonyms can appear as the 
-                       -- RHS of a type synonym.
-
-  | FunTy              -- Special case of TyConApp: TyConApp FunTyCon [t1,t2]
        Type
+       Type            -- ^ Type application to something other than a 'TyCon'. Parameters:
+                       --
+                       --  1) Function: must /not/ be a 'TyConApp', must be another 'AppTy', or 'TyVarTy'
+                       --
+                       --  2) Argument type
+
+  | TyConApp
+       TyCon
+       [Type]          -- ^ Application of a 'TyCon', including newtypes /and/ synonyms.
+                       -- Invariant: saturated appliations of 'FunTyCon' must
+                       -- use 'FunTy' and saturated synonyms must use their own
+                       -- constructors. However, /unsaturated/ 'FunTyCon's do appear as 'TyConApp's.
+                       -- Parameters:
+                       --
+                       -- 1) Type constructor being applied to.
+                       --
+                       -- 2) Type arguments. Might not have enough type arguments here to saturate the constructor.
+                       -- Even type synonyms are not necessarily saturated; for example unsaturated type synonyms
+                       -- can appear as the right hand side of a type synonym.
+
+  | FunTy
        Type
+       Type            -- ^ Special case of 'TyConApp': @TyConApp FunTyCon [t1, t2]@
 
-  | ForAllTy           -- A polymorphic type
+  | ForAllTy
        TyVar
-       Type    
-
-  | PredTy             -- The type of evidence for a type predictate
-       PredType        -- See Note [PredTy], and Note [Equality predicates]
-       -- NB: A PredTy (EqPred _ _) can appear only as the kind
-       --     of a coercion variable; never as the argument or result
-       --     of a FunTy (unlike ClassP, IParam)
-
-type Kind = Type       -- Invariant: a kind is always
-                       --      FunTy k1 k2
-                       -- or   TyConApp PrimTyCon [...]
-                       -- or   TyVar kv (during inference only)
-                       -- or   ForAll ... (for top-level coercions)
-
-type SuperKind = Type   -- Invariant: a super kind is always 
-                        --   TyConApp SuperKindTyCon ...
+       Type            -- ^ A polymorphic type
+
+  | PredTy
+       PredType        -- ^ The type of evidence for a type predictate.
+                        -- Note that a @PredTy (EqPred _ _)@ can appear only as the kind
+                       -- of a coercion variable; never as the argument or result
+                       -- of a 'FunTy' (unlike the 'PredType' constructors 'ClassP' or 'IParam')
+                       
+                       -- See Note [PredTy], and Note [Equality predicates]
+  deriving (Data, Typeable)
+
+-- | The key type representing kinds in the compiler.
+-- Invariant: a kind is always in one of these forms:
+--
+-- > FunTy k1 k2
+-- > TyConApp PrimTyCon [...]
+-- > TyVar kv   -- (during inference only)
+-- > ForAll ... -- (for top-level coercions)
+type Kind = Type
+
+-- | "Super kinds", used to help encode 'Kind's as types.
+-- Invariant: a super kind is always of this form:
+--
+-- > TyConApp SuperKindTyCon ...
+type SuperKind = Type
 \end{code}
 
 -------------------------------------
                Note [PredTy]
 
-A type of the form
-       PredTy p
-represents a value whose type is the Haskell predicate p, 
-where a predicate is what occurs before the '=>' in a Haskell type.
-It can be expanded into its representation, but: 
-
-       * The type checker must treat it as opaque
-       * The rest of the compiler treats it as transparent
-
-Consider these examples:
-       f :: (Eq a) => a -> Int
-       g :: (?x :: Int -> Int) => a -> Int
-       h :: (r\l) => {r} => {l::Int | r}
-
-Here the "Eq a" and "?x :: Int -> Int" and "r\l" are all called *predicates*
-Predicates are represented inside GHC by PredType:
-
 \begin{code}
+-- | A type of the form @PredTy p@ represents a value whose type is
+-- the Haskell predicate @p@, where a predicate is what occurs before 
+-- the @=>@ in a Haskell type.
+-- It can be expanded into its representation, but: 
+--
+-- * The type checker must treat it as opaque
+--
+-- * The rest of the compiler treats it as transparent
+--
+-- Consider these examples:
+--
+-- > f :: (Eq a) => a -> Int
+-- > g :: (?x :: Int -> Int) => a -> Int
+-- > h :: (r\l) => {r} => {l::Int | r}
+--
+-- Here the @Eq a@ and @?x :: Int -> Int@ and @r\l@ are all called \"predicates\"
 data PredType 
-  = ClassP Class [Type]                -- Class predicate
-  | IParam (IPName Name) Type  -- Implicit parameter
-  | EqPred Type Type           -- Equality predicate (ty1 ~ ty2)
+  = ClassP Class [Type]                -- ^ Class predicate e.g. @Eq a@
+  | IParam (IPName Name) Type  -- ^ Implicit parameter e.g. @?x :: Int@
+  | EqPred Type Type           -- ^ Equality predicate e.g @ty1 ~ ty2@
+  deriving (Data, Typeable)
 
+-- | A collection of 'PredType's
 type ThetaType = [PredType]
 \end{code}
 
@@ -274,6 +249,7 @@ this module seems the right place for TyThing, because it's needed for
 funTyCon and all the types in TysPrim.
 
 \begin{code}
+-- | A typecheckable-thing, essentially anything that has a name
 data TyThing = AnId     Id
             | ADataCon DataCon
             | ATyCon   TyCon
@@ -286,10 +262,10 @@ pprTyThing :: TyThing -> SDoc
 pprTyThing thing = pprTyThingCategory thing <+> quotes (ppr (getName thing))
 
 pprTyThingCategory :: TyThing -> SDoc
-pprTyThingCategory (ATyCon _)  = ptext SLIT("Type constructor")
-pprTyThingCategory (AClass _)   = ptext SLIT("Class")
-pprTyThingCategory (AnId   _)   = ptext SLIT("Identifier")
-pprTyThingCategory (ADataCon _) = ptext SLIT("Data constructor")
+pprTyThingCategory (ATyCon _)  = ptext (sLit "Type constructor")
+pprTyThingCategory (AClass _)   = ptext (sLit "Class")
+pprTyThingCategory (AnId   _)   = ptext (sLit "Identifier")
+pprTyThingCategory (ADataCon _) = ptext (sLit "Data constructor")
 
 instance NamedThing TyThing where      -- Can't put this with the type
   getName (AnId id)     = getName id   -- decl, because the DataCon instance
@@ -311,6 +287,7 @@ We define a few wired-in type constructors here to avoid module knots
 --------------------------
 -- First the TyCons...
 
+-- | See "Type#kind_subtyping" for details of the distinction between the 'Kind' 'TyCon's
 funTyCon, tySuperKindTyCon, coSuperKindTyCon, liftedTypeKindTyCon,
       openTypeKindTyCon, unliftedTypeKindTyCon,
       ubxTupleKindTyCon, argTypeKindTyCon
@@ -333,29 +310,26 @@ funTyCon = mkFunTyCon funTyConName (mkArrowKinds [argTypeKind, openTypeKind] lif
 tySuperKindTyCon     = mkSuperKindTyCon tySuperKindTyConName
 coSuperKindTyCon     = mkSuperKindTyCon coSuperKindTyConName
 
-liftedTypeKindTyCon   = mkKindTyCon liftedTypeKindTyConName
-openTypeKindTyCon     = mkKindTyCon openTypeKindTyConName
-unliftedTypeKindTyCon = mkKindTyCon unliftedTypeKindTyConName
-ubxTupleKindTyCon     = mkKindTyCon ubxTupleKindTyConName
-argTypeKindTyCon      = mkKindTyCon argTypeKindTyConName
-
-mkKindTyCon :: Name -> TyCon
-mkKindTyCon name = mkVoidPrimTyCon name tySuperKind 0
+liftedTypeKindTyCon   = mkKindTyCon liftedTypeKindTyConName   tySuperKind
+openTypeKindTyCon     = mkKindTyCon openTypeKindTyConName     tySuperKind
+unliftedTypeKindTyCon = mkKindTyCon unliftedTypeKindTyConName tySuperKind
+ubxTupleKindTyCon     = mkKindTyCon ubxTupleKindTyConName     tySuperKind
+argTypeKindTyCon      = mkKindTyCon argTypeKindTyConName      tySuperKind
 
 --------------------------
 -- ... and now their names
 
-tySuperKindTyConName      = mkPrimTyConName FSLIT("BOX") tySuperKindTyConKey tySuperKindTyCon
-coSuperKindTyConName      = mkPrimTyConName FSLIT("COERCION") coSuperKindTyConKey coSuperKindTyCon
-liftedTypeKindTyConName   = mkPrimTyConName FSLIT("*") liftedTypeKindTyConKey liftedTypeKindTyCon
-openTypeKindTyConName     = mkPrimTyConName FSLIT("?") openTypeKindTyConKey openTypeKindTyCon
-unliftedTypeKindTyConName = mkPrimTyConName FSLIT("#") unliftedTypeKindTyConKey unliftedTypeKindTyCon
-ubxTupleKindTyConName     = mkPrimTyConName FSLIT("(#)") ubxTupleKindTyConKey ubxTupleKindTyCon
-argTypeKindTyConName      = mkPrimTyConName FSLIT("??") argTypeKindTyConKey argTypeKindTyCon
-funTyConName              = mkPrimTyConName FSLIT("(->)") funTyConKey funTyCon
+tySuperKindTyConName      = mkPrimTyConName (fsLit "BOX") tySuperKindTyConKey tySuperKindTyCon
+coSuperKindTyConName      = mkPrimTyConName (fsLit "COERCION") coSuperKindTyConKey coSuperKindTyCon
+liftedTypeKindTyConName   = mkPrimTyConName (fsLit "*") liftedTypeKindTyConKey liftedTypeKindTyCon
+openTypeKindTyConName     = mkPrimTyConName (fsLit "?") openTypeKindTyConKey openTypeKindTyCon
+unliftedTypeKindTyConName = mkPrimTyConName (fsLit "#") unliftedTypeKindTyConKey unliftedTypeKindTyCon
+ubxTupleKindTyConName     = mkPrimTyConName (fsLit "(#)") ubxTupleKindTyConKey ubxTupleKindTyCon
+argTypeKindTyConName      = mkPrimTyConName (fsLit "??") argTypeKindTyConKey argTypeKindTyCon
+funTyConName              = mkPrimTyConName (fsLit "(->)") funTyConKey funTyCon
 
 mkPrimTyConName :: FastString -> Unique -> TyCon -> Name
-mkPrimTyConName occ key tycon = mkWiredInName gHC_PRIM (mkOccNameFS tcName occ) 
+mkPrimTyConName occ key tycon = mkWiredInName gHC_PRIM (mkTcOccFS occ) 
                                              key 
                                              (ATyCon tycon)
                                              BuiltInSyntax
@@ -368,6 +342,7 @@ mkPrimTyConName occ key tycon = mkWiredInName gHC_PRIM (mkOccNameFS tcName occ)
 kindTyConType :: TyCon -> Type
 kindTyConType kind = TyConApp kind []
 
+-- | See "Type#kind_subtyping" for details of the distinction between these 'Kind's
 liftedTypeKind, unliftedTypeKind, openTypeKind, argTypeKind, ubxTupleKind :: Kind
 
 liftedTypeKind   = kindTyConType liftedTypeKindTyCon
@@ -376,9 +351,11 @@ openTypeKind     = kindTyConType openTypeKindTyCon
 argTypeKind      = kindTyConType argTypeKindTyCon
 ubxTupleKind    = kindTyConType ubxTupleKindTyCon
 
+-- | Given two kinds @k1@ and @k2@, creates the 'Kind' @k1 -> k2@
 mkArrowKind :: Kind -> Kind -> Kind
 mkArrowKind k1 k2 = FunTy k1 k2
 
+-- | Iterated application of 'mkArrowKind'
 mkArrowKinds :: [Kind] -> Kind -> Kind
 mkArrowKinds arg_kinds result_kind = foldr mkArrowKind result_kind arg_kinds
 
@@ -448,27 +425,47 @@ pprType, pprParendType :: Type -> SDoc
 pprType       ty = ppr_type TopPrec   ty
 pprParendType ty = ppr_type TyConPrec ty
 
-pprTypeApp :: NamedThing a => a -> SDoc -> [Type] -> SDoc
--- The first arg is the tycon; it's used to arrange printing infix 
--- if it looks like an operator
--- Second arg is the pretty-printed tycon
-pprTypeApp tc pp_tc tys = ppr_type_app TopPrec (getName tc) pp_tc tys
+pprTypeApp :: NamedThing a => a -> [Type] -> SDoc
+-- The first arg is the tycon, or sometimes class
+-- Print infix if the tycon/class looks like an operator
+pprTypeApp tc tys = ppr_type_app TopPrec (getName tc) tys
 
 ------------------
 pprPred :: PredType -> SDoc
 pprPred (ClassP cls tys) = pprClassPred cls tys
 pprPred (IParam ip ty)   = ppr ip <> dcolon <> pprType ty
-pprPred (EqPred ty1 ty2) = sep [ppr ty1, nest 2 (ptext SLIT("~")), ppr ty2]
+pprPred (EqPred ty1 ty2) = pprEqPred (ty1,ty2)
+
+pprEqPred :: (Type,Type) -> SDoc
+pprEqPred (ty1,ty2) = sep [ ppr_type FunPrec ty1
+                          , nest 2 (ptext (sLit "~"))
+                          , ppr_type FunPrec ty2]
+                              -- Precedence looks like (->) so that we get
+                              --    Maybe a ~ Bool
+                              --    (a->a) ~ Bool
+                              -- Note parens on the latter!
+
 pprClassPred :: Class -> [Type] -> SDoc
-pprClassPred clas tys = ppr_type_app TopPrec (getName clas) (ppr clas) tys
+pprClassPred clas tys = ppr_type_app TopPrec (getName clas) tys
 
 pprTheta :: ThetaType -> SDoc
-pprTheta theta = parens (sep (punctuate comma (map pprPred theta)))
+-- pprTheta [pred] = pprPred pred       -- I'm in two minds about this
+pprTheta theta  = parens (sep (punctuate comma (map pprPred theta)))
 
 pprThetaArrow :: ThetaType -> SDoc
-pprThetaArrow theta 
-  | null theta = empty
-  | otherwise  = parens (sep (punctuate comma (map pprPred theta))) <+> ptext SLIT("=>")
+pprThetaArrow []     = empty
+pprThetaArrow [pred] 
+  | noParenPred pred = pprPred pred <+> darrow
+pprThetaArrow preds  = parens (sep (punctuate comma (map pprPred preds))) <+> darrow
+
+noParenPred :: PredType -> Bool
+-- A predicate that can appear without parens before a "=>"
+--       C a => a -> a
+--       a~b => a -> b
+-- But   (?x::Int) => Int -> Int
+noParenPred (ClassP {}) = True
+noParenPred (EqPred {}) = True
+noParenPred (IParam {}) = False
 
 ------------------
 instance Outputable Type where
@@ -488,8 +485,9 @@ pprKind = pprType
 pprParendKind = pprParendType
 
 ppr_type :: Prec -> Type -> SDoc
-ppr_type _ (TyVarTy tv)       = ppr tv
-ppr_type _ (PredTy pred)      = ifPprDebug (ptext SLIT("<pred>")) <> (ppr pred)
+ppr_type _ (TyVarTy tv)              = ppr_tvar tv
+ppr_type p (PredTy pred)      = maybeParen p TyConPrec $
+                                ifPprDebug (ptext (sLit "<pred>")) <> (ppr pred)
 ppr_type p (TyConApp tc tys)  = ppr_tc_app p tc tys
 
 ppr_type p (AppTy t1 t2) = maybeParen p TyConPrec $
@@ -503,8 +501,11 @@ ppr_type p (FunTy ty1 ty2)
     maybeParen p FunPrec $
     sep (ppr_type FunPrec ty1 : ppr_fun_tail ty2)
   where
-    ppr_fun_tail (FunTy ty1 ty2) = (arrow <+> ppr_type FunPrec ty1) : ppr_fun_tail ty2
-    ppr_fun_tail other_ty        = [arrow <+> pprType other_ty]
+    ppr_fun_tail (FunTy ty1 ty2) 
+      | not (is_pred ty1) = (arrow <+> ppr_type FunPrec ty1) : ppr_fun_tail ty2
+    ppr_fun_tail other_ty = [arrow <+> pprType other_ty]
+    is_pred (PredTy {}) = True
+    is_pred _           = False
 
 ppr_forall_type :: Prec -> Type -> SDoc
 ppr_forall_type p ty
@@ -532,53 +533,78 @@ ppr_tc_app _ tc []
   = ppr_tc tc
 ppr_tc_app _ tc [ty]
   | tc `hasKey` listTyConKey = brackets (pprType ty)
-  | tc `hasKey` parrTyConKey = ptext SLIT("[:") <> pprType ty <> ptext SLIT(":]")
-  | tc `hasKey` liftedTypeKindTyConKey   = ptext SLIT("*")
-  | tc `hasKey` unliftedTypeKindTyConKey = ptext SLIT("#")
-  | tc `hasKey` openTypeKindTyConKey     = ptext SLIT("(?)")
-  | tc `hasKey` ubxTupleKindTyConKey     = ptext SLIT("(#)")
-  | tc `hasKey` argTypeKindTyConKey      = ptext SLIT("??")
+  | tc `hasKey` parrTyConKey = ptext (sLit "[:") <> pprType ty <> ptext (sLit ":]")
+  | tc `hasKey` liftedTypeKindTyConKey   = ptext (sLit "*")
+  | tc `hasKey` unliftedTypeKindTyConKey = ptext (sLit "#")
+  | tc `hasKey` openTypeKindTyConKey     = ptext (sLit "(?)")
+  | tc `hasKey` ubxTupleKindTyConKey     = ptext (sLit "(#)")
+  | tc `hasKey` argTypeKindTyConKey      = ptext (sLit "??")
 
 ppr_tc_app p tc tys
+  | [ecvar,ty] <- tys, tc `hasKey` hetMetCodeTypeTyConKey
+  = ptext (sLit "<[")  <> pprType ty <> ptext (sLit "]>@") <> ppr ecvar
   | isTupleTyCon tc && tyConArity tc == length tys
   = tupleParens (tupleTyConBoxity tc) (sep (punctuate comma (map pprType tys)))
   | otherwise
-  = ppr_type_app p (getName tc) (ppr_naked_tc tc) tys
+  = ppr_type_app p (getName tc) tys
 
-ppr_type_app :: Prec -> Name -> SDoc -> [Type] -> SDoc
-ppr_type_app p tc pp_tc tys
+ppr_type_app :: Prec -> Name -> [Type] -> SDoc
+-- Used for classes as well as types; that's why it's separate from ppr_tc_app
+ppr_type_app p tc tys
   | is_sym_occ         -- Print infix if possible
   , [ty1,ty2] <- tys   -- We know nothing of precedence though
   = maybeParen p FunPrec (sep [ppr_type FunPrec ty1, 
-                              pp_tc <+> ppr_type FunPrec ty2])
+                              pprInfixVar True (ppr tc) <+> ppr_type FunPrec ty2])
   | otherwise
-  = maybeParen p TyConPrec (hang paren_tc 2 (sep (map pprParendType tys)))
+  = maybeParen p TyConPrec (hang (pprPrefixVar is_sym_occ (ppr tc))
+                              2 (sep (map pprParendType tys)))
   where
     is_sym_occ = isSymOcc (getOccName tc)
-    paren_tc | is_sym_occ = parens pp_tc
-            | otherwise  = pp_tc
-
-ppr_tc :: TyCon -> SDoc
-ppr_tc tc = parenSymOcc (getOccName tc) (ppr_naked_tc tc)
 
-ppr_naked_tc :: TyCon -> SDoc  -- No brackets for SymOcc
-ppr_naked_tc tc 
+ppr_tc :: TyCon -> SDoc        -- No brackets for SymOcc
+ppr_tc tc 
   = pp_nt_debug <> ppr tc
   where
    pp_nt_debug | isNewTyCon tc = ifPprDebug (if isRecursiveTyCon tc 
-                                            then ptext SLIT("<recnt>")
-                                            else ptext SLIT("<nt>"))
+                                            then ptext (sLit "<recnt>")
+                                            else ptext (sLit "<nt>"))
               | otherwise     = empty
 
+ppr_tvar :: TyVar -> SDoc
+ppr_tvar tv  -- Note [Infix type variables]
+  | isSymOcc (getOccName tv)  = parens (ppr tv)
+  | otherwise                = ppr tv
+
 -------------------
 pprForAll :: [TyVar] -> SDoc
 pprForAll []  = empty
-pprForAll tvs = ptext SLIT("forall") <+> sep (map pprTvBndr tvs) <> dot
+pprForAll tvs = ptext (sLit "forall") <+> sep (map pprTvBndr tvs) <> dot
 
 pprTvBndr :: TyVar -> SDoc
-pprTvBndr tv | isLiftedTypeKind kind = ppr tv
-            | otherwise             = parens (ppr tv <+> dcolon <+> pprKind kind)
+pprTvBndr tv | isLiftedTypeKind kind = ppr_tvar tv
+            | otherwise             = parens (ppr_tvar tv <+> dcolon <+> pprKind kind)
             where
               kind = tyVarKind tv
 \end{code}
 
+Note [Infix type variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+With TypeOperators you can say
+
+   f :: (a ~> b) -> b
+
+and the (~>) is considered a type variable.  However, the type
+pretty-printer in this module will just see (a ~> b) as
+
+   App (App (TyVarTy "~>") (TyVarTy "a")) (TyVarTy "b")
+
+So it'll print the type in prefix form.  To avoid confusion we must
+remember to parenthesise the operator, thus
+
+   (~>) a b -> b
+
+See Trac #2766.
+
+
+
+