    module GHC.Tc.Types.Rank (Rank(..))  where

    import GHC.Base (Bool)
    import GHC.Utils.Outputable (Outputable, (<+>), parens, ppr, text)

    {-
    Note [Higher rank types]
    ~~~~~~~~~~~~~~~~~~~~~~~~
    Technically
                Int -> forall a. a->a
    is still a rank-1 type, but it's not Haskell 98 (#5957).  So the
    validity checker allow a forall after an arrow only if we allow it
    before -- that is, with Rank2Types or RankNTypes
    -}

    data Rank = ArbitraryRank -- Any rank ok

              | LimitedRank   -- Note [Higher rank types]
                     Bool     -- Forall ok at top
                     Rank     -- Use for function arguments

              -- Monotypes that could be a polytype through an extension
              | MonoTypeRankZero   -- RankNTypes
              | MonoTypeTyConArg   -- ImpredicativeTypes
              | MonoTypeSynArg     -- LiberalTypeSynonyms
              | MonoTypeConstraint -- QuantifiedConstraints
              --

              | MustBeMonoType  -- Monotype regardless of flags

    instance Outputable Rank where
      ppr :: Rank -> SDoc
    ppr Rank
    ArbitraryRank      = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "ArbitraryRank"
      ppr (LimitedRank Bool
    top_forall_ok Rank
    r)
                             = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "LimitedRank" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Bool -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Bool
    top_forall_ok
                                                  SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    parens (Rank -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Rank
    r)
      ppr Rank
    MonoTypeRankZero   = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "MonoTypeRankZero"
      ppr Rank
    MonoTypeTyConArg   = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "MonoTypeTyConArg"
      ppr Rank
    MonoTypeSynArg     = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "MonoTypeSynArg"
      ppr Rank
    MonoTypeConstraint = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "MonoTypeConstraint"
      ppr Rank
    MustBeMonoType     = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "MustBeMonoType"