    {-# LANGUAGE MultiWayIf      #-}
    {-# LANGUAGE RecursiveDo     #-}
    {-# LANGUAGE TupleSections   #-}

    {-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
    {-
    (c) The University of Glasgow 2006
    (c) The GRASP/AQUA Project, Glasgow University, 1992-1998

    -}

    -- | Monadic type operations
    --
    -- This module contains monadic operations over types that contain mutable type
    -- variables.
    module GHC.Tc.Utils.TcMType (
      TcTyVar, TcKind, TcType, TcTauType, TcThetaType, TcTyVarSet,

      --------------------------------
      -- Creating new mutable type variables
      newFlexiTyVar,
      newNamedFlexiTyVar,
      newFlexiTyVarTy,              -- Kind -> TcM TcType
      newFlexiTyVarTys,             -- Int -> Kind -> TcM [TcType]
      newOpenFlexiTyVar, newOpenFlexiTyVarTy, newOpenTypeKind,
      newOpenBoxedTypeKind,
      newMetaKindVar, newMetaKindVars, newMetaTyVarTyAtLevel,
      newAnonMetaTyVar, newConcreteTyVar, cloneMetaTyVar,
      newCycleBreakerTyVar,

      newMultiplicityVar,
      readMetaTyVar, writeMetaTyVar, writeMetaTyVarRef,
      newTauTvDetailsAtLevel, newMetaDetails, newMetaTyVarName,
      isFilledMetaTyVar_maybe, isFilledMetaTyVar, isUnfilledMetaTyVar,

      --------------------------------
      -- Creating new evidence variables
      newEvVar, newEvVars, newDict,
      newWantedWithLoc, newWanted, newWanteds, cloneWanted, cloneWC, cloneWantedCtEv,
      emitWanted, emitWantedEq, emitWantedEvVar, emitWantedEvVars,
      emitWantedEqs,
      newTcEvBinds, newNoTcEvBinds, addTcEvBind,
      emitNewExprHole,

      newCoercionHole, fillCoercionHole, isFilledCoercionHole,
      unpackCoercionHole, unpackCoercionHole_maybe,
      checkCoercionHole,

      ConcreteHole, newConcreteHole,

      newImplication,

      --------------------------------
      -- Instantiation
      newMetaTyVars, newMetaTyVarX, newMetaTyVarsX,
      newMetaTyVarTyVarX,
      newTyVarTyVar, cloneTyVarTyVar,
      newPatSigTyVar, newSkolemTyVar, newWildCardX,

      --------------------------------
      -- Expected types
      ExpType(..), ExpSigmaType, ExpRhoType,
      mkCheckExpType, newInferExpType, newInferExpTypeFRR,
      tcInfer, tcInferFRR,
      readExpType, readExpType_maybe, readScaledExpType,
      expTypeToType, scaledExpTypeToType,
      checkingExpType_maybe, checkingExpType,
      inferResultToType, ensureMonoType, promoteTcType,

      --------------------------------
      -- Zonking and tidying
      zonkTidyTcType, zonkTidyTcTypes, zonkTidyOrigin, zonkTidyOrigins,
      zonkTidyFRRInfos,
      tidyEvVar, tidyCt, tidyHole, tidyDelayedError,
        zonkTcTyVar, zonkTcTyVars,
      zonkTcTyVarToTcTyVar, zonkTcTyVarsToTcTyVars,
      zonkInvisTVBinder,
      zonkTyCoVarsAndFV, zonkTcTypeAndFV, zonkDTyCoVarSetAndFV,
      zonkTyCoVarsAndFVList,

      zonkTcType, zonkTcTypes, zonkCo,
      zonkTyCoVarKind,
      zonkEvVar, zonkWC, zonkImplication, zonkSimples,
      zonkId, zonkCoVar,
      zonkCt, zonkSkolemInfo, zonkSkolemInfoAnon,

      ---------------------------------
      -- Promotion, defaulting, skolemisation
      defaultTyVar, promoteMetaTyVarTo, promoteTyVarSet,
      quantifyTyVars, isQuantifiableTv,
      zonkAndSkolemise, skolemiseQuantifiedTyVar,
      doNotQuantifyTyVars,

      candidateQTyVarsOfType,  candidateQTyVarsOfKind,
      candidateQTyVarsOfTypes, candidateQTyVarsOfKinds,
      candidateQTyVarsWithBinders,
      CandidatesQTvs(..), delCandidates,
      candidateKindVars, partitionCandidates,

      ------------------------------
      -- Representation polymorphism
      checkTypeHasFixedRuntimeRep,

      ------------------------------
      -- Other
      anyUnfilledCoercionHoles
      ) where

    import GHC.Prelude

    import GHC.Driver.Session
    import qualified GHC.LanguageExtensions as LangExt

    import GHC.Tc.Types.Origin
    import GHC.Tc.Types.Constraint
    import GHC.Tc.Types.Evidence
    import GHC.Tc.Utils.Monad        -- TcType, amongst others
    import GHC.Tc.Utils.TcType
    import GHC.Tc.Errors.Types
    import GHC.Tc.Errors.Ppr

    import GHC.Core.TyCo.Rep
    import GHC.Core.TyCo.Ppr
    import GHC.Core.Type
    import GHC.Core.TyCon
    import GHC.Core.Coercion
    import GHC.Core.Class
    import GHC.Core.Predicate
    import GHC.Core.InstEnv (ClsInst(is_tys))

    import GHC.Types.Var
    import GHC.Types.Id as Id
    import GHC.Types.Name
    import GHC.Types.Var.Set

    import GHC.Builtin.Types
    import GHC.Types.Error
    import GHC.Types.Var.Env
    import GHC.Types.Unique.Set
    import GHC.Types.Basic ( TypeOrKind(..)
                           , NonStandardDefaultingStrategy(..)
                           , DefaultingStrategy(..), defaultNonStandardTyVars )

    import GHC.Data.FastString
    import GHC.Data.Bag
    import GHC.Data.Pair

    import GHC.Utils.Misc
    import GHC.Utils.Outputable
    import GHC.Utils.Panic
    import GHC.Utils.Panic.Plain
    import GHC.Utils.Constants (debugIsOn)

    import Control.Monad
    import GHC.Data.Maybe
    import qualified Data.Semigroup as Semi
    import GHC.Types.Name.Reader

    {-
    ************************************************************************
    *                                                                      *
            Kind variables
    *                                                                      *
    ************************************************************************
    -}

    newMetaKindVar :: TcM TcKind
    newMetaKindVar :: TcM Kind
    newMetaKindVar
      = do { TcTyVarDetails
    details <- MetaInfo -> TcM TcTyVarDetails
    newMetaDetails MetaInfo
    TauTv
           ; Name
    name    <- FastString -> TcM Name
    newMetaTyVarName (String -> FastString
    fsLit String
    "k")
                        -- All MetaKindVars are called "k"
                        -- They may be jiggled by tidying
           ; let kv :: TyVar
    kv = Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name Kind
    liftedTypeKind TcTyVarDetails
    details
           ; String -> SDoc -> TcRn ()
    traceTc String
    "newMetaKindVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    kv)
           ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVar -> Kind
    mkTyVarTy TyVar
    kv) }

    newMetaKindVars :: Int -> TcM [TcKind]
    newMetaKindVars :: Int -> TcM [Kind]
    newMetaKindVars Int
    n = Int -> TcM Kind -> TcM [Kind]
    forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
    replicateM Int
    n TcM Kind
    newMetaKindVar

    {-
    ************************************************************************
    *                                                                      *
         Evidence variables; range over constraints we can abstract over
    *                                                                      *
    ************************************************************************
    -}

    newEvVars :: TcThetaType -> TcM [EvVar]
    newEvVars :: [Kind] -> TcM [TyVar]
    newEvVars [Kind]
    theta = (Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar)
    -> [Kind] -> TcM [TyVar]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall gbl lcl. Kind -> TcRnIf gbl lcl TyVar
    newEvVar [Kind]
    theta

    --------------

    newEvVar :: TcPredType -> TcRnIf gbl lcl EvVar
    -- Creates new *rigid* variables for predicates
    newEvVar :: forall gbl lcl. Kind -> TcRnIf gbl lcl TyVar
    newEvVar Kind
    ty = do { Name
    name <- OccName -> TcRnIf gbl lcl Name
    forall gbl lcl. OccName -> TcRnIf gbl lcl Name
    newSysName (Kind -> OccName
    predTypeOccName Kind
    ty)
                     ; TyVar -> TcRnIf gbl lcl TyVar
    forall a. a -> IOEnv (Env gbl lcl) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Name -> Kind -> Kind -> TyVar
    mkLocalIdOrCoVar Name
    name Kind
    ManyTy Kind
    ty) }

    -- | Create a new Wanted constraint with the given 'CtLoc'.
    newWantedWithLoc :: CtLoc -> PredType -> TcM CtEvidence
    newWantedWithLoc :: CtLoc -> Kind -> TcM CtEvidence
    newWantedWithLoc CtLoc
    loc Kind
    pty
      = do TcEvDest
    dst <- case Kind -> Pred
    classifyPredType Kind
    pty of
                    EqPred {} -> CoercionHole -> TcEvDest
    HoleDest  (CoercionHole -> TcEvDest)
    -> IOEnv (Env TcGblEnv TcLclEnv) CoercionHole
    -> IOEnv (Env TcGblEnv TcLclEnv) TcEvDest
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Kind -> IOEnv (Env TcGblEnv TcLclEnv) CoercionHole
    newCoercionHole Kind
    pty
                    Pred
    _         -> TyVar -> TcEvDest
    EvVarDest (TyVar -> TcEvDest)
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) TcEvDest
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall gbl lcl. Kind -> TcRnIf gbl lcl TyVar
    newEvVar Kind
    pty
           CtEvidence -> TcM CtEvidence
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CtEvidence -> TcM CtEvidence) -> CtEvidence -> TcM CtEvidence
    forall a b. (a -> b) -> a -> b
    $ CtWanted { ctev_dest :: TcEvDest
    ctev_dest      = TcEvDest
    dst
                             , ctev_pred :: Kind
    ctev_pred      = Kind
    pty
                             , ctev_loc :: CtLoc
    ctev_loc       = CtLoc
    loc
                             , ctev_rewriters :: RewriterSet
    ctev_rewriters = RewriterSet
    emptyRewriterSet }

    -- | Create a new Wanted constraint with the given 'CtOrigin', and
    -- location information taken from the 'TcM' environment.
    newWanted :: CtOrigin -> Maybe TypeOrKind -> PredType -> TcM CtEvidence
    -- Deals with both equality and non-equality predicates
    newWanted :: CtOrigin -> Maybe TypeOrKind -> Kind -> TcM CtEvidence
    newWanted CtOrigin
    orig Maybe TypeOrKind
    t_or_k Kind
    pty
      = do CtLoc
    loc <- CtOrigin -> Maybe TypeOrKind -> TcM CtLoc
    getCtLocM CtOrigin
    orig Maybe TypeOrKind
    t_or_k
           CtLoc -> Kind -> TcM CtEvidence
    newWantedWithLoc CtLoc
    loc Kind
    pty

    -- | Create new Wanted constraints with the given 'CtOrigin',
    -- and location information taken from the 'TcM' environment.
    newWanteds :: CtOrigin -> ThetaType -> TcM [CtEvidence]
    newWanteds :: CtOrigin -> [Kind] -> TcM [CtEvidence]
    newWanteds CtOrigin
    orig = (Kind -> TcM CtEvidence) -> [Kind] -> TcM [CtEvidence]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (CtOrigin -> Maybe TypeOrKind -> Kind -> TcM CtEvidence
    newWanted CtOrigin
    orig Maybe TypeOrKind
    forall a. Maybe a
    Nothing)

    ----------------------------------------------
    -- Cloning constraints
    ----------------------------------------------

    cloneWantedCtEv :: CtEvidence -> TcM CtEvidence
    cloneWantedCtEv :: CtEvidence -> TcM CtEvidence
    cloneWantedCtEv ctev :: CtEvidence
    ctev@(CtWanted { ctev_pred :: CtEvidence -> Kind
    ctev_pred = Kind
    pty, ctev_dest :: CtEvidence -> TcEvDest
    ctev_dest = HoleDest CoercionHole
    _ })
      | Kind -> Bool
    isEqPrimPred Kind
    pty
      = do { CoercionHole
    co_hole <- Kind -> IOEnv (Env TcGblEnv TcLclEnv) CoercionHole
    newCoercionHole Kind
    pty
           ; CtEvidence -> TcM CtEvidence
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CtEvidence
    ctev { ctev_dest = HoleDest co_hole }) }
      | Bool
    otherwise
      = String -> SDoc -> TcM CtEvidence
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "cloneWantedCtEv" (Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    pty)
    cloneWantedCtEv CtEvidence
    ctev = CtEvidence -> TcM CtEvidence
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CtEvidence
    ctev

    cloneWanted :: Ct -> TcM Ct
    cloneWanted :: Ct -> TcM Ct
    cloneWanted Ct
    ct = CtEvidence -> Ct
    mkNonCanonical (CtEvidence -> Ct) -> TcM CtEvidence -> TcM Ct
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> CtEvidence -> TcM CtEvidence
    cloneWantedCtEv (Ct -> CtEvidence
    ctEvidence Ct
    ct)

    cloneWC :: WantedConstraints -> TcM WantedConstraints
    -- Clone all the evidence bindings in
    --   a) the ic_bind field of any implications
    --   b) the CoercionHoles of any wanted constraints
    -- so that solving the WantedConstraints will not have any visible side
    -- effect, /except/ from causing unifications
    cloneWC :: WantedConstraints -> TcM WantedConstraints
    cloneWC wc :: WantedConstraints
    wc@(WC { wc_simple :: WantedConstraints -> Bag Ct
    wc_simple = Bag Ct
    simples, wc_impl :: WantedConstraints -> Bag Implication
    wc_impl = Bag Implication
    implics })
      = do { Bag Ct
    simples' <- (Ct -> TcM Ct) -> Bag Ct -> IOEnv (Env TcGblEnv TcLclEnv) (Bag Ct)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Bag a -> m (Bag b)
    mapBagM Ct -> TcM Ct
    cloneWanted Bag Ct
    simples
           ; Bag Implication
    implics' <- (Implication -> IOEnv (Env TcGblEnv TcLclEnv) Implication)
    -> Bag Implication
    -> IOEnv (Env TcGblEnv TcLclEnv) (Bag Implication)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Bag a -> m (Bag b)
    mapBagM Implication -> IOEnv (Env TcGblEnv TcLclEnv) Implication
    cloneImplication Bag Implication
    implics
           ; WantedConstraints -> TcM WantedConstraints
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WantedConstraints
    wc { wc_simple = simples', wc_impl = implics' }) }

    cloneImplication :: Implication -> TcM Implication
    cloneImplication :: Implication -> IOEnv (Env TcGblEnv TcLclEnv) Implication
    cloneImplication implic :: Implication
    implic@(Implic { ic_binds :: Implication -> EvBindsVar
    ic_binds = EvBindsVar
    binds, ic_wanted :: Implication -> WantedConstraints
    ic_wanted = WantedConstraints
    inner_wanted })
      = do { EvBindsVar
    binds'        <- EvBindsVar -> TcM EvBindsVar
    cloneEvBindsVar EvBindsVar
    binds
           ; WantedConstraints
    inner_wanted' <- WantedConstraints -> TcM WantedConstraints
    cloneWC WantedConstraints
    inner_wanted
           ; Implication -> IOEnv (Env TcGblEnv TcLclEnv) Implication
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Implication
    implic { ic_binds = binds', ic_wanted = inner_wanted' }) }

    ----------------------------------------------
    -- Emitting constraints
    ----------------------------------------------

    -- | Emits a new Wanted. Deals with both equalities and non-equalities.
    emitWanted :: CtOrigin -> TcPredType -> TcM EvTerm
    emitWanted :: CtOrigin -> Kind -> TcM EvTerm
    emitWanted CtOrigin
    origin Kind
    pty
      = do { CtEvidence
    ev <- CtOrigin -> Maybe TypeOrKind -> Kind -> TcM CtEvidence
    newWanted CtOrigin
    origin Maybe TypeOrKind
    forall a. Maybe a
    Nothing Kind
    pty
           ; Ct -> TcRn ()
    emitSimple (Ct -> TcRn ()) -> Ct -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $ CtEvidence -> Ct
    mkNonCanonical CtEvidence
    ev
           ; EvTerm -> TcM EvTerm
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EvTerm -> TcM EvTerm) -> EvTerm -> TcM EvTerm
    forall a b. (a -> b) -> a -> b
    $ CtEvidence -> EvTerm
    ctEvTerm CtEvidence
    ev }

    emitWantedEqs :: CtOrigin -> [(TcType,TcType)] -> TcM ()
    -- Emit some new wanted nominal equalities
    emitWantedEqs :: CtOrigin -> [(Kind, Kind)] -> TcRn ()
    emitWantedEqs CtOrigin
    origin [(Kind, Kind)]
    pairs
      | [(Kind, Kind)] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(Kind, Kind)]
    pairs
      = () -> TcRn ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      | Bool
    otherwise
      = ((Kind, Kind) -> IOEnv (Env TcGblEnv TcLclEnv) Coercion)
    -> [(Kind, Kind)] -> TcRn ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ ((Kind -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) Coercion)
    -> (Kind, Kind) -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry (CtOrigin
    -> TypeOrKind
    -> Role
    -> Kind
    -> Kind
    -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    emitWantedEq CtOrigin
    origin TypeOrKind
    TypeLevel Role
    Nominal)) [(Kind, Kind)]
    pairs

    -- | Emits a new equality constraint
    emitWantedEq :: CtOrigin -> TypeOrKind -> Role -> TcType -> TcType -> TcM Coercion
    emitWantedEq :: CtOrigin
    -> TypeOrKind
    -> Role
    -> Kind
    -> Kind
    -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    emitWantedEq CtOrigin
    origin TypeOrKind
    t_or_k Role
    role Kind
    ty1 Kind
    ty2
      = do { CoercionHole
    hole <- Kind -> IOEnv (Env TcGblEnv TcLclEnv) CoercionHole
    newCoercionHole Kind
    pty
           ; CtLoc
    loc <- CtOrigin -> Maybe TypeOrKind -> TcM CtLoc
    getCtLocM CtOrigin
    origin (TypeOrKind -> Maybe TypeOrKind
    forall a. a -> Maybe a
    Just TypeOrKind
    t_or_k)
           ; Ct -> TcRn ()
    emitSimple (Ct -> TcRn ()) -> Ct -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $ CtEvidence -> Ct
    mkNonCanonical (CtEvidence -> Ct) -> CtEvidence -> Ct
    forall a b. (a -> b) -> a -> b
    $
             CtWanted { ctev_pred :: Kind
    ctev_pred = Kind
    pty
                      , ctev_dest :: TcEvDest
    ctev_dest = CoercionHole -> TcEvDest
    HoleDest CoercionHole
    hole
                      , ctev_loc :: CtLoc
    ctev_loc = CtLoc
    loc
                      , ctev_rewriters :: RewriterSet
    ctev_rewriters = [Kind] -> RewriterSet
    rewriterSetFromTypes [Kind
    ty1, Kind
    ty2] }
           ; Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CoercionHole -> Coercion
    HoleCo CoercionHole
    hole) }
      where
        pty :: Kind
    pty = Role -> Kind -> Kind -> Kind
    mkPrimEqPredRole Role
    role Kind
    ty1 Kind
    ty2

    -- | Creates a new EvVar and immediately emits it as a Wanted.
    -- No equality predicates here.
    emitWantedEvVar :: CtOrigin -> TcPredType -> TcM EvVar
    emitWantedEvVar :: CtOrigin -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    emitWantedEvVar CtOrigin
    origin Kind
    ty
      = do { TyVar
    new_cv <- Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall gbl lcl. Kind -> TcRnIf gbl lcl TyVar
    newEvVar Kind
    ty
           ; CtLoc
    loc <- CtOrigin -> Maybe TypeOrKind -> TcM CtLoc
    getCtLocM CtOrigin
    origin Maybe TypeOrKind
    forall a. Maybe a
    Nothing
           ; let ctev :: CtEvidence
    ctev = CtWanted { ctev_dest :: TcEvDest
    ctev_dest      = TyVar -> TcEvDest
    EvVarDest TyVar
    new_cv
                                 , ctev_pred :: Kind
    ctev_pred      = Kind
    ty
                                 , ctev_loc :: CtLoc
    ctev_loc       = CtLoc
    loc
                                 , ctev_rewriters :: RewriterSet
    ctev_rewriters = RewriterSet
    emptyRewriterSet }
           ; Ct -> TcRn ()
    emitSimple (Ct -> TcRn ()) -> Ct -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $ CtEvidence -> Ct
    mkNonCanonical CtEvidence
    ctev
           ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyVar
    new_cv }

    emitWantedEvVars :: CtOrigin -> [TcPredType] -> TcM [EvVar]
    emitWantedEvVars :: CtOrigin -> [Kind] -> TcM [TyVar]
    emitWantedEvVars CtOrigin
    orig = (Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar)
    -> [Kind] -> TcM [TyVar]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (CtOrigin -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    emitWantedEvVar CtOrigin
    orig)

    -- | Emit a new wanted expression hole
    emitNewExprHole :: RdrName         -- of the hole
                    -> Type -> TcM HoleExprRef
    emitNewExprHole :: RdrName -> Kind -> TcM HoleExprRef
    emitNewExprHole RdrName
    occ Kind
    ty
      = do { Unique
    u <- TcRnIf TcGblEnv TcLclEnv Unique
    forall gbl lcl. TcRnIf gbl lcl Unique
    newUnique
           ; TcRef EvTerm
    ref <- EvTerm -> TcRnIf TcGblEnv TcLclEnv (TcRef EvTerm)
    forall a gbl lcl. a -> TcRnIf gbl lcl (TcRef a)
    newTcRef (String -> SDoc -> EvTerm
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "unfilled unbound-variable evidence" (Unique -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Unique
    u))
           ; let her :: HoleExprRef
    her = TcRef EvTerm -> Kind -> Unique -> HoleExprRef
    HER TcRef EvTerm
    ref Kind
    ty Unique
    u

           ; CtLoc
    loc <- CtOrigin -> Maybe TypeOrKind -> TcM CtLoc
    getCtLocM (Maybe RdrName -> CtOrigin
    ExprHoleOrigin (RdrName -> Maybe RdrName
    forall a. a -> Maybe a
    Just RdrName
    occ)) (TypeOrKind -> Maybe TypeOrKind
    forall a. a -> Maybe a
    Just TypeOrKind
    TypeLevel)

           ; let hole :: Hole
    hole = Hole { hole_sort :: HoleSort
    hole_sort = HoleExprRef -> HoleSort
    ExprHole HoleExprRef
    her
                             , hole_occ :: RdrName
    hole_occ  = RdrName
    occ
                             , hole_ty :: Kind
    hole_ty   = Kind
    ty
                             , hole_loc :: CtLoc
    hole_loc  = CtLoc
    loc }
           ; Hole -> TcRn ()
    emitHole Hole
    hole
           ; HoleExprRef -> TcM HoleExprRef
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return HoleExprRef
    her }

    newDict :: Class -> [TcType] -> TcM DictId
    newDict :: Class -> [Kind] -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newDict Class
    cls [Kind]
    tys
      = do { Name
    name <- OccName -> TcM Name
    forall gbl lcl. OccName -> TcRnIf gbl lcl Name
    newSysName (OccName -> OccName
    mkDictOcc (Class -> OccName
    forall a. NamedThing a => a -> OccName
    getOccName Class
    cls))
           ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((() :: Constraint) => Name -> Kind -> Kind -> TyVar
    Name -> Kind -> Kind -> TyVar
    mkLocalId Name
    name Kind
    ManyTy (Class -> [Kind] -> Kind
    mkClassPred Class
    cls [Kind]
    tys)) }

    predTypeOccName :: PredType -> OccName
    predTypeOccName :: Kind -> OccName
    predTypeOccName Kind
    ty = case Kind -> Pred
    classifyPredType Kind
    ty of
        ClassPred Class
    cls [Kind]
    _ -> OccName -> OccName
    mkDictOcc (Class -> OccName
    forall a. NamedThing a => a -> OccName
    getOccName Class
    cls)
        EqPred {}       -> FastString -> OccName
    mkVarOccFS (String -> FastString
    fsLit String
    "co")
        IrredPred {}    -> FastString -> OccName
    mkVarOccFS (String -> FastString
    fsLit String
    "irred")
        ForAllPred {}   -> FastString -> OccName
    mkVarOccFS (String -> FastString
    fsLit String
    "df")

    -- | Create a new 'Implication' with as many sensible defaults for its fields
    -- as possible. Note that the 'ic_tclvl', 'ic_binds', and 'ic_info' fields do
    -- /not/ have sensible defaults, so they are initialized with lazy thunks that
    -- will 'panic' if forced, so one should take care to initialize these fields
    -- after creation.
    --
    -- This is monadic to look up the 'TcLclEnv', which is used to initialize
    -- 'ic_env', and to set the -Winaccessible-code flag. See
    -- Note [Avoid -Winaccessible-code when deriving] in "GHC.Tc.TyCl.Instance".
    newImplication :: TcM Implication
    newImplication :: IOEnv (Env TcGblEnv TcLclEnv) Implication
    newImplication
      = do TcLclEnv
    env <- TcRnIf TcGblEnv TcLclEnv TcLclEnv
    forall gbl lcl. TcRnIf gbl lcl lcl
    getLclEnv
           Bool
    warn_inaccessible <- WarningFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. WarningFlag -> TcRnIf gbl lcl Bool
    woptM WarningFlag
    Opt_WarnInaccessibleCode
           Implication -> IOEnv (Env TcGblEnv TcLclEnv) Implication
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Implication
    implicationPrototype { ic_env = env
                                        , ic_warn_inaccessible = warn_inaccessible })

    {-
    ************************************************************************
    *                                                                      *
            Coercion holes
    *                                                                      *
    ************************************************************************
    -}

    newCoercionHole :: TcPredType -> TcM CoercionHole
    newCoercionHole :: Kind -> IOEnv (Env TcGblEnv TcLclEnv) CoercionHole
    newCoercionHole Kind
    pred_ty
      = do { TyVar
    co_var <- Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall gbl lcl. Kind -> TcRnIf gbl lcl TyVar
    newEvVar Kind
    pred_ty
           ; String -> SDoc -> TcRn ()
    traceTc String
    "New coercion hole:" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    co_var SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc
    dcolon SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    pred_ty)
           ; IORef (Maybe Coercion)
    ref <- Maybe Coercion
    -> IOEnv (Env TcGblEnv TcLclEnv) (IORef (Maybe Coercion))
    forall a env. a -> IOEnv env (IORef a)
    newMutVar Maybe Coercion
    forall a. Maybe a
    Nothing
           ; CoercionHole -> IOEnv (Env TcGblEnv TcLclEnv) CoercionHole
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CoercionHole -> IOEnv (Env TcGblEnv TcLclEnv) CoercionHole)
    -> CoercionHole -> IOEnv (Env TcGblEnv TcLclEnv) CoercionHole
    forall a b. (a -> b) -> a -> b
    $ CoercionHole { ch_co_var :: TyVar
    ch_co_var = TyVar
    co_var, ch_ref :: IORef (Maybe Coercion)
    ch_ref = IORef (Maybe Coercion)
    ref } }

    -- | Put a value in a coercion hole
    fillCoercionHole :: CoercionHole -> Coercion -> TcM ()
    fillCoercionHole :: CoercionHole -> Coercion -> TcRn ()
    fillCoercionHole (CoercionHole { ch_ref :: CoercionHole -> IORef (Maybe Coercion)
    ch_ref = IORef (Maybe Coercion)
    ref, ch_co_var :: CoercionHole -> TyVar
    ch_co_var = TyVar
    cv }) Coercion
    co = do
      Bool -> TcRn () -> TcRn ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    debugIsOn (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $ do
        Maybe Coercion
    cts <- IORef (Maybe Coercion) -> TcRnIf TcGblEnv TcLclEnv (Maybe Coercion)
    forall a gbl lcl. TcRef a -> TcRnIf gbl lcl a
    readTcRef IORef (Maybe Coercion)
    ref
        Maybe Coercion -> (Coercion -> TcRn ()) -> TcRn ()
    forall (m :: * -> *) a. Monad m => Maybe a -> (a -> m ()) -> m ()
    whenIsJust Maybe Coercion
    cts ((Coercion -> TcRn ()) -> TcRn ())
    -> (Coercion -> TcRn ()) -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $ \Coercion
    old_co ->
          String -> SDoc -> TcRn ()
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "Filling a filled coercion hole" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    cv SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Coercion -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Coercion
    co SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Coercion -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Coercion
    old_co)
      String -> SDoc -> TcRn ()
    traceTc String
    "Filling coercion hole" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    cv SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    ":=" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Coercion -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Coercion
    co)
      IORef (Maybe Coercion) -> Maybe Coercion -> TcRn ()
    forall a gbl lcl. TcRef a -> a -> TcRnIf gbl lcl ()
    writeTcRef IORef (Maybe Coercion)
    ref (Coercion -> Maybe Coercion
    forall a. a -> Maybe a
    Just Coercion
    co)

    -- | Is a coercion hole filled in?
    isFilledCoercionHole :: CoercionHole -> TcM Bool
    isFilledCoercionHole :: CoercionHole -> TcRnIf TcGblEnv TcLclEnv Bool
    isFilledCoercionHole (CoercionHole { ch_ref :: CoercionHole -> IORef (Maybe Coercion)
    ch_ref = IORef (Maybe Coercion)
    ref }) = Maybe Coercion -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe Coercion -> Bool)
    -> TcRnIf TcGblEnv TcLclEnv (Maybe Coercion)
    -> TcRnIf TcGblEnv TcLclEnv Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IORef (Maybe Coercion) -> TcRnIf TcGblEnv TcLclEnv (Maybe Coercion)
    forall a gbl lcl. TcRef a -> TcRnIf gbl lcl a
    readTcRef IORef (Maybe Coercion)
    ref

    -- | Retrieve the contents of a coercion hole. Panics if the hole
    -- is unfilled
    unpackCoercionHole :: CoercionHole -> TcM Coercion
    unpackCoercionHole :: CoercionHole -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    unpackCoercionHole CoercionHole
    hole
      = do { Maybe Coercion
    contents <- CoercionHole -> TcRnIf TcGblEnv TcLclEnv (Maybe Coercion)
    unpackCoercionHole_maybe CoercionHole
    hole
           ; case Maybe Coercion
    contents of
               Just Coercion
    co -> Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Coercion
    co
               Maybe Coercion
    Nothing -> String -> SDoc -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "Unfilled coercion hole" (CoercionHole -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr CoercionHole
    hole) }

    -- | Retrieve the contents of a coercion hole, if it is filled
    unpackCoercionHole_maybe :: CoercionHole -> TcM (Maybe Coercion)
    unpackCoercionHole_maybe :: CoercionHole -> TcRnIf TcGblEnv TcLclEnv (Maybe Coercion)
    unpackCoercionHole_maybe (CoercionHole { ch_ref :: CoercionHole -> IORef (Maybe Coercion)
    ch_ref = IORef (Maybe Coercion)
    ref }) = IORef (Maybe Coercion) -> TcRnIf TcGblEnv TcLclEnv (Maybe Coercion)
    forall a gbl lcl. TcRef a -> TcRnIf gbl lcl a
    readTcRef IORef (Maybe Coercion)
    ref

    -- | Check that a coercion is appropriate for filling a hole. (The hole
    -- itself is needed only for printing.)
    -- Always returns the checked coercion, but this return value is necessary
    -- so that the input coercion is forced only when the output is forced.
    checkCoercionHole :: CoVar -> Coercion -> TcM Coercion
    checkCoercionHole :: TyVar -> Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    checkCoercionHole TyVar
    cv Coercion
    co
      | Bool
    debugIsOn
      = do { Kind
    cv_ty <- Kind -> TcM Kind
    zonkTcType (TyVar -> Kind
    varType TyVar
    cv)
                      -- co is already zonked, but cv might not be
           ; Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion)
    -> Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a b. (a -> b) -> a -> b
    $
             Bool -> SDoc -> Coercion -> Coercion
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (Kind -> Bool
    ok Kind
    cv_ty)
                       (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Bad coercion hole" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+>
                        TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    cv SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    colon SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat [ Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    t1, Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    t2, Role -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Role
    role
                                                 , Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    cv_ty ])
             Coercion
    co }
      | Bool
    otherwise
      = Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Coercion
    co

      where
        (Pair Kind
    t1 Kind
    t2, Role
    role) = Coercion -> (Pair Kind, Role)
    coercionKindRole Coercion
    co
        ok :: Kind -> Bool
    ok Kind
    cv_ty | EqPred EqRel
    cv_rel Kind
    cv_t1 Kind
    cv_t2 <- Kind -> Pred
    classifyPredType Kind
    cv_ty
                 =  Kind
    t1 Kind -> Kind -> Bool
    `eqType` Kind
    cv_t1
                 Bool -> Bool -> Bool
    && Kind
    t2 Kind -> Kind -> Bool
    `eqType` Kind
    cv_t2
                 Bool -> Bool -> Bool
    && Role
    role Role -> Role -> Bool
    forall a. Eq a => a -> a -> Bool
    == EqRel -> Role
    eqRelRole EqRel
    cv_rel
                 | Bool
    otherwise
                 = Bool
    False

    -- | A coercion hole used to store evidence for `Concrete#` constraints.
    --
    -- See Note [The Concrete mechanism].
    type ConcreteHole = CoercionHole

    -- | Create a new (initially unfilled) coercion hole,
    -- to hold evidence for a @'Concrete#' (ty :: ki)@ constraint.
    newConcreteHole :: Kind -- ^ Kind of the thing we want to ensure is concrete (e.g. 'runtimeRepTy')
                    -> Type -- ^ Thing we want to ensure is concrete (e.g. some 'RuntimeRep')
                    -> TcM (ConcreteHole, TcType)
                      -- ^ where to put the evidence, and a metavariable to store
                      -- the concrete type
    newConcreteHole :: Kind -> Kind -> TcM (CoercionHole, Kind)
    newConcreteHole Kind
    ki Kind
    ty
      = do { Kind
    concrete_ty <- Kind -> TcM Kind
    newFlexiTyVarTy Kind
    ki
           ; let co_ty :: Kind
    co_ty = Kind -> Kind -> Kind -> Kind -> Kind
    mkHeteroPrimEqPred Kind
    ki Kind
    ki Kind
    ty Kind
    concrete_ty
           ; CoercionHole
    hole <- Kind -> IOEnv (Env TcGblEnv TcLclEnv) CoercionHole
    newCoercionHole Kind
    co_ty
           ; (CoercionHole, Kind) -> TcM (CoercionHole, Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CoercionHole
    hole, Kind
    concrete_ty) }

    {- **********************************************************************
    *
                          ExpType functions
    *
    ********************************************************************** -}

    {- Note [ExpType]
    ~~~~~~~~~~~~~~~~~
    An ExpType is used as the "expected type" when type-checking an expression.
    An ExpType can hold a "hole" that can be filled in by the type-checker.
    This allows us to have one tcExpr that works in both checking mode and
    synthesis mode (that is, bidirectional type-checking). Previously, this
    was achieved by using ordinary unification variables, but we don't need
    or want that generality. (For example, #11397 was caused by doing the
    wrong thing with unification variables.) Instead, we observe that these
    holes should

    1. never be nested
    2. never appear as the type of a variable
    3. be used linearly (never be duplicated)

    By defining ExpType, separately from Type, we can achieve goals 1 and 2
    statically.

    See also [wiki:typechecking]

    Note [TcLevel of ExpType]
    ~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider

      data G a where
        MkG :: G Bool

      foo MkG = True

    This is a classic untouchable-variable / ambiguous GADT return type
    scenario. But, with ExpTypes, we'll be inferring the type of the RHS.
    We thus must track a TcLevel in an Inferring ExpType. If we try to
    fill the ExpType and find that the TcLevels don't work out, we fill
    the ExpType with a tau-tv at the low TcLevel, hopefully to be worked
    out later by some means -- see fillInferResult, and Note [fillInferResult]

    This behaviour triggered in test gadt/gadt-escape1.

    Note [FixedRuntimeRep context in ExpType]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Sometimes, we want to be sure that we fill an ExpType with a type
    that has a syntactically fixed RuntimeRep (in the sense of
    Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete).

    Example:

      pattern S a = (a :: (T :: TYPE R))

    We have to infer a type for `a` which has a syntactically fixed RuntimeRep.
    When it comes time to filling in the inferred type, we do the appropriate
    representation-polymorphism check, much like we do a level check
    as explained in Note [TcLevel of ExpType].

    See test case T21325.
    -}

    -- actual data definition is in GHC.Tc.Utils.TcType

    newInferExpType :: TcM ExpType
    newInferExpType :: TcM ExpType
    newInferExpType = Maybe FixedRuntimeRepContext -> TcM ExpType
    new_inferExpType Maybe FixedRuntimeRepContext
    forall a. Maybe a
    Nothing

    newInferExpTypeFRR :: FixedRuntimeRepContext -> TcM ExpTypeFRR
    newInferExpTypeFRR :: FixedRuntimeRepContext -> TcM ExpType
    newInferExpTypeFRR FixedRuntimeRepContext
    frr_orig
      = do { ThStage
    th_stage <- TcM ThStage
    getStage
           ; if
              -- See [Wrinkle: Typed Template Haskell]
              -- in Note [hasFixedRuntimeRep] in GHC.Tc.Utils.Concrete.
              | Brack ThStage
    _ (TcPending {}) <- ThStage
    th_stage
              -> Maybe FixedRuntimeRepContext -> TcM ExpType
    new_inferExpType Maybe FixedRuntimeRepContext
    forall a. Maybe a
    Nothing

              | Bool
    otherwise
              -> Maybe FixedRuntimeRepContext -> TcM ExpType
    new_inferExpType (FixedRuntimeRepContext -> Maybe FixedRuntimeRepContext
    forall a. a -> Maybe a
    Just FixedRuntimeRepContext
    frr_orig) }

    new_inferExpType :: Maybe FixedRuntimeRepContext -> TcM ExpType
    new_inferExpType :: Maybe FixedRuntimeRepContext -> TcM ExpType
    new_inferExpType Maybe FixedRuntimeRepContext
    mb_frr_orig
      = do { Unique
    u <- TcRnIf TcGblEnv TcLclEnv Unique
    forall gbl lcl. TcRnIf gbl lcl Unique
    newUnique
           ; TcLevel
    tclvl <- TcM TcLevel
    getTcLevel
           ; String -> SDoc -> TcRn ()
    traceTc String
    "newInferExpType" (Unique -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Unique
    u SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> TcLevel -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TcLevel
    tclvl)
           ; IORef (Maybe Kind)
    ref <- Maybe Kind -> IOEnv (Env TcGblEnv TcLclEnv) (IORef (Maybe Kind))
    forall a env. a -> IOEnv env (IORef a)
    newMutVar Maybe Kind
    forall a. Maybe a
    Nothing
           ; ExpType -> TcM ExpType
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (InferResult -> ExpType
    Infer (IR { ir_uniq :: Unique
    ir_uniq = Unique
    u, ir_lvl :: TcLevel
    ir_lvl = TcLevel
    tclvl
                               , ir_ref :: IORef (Maybe Kind)
    ir_ref = IORef (Maybe Kind)
    ref
                               , ir_frr :: Maybe FixedRuntimeRepContext
    ir_frr = Maybe FixedRuntimeRepContext
    mb_frr_orig })) }

    -- | Extract a type out of an ExpType, if one exists. But one should always
    -- exist. Unless you're quite sure you know what you're doing.
    readExpType_maybe :: ExpType -> TcM (Maybe TcType)
    readExpType_maybe :: ExpType -> TcM (Maybe Kind)
    readExpType_maybe (Check Kind
    ty)                   = Maybe Kind -> TcM (Maybe Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    ty)
    readExpType_maybe (Infer (IR { ir_ref :: InferResult -> IORef (Maybe Kind)
    ir_ref = IORef (Maybe Kind)
    ref})) = IORef (Maybe Kind) -> TcM (Maybe Kind)
    forall a env. IORef a -> IOEnv env a
    readMutVar IORef (Maybe Kind)
    ref

    -- | Same as readExpType, but for Scaled ExpTypes
    readScaledExpType :: Scaled ExpType -> TcM (Scaled Type)
    readScaledExpType :: Scaled ExpType -> TcM (Scaled Kind)
    readScaledExpType (Scaled Kind
    m ExpType
    exp_ty)
      = do { Kind
    ty <- ExpType -> TcM Kind
    readExpType ExpType
    exp_ty
           ; Scaled Kind -> TcM (Scaled Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Kind -> Kind -> Scaled Kind
    forall a. Kind -> a -> Scaled a
    Scaled Kind
    m Kind
    ty) }

    -- | Extract a type out of an ExpType. Otherwise, panics.
    readExpType :: ExpType -> TcM TcType
    readExpType :: ExpType -> TcM Kind
    readExpType ExpType
    exp_ty
      = do { Maybe Kind
    mb_ty <- ExpType -> TcM (Maybe Kind)
    readExpType_maybe ExpType
    exp_ty
           ; case Maybe Kind
    mb_ty of
               Just Kind
    ty -> Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Kind
    ty
               Maybe Kind
    Nothing -> String -> SDoc -> TcM Kind
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "Unknown expected type" (ExpType -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ExpType
    exp_ty) }

    -- | Returns the expected type when in checking mode.
    checkingExpType_maybe :: ExpType -> Maybe TcType
    checkingExpType_maybe :: ExpType -> Maybe Kind
    checkingExpType_maybe (Check Kind
    ty) = Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    ty
    checkingExpType_maybe (Infer {}) = Maybe Kind
    forall a. Maybe a
    Nothing

    -- | Returns the expected type when in checking mode. Panics if in inference
    -- mode.
    checkingExpType :: String -> ExpType -> TcType
    checkingExpType :: String -> ExpType -> Kind
    checkingExpType String
    _   (Check Kind
    ty) = Kind
    ty
    checkingExpType String
    err ExpType
    et         = String -> SDoc -> Kind
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "checkingExpType" (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    err SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ ExpType -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ExpType
    et)

    scaledExpTypeToType :: Scaled ExpType -> TcM (Scaled TcType)
    scaledExpTypeToType :: Scaled ExpType -> TcM (Scaled Kind)
    scaledExpTypeToType (Scaled Kind
    m ExpType
    exp_ty)
      = do { Kind
    ty <- ExpType -> TcM Kind
    expTypeToType ExpType
    exp_ty
           ; Scaled Kind -> TcM (Scaled Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Kind -> Kind -> Scaled Kind
    forall a. Kind -> a -> Scaled a
    Scaled Kind
    m Kind
    ty) }

    -- | Extracts the expected type if there is one, or generates a new
    -- TauTv if there isn't.
    expTypeToType :: ExpType -> TcM TcType
    expTypeToType :: ExpType -> TcM Kind
    expTypeToType (Check Kind
    ty)      = Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Kind
    ty
    expTypeToType (Infer InferResult
    inf_res) = InferResult -> TcM Kind
    inferResultToType InferResult
    inf_res

    inferResultToType :: InferResult -> TcM Type
    inferResultToType :: InferResult -> TcM Kind
    inferResultToType (IR { ir_uniq :: InferResult -> Unique
    ir_uniq = Unique
    u, ir_lvl :: InferResult -> TcLevel
    ir_lvl = TcLevel
    tc_lvl
                          , ir_ref :: InferResult -> IORef (Maybe Kind)
    ir_ref = IORef (Maybe Kind)
    ref
                          , ir_frr :: InferResult -> Maybe FixedRuntimeRepContext
    ir_frr = Maybe FixedRuntimeRepContext
    mb_frr })
      = do { Maybe Kind
    mb_inferred_ty <- IORef (Maybe Kind) -> TcM (Maybe Kind)
    forall a gbl lcl. TcRef a -> TcRnIf gbl lcl a
    readTcRef IORef (Maybe Kind)
    ref
           ; Kind
    tau <- case Maybe Kind
    mb_inferred_ty of
                Just Kind
    ty -> do { Kind -> TcRn ()
    ensureMonoType Kind
    ty
                                -- See Note [inferResultToType]
                              ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Kind
    ty }
                Maybe Kind
    Nothing -> do { Kind
    tau <- TcM Kind
    new_meta
                              ; IORef (Maybe Kind) -> Maybe Kind -> TcRn ()
    forall a env. IORef a -> a -> IOEnv env ()
    writeMutVar IORef (Maybe Kind)
    ref (Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    tau)
                              ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Kind
    tau }
           ; String -> SDoc -> TcRn ()
    traceTc String
    "Forcing ExpType to be monomorphic:"
                     (Unique -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Unique
    u SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    ":=" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    tau)
           ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Kind
    tau }
      where
        -- See Note [TcLevel of ExpType]
        new_meta :: TcM Kind
    new_meta = case Maybe FixedRuntimeRepContext
    mb_frr of
          Maybe FixedRuntimeRepContext
    Nothing  ->  do { Kind
    rr  <- TcLevel -> Kind -> TcM Kind
    newMetaTyVarTyAtLevel TcLevel
    tc_lvl Kind
    runtimeRepTy
                          ; TcLevel -> Kind -> TcM Kind
    newMetaTyVarTyAtLevel TcLevel
    tc_lvl (Kind -> Kind
    mkTYPEapp Kind
    rr) }
          Just FixedRuntimeRepContext
    frr -> mdo { Kind
    rr  <- ConcreteTvOrigin -> TcLevel -> Kind -> TcM Kind
    newConcreteTyVarAtLevel ConcreteTvOrigin
    conc_orig TcLevel
    tc_lvl Kind
    runtimeRepTy
                          ; Kind
    tau <- TcLevel -> Kind -> TcM Kind
    newMetaTyVarTyAtLevel TcLevel
    tc_lvl (Kind -> Kind
    mkTYPEapp Kind
    rr)
                          ; let conc_orig :: ConcreteTvOrigin
    conc_orig = FixedRuntimeRepOrigin -> ConcreteTvOrigin
    ConcreteFRR (FixedRuntimeRepOrigin -> ConcreteTvOrigin)
    -> FixedRuntimeRepOrigin -> ConcreteTvOrigin
    forall a b. (a -> b) -> a -> b
    $ Kind -> FixedRuntimeRepContext -> FixedRuntimeRepOrigin
    FixedRuntimeRepOrigin Kind
    tau FixedRuntimeRepContext
    frr
                          ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Kind
    tau }

    {- Note [inferResultToType]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    expTypeToType and inferResultType convert an InferResult to a monotype.
    It must be a monotype because if the InferResult isn't already filled in,
    we fill it in with a unification variable (hence monotype).  So to preserve
    order-independence we check for mono-type-ness even if it *is* filled in
    already.

    See also Note [TcLevel of ExpType] above, and
    Note [fillInferResult] in GHC.Tc.Utils.Unify.
    -}

    -- | Infer a type using a fresh ExpType
    -- See also Note [ExpType] in "GHC.Tc.Utils.TcMType"
    --
    -- Use 'tcInferFRR' if you require the type to have a fixed
    -- runtime representation.
    tcInfer :: (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType)
    tcInfer :: forall a. (ExpType -> TcM a) -> TcM (a, Kind)
    tcInfer = Maybe FixedRuntimeRepContext -> (ExpType -> TcM a) -> TcM (a, Kind)
    forall a.
    Maybe FixedRuntimeRepContext -> (ExpType -> TcM a) -> TcM (a, Kind)
    tc_infer Maybe FixedRuntimeRepContext
    forall a. Maybe a
    Nothing

    -- | Like 'tcInfer', except it ensures that the resulting type
    -- has a syntactically fixed RuntimeRep as per Note [Fixed RuntimeRep] in
    -- GHC.Tc.Utils.Concrete.
    tcInferFRR :: FixedRuntimeRepContext -> (ExpSigmaTypeFRR -> TcM a) -> TcM (a, TcSigmaTypeFRR)
    tcInferFRR :: forall a.
    FixedRuntimeRepContext -> (ExpType -> TcM a) -> TcM (a, Kind)
    tcInferFRR FixedRuntimeRepContext
    frr_orig = Maybe FixedRuntimeRepContext -> (ExpType -> TcM a) -> TcM (a, Kind)
    forall a.
    Maybe FixedRuntimeRepContext -> (ExpType -> TcM a) -> TcM (a, Kind)
    tc_infer (FixedRuntimeRepContext -> Maybe FixedRuntimeRepContext
    forall a. a -> Maybe a
    Just FixedRuntimeRepContext
    frr_orig)

    tc_infer :: Maybe FixedRuntimeRepContext -> (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType)
    tc_infer :: forall a.
    Maybe FixedRuntimeRepContext -> (ExpType -> TcM a) -> TcM (a, Kind)
    tc_infer Maybe FixedRuntimeRepContext
    mb_frr ExpType -> TcM a
    tc_check
      = do { ExpType
    res_ty <- Maybe FixedRuntimeRepContext -> TcM ExpType
    new_inferExpType Maybe FixedRuntimeRepContext
    mb_frr
           ; a
    result <- ExpType -> TcM a
    tc_check ExpType
    res_ty
           ; Kind
    res_ty <- ExpType -> TcM Kind
    readExpType ExpType
    res_ty
           ; (a, Kind) -> TcM (a, Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    result, Kind
    res_ty) }

    {- *********************************************************************
    *                                                                      *
                  Promoting types
    *                                                                      *
    ********************************************************************* -}

    ensureMonoType :: TcType -> TcM ()
    -- Assuming that the argument type is of kind (TYPE r),
    -- ensure that it is a /monotype/
    -- If it is not a monotype we can see right away (since unification
    -- variables and type-function applications stand for monotypes), but
    -- we emit a Wanted equality just to delay the error message until later
    ensureMonoType :: Kind -> TcRn ()
    ensureMonoType Kind
    res_ty
      | Kind -> Bool
    isTauTy Kind
    res_ty   -- isTauTy doesn't need zonking or anything
      = () -> TcRn ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      | Bool
    otherwise
      = do { Kind
    mono_ty <- TcM Kind
    newOpenFlexiTyVarTy
           ; let eq_orig :: CtOrigin
    eq_orig = TypeEqOrigin { uo_actual :: Kind
    uo_actual   = Kind
    res_ty
                                        , uo_expected :: Kind
    uo_expected = Kind
    mono_ty
                                        , uo_thing :: Maybe TypedThing
    uo_thing    = Maybe TypedThing
    forall a. Maybe a
    Nothing
                                        , uo_visible :: Bool
    uo_visible  = Bool
    False }

           ; Coercion
    _co <- CtOrigin
    -> TypeOrKind
    -> Role
    -> Kind
    -> Kind
    -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    emitWantedEq CtOrigin
    eq_orig TypeOrKind
    TypeLevel Role
    Nominal Kind
    res_ty Kind
    mono_ty
           ; () -> TcRn ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return () }

    promoteTcType :: TcLevel -> TcType -> TcM (TcCoercionN, TcType)
    -- See Note [Promoting a type]
    -- See also Note [fillInferResult]
    -- promoteTcType level ty = (co, ty')
    --   * Returns ty'  whose max level is just 'level'
    --             and  whose kind is ~# to the kind of 'ty'
    --             and  whose kind has form TYPE rr
    --   * and co :: ty ~ ty'
    --   * and emits constraints to justify the coercion
    --
    -- NB: we expect that 'ty' has already kind (TYPE rr) for
    --     some rr::RuntimeRep.  It is, after all, the type of a term.
    promoteTcType :: TcLevel -> Kind -> TcM (Coercion, Kind)
    promoteTcType TcLevel
    dest_lvl Kind
    ty
      = do { TcLevel
    cur_lvl <- TcM TcLevel
    getTcLevel
           ; if (TcLevel
    cur_lvl TcLevel -> TcLevel -> Bool
    `sameDepthAs` TcLevel
    dest_lvl)
             then (Coercion, Kind) -> TcM (Coercion, Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Kind -> Coercion
    mkNomReflCo Kind
    ty, Kind
    ty)
             else TcM (Coercion, Kind)
    promote_it }
      where
        promote_it :: TcM (TcCoercion, TcType)
        promote_it :: TcM (Coercion, Kind)
    promote_it  -- Emit a constraint  (alpha :: TYPE rr) ~ ty
                    -- where alpha and rr are fresh and from level dest_lvl
          = do { Kind
    rr      <- TcLevel -> Kind -> TcM Kind
    newMetaTyVarTyAtLevel TcLevel
    dest_lvl Kind
    runtimeRepTy
               ; Kind
    prom_ty <- TcLevel -> Kind -> TcM Kind
    newMetaTyVarTyAtLevel TcLevel
    dest_lvl (Kind -> Kind
    mkTYPEapp Kind
    rr)
               ; let eq_orig :: CtOrigin
    eq_orig = TypeEqOrigin { uo_actual :: Kind
    uo_actual   = Kind
    ty
                                            , uo_expected :: Kind
    uo_expected = Kind
    prom_ty
                                            , uo_thing :: Maybe TypedThing
    uo_thing    = Maybe TypedThing
    forall a. Maybe a
    Nothing
                                            , uo_visible :: Bool
    uo_visible  = Bool
    False }

               ; Coercion
    co <- CtOrigin
    -> TypeOrKind
    -> Role
    -> Kind
    -> Kind
    -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    emitWantedEq CtOrigin
    eq_orig TypeOrKind
    TypeLevel Role
    Nominal Kind
    ty Kind
    prom_ty
               ; (Coercion, Kind) -> TcM (Coercion, Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Coercion
    co, Kind
    prom_ty) }

    {- Note [Promoting a type]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider (#12427)

      data T where
        MkT :: (Int -> Int) -> a -> T

      h y = case y of MkT v w -> v

    We'll infer the RHS type with an expected type ExpType of
      (IR { ir_lvl = l, ir_ref = ref, ... )
    where 'l' is the TcLevel of the RHS of 'h'.  Then the MkT pattern
    match will increase the level, so we'll end up in tcSubType, trying to
    unify the type of v,
      v :: Int -> Int
    with the expected type.  But this attempt takes place at level (l+1),
    rightly so, since v's type could have mentioned existential variables,
    (like w's does) and we want to catch that.

    So we
      - create a new meta-var alpha[l+1]
      - fill in the InferRes ref cell 'ref' with alpha
      - emit an equality constraint, thus
            [W] alpha[l+1] ~ (Int -> Int)

    That constraint will float outwards, as it should, unless v's
    type mentions a skolem-captured variable.

    This approach fails if v has a higher rank type; see
    Note [Promotion and higher rank types]

    Note [Promotion and higher rank types]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If v had a higher-rank type, say v :: (forall a. a->a) -> Int,
    then we'd emit an equality
            [W] alpha[l+1] ~ ((forall a. a->a) -> Int)
    which will sadly fail because we can't unify a unification variable
    with a polytype.  But there is nothing really wrong with the program
    here.

    We could just about solve this by "promote the type" of v, to expose
    its polymorphic "shape" while still leaving constraints that will
    prevent existential escape.  But we must be careful!  Exposing
    the "shape" of the type is precisely what we must NOT do under
    a GADT pattern match!  So in this case we might promote the type
    to
            (forall a. a->a) -> alpha[l+1]
    and emit the constraint
            [W] alpha[l+1] ~ Int
    Now the promoted type can fill the ref cell, while the emitted
    equality can float or not, according to the usual rules.

    But that's not quite right!  We are exposing the arrow! We could
    deal with that too:
            (forall a. mu[l+1] a a) -> alpha[l+1]
    with constraints
            [W] alpha[l+1] ~ Int
            [W] mu[l+1] ~ (->)
    Here we abstract over the '->' inside the forall, in case that
    is subject to an equality constraint from a GADT match.

    Note that we kept the outer (->) because that's part of
    the polymorphic "shape".  And because of impredicativity,
    GADT matches can't give equalities that affect polymorphic
    shape.

    This reasoning just seems too complicated, so I decided not
    to do it.  These higher-rank notes are just here to record
    the thinking.
    -}

    {- *********************************************************************
    *                                                                      *
            MetaTvs (meta type variables; mutable)
    *                                                                      *
    ********************************************************************* -}

    {- Note [TyVarTv]
    ~~~~~~~~~~~~~~~~~
    A TyVarTv can unify with type *variables* only, including other TyVarTvs and
    skolems.  They are used in two places:

    1. In kind signatures, see GHC.Tc.TyCl
          Note [Inferring kinds for type declarations]
       and Note [Using TyVarTvs for kind-checking GADTs]

    2. In partial type signatures.  See GHC.Tc.Types
       Note [Quantified variables in partial type signatures]

    Sometimes, they can unify with type variables that the user would
    rather keep distinct; see #11203 for an example.  So, any client of
    this function needs to either allow the TyVarTvs to unify with each
    other or check that they don't. In the case of (1) the check is done
    in GHC.Tc.TyCl.swizzleTcTyConBndrs.  In case of (2) it's done by
    findDupTyVarTvs in GHC.Tc.Gen.Bind.chooseInferredQuantifiers.

    Historical note: Before #15050 this (under the name SigTv) was also
    used for ScopedTypeVariables in patterns, to make sure these type
    variables only refer to other type variables, but this restriction was
    dropped, and ScopedTypeVariables can now refer to full types (GHC
    Proposal 29).
    -}

    newMetaTyVarName :: FastString -> TcM Name
    -- Makes a /System/ Name, which is eagerly eliminated by
    -- the unifier; see GHC.Tc.Utils.Unify.nicer_to_update_tv1, and
    -- GHC.Tc.Solver.Canonical.canEqTyVarTyVar (nicer_to_update_tv2)
    newMetaTyVarName :: FastString -> TcM Name
    newMetaTyVarName FastString
    str
      = do { Unique
    uniq <- TcRnIf TcGblEnv TcLclEnv Unique
    forall gbl lcl. TcRnIf gbl lcl Unique
    newUnique
           ; Name -> TcM Name
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Unique -> OccName -> Name
    mkSystemName Unique
    uniq (FastString -> OccName
    mkTyVarOccFS FastString
    str)) }

    cloneMetaTyVarName :: Name -> TcM Name
    cloneMetaTyVarName :: Name -> TcM Name
    cloneMetaTyVarName Name
    name
      = do { Unique
    uniq <- TcRnIf TcGblEnv TcLclEnv Unique
    forall gbl lcl. TcRnIf gbl lcl Unique
    newUnique
           ; Name -> TcM Name
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Unique -> OccName -> Name
    mkSystemName Unique
    uniq (Name -> OccName
    nameOccName Name
    name)) }
             -- See Note [Name of an instantiated type variable]

    {- Note [Name of an instantiated type variable]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    At the moment we give a unification variable a System Name, which
    influences the way it is tidied; see TypeRep.tidyTyVarBndr.
    -}

    metaInfoToTyVarName :: MetaInfo -> FastString
    metaInfoToTyVarName :: MetaInfo -> FastString
    metaInfoToTyVarName  MetaInfo
    meta_info =
      case MetaInfo
    meta_info of
           MetaInfo
    TauTv          -> String -> FastString
    fsLit String
    "t"
           MetaInfo
    TyVarTv        -> String -> FastString
    fsLit String
    "a"
           MetaInfo
    RuntimeUnkTv   -> String -> FastString
    fsLit String
    "r"
           MetaInfo
    CycleBreakerTv -> String -> FastString
    fsLit String
    "b"
           ConcreteTv {}  -> String -> FastString
    fsLit String
    "c"

    newAnonMetaTyVar :: MetaInfo -> Kind -> TcM TcTyVar
    newAnonMetaTyVar :: MetaInfo -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newAnonMetaTyVar MetaInfo
    mi = FastString
    -> MetaInfo -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newNamedAnonMetaTyVar (MetaInfo -> FastString
    metaInfoToTyVarName MetaInfo
    mi) MetaInfo
    mi

    newNamedAnonMetaTyVar :: FastString -> MetaInfo -> Kind -> TcM TcTyVar
    -- Make a new meta tyvar out of thin air
    newNamedAnonMetaTyVar :: FastString
    -> MetaInfo -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newNamedAnonMetaTyVar FastString
    tyvar_name MetaInfo
    meta_info Kind
    kind

      = do  { Name
    name    <- FastString -> TcM Name
    newMetaTyVarName FastString
    tyvar_name
            ; TcTyVarDetails
    details <- MetaInfo -> TcM TcTyVarDetails
    newMetaDetails MetaInfo
    meta_info
            ; let tyvar :: TyVar
    tyvar = Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name Kind
    kind TcTyVarDetails
    details
            ; String -> SDoc -> TcRn ()
    traceTc String
    "newAnonMetaTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar)
            ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyVar
    tyvar }

    -- makes a new skolem tv
    newSkolemTyVar :: SkolemInfo -> Name -> Kind -> TcM TcTyVar
    newSkolemTyVar :: SkolemInfo -> Name -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newSkolemTyVar SkolemInfo
    skol_info Name
    name Kind
    kind
      = do { TcLevel
    lvl <- TcM TcLevel
    getTcLevel
           ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name Kind
    kind (SkolemInfo -> TcLevel -> Bool -> TcTyVarDetails
    SkolemTv SkolemInfo
    skol_info TcLevel
    lvl Bool
    False)) }

    newTyVarTyVar :: Name -> Kind -> TcM TcTyVar
    -- See Note [TyVarTv]
    -- Does not clone a fresh unique
    newTyVarTyVar :: Name -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newTyVarTyVar Name
    name Kind
    kind
      = do { TcTyVarDetails
    details <- MetaInfo -> TcM TcTyVarDetails
    newMetaDetails MetaInfo
    TyVarTv
           ; let tyvar :: TyVar
    tyvar = Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name Kind
    kind TcTyVarDetails
    details
           ; String -> SDoc -> TcRn ()
    traceTc String
    "newTyVarTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar)
           ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyVar
    tyvar }

    cloneTyVarTyVar :: Name -> Kind -> TcM TcTyVar
    -- See Note [TyVarTv]
    -- Clones a fresh unique
    cloneTyVarTyVar :: Name -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    cloneTyVarTyVar Name
    name Kind
    kind
      = do { TcTyVarDetails
    details <- MetaInfo -> TcM TcTyVarDetails
    newMetaDetails MetaInfo
    TyVarTv
           ; Unique
    uniq <- TcRnIf TcGblEnv TcLclEnv Unique
    forall gbl lcl. TcRnIf gbl lcl Unique
    newUnique
           ; let name' :: Name
    name' = Name
    name Name -> Unique -> Name
    `setNameUnique` Unique
    uniq
                 tyvar :: TyVar
    tyvar = Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name' Kind
    kind TcTyVarDetails
    details
             -- Don't use cloneMetaTyVar, which makes a SystemName
             -- We want to keep the original more user-friendly Name
             -- In practical terms that means that in error messages,
             -- when the Name is tidied we get 'a' rather than 'a0'
           ; String -> SDoc -> TcRn ()
    traceTc String
    "cloneTyVarTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar)
           ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyVar
    tyvar }

    -- | Create a new metavariable, of the given kind, which can only be unified
    -- with a concrete type.
    --
    -- Invariant: the kind must be concrete, as per Note [ConcreteTv].
    -- This is checked with an assertion.
    newConcreteTyVar :: HasDebugCallStack => ConcreteTvOrigin -> TcKind -> TcM TcTyVar
    newConcreteTyVar :: (() :: Constraint) =>
    ConcreteTvOrigin -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newConcreteTyVar ConcreteTvOrigin
    reason Kind
    kind =
      Bool
    -> SDoc
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (Kind -> Bool
    isConcrete Kind
    kind)
        (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "newConcreteTyVar: non-concrete kind" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    kind)
      (IOEnv (Env TcGblEnv TcLclEnv) TyVar
     -> IOEnv (Env TcGblEnv TcLclEnv) TyVar)
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a b. (a -> b) -> a -> b
    $ MetaInfo -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newAnonMetaTyVar (ConcreteTvOrigin -> MetaInfo
    ConcreteTv ConcreteTvOrigin
    reason) Kind
    kind

    newPatSigTyVar :: Name -> Kind -> TcM TcTyVar
    newPatSigTyVar :: Name -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newPatSigTyVar Name
    name Kind
    kind
      = do { TcTyVarDetails
    details <- MetaInfo -> TcM TcTyVarDetails
    newMetaDetails MetaInfo
    TauTv
           ; Unique
    uniq <- TcRnIf TcGblEnv TcLclEnv Unique
    forall gbl lcl. TcRnIf gbl lcl Unique
    newUnique
           ; let name' :: Name
    name' = Name
    name Name -> Unique -> Name
    `setNameUnique` Unique
    uniq
                 tyvar :: TyVar
    tyvar = Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name' Kind
    kind TcTyVarDetails
    details
             -- Don't use cloneMetaTyVar;
             -- same reasoning as in newTyVarTyVar
           ; String -> SDoc -> TcRn ()
    traceTc String
    "newPatSigTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar)
           ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyVar
    tyvar }

    cloneAnonMetaTyVar :: MetaInfo -> TyVar -> TcKind -> TcM TcTyVar
    -- Make a fresh MetaTyVar, basing the name
    -- on that of the supplied TyVar
    cloneAnonMetaTyVar :: MetaInfo -> TyVar -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    cloneAnonMetaTyVar MetaInfo
    info TyVar
    tv Kind
    kind
      = do  { TcTyVarDetails
    details <- MetaInfo -> TcM TcTyVarDetails
    newMetaDetails MetaInfo
    info
            ; Name
    name    <- Name -> TcM Name
    cloneMetaTyVarName (TyVar -> Name
    tyVarName TyVar
    tv)
            ; let tyvar :: TyVar
    tyvar = Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name Kind
    kind TcTyVarDetails
    details
            ; String -> SDoc -> TcRn ()
    traceTc String
    "cloneAnonMetaTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc
    dcolon SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (TyVar -> Kind
    tyVarKind TyVar
    tyvar))
            ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyVar
    tyvar }

    -- Make a new CycleBreakerTv. See Note [Type equality cycles]
    -- in GHC.Tc.Solver.Canonical.
    newCycleBreakerTyVar :: TcKind -> TcM TcTyVar
    newCycleBreakerTyVar :: Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newCycleBreakerTyVar Kind
    kind
      = do { TcTyVarDetails
    details <- MetaInfo -> TcM TcTyVarDetails
    newMetaDetails MetaInfo
    CycleBreakerTv
           ; Name
    name <- FastString -> TcM Name
    newMetaTyVarName (String -> FastString
    fsLit String
    "cbv")
           ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name Kind
    kind TcTyVarDetails
    details) }

    newMetaDetails :: MetaInfo -> TcM TcTyVarDetails
    newMetaDetails :: MetaInfo -> TcM TcTyVarDetails
    newMetaDetails MetaInfo
    info
      = do { IORef MetaDetails
    ref <- MetaDetails -> IOEnv (Env TcGblEnv TcLclEnv) (IORef MetaDetails)
    forall a env. a -> IOEnv env (IORef a)
    newMutVar MetaDetails
    Flexi
           ; TcLevel
    tclvl <- TcM TcLevel
    getTcLevel
           ; TcTyVarDetails -> TcM TcTyVarDetails
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (MetaTv { mtv_info :: MetaInfo
    mtv_info = MetaInfo
    info
                            , mtv_ref :: IORef MetaDetails
    mtv_ref = IORef MetaDetails
    ref
                            , mtv_tclvl :: TcLevel
    mtv_tclvl = TcLevel
    tclvl }) }

    newTauTvDetailsAtLevel :: TcLevel -> TcM TcTyVarDetails
    newTauTvDetailsAtLevel :: TcLevel -> TcM TcTyVarDetails
    newTauTvDetailsAtLevel TcLevel
    tclvl
      = do { IORef MetaDetails
    ref <- MetaDetails -> IOEnv (Env TcGblEnv TcLclEnv) (IORef MetaDetails)
    forall a env. a -> IOEnv env (IORef a)
    newMutVar MetaDetails
    Flexi
           ; TcTyVarDetails -> TcM TcTyVarDetails
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (MetaTv { mtv_info :: MetaInfo
    mtv_info  = MetaInfo
    TauTv
                            , mtv_ref :: IORef MetaDetails
    mtv_ref   = IORef MetaDetails
    ref
                            , mtv_tclvl :: TcLevel
    mtv_tclvl = TcLevel
    tclvl }) }

    newConcreteTvDetailsAtLevel :: ConcreteTvOrigin -> TcLevel -> TcM TcTyVarDetails
    newConcreteTvDetailsAtLevel :: ConcreteTvOrigin -> TcLevel -> TcM TcTyVarDetails
    newConcreteTvDetailsAtLevel ConcreteTvOrigin
    conc_orig TcLevel
    tclvl
      = do { IORef MetaDetails
    ref <- MetaDetails -> IOEnv (Env TcGblEnv TcLclEnv) (IORef MetaDetails)
    forall a env. a -> IOEnv env (IORef a)
    newMutVar MetaDetails
    Flexi
           ; TcTyVarDetails -> TcM TcTyVarDetails
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (MetaTv { mtv_info :: MetaInfo
    mtv_info  = ConcreteTvOrigin -> MetaInfo
    ConcreteTv ConcreteTvOrigin
    conc_orig
                            , mtv_ref :: IORef MetaDetails
    mtv_ref   = IORef MetaDetails
    ref
                            , mtv_tclvl :: TcLevel
    mtv_tclvl = TcLevel
    tclvl }) }

    cloneMetaTyVar :: TcTyVar -> TcM TcTyVar
    cloneMetaTyVar :: TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    cloneMetaTyVar TyVar
    tv
      = Bool
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. HasCallStack => Bool -> a -> a
    assert (TyVar -> Bool
    isTcTyVar TyVar
    tv) (IOEnv (Env TcGblEnv TcLclEnv) TyVar
     -> IOEnv (Env TcGblEnv TcLclEnv) TyVar)
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a b. (a -> b) -> a -> b
    $
        do  { IORef MetaDetails
    ref  <- MetaDetails -> IOEnv (Env TcGblEnv TcLclEnv) (IORef MetaDetails)
    forall a env. a -> IOEnv env (IORef a)
    newMutVar MetaDetails
    Flexi
            ; Name
    name' <- Name -> TcM Name
    cloneMetaTyVarName (TyVar -> Name
    tyVarName TyVar
    tv)
            ; let details' :: TcTyVarDetails
    details' = case TyVar -> TcTyVarDetails
    tcTyVarDetails TyVar
    tv of
                               details :: TcTyVarDetails
    details@(MetaTv {}) -> TcTyVarDetails
    details { mtv_ref = ref }
                               TcTyVarDetails
    _ -> String -> SDoc -> TcTyVarDetails
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "cloneMetaTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv)
                  tyvar :: TyVar
    tyvar = Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name' (TyVar -> Kind
    tyVarKind TyVar
    tv) TcTyVarDetails
    details'
            ; String -> SDoc -> TcRn ()
    traceTc String
    "cloneMetaTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar)
            ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyVar
    tyvar }

    -- Works for both type and kind variables
    readMetaTyVar :: TyVar -> TcM MetaDetails
    readMetaTyVar :: TyVar -> TcM MetaDetails
    readMetaTyVar TyVar
    tyvar = Bool -> SDoc -> TcM MetaDetails -> TcM MetaDetails
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (TyVar -> Bool
    isMetaTyVar TyVar
    tyvar) (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar) (TcM MetaDetails -> TcM MetaDetails)
    -> TcM MetaDetails -> TcM MetaDetails
    forall a b. (a -> b) -> a -> b
    $
                          IORef MetaDetails -> TcM MetaDetails
    forall a env. IORef a -> IOEnv env a
    readMutVar (TyVar -> IORef MetaDetails
    metaTyVarRef TyVar
    tyvar)

    isFilledMetaTyVar_maybe :: TcTyVar -> TcM (Maybe Type)
    isFilledMetaTyVar_maybe :: TyVar -> TcM (Maybe Kind)
    isFilledMetaTyVar_maybe TyVar
    tv
    -- TODO: This should be an assertion that tv is definitely a TcTyVar but it fails
    -- at the moment (Jan 22)
     | TyVar -> Bool
    isTcTyVar TyVar
    tv
     , MetaTv { mtv_ref :: TcTyVarDetails -> IORef MetaDetails
    mtv_ref = IORef MetaDetails
    ref } <- TyVar -> TcTyVarDetails
    tcTyVarDetails TyVar
    tv
     = do { MetaDetails
    cts <- IORef MetaDetails -> TcM MetaDetails
    forall a gbl lcl. TcRef a -> TcRnIf gbl lcl a
    readTcRef IORef MetaDetails
    ref
          ; case MetaDetails
    cts of
              Indirect Kind
    ty -> Maybe Kind -> TcM (Maybe Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    ty)
              MetaDetails
    Flexi       -> Maybe Kind -> TcM (Maybe Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Kind
    forall a. Maybe a
    Nothing }
     | Bool
    otherwise
     = Maybe Kind -> TcM (Maybe Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Kind
    forall a. Maybe a
    Nothing

    isFilledMetaTyVar :: TyVar -> TcM Bool
    -- True of a filled-in (Indirect) meta type variable
    isFilledMetaTyVar :: TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    isFilledMetaTyVar TyVar
    tv = Maybe Kind -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe Kind -> Bool)
    -> TcM (Maybe Kind) -> TcRnIf TcGblEnv TcLclEnv Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> TyVar -> TcM (Maybe Kind)
    isFilledMetaTyVar_maybe TyVar
    tv

    isUnfilledMetaTyVar :: TyVar -> TcM Bool
    -- True of a un-filled-in (Flexi) meta type variable
    -- NB: Not the opposite of isFilledMetaTyVar
    isUnfilledMetaTyVar :: TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    isUnfilledMetaTyVar TyVar
    tv
      | MetaTv { mtv_ref :: TcTyVarDetails -> IORef MetaDetails
    mtv_ref = IORef MetaDetails
    ref } <- TyVar -> TcTyVarDetails
    tcTyVarDetails TyVar
    tv
      = do  { MetaDetails
    details <- IORef MetaDetails -> TcM MetaDetails
    forall a env. IORef a -> IOEnv env a
    readMutVar IORef MetaDetails
    ref
            ; Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (MetaDetails -> Bool
    isFlexi MetaDetails
    details) }
      | Bool
    otherwise = Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

    --------------------
    -- Works with both type and kind variables
    writeMetaTyVar :: HasDebugCallStack => TcTyVar -> TcType -> TcM ()
    -- Write into a currently-empty MetaTyVar

    writeMetaTyVar :: (() :: Constraint) => TyVar -> Kind -> TcRn ()
    writeMetaTyVar TyVar
    tyvar Kind
    ty
      | Bool -> Bool
    not Bool
    debugIsOn
      = (() :: Constraint) => TyVar -> IORef MetaDetails -> Kind -> TcRn ()
    TyVar -> IORef MetaDetails -> Kind -> TcRn ()
    writeMetaTyVarRef TyVar
    tyvar (TyVar -> IORef MetaDetails
    metaTyVarRef TyVar
    tyvar) Kind
    ty

    -- Everything from here on only happens if DEBUG is on
      | Bool -> Bool
    not (TyVar -> Bool
    isTcTyVar TyVar
    tyvar)
      = Bool -> SDoc -> TcRn ()
    forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr Bool
    False (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Writing to non-tc tyvar" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar)

      | MetaTv { mtv_ref :: TcTyVarDetails -> IORef MetaDetails
    mtv_ref = IORef MetaDetails
    ref } <- TyVar -> TcTyVarDetails
    tcTyVarDetails TyVar
    tyvar
      = (() :: Constraint) => TyVar -> IORef MetaDetails -> Kind -> TcRn ()
    TyVar -> IORef MetaDetails -> Kind -> TcRn ()
    writeMetaTyVarRef TyVar
    tyvar IORef MetaDetails
    ref Kind
    ty

      | Bool
    otherwise
      = Bool -> SDoc -> TcRn ()
    forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr Bool
    False (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Writing to non-meta tyvar" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar)

    --------------------
    writeMetaTyVarRef :: HasDebugCallStack => TcTyVar -> TcRef MetaDetails -> TcType -> TcM ()
    -- Here the tyvar is for error checking only;
    -- the ref cell must be for the same tyvar
    writeMetaTyVarRef :: (() :: Constraint) => TyVar -> IORef MetaDetails -> Kind -> TcRn ()
    writeMetaTyVarRef TyVar
    tyvar IORef MetaDetails
    ref Kind
    ty
      | Bool -> Bool
    not Bool
    debugIsOn
      = do { String -> SDoc -> TcRn ()
    traceTc String
    "writeMetaTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc
    dcolon SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (TyVar -> Kind
    tyVarKind TyVar
    tyvar)
                                       SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    ":=" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    ty)
           ; IORef MetaDetails -> MetaDetails -> TcRn ()
    forall a gbl lcl. TcRef a -> a -> TcRnIf gbl lcl ()
    writeTcRef IORef MetaDetails
    ref (Kind -> MetaDetails
    Indirect Kind
    ty) }

      -- Everything from here on only happens if DEBUG is on
      -- Need to zonk 'ty' because we may only recently have promoted
      -- its free meta-tyvars (see Solver.Interact.tryToSolveByUnification)
      | Bool
    otherwise
      = do { MetaDetails
    meta_details <- IORef MetaDetails -> TcM MetaDetails
    forall a env. IORef a -> IOEnv env a
    readMutVar IORef MetaDetails
    ref;
           -- Zonk kinds to allow the error check to work
           ; Kind
    zonked_tv_kind <- Kind -> TcM Kind
    zonkTcType Kind
    tv_kind
           ; Kind
    zonked_ty      <- Kind -> TcM Kind
    zonkTcType Kind
    ty
           ; let zonked_ty_kind :: Kind
    zonked_ty_kind = (() :: Constraint) => Kind -> Kind
    Kind -> Kind
    typeKind Kind
    zonked_ty
                 zonked_ty_lvl :: TcLevel
    zonked_ty_lvl  = Kind -> TcLevel
    tcTypeLevel Kind
    zonked_ty
                 level_check_ok :: Bool
    level_check_ok  = Bool -> Bool
    not (TcLevel
    zonked_ty_lvl TcLevel -> TcLevel -> Bool
    `strictlyDeeperThan` TcLevel
    tv_lvl)
                 level_check_msg :: SDoc
    level_check_msg = TcLevel -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TcLevel
    zonked_ty_lvl SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ TcLevel -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TcLevel
    tv_lvl SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    ty
                 kind_check_ok :: Bool
    kind_check_ok = Kind
    zonked_ty_kind Kind -> Kind -> Bool
    `eqType` Kind
    zonked_tv_kind
                 -- Note [Extra-constraint holes in partial type signatures] in GHC.Tc.Gen.HsType

                 kind_msg :: SDoc
    kind_msg = SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Ill-kinded update to meta tyvar")
                               Int
    2 (    TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "::" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> (Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    tv_kind SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    zonked_tv_kind)
                                  SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    ":="
                                  SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    ty SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "::" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> (Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    zonked_ty_kind) )

           ; String -> SDoc -> TcRn ()
    traceTc String
    "writeMetaTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    ":=" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    ty)

           -- Check for double updates
           ; Bool -> SDoc -> TcRn ()
    forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr (MetaDetails -> Bool
    isFlexi MetaDetails
    meta_details) (MetaDetails -> SDoc
    double_upd_msg MetaDetails
    meta_details)

           -- Check for level OK
           ; Bool -> SDoc -> TcRn ()
    forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr Bool
    level_check_ok SDoc
    level_check_msg

           -- Check Kinds ok
           ; Bool -> SDoc -> TcRn ()
    forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr Bool
    kind_check_ok SDoc
    kind_msg

           -- Do the write
           ; IORef MetaDetails -> MetaDetails -> TcRn ()
    forall a env. IORef a -> a -> IOEnv env ()
    writeMutVar IORef MetaDetails
    ref (Kind -> MetaDetails
    Indirect Kind
    ty) }
      where
        tv_kind :: Kind
    tv_kind = TyVar -> Kind
    tyVarKind TyVar
    tyvar

        tv_lvl :: TcLevel
    tv_lvl = TyVar -> TcLevel
    tcTyVarLevel TyVar
    tyvar

        double_upd_msg :: MetaDetails -> SDoc
    double_upd_msg MetaDetails
    details = SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Double update of meta tyvar")
                                    Int
    2 (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tyvar SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ MetaDetails -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr MetaDetails
    details)

    {-
    ************************************************************************
    *                                                                      *
            MetaTvs: TauTvs
    *                                                                      *
    ************************************************************************

    Note [Never need to instantiate coercion variables]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    With coercion variables sloshing around in types, it might seem that we
    sometimes need to instantiate coercion variables. This would be problematic,
    because coercion variables inhabit unboxed equality (~#), and the constraint
    solver thinks in terms only of boxed equality (~). The solution is that
    we never need to instantiate coercion variables in the first place.

    The tyvars that we need to instantiate come from the types of functions,
    data constructors, and patterns. These will never be quantified over
    coercion variables, except for the special case of the promoted Eq#. But,
    that can't ever appear in user code, so we're safe!
    -}

    newMultiplicityVar :: TcM TcType
    newMultiplicityVar :: TcM Kind
    newMultiplicityVar = Kind -> TcM Kind
    newFlexiTyVarTy Kind
    multiplicityTy

    newFlexiTyVar :: Kind -> TcM TcTyVar
    newFlexiTyVar :: Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newFlexiTyVar Kind
    kind = MetaInfo -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newAnonMetaTyVar MetaInfo
    TauTv Kind
    kind

    -- | Create a new flexi ty var with a specific name
    newNamedFlexiTyVar :: FastString -> Kind -> TcM TcTyVar
    newNamedFlexiTyVar :: FastString -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newNamedFlexiTyVar FastString
    fs Kind
    kind = FastString
    -> MetaInfo -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newNamedAnonMetaTyVar FastString
    fs MetaInfo
    TauTv Kind
    kind

    newFlexiTyVarTy :: Kind -> TcM TcType
    newFlexiTyVarTy :: Kind -> TcM Kind
    newFlexiTyVarTy Kind
    kind = do
        TyVar
    tc_tyvar <- Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newFlexiTyVar Kind
    kind
        Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVar -> Kind
    mkTyVarTy TyVar
    tc_tyvar)

    newFlexiTyVarTys :: Int -> Kind -> TcM [TcType]
    newFlexiTyVarTys :: Int -> Kind -> TcM [Kind]
    newFlexiTyVarTys Int
    n Kind
    kind = Int -> TcM Kind -> TcM [Kind]
    forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
    replicateM Int
    n (Kind -> TcM Kind
    newFlexiTyVarTy Kind
    kind)

    newOpenTypeKind :: TcM TcKind
    newOpenTypeKind :: TcM Kind
    newOpenTypeKind
      = do { Kind
    rr <- Kind -> TcM Kind
    newFlexiTyVarTy Kind
    runtimeRepTy
           ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Kind -> Kind
    mkTYPEapp Kind
    rr) }

    -- | Create a tyvar that can be a lifted or unlifted type.
    -- Returns alpha :: TYPE kappa, where both alpha and kappa are fresh
    newOpenFlexiTyVarTy :: TcM TcType
    newOpenFlexiTyVarTy :: TcM Kind
    newOpenFlexiTyVarTy
      = do { TyVar
    tv <- IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newOpenFlexiTyVar
           ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVar -> Kind
    mkTyVarTy TyVar
    tv) }

    newOpenFlexiTyVar :: TcM TcTyVar
    newOpenFlexiTyVar :: IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newOpenFlexiTyVar
      = do { Kind
    kind <- TcM Kind
    newOpenTypeKind
           ; Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newFlexiTyVar Kind
    kind }

    newOpenBoxedTypeKind :: TcM TcKind
    newOpenBoxedTypeKind :: TcM Kind
    newOpenBoxedTypeKind
      = do { Kind
    lev <- Kind -> TcM Kind
    newFlexiTyVarTy (TyCon -> Kind
    mkTyConTy TyCon
    levityTyCon)
           ; let rr :: Kind
    rr = TyCon -> [Kind] -> Kind
    mkTyConApp TyCon
    boxedRepDataConTyCon [Kind
    lev]
           ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Kind -> Kind
    mkTYPEapp Kind
    rr) }

    newMetaTyVars :: [TyVar] -> TcM (Subst, [TcTyVar])
    -- Instantiate with META type variables
    -- Note that this works for a sequence of kind, type, and coercion variables
    -- variables.  Eg    [ (k:*), (a:k->k) ]
    --             Gives [ (k7:*), (a8:k7->k7) ]
    newMetaTyVars :: [TyVar] -> TcM (Subst, [TyVar])
    newMetaTyVars = Subst -> [TyVar] -> TcM (Subst, [TyVar])
    newMetaTyVarsX Subst
    emptySubst
        -- emptySubst has an empty in-scope set, but that's fine here
        -- Since the tyvars are freshly made, they cannot possibly be
        -- captured by any existing for-alls.

    newMetaTyVarsX :: Subst -> [TyVar] -> TcM (Subst, [TcTyVar])
    -- Just like newMetaTyVars, but start with an existing substitution.
    newMetaTyVarsX :: Subst -> [TyVar] -> TcM (Subst, [TyVar])
    newMetaTyVarsX Subst
    subst = (Subst -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar))
    -> Subst -> [TyVar] -> TcM (Subst, [TyVar])
    forall (m :: * -> *) (t :: * -> *) acc x y.
    (Monad m, Traversable t) =>
    (acc -> x -> m (acc, y)) -> acc -> t x -> m (acc, t y)
    mapAccumLM Subst -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar)
    newMetaTyVarX Subst
    subst

    newMetaTyVarX :: Subst -> TyVar -> TcM (Subst, TcTyVar)
    -- Make a new unification variable tyvar whose Name and Kind come from
    -- an existing TyVar. We substitute kind variables in the kind.
    newMetaTyVarX :: Subst -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar)
    newMetaTyVarX = MetaInfo
    -> Subst -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar)
    new_meta_tv_x MetaInfo
    TauTv

    newMetaTyVarTyVarX :: Subst -> TyVar -> TcM (Subst, TcTyVar)
    -- Just like newMetaTyVarX, but make a TyVarTv
    newMetaTyVarTyVarX :: Subst -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar)
    newMetaTyVarTyVarX = MetaInfo
    -> Subst -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar)
    new_meta_tv_x MetaInfo
    TyVarTv

    newWildCardX :: Subst -> TyVar -> TcM (Subst, TcTyVar)
    newWildCardX :: Subst -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar)
    newWildCardX Subst
    subst TyVar
    tv
      = do { TyVar
    new_tv <- MetaInfo -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    newAnonMetaTyVar MetaInfo
    TauTv ((() :: Constraint) => Subst -> Kind -> Kind
    Subst -> Kind -> Kind
    substTy Subst
    subst (TyVar -> Kind
    tyVarKind TyVar
    tv))
           ; (Subst, TyVar) -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Subst -> TyVar -> TyVar -> Subst
    extendTvSubstWithClone Subst
    subst TyVar
    tv TyVar
    new_tv, TyVar
    new_tv) }

    new_meta_tv_x :: MetaInfo -> Subst -> TyVar -> TcM (Subst, TcTyVar)
    new_meta_tv_x :: MetaInfo
    -> Subst -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar)
    new_meta_tv_x MetaInfo
    info Subst
    subst TyVar
    tv
      = do  { TyVar
    new_tv <- MetaInfo -> TyVar -> Kind -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    cloneAnonMetaTyVar MetaInfo
    info TyVar
    tv Kind
    substd_kind
            ; let subst1 :: Subst
    subst1 = Subst -> TyVar -> TyVar -> Subst
    extendTvSubstWithClone Subst
    subst TyVar
    tv TyVar
    new_tv
            ; (Subst, TyVar) -> IOEnv (Env TcGblEnv TcLclEnv) (Subst, TyVar)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Subst
    subst1, TyVar
    new_tv) }
      where
        substd_kind :: Kind
    substd_kind = Subst -> Kind -> Kind
    substTyUnchecked Subst
    subst (TyVar -> Kind
    tyVarKind TyVar
    tv)
          -- NOTE: #12549 is fixed so we could use
          -- substTy here, but the tc_infer_args problem
          -- is not yet fixed so leaving as unchecked for now.
          -- OLD NOTE:
          -- Unchecked because we call newMetaTyVarX from
          -- tcInstTyBinder, which is called from tcInferTyApps
          -- which does not yet take enough trouble to ensure
          -- the in-scope set is right; e.g. #12785 trips
          -- if we use substTy here

    newMetaTyVarTyAtLevel :: TcLevel -> TcKind -> TcM TcType
    newMetaTyVarTyAtLevel :: TcLevel -> Kind -> TcM Kind
    newMetaTyVarTyAtLevel TcLevel
    tc_lvl Kind
    kind
      = do  { TcTyVarDetails
    details <- TcLevel -> TcM TcTyVarDetails
    newTauTvDetailsAtLevel TcLevel
    tc_lvl
            ; Name
    name    <- FastString -> TcM Name
    newMetaTyVarName (String -> FastString
    fsLit String
    "p")
            ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVar -> Kind
    mkTyVarTy (Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name Kind
    kind TcTyVarDetails
    details)) }

    newConcreteTyVarAtLevel :: ConcreteTvOrigin -> TcLevel -> TcKind -> TcM TcType
    newConcreteTyVarAtLevel :: ConcreteTvOrigin -> TcLevel -> Kind -> TcM Kind
    newConcreteTyVarAtLevel ConcreteTvOrigin
    conc_orig TcLevel
    tc_lvl Kind
    kind
      = do  { TcTyVarDetails
    details <- ConcreteTvOrigin -> TcLevel -> TcM TcTyVarDetails
    newConcreteTvDetailsAtLevel ConcreteTvOrigin
    conc_orig TcLevel
    tc_lvl
            ; Name
    name    <- FastString -> TcM Name
    newMetaTyVarName (String -> FastString
    fsLit String
    "c")
            ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVar -> Kind
    mkTyVarTy (Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name Kind
    kind TcTyVarDetails
    details)) }

    {- *********************************************************************
    *                                                                      *
              Finding variables to quantify over
    *                                                                      *
    ********************************************************************* -}

    {- Note [Dependent type variables]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In Haskell type inference we quantify over type variables; but we only
    quantify over /kind/ variables when -XPolyKinds is on.  Without -XPolyKinds
    we default the kind variables to *.

    So, to support this defaulting, and only for that reason, when
    collecting the free vars of a type (in candidateQTyVarsOfType and friends),
    prior to quantifying, we must keep the type and kind variables separate.

    But what does that mean in a system where kind variables /are/ type
    variables? It's a fairly arbitrary distinction based on how the
    variables appear:

      - "Kind variables" appear in the kind of some other free variable
        or in the kind of a locally quantified type variable
        (forall (a :: kappa). ...) or in the kind of a coercion
        (a |> (co :: kappa1 ~ kappa2)).

         These are the ones we default to * if -XPolyKinds is off

      - "Type variables" are all free vars that are not kind variables

    E.g.  In the type    T k (a::k)
          'k' is a kind variable, because it occurs in the kind of 'a',
              even though it also appears at "top level" of the type
          'a' is a type variable, because it doesn't

    We gather these variables using a CandidatesQTvs record:
      DV { dv_kvs: Variables free in the kind of a free type variable
                   or of a forall-bound type variable
         , dv_tvs: Variables syntactically free in the type }

    So:  dv_kvs            are the kind variables of the type
         (dv_tvs - dv_kvs) are the type variable of the type

    Note that

    * A variable can occur in both.
          T k (x::k)    The first occurrence of k makes it
                        show up in dv_tvs, the second in dv_kvs

    * We include any coercion variables in the "dependent",
      "kind-variable" set because we never quantify over them.

    * The "kind variables" might depend on each other; e.g
         (k1 :: k2), (k2 :: *)
      The "type variables" do not depend on each other; if
      one did, it'd be classified as a kind variable!

    Note [CandidatesQTvs determinism and order]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    * Determinism: when we quantify over type variables we decide the
      order in which they appear in the final type. Because the order of
      type variables in the type can end up in the interface file and
      affects some optimizations like worker-wrapper, we want this order to
      be deterministic.

      To achieve that we use deterministic sets of variables that can be
      converted to lists in a deterministic order. For more information
      about deterministic sets see Note [Deterministic UniqFM] in GHC.Types.Unique.DFM.

    * Order: as well as being deterministic, we use an
      accumulating-parameter style for candidateQTyVarsOfType so that we
      add variables one at a time, left to right.  That means we tend to
      produce the variables in left-to-right order.  This is just to make
      it bit more predictable for the programmer.

    Note [Naughty quantification candidates]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider (#14880, dependent/should_compile/T14880-2), suppose
    we are trying to generalise this type:

      forall arg. ... (alpha[tau]:arg) ...

    We have a metavariable alpha whose kind mentions a skolem variable
    bound inside the very type we are generalising.
    This can arise while type-checking a user-written type signature
    (see the test case for the full code).

    We cannot generalise over alpha!  That would produce a type like
      forall {a :: arg}. forall arg. ...blah...
    The fact that alpha's kind mentions arg renders it completely
    ineligible for generalisation.

    However, we are not going to learn any new constraints on alpha,
    because its kind isn't even in scope in the outer context (but see Wrinkle).
    So alpha is entirely unconstrained.

    What then should we do with alpha?  During generalization, every
    metavariable is either (A) promoted, (B) generalized, or (C) zapped
    (according to Note [Recipe for checking a signature] in GHC.Tc.Gen.HsType).

     * We can't generalise it.
     * We can't promote it, because its kind prevents that
     * We can't simply leave it be, because this type is about to
       go into the typing environment (as the type of some let-bound
       variable, say), and then chaos erupts when we try to instantiate.

    Previously, we zapped it to Any. This worked, but it had the unfortunate
    effect of causing Any sometimes to appear in error messages. If this
    kind of signature happens, the user probably has made a mistake -- no
    one really wants Any in their types. So we now error. This must be
    a hard error (failure in the monad) to avoid other messages from mentioning
    Any.

    We do this eager erroring in candidateQTyVars, which always precedes
    generalisation, because at that moment we have a clear picture of what
    skolems are in scope within the type itself (e.g. that 'forall arg').

    This change is inspired by and described in Section 7.2 of "Kind Inference
    for Datatypes", POPL'20.

    NB: this is all rather similar to, but sadly not the same as
        Note [Error on unconstrained meta-variables]

    Wrinkle:

    We must make absolutely sure that alpha indeed is not
    from an outer context. (Otherwise, we might indeed learn more information
    about it.) This can be done easily: we just check alpha's TcLevel.
    That level must be strictly greater than the ambient TcLevel in order
    to treat it as naughty. We say "strictly greater than" because the call to
    candidateQTyVars is made outside the bumped TcLevel, as stated in the
    comment to candidateQTyVarsOfType. The level check is done in go_tv
    in collect_cand_qtvs. Skipping this check caused #16517.

    -}

    data CandidatesQTvs
      -- See Note [Dependent type variables]
      -- See Note [CandidatesQTvs determinism and order]
      --
      -- Invariants:
      --   * All variables are fully zonked, including their kinds
      --   * All variables are at a level greater than the ambient level
      --     See Note [Use level numbers for quantification]
      --
      -- This *can* contain skolems. For example, in `data X k :: k -> Type`
      -- we need to know that the k is a dependent variable. This is done
      -- by collecting the candidates in the kind after skolemising. It also
      -- comes up when generalizing a associated type instance, where instance
      -- variables are skolems. (Recall that associated type instances are generalized
      -- independently from their enclosing class instance, and the associated
      -- type instance may be generalized by more, fewer, or different variables
      -- than the class instance.)
      --
      = DV { CandidatesQTvs -> DTyVarSet
    dv_kvs :: DTyVarSet    -- "kind" metavariables (dependent)
           , CandidatesQTvs -> DTyVarSet
    dv_tvs :: DTyVarSet    -- "type" metavariables (non-dependent)
             -- A variable may appear in both sets
             -- E.g.   T k (x::k)    The first occurrence of k makes it
             --                      show up in dv_tvs, the second in dv_kvs
             -- See Note [Dependent type variables]

           , CandidatesQTvs -> CoVarSet
    dv_cvs :: CoVarSet
             -- These are covars. Included only so that we don't repeatedly
             -- look at covars' kinds in accumulator. Not used by quantifyTyVars.
        }

    instance Semi.Semigroup CandidatesQTvs where
       (DV { dv_kvs :: CandidatesQTvs -> DTyVarSet
    dv_kvs = DTyVarSet
    kv1, dv_tvs :: CandidatesQTvs -> DTyVarSet
    dv_tvs = DTyVarSet
    tv1, dv_cvs :: CandidatesQTvs -> CoVarSet
    dv_cvs = CoVarSet
    cv1 })
         <> :: CandidatesQTvs -> CandidatesQTvs -> CandidatesQTvs
    <> (DV { dv_kvs :: CandidatesQTvs -> DTyVarSet
    dv_kvs = DTyVarSet
    kv2, dv_tvs :: CandidatesQTvs -> DTyVarSet
    dv_tvs = DTyVarSet
    tv2, dv_cvs :: CandidatesQTvs -> CoVarSet
    dv_cvs = CoVarSet
    cv2 })
              = DV { dv_kvs :: DTyVarSet
    dv_kvs = DTyVarSet
    kv1 DTyVarSet -> DTyVarSet -> DTyVarSet
    `unionDVarSet` DTyVarSet
    kv2
                   , dv_tvs :: DTyVarSet
    dv_tvs = DTyVarSet
    tv1 DTyVarSet -> DTyVarSet -> DTyVarSet
    `unionDVarSet` DTyVarSet
    tv2
                   , dv_cvs :: CoVarSet
    dv_cvs = CoVarSet
    cv1 CoVarSet -> CoVarSet -> CoVarSet
    `unionVarSet` CoVarSet
    cv2 }

    instance Monoid CandidatesQTvs where
       mempty :: CandidatesQTvs
    mempty = DV { dv_kvs :: DTyVarSet
    dv_kvs = DTyVarSet
    emptyDVarSet, dv_tvs :: DTyVarSet
    dv_tvs = DTyVarSet
    emptyDVarSet, dv_cvs :: CoVarSet
    dv_cvs = CoVarSet
    emptyVarSet }
       mappend :: CandidatesQTvs -> CandidatesQTvs -> CandidatesQTvs
    mappend = CandidatesQTvs -> CandidatesQTvs -> CandidatesQTvs
    forall a. Semigroup a => a -> a -> a
    (Semi.<>)

    instance Outputable CandidatesQTvs where
      ppr :: CandidatesQTvs -> SDoc
    ppr (DV {dv_kvs :: CandidatesQTvs -> DTyVarSet
    dv_kvs = DTyVarSet
    kvs, dv_tvs :: CandidatesQTvs -> DTyVarSet
    dv_tvs = DTyVarSet
    tvs, dv_cvs :: CandidatesQTvs -> CoVarSet
    dv_cvs = CoVarSet
    cvs })
        = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "DV" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    braces ((SDoc -> SDoc) -> [SDoc] -> SDoc
    forall a. (a -> SDoc) -> [a] -> SDoc
    pprWithCommas SDoc -> SDoc
    forall a. a -> a
    id [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "dv_kvs =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> DTyVarSet -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr DTyVarSet
    kvs
                                                 , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "dv_tvs =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> DTyVarSet -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr DTyVarSet
    tvs
                                                 , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "dv_cvs =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> CoVarSet -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr CoVarSet
    cvs ])

    isEmptyCandidates :: CandidatesQTvs -> Bool
    isEmptyCandidates :: CandidatesQTvs -> Bool
    isEmptyCandidates (DV { dv_kvs :: CandidatesQTvs -> DTyVarSet
    dv_kvs = DTyVarSet
    kvs, dv_tvs :: CandidatesQTvs -> DTyVarSet
    dv_tvs = DTyVarSet
    tvs })
      = DTyVarSet -> Bool
    isEmptyDVarSet DTyVarSet
    kvs Bool -> Bool -> Bool
    && DTyVarSet -> Bool
    isEmptyDVarSet DTyVarSet
    tvs

    -- | Extract out the kind vars (in order) and type vars (in order) from
    -- a 'CandidatesQTvs'. The lists are guaranteed to be distinct. Keeping
    -- the lists separate is important only in the -XNoPolyKinds case.
    candidateVars :: CandidatesQTvs -> ([TcTyVar], [TcTyVar])
    candidateVars :: CandidatesQTvs -> ([TyVar], [TyVar])
    candidateVars (DV { dv_kvs :: CandidatesQTvs -> DTyVarSet
    dv_kvs = DTyVarSet
    dep_kv_set, dv_tvs :: CandidatesQTvs -> DTyVarSet
    dv_tvs = DTyVarSet
    nondep_tkv_set })
      = ([TyVar]
    dep_kvs, [TyVar]
    nondep_tvs)
      where
        dep_kvs :: [TyVar]
    dep_kvs = [TyVar] -> [TyVar]
    scopedSort ([TyVar] -> [TyVar]) -> [TyVar] -> [TyVar]
    forall a b. (a -> b) -> a -> b
    $ DTyVarSet -> [TyVar]
    dVarSetElems DTyVarSet
    dep_kv_set
          -- scopedSort: put the kind variables into
          --    well-scoped order.
          --    E.g.  [k, (a::k)] not the other way round

        nondep_tvs :: [TyVar]
    nondep_tvs = DTyVarSet -> [TyVar]
    dVarSetElems (DTyVarSet
    nondep_tkv_set DTyVarSet -> DTyVarSet -> DTyVarSet
    `minusDVarSet` DTyVarSet
    dep_kv_set)
          -- See Note [Dependent type variables]
          -- The `minus` dep_tkvs removes any kind-level vars
          --    e.g. T k (a::k)   Since k appear in a kind it'll
          --    be in dv_kvs, and is dependent. So remove it from
          --    dv_tvs which will also contain k
          -- NB kinds of tvs are already zonked

    candidateKindVars :: CandidatesQTvs -> TyVarSet
    candidateKindVars :: CandidatesQTvs -> CoVarSet
    candidateKindVars CandidatesQTvs
    dvs = DTyVarSet -> CoVarSet
    dVarSetToVarSet (CandidatesQTvs -> DTyVarSet
    dv_kvs CandidatesQTvs
    dvs)

    delCandidates :: CandidatesQTvs -> [Var] -> CandidatesQTvs
    delCandidates :: CandidatesQTvs -> [TyVar] -> CandidatesQTvs
    delCandidates (DV { dv_kvs :: CandidatesQTvs -> DTyVarSet
    dv_kvs = DTyVarSet
    kvs, dv_tvs :: CandidatesQTvs -> DTyVarSet
    dv_tvs = DTyVarSet
    tvs, dv_cvs :: CandidatesQTvs -> CoVarSet
    dv_cvs = CoVarSet
    cvs }) [TyVar]
    vars
      = DV { dv_kvs :: DTyVarSet
    dv_kvs = DTyVarSet
    kvs DTyVarSet -> [TyVar] -> DTyVarSet
    `delDVarSetList` [TyVar]
    vars
           , dv_tvs :: DTyVarSet
    dv_tvs = DTyVarSet
    tvs DTyVarSet -> [TyVar] -> DTyVarSet
    `delDVarSetList` [TyVar]
    vars
           , dv_cvs :: CoVarSet
    dv_cvs = CoVarSet
    cvs CoVarSet -> [TyVar] -> CoVarSet
    `delVarSetList`  [TyVar]
    vars }

    partitionCandidates :: CandidatesQTvs -> (TyVar -> Bool) -> (TyVarSet, CandidatesQTvs)
    -- The selected TyVars are returned as a non-deterministic TyVarSet
    partitionCandidates :: CandidatesQTvs -> (TyVar -> Bool) -> (CoVarSet, CandidatesQTvs)
    partitionCandidates dvs :: CandidatesQTvs
    dvs@(DV { dv_kvs :: CandidatesQTvs -> DTyVarSet
    dv_kvs = DTyVarSet
    kvs, dv_tvs :: CandidatesQTvs -> DTyVarSet
    dv_tvs = DTyVarSet
    tvs }) TyVar -> Bool
    pred
      = (CoVarSet
    extracted, CandidatesQTvs
    dvs { dv_kvs = rest_kvs, dv_tvs = rest_tvs })
      where
        (DTyVarSet
    extracted_kvs, DTyVarSet
    rest_kvs) = (TyVar -> Bool) -> DTyVarSet -> (DTyVarSet, DTyVarSet)
    partitionDVarSet TyVar -> Bool
    pred DTyVarSet
    kvs
        (DTyVarSet
    extracted_tvs, DTyVarSet
    rest_tvs) = (TyVar -> Bool) -> DTyVarSet -> (DTyVarSet, DTyVarSet)
    partitionDVarSet TyVar -> Bool
    pred DTyVarSet
    tvs
        extracted :: CoVarSet
    extracted = DTyVarSet -> CoVarSet
    dVarSetToVarSet DTyVarSet
    extracted_kvs CoVarSet -> CoVarSet -> CoVarSet
    `unionVarSet` DTyVarSet -> CoVarSet
    dVarSetToVarSet DTyVarSet
    extracted_tvs

    candidateQTyVarsWithBinders :: [TyVar] -> Type -> TcM CandidatesQTvs
    -- (candidateQTyVarsWithBinders tvs ty) returns the candidateQTyVars
    -- of (forall tvs. ty), but do not treat 'tvs' as bound for the purpose
    -- of Note [Naughty quantification candidates].  Why?
    -- Because we are going to scoped-sort the quantified variables
    -- in among the tvs
    candidateQTyVarsWithBinders :: [TyVar] -> Kind -> TcM CandidatesQTvs
    candidateQTyVarsWithBinders [TyVar]
    bound_tvs Kind
    ty
      = do { CandidatesQTvs
    kvs <- [Kind] -> TcM CandidatesQTvs
    candidateQTyVarsOfKinds ((TyVar -> Kind) -> [TyVar] -> [Kind]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVar -> Kind
    tyVarKind [TyVar]
    bound_tvs)
           ; CandidatesQTvs
    all_tvs <- Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    ty Bool
    False CoVarSet
    emptyVarSet CandidatesQTvs
    kvs Kind
    ty
           ; CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CandidatesQTvs
    all_tvs CandidatesQTvs -> [TyVar] -> CandidatesQTvs
    `delCandidates` [TyVar]
    bound_tvs) }

    -- | Gathers free variables to use as quantification candidates (in
    -- 'quantifyTyVars'). This might output the same var
    -- in both sets, if it's used in both a type and a kind.
    -- The variables to quantify must have a TcLevel strictly greater than
    -- the ambient level. (See Wrinkle in Note [Naughty quantification candidates])
    -- See Note [CandidatesQTvs determinism and order]
    -- See Note [Dependent type variables]
    candidateQTyVarsOfType :: TcType       -- not necessarily zonked
                           -> TcM CandidatesQTvs
    candidateQTyVarsOfType :: Kind -> TcM CandidatesQTvs
    candidateQTyVarsOfType Kind
    ty = Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    ty Bool
    False CoVarSet
    emptyVarSet CandidatesQTvs
    forall a. Monoid a => a
    mempty Kind
    ty

    -- | Like 'candidateQTyVarsOfType', but over a list of types
    -- The variables to quantify must have a TcLevel strictly greater than
    -- the ambient level. (See Wrinkle in Note [Naughty quantification candidates])
    candidateQTyVarsOfTypes :: [Type] -> TcM CandidatesQTvs
    candidateQTyVarsOfTypes :: [Kind] -> TcM CandidatesQTvs
    candidateQTyVarsOfTypes [Kind]
    tys = (CandidatesQTvs -> Kind -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Kind] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM (\CandidatesQTvs
    acc Kind
    ty -> Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    ty Bool
    False CoVarSet
    emptyVarSet CandidatesQTvs
    acc Kind
    ty)
                                         CandidatesQTvs
    forall a. Monoid a => a
    mempty [Kind]
    tys

    -- | Like 'candidateQTyVarsOfType', but consider every free variable
    -- to be dependent. This is appropriate when generalizing a *kind*,
    -- instead of a type. (That way, -XNoPolyKinds will default the variables
    -- to Type.)
    candidateQTyVarsOfKind :: TcKind       -- Not necessarily zonked
                           -> TcM CandidatesQTvs
    candidateQTyVarsOfKind :: Kind -> TcM CandidatesQTvs
    candidateQTyVarsOfKind Kind
    ty = Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    ty Bool
    True CoVarSet
    emptyVarSet CandidatesQTvs
    forall a. Monoid a => a
    mempty Kind
    ty

    candidateQTyVarsOfKinds :: [TcKind]    -- Not necessarily zonked
                           -> TcM CandidatesQTvs
    candidateQTyVarsOfKinds :: [Kind] -> TcM CandidatesQTvs
    candidateQTyVarsOfKinds [Kind]
    tys = (CandidatesQTvs -> Kind -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Kind] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldM (\CandidatesQTvs
    acc Kind
    ty -> Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    ty Bool
    True CoVarSet
    emptyVarSet CandidatesQTvs
    acc Kind
    ty)
                                        CandidatesQTvs
    forall a. Monoid a => a
    mempty [Kind]
    tys

    collect_cand_qtvs
      :: TcType          -- original type that we started recurring into; for errors
      -> Bool            -- True <=> consider every fv in Type to be dependent
      -> VarSet          -- Bound variables (locals only)
      -> CandidatesQTvs  -- Accumulating parameter
      -> Type            -- Not necessarily zonked
      -> TcM CandidatesQTvs

    -- Key points:
    --   * Looks through meta-tyvars as it goes;
    --     no need to zonk in advance
    --
    --   * Needs to be monadic anyway, because it handles naughty
    --     quantification; see Note [Naughty quantification candidates]
    --
    --   * Returns fully-zonked CandidateQTvs, including their kinds
    --     so that subsequent dependency analysis (to build a well
    --     scoped telescope) works correctly

    collect_cand_qtvs :: Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty Bool
    is_dep CoVarSet
    bound CandidatesQTvs
    dvs Kind
    ty
      = CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    go CandidatesQTvs
    dvs Kind
    ty
      where
        is_bound :: TyVar -> Bool
    is_bound TyVar
    tv = TyVar
    tv TyVar -> CoVarSet -> Bool
    `elemVarSet` CoVarSet
    bound

        -----------------
        go :: CandidatesQTvs -> TcType -> TcM CandidatesQTvs
        -- Uses accumulating-parameter style
        go :: CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    go CandidatesQTvs
    dv (AppTy Kind
    t1 Kind
    t2)    = (CandidatesQTvs -> Kind -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Kind] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    go CandidatesQTvs
    dv [Kind
    t1, Kind
    t2]
        go CandidatesQTvs
    dv (TyConApp TyCon
    tc [Kind]
    tys) = CandidatesQTvs -> [TyConBinder] -> [Kind] -> TcM CandidatesQTvs
    go_tc_args CandidatesQTvs
    dv (TyCon -> [TyConBinder]
    tyConBinders TyCon
    tc) [Kind]
    tys
        go CandidatesQTvs
    dv (FunTy FunTyFlag
    _ Kind
    w Kind
    arg Kind
    res) = (CandidatesQTvs -> Kind -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Kind] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    go CandidatesQTvs
    dv [Kind
    w, Kind
    arg, Kind
    res]
        go CandidatesQTvs
    dv (LitTy {})        = CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv
        go CandidatesQTvs
    dv (CastTy Kind
    ty Coercion
    co)    = do CandidatesQTvs
    dv1 <- CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    go CandidatesQTvs
    dv Kind
    ty
                                     Kind
    -> CoVarSet -> CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    collect_cand_qtvs_co Kind
    orig_ty CoVarSet
    bound CandidatesQTvs
    dv1 Coercion
    co
        go CandidatesQTvs
    dv (CoercionTy Coercion
    co)   = Kind
    -> CoVarSet -> CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    collect_cand_qtvs_co Kind
    orig_ty CoVarSet
    bound CandidatesQTvs
    dv Coercion
    co

        go CandidatesQTvs
    dv (TyVarTy TyVar
    tv)
          | TyVar -> Bool
    is_bound TyVar
    tv = CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv
          | Bool
    otherwise   = do { Maybe Kind
    m_contents <- TyVar -> TcM (Maybe Kind)
    isFilledMetaTyVar_maybe TyVar
    tv
                             ; case Maybe Kind
    m_contents of
                                 Just Kind
    ind_ty -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    go CandidatesQTvs
    dv Kind
    ind_ty
                                 Maybe Kind
    Nothing     -> CandidatesQTvs -> TyVar -> TcM CandidatesQTvs
    go_tv CandidatesQTvs
    dv TyVar
    tv }

        go CandidatesQTvs
    dv (ForAllTy (Bndr TyVar
    tv ForAllTyFlag
    _) Kind
    ty)
          = do { CandidatesQTvs
    dv1 <- Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty Bool
    True CoVarSet
    bound CandidatesQTvs
    dv (TyVar -> Kind
    tyVarKind TyVar
    tv)
               ; Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty Bool
    is_dep (CoVarSet
    bound CoVarSet -> TyVar -> CoVarSet
    `extendVarSet` TyVar
    tv) CandidatesQTvs
    dv1 Kind
    ty }

          -- This makes sure that we default e.g. the alpha in Proxy alpha (Any alpha).
          -- Tested in polykinds/NestedProxies.
          -- We just might get this wrong in AppTy, but I don't think that's possible
          -- with -XNoPolyKinds. And fixing it would be non-performant, as we'd need
          -- to look at kinds.
        go_tc_args :: CandidatesQTvs -> [TyConBinder] -> [Kind] -> TcM CandidatesQTvs
    go_tc_args CandidatesQTvs
    dv (TyConBinder
    tc_bndr:[TyConBinder]
    tc_bndrs) (Kind
    ty:[Kind]
    tys)
          = do { CandidatesQTvs
    dv1 <- Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty (Bool
    is_dep Bool -> Bool -> Bool
    || TyConBinder -> Bool
    isNamedTyConBinder TyConBinder
    tc_bndr)
                                          CoVarSet
    bound CandidatesQTvs
    dv Kind
    ty
               ; CandidatesQTvs -> [TyConBinder] -> [Kind] -> TcM CandidatesQTvs
    go_tc_args CandidatesQTvs
    dv1 [TyConBinder]
    tc_bndrs [Kind]
    tys }
        go_tc_args CandidatesQTvs
    dv [TyConBinder]
    _bndrs [Kind]
    tys  -- _bndrs might be non-empty: undersaturation
                                  -- tys might be non-empty: oversaturation
                                  -- either way, the foldlM is correct
          = (CandidatesQTvs -> Kind -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Kind] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    go CandidatesQTvs
    dv [Kind]
    tys

        -----------------
        go_tv :: CandidatesQTvs -> TyVar -> TcM CandidatesQTvs
    go_tv dv :: CandidatesQTvs
    dv@(DV { dv_kvs :: CandidatesQTvs -> DTyVarSet
    dv_kvs = DTyVarSet
    kvs, dv_tvs :: CandidatesQTvs -> DTyVarSet
    dv_tvs = DTyVarSet
    tvs }) TyVar
    tv
          | TyVar
    tv TyVar -> DTyVarSet -> Bool
    `elemDVarSet` DTyVarSet
    kvs
          = CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv  -- We have met this tyvar already

          | Bool -> Bool
    not Bool
    is_dep
          , TyVar
    tv TyVar -> DTyVarSet -> Bool
    `elemDVarSet` DTyVarSet
    tvs
          = CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv  -- We have met this tyvar already

          | Bool
    otherwise
          = do { Kind
    tv_kind <- Kind -> TcM Kind
    zonkTcType (TyVar -> Kind
    tyVarKind TyVar
    tv)
                     -- This zonk is annoying, but it is necessary, both to
                     -- ensure that the collected candidates have zonked kinds
                     -- (#15795) and to make the naughty check
                     -- (which comes next) works correctly

               ; let tv_kind_vars :: CoVarSet
    tv_kind_vars = Kind -> CoVarSet
    tyCoVarsOfType Kind
    tv_kind
               ; TcLevel
    cur_lvl <- TcM TcLevel
    getTcLevel
               ; if |  TyVar -> TcLevel
    tcTyVarLevel TyVar
    tv TcLevel -> TcLevel -> Bool
    forall a. Ord a => a -> a -> Bool
    <= TcLevel
    cur_lvl
                    -> CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv   -- this variable is from an outer context; skip
                                   -- See Note [Use level numbers for quantification]

                    | case TyVar -> TcTyVarDetails
    tcTyVarDetails TyVar
    tv of
                         SkolemTv SkolemInfo
    _ TcLevel
    lvl Bool
    _ -> TcLevel
    lvl TcLevel -> TcLevel -> Bool
    forall a. Ord a => a -> a -> Bool
    > TcLevel -> TcLevel
    pushTcLevel TcLevel
    cur_lvl
                         TcTyVarDetails
    _                -> Bool
    False
                    -> CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv  -- Skip inner skolems; ToDo: explain

                    |  CoVarSet -> CoVarSet -> Bool
    intersectsVarSet CoVarSet
    bound CoVarSet
    tv_kind_vars
                       -- the tyvar must not be from an outer context, but we have
                       -- already checked for this.
                       -- See Note [Naughty quantification candidates]
                    -> do { String -> SDoc -> TcRn ()
    traceTc String
    "Naughty quantifier" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $
                              [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat [ TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc
    dcolon SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    tv_kind
                                   , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "bound:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [TyVar] -> SDoc
    pprTyVars (CoVarSet -> [TyVar]
    forall elt. UniqSet elt -> [elt]
    nonDetEltsUniqSet CoVarSet
    bound)
                                   , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "fvs:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [TyVar] -> SDoc
    pprTyVars (CoVarSet -> [TyVar]
    forall elt. UniqSet elt -> [elt]
    nonDetEltsUniqSet CoVarSet
    tv_kind_vars) ]

                          ; let escapees :: CoVarSet
    escapees = CoVarSet -> CoVarSet -> CoVarSet
    intersectVarSet CoVarSet
    bound CoVarSet
    tv_kind_vars
                          ; Kind -> TyVar -> CoVarSet -> TcM CandidatesQTvs
    forall a. Kind -> TyVar -> CoVarSet -> TcM a
    naughtyQuantification Kind
    orig_ty TyVar
    tv CoVarSet
    escapees }

                    |  Bool
    otherwise
                    -> do { let tv' :: TyVar
    tv' = TyVar
    tv TyVar -> Kind -> TyVar
    `setTyVarKind` Kind
    tv_kind
                                dv' :: CandidatesQTvs
    dv' | Bool
    is_dep    = CandidatesQTvs
    dv { dv_kvs = kvs `extendDVarSet` tv' }
                                    | Bool
    otherwise = CandidatesQTvs
    dv { dv_tvs = tvs `extendDVarSet` tv' }
                                    -- See Note [Order of accumulation]

                            -- See Note [Recurring into kinds for candidateQTyVars]
                          ; Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty Bool
    True CoVarSet
    bound CandidatesQTvs
    dv' Kind
    tv_kind } }

    collect_cand_qtvs_co :: TcType -- original type at top of recursion; for errors
                         -> VarSet -- bound variables
                         -> CandidatesQTvs -> Coercion
                         -> TcM CandidatesQTvs
    collect_cand_qtvs_co :: Kind
    -> CoVarSet -> CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    collect_cand_qtvs_co Kind
    orig_ty CoVarSet
    bound = CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co
      where
        go_co :: CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv (Refl Kind
    ty)               = Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty Bool
    True CoVarSet
    bound CandidatesQTvs
    dv Kind
    ty
        go_co CandidatesQTvs
    dv (GRefl Role
    _ Kind
    ty MCoercionN
    mco)        = do CandidatesQTvs
    dv1 <- Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty Bool
    True CoVarSet
    bound CandidatesQTvs
    dv Kind
    ty
                                              CandidatesQTvs -> MCoercionN -> TcM CandidatesQTvs
    go_mco CandidatesQTvs
    dv1 MCoercionN
    mco
        go_co CandidatesQTvs
    dv (TyConAppCo Role
    _ TyCon
    _ [Coercion]
    cos)    = (CandidatesQTvs -> Coercion -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Coercion] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv [Coercion]
    cos
        go_co CandidatesQTvs
    dv (AppCo Coercion
    co1 Coercion
    co2)         = (CandidatesQTvs -> Coercion -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Coercion] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv [Coercion
    co1, Coercion
    co2]
        go_co CandidatesQTvs
    dv (FunCo Role
    _ FunTyFlag
    _ FunTyFlag
    _ Coercion
    w Coercion
    co1 Coercion
    co2) = (CandidatesQTvs -> Coercion -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Coercion] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv [Coercion
    w, Coercion
    co1, Coercion
    co2]
        go_co CandidatesQTvs
    dv (AxiomInstCo CoAxiom Branched
    _ Int
    _ [Coercion]
    cos)   = (CandidatesQTvs -> Coercion -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Coercion] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv [Coercion]
    cos
        go_co CandidatesQTvs
    dv (AxiomRuleCo CoAxiomRule
    _ [Coercion]
    cos)     = (CandidatesQTvs -> Coercion -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Coercion] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv [Coercion]
    cos
        go_co CandidatesQTvs
    dv (UnivCo UnivCoProvenance
    prov Role
    _ Kind
    t1 Kind
    t2)   = do CandidatesQTvs
    dv1 <- CandidatesQTvs -> UnivCoProvenance -> TcM CandidatesQTvs
    go_prov CandidatesQTvs
    dv UnivCoProvenance
    prov
                                              CandidatesQTvs
    dv2 <- Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty Bool
    True CoVarSet
    bound CandidatesQTvs
    dv1 Kind
    t1
                                              Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty Bool
    True CoVarSet
    bound CandidatesQTvs
    dv2 Kind
    t2
        go_co CandidatesQTvs
    dv (SymCo Coercion
    co)              = CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    co
        go_co CandidatesQTvs
    dv (TransCo Coercion
    co1 Coercion
    co2)       = (CandidatesQTvs -> Coercion -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Coercion] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv [Coercion
    co1, Coercion
    co2]
        go_co CandidatesQTvs
    dv (SelCo CoSel
    _ Coercion
    co)            = CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    co
        go_co CandidatesQTvs
    dv (LRCo LeftOrRight
    _ Coercion
    co)             = CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    co
        go_co CandidatesQTvs
    dv (InstCo Coercion
    co1 Coercion
    co2)        = (CandidatesQTvs -> Coercion -> TcM CandidatesQTvs)
    -> CandidatesQTvs -> [Coercion] -> TcM CandidatesQTvs
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv [Coercion
    co1, Coercion
    co2]
        go_co CandidatesQTvs
    dv (KindCo Coercion
    co)             = CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    co
        go_co CandidatesQTvs
    dv (SubCo Coercion
    co)              = CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    co

        go_co CandidatesQTvs
    dv (HoleCo CoercionHole
    hole)
          = do Maybe Coercion
    m_co <- CoercionHole -> TcRnIf TcGblEnv TcLclEnv (Maybe Coercion)
    unpackCoercionHole_maybe CoercionHole
    hole
               case Maybe Coercion
    m_co of
                 Just Coercion
    co -> CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    co
                 Maybe Coercion
    Nothing -> CandidatesQTvs -> TyVar -> TcM CandidatesQTvs
    go_cv CandidatesQTvs
    dv (CoercionHole -> TyVar
    coHoleCoVar CoercionHole
    hole)

        go_co CandidatesQTvs
    dv (CoVarCo TyVar
    cv) = CandidatesQTvs -> TyVar -> TcM CandidatesQTvs
    go_cv CandidatesQTvs
    dv TyVar
    cv

        go_co CandidatesQTvs
    dv (ForAllCo TyVar
    tcv Coercion
    kind_co Coercion
    co)
          = do { CandidatesQTvs
    dv1 <- CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    kind_co
               ; Kind
    -> CoVarSet -> CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    collect_cand_qtvs_co Kind
    orig_ty (CoVarSet
    bound CoVarSet -> TyVar -> CoVarSet
    `extendVarSet` TyVar
    tcv) CandidatesQTvs
    dv1 Coercion
    co }

        go_mco :: CandidatesQTvs -> MCoercionN -> TcM CandidatesQTvs
    go_mco CandidatesQTvs
    dv MCoercionN
    MRefl    = CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv
        go_mco CandidatesQTvs
    dv (MCo Coercion
    co) = CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    co

        go_prov :: CandidatesQTvs -> UnivCoProvenance -> TcM CandidatesQTvs
    go_prov CandidatesQTvs
    dv (PhantomProv Coercion
    co)    = CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    co
        go_prov CandidatesQTvs
    dv (ProofIrrelProv Coercion
    co) = CandidatesQTvs -> Coercion -> TcM CandidatesQTvs
    go_co CandidatesQTvs
    dv Coercion
    co
        go_prov CandidatesQTvs
    dv (PluginProv String
    _)      = CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv
        go_prov CandidatesQTvs
    dv (CorePrepProv Bool
    _)    = CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv

        go_cv :: CandidatesQTvs -> CoVar -> TcM CandidatesQTvs
        go_cv :: CandidatesQTvs -> TyVar -> TcM CandidatesQTvs
    go_cv dv :: CandidatesQTvs
    dv@(DV { dv_cvs :: CandidatesQTvs -> CoVarSet
    dv_cvs = CoVarSet
    cvs }) TyVar
    cv
          | TyVar -> Bool
    is_bound TyVar
    cv         = CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv
          | TyVar
    cv TyVar -> CoVarSet -> Bool
    `elemVarSet` CoVarSet
    cvs = CandidatesQTvs -> TcM CandidatesQTvs
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CandidatesQTvs
    dv

            -- See Note [Recurring into kinds for candidateQTyVars]
          | Bool
    otherwise           = Kind
    -> Bool -> CoVarSet -> CandidatesQTvs -> Kind -> TcM CandidatesQTvs
    collect_cand_qtvs Kind
    orig_ty Bool
    True CoVarSet
    bound
                                        (CandidatesQTvs
    dv { dv_cvs = cvs `extendVarSet` cv })
                                        (TyVar -> Kind
    idType TyVar
    cv)

        is_bound :: TyVar -> Bool
    is_bound TyVar
    tv = TyVar
    tv TyVar -> CoVarSet -> Bool
    `elemVarSet` CoVarSet
    bound

    {- Note [Order of accumulation]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    You might be tempted (like I was) to use unitDVarSet and mappend
    rather than extendDVarSet.  However, the union algorithm for
    deterministic sets depends on (roughly) the size of the sets. The
    elements from the smaller set end up to the right of the elements from
    the larger one. When sets are equal, the left-hand argument to
    `mappend` goes to the right of the right-hand argument.

    In our case, if we use unitDVarSet and mappend, we learn that the free
    variables of (a -> b -> c -> d) are [b, a, c, d], and we then quantify
    over them in that order. (The a comes after the b because we union the
    singleton sets as ({a} `mappend` {b}), producing {b, a}. Thereafter,
    the size criterion works to our advantage.) This is just annoying to
    users, so I use `extendDVarSet`, which unambiguously puts the new
    element to the right.

    Note that the unitDVarSet/mappend implementation would not be wrong
    against any specification -- just suboptimal and confounding to users.

    Note [Recurring into kinds for candidateQTyVars]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    First, read Note [Closing over free variable kinds] in GHC.Core.TyCo.FVs, paying
    attention to the end of the Note about using an empty bound set when
    traversing a variable's kind.

    That Note concludes with the recommendation that we empty out the bound
    set when recurring into the kind of a type variable. Yet, we do not do
    this here. I have two tasks in order to convince you that this code is
    right. First, I must show why it is safe to ignore the reasoning in that
    Note. Then, I must show why is is necessary to contradict the reasoning in
    that Note.

    Why it is safe: There can be no
    shadowing in the candidateQ... functions: they work on the output of
    type inference, which is seeded by the renamer and its insistence to
    use different Uniques for different variables. (In contrast, the Core
    functions work on the output of optimizations, which may introduce
    shadowing.) Without shadowing, the problem studied by
    Note [Closing over free variable kinds] in GHC.Core.TyCo.FVs cannot happen.

    Why it is necessary:
    Wiping the bound set would be just plain wrong here. Consider

      forall k1 k2 (a :: k1). Proxy k2 (a |> (hole :: k1 ~# k2))

    We really don't want to think k1 and k2 are free here. (It's true that we'll
    never be able to fill in `hole`, but we don't want to go off the rails just
    because we have an insoluble coercion hole.) So: why is it wrong to wipe
    the bound variables here but right in Core? Because the final statement
    in Note [Closing over free variable kinds] in GHC.Core.TyCo.FVs is wrong: not
    every variable is either free or bound. A variable can be a hole, too!
    The reasoning in that Note then breaks down.

    And the reasoning applies just as well to free non-hole variables, so we
    retain the bound set always.

    -}

    {- *********************************************************************
    *                                                                      *
                 Quantification
    *                                                                      *
    ************************************************************************

    Note [quantifyTyVars]
    ~~~~~~~~~~~~~~~~~~~~~
    quantifyTyVars is given the free vars of a type that we
    are about to wrap in a forall.

    It takes these free type/kind variables (partitioned into dependent and
    non-dependent variables) skolemises metavariables with a TcLevel greater
    than the ambient level (see Note [Use level numbers for quantification]).

    * This function distinguishes between dependent and non-dependent
      variables only to keep correct defaulting behavior with -XNoPolyKinds.
      With -XPolyKinds, it treats both classes of variables identically.

    * quantifyTyVars never quantifies over
        - a coercion variable (or any tv mentioned in the kind of a covar)
        - a runtime-rep variable

    Note [Use level numbers for quantification]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The level numbers assigned to metavariables are very useful. Not only
    do they track touchability (Note [TcLevel invariants] in GHC.Tc.Utils.TcType),
    but they also allow us to determine which variables to
    generalise. The rule is this:

      When generalising, quantify only metavariables with a TcLevel greater
      than the ambient level.

    This works because we bump the level every time we go inside a new
    source-level construct. In a traditional generalisation algorithm, we
    would gather all free variables that aren't free in an environment.
    However, if a variable is in that environment, it will always have a lower
    TcLevel: it came from an outer scope. So we can replace the "free in
    environment" check with a level-number check.

    Here is an example:

      f x = x + (z True)
        where
          z y = x * x

    We start by saying (x :: alpha[1]). When inferring the type of z, we'll
    quickly discover that z :: alpha[1]. But it would be disastrous to
    generalise over alpha in the type of z. So we need to know that alpha
    comes from an outer environment. By contrast, the type of y is beta[2],
    and we are free to generalise over it. What's the difference between
    alpha[1] and beta[2]? Their levels. beta[2] has the right TcLevel for
    generalisation, and so we generalise it. alpha[1] does not, and so
    we leave it alone.

    Note that not *every* variable with a higher level will get
    generalised, either due to the monomorphism restriction or other
    quirks. See, for example, the code in GHC.Tc.Solver.decideMonoTyVars
    and in GHC.Tc.Gen.HsType.kindGeneralizeSome, both of which exclude
    certain otherwise-eligible variables from being generalised.

    Using level numbers for quantification is implemented in the candidateQTyVars...
    functions, by adding only those variables with a level strictly higher than
    the ambient level to the set of candidates.

    Note [quantifyTyVars determinism]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The results of quantifyTyVars are wrapped in a forall and can end up in the
    interface file. One such example is inferred type signatures. They also affect
    the results of optimizations, for example worker-wrapper. This means that to
    get deterministic builds quantifyTyVars needs to be deterministic.

    To achieve this CandidatesQTvs is backed by deterministic sets which allows them
    to be later converted to a list in a deterministic order.

    For more information about deterministic sets see
    Note [Deterministic UniqFM] in GHC.Types.Unique.DFM.
    -}

    quantifyTyVars :: SkolemInfo
                   -> NonStandardDefaultingStrategy
                   -> CandidatesQTvs   -- See Note [Dependent type variables]
                                       -- Already zonked
                   -> TcM [TcTyVar]
    -- See Note [quantifyTyVars]
    -- Can be given a mixture of TcTyVars and TyVars, in the case of
    --   associated type declarations. Also accepts covars, but *never* returns any.
    -- According to Note [Use level numbers for quantification] and the
    -- invariants on CandidateQTvs, we do not have to filter out variables
    -- free in the environment here. Just quantify unconditionally, subject
    -- to the restrictions in Note [quantifyTyVars].
    quantifyTyVars :: SkolemInfo
    -> NonStandardDefaultingStrategy -> CandidatesQTvs -> TcM [TyVar]
    quantifyTyVars SkolemInfo
    skol_info NonStandardDefaultingStrategy
    ns_strat CandidatesQTvs
    dvs
           -- short-circuit common case
      | CandidatesQTvs -> Bool
    isEmptyCandidates CandidatesQTvs
    dvs
      = do { String -> SDoc -> TcRn ()
    traceTc String
    "quantifyTyVars has nothing to quantify" SDoc
    forall doc. IsOutput doc => doc
    empty
           ; [TyVar] -> TcM [TyVar]
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [] }

      | Bool
    otherwise
      = do { String -> SDoc -> TcRn ()
    traceTc String
    "quantifyTyVars {"
               ( [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "ns_strat =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> NonStandardDefaultingStrategy -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr NonStandardDefaultingStrategy
    ns_strat
                      , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "dvs =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> CandidatesQTvs -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr CandidatesQTvs
    dvs ])

           ; [TyVar]
    undefaulted <- NonStandardDefaultingStrategy -> CandidatesQTvs -> TcM [TyVar]
    defaultTyVars NonStandardDefaultingStrategy
    ns_strat CandidatesQTvs
    dvs
           ; [TyVar]
    final_qtvs  <- (TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TyVar))
    -> [TyVar] -> TcM [TyVar]
    forall (m :: * -> *) a b.
    Applicative m =>
    (a -> m (Maybe b)) -> [a] -> m [b]
    mapMaybeM TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TyVar)
    zonk_quant [TyVar]
    undefaulted

           ; String -> SDoc -> TcRn ()
    traceTc String
    "quantifyTyVars }"
               ([SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "undefaulted:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [TyVar] -> SDoc
    pprTyVars [TyVar]
    undefaulted
                     , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "final_qtvs:"  SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [TyVar] -> SDoc
    pprTyVars [TyVar]
    final_qtvs ])

           -- We should never quantify over coercion variables; check this
           ; let co_vars :: [TyVar]
    co_vars = (TyVar -> Bool) -> [TyVar] -> [TyVar]
    forall a. (a -> Bool) -> [a] -> [a]
    filter TyVar -> Bool
    isCoVar [TyVar]
    final_qtvs
           ; Bool -> SDoc -> TcRn ()
    forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr ([TyVar] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TyVar]
    co_vars) ([TyVar] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [TyVar]
    co_vars)

           ; [TyVar] -> TcM [TyVar]
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [TyVar]
    final_qtvs }
      where
        -- zonk_quant returns a tyvar if it should be quantified over;
        -- otherwise, it returns Nothing. The latter case happens for
        -- non-meta-tyvars
        zonk_quant :: TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TyVar)
    zonk_quant TyVar
    tkv
          | Bool -> Bool
    not (TyVar -> Bool
    isTyVar TyVar
    tkv)
          = Maybe TyVar -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TyVar)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe TyVar
    forall a. Maybe a
    Nothing   -- this can happen for a covar that's associated with
                             -- a coercion hole. Test case: typecheck/should_compile/T2494

          | Bool
    otherwise
          = TyVar -> Maybe TyVar
    forall a. a -> Maybe a
    Just (TyVar -> Maybe TyVar)
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TyVar)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> SkolemInfo -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    skolemiseQuantifiedTyVar SkolemInfo
    skol_info TyVar
    tkv

    isQuantifiableTv :: TcLevel   -- Level of the context, outside the quantification
                     -> TcTyVar
                     -> Bool
    isQuantifiableTv :: TcLevel -> TyVar -> Bool
    isQuantifiableTv TcLevel
    outer_tclvl TyVar
    tcv
      | TyVar -> Bool
    isTcTyVar TyVar
    tcv  -- Might be a CoVar; change this when gather covars separately
      = TyVar -> TcLevel
    tcTyVarLevel TyVar
    tcv TcLevel -> TcLevel -> Bool
    forall a. Ord a => a -> a -> Bool
    > TcLevel
    outer_tclvl
      | Bool
    otherwise
      = Bool
    False

    zonkAndSkolemise :: SkolemInfo -> TcTyCoVar -> TcM TcTyCoVar
    -- A tyvar binder is never a unification variable (TauTv),
    -- rather it is always a skolem. It *might* be a TyVarTv.
    -- (Because non-CUSK type declarations use TyVarTvs.)
    -- Regardless, it may have a kind that has not yet been zonked,
    -- and may include kind unification variables.
    zonkAndSkolemise :: SkolemInfo -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkAndSkolemise SkolemInfo
    skol_info TyVar
    tyvar
      | TyVar -> Bool
    isTyVarTyVar TyVar
    tyvar
         -- We want to preserve the binding location of the original TyVarTv.
         -- This is important for error messages. If we don't do this, then
         -- we get bad locations in, e.g., typecheck/should_fail/T2688
      = do { TyVar
    zonked_tyvar <- (() :: Constraint) => TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTcTyVarToTcTyVar TyVar
    tyvar
           ; SkolemInfo -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    skolemiseQuantifiedTyVar SkolemInfo
    skol_info TyVar
    zonked_tyvar }

      | Bool
    otherwise
      = Bool
    -> SDoc
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (TyVar -> Bool
    isImmutableTyVar TyVar
    tyvar Bool -> Bool -> Bool
    || TyVar -> Bool
    isCoVar TyVar
    tyvar) (TyVar -> SDoc
    pprTyVar TyVar
    tyvar) (IOEnv (Env TcGblEnv TcLclEnv) TyVar
     -> IOEnv (Env TcGblEnv TcLclEnv) TyVar)
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a b. (a -> b) -> a -> b
    $
        TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTyCoVarKind TyVar
    tyvar

    skolemiseQuantifiedTyVar :: SkolemInfo -> TcTyVar -> TcM TcTyVar
    -- The quantified type variables often include meta type variables
    -- we want to freeze them into ordinary type variables
    -- The meta tyvar is updated to point to the new skolem TyVar.  Now any
    -- bound occurrences of the original type variable will get zonked to
    -- the immutable version.
    --
    -- We leave skolem TyVars alone; they are immutable.
    --
    -- This function is called on both kind and type variables,
    -- but kind variables *only* if PolyKinds is on.

    skolemiseQuantifiedTyVar :: SkolemInfo -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    skolemiseQuantifiedTyVar SkolemInfo
    skol_info TyVar
    tv
      = case TyVar -> TcTyVarDetails
    tcTyVarDetails TyVar
    tv of
          MetaTv {} -> SkolemInfo -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    skolemiseUnboundMetaTyVar SkolemInfo
    skol_info TyVar
    tv

          SkolemTv SkolemInfo
    _ TcLevel
    lvl Bool
    _  -- It might be a skolem type variable,
                            -- for example from a user type signature
            -- But it might also be a shared meta-variable across several
            -- type declarations, each with its own skol_info. The first
            -- will skolemise it, but the other uses must update its
            -- skolem info (#22379)
            -> do { Kind
    kind <- Kind -> TcM Kind
    zonkTcType (TyVar -> Kind
    tyVarKind TyVar
    tv)
                  ; let details :: TcTyVarDetails
    details = SkolemInfo -> TcLevel -> Bool -> TcTyVarDetails
    SkolemTv SkolemInfo
    skol_info TcLevel
    lvl Bool
    False
                        name :: Name
    name = TyVar -> Name
    tyVarName TyVar
    tv
                  ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    name Kind
    kind TcTyVarDetails
    details) }

          TcTyVarDetails
    _other -> String -> SDoc -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "skolemiseQuantifiedTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv) -- RuntimeUnk

    -- | Default a type variable using the given defaulting strategy.
    --
    -- See Note [Type variable defaulting options] in GHC.Types.Basic.
    defaultTyVar :: DefaultingStrategy
                 -> TcTyVar    -- If it's a MetaTyVar then it is unbound
                 -> TcM Bool   -- True <=> defaulted away altogether
    defaultTyVar :: DefaultingStrategy -> TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    defaultTyVar DefaultingStrategy
    def_strat TyVar
    tv
      | Bool -> Bool
    not (TyVar -> Bool
    isMetaTyVar TyVar
    tv)
      Bool -> Bool -> Bool
    || TyVar -> Bool
    isTyVarTyVar TyVar
    tv
        -- Do not default TyVarTvs. Doing so would violate the invariants
        -- on TyVarTvs; see Note [TyVarTv] in GHC.Tc.Utils.TcMType.
        -- #13343 is an example; #14555 is another
        -- See Note [Inferring kinds for type declarations] in GHC.Tc.TyCl
      = Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

      | TyVar -> Bool
    isRuntimeRepVar TyVar
    tv
      , Bool
    default_ns_vars
      = do { String -> SDoc -> TcRn ()
    traceTc String
    "Defaulting a RuntimeRep var to LiftedRep" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv)
           ; (() :: Constraint) => TyVar -> Kind -> TcRn ()
    TyVar -> Kind -> TcRn ()
    writeMetaTyVar TyVar
    tv Kind
    liftedRepTy
           ; Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True }
      | TyVar -> Bool
    isLevityVar TyVar
    tv
      , Bool
    default_ns_vars
      = do { String -> SDoc -> TcRn ()
    traceTc String
    "Defaulting a Levity var to Lifted" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv)
           ; (() :: Constraint) => TyVar -> Kind -> TcRn ()
    TyVar -> Kind -> TcRn ()
    writeMetaTyVar TyVar
    tv Kind
    liftedDataConTy
           ; Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True }
      | TyVar -> Bool
    isMultiplicityVar TyVar
    tv
      , Bool
    default_ns_vars
      = do { String -> SDoc -> TcRn ()
    traceTc String
    "Defaulting a Multiplicity var to Many" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv)
           ; (() :: Constraint) => TyVar -> Kind -> TcRn ()
    TyVar -> Kind -> TcRn ()
    writeMetaTyVar TyVar
    tv Kind
    manyDataConTy
           ; Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True }

      | TyVar -> Bool
    isConcreteTyVar TyVar
    tv
        -- We don't want to quantify; but neither can we default to
        -- anything sensible.  (If it has kind RuntimeRep or Levity, as is
        -- often the case, it'll have been caught earlier by earlier
        -- cases. So in this exotic situation we just promote.  Not very
        -- satisfing, but it's very much a corner case: #23051)
        -- We should really implement the plan in #20686.
      = do { TcLevel
    lvl <- TcM TcLevel
    getTcLevel
           ; Bool
    _ <- (() :: Constraint) =>
    TcLevel -> TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    TcLevel -> TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    promoteMetaTyVarTo TcLevel
    lvl TyVar
    tv
           ; Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True }

      | DefaultingStrategy
    DefaultKindVars <- DefaultingStrategy
    def_strat -- -XNoPolyKinds and this is a kind var: we must default it
      = TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    default_kind_var TyVar
    tv

      | Bool
    otherwise
      = Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

      where
        default_ns_vars :: Bool
        default_ns_vars :: Bool
    default_ns_vars = DefaultingStrategy -> Bool
    defaultNonStandardTyVars DefaultingStrategy
    def_strat
        default_kind_var :: TyVar -> TcM Bool
           -- defaultKindVar is used exclusively with -XNoPolyKinds
           -- See Note [Defaulting with -XNoPolyKinds]
           -- It takes an (unconstrained) meta tyvar and defaults it.
           -- Works only on vars of type *; for other kinds, it issues an error.
        default_kind_var :: TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    default_kind_var TyVar
    kv
          | Kind -> Bool
    isLiftedTypeKind (TyVar -> Kind
    tyVarKind TyVar
    kv)
          = do { String -> SDoc -> TcRn ()
    traceTc String
    "Defaulting a kind var to *" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    kv)
               ; (() :: Constraint) => TyVar -> Kind -> TcRn ()
    TyVar -> Kind -> TcRn ()
    writeMetaTyVar TyVar
    kv Kind
    liftedTypeKind
               ; Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True }
          | Bool
    otherwise
          = do { TcRnMessage -> TcRn ()
    addErr (TcRnMessage -> TcRn ()) -> TcRnMessage -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $ DiagnosticMessage -> TcRnMessage
    forall a.
    (Diagnostic a, Typeable a, DiagnosticOpts a ~ NoDiagnosticOpts) =>
    a -> TcRnMessage
    mkTcRnUnknownMessage (DiagnosticMessage -> TcRnMessage)
    -> DiagnosticMessage -> TcRnMessage
    forall a b. (a -> b) -> a -> b
    $ [GhcHint] -> SDoc -> DiagnosticMessage
    mkPlainError [GhcHint]
    noHints (SDoc -> DiagnosticMessage) -> SDoc -> DiagnosticMessage
    forall a b. (a -> b) -> a -> b
    $
                   ([SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Cannot default kind variable" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc -> SDoc
    quotes (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    kv')
                         , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "of kind:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (TyVar -> Kind
    tyVarKind TyVar
    kv')
                         , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Perhaps enable PolyKinds or add a kind signature" ])
               -- We failed to default it, so return False to say so.
               -- Hence, it'll get skolemised.  That might seem odd, but we must either
               -- promote, skolemise, or zap-to-Any, to satisfy GHC.Tc.Gen.HsType
               --    Note [Recipe for checking a signature]
               -- Otherwise we get level-number assertion failures. It doesn't matter much
               -- because we are in an error situation anyway.
               ; Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
            }
          where
            (TidyEnv
    _, TyVar
    kv') = TidyEnv -> TyVar -> (TidyEnv, TyVar)
    tidyOpenTyCoVar TidyEnv
    emptyTidyEnv TyVar
    kv

    -- | Default some unconstrained type variables, as specified
    -- by the defaulting options:
    --
    --  - 'RuntimeRep' tyvars default to 'LiftedRep'
    --  - 'Levity' tyvars default to 'Lifted'
    --  - 'Multiplicity' tyvars default to 'Many'
    --  - 'Type' tyvars from dv_kvs default to 'Type', when -XNoPolyKinds
    --    (under -XNoPolyKinds, non-defaulting vars in dv_kvs is an error)
    defaultTyVars :: NonStandardDefaultingStrategy
                  -> CandidatesQTvs    -- ^ all candidates for quantification
                  -> TcM [TcTyVar]     -- ^ those variables not defaulted
    defaultTyVars :: NonStandardDefaultingStrategy -> CandidatesQTvs -> TcM [TyVar]
    defaultTyVars NonStandardDefaultingStrategy
    ns_strat CandidatesQTvs
    dvs
      = do { Bool
    poly_kinds <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
    xoptM Extension
    LangExt.PolyKinds
           ; let
               def_tvs, def_kvs :: DefaultingStrategy
               def_tvs :: DefaultingStrategy
    def_tvs = NonStandardDefaultingStrategy -> DefaultingStrategy
    NonStandardDefaulting NonStandardDefaultingStrategy
    ns_strat
               def_kvs :: DefaultingStrategy
    def_kvs
                 | Bool
    poly_kinds = DefaultingStrategy
    def_tvs
                 | Bool
    otherwise  = DefaultingStrategy
    DefaultKindVars
                 -- As -XNoPolyKinds precludes polymorphic kind variables, we default them.
                 -- For example:
                 --
                 --   type F :: Type -> Type
                 --   type family F a where
                 --      F (a -> b) = b
                 --
                 -- Here we get `a :: TYPE r`, so to accept this program when -XNoPolyKinds is enabled
                 -- we must default the kind variable `r :: RuntimeRep`.
                 -- Test case: T20584.
           ; [Bool]
    defaulted_kvs <- (TyVar -> TcRnIf TcGblEnv TcLclEnv Bool)
    -> [TyVar] -> IOEnv (Env TcGblEnv TcLclEnv) [Bool]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (DefaultingStrategy -> TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    defaultTyVar DefaultingStrategy
    def_kvs) [TyVar]
    dep_kvs
           ; [Bool]
    defaulted_tvs <- (TyVar -> TcRnIf TcGblEnv TcLclEnv Bool)
    -> [TyVar] -> IOEnv (Env TcGblEnv TcLclEnv) [Bool]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (DefaultingStrategy -> TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    defaultTyVar DefaultingStrategy
    def_tvs) [TyVar]
    nondep_tvs
           ; let undefaulted_kvs :: [TyVar]
    undefaulted_kvs = [ TyVar
    kv | (TyVar
    kv, Bool
    False) <- [TyVar]
    dep_kvs    [TyVar] -> [Bool] -> [(TyVar, Bool)]
    forall a b. [a] -> [b] -> [(a, b)]
    `zip` [Bool]
    defaulted_kvs ]
                 undefaulted_tvs :: [TyVar]
    undefaulted_tvs = [ TyVar
    tv | (TyVar
    tv, Bool
    False) <- [TyVar]
    nondep_tvs [TyVar] -> [Bool] -> [(TyVar, Bool)]
    forall a b. [a] -> [b] -> [(a, b)]
    `zip` [Bool]
    defaulted_tvs ]
           ; [TyVar] -> TcM [TyVar]
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([TyVar]
    undefaulted_kvs [TyVar] -> [TyVar] -> [TyVar]
    forall a. [a] -> [a] -> [a]
    ++ [TyVar]
    undefaulted_tvs) }
              -- NB: kvs before tvs because tvs may depend on kvs
      where
        ([TyVar]
    dep_kvs, [TyVar]
    nondep_tvs) = CandidatesQTvs -> ([TyVar], [TyVar])
    candidateVars CandidatesQTvs
    dvs

    skolemiseUnboundMetaTyVar :: SkolemInfo -> TcTyVar -> TcM TyVar
    -- We have a Meta tyvar with a ref-cell inside it
    -- Skolemise it, so that we are totally out of Meta-tyvar-land
    -- We create a skolem TcTyVar, not a regular TyVar
    --   See Note [Zonking to Skolem]
    --
    -- Its level should be one greater than the ambient level, which will typically
    -- be the same as the level on the meta-tyvar. But not invariably; for example
    --    f :: (forall a b. SameKind a b) -> Int
    -- The skolems 'a' and 'b' are bound by tcTKTelescope, at level 2; and they each
    -- have a level-2 kind unification variable, since it might get unified with another
    -- of the level-2 skolems e.g. 'k' in this version
    --    f :: (forall k (a :: k) b. SameKind a b) -> Int
    -- So when we quantify the kind vars at the top level of the signature, the ambient
    -- level is 1, but we will quantify over kappa[2].

    skolemiseUnboundMetaTyVar :: SkolemInfo -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    skolemiseUnboundMetaTyVar SkolemInfo
    skol_info TyVar
    tv
      = Bool
    -> SDoc
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (TyVar -> Bool
    isMetaTyVar TyVar
    tv) (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv) (IOEnv (Env TcGblEnv TcLclEnv) TyVar
     -> IOEnv (Env TcGblEnv TcLclEnv) TyVar)
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a b. (a -> b) -> a -> b
    $
        do  { TyVar -> TcRn ()
    check_empty TyVar
    tv
            ; TcLevel
    tc_lvl <- TcM TcLevel
    getTcLevel   -- Get the location and level from "here"
            ; SrcSpan
    here   <- TcRn SrcSpan
    getSrcSpanM  -- i.e. where we are generalising
            ; Kind
    kind   <- Kind -> TcM Kind
    zonkTcType (TyVar -> Kind
    tyVarKind TyVar
    tv)
            ; let tv_name :: Name
    tv_name = TyVar -> Name
    tyVarName TyVar
    tv
                  -- See Note [Skolemising and identity]
                  final_name :: Name
    final_name | Name -> Bool
    isSystemName Name
    tv_name
                             = Unique -> OccName -> SrcSpan -> Name
    mkInternalName (Name -> Unique
    nameUnique Name
    tv_name)
                                              (Name -> OccName
    nameOccName Name
    tv_name) SrcSpan
    here
                             | Bool
    otherwise
                             = Name
    tv_name
                  details :: TcTyVarDetails
    details    = SkolemInfo -> TcLevel -> Bool -> TcTyVarDetails
    SkolemTv SkolemInfo
    skol_info (TcLevel -> TcLevel
    pushTcLevel TcLevel
    tc_lvl) Bool
    False
                  final_tv :: TyVar
    final_tv   = Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar Name
    final_name Kind
    kind TcTyVarDetails
    details

            ; String -> SDoc -> TcRn ()
    traceTc String
    "Skolemising" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    ":=" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    final_tv)
            ; (() :: Constraint) => TyVar -> Kind -> TcRn ()
    TyVar -> Kind -> TcRn ()
    writeMetaTyVar TyVar
    tv (TyVar -> Kind
    mkTyVarTy TyVar
    final_tv)
            ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyVar
    final_tv }
      where
        check_empty :: TyVar -> TcRn ()
    check_empty TyVar
    tv       -- [Sept 04] Check for non-empty.
          = Bool -> TcRn () -> TcRn ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    debugIsOn (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $  -- See Note [Silly Type Synonyms]
            do { MetaDetails
    cts <- TyVar -> TcM MetaDetails
    readMetaTyVar TyVar
    tv
               ; case MetaDetails
    cts of
                   MetaDetails
    Flexi       -> () -> TcRn ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                   Indirect Kind
    ty -> Bool -> String -> SDoc -> TcRn () -> TcRn ()
    forall a. HasCallStack => Bool -> String -> SDoc -> a -> a
    warnPprTrace Bool
    True String
    "skolemiseUnboundMetaTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    ty) (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $
                                  () -> TcRn ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return () }

    {- Note [Error on unconstrained meta-variables]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider

    * type C :: Type -> Type -> Constraint
      class (forall a. a b ~ a c) => C b c

    * type T = forall a. Proxy a

    * data (forall a. a b ~ a c) => T b c

    * type instance F Int = Proxy Any
      where Any :: forall k. k

    In the first three cases we will infer a :: Type -> kappa, but then
    we get no further information on kappa. In the last, we will get
      Proxy kappa Any
    but again will get no further info on kappa.

    What do do?
     A. We could choose kappa := Type. But this only works when the kind of kappa
        is Type (true in this example, but not always).
     B. We could default to Any.
     C. We could quantify.
     D. We could error.

    We choose (D), as described in #17567, and implement this choice in
    doNotQuantifyTyVars.  Discussion of alternativs A-C is below.

    NB: this is all rather similar to, but sadly not the same as
        Note [Naughty quantification candidates]

    To do this, we must take an extra step before doing the final zonk to create
    e.g. a TyCon. (There is no problem in the final term-level zonk. See the
    section on alternative (B) below.) This extra step is needed only for
    constructs that do not quantify their free meta-variables, such as a class
    constraint or right-hand side of a type synonym.

    Specifically: before the final zonk, every construct must either call
    quantifyTyVars or doNotQuantifyTyVars. The latter issues an error
    if it is passed any free variables. (Exception: we still default
    RuntimeRep and Multiplicity variables.)

    Because no meta-variables remain after quantifying or erroring, we perform
    the zonk with NoFlexi, which panics upon seeing a meta-variable.

    Alternatives A-C, not implemented:

    A. As stated above, this works only sometimes. We might have a free
       meta-variable of kind Nat, for example.

    B. This is what we used to do, but it caused Any to appear in error
       messages sometimes. See #17567 for several examples. Defaulting to
       Any during the final, whole-program zonk is OK, though, because
       we are completely done type-checking at that point. No chance to
       leak into an error message.

    C. Examine the class declaration at the top of this Note again.
       Where should we quantify? We might imagine quantifying and
       putting the kind variable in the forall of the quantified constraint.
       But what if there are nested foralls? Which one should get the
       variable? Other constructs have other problems. (For example,
       the right-hand side of a type family instance equation may not
       be a poly-type.)

       More broadly, the GHC AST defines a set of places where it performs
       implicit lexical generalization. For example, in a type
       signature

         f :: Proxy a -> Bool

       the otherwise-unbound a is lexically quantified, giving us

         f :: forall a. Proxy a -> Bool

       The places that allow lexical quantification are marked in the AST with
       HsImplicitBndrs. HsImplicitBndrs offers a binding site for otherwise-unbound
       variables.

       Later, during type-checking, we discover that a's kind is unconstrained.
       We thus quantify *again*, to

         f :: forall {k} (a :: k). Proxy @k a -> Bool

       It is this second quantification that this Note is really about --
       let's call it *inferred quantification*.
       So there are two sorts of implicit quantification in types:
         1. Lexical quantification: signalled by HsImplicitBndrs, occurs over
            variables mentioned by the user but with no explicit binding site,
            suppressed by a user-written forall (by the forall-or-nothing rule,
            in Note [forall-or-nothing rule] in GHC.Hs.Type).
         2. Inferred quantification: no signal in HsSyn, occurs over unconstrained
            variables invented by the type-checker, possible only with -XPolyKinds,
            unaffected by forall-or-nothing rule
       These two quantifications are performed in different compiler phases, and are
       essentially unrelated. However, it is convenient
       for programmers to remember only one set of implicit quantification
       sites. So, we choose to use the same places (those with HsImplicitBndrs)
       for lexical quantification as for inferred quantification of unconstrained
       meta-variables. Accordingly, there is no quantification in a class
       constraint, or the other constructs that call doNotQuantifyTyVars.
    -}

    doNotQuantifyTyVars :: CandidatesQTvs
                        -> (TidyEnv -> TcM (TidyEnv, SDoc))
                                -- ^ like "the class context (D a b, E foogle)"
                        -> TcM ()
    -- See Note [Error on unconstrained meta-variables]
    doNotQuantifyTyVars :: CandidatesQTvs -> (TidyEnv -> TcM (TidyEnv, SDoc)) -> TcRn ()
    doNotQuantifyTyVars CandidatesQTvs
    dvs TidyEnv -> TcM (TidyEnv, SDoc)
    where_found
      | CandidatesQTvs -> Bool
    isEmptyCandidates CandidatesQTvs
    dvs
      = String -> SDoc -> TcRn ()
    traceTc String
    "doNotQuantifyTyVars has nothing to error on" SDoc
    forall doc. IsOutput doc => doc
    empty

      | Bool
    otherwise
      = do { String -> SDoc -> TcRn ()
    traceTc String
    "doNotQuantifyTyVars" (CandidatesQTvs -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr CandidatesQTvs
    dvs)
           ; [TyVar]
    undefaulted <- NonStandardDefaultingStrategy -> CandidatesQTvs -> TcM [TyVar]
    defaultTyVars NonStandardDefaultingStrategy
    DefaultNonStandardTyVars CandidatesQTvs
    dvs
              -- could have regular TyVars here, in an associated type RHS, or
              -- bound by a type declaration head. So filter looking only for
              -- metavars. e.g. b and c in `class (forall a. a b ~ a c) => C b c`
              -- are OK
           ; let leftover_metas :: [TyVar]
    leftover_metas = (TyVar -> Bool) -> [TyVar] -> [TyVar]
    forall a. (a -> Bool) -> [a] -> [a]
    filter TyVar -> Bool
    isMetaTyVar [TyVar]
    undefaulted
           ; Bool -> TcRn () -> TcRn ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ([TyVar] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TyVar]
    leftover_metas) (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $
             do { let (TidyEnv
    tidy_env1, [TyVar]
    tidied_tvs) = TidyEnv -> [TyVar] -> (TidyEnv, [TyVar])
    tidyOpenTyCoVars TidyEnv
    emptyTidyEnv [TyVar]
    leftover_metas
                ; (TidyEnv
    tidy_env2, SDoc
    where_doc) <- TidyEnv -> TcM (TidyEnv, SDoc)
    where_found TidyEnv
    tidy_env1
                ; let msg :: TcRnMessage
    msg = DiagnosticMessage -> TcRnMessage
    forall a.
    (Diagnostic a, Typeable a, DiagnosticOpts a ~ NoDiagnosticOpts) =>
    a -> TcRnMessage
    mkTcRnUnknownMessage            (DiagnosticMessage -> TcRnMessage)
    -> DiagnosticMessage -> TcRnMessage
    forall a b. (a -> b) -> a -> b
    $
                            [GhcHint] -> SDoc -> DiagnosticMessage
    mkPlainError [GhcHint]
    noHints          (SDoc -> DiagnosticMessage) -> SDoc -> DiagnosticMessage
    forall a b. (a -> b) -> a -> b
    $
                            Bool -> SDoc -> SDoc
    pprWithExplicitKindsWhen Bool
    True (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
                        [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Uninferrable type variable"
                               SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> [TyVar] -> SDoc
    forall a. [a] -> SDoc
    plural [TyVar]
    tidied_tvs
                               SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> (TyVar -> SDoc) -> [TyVar] -> SDoc
    forall a. (a -> SDoc) -> [a] -> SDoc
    pprWithCommas TyVar -> SDoc
    pprTyVar [TyVar]
    tidied_tvs
                               SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "in"
                             , SDoc
    where_doc ]
                ; (TidyEnv, TcRnMessage) -> TcRn ()
    forall a. (TidyEnv, TcRnMessage) -> TcM a
    failWithTcM (TidyEnv
    tidy_env2, TcRnMessage
    msg) }
           ; String -> SDoc -> TcRn ()
    traceTc String
    "doNotQuantifyTyVars success" SDoc
    forall doc. IsOutput doc => doc
    empty }

    {- Note [Defaulting with -XNoPolyKinds]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider

      data Compose f g a = Mk (f (g a))

    We infer

      Compose :: forall k1 k2. (k2 -> *) -> (k1 -> k2) -> k1 -> *
      Mk :: forall k1 k2 (f :: k2 -> *) (g :: k1 -> k2) (a :: k1).
            f (g a) -> Compose k1 k2 f g a

    Now, in another module, we have -XNoPolyKinds -XDataKinds in effect.
    What does 'Mk mean? Pre GHC-8.0 with -XNoPolyKinds,
    we just defaulted all kind variables to *. But that's no good here,
    because the kind variables in 'Mk aren't of kind *, so defaulting to *
    is ill-kinded.

    After some debate on #11334, we decided to issue an error in this case.
    The code is in defaultKindVar.

    Note [What is a meta variable?]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    A "meta type-variable", also know as a "unification variable" is a placeholder
    introduced by the typechecker for an as-yet-unknown monotype.

    For example, when we see a call `reverse (f xs)`, we know that we calling
        reverse :: forall a. [a] -> [a]
    So we know that the argument `f xs` must be a "list of something". But what is
    the "something"? We don't know until we explore the `f xs` a bit more. So we set
    out what we do know at the call of `reverse` by instantiating its type with a fresh
    meta tyvar, `alpha` say. So now the type of the argument `f xs`, and of the
    result, is `[alpha]`. The unification variable `alpha` stands for the
    as-yet-unknown type of the elements of the list.

    As type inference progresses we may learn more about `alpha`. For example, suppose
    `f` has the type
        f :: forall b. b -> [Maybe b]
    Then we instantiate `f`'s type with another fresh unification variable, say
    `beta`; and equate `f`'s result type with reverse's argument type, thus
    `[alpha] ~ [Maybe beta]`.

    Now we can solve this equality to learn that `alpha ~ Maybe beta`, so we've
    refined our knowledge about `alpha`. And so on.

    If you found this Note useful, you may also want to have a look at
    Section 5 of "Practical type inference for higher rank types" (Peyton Jones,
    Vytiniotis, Weirich and Shields. J. Functional Programming. 2011).

    Note [What is zonking?]
    ~~~~~~~~~~~~~~~~~~~~~~~
    GHC relies heavily on mutability in the typechecker for efficient operation.
    For this reason, throughout much of the type checking process meta type
    variables (the MetaTv constructor of TcTyVarDetails) are represented by mutable
    variables (known as TcRefs).

    Zonking is the process of ripping out these mutable variables and replacing them
    with a real Type. This involves traversing the entire type expression, but the
    interesting part of replacing the mutable variables occurs in zonkTyVarOcc.

    There are two ways to zonk a Type:

     * zonkTcTypeToType, which is intended to be used at the end of type-checking
       for the final zonk. It has to deal with unfilled metavars, either by filling
       it with a value like Any or failing (determined by the UnboundTyVarZonker
       used).

     * zonkTcType, which will happily ignore unfilled metavars. This is the
       appropriate function to use while in the middle of type-checking.

    Note [Zonking to Skolem]
    ~~~~~~~~~~~~~~~~~~~~~~~~
    We used to zonk quantified type variables to regular TyVars.  However, this
    leads to problems.  Consider this program from the regression test suite:

      eval :: Int -> String -> String -> String
      eval 0 root actual = evalRHS 0 root actual

      evalRHS :: Int -> a
      evalRHS 0 root actual = eval 0 root actual

    It leads to the deferral of an equality (wrapped in an implication constraint)

      forall a. () => ((String -> String -> String) ~ a)

    which is propagated up to the toplevel (see GHC.Tc.Solver.tcSimplifyInferCheck).
    In the meantime `a' is zonked and quantified to form `evalRHS's signature.
    This has the *side effect* of also zonking the `a' in the deferred equality
    (which at this point is being handed around wrapped in an implication
    constraint).

    Finally, the equality (with the zonked `a') will be handed back to the
    simplifier by GHC.Tc.Module.tcRnSrcDecls calling GHC.Tc.Solver.tcSimplifyTop.
    If we zonk `a' with a regular type variable, we will have this regular type
    variable now floating around in the simplifier, which in many places assumes to
    only see proper TcTyVars.

    We can avoid this problem by zonking with a skolem TcTyVar.  The
    skolem is rigid (which we require for a quantified variable), but is
    still a TcTyVar that the simplifier knows how to deal with.

    Note [Skolemising and identity]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In some places, we make a TyVarTv for a binder. E.g.
        class C a where ...
    As Note [Inferring kinds for type declarations] discusses,
    we make a TyVarTv for 'a'.  Later we skolemise it, and we'd
    like to retain its identity, location info etc.  (If we don't
    retain its identity we'll have to do some pointless swizzling;
    see GHC.Tc.TyCl.swizzleTcTyConBndrs.  If we retain its identity
    but not its location we'll lose the detailed binding site info.

    Conclusion: use the Name of the TyVarTv.  But we don't want
    to do that when skolemising random unification variables;
    there the location we want is the skolemisation site.

    Fortunately we can tell the difference: random unification
    variables have System Names.  That's why final_name is
    set based on the isSystemName test.

    Note [Silly Type Synonyms]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider this:
            type C u a = u  -- Note 'a' unused

            foo :: (forall a. C u a -> C u a) -> u
            foo x = ...

            bar :: Num u => u
            bar = foo (\t -> t + t)

    * From the (\t -> t+t) we get type  {Num d} =>  d -> d
      where d is fresh.

    * Now unify with type of foo's arg, and we get:
            {Num (C d a)} =>  C d a -> C d a
      where a is fresh.

    * Now abstract over the 'a', but float out the Num (C d a) constraint
      because it does not 'really' mention a.  (see exactTyVarsOfType)
      The arg to foo becomes
            \/\a -> \t -> t+t

    * So we get a dict binding for Num (C d a), which is zonked to give
            a = ()
      Note (Sept 04): now that we are zonking quantified type variables
      on construction, the 'a' will be frozen as a regular tyvar on
      quantification, so the floated dict will still have type (C d a).
      Which renders this whole note moot; happily!]

    * Then the \/\a abstraction has a zonked 'a' in it.

    All very silly.   I think its harmless to ignore the problem.  We'll end up with
    a \/\a in the final result but all the occurrences of a will be zonked to ()
    -}

    {- *********************************************************************
    *                                                                      *
                  Promotion
    *                                                                      *
    ********************************************************************* -}

    promoteMetaTyVarTo :: HasDebugCallStack => TcLevel -> TcTyVar -> TcM Bool
    -- When we float a constraint out of an implication we must restore
    -- invariant (WantedInv) in Note [TcLevel invariants] in GHC.Tc.Utils.TcType
    -- Return True <=> we did some promotion
    -- Also returns either the original tyvar (no promotion) or the new one
    -- See Note [Promoting unification variables]
    promoteMetaTyVarTo :: (() :: Constraint) =>
    TcLevel -> TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    promoteMetaTyVarTo TcLevel
    tclvl TyVar
    tv
      | Bool -> SDoc -> Bool -> Bool
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (TyVar -> Bool
    isMetaTyVar TyVar
    tv) (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv) (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $
        TyVar -> TcLevel
    tcTyVarLevel TyVar
    tv TcLevel -> TcLevel -> Bool
    `strictlyDeeperThan` TcLevel
    tclvl
      = do { TyVar
    cloned_tv <- TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    cloneMetaTyVar TyVar
    tv
           ; let rhs_tv :: TyVar
    rhs_tv = TyVar -> TcLevel -> TyVar
    setMetaTyVarTcLevel TyVar
    cloned_tv TcLevel
    tclvl
           ; (() :: Constraint) => TyVar -> Kind -> TcRn ()
    TyVar -> Kind -> TcRn ()
    writeMetaTyVar TyVar
    tv (TyVar -> Kind
    mkTyVarTy TyVar
    rhs_tv)
           ; String -> SDoc -> TcRn ()
    traceTc String
    "promoteTyVar" (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "-->" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    rhs_tv)
           ; Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True }
       | Bool
    otherwise
       = Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

    -- Returns whether or not *any* tyvar is defaulted
    promoteTyVarSet :: HasDebugCallStack => TcTyVarSet -> TcM Bool
    promoteTyVarSet :: (() :: Constraint) => CoVarSet -> TcRnIf TcGblEnv TcLclEnv Bool
    promoteTyVarSet CoVarSet
    tvs
      = do { TcLevel
    tclvl <- TcM TcLevel
    getTcLevel
           ; [Bool]
    bools <- (TyVar -> TcRnIf TcGblEnv TcLclEnv Bool)
    -> [TyVar] -> IOEnv (Env TcGblEnv TcLclEnv) [Bool]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM ((() :: Constraint) =>
    TcLevel -> TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    TcLevel -> TyVar -> TcRnIf TcGblEnv TcLclEnv Bool
    promoteMetaTyVarTo TcLevel
    tclvl)  ([TyVar] -> IOEnv (Env TcGblEnv TcLclEnv) [Bool])
    -> [TyVar] -> IOEnv (Env TcGblEnv TcLclEnv) [Bool]
    forall a b. (a -> b) -> a -> b
    $
                      (TyVar -> Bool) -> [TyVar] -> [TyVar]
    forall a. (a -> Bool) -> [a] -> [a]
    filter TyVar -> Bool
    isPromotableMetaTyVar ([TyVar] -> [TyVar]) -> [TyVar] -> [TyVar]
    forall a b. (a -> b) -> a -> b
    $
                      CoVarSet -> [TyVar]
    forall elt. UniqSet elt -> [elt]
    nonDetEltsUniqSet CoVarSet
    tvs
             -- Non-determinism is OK because order of promotion doesn't matter
           ; Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Bool] -> Bool
    forall (t :: * -> *). Foldable t => t Bool -> Bool
    or [Bool]
    bools) }

    {- *********************************************************************
    *                                                                      *
                  Zonking types
    *                                                                      *
    ********************************************************************* -}

    zonkTcTypeAndFV :: TcType -> TcM DTyCoVarSet
    -- Zonk a type and take its free variables
    -- With kind polymorphism it can be essential to zonk *first*
    -- so that we find the right set of free variables.  Eg
    --    forall k1. forall (a:k2). a
    -- where k2:=k1 is in the substitution.  We don't want
    -- k2 to look free in this type!
    zonkTcTypeAndFV :: Kind -> TcM DTyVarSet
    zonkTcTypeAndFV Kind
    ty
      = Kind -> DTyVarSet
    tyCoVarsOfTypeDSet (Kind -> DTyVarSet) -> TcM Kind -> TcM DTyVarSet
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Kind -> TcM Kind
    zonkTcType Kind
    ty

    zonkTyCoVar :: TyCoVar -> TcM TcType
    -- Works on TyVars and TcTyVars
    zonkTyCoVar :: TyVar -> TcM Kind
    zonkTyCoVar TyVar
    tv | TyVar -> Bool
    isTcTyVar TyVar
    tv = TyVar -> TcM Kind
    zonkTcTyVar TyVar
    tv
                   | TyVar -> Bool
    isTyVar   TyVar
    tv = TyVar -> Kind
    mkTyVarTy (TyVar -> Kind) -> IOEnv (Env TcGblEnv TcLclEnv) TyVar -> TcM Kind
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTyCoVarKind TyVar
    tv
                   | Bool
    otherwise    = Bool -> SDoc -> TcM Kind -> TcM Kind
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (TyVar -> Bool
    isCoVar TyVar
    tv) (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv) (TcM Kind -> TcM Kind) -> TcM Kind -> TcM Kind
    forall a b. (a -> b) -> a -> b
    $
                                    Coercion -> Kind
    mkCoercionTy (Coercion -> Kind) -> (TyVar -> Coercion) -> TyVar -> Kind
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TyVar -> Coercion
    mkCoVarCo (TyVar -> Kind) -> IOEnv (Env TcGblEnv TcLclEnv) TyVar -> TcM Kind
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTyCoVarKind TyVar
    tv
       -- Hackily, when typechecking type and class decls
       -- we have TyVars in scope added (only) in
       -- GHC.Tc.Gen.HsType.bindTyClTyVars, but it seems
       -- painful to make them into TcTyVars there

    zonkTyCoVarsAndFV :: TyCoVarSet -> TcM TyCoVarSet
    zonkTyCoVarsAndFV :: CoVarSet -> TcM CoVarSet
    zonkTyCoVarsAndFV CoVarSet
    tycovars
      = [Kind] -> CoVarSet
    tyCoVarsOfTypes ([Kind] -> CoVarSet) -> TcM [Kind] -> TcM CoVarSet
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (TyVar -> TcM Kind) -> [TyVar] -> TcM [Kind]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM TyVar -> TcM Kind
    zonkTyCoVar (CoVarSet -> [TyVar]
    forall elt. UniqSet elt -> [elt]
    nonDetEltsUniqSet CoVarSet
    tycovars)
      -- It's OK to use nonDetEltsUniqSet here because we immediately forget about
      -- the ordering by turning it into a nondeterministic set and the order
      -- of zonking doesn't matter for determinism.

    zonkDTyCoVarSetAndFV :: DTyCoVarSet -> TcM DTyCoVarSet
    zonkDTyCoVarSetAndFV :: DTyVarSet -> TcM DTyVarSet
    zonkDTyCoVarSetAndFV DTyVarSet
    tycovars
      = [TyVar] -> DTyVarSet
    mkDVarSet ([TyVar] -> DTyVarSet) -> TcM [TyVar] -> TcM DTyVarSet
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ([TyVar] -> TcM [TyVar]
    zonkTyCoVarsAndFVList ([TyVar] -> TcM [TyVar]) -> [TyVar] -> TcM [TyVar]
    forall a b. (a -> b) -> a -> b
    $ DTyVarSet -> [TyVar]
    dVarSetElems DTyVarSet
    tycovars)

    -- Takes a list of TyCoVars, zonks them and returns a
    -- deterministically ordered list of their free variables.
    zonkTyCoVarsAndFVList :: [TyCoVar] -> TcM [TyCoVar]
    zonkTyCoVarsAndFVList :: [TyVar] -> TcM [TyVar]
    zonkTyCoVarsAndFVList [TyVar]
    tycovars
      = [Kind] -> [TyVar]
    tyCoVarsOfTypesList ([Kind] -> [TyVar]) -> TcM [Kind] -> TcM [TyVar]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (TyVar -> TcM Kind) -> [TyVar] -> TcM [Kind]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM TyVar -> TcM Kind
    zonkTyCoVar [TyVar]
    tycovars

    zonkTcTyVars :: [TcTyVar] -> TcM [TcType]
    zonkTcTyVars :: [TyVar] -> TcM [Kind]
    zonkTcTyVars [TyVar]
    tyvars = (TyVar -> TcM Kind) -> [TyVar] -> TcM [Kind]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM TyVar -> TcM Kind
    zonkTcTyVar [TyVar]
    tyvars

    -----------------  Types
    zonkTyCoVarKind :: TyCoVar -> TcM TyCoVar
    zonkTyCoVarKind :: TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTyCoVarKind TyVar
    tv = do { Kind
    kind' <- Kind -> TcM Kind
    zonkTcType (TyVar -> Kind
    tyVarKind TyVar
    tv)
                            ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVar -> Kind -> TyVar
    setTyVarKind TyVar
    tv Kind
    kind') }

    {-
    ************************************************************************
    *                                                                      *
                  Zonking constraints
    *                                                                      *
    ************************************************************************
    -}

    zonkImplication :: Implication -> TcM Implication
    zonkImplication :: Implication -> IOEnv (Env TcGblEnv TcLclEnv) Implication
    zonkImplication implic :: Implication
    implic@(Implic { ic_skols :: Implication -> [TyVar]
    ic_skols  = [TyVar]
    skols
                                   , ic_given :: Implication -> [TyVar]
    ic_given  = [TyVar]
    given
                                   , ic_wanted :: Implication -> WantedConstraints
    ic_wanted = WantedConstraints
    wanted
                                   , ic_info :: Implication -> SkolemInfoAnon
    ic_info   = SkolemInfoAnon
    info })
      = do { [TyVar]
    skols'  <- (TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar)
    -> [TyVar] -> TcM [TyVar]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTyCoVarKind [TyVar]
    skols  -- Need to zonk their kinds!
                                                    -- as #7230 showed
           ; [TyVar]
    given'  <- (TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar)
    -> [TyVar] -> TcM [TyVar]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkEvVar [TyVar]
    given
           ; SkolemInfoAnon
    info'   <- SkolemInfoAnon -> TcM SkolemInfoAnon
    zonkSkolemInfoAnon SkolemInfoAnon
    info
           ; WantedConstraints
    wanted' <- WantedConstraints -> TcM WantedConstraints
    zonkWCRec WantedConstraints
    wanted
           ; Implication -> IOEnv (Env TcGblEnv TcLclEnv) Implication
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Implication
    implic { ic_skols  = skols'
                            , ic_given  = given'
                            , ic_wanted = wanted'
                            , ic_info   = info' }) }

    zonkEvVar :: EvVar -> TcM EvVar
    zonkEvVar :: TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkEvVar TyVar
    var = (Kind -> TcM Kind) -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall (m :: * -> *).
    Monad m =>
    (Kind -> m Kind) -> TyVar -> m TyVar
    updateIdTypeAndMultM Kind -> TcM Kind
    zonkTcType TyVar
    var

    zonkWC :: WantedConstraints -> TcM WantedConstraints
    zonkWC :: WantedConstraints -> TcM WantedConstraints
    zonkWC WantedConstraints
    wc = WantedConstraints -> TcM WantedConstraints
    zonkWCRec WantedConstraints
    wc

    zonkWCRec :: WantedConstraints -> TcM WantedConstraints
    zonkWCRec :: WantedConstraints -> TcM WantedConstraints
    zonkWCRec (WC { wc_simple :: WantedConstraints -> Bag Ct
    wc_simple = Bag Ct
    simple, wc_impl :: WantedConstraints -> Bag Implication
    wc_impl = Bag Implication
    implic, wc_errors :: WantedConstraints -> Bag DelayedError
    wc_errors = Bag DelayedError
    errs })
      = do { Bag Ct
    simple' <- Bag Ct -> IOEnv (Env TcGblEnv TcLclEnv) (Bag Ct)
    zonkSimples Bag Ct
    simple
           ; Bag Implication
    implic' <- (Implication -> IOEnv (Env TcGblEnv TcLclEnv) Implication)
    -> Bag Implication
    -> IOEnv (Env TcGblEnv TcLclEnv) (Bag Implication)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Bag a -> m (Bag b)
    mapBagM Implication -> IOEnv (Env TcGblEnv TcLclEnv) Implication
    zonkImplication Bag Implication
    implic
           ; Bag DelayedError
    errs'   <- (DelayedError -> IOEnv (Env TcGblEnv TcLclEnv) DelayedError)
    -> Bag DelayedError
    -> IOEnv (Env TcGblEnv TcLclEnv) (Bag DelayedError)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Bag a -> m (Bag b)
    mapBagM DelayedError -> IOEnv (Env TcGblEnv TcLclEnv) DelayedError
    zonkDelayedError Bag DelayedError
    errs
           ; WantedConstraints -> TcM WantedConstraints
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WC { wc_simple :: Bag Ct
    wc_simple = Bag Ct
    simple', wc_impl :: Bag Implication
    wc_impl = Bag Implication
    implic', wc_errors :: Bag DelayedError
    wc_errors = Bag DelayedError
    errs' }) }

    zonkSimples :: Cts -> TcM Cts
    zonkSimples :: Bag Ct -> IOEnv (Env TcGblEnv TcLclEnv) (Bag Ct)
    zonkSimples Bag Ct
    cts = do { Bag Ct
    cts' <- (Ct -> TcM Ct) -> Bag Ct -> IOEnv (Env TcGblEnv TcLclEnv) (Bag Ct)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Bag a -> m (Bag b)
    mapBagM Ct -> TcM Ct
    zonkCt Bag Ct
    cts
                         ; String -> SDoc -> TcRn ()
    traceTc String
    "zonkSimples done:" (Bag Ct -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Bag Ct
    cts')
                         ; Bag Ct -> IOEnv (Env TcGblEnv TcLclEnv) (Bag Ct)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bag Ct
    cts' }

    zonkDelayedError :: DelayedError -> TcM DelayedError
    zonkDelayedError :: DelayedError -> IOEnv (Env TcGblEnv TcLclEnv) DelayedError
    zonkDelayedError (DE_Hole Hole
    hole)
      = Hole -> DelayedError
    DE_Hole (Hole -> DelayedError)
    -> IOEnv (Env TcGblEnv TcLclEnv) Hole
    -> IOEnv (Env TcGblEnv TcLclEnv) DelayedError
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Hole -> IOEnv (Env TcGblEnv TcLclEnv) Hole
    zonkHole Hole
    hole
    zonkDelayedError (DE_NotConcrete NotConcreteError
    err)
      = NotConcreteError -> DelayedError
    DE_NotConcrete (NotConcreteError -> DelayedError)
    -> IOEnv (Env TcGblEnv TcLclEnv) NotConcreteError
    -> IOEnv (Env TcGblEnv TcLclEnv) DelayedError
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> NotConcreteError -> IOEnv (Env TcGblEnv TcLclEnv) NotConcreteError
    zonkNotConcreteError NotConcreteError
    err

    zonkHole :: Hole -> TcM Hole
    zonkHole :: Hole -> IOEnv (Env TcGblEnv TcLclEnv) Hole
    zonkHole hole :: Hole
    hole@(Hole { hole_ty :: Hole -> Kind
    hole_ty = Kind
    ty })
      = do { Kind
    ty' <- Kind -> TcM Kind
    zonkTcType Kind
    ty
           ; Hole -> IOEnv (Env TcGblEnv TcLclEnv) Hole
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Hole
    hole { hole_ty = ty' }) }

    zonkNotConcreteError :: NotConcreteError -> TcM NotConcreteError
    zonkNotConcreteError :: NotConcreteError -> IOEnv (Env TcGblEnv TcLclEnv) NotConcreteError
    zonkNotConcreteError err :: NotConcreteError
    err@(NCE_FRR { nce_frr_origin :: NotConcreteError -> FixedRuntimeRepOrigin
    nce_frr_origin = FixedRuntimeRepOrigin
    frr_orig })
      = do { FixedRuntimeRepOrigin
    frr_orig  <- FixedRuntimeRepOrigin -> TcM FixedRuntimeRepOrigin
    zonkFRROrigin FixedRuntimeRepOrigin
    frr_orig
           ; NotConcreteError -> IOEnv (Env TcGblEnv TcLclEnv) NotConcreteError
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (NotConcreteError
     -> IOEnv (Env TcGblEnv TcLclEnv) NotConcreteError)
    -> NotConcreteError
    -> IOEnv (Env TcGblEnv TcLclEnv) NotConcreteError
    forall a b. (a -> b) -> a -> b
    $ NotConcreteError
    err { nce_frr_origin = frr_orig  } }

    zonkFRROrigin :: FixedRuntimeRepOrigin -> TcM FixedRuntimeRepOrigin
    zonkFRROrigin :: FixedRuntimeRepOrigin -> TcM FixedRuntimeRepOrigin
    zonkFRROrigin (FixedRuntimeRepOrigin Kind
    ty FixedRuntimeRepContext
    orig)
      = do { Kind
    ty' <- Kind -> TcM Kind
    zonkTcType Kind
    ty
           ; FixedRuntimeRepOrigin -> TcM FixedRuntimeRepOrigin
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FixedRuntimeRepOrigin -> TcM FixedRuntimeRepOrigin)
    -> FixedRuntimeRepOrigin -> TcM FixedRuntimeRepOrigin
    forall a b. (a -> b) -> a -> b
    $ Kind -> FixedRuntimeRepContext -> FixedRuntimeRepOrigin
    FixedRuntimeRepOrigin Kind
    ty' FixedRuntimeRepContext
    orig }

    {- Note [zonkCt behaviour]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
    zonkCt tries to maintain the canonical form of a Ct.  For example,
      - a CDictCan should stay a CDictCan;
      - a CIrredCan should stay a CIrredCan with its cc_reason flag intact

    Why?, for example:
    - For CDictCan, the @GHC.Tc.Solver.expandSuperClasses@ step, which runs after the
      simple wanted and plugin loop, looks for @CDictCan@s. If a plugin is in use,
      constraints are zonked before being passed to the plugin. This means if we
      don't preserve a canonical form, @expandSuperClasses@ fails to expand
      superclasses. This is what happened in #11525.

    - For CIrredCan we want to see if a constraint is insoluble with insolubleWC

    On the other hand, we change CEqCan to CNonCanonical, because of all of
    CEqCan's invariants, which can break during zonking. (Example: a ~R alpha, where
    we have alpha := N Int, where N is a newtype.) Besides, the constraint
    will be canonicalised again, so there is little benefit in keeping the
    CEqCan structure.

    NB: Constraints are always rewritten etc by the canonicaliser in
    @GHC.Tc.Solver.Canonical@ even if they come in as CDictCan. Only canonical constraints that
    are actually in the inert set carry all the guarantees. So it is okay if zonkCt
    creates e.g. a CDictCan where the cc_tyars are /not/ fully reduced.
    -}

    zonkCt :: Ct -> TcM Ct
    -- See Note [zonkCt behaviour]
    zonkCt :: Ct -> TcM Ct
    zonkCt ct :: Ct
    ct@(CDictCan { cc_ev :: Ct -> CtEvidence
    cc_ev = CtEvidence
    ev, cc_tyargs :: Ct -> [Kind]
    cc_tyargs = [Kind]
    args })
      = do { CtEvidence
    ev'   <- CtEvidence -> TcM CtEvidence
    zonkCtEvidence CtEvidence
    ev
           ; [Kind]
    args' <- (Kind -> TcM Kind) -> [Kind] -> TcM [Kind]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Kind -> TcM Kind
    zonkTcType [Kind]
    args
           ; Ct -> TcM Ct
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Ct -> TcM Ct) -> Ct -> TcM Ct
    forall a b. (a -> b) -> a -> b
    $ Ct
    ct { cc_ev = ev', cc_tyargs = args' } }

    zonkCt (CEqCan { cc_ev :: Ct -> CtEvidence
    cc_ev = CtEvidence
    ev })
      = CtEvidence -> Ct
    mkNonCanonical (CtEvidence -> Ct) -> TcM CtEvidence -> TcM Ct
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> CtEvidence -> TcM CtEvidence
    zonkCtEvidence CtEvidence
    ev

    zonkCt ct :: Ct
    ct@(CIrredCan { cc_ev :: Ct -> CtEvidence
    cc_ev = CtEvidence
    ev }) -- Preserve the cc_reason flag
      = do { CtEvidence
    ev' <- CtEvidence -> TcM CtEvidence
    zonkCtEvidence CtEvidence
    ev
           ; Ct -> TcM Ct
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Ct
    ct { cc_ev = ev' }) }

    zonkCt Ct
    ct
      = do { CtEvidence
    fl' <- CtEvidence -> TcM CtEvidence
    zonkCtEvidence (Ct -> CtEvidence
    ctEvidence Ct
    ct)
           ; Ct -> TcM Ct
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CtEvidence -> Ct
    mkNonCanonical CtEvidence
    fl') }

    zonkCtEvidence :: CtEvidence -> TcM CtEvidence
    zonkCtEvidence :: CtEvidence -> TcM CtEvidence
    zonkCtEvidence CtEvidence
    ctev
      = do { Kind
    pred' <- Kind -> TcM Kind
    zonkTcType (CtEvidence -> Kind
    ctev_pred CtEvidence
    ctev)
           ; CtEvidence -> TcM CtEvidence
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((() :: Constraint) => CtEvidence -> Kind -> CtEvidence
    CtEvidence -> Kind -> CtEvidence
    setCtEvPredType CtEvidence
    ctev Kind
    pred')
           }

    zonkSkolemInfo :: SkolemInfo -> TcM SkolemInfo
    zonkSkolemInfo :: SkolemInfo -> TcM SkolemInfo
    zonkSkolemInfo (SkolemInfo Unique
    u SkolemInfoAnon
    sk) = Unique -> SkolemInfoAnon -> SkolemInfo
    SkolemInfo Unique
    u (SkolemInfoAnon -> SkolemInfo)
    -> TcM SkolemInfoAnon -> TcM SkolemInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> SkolemInfoAnon -> TcM SkolemInfoAnon
    zonkSkolemInfoAnon SkolemInfoAnon
    sk

    zonkSkolemInfoAnon :: SkolemInfoAnon -> TcM SkolemInfoAnon
    zonkSkolemInfoAnon :: SkolemInfoAnon -> TcM SkolemInfoAnon
    zonkSkolemInfoAnon (SigSkol UserTypeCtxt
    cx Kind
    ty [(Name, TyVar)]
    tv_prs)  = do { Kind
    ty' <- Kind -> TcM Kind
    zonkTcType Kind
    ty
                                                ; SkolemInfoAnon -> TcM SkolemInfoAnon
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (UserTypeCtxt -> Kind -> [(Name, TyVar)] -> SkolemInfoAnon
    SigSkol UserTypeCtxt
    cx Kind
    ty' [(Name, TyVar)]
    tv_prs) }
    zonkSkolemInfoAnon (InferSkol [(Name, Kind)]
    ntys) = do { [(Name, Kind)]
    ntys' <- ((Name, Kind) -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Kind))
    -> [(Name, Kind)] -> IOEnv (Env TcGblEnv TcLclEnv) [(Name, Kind)]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (Name, Kind) -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Kind)
    forall {a}. (a, Kind) -> IOEnv (Env TcGblEnv TcLclEnv) (a, Kind)
    do_one [(Name, Kind)]
    ntys
                                         ; SkolemInfoAnon -> TcM SkolemInfoAnon
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(Name, Kind)] -> SkolemInfoAnon
    InferSkol [(Name, Kind)]
    ntys') }
      where
        do_one :: (a, Kind) -> IOEnv (Env TcGblEnv TcLclEnv) (a, Kind)
    do_one (a
    n, Kind
    ty) = do { Kind
    ty' <- Kind -> TcM Kind
    zonkTcType Kind
    ty; (a, Kind) -> IOEnv (Env TcGblEnv TcLclEnv) (a, Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    n, Kind
    ty') }
    zonkSkolemInfoAnon SkolemInfoAnon
    skol_info = SkolemInfoAnon -> TcM SkolemInfoAnon
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return SkolemInfoAnon
    skol_info

    {-
    ************************************************************************
    *                                                                      *
         Zonking -- the main work-horses: zonkTcType, zonkTcTyVar
    *                                                                      *
    ************************************************************************
    -}

    -- For unbound, mutable tyvars, zonkType uses the function given to it
    -- For tyvars bound at a for-all, zonkType zonks them to an immutable
    --      type variable and zonks the kind too
    zonkTcType  :: TcType -> TcM TcType
    zonkTcTypes :: [TcType] -> TcM [TcType]
    zonkCo      :: Coercion -> TcM Coercion

    (Kind -> TcM Kind
    zonkTcType, [Kind] -> TcM [Kind]
    zonkTcTypes, Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    zonkCo, [Coercion] -> IOEnv (Env TcGblEnv TcLclEnv) [Coercion]
    _)
      = TyCoMapper () (IOEnv (Env TcGblEnv TcLclEnv))
    -> (Kind -> TcM Kind, [Kind] -> TcM [Kind],
        Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion,
        [Coercion] -> IOEnv (Env TcGblEnv TcLclEnv) [Coercion])
    forall (m :: * -> *).
    Monad m =>
    TyCoMapper () m
    -> (Kind -> m Kind, [Kind] -> m [Kind], Coercion -> m Coercion,
        [Coercion] -> m [Coercion])
    mapTyCo TyCoMapper () (IOEnv (Env TcGblEnv TcLclEnv))
    zonkTcTypeMapper

    -- | A suitable TyCoMapper for zonking a type during type-checking,
    -- before all metavars are filled in.
    zonkTcTypeMapper :: TyCoMapper () TcM
    zonkTcTypeMapper :: TyCoMapper () (IOEnv (Env TcGblEnv TcLclEnv))
    zonkTcTypeMapper = TyCoMapper
      { tcm_tyvar :: () -> TyVar -> TcM Kind
    tcm_tyvar = (TyVar -> TcM Kind) -> () -> TyVar -> TcM Kind
    forall a b. a -> b -> a
    const TyVar -> TcM Kind
    zonkTcTyVar
      , tcm_covar :: () -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    tcm_covar = (TyVar -> IOEnv (Env TcGblEnv TcLclEnv) Coercion)
    -> () -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a b. a -> b -> a
    const (\TyVar
    cv -> TyVar -> Coercion
    mkCoVarCo (TyVar -> Coercion)
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTyCoVarKind TyVar
    cv)
      , tcm_hole :: () -> CoercionHole -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    tcm_hole  = () -> CoercionHole -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    hole
      , tcm_tycobinder :: ()
    -> TyVar
    -> ForAllTyFlag
    -> IOEnv (Env TcGblEnv TcLclEnv) ((), TyVar)
    tcm_tycobinder = \()
    _env TyVar
    tv ForAllTyFlag
    _vis -> ((), ) (TyVar -> ((), TyVar))
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    -> IOEnv (Env TcGblEnv TcLclEnv) ((), TyVar)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTyCoVarKind TyVar
    tv
      , tcm_tycon :: TyCon -> IOEnv (Env TcGblEnv TcLclEnv) TyCon
    tcm_tycon      = TyCon -> IOEnv (Env TcGblEnv TcLclEnv) TyCon
    zonkTcTyCon }
      where
        hole :: () -> CoercionHole -> TcM Coercion
        hole :: () -> CoercionHole -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    hole ()
    _ hole :: CoercionHole
    hole@(CoercionHole { ch_ref :: CoercionHole -> IORef (Maybe Coercion)
    ch_ref = IORef (Maybe Coercion)
    ref, ch_co_var :: CoercionHole -> TyVar
    ch_co_var = TyVar
    cv })
          = do { Maybe Coercion
    contents <- IORef (Maybe Coercion) -> TcRnIf TcGblEnv TcLclEnv (Maybe Coercion)
    forall a gbl lcl. TcRef a -> TcRnIf gbl lcl a
    readTcRef IORef (Maybe Coercion)
    ref
               ; case Maybe Coercion
    contents of
                   Just Coercion
    co -> do { Coercion
    co' <- Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    zonkCo Coercion
    co
                                 ; TyVar -> Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    checkCoercionHole TyVar
    cv Coercion
    co' }
                   Maybe Coercion
    Nothing -> do { TyVar
    cv' <- TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkCoVar TyVar
    cv
                                 ; Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion)
    -> Coercion -> IOEnv (Env TcGblEnv TcLclEnv) Coercion
    forall a b. (a -> b) -> a -> b
    $ CoercionHole -> Coercion
    HoleCo (CoercionHole
    hole { ch_co_var = cv' }) } }

    zonkTcTyCon :: TcTyCon -> TcM TcTyCon
    -- Only called on TcTyCons
    -- A non-poly TcTyCon may have unification
    -- variables that need zonking, but poly ones cannot
    zonkTcTyCon :: TyCon -> IOEnv (Env TcGblEnv TcLclEnv) TyCon
    zonkTcTyCon TyCon
    tc
     | TyCon -> Bool
    isMonoTcTyCon TyCon
    tc = do { Kind
    tck' <- Kind -> TcM Kind
    zonkTcType (TyCon -> Kind
    tyConKind TyCon
    tc)
                             ; TyCon -> IOEnv (Env TcGblEnv TcLclEnv) TyCon
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyCon -> Kind -> TyCon
    setTcTyConKind TyCon
    tc Kind
    tck') }
     | Bool
    otherwise        = TyCon -> IOEnv (Env TcGblEnv TcLclEnv) TyCon
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyCon
    tc

    zonkTcTyVar :: TcTyVar -> TcM TcType
    -- Simply look through all Flexis
    zonkTcTyVar :: TyVar -> TcM Kind
    zonkTcTyVar TyVar
    tv
      | TyVar -> Bool
    isTcTyVar TyVar
    tv
      = case TyVar -> TcTyVarDetails
    tcTyVarDetails TyVar
    tv of
          SkolemTv {}   -> TcM Kind
    zonk_kind_and_return
          RuntimeUnk {} -> TcM Kind
    zonk_kind_and_return
          MetaTv { mtv_ref :: TcTyVarDetails -> IORef MetaDetails
    mtv_ref = IORef MetaDetails
    ref }
             -> do { MetaDetails
    cts <- IORef MetaDetails -> TcM MetaDetails
    forall a env. IORef a -> IOEnv env a
    readMutVar IORef MetaDetails
    ref
                   ; case MetaDetails
    cts of
                        MetaDetails
    Flexi       -> TcM Kind
    zonk_kind_and_return
                        Indirect Kind
    ty -> do { Kind
    zty <- Kind -> TcM Kind
    zonkTcType Kind
    ty
                                          ; IORef MetaDetails -> MetaDetails -> TcRn ()
    forall a gbl lcl. TcRef a -> a -> TcRnIf gbl lcl ()
    writeTcRef IORef MetaDetails
    ref (Kind -> MetaDetails
    Indirect Kind
    zty)
                                            -- See Note [Sharing in zonking]
                                          ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Kind
    zty } }

      | Bool
    otherwise -- coercion variable
      = TcM Kind
    zonk_kind_and_return
      where
        zonk_kind_and_return :: TcM Kind
    zonk_kind_and_return = do { TyVar
    z_tv <- TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTyCoVarKind TyVar
    tv
                                  ; Kind -> TcM Kind
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVar -> Kind
    mkTyVarTy TyVar
    z_tv) }

    -- Variant that assumes that any result of zonking is still a TyVar.
    -- Should be used only on skolems and TyVarTvs
    zonkTcTyVarsToTcTyVars :: HasDebugCallStack => [TcTyVar] -> TcM [TcTyVar]
    zonkTcTyVarsToTcTyVars :: (() :: Constraint) => [TyVar] -> TcM [TyVar]
    zonkTcTyVarsToTcTyVars = (TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar)
    -> [TyVar] -> TcM [TyVar]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (() :: Constraint) => TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTcTyVarToTcTyVar

    zonkTcTyVarToTcTyVar :: HasDebugCallStack => TcTyVar -> TcM TcTyVar
    zonkTcTyVarToTcTyVar :: (() :: Constraint) => TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTcTyVarToTcTyVar TyVar
    tv
      = do { Kind
    ty <- TyVar -> TcM Kind
    zonkTcTyVar TyVar
    tv
           ; let tv' :: TyVar
    tv' = case Kind -> Maybe TyVar
    getTyVar_maybe Kind
    ty of
                         Just TyVar
    tv' -> TyVar
    tv'
                         Maybe TyVar
    Nothing  -> String -> SDoc -> TyVar
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "zonkTcTyVarToTcTyVar"
                                              (TyVar -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyVar
    tv SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Kind -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Kind
    ty)
           ; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TyVar
    tv' }

    zonkInvisTVBinder :: VarBndr TcTyVar spec -> TcM (VarBndr TcTyVar spec)
    zonkInvisTVBinder :: forall spec. VarBndr TyVar spec -> TcM (VarBndr TyVar spec)
    zonkInvisTVBinder (Bndr TyVar
    tv spec
    spec) = do { TyVar
    tv' <- (() :: Constraint) => TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkTcTyVarToTcTyVar TyVar
    tv
                                          ; VarBndr TyVar spec -> TcM (VarBndr TyVar spec)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVar -> spec -> VarBndr TyVar spec
    forall var argf. var -> argf -> VarBndr var argf
    Bndr TyVar
    tv' spec
    spec) }

    -- zonkId is used *during* typechecking just to zonk the Id's type
    zonkId :: TcId -> TcM TcId
    zonkId :: TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkId TyVar
    id = (Kind -> TcM Kind) -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    forall (m :: * -> *).
    Monad m =>
    (Kind -> m Kind) -> TyVar -> m TyVar
    Id.updateIdTypeAndMultM Kind -> TcM Kind
    zonkTcType TyVar
    id

    zonkCoVar :: CoVar -> TcM CoVar
    zonkCoVar :: TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkCoVar = TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
    zonkId

    {- Note [Sharing in zonking]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Suppose we have
       alpha :-> beta :-> gamma :-> ty
    where the ":->" means that the unification variable has been
    filled in with Indirect. Then when zonking alpha, it'd be nice
    to short-circuit beta too, so we end up with
       alpha :-> zty
       beta  :-> zty
       gamma :-> zty
    where zty is the zonked version of ty.  That way, if we come across
    beta later, we'll have less work to do.  (And indeed the same for
    alpha.)

    This is easily achieved: just overwrite (Indirect ty) with (Indirect
    zty).  Non-systematic perf comparisons suggest that this is a modest
    win.

    But c.f Note [Sharing when zonking to Type] in GHC.Tc.Utils.Zonk.

    %************************************************************************
    %*                                                                      *
                     Tidying
    *                                                                      *
    ************************************************************************
    -}

    zonkTidyTcType :: TidyEnv -> TcType -> TcM (TidyEnv, TcType)
    zonkTidyTcType :: TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env Kind
    ty = do { Kind
    ty' <- Kind -> TcM Kind
    zonkTcType Kind
    ty
                               ; (TidyEnv, Kind) -> TcM (TidyEnv, Kind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv -> Kind -> (TidyEnv, Kind)
    tidyOpenType TidyEnv
    env Kind
    ty') }

    zonkTidyTcTypes :: TidyEnv -> [TcType] -> TcM (TidyEnv, [TcType])
    zonkTidyTcTypes :: TidyEnv -> [Kind] -> TcM (TidyEnv, [Kind])
    zonkTidyTcTypes = [Kind] -> TidyEnv -> [Kind] -> TcM (TidyEnv, [Kind])
    zonkTidyTcTypes' []
      where zonkTidyTcTypes' :: [Kind] -> TidyEnv -> [Kind] -> TcM (TidyEnv, [Kind])
    zonkTidyTcTypes' [Kind]
    zs TidyEnv
    env [] = (TidyEnv, [Kind]) -> TcM (TidyEnv, [Kind])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env, [Kind] -> [Kind]
    forall a. [a] -> [a]
    reverse [Kind]
    zs)
            zonkTidyTcTypes' [Kind]
    zs TidyEnv
    env (Kind
    ty:[Kind]
    tys)
              = do { (TidyEnv
    env', Kind
    ty') <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env Kind
    ty
                   ; [Kind] -> TidyEnv -> [Kind] -> TcM (TidyEnv, [Kind])
    zonkTidyTcTypes' (Kind
    ty'Kind -> [Kind] -> [Kind]
    forall a. a -> [a] -> [a]
    :[Kind]
    zs) TidyEnv
    env' [Kind]
    tys }

    zonkTidyOrigin :: TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin :: TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin TidyEnv
    env (GivenOrigin SkolemInfoAnon
    skol_info)
      = do { SkolemInfoAnon
    skol_info1 <- SkolemInfoAnon -> TcM SkolemInfoAnon
    zonkSkolemInfoAnon SkolemInfoAnon
    skol_info
           ; let skol_info2 :: SkolemInfoAnon
    skol_info2 = TidyEnv -> SkolemInfoAnon -> SkolemInfoAnon
    tidySkolemInfoAnon TidyEnv
    env SkolemInfoAnon
    skol_info1
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env, SkolemInfoAnon -> CtOrigin
    GivenOrigin SkolemInfoAnon
    skol_info2) }
    zonkTidyOrigin TidyEnv
    env (GivenSCOrigin SkolemInfoAnon
    skol_info Int
    sc_depth Bool
    blocked)
      = do { SkolemInfoAnon
    skol_info1 <- SkolemInfoAnon -> TcM SkolemInfoAnon
    zonkSkolemInfoAnon SkolemInfoAnon
    skol_info
           ; let skol_info2 :: SkolemInfoAnon
    skol_info2 = TidyEnv -> SkolemInfoAnon -> SkolemInfoAnon
    tidySkolemInfoAnon TidyEnv
    env SkolemInfoAnon
    skol_info1
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env, SkolemInfoAnon -> Int -> Bool -> CtOrigin
    GivenSCOrigin SkolemInfoAnon
    skol_info2 Int
    sc_depth Bool
    blocked) }
    zonkTidyOrigin TidyEnv
    env orig :: CtOrigin
    orig@(TypeEqOrigin { uo_actual :: CtOrigin -> Kind
    uo_actual   = Kind
    act
                                          , uo_expected :: CtOrigin -> Kind
    uo_expected = Kind
    exp })
      = do { (TidyEnv
    env1, Kind
    act') <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env  Kind
    act
           ; (TidyEnv
    env2, Kind
    exp') <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env1 Kind
    exp
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ( TidyEnv
    env2, CtOrigin
    orig { uo_actual   = act'
                                 , uo_expected = exp' }) }
    zonkTidyOrigin TidyEnv
    env (KindEqOrigin Kind
    ty1 Kind
    ty2 CtOrigin
    orig Maybe TypeOrKind
    t_or_k)
      = do { (TidyEnv
    env1, Kind
    ty1')  <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env  Kind
    ty1
           ; (TidyEnv
    env2, Kind
    ty2')  <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env1 Kind
    ty2
           ; (TidyEnv
    env3, CtOrigin
    orig') <- TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin TidyEnv
    env2 CtOrigin
    orig
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env3, Kind -> Kind -> CtOrigin -> Maybe TypeOrKind -> CtOrigin
    KindEqOrigin Kind
    ty1' Kind
    ty2' CtOrigin
    orig' Maybe TypeOrKind
    t_or_k) }
    zonkTidyOrigin TidyEnv
    env (FunDepOrigin1 Kind
    p1 CtOrigin
    o1 RealSrcSpan
    l1 Kind
    p2 CtOrigin
    o2 RealSrcSpan
    l2)
      = do { (TidyEnv
    env1, Kind
    p1') <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env  Kind
    p1
           ; (TidyEnv
    env2, CtOrigin
    o1') <- TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin TidyEnv
    env1 CtOrigin
    o1
           ; (TidyEnv
    env3, Kind
    p2') <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env2 Kind
    p2
           ; (TidyEnv
    env4, CtOrigin
    o2') <- TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin TidyEnv
    env3 CtOrigin
    o2
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env4, Kind
    -> CtOrigin
    -> RealSrcSpan
    -> Kind
    -> CtOrigin
    -> RealSrcSpan
    -> CtOrigin
    FunDepOrigin1 Kind
    p1' CtOrigin
    o1' RealSrcSpan
    l1 Kind
    p2' CtOrigin
    o2' RealSrcSpan
    l2) }
    zonkTidyOrigin TidyEnv
    env (FunDepOrigin2 Kind
    p1 CtOrigin
    o1 Kind
    p2 SrcSpan
    l2)
      = do { (TidyEnv
    env1, Kind
    p1') <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env  Kind
    p1
           ; (TidyEnv
    env2, Kind
    p2') <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env1 Kind
    p2
           ; (TidyEnv
    env3, CtOrigin
    o1') <- TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin TidyEnv
    env2 CtOrigin
    o1
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env3, Kind -> CtOrigin -> Kind -> SrcSpan -> CtOrigin
    FunDepOrigin2 Kind
    p1' CtOrigin
    o1' Kind
    p2' SrcSpan
    l2) }
    zonkTidyOrigin TidyEnv
    env (InjTFOrigin1 Kind
    pred1 CtOrigin
    orig1 RealSrcSpan
    loc1 Kind
    pred2 CtOrigin
    orig2 RealSrcSpan
    loc2)
      = do { (TidyEnv
    env1, Kind
    pred1') <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env  Kind
    pred1
           ; (TidyEnv
    env2, CtOrigin
    orig1') <- TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin TidyEnv
    env1 CtOrigin
    orig1
           ; (TidyEnv
    env3, Kind
    pred2') <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env2 Kind
    pred2
           ; (TidyEnv
    env4, CtOrigin
    orig2') <- TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin TidyEnv
    env3 CtOrigin
    orig2
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env4, Kind
    -> CtOrigin
    -> RealSrcSpan
    -> Kind
    -> CtOrigin
    -> RealSrcSpan
    -> CtOrigin
    InjTFOrigin1 Kind
    pred1' CtOrigin
    orig1' RealSrcSpan
    loc1 Kind
    pred2' CtOrigin
    orig2' RealSrcSpan
    loc2) }
    zonkTidyOrigin TidyEnv
    env (CycleBreakerOrigin CtOrigin
    orig)
      = do { (TidyEnv
    env1, CtOrigin
    orig') <- TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin TidyEnv
    env CtOrigin
    orig
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env1, CtOrigin -> CtOrigin
    CycleBreakerOrigin CtOrigin
    orig') }
    zonkTidyOrigin TidyEnv
    env (InstProvidedOrigin Module
    mod ClsInst
    cls_inst)
      = do { (TidyEnv
    env1, [Kind]
    is_tys') <- (TidyEnv -> Kind -> TcM (TidyEnv, Kind))
    -> TidyEnv -> [Kind] -> TcM (TidyEnv, [Kind])
    forall (m :: * -> *) (t :: * -> *) acc x y.
    (Monad m, Traversable t) =>
    (acc -> x -> m (acc, y)) -> acc -> t x -> m (acc, t y)
    mapAccumLM TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env (ClsInst -> [Kind]
    is_tys ClsInst
    cls_inst)
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env1, Module -> ClsInst -> CtOrigin
    InstProvidedOrigin Module
    mod (ClsInst
    cls_inst {is_tys = is_tys'})) }
    zonkTidyOrigin TidyEnv
    env (WantedSuperclassOrigin Kind
    pty CtOrigin
    orig)
      = do { (TidyEnv
    env1, Kind
    pty')  <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env Kind
    pty
           ; (TidyEnv
    env2, CtOrigin
    orig') <- TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin TidyEnv
    env1 CtOrigin
    orig
           ; (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env2, Kind -> CtOrigin -> CtOrigin
    WantedSuperclassOrigin Kind
    pty' CtOrigin
    orig') }
    zonkTidyOrigin TidyEnv
    env CtOrigin
    orig = (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env, CtOrigin
    orig)

    zonkTidyOrigins :: TidyEnv -> [CtOrigin] -> TcM (TidyEnv, [CtOrigin])
    zonkTidyOrigins :: TidyEnv -> [CtOrigin] -> TcM (TidyEnv, [CtOrigin])
    zonkTidyOrigins = (TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin))
    -> TidyEnv -> [CtOrigin] -> TcM (TidyEnv, [CtOrigin])
    forall (m :: * -> *) (t :: * -> *) acc x y.
    (Monad m, Traversable t) =>
    (acc -> x -> m (acc, y)) -> acc -> t x -> m (acc, t y)
    mapAccumLM TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
    zonkTidyOrigin

    zonkTidyFRRInfos :: TidyEnv
                     -> [FixedRuntimeRepErrorInfo]
                     -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    zonkTidyFRRInfos :: TidyEnv
    -> [FixedRuntimeRepErrorInfo]
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    zonkTidyFRRInfos = [FixedRuntimeRepErrorInfo]
    -> TidyEnv
    -> [FixedRuntimeRepErrorInfo]
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    go []
      where
        go :: [FixedRuntimeRepErrorInfo]
    -> TidyEnv
    -> [FixedRuntimeRepErrorInfo]
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    go [FixedRuntimeRepErrorInfo]
    zs TidyEnv
    env [] = (TidyEnv, [FixedRuntimeRepErrorInfo])
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env, [FixedRuntimeRepErrorInfo] -> [FixedRuntimeRepErrorInfo]
    forall a. [a] -> [a]
    reverse [FixedRuntimeRepErrorInfo]
    zs)
        go [FixedRuntimeRepErrorInfo]
    zs TidyEnv
    env (FRR_Info { frr_info_origin :: FixedRuntimeRepErrorInfo -> FixedRuntimeRepOrigin
    frr_info_origin = FixedRuntimeRepOrigin Kind
    ty FixedRuntimeRepContext
    orig
                            , frr_info_not_concrete :: FixedRuntimeRepErrorInfo -> Maybe (TyVar, Kind)
    frr_info_not_concrete = Maybe (TyVar, Kind)
    mb_not_conc } : [FixedRuntimeRepErrorInfo]
    tys)
          = do { (TidyEnv
    env, Kind
    ty) <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env Kind
    ty
               ; (TidyEnv
    env, Maybe (TyVar, Kind)
    mb_not_conc) <- TidyEnv
    -> Maybe (TyVar, Kind)
    -> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, Maybe (TyVar, Kind))
    go_mb_not_conc TidyEnv
    env Maybe (TyVar, Kind)
    mb_not_conc
               ; let info :: FixedRuntimeRepErrorInfo
    info = FRR_Info { frr_info_origin :: FixedRuntimeRepOrigin
    frr_info_origin = Kind -> FixedRuntimeRepContext -> FixedRuntimeRepOrigin
    FixedRuntimeRepOrigin Kind
    ty FixedRuntimeRepContext
    orig
                                     , frr_info_not_concrete :: Maybe (TyVar, Kind)
    frr_info_not_concrete = Maybe (TyVar, Kind)
    mb_not_conc }
               ; [FixedRuntimeRepErrorInfo]
    -> TidyEnv
    -> [FixedRuntimeRepErrorInfo]
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    go (FixedRuntimeRepErrorInfo
    infoFixedRuntimeRepErrorInfo
    -> [FixedRuntimeRepErrorInfo] -> [FixedRuntimeRepErrorInfo]
    forall a. a -> [a] -> [a]
    :[FixedRuntimeRepErrorInfo]
    zs) TidyEnv
    env [FixedRuntimeRepErrorInfo]
    tys }

        go_mb_not_conc :: TidyEnv
    -> Maybe (TyVar, Kind)
    -> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, Maybe (TyVar, Kind))
    go_mb_not_conc TidyEnv
    env Maybe (TyVar, Kind)
    Nothing = (TidyEnv, Maybe (TyVar, Kind))
    -> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, Maybe (TyVar, Kind))
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env, Maybe (TyVar, Kind)
    forall a. Maybe a
    Nothing)
        go_mb_not_conc TidyEnv
    env (Just (TyVar
    tv, Kind
    ty))
          = do { (TidyEnv
    env, TyVar
    tv) <- (TidyEnv, TyVar) -> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, TyVar)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((TidyEnv, TyVar)
     -> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, TyVar))
    -> (TidyEnv, TyVar)
    -> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, TyVar)
    forall a b. (a -> b) -> a -> b
    $ TidyEnv -> TyVar -> (TidyEnv, TyVar)
    tidyOpenTyCoVar TidyEnv
    env TyVar
    tv
               ; (TidyEnv
    env, Kind
    ty) <- TidyEnv -> Kind -> TcM (TidyEnv, Kind)
    zonkTidyTcType TidyEnv
    env Kind
    ty
               ; (TidyEnv, Maybe (TyVar, Kind))
    -> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, Maybe (TyVar, Kind))
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    env, (TyVar, Kind) -> Maybe (TyVar, Kind)
    forall a. a -> Maybe a
    Just (TyVar
    tv, Kind
    ty)) }

    ----------------
    tidyCt :: TidyEnv -> Ct -> Ct
    -- Used only in error reporting
    tidyCt :: TidyEnv -> Ct -> Ct
    tidyCt TidyEnv
    env Ct
    ct = Ct
    ct { cc_ev = tidyCtEvidence env (ctEvidence ct) }

    tidyCtEvidence :: TidyEnv -> CtEvidence -> CtEvidence
         -- NB: we do not tidy the ctev_evar field because we don't
         --     show it in error messages
    tidyCtEvidence :: TidyEnv -> CtEvidence -> CtEvidence
    tidyCtEvidence TidyEnv
    env CtEvidence
    ctev = CtEvidence
    ctev { ctev_pred = tidyType env ty }
      where
        ty :: Kind
    ty  = CtEvidence -> Kind
    ctev_pred CtEvidence
    ctev

    tidyHole :: TidyEnv -> Hole -> Hole
    tidyHole :: TidyEnv -> Hole -> Hole
    tidyHole TidyEnv
    env h :: Hole
    h@(Hole { hole_ty :: Hole -> Kind
    hole_ty = Kind
    ty }) = Hole
    h { hole_ty = tidyType env ty }

    tidyDelayedError :: TidyEnv -> DelayedError -> DelayedError
    tidyDelayedError :: TidyEnv -> DelayedError -> DelayedError
    tidyDelayedError TidyEnv
    env (DE_Hole Hole
    hole)
      = Hole -> DelayedError
    DE_Hole (Hole -> DelayedError) -> Hole -> DelayedError
    forall a b. (a -> b) -> a -> b
    $ TidyEnv -> Hole -> Hole
    tidyHole TidyEnv
    env Hole
    hole
    tidyDelayedError TidyEnv
    env (DE_NotConcrete NotConcreteError
    err)
      = NotConcreteError -> DelayedError
    DE_NotConcrete (NotConcreteError -> DelayedError)
    -> NotConcreteError -> DelayedError
    forall a b. (a -> b) -> a -> b
    $ TidyEnv -> NotConcreteError -> NotConcreteError
    tidyConcreteError TidyEnv
    env NotConcreteError
    err

    tidyConcreteError :: TidyEnv -> NotConcreteError -> NotConcreteError
    tidyConcreteError :: TidyEnv -> NotConcreteError -> NotConcreteError
    tidyConcreteError TidyEnv
    env err :: NotConcreteError
    err@(NCE_FRR { nce_frr_origin :: NotConcreteError -> FixedRuntimeRepOrigin
    nce_frr_origin = FixedRuntimeRepOrigin
    frr_orig })
      = NotConcreteError
    err { nce_frr_origin = tidyFRROrigin env frr_orig }

    tidyFRROrigin :: TidyEnv -> FixedRuntimeRepOrigin -> FixedRuntimeRepOrigin
    tidyFRROrigin :: TidyEnv -> FixedRuntimeRepOrigin -> FixedRuntimeRepOrigin
    tidyFRROrigin TidyEnv
    env (FixedRuntimeRepOrigin Kind
    ty FixedRuntimeRepContext
    orig)
      = Kind -> FixedRuntimeRepContext -> FixedRuntimeRepOrigin
    FixedRuntimeRepOrigin (TidyEnv -> Kind -> Kind
    tidyType TidyEnv
    env Kind
    ty) FixedRuntimeRepContext
    orig

    ----------------
    tidyEvVar :: TidyEnv -> EvVar -> EvVar
    tidyEvVar :: TidyEnv -> TyVar -> TyVar
    tidyEvVar TidyEnv
    env TyVar
    var = (Kind -> Kind) -> TyVar -> TyVar
    updateIdTypeAndMult (TidyEnv -> Kind -> Kind
    tidyType TidyEnv
    env) TyVar
    var

    -------------------------------------------------------------------------
    {-
    %************************************************************************
    %*                                                                      *
                 Representation polymorphism checks
    *                                                                       *
    ***********************************************************************-}

    -- | Check that the specified type has a fixed runtime representation.
    --
    -- If it isn't, throw a representation-polymorphism error appropriate
    -- for the context (as specified by the 'FixedRuntimeRepProvenance').
    --
    -- Unlike the other representation polymorphism checks, which can emit
    -- new Wanted constraints to be solved by the constraint solver, this function
    -- does not emit any constraints: it has enough information to immediately
    -- make a decision.
    --
    -- See (1) in Note [Representation polymorphism checking] in GHC.Tc.Utils.Concrete
    checkTypeHasFixedRuntimeRep :: FixedRuntimeRepProvenance -> Type -> TcM ()
    checkTypeHasFixedRuntimeRep :: FixedRuntimeRepProvenance -> Kind -> TcRn ()
    checkTypeHasFixedRuntimeRep FixedRuntimeRepProvenance
    prov Kind
    ty =
      Bool -> TcRn () -> TcRn ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ((() :: Constraint) => Kind -> Bool
    Kind -> Bool
    typeHasFixedRuntimeRep Kind
    ty)
        ((ErrInfo -> TcRnMessage) -> TcRn ()
    addDetailedDiagnostic ((ErrInfo -> TcRnMessage) -> TcRn ())
    -> (ErrInfo -> TcRnMessage) -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $ Kind -> FixedRuntimeRepProvenance -> ErrInfo -> TcRnMessage
    TcRnTypeDoesNotHaveFixedRuntimeRep Kind
    ty FixedRuntimeRepProvenance
    prov)

    {-
    %************************************************************************
    %*                                                                      *
                 Error messages
    *                                                                       *
    *************************************************************************

    -}

    -- See Note [Naughty quantification candidates]
    naughtyQuantification :: TcType   -- original type user wanted to quantify
                          -> TcTyVar  -- naughty var
                          -> TyVarSet -- skolems that would escape
                          -> TcM a
    naughtyQuantification :: forall a. Kind -> TyVar -> CoVarSet -> TcM a
    naughtyQuantification Kind
    orig_ty TyVar
    tv CoVarSet
    escapees
      = do { Kind
    orig_ty1 <- Kind -> TcM Kind
    zonkTcType Kind
    orig_ty  -- in case it's not zonked

           ; [TyVar]
    escapees' <- [TyVar] -> TcM [TyVar]
    (() :: Constraint) => [TyVar] -> TcM [TyVar]
    zonkTcTyVarsToTcTyVars ([TyVar] -> TcM [TyVar]) -> [TyVar] -> TcM [TyVar]
    forall a b. (a -> b) -> a -> b
    $
                          CoVarSet -> [TyVar]
    forall elt. UniqSet elt -> [elt]
    nonDetEltsUniqSet CoVarSet
    escapees
                         -- we'll just be printing, so no harmful non-determinism

           ; let fvs :: [TyVar]
    fvs  = Kind -> [TyVar]
    tyCoVarsOfTypeWellScoped Kind
    orig_ty1
                 env0 :: TidyEnv
    env0 = TidyEnv -> [TyVar] -> TidyEnv
    tidyFreeTyCoVars TidyEnv
    emptyTidyEnv [TyVar]
    fvs
                 env :: TidyEnv
    env  = TidyEnv
    env0 TidyEnv -> [TyVar] -> TidyEnv
    `delTidyEnvList` [TyVar]
    escapees'
                        -- this avoids gratuitous renaming of the escaped
                        -- variables; very confusing to users!

                 orig_ty' :: Kind
    orig_ty'   = TidyEnv -> Kind -> Kind
    tidyType TidyEnv
    env Kind
    orig_ty1
                 ppr_tidied :: [TyVar] -> SDoc
    ppr_tidied = [TyVar] -> SDoc
    pprTyVars ([TyVar] -> SDoc) -> ([TyVar] -> [TyVar]) -> [TyVar] -> SDoc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (TyVar -> TyVar) -> [TyVar] -> [TyVar]
    forall a b. (a -> b) -> [a] -> [b]
    map (TidyEnv -> TyVar -> TyVar
    tidyTyCoVarOcc TidyEnv
    env)
                 msg :: TcRnMessage
    msg = DiagnosticMessage -> TcRnMessage
    forall a.
    (Diagnostic a, Typeable a, DiagnosticOpts a ~ NoDiagnosticOpts) =>
    a -> TcRnMessage
    mkTcRnUnknownMessage (DiagnosticMessage -> TcRnMessage)
    -> DiagnosticMessage -> TcRnMessage
    forall a b. (a -> b) -> a -> b
    $ [GhcHint] -> SDoc -> DiagnosticMessage
    mkPlainError [GhcHint]
    noHints (SDoc -> DiagnosticMessage) -> SDoc -> DiagnosticMessage
    forall a b. (a -> b) -> a -> b
    $
                       Bool -> SDoc -> SDoc
    pprWithExplicitKindsWhen Bool
    True (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
                       [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat [ [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    sep [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Cannot generalise type; skolem" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> [TyVar] -> SDoc
    forall a. [a] -> SDoc
    plural [TyVar]
    escapees'
                                  , SDoc -> SDoc
    quotes (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $ [TyVar] -> SDoc
    ppr_tidied [TyVar]
    escapees'
                                  , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "would escape" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [TyVar] -> SDoc
    forall a. [a] -> SDoc
    itsOrTheir [TyVar]
    escapees' SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "scope"
                                  ]
                            , [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    sep [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "if I tried to quantify"
                                  , [TyVar] -> SDoc
    ppr_tidied [TyVar
    tv]
                                  , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "in this type:"
                                  ]
                            , Int -> SDoc -> SDoc
    nest Int
    2 (Kind -> SDoc
    pprTidiedType Kind
    orig_ty')
                            , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "(Indeed, I sometimes struggle even printing this correctly,"
                            , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    " due to its ill-scoped nature.)"
                            ]

           ; (TidyEnv, TcRnMessage) -> TcM a
    forall a. (TidyEnv, TcRnMessage) -> TcM a
    failWithTcM (TidyEnv
    env, TcRnMessage
    msg) }

    {-
    ************************************************************************
    *                                                                      *
                 Checking for coercion holes
    *                                                                      *
    ************************************************************************
    -}

    -- | Check whether any coercion hole in a RewriterSet is still unsolved.
    -- Does this by recursively looking through filled coercion holes until
    -- one is found that is not yet filled in, at which point this aborts.
    anyUnfilledCoercionHoles :: RewriterSet -> TcM Bool
    anyUnfilledCoercionHoles :: RewriterSet -> TcRnIf TcGblEnv TcLclEnv Bool
    anyUnfilledCoercionHoles (RewriterSet UniqSet CoercionHole
    set)
      = (CoercionHole
     -> TcRnIf TcGblEnv TcLclEnv Bool -> TcRnIf TcGblEnv TcLclEnv Bool)
    -> TcRnIf TcGblEnv TcLclEnv Bool
    -> UniqSet CoercionHole
    -> TcRnIf TcGblEnv TcLclEnv Bool
    forall elt a. (elt -> a -> a) -> a -> UniqSet elt -> a
    nonDetStrictFoldUniqSet CoercionHole
    -> TcRnIf TcGblEnv TcLclEnv Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    go (Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False) UniqSet CoercionHole
    set
         -- this does not introduce non-determinism, because the only
         -- monadic action is to read, and the combining function is
         -- commutative
      where
        go :: CoercionHole -> TcM Bool -> TcM Bool
        go :: CoercionHole
    -> TcRnIf TcGblEnv TcLclEnv Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    go CoercionHole
    hole TcRnIf TcGblEnv TcLclEnv Bool
    m_acc = TcRnIf TcGblEnv TcLclEnv Bool
    m_acc TcRnIf TcGblEnv TcLclEnv Bool
    -> TcRnIf TcGblEnv TcLclEnv Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall (f :: * -> *). Applicative f => f Bool -> f Bool -> f Bool
    <||> CoercionHole -> TcRnIf TcGblEnv TcLclEnv Bool
    check_hole CoercionHole
    hole

        check_hole :: CoercionHole -> TcM Bool
        check_hole :: CoercionHole -> TcRnIf TcGblEnv TcLclEnv Bool
    check_hole CoercionHole
    hole = do { Maybe Coercion
    m_co <- CoercionHole -> TcRnIf TcGblEnv TcLclEnv (Maybe Coercion)
    unpackCoercionHole_maybe CoercionHole
    hole
                             ; case Maybe Coercion
    m_co of
                                 Maybe Coercion
    Nothing -> Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True  -- unfilled hole
                                 Just Coercion
    co -> UnfilledCoercionHoleMonoid -> TcRnIf TcGblEnv TcLclEnv Bool
    unUCHM (Coercion -> UnfilledCoercionHoleMonoid
    check_co Coercion
    co) }

        check_ty :: Type -> UnfilledCoercionHoleMonoid
        check_co :: Coercion -> UnfilledCoercionHoleMonoid
        (Kind -> UnfilledCoercionHoleMonoid
    check_ty, [Kind] -> UnfilledCoercionHoleMonoid
    _, Coercion -> UnfilledCoercionHoleMonoid
    check_co, [Coercion] -> UnfilledCoercionHoleMonoid
    _) = TyCoFolder () UnfilledCoercionHoleMonoid
    -> ()
    -> (Kind -> UnfilledCoercionHoleMonoid,
        [Kind] -> UnfilledCoercionHoleMonoid,
        Coercion -> UnfilledCoercionHoleMonoid,
        [Coercion] -> UnfilledCoercionHoleMonoid)
    forall a env.
    Monoid a =>
    TyCoFolder env a
    -> env -> (Kind -> a, [Kind] -> a, Coercion -> a, [Coercion] -> a)
    foldTyCo TyCoFolder () UnfilledCoercionHoleMonoid
    folder ()

        folder :: TyCoFolder () UnfilledCoercionHoleMonoid
        folder :: TyCoFolder () UnfilledCoercionHoleMonoid
    folder = TyCoFolder { tcf_view :: Kind -> Maybe Kind
    tcf_view  = Kind -> Maybe Kind
    noView
                            , tcf_tyvar :: () -> TyVar -> UnfilledCoercionHoleMonoid
    tcf_tyvar = \ ()
    _ TyVar
    tv -> Kind -> UnfilledCoercionHoleMonoid
    check_ty (TyVar -> Kind
    tyVarKind TyVar
    tv)
                            , tcf_covar :: () -> TyVar -> UnfilledCoercionHoleMonoid
    tcf_covar = \ ()
    _ TyVar
    cv -> Kind -> UnfilledCoercionHoleMonoid
    check_ty (TyVar -> Kind
    varType TyVar
    cv)
                            , tcf_hole :: () -> CoercionHole -> UnfilledCoercionHoleMonoid
    tcf_hole  = \ ()
    _ -> TcRnIf TcGblEnv TcLclEnv Bool -> UnfilledCoercionHoleMonoid
    UCHM (TcRnIf TcGblEnv TcLclEnv Bool -> UnfilledCoercionHoleMonoid)
    -> (CoercionHole -> TcRnIf TcGblEnv TcLclEnv Bool)
    -> CoercionHole
    -> UnfilledCoercionHoleMonoid
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CoercionHole -> TcRnIf TcGblEnv TcLclEnv Bool
    check_hole
                            , tcf_tycobinder :: () -> TyVar -> ForAllTyFlag -> ()
    tcf_tycobinder = \ ()
    _ TyVar
    _ ForAllTyFlag
    _ -> () }

    newtype UnfilledCoercionHoleMonoid = UCHM { UnfilledCoercionHoleMonoid -> TcRnIf TcGblEnv TcLclEnv Bool
    unUCHM :: TcM Bool }

    instance Semigroup UnfilledCoercionHoleMonoid where
      UCHM TcRnIf TcGblEnv TcLclEnv Bool
    l <> :: UnfilledCoercionHoleMonoid
    -> UnfilledCoercionHoleMonoid -> UnfilledCoercionHoleMonoid
    <> UCHM TcRnIf TcGblEnv TcLclEnv Bool
    r = TcRnIf TcGblEnv TcLclEnv Bool -> UnfilledCoercionHoleMonoid
    UCHM (TcRnIf TcGblEnv TcLclEnv Bool
    l TcRnIf TcGblEnv TcLclEnv Bool
    -> TcRnIf TcGblEnv TcLclEnv Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall (f :: * -> *). Applicative f => f Bool -> f Bool -> f Bool
    <||> TcRnIf TcGblEnv TcLclEnv Bool
    r)

    instance Monoid UnfilledCoercionHoleMonoid where
      mempty :: UnfilledCoercionHoleMonoid
    mempty = TcRnIf TcGblEnv TcLclEnv Bool -> UnfilledCoercionHoleMonoid
    UCHM (Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False)