    {-# LANGUAGE FlexibleContexts    #-}
    {-# LANGUAGE LambdaCase          #-}
    {-# LANGUAGE MultiWayIf          #-}
    {-# LANGUAGE NamedFieldPuns      #-}
    {-# LANGUAGE ParallelListComp    #-}
    {-# LANGUAGE ScopedTypeVariables #-}

    {-# OPTIONS_GHC -Wno-incomplete-uni-patterns   #-}

    module GHC.Tc.Errors(
           reportUnsolved, reportAllUnsolved, warnAllUnsolved,
           warnDefaulting,

           -- * GHC API helper functions
           solverReportMsg_ExpectedActuals, mismatchMsg_ExpectedActuals
      ) where

    import GHC.Prelude

    import GHC.Driver.Env (hsc_units)
    import GHC.Driver.DynFlags
    import GHC.Driver.Ppr
    import GHC.Driver.Config.Diagnostic

    import GHC.Rename.Unbound

    import GHC.Tc.Types
    import GHC.Tc.Utils.Monad
    import GHC.Tc.Errors.Types
    import GHC.Tc.Errors.Ppr
    import GHC.Tc.Types.Constraint
    import GHC.Tc.Utils.TcMType
    import GHC.Tc.Zonk.Type
    import GHC.Tc.Utils.TcType
    import GHC.Tc.Zonk.TcType
    import GHC.Tc.Types.Origin
    import GHC.Tc.Types.Evidence
    import GHC.Tc.Types.EvTerm
    import GHC.Tc.Instance.Family
    import GHC.Tc.Utils.Instantiate
    import {-# SOURCE #-} GHC.Tc.Errors.Hole ( findValidHoleFits, getHoleFitDispConfig, pprHoleFit )

    import GHC.Types.Name
    import GHC.Types.Name.Reader
    import GHC.Types.Id
    import GHC.Types.Var
    import GHC.Types.Var.Set
    import GHC.Types.Var.Env
    import GHC.Types.Name.Env
    import GHC.Types.SrcLoc
    import GHC.Types.Basic
    import GHC.Types.Error
    import qualified GHC.Types.Unique.Map as UM

    --import GHC.Rename.Unbound ( unknownNameSuggestions, WhatLooking(..) )
    import GHC.Unit.Module
    import qualified GHC.LanguageExtensions as LangExt

    import GHC.Core.Predicate
    import GHC.Core.Type
    import GHC.Core.Coercion
    import GHC.Core.TyCo.Ppr     ( pprTyVars )
    import GHC.Core.InstEnv
    import GHC.Core.TyCon
    import GHC.Core.DataCon

    import GHC.Utils.Error  (diagReasonSeverity,  pprLocMsgEnvelope )
    import GHC.Utils.Misc
    import GHC.Utils.Outputable as O
    import GHC.Utils.Panic
    import GHC.Utils.FV ( fvVarList, unionFV )

    import GHC.Data.Bag
    import GHC.Data.List.SetOps ( equivClasses, nubOrdBy )
    import GHC.Data.Maybe
    import qualified GHC.Data.Strict as Strict

    import Control.Monad      ( unless, when, foldM, forM_ )
    import Data.Foldable      ( toList )
    import Data.Function      ( on )
    import Data.List          ( partition, sort, sortBy )
    import Data.List.NonEmpty ( NonEmpty(..), nonEmpty )
    import qualified Data.List.NonEmpty as NE
    import Data.Ord         ( comparing )
    import qualified Data.Semigroup as S

    {-
    ************************************************************************
    *                                                                      *
    \section{Errors and contexts}
    *                                                                      *
    ************************************************************************

    ToDo: for these error messages, should we note the location as coming
    from the insts, or just whatever seems to be around in the monad just
    now?

    Note [Deferring coercion errors to runtime]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    While developing, sometimes it is desirable to allow compilation to succeed even
    if there are type errors in the code. Consider the following case:

      module Main where

      a :: Int
      a = 'a'

      main = print "b"

    Even though `a` is ill-typed, it is not used in the end, so if all that we're
    interested in is `main` it is handy to be able to ignore the problems in `a`.

    Since we treat type equalities as evidence, this is relatively simple. Whenever
    we run into a type mismatch in GHC.Tc.Utils.Unify, we normally just emit an error. But it
    is always safe to defer the mismatch to the main constraint solver. If we do
    that, `a` will get transformed into

      co :: Int ~ Char
      co = ...

      a :: Int
      a = 'a' `cast` co

    The constraint solver would realize that `co` is an insoluble constraint, and
    emit an error with `reportUnsolved`. But we can also replace the right-hand side
    of `co` with `error "Deferred type error: Int ~ Char"`. This allows the program
    to compile, and it will run fine unless we evaluate `a`. This is what
    `deferErrorsToRuntime` does.

    It does this by keeping track of which errors correspond to which coercion
    in GHC.Tc.Errors. GHC.Tc.Errors.reportTidyWanteds does not print the errors
    and does not fail if -fdefer-type-errors is on, so that we can continue
    compilation. The errors are turned into warnings in `reportUnsolved`.
    -}

    -- | Report unsolved goals as errors or warnings. We may also turn some into
    -- deferred run-time errors if `-fdefer-type-errors` is on.
    reportUnsolved :: WantedConstraints -> TcM (Bag EvBind)
    reportUnsolved :: WantedConstraints -> TcM (Bag EvBind)
    reportUnsolved WantedConstraints
    wanted
      = do { binds_var <- TcM EvBindsVar
    newTcEvBinds
           ; defer_errors <- goptM Opt_DeferTypeErrors
           ; let type_errors | Bool -> Bool
    not Bool
    defer_errors = DiagnosticReason
    ErrorWithoutFlag
                             | Bool
    otherwise        = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnDeferredTypeErrors

           ; defer_holes <- goptM Opt_DeferTypedHoles
           ; let expr_holes | Bool -> Bool
    not Bool
    defer_holes = DiagnosticReason
    ErrorWithoutFlag
                            | Bool
    otherwise       = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnTypedHoles

           ; partial_sigs      <- xoptM LangExt.PartialTypeSignatures
           ; let type_holes | Bool -> Bool
    not Bool
    partial_sigs
                            = DiagnosticReason
    ErrorWithoutFlag
                            | Bool
    otherwise
                            = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnPartialTypeSignatures

           ; defer_out_of_scope <- goptM Opt_DeferOutOfScopeVariables
           ; let out_of_scope_holes | Bool -> Bool
    not Bool
    defer_out_of_scope
                                    = DiagnosticReason
    ErrorWithoutFlag
                                    | Bool
    otherwise
                                    = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnDeferredOutOfScopeVariables

           ; report_unsolved type_errors expr_holes
                             type_holes out_of_scope_holes
                             binds_var wanted

           ; ev_binds <- getTcEvBindsMap binds_var
           ; return (evBindMapBinds ev_binds)}

    -- | Report *all* unsolved goals as errors, even if -fdefer-type-errors is on
    -- However, do not make any evidence bindings, because we don't
    -- have any convenient place to put them.
    -- NB: Type-level holes are OK, because there are no bindings.
    -- See Note [Deferring coercion errors to runtime]
    -- Used by solveEqualities for kind equalities
    --      (see Note [Failure in local type signatures] in GHC.Tc.Solver)
    reportAllUnsolved :: WantedConstraints -> TcM ()
    reportAllUnsolved :: WantedConstraints -> TcM ()
    reportAllUnsolved WantedConstraints
    wanted
      = do { ev_binds <- TcM EvBindsVar
    newNoTcEvBinds

           ; partial_sigs      <- xoptM LangExt.PartialTypeSignatures
           ; let type_holes | Bool -> Bool
    not Bool
    partial_sigs  = DiagnosticReason
    ErrorWithoutFlag
                            | Bool
    otherwise         = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnPartialTypeSignatures

           ; report_unsolved ErrorWithoutFlag
                             ErrorWithoutFlag type_holes ErrorWithoutFlag
                             ev_binds wanted }

    -- | Report all unsolved goals as warnings (but without deferring any errors to
    -- run-time). See Note [Safe Haskell Overlapping Instances Implementation] in
    -- "GHC.Tc.Solver"
    warnAllUnsolved :: WantedConstraints -> TcM ()
    warnAllUnsolved :: WantedConstraints -> TcM ()
    warnAllUnsolved WantedConstraints
    wanted
      = do { ev_binds <- TcM EvBindsVar
    newTcEvBinds
           ; report_unsolved WarningWithoutFlag
                             WarningWithoutFlag
                             WarningWithoutFlag
                             WarningWithoutFlag
                             ev_binds wanted }

    -- | Report unsolved goals as errors or warnings.
    report_unsolved :: DiagnosticReason -- Deferred type errors
                    -> DiagnosticReason -- Expression holes
                    -> DiagnosticReason -- Type holes
                    -> DiagnosticReason -- Out of scope holes
                    -> EvBindsVar        -- cec_binds
                    -> WantedConstraints -> TcM ()
    report_unsolved :: DiagnosticReason
    -> DiagnosticReason
    -> DiagnosticReason
    -> DiagnosticReason
    -> EvBindsVar
    -> WantedConstraints
    -> TcM ()
    report_unsolved DiagnosticReason
    type_errors DiagnosticReason
    expr_holes
        DiagnosticReason
    type_holes DiagnosticReason
    out_of_scope_holes EvBindsVar
    binds_var WantedConstraints
    wanted
      | WantedConstraints -> Bool
    isEmptyWC WantedConstraints
    wanted
      = () -> TcM ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      | Bool
    otherwise
      = do { String -> SDoc -> TcM ()
    traceTc String
    "reportUnsolved {" (SDoc -> TcM ()) -> SDoc -> TcM ()
    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
    "type errors:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> DiagnosticReason -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr DiagnosticReason
    type_errors
                  , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "expr holes:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> DiagnosticReason -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr DiagnosticReason
    expr_holes
                  , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "type holes:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> DiagnosticReason -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr DiagnosticReason
    type_holes
                  , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "scope holes:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> DiagnosticReason -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr DiagnosticReason
    out_of_scope_holes ]
           ; String -> SDoc -> TcM ()
    traceTc String
    "reportUnsolved (before zonking and tidying)" (WantedConstraints -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr WantedConstraints
    wanted)

           ; wanted <- ZonkM WantedConstraints -> TcM WantedConstraints
    forall a. ZonkM a -> TcM a
    liftZonkM (ZonkM WantedConstraints -> TcM WantedConstraints)
    -> ZonkM WantedConstraints -> TcM WantedConstraints
    forall a b. (a -> b) -> a -> b
    $ WantedConstraints -> ZonkM WantedConstraints
    zonkWC WantedConstraints
    wanted   -- Zonk to reveal all information

           ; let tidy_env = TidyEnv -> [TcId] -> TidyEnv
    tidyFreeTyCoVars TidyEnv
    emptyTidyEnv [TcId]
    free_tvs
                 free_tvs = (TcId -> Bool) -> [TcId] -> [TcId]
    forall a. (a -> Bool) -> [a] -> [a]
    filterOut TcId -> Bool
    isCoVar ([TcId] -> [TcId]) -> [TcId] -> [TcId]
    forall a b. (a -> b) -> a -> b
    $
                            WantedConstraints -> [TcId]
    tyCoVarsOfWCList WantedConstraints
    wanted
                            -- tyCoVarsOfWC returns free coercion *holes*, even though
                            -- they are "bound" by other wanted constraints. They in
                            -- turn may mention variables bound further in, which makes
                            -- no sense. Really we should not return those holes at all;
                            -- for now we just filter them out.

           ; traceTc "reportUnsolved (after zonking):" $
             vcat [ text "Free tyvars:" <+> pprTyVars free_tvs
                  , text "Tidy env:" <+> ppr tidy_env
                  , text "Wanted:" <+> ppr wanted ]

           ; warn_redundant <- woptM Opt_WarnRedundantConstraints
           ; exp_syns <- goptM Opt_PrintExpandedSynonyms
           ; let err_ctxt = CEC { cec_encl :: [Implication]
    cec_encl  = []
                                , cec_tidy :: TidyEnv
    cec_tidy  = TidyEnv
    tidy_env
                                , cec_defer_type_errors :: DiagnosticReason
    cec_defer_type_errors = DiagnosticReason
    type_errors
                                , cec_expr_holes :: DiagnosticReason
    cec_expr_holes = DiagnosticReason
    expr_holes
                                , cec_type_holes :: DiagnosticReason
    cec_type_holes = DiagnosticReason
    type_holes
                                , cec_out_of_scope_holes :: DiagnosticReason
    cec_out_of_scope_holes = DiagnosticReason
    out_of_scope_holes
                                , cec_suppress :: Bool
    cec_suppress = WantedConstraints -> Bool
    insolubleWC WantedConstraints
    wanted
                                     -- See Note [Suppressing error messages]
                                     -- Suppress low-priority errors if there
                                     -- are insoluble errors anywhere;
                                     -- See #15539 and c.f. setting ic_status
                                     -- in GHC.Tc.Solver.setImplicationStatus
                                , cec_warn_redundant :: Bool
    cec_warn_redundant = Bool
    warn_redundant
                                , cec_expand_syns :: Bool
    cec_expand_syns = Bool
    exp_syns
                                , cec_binds :: EvBindsVar
    cec_binds    = EvBindsVar
    binds_var }

           ; tc_lvl <- getTcLevel
           ; reportWanteds err_ctxt tc_lvl wanted
           ; traceTc "reportUnsolved }" empty }

    --------------------------------------------
    --      Internal functions
    --------------------------------------------

    -- | Make a report from a single 'TcSolverReportMsg'.
    important :: SolverReportErrCtxt -> TcSolverReportMsg -> SolverReport
    important :: SolverReportErrCtxt -> TcSolverReportMsg -> SolverReport
    important SolverReportErrCtxt
    ctxt TcSolverReportMsg
    doc
      = SolverReport { sr_important_msg :: SolverReportWithCtxt
    sr_important_msg = SolverReportErrCtxt -> TcSolverReportMsg -> SolverReportWithCtxt
    SolverReportWithCtxt SolverReportErrCtxt
    ctxt TcSolverReportMsg
    doc
                     , sr_supplementary :: [SolverReportSupplementary]
    sr_supplementary = [] }

    add_relevant_bindings :: RelevantBindings -> SolverReport -> SolverReport
    add_relevant_bindings :: RelevantBindings -> SolverReport -> SolverReport
    add_relevant_bindings RelevantBindings
    binds report :: SolverReport
    report@(SolverReport { sr_supplementary :: SolverReport -> [SolverReportSupplementary]
    sr_supplementary = [SolverReportSupplementary]
    supp })
      = SolverReport
    report { sr_supplementary = SupplementaryBindings binds : supp }

    -- | Returns True <=> the SolverReportErrCtxt indicates that something is deferred
    deferringAnyBindings :: SolverReportErrCtxt -> Bool
      -- Don't check cec_type_holes, as these don't cause bindings to be deferred
    deferringAnyBindings :: SolverReportErrCtxt -> Bool
    deferringAnyBindings (CEC { cec_defer_type_errors :: SolverReportErrCtxt -> DiagnosticReason
    cec_defer_type_errors  = DiagnosticReason
    ErrorWithoutFlag
                              , cec_expr_holes :: SolverReportErrCtxt -> DiagnosticReason
    cec_expr_holes         = DiagnosticReason
    ErrorWithoutFlag
                              , cec_out_of_scope_holes :: SolverReportErrCtxt -> DiagnosticReason
    cec_out_of_scope_holes = DiagnosticReason
    ErrorWithoutFlag }) = Bool
    False
    deferringAnyBindings SolverReportErrCtxt
    _                                                   = Bool
    True

    maybeSwitchOffDefer :: EvBindsVar -> SolverReportErrCtxt -> SolverReportErrCtxt
    -- Switch off defer-type-errors inside CoEvBindsVar
    -- See Note [Failing equalities with no evidence bindings]
    maybeSwitchOffDefer :: EvBindsVar -> SolverReportErrCtxt -> SolverReportErrCtxt
    maybeSwitchOffDefer EvBindsVar
    evb SolverReportErrCtxt
    ctxt
     | CoEvBindsVar{} <- EvBindsVar
    evb
     = SolverReportErrCtxt
    ctxt { cec_defer_type_errors  = ErrorWithoutFlag
            , cec_expr_holes         = ErrorWithoutFlag
            , cec_out_of_scope_holes = ErrorWithoutFlag }
     | Bool
    otherwise
     = SolverReportErrCtxt
    ctxt

    {- Note [Failing equalities with no evidence bindings]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If we go inside an implication that has no term evidence
    (e.g. unifying under a forall), we can't defer type errors.  You could
    imagine using the /enclosing/ bindings (in cec_binds), but that may
    not have enough stuff in scope for the bindings to be well typed.  So
    we just switch off deferred type errors altogether.  See #14605.

    This is done by maybeSwitchOffDefer.  It's also useful in one other
    place: see Note [Wrapping failing kind equalities] in GHC.Tc.Solver.

    Note [Suppressing error messages]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The cec_suppress flag says "don't report any errors".  Instead, just create
    evidence bindings (as usual).  It's used when more important errors have occurred.

    Specifically (see reportWanteds)
      * If there are insoluble Givens, then we are in unreachable code and all bets
        are off.  So don't report any further errors.
      * If there are any insolubles (eg Int~Bool), here or in a nested implication,
        then suppress errors from the simple constraints here.  Sometimes the
        simple-constraint errors are a knock-on effect of the insolubles.

    This suppression behaviour is controlled by the Bool flag in
    ReportErrorSpec, as used in reportWanteds.

    But we need to take care: flags can turn errors into warnings, and we
    don't want those warnings to suppress subsequent errors (including
    suppressing the essential addTcEvBind for them: #15152). So in
    tryReporter we use askNoErrs to see if any error messages were
    /actually/ produced; if not, we don't switch on suppression.

    A consequence is that warnings never suppress warnings, so turning an
    error into a warning may allow subsequent warnings to appear that were
    previously suppressed.   (e.g. partial-sigs/should_fail/T14584)
    -}

    reportImplic :: SolverReportErrCtxt -> Implication -> TcM ()
    reportImplic :: SolverReportErrCtxt -> Implication -> TcM ()
    reportImplic SolverReportErrCtxt
    ctxt implic :: Implication
    implic@(Implic { ic_skols :: Implication -> [TcId]
    ic_skols  = [TcId]
    tvs
                                     , ic_given :: Implication -> [TcId]
    ic_given  = [TcId]
    given
                                     , ic_wanted :: Implication -> WantedConstraints
    ic_wanted = WantedConstraints
    wanted, ic_binds :: Implication -> EvBindsVar
    ic_binds = EvBindsVar
    evb
                                     , ic_status :: Implication -> ImplicStatus
    ic_status = ImplicStatus
    status, ic_info :: Implication -> SkolemInfoAnon
    ic_info = SkolemInfoAnon
    info
                                     , ic_env :: Implication -> CtLocEnv
    ic_env    = CtLocEnv
    ct_loc_env
                                     , ic_tclvl :: Implication -> TcLevel
    ic_tclvl  = TcLevel
    tc_lvl })
      | SkolemInfoAnon
    BracketSkol <- SkolemInfoAnon
    info
      , Bool -> Bool
    not Bool
    insoluble
      = () -> TcM ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()        -- For Template Haskell brackets report only
                         -- definite errors. The whole thing will be re-checked
                         -- later when we plug it in, and meanwhile there may
                         -- certainly be un-satisfied constraints

      | Bool
    otherwise
      = do { String -> SDoc -> TcM ()
    traceTc String
    "reportImplic" (SDoc -> TcM ()) -> SDoc -> TcM ()
    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
    "tidy env:"   SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> TidyEnv -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt)
               , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "skols:     " SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [TcId] -> SDoc
    pprTyVars [TcId]
    tvs
               , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "tidy skols:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [TcId] -> SDoc
    pprTyVars [TcId]
    tvs' ]

           ; Bool -> TcM () -> TcM ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    bad_telescope (TcM () -> TcM ()) -> TcM () -> TcM ()
    forall a b. (a -> b) -> a -> b
    $ SolverReportErrCtxt
    -> CtLocEnv -> SkolemInfoAnon -> [TcId] -> TcM ()
    reportBadTelescope SolverReportErrCtxt
    ctxt CtLocEnv
    ct_loc_env SkolemInfoAnon
    info [TcId]
    tvs
                   -- Do /not/ use the tidied tvs because then are in the
                   -- wrong order, so tidying will rename things wrongly
           ; SolverReportErrCtxt -> TcLevel -> WantedConstraints -> TcM ()
    reportWanteds SolverReportErrCtxt
    ctxt' TcLevel
    tc_lvl WantedConstraints
    wanted

           -- Report redundant (unused) constraints
           ; SolverReportErrCtxt
    -> CtLocEnv -> SkolemInfoAnon -> [TcId] -> TcM ()
    warnRedundantConstraints SolverReportErrCtxt
    ctxt' CtLocEnv
    ct_loc_env SkolemInfoAnon
    info' [TcId]
    dead_givens }
      where
        insoluble :: Bool
    insoluble    = ImplicStatus -> Bool
    isInsolubleStatus ImplicStatus
    status
        (TidyEnv
    env1, [TcId]
    tvs') = TidyEnv -> [TcId] -> (TidyEnv, [TcId])
    tidyVarBndrs (SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt) ([TcId] -> (TidyEnv, [TcId])) -> [TcId] -> (TidyEnv, [TcId])
    forall a b. (a -> b) -> a -> b
    $
                       [TcId] -> [TcId]
    scopedSort [TcId]
    tvs
            -- scopedSort: the ic_skols may not be in dependency order
            -- (see Note [Skolems in an implication] in GHC.Tc.Types.Constraint)
            -- but tidying goes wrong on out-of-order constraints;
            -- so we sort them here before tidying
        info' :: SkolemInfoAnon
    info'   = TidyEnv -> SkolemInfoAnon -> SkolemInfoAnon
    tidySkolemInfoAnon TidyEnv
    env1 SkolemInfoAnon
    info
        implic' :: Implication
    implic' = Implication
    implic { ic_skols = tvs'
                         , ic_given = map (tidyEvVar env1) given
                         , ic_info  = info' }

        ctxt1 :: SolverReportErrCtxt
    ctxt1 = EvBindsVar -> SolverReportErrCtxt -> SolverReportErrCtxt
    maybeSwitchOffDefer EvBindsVar
    evb SolverReportErrCtxt
    ctxt
        ctxt' :: SolverReportErrCtxt
    ctxt' = SolverReportErrCtxt
    ctxt1 { cec_tidy     = env1
                      , cec_encl     = implic' : cec_encl ctxt

                      , cec_suppress = insoluble || cec_suppress ctxt
                            -- Suppress inessential errors if there
                            -- are insolubles anywhere in the
                            -- tree rooted here, or we've come across
                            -- a suppress-worthy constraint higher up (#11541)

                      , cec_binds    = evb }

        dead_givens :: [TcId]
    dead_givens = case ImplicStatus
    status of
                        IC_Solved { ics_dead :: ImplicStatus -> [TcId]
    ics_dead = [TcId]
    dead } -> [TcId]
    dead
                        ImplicStatus
    _                             -> []

        bad_telescope :: Bool
    bad_telescope = case ImplicStatus
    status of
                  ImplicStatus
    IC_BadTelescope -> Bool
    True
                  ImplicStatus
    _               -> Bool
    False

    warnRedundantConstraints :: SolverReportErrCtxt -> CtLocEnv -> SkolemInfoAnon -> [EvVar] -> TcM ()
    -- See Note [Tracking redundant constraints] in GHC.Tc.Solver
    warnRedundantConstraints :: SolverReportErrCtxt
    -> CtLocEnv -> SkolemInfoAnon -> [TcId] -> TcM ()
    warnRedundantConstraints SolverReportErrCtxt
    ctxt CtLocEnv
    env SkolemInfoAnon
    info [TcId]
    redundant_evs
     | Bool -> Bool
    not (SolverReportErrCtxt -> Bool
    cec_warn_redundant SolverReportErrCtxt
    ctxt)
     = () -> TcM ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

     | [TcId] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TcId]
    redundant_evs
     = () -> TcM ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

     -- Do not report redundant constraints for quantified constraints
     -- See (RC4) in Note [Tracking redundant constraints]
     -- Fortunately it is easy to spot implications constraints that arise
     -- from quantified constraints, from their SkolInfo
     | InstSkol (IsQC {}) PatersonSize
    _ <- SkolemInfoAnon
    info
     = () -> TcM ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

     | SigSkol UserTypeCtxt
    user_ctxt Type
    _ [(Name, TcId)]
    _ <- SkolemInfoAnon
    info
     -- When dealing with a user-written type signature,
     -- we want to add "In the type signature for f".
     = Bool -> CtLocEnv -> TcM ()
    report_redundant_msg Bool
    True (CtLocEnv -> SrcSpan -> CtLocEnv
    setCtLocEnvLoc CtLocEnv
    env (UserTypeCtxt -> SrcSpan
    redundantConstraintsSpan UserTypeCtxt
    user_ctxt))
                                 --  ^^^^ add "In the type signature..."

     | Bool
    otherwise
     -- But for InstSkol there already *is* a surrounding
     -- "In the instance declaration for Eq [a]" context
     -- and we don't want to say it twice. Seems a bit ad-hoc
     = Bool -> CtLocEnv -> TcM ()
    report_redundant_msg Bool
    False CtLocEnv
    env
                       --   ^^^^^ don't add "In the type signature..."
     where
       report_redundant_msg :: Bool -- whether to add "In the type signature..." to the diagnostic
                            -> CtLocEnv
                            -> TcRn ()
       report_redundant_msg :: Bool -> CtLocEnv -> TcM ()
    report_redundant_msg Bool
    show_info CtLocEnv
    lcl_env
         = do { msg <-
                  CtLocEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport
                    CtLocEnv
    lcl_env
                    ([TcId] -> (SkolemInfoAnon, Bool) -> TcRnMessage
    TcRnRedundantConstraints [TcId]
    redundant_evs (SkolemInfoAnon
    info, Bool
    show_info))
                    (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt)
                    []
              ; reportDiagnostic msg }

    reportBadTelescope :: SolverReportErrCtxt -> CtLocEnv -> SkolemInfoAnon -> [TcTyVar] -> TcM ()
    reportBadTelescope :: SolverReportErrCtxt
    -> CtLocEnv -> SkolemInfoAnon -> [TcId] -> TcM ()
    reportBadTelescope SolverReportErrCtxt
    ctxt CtLocEnv
    env (ForAllSkol TyVarBndrs
    telescope) [TcId]
    skols
      = do { msg <- CtLocEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport
                      CtLocEnv
    env
                      (SolverReportWithCtxt -> DiagnosticReason -> TcRnMessage
    TcRnSolverReport SolverReportWithCtxt
    report DiagnosticReason
    ErrorWithoutFlag)
                      (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt)
                      []
           ; reportDiagnostic msg }
      where
        report :: SolverReportWithCtxt
    report = SolverReportErrCtxt -> TcSolverReportMsg -> SolverReportWithCtxt
    SolverReportWithCtxt SolverReportErrCtxt
    ctxt (TcSolverReportMsg -> SolverReportWithCtxt)
    -> TcSolverReportMsg -> SolverReportWithCtxt
    forall a b. (a -> b) -> a -> b
    $ TyVarBndrs -> [TcId] -> TcSolverReportMsg
    BadTelescope TyVarBndrs
    telescope [TcId]
    skols

    reportBadTelescope SolverReportErrCtxt
    _ CtLocEnv
    _ SkolemInfoAnon
    skol_info [TcId]
    skols
      = String -> SDoc -> TcM ()
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "reportBadTelescope" (SkolemInfoAnon -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr SkolemInfoAnon
    skol_info SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ [TcId] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [TcId]
    skols)

    -- | Should we completely ignore this constraint in error reporting?
    -- It *must* be the case that any constraint for which this returns True
    -- somehow causes an error to be reported elsewhere.
    -- See Note [Constraints to ignore].
    ignoreConstraint :: Ct -> Bool
    ignoreConstraint :: Ct -> Bool
    ignoreConstraint Ct
    ct
      | CtOrigin
    AssocFamPatOrigin <- Ct -> CtOrigin
    ctOrigin Ct
    ct
      = Bool
    True
      | Bool
    otherwise
      = Bool
    False

    -- | Makes an error item from a constraint, calculating whether or not
    -- the item should be suppressed. See Note [Wanteds rewrite Wanteds]
    -- in GHC.Tc.Types.Constraint. Returns Nothing if we should just ignore
    -- a constraint. See Note [Constraints to ignore].
    mkErrorItem :: Ct -> TcM (Maybe ErrorItem)
    mkErrorItem :: Ct -> TcM (Maybe ErrorItem)
    mkErrorItem Ct
    ct
      | Ct -> Bool
    ignoreConstraint Ct
    ct
      = do { String -> SDoc -> TcM ()
    traceTc String
    "Ignoring constraint:" (Ct -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Ct
    ct)
           ; Maybe ErrorItem -> TcM (Maybe ErrorItem)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe ErrorItem
    forall a. Maybe a
    Nothing }   -- See Note [Constraints to ignore]

      | Bool
    otherwise
      = do { let loc :: CtLoc
    loc = Ct -> CtLoc
    ctLoc Ct
    ct
                 flav :: CtFlavour
    flav = Ct -> CtFlavour
    ctFlavour Ct
    ct

           ; (suppress, m_evdest) <- case Ct -> CtEvidence
    ctEvidence Ct
    ct of
             -- For this `suppress` stuff
             -- see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint
               CtGiven {} -> (Bool, Maybe TcEvDest)
    -> IOEnv (Env TcGblEnv TcLclEnv) (Bool, Maybe TcEvDest)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool
    False, Maybe TcEvDest
    forall a. Maybe a
    Nothing)
               CtWanted { ctev_rewriters :: CtEvidence -> RewriterSet
    ctev_rewriters = RewriterSet
    rewriters, ctev_dest :: CtEvidence -> TcEvDest
    ctev_dest = TcEvDest
    dest }
                 -> do { rewriters' <- RewriterSet -> TcM RewriterSet
    zonkRewriterSet RewriterSet
    rewriters
                       ; return (not (isEmptyRewriterSet rewriters'), Just dest) }

           ; let m_reason = case Ct
    ct of
                    CIrredCan (IrredCt { ir_reason :: IrredCt -> CtIrredReason
    ir_reason = CtIrredReason
    reason }) -> CtIrredReason -> Maybe CtIrredReason
    forall a. a -> Maybe a
    Just CtIrredReason
    reason
                    Ct
    _                                          -> Maybe CtIrredReason
    forall a. Maybe a
    Nothing

           ; return $ Just $ EI { ei_pred     = ctPred ct
                                , ei_evdest   = m_evdest
                                , ei_flavour  = flav
                                , ei_loc      = loc
                                , ei_m_reason = m_reason
                                , ei_suppress = suppress }}

    -- | Actually report this 'ErrorItem'.
    unsuppressErrorItem :: ErrorItem -> ErrorItem
    unsuppressErrorItem :: ErrorItem -> ErrorItem
    unsuppressErrorItem ErrorItem
    ei = ErrorItem
    ei { ei_suppress = False }

    ----------------------------------------------------------------
    reportWanteds :: SolverReportErrCtxt -> TcLevel -> WantedConstraints -> TcM ()
    reportWanteds :: SolverReportErrCtxt -> TcLevel -> WantedConstraints -> TcM ()
    reportWanteds SolverReportErrCtxt
    ctxt TcLevel
    tc_lvl wc :: WantedConstraints
    wc@(WC { wc_simple :: WantedConstraints -> Cts
    wc_simple = Cts
    simples, wc_impl :: WantedConstraints -> Bag Implication
    wc_impl = Bag Implication
    implics
                                     , wc_errors :: WantedConstraints -> Bag DelayedError
    wc_errors = Bag DelayedError
    errs })
      | WantedConstraints -> Bool
    isEmptyWC WantedConstraints
    wc = String -> SDoc -> TcM ()
    traceTc String
    "reportWanteds empty WC" SDoc
    forall doc. IsOutput doc => doc
    empty
      | Bool
    otherwise
      = do { tidy_items1 <- (Ct -> TcM (Maybe ErrorItem))
    -> [Ct] -> IOEnv (Env TcGblEnv TcLclEnv) [ErrorItem]
    forall (m :: * -> *) a b.
    Applicative m =>
    (a -> m (Maybe b)) -> [a] -> m [b]
    mapMaybeM Ct -> TcM (Maybe ErrorItem)
    mkErrorItem [Ct]
    tidy_cts
           ; traceTc "reportWanteds 1" (vcat [ text "Simples =" <+> ppr simples
                                             , text "Suppress =" <+> ppr (cec_suppress ctxt)
                                             , text "tidy_cts   =" <+> ppr tidy_cts
                                             , text "tidy_items1 =" <+> ppr tidy_items1
                                             , text "tidy_errs =" <+> ppr tidy_errs ])

             -- Catch an awkward (and probably rare) case in which /all/ errors are
             -- suppressed: see Wrinkle (WRW2) in Note [Prioritise Wanteds with empty
             -- RewriterSet] in GHC.Tc.Types.Constraint.
             --
             -- Unless we are sure that an error will be reported some other way
             -- (details in the defn of tidy_items) un-suppress the lot. This makes
             -- sure we don't forget to report an error at all, which is
             -- catastrophic: GHC proceeds to desguar and optimise the program, even
             -- though it is full of type errors (#22702, #22793)
           ; errs_already <- ifErrsM (return True) (return False)
           ; let tidy_items
                   | Bool -> Bool
    not Bool
    errs_already                     -- Have not already reported an error (perhaps
                                                          --   from an outer implication); see #21405
                   , Bool -> Bool
    not ((Ct -> Bool) -> Cts -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any Ct -> Bool
    ignoreConstraint Cts
    simples)   -- No error is ignorable (is reported elsewhere)
                   , (ErrorItem -> Bool) -> [ErrorItem] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all ErrorItem -> Bool
    ei_suppress [ErrorItem]
    tidy_items1          -- All errors are suppressed
                   = (ErrorItem -> ErrorItem) -> [ErrorItem] -> [ErrorItem]
    forall a b. (a -> b) -> [a] -> [b]
    map ErrorItem -> ErrorItem
    unsuppressErrorItem [ErrorItem]
    tidy_items1
                   | Bool
    otherwise
                   = [ErrorItem]
    tidy_items1

             -- First, deal with any out-of-scope errors:
           ; let (out_of_scope, other_holes, not_conc_errs) = partition_errors tidy_errs
                   -- don't suppress out-of-scope errors
                 ctxt_for_scope_errs = SolverReportErrCtxt
    ctxt { cec_suppress = False }
           ; (_, no_out_of_scope) <- askNoErrs $
                                     reportHoles tidy_items ctxt_for_scope_errs out_of_scope

             -- Next, deal with things that are utterly wrong
             -- Like Int ~ Bool (incl nullary TyCons)
             -- or  Int ~ t a   (AppTy on one side)
             -- These /ones/ are not suppressed by the incoming context
             -- (but will be by out-of-scope errors)
           ; let ctxt_for_insols = SolverReportErrCtxt
    ctxt { cec_suppress = not no_out_of_scope }
           ; reportHoles tidy_items ctxt_for_insols other_holes
              -- holes never suppress

           ; reportNotConcreteErrs ctxt_for_insols not_conc_errs

              -- See Note [Suppressing confusing errors]
           ; let (suppressed_items, items0) = partition suppress tidy_items
           ; traceTc "reportWanteds suppressed:" (ppr suppressed_items)
           ; (ctxt1, items1) <- tryReporters ctxt_for_insols report1 items0

             -- Now all the other constraints.  We suppress errors here if
             -- any of the first batch failed, or if the enclosing context
             -- says to suppress
           ; let ctxt2 = SolverReportErrCtxt
    ctxt1 { cec_suppress = cec_suppress ctxt || cec_suppress ctxt1 }
           ; (ctxt3, leftovers) <- tryReporters ctxt2 report2 items1
           ; massertPpr (null leftovers)
               (text "The following unsolved Wanted constraints \
                     \have not been reported to the user:"
               $$ ppr leftovers)

           ; mapBagM_ (reportImplic ctxt2) implics
                -- NB ctxt2: don't suppress inner insolubles if there's only a
                -- wanted insoluble here; but do suppress inner insolubles
                -- if there's a *given* insoluble here (= inaccessible code)

                -- Only now, if there are no errors, do we report suppressed ones
                -- See Note [Suppressing confusing errors]
                -- We don't need to update the context further because of the
                -- whenNoErrs guard
           ; whenNoErrs $
             do { (_, more_leftovers) <- tryReporters ctxt3 report3 suppressed_items
                ; massertPpr (null more_leftovers) (ppr more_leftovers) } }
     where
        env :: TidyEnv
    env       = SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt
        tidy_cts :: [Ct]
    tidy_cts  = Cts -> [Ct]
    forall a. Bag a -> [a]
    bagToList ((Ct -> Ct) -> Cts -> Cts
    forall a b. (a -> b) -> Bag a -> Bag b
    mapBag (TidyEnv -> Ct -> Ct
    tidyCt TidyEnv
    env)   Cts
    simples)
        tidy_errs :: [DelayedError]
    tidy_errs = Bag DelayedError -> [DelayedError]
    forall a. Bag a -> [a]
    bagToList ((DelayedError -> DelayedError)
    -> Bag DelayedError -> Bag DelayedError
    forall a b. (a -> b) -> Bag a -> Bag b
    mapBag (TidyEnv -> DelayedError -> DelayedError
    tidyDelayedError TidyEnv
    env) Bag DelayedError
    errs)

        partition_errors :: [DelayedError] -> ([Hole], [Hole], [NotConcreteError])
        partition_errors :: [DelayedError] -> ([Hole], [Hole], [NotConcreteError])
    partition_errors = [Hole]
    -> [Hole]
    -> [NotConcreteError]
    -> [DelayedError]
    -> ([Hole], [Hole], [NotConcreteError])
    go [] [] []
          where
            go :: [Hole]
    -> [Hole]
    -> [NotConcreteError]
    -> [DelayedError]
    -> ([Hole], [Hole], [NotConcreteError])
    go [Hole]
    out_of_scope [Hole]
    other_holes [NotConcreteError]
    syn_eqs []
              = ([Hole]
    out_of_scope, [Hole]
    other_holes, [NotConcreteError]
    syn_eqs)
            go [Hole]
    es1 [Hole]
    es2 [NotConcreteError]
    es3 (DelayedError
    err:[DelayedError]
    errs)
              | ([Hole]
    es1, [Hole]
    es2, [NotConcreteError]
    es3) <- [Hole]
    -> [Hole]
    -> [NotConcreteError]
    -> [DelayedError]
    -> ([Hole], [Hole], [NotConcreteError])
    go [Hole]
    es1 [Hole]
    es2 [NotConcreteError]
    es3 [DelayedError]
    errs
              = case DelayedError
    err of
                  DE_Hole Hole
    hole
                    | Hole -> Bool
    isOutOfScopeHole Hole
    hole
                    -> (Hole
    hole Hole -> [Hole] -> [Hole]
    forall a. a -> [a] -> [a]
    : [Hole]
    es1, [Hole]
    es2, [NotConcreteError]
    es3)
                    | Bool
    otherwise
                    -> ([Hole]
    es1, Hole
    hole Hole -> [Hole] -> [Hole]
    forall a. a -> [a] -> [a]
    : [Hole]
    es2, [NotConcreteError]
    es3)
                  DE_NotConcrete NotConcreteError
    err
                    -> ([Hole]
    es1, [Hole]
    es2, NotConcreteError
    err NotConcreteError -> [NotConcreteError] -> [NotConcreteError]
    forall a. a -> [a] -> [a]
    : [NotConcreteError]
    es3)

          -- See Note [Suppressing confusing errors]
        suppress :: ErrorItem -> Bool
        suppress :: ErrorItem -> Bool
    suppress ErrorItem
    item
          | CtFlavour
    Wanted <- ErrorItem -> CtFlavour
    ei_flavour ErrorItem
    item
          = ErrorItem -> Bool
    is_ww_fundep_item ErrorItem
    item
          | Bool
    otherwise
          = Bool
    False

        -- report1: ones that should *not* be suppressed by
        --          an insoluble somewhere else in the tree
        -- It's crucial that anything that is considered insoluble
        -- (see GHC.Tc.Utils.insolublWantedCt) is caught here, otherwise
        -- we might suppress its error message, and proceed on past
        -- type checking to get a Lint error later
        report1 :: [ReporterSpec]
    report1 = [ (String
    "custom_error", ErrorItem -> Pred -> Bool
    forall {p}. ErrorItem -> p -> Bool
    is_user_type_error, Bool
    True,  Reporter
    mkUserTypeErrorReporter)
                     -- (Handles TypeError and Unsatisfiable)

                  , ReporterSpec
    given_eq_spec
                  , (String
    "insoluble2",      ErrorItem -> Pred -> Bool
    forall {p}. p -> Pred -> Bool
    utterly_wrong,  Bool
    True, (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkEqErr)
                  , (String
    "skolem eq1",      ErrorItem -> Pred -> Bool
    very_wrong,     Bool
    True, Reporter
    mkSkolReporter)
                  , (String
    "FixedRuntimeRep", ErrorItem -> Pred -> Bool
    is_FRR,         Bool
    True, (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    mkGroupReporter HasDebugCallStack =>
    SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkFRRErr)
                  , (String
    "skolem eq2",      ErrorItem -> Pred -> Bool
    skolem_eq,      Bool
    True, Reporter
    mkSkolReporter)
                  , (String
    "non-tv eq",       ErrorItem -> Pred -> Bool
    forall {p}. p -> Pred -> Bool
    non_tv_eq,      Bool
    True, Reporter
    mkSkolReporter)

                      -- The only remaining equalities are alpha ~ ty,
                      -- where alpha is untouchable; and representational equalities
                      -- Prefer homogeneous equalities over hetero, because the
                      -- former might be holding up the latter.
                      -- See Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality
                  , (String
    "Homo eqs",      ErrorItem -> Pred -> Bool
    forall {p}. p -> Pred -> Bool
    is_homo_equality,  Bool
    True,  (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkEqErr)
                  , (String
    "Other eqs",     ErrorItem -> Pred -> Bool
    is_equality,       Bool
    True,  (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkEqErr)
                  ]

        -- report2: we suppress these if there are insolubles elsewhere in the tree
        report2 :: [ReporterSpec]
    report2 = [ (String
    "Implicit params", ErrorItem -> Pred -> Bool
    is_ip,           Bool
    False, (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkIPErr)
                  , (String
    "Irreds",          ErrorItem -> Pred -> Bool
    is_irred,        Bool
    False, (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkIrredErr)
                  , (String
    "Dicts",           ErrorItem -> Pred -> Bool
    is_dict,         Bool
    False, (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    mkGroupReporter HasDebugCallStack =>
    SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkDictErr) ]

        -- report3: suppressed errors should be reported as categorized by either report1
        -- or report2. Keep this in sync with the suppress function above
        report3 :: [(String, ErrorItem -> p -> Bool, Bool, Reporter)]
    report3 = [ (String
    "wanted/wanted fundeps", ErrorItem -> p -> Bool
    forall {p}. ErrorItem -> p -> Bool
    is_ww_fundep, Bool
    True, (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkEqErr)
                  ]

        -- rigid_nom_eq, rigid_nom_tv_eq,
        is_dict, is_equality, is_ip, is_FRR, is_irred :: ErrorItem -> Pred -> Bool

        is_given_eq :: ErrorItem -> Pred -> Bool
    is_given_eq ErrorItem
    item Pred
    pred
           | CtFlavour
    Given <- ErrorItem -> CtFlavour
    ei_flavour ErrorItem
    item
           , EqPred {} <- Pred
    pred = Bool
    True
           | Bool
    otherwise         = Bool
    False
           -- I think all given residuals are equalities

        -- Things like (Int ~N Bool)
        utterly_wrong :: p -> Pred -> Bool
    utterly_wrong p
    _ (EqPred EqRel
    NomEq Type
    ty1 Type
    ty2) = Type -> Bool
    isRigidTy Type
    ty1 Bool -> Bool -> Bool
    && Type -> Bool
    isRigidTy Type
    ty2
        utterly_wrong p
    _ Pred
    _                      = Bool
    False

        -- Things like (a ~N Int)
        very_wrong :: ErrorItem -> Pred -> Bool
    very_wrong ErrorItem
    _ (EqPred EqRel
    NomEq Type
    ty1 Type
    ty2) = TcLevel -> Type -> Bool
    isSkolemTy TcLevel
    tc_lvl Type
    ty1 Bool -> Bool -> Bool
    && Type -> Bool
    isRigidTy Type
    ty2
        very_wrong ErrorItem
    _ Pred
    _                      = Bool
    False

        -- Representation-polymorphism errors, to be reported using mkFRRErr.
        is_FRR :: ErrorItem -> Pred -> Bool
    is_FRR ErrorItem
    item Pred
    _ = Maybe FixedRuntimeRepErrorInfo -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe FixedRuntimeRepErrorInfo -> Bool)
    -> Maybe FixedRuntimeRepErrorInfo -> Bool
    forall a b. (a -> b) -> a -> b
    $ HasDebugCallStack => ErrorItem -> Maybe FixedRuntimeRepErrorInfo
    ErrorItem -> Maybe FixedRuntimeRepErrorInfo
    fixedRuntimeRepOrigin_maybe ErrorItem
    item

        -- Things like (a ~N b) or (a  ~N  F Bool)
        skolem_eq :: ErrorItem -> Pred -> Bool
    skolem_eq ErrorItem
    _ (EqPred EqRel
    NomEq Type
    ty1 Type
    _) = TcLevel -> Type -> Bool
    isSkolemTy TcLevel
    tc_lvl Type
    ty1
        skolem_eq ErrorItem
    _ Pred
    _                    = Bool
    False

        -- Things like (F a  ~N  Int)
        non_tv_eq :: p -> Pred -> Bool
    non_tv_eq p
    _ (EqPred EqRel
    NomEq Type
    ty1 Type
    _) = Bool -> Bool
    not (Type -> Bool
    isTyVarTy Type
    ty1)
        non_tv_eq p
    _ Pred
    _                    = Bool
    False

        -- Catch TypeError and Unsatisfiable.
        -- Here, we want any nested TypeErrors to bubble up, so we use
        -- 'containsUserTypeError' and not 'isTopLevelUserTypeError'.
        --
        -- See also Note [Implementation of Unsatisfiable constraints], point (F).
        is_user_type_error :: ErrorItem -> p -> Bool
    is_user_type_error ErrorItem
    item p
    _ = Type -> Bool
    containsUserTypeError (ErrorItem -> Type
    errorItemPred ErrorItem
    item)

        is_homo_equality :: p -> Pred -> Bool
    is_homo_equality p
    _ (EqPred EqRel
    _ Type
    ty1 Type
    ty2)
          = HasDebugCallStack => Type -> Type
    Type -> Type
    typeKind Type
    ty1 HasDebugCallStack => Type -> Type -> Bool
    Type -> Type -> Bool
    `tcEqType` HasDebugCallStack => Type -> Type
    Type -> Type
    typeKind Type
    ty2
        is_homo_equality p
    _ Pred
    _
          = Bool
    False

        is_equality :: ErrorItem -> Pred -> Bool
    is_equality ErrorItem
    _(EqPred {}) = Bool
    True
        is_equality ErrorItem
    _ Pred
    _          = Bool
    False

        is_dict :: ErrorItem -> Pred -> Bool
    is_dict ErrorItem
    _ (ClassPred {}) = Bool
    True
        is_dict ErrorItem
    _ Pred
    _              = Bool
    False

        is_ip :: ErrorItem -> Pred -> Bool
    is_ip ErrorItem
    _ (ClassPred Class
    cls [Type]
    _) = Class -> Bool
    isIPClass Class
    cls
        is_ip ErrorItem
    _ Pred
    _                 = Bool
    False

        is_irred :: ErrorItem -> Pred -> Bool
    is_irred ErrorItem
    _ (IrredPred {}) = Bool
    True
        is_irred ErrorItem
    _ Pred
    _              = Bool
    False

         -- See situation (1) of Note [Suppressing confusing errors]
        is_ww_fundep :: ErrorItem -> p -> Bool
    is_ww_fundep ErrorItem
    item p
    _ = ErrorItem -> Bool
    is_ww_fundep_item ErrorItem
    item
        is_ww_fundep_item :: ErrorItem -> Bool
    is_ww_fundep_item = CtOrigin -> Bool
    isWantedWantedFunDepOrigin (CtOrigin -> Bool) -> (ErrorItem -> CtOrigin) -> ErrorItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorItem -> CtOrigin
    errorItemOrigin

        given_eq_spec :: ReporterSpec
    given_eq_spec  -- See Note [Given errors]
          | Bool
    has_gadt_match_here
          = (String
    "insoluble1a", ErrorItem -> Pred -> Bool
    is_given_eq, Bool
    True,  Reporter
    mkGivenErrorReporter)
          | Bool
    otherwise
          = (String
    "insoluble1b", ErrorItem -> Pred -> Bool
    is_given_eq, Bool
    False, Reporter
    ignoreErrorReporter)
              -- False means don't suppress subsequent errors
              -- Reason: we don't report all given errors
              --         (see mkGivenErrorReporter), and we should only suppress
              --         subsequent errors if we actually report this one!
              --         #13446 is an example

        -- See Note [Given errors]
        has_gadt_match_here :: Bool
    has_gadt_match_here = [Implication] -> Bool
    has_gadt_match (SolverReportErrCtxt -> [Implication]
    cec_encl SolverReportErrCtxt
    ctxt)
        has_gadt_match :: [Implication] -> Bool
    has_gadt_match [] = Bool
    False
        has_gadt_match (Implication
    implic : [Implication]
    implics)
          | PatSkol {} <- Implication -> SkolemInfoAnon
    ic_info Implication
    implic
          , Implication -> HasGivenEqs
    ic_given_eqs Implication
    implic HasGivenEqs -> HasGivenEqs -> Bool
    forall a. Eq a => a -> a -> Bool
    /= HasGivenEqs
    NoGivenEqs
          , Implication -> Bool
    ic_warn_inaccessible Implication
    implic
              -- Don't bother doing this if -Winaccessible-code isn't enabled.
              -- See Note [Avoid -Winaccessible-code when deriving] in GHC.Tc.TyCl.Instance.
          = Bool
    True
          | Bool
    otherwise
          = [Implication] -> Bool
    has_gadt_match [Implication]
    implics

    ---------------
    isSkolemTy :: TcLevel -> Type -> Bool
    -- The type is a skolem tyvar
    isSkolemTy :: TcLevel -> Type -> Bool
    isSkolemTy TcLevel
    tc_lvl Type
    ty
      | Just TcId
    tv <- Type -> Maybe TcId
    getTyVar_maybe Type
    ty
      =  TcId -> Bool
    isSkolemTyVar TcId
    tv
      Bool -> Bool -> Bool
    || (TcId -> Bool
    isTyVarTyVar TcId
    tv Bool -> Bool -> Bool
    && TcLevel -> TcId -> Bool
    isTouchableMetaTyVar TcLevel
    tc_lvl TcId
    tv)
         -- The last case is for touchable TyVarTvs
         -- we postpone untouchables to a latter test (too obscure)

      | Bool
    otherwise
      = Bool
    False

    isTyFun_maybe :: Type -> Maybe TyCon
    isTyFun_maybe :: Type -> Maybe TyCon
    isTyFun_maybe Type
    ty = case HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe Type
    ty of
                          Just (TyCon
    tc,[Type]
    _) | TyCon -> Bool
    isTypeFamilyTyCon TyCon
    tc -> TyCon -> Maybe TyCon
    forall a. a -> Maybe a
    Just TyCon
    tc
                          Maybe (TyCon, [Type])
    _ -> Maybe TyCon
    forall a. Maybe a
    Nothing

    {- Note [Suppressing confusing errors]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Certain errors we might encounter are potentially confusing to users.
    If there are any other errors to report, at all, we want to suppress these.

    Which errors (only 1 case right now):

    1) Errors which arise from the interaction of two Wanted fun-dep constraints.
       Example:

         class C a b | a -> b where
           op :: a -> b -> b

         foo _ = op True Nothing

         bar _ = op False []

       Here, we could infer
         foo :: C Bool (Maybe a) => p -> Maybe a
         bar :: C Bool [a]       => p -> [a]

       (The unused arguments suppress the monomorphism restriction.) The problem
       is that these types can't both be correct, as they violate the functional
       dependency. Yet reporting an error here is awkward: we must
       non-deterministically choose either foo or bar to reject. We thus want
       to report this problem only when there is nothing else to report.
       See typecheck/should_fail/T13506 for an example of when to suppress
       the error. The case above is actually accepted, because foo and bar
       are checked separately, and thus the two fundep constraints never
       encounter each other. It is test case typecheck/should_compile/FunDepOrigin1.

       This case applies only when both fundeps are *Wanted* fundeps; when
       both are givens, the error represents unreachable code. For
       a Given/Wanted case, see #9612.

    Mechanism:

    We use the `suppress` function within reportWanteds to filter out these two
    cases, then report all other errors. Lastly, we return to these suppressed
    ones and report them only if there have been no errors so far.

    Note [Constraints to ignore]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Some constraints are meant only to aid the solver by unification; a failure
    to solve them is not necessarily an error to report to the user. It is critical
    that compilation is aborted elsewhere if there are any ignored constraints here;
    they will remain unfilled, and might have been used to rewrite another constraint.

    Currently, the constraints to ignore are:

    1) Constraints generated in order to unify associated type instance parameters
       with class parameters. Here are two illustrative examples:

         class C (a :: k) where
           type F (b :: k)

         instance C True where
           type F a = Int

         instance C Left where
           type F (Left :: a -> Either a b) = Bool

       In the first instance, we want to infer that `a` has type Bool. So we emit
       a constraint unifying kappa (the guessed type of `a`) with Bool. All is well.

       In the second instance, we process the associated type instance only
       after fixing the quantified type variables of the class instance. We thus
       have skolems a1 and b1 such that the class instance is for (Left :: a1 -> Either a1 b1).
       Unifying a1 and b1 with a and b in the type instance will fail, but harmlessly so.
       checkConsistentFamInst checks for this, and will fail if anything has gone
       awry. Really the equality constraints emitted are just meant as an aid, not
       a requirement. This is test case T13972.

       We detect this case by looking for an origin of AssocFamPatOrigin; constraints
       with this origin are dropped entirely during error message reporting.

       If there is any trouble, checkValidFamInst bleats, aborting compilation.

    Note [Implementation of Unsatisfiable constraints]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The Unsatisfiable constraint was introduced in GHC proposal #433 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0433-unsatisfiable.rst).
    See Note [The Unsatisfiable constraint] in GHC.TypeError.

    Its implementation consists of the following:

      A. The definitions.

         The Unsatisfiable class is defined in GHC.TypeError, in base.
         It consists of the following definitions:

           type Unsatisfiable :: ErrorMessage -> Constraint
           class Unsatisfiable msg where
             unsatisfiableLifted :: a

           unsatisfiable :: forall {rep} (msg :: ErrorMessage) (a :: TYPE rep). Unsatisfiable msg => a
           unsatisfiable = unsatisfiableLifted @msg @((##) -> a) (##)

         The class TyCon as well as the unsatisfiable Id have known-key Names
         in GHC; they are not wired-in.

      B. Unsatisfiable instances.

         The Unsatisfiable typeclass has no instances (see GHC.Tc.Instance.Class.matchGlobalInst).

         Users are prevented from writing instances in GHC.Tc.Validity.check_special_inst_head.
         This is done using the same mechanism as for, say, Coercible or WithDict.

      C. Using [G] Unsatisfiable msg to solve any Wanted.

         In GHC.Tc.Solver.simplifyTopWanteds, after defaulting happens, when an
         implication contains Givens of the form [G] Unsatisfiable msg, and the
         implication supports term-level evidence (as per Note [Coercion evidence only]
         in GHC.Tc.Types.Evidence), we use any such Given to solve all the Wanteds
         in that implication. See GHC.Tc.Solver.useUnsatisfiableGivens.

         The way we construct the evidence terms is slightly complicated by
         Type vs Constraint considerations; see Note [Evidence terms from Unsatisfiable Givens]
         in GHC.Tc.Solver.

         The proposal explains why this happens after defaulting: if there are other
         ways to solve the Wanteds, we would prefer to use that, as that will make
         user programs "as defined as possible".

         Wrinkle [Ambiguity]

           We also use an Unsatisfiable Given to solve Wanteds when performing an
           ambiguity check. See the call to "useUnsatisfiableGivens" in
           GHC.Tc.Solver.simplifyAmbiguityCheck.

           This is, for example, required to typecheck the definition
           of "unsatisfiable" itself:

             unsatisfiable :: forall {rep} (msg :: ErrorMessage) (a :: TYPE rep). Unsatisfiable msg => a

           The ambiguity check on this type signature will produce

             [G] Unsatisfiable msg1, [W] Unsatisfiable msg2

           and we want to ensure the Given solves the Wanted, to accept the definition.

           NB:

             An alternative would be to add a functional dependency on Unsatisfiable:

               class Unsatisfiable msg | -> msg

             Then we would unify msg1 and msg2 in the above constraint solving problem,
             and would be able to solve the Wanted using the Given in the normal way.
             However, adding such a functional dependency solely for this purpose
             could have undesirable consequences. For example, one might have

               [W] Unsatisfiable (Text "msg1"), [W] Unsatisfiable (Text "msg2")

             and W-W fundep interaction would produce the insoluble constraint

               [W] "msg1" ~ "msg2"

             which we definitely wouldn't want to report to the user.

      D. Adding "meth = unsatisfiable @msg" method bindings.

         When a class instance has an "Unsatisfiable msg" constraint in its context,
         and the user has omitted methods, we add method bindings of the form
         "meth = unsatisfiable @msg".
         See GHC.Tc.TyCl.Instance.tcMethods, in particular "tc_default".

         Example:

             class C a where { op :: a -> a }
             instance Unsatisfiable Msg => C [a] where {}

           elaborates to

             instance Unsatisfiable Msg => C [a] where { op = unsatisfiable @Msg }

           due to the (Unsatisfiable Msg) constraint in the instance context.

         We also switch off the "missing methods" warning in this situation.
         See "checkMinimalDefinition" in GHC.Tc.TyCl.Instance.tcMethods.

         Note that we do this even when there is a default method available. This
         ensures we run into the unsatisfiable error message when deferring type
         errors; otherwise we could end up with a runtime loop as seen in #23816.

      E. Switching off functional dependency coverage checks when there is
         an "Unsatisfiable msg" context.

         This is because we want to allow users to rule out certain instances with
         an "unsatisfiable" error, even when that would violate a functional
         dependency. For example:

           class C a b | a -> b
           instance Unsatisfiable (Text "No") => C a b

         See GHC.Tc.Instance.FunDeps.checkInstCoverage.

      F. Error reporting of "Unsatisfiable msg" constraints.

         This is done in GHC.Tc.Errors.reportWanteds: we detect when a constraint
         is of the form "Unsatisfiable msg" and just emit the custom message
         as an error to the user.

         This is the only way that "Unsatisfiable msg" constraints are reported,
         which makes their behaviour much more predictable than TypeError.
    -}

    --------------------------------------------
    --      Reporters
    --------------------------------------------

    type Reporter
      = SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM ()
    type ReporterSpec
      = ( String                      -- Name
        , ErrorItem -> Pred -> Bool  -- Pick these ones
        , Bool                        -- True <=> suppress subsequent reporters
        , Reporter)                   -- The reporter itself

    mkSkolReporter :: Reporter
    -- Suppress duplicates with either the same LHS, or same location
    -- Pre-condition: all items are equalities
    mkSkolReporter :: Reporter
    mkSkolReporter SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    items
      = (NonEmpty ErrorItem -> TcM ()) -> [NonEmpty ErrorItem] -> TcM ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ ((SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    reportGroup SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkEqErr SolverReportErrCtxt
    ctxt) ([ErrorItem] -> [NonEmpty ErrorItem]
    group (NonEmpty ErrorItem -> [ErrorItem]
    forall a. NonEmpty a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList NonEmpty ErrorItem
    items))
      where
         group :: [ErrorItem] -> [NonEmpty ErrorItem]
    group [] = []
         group (ErrorItem
    item:[ErrorItem]
    items) = (ErrorItem
    item ErrorItem -> [ErrorItem] -> NonEmpty ErrorItem
    forall a. a -> [a] -> NonEmpty a
    :| [ErrorItem]
    yeses) NonEmpty ErrorItem -> [NonEmpty ErrorItem] -> [NonEmpty ErrorItem]
    forall a. a -> [a] -> [a]
    : [ErrorItem] -> [NonEmpty ErrorItem]
    group [ErrorItem]
    noes
            where
              ([ErrorItem]
    yeses, [ErrorItem]
    noes) = (ErrorItem -> Bool) -> [ErrorItem] -> ([ErrorItem], [ErrorItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition (ErrorItem -> ErrorItem -> Bool
    group_with ErrorItem
    item) [ErrorItem]
    items

         group_with :: ErrorItem -> ErrorItem -> Bool
    group_with ErrorItem
    item1 ErrorItem
    item2
           | Ordering
    EQ <- ErrorItem -> ErrorItem -> Ordering
    cmp_loc ErrorItem
    item1 ErrorItem
    item2 = Bool
    True
           | ErrorItem -> ErrorItem -> Bool
    eq_lhs_type   ErrorItem
    item1 ErrorItem
    item2 = Bool
    True
           | Bool
    otherwise                 = Bool
    False

    reportHoles :: [ErrorItem]  -- other (tidied) constraints
                -> SolverReportErrCtxt -> [Hole] -> TcM ()
    reportHoles :: [ErrorItem] -> SolverReportErrCtxt -> [Hole] -> TcM ()
    reportHoles [ErrorItem]
    tidy_items SolverReportErrCtxt
    ctxt [Hole]
    holes
      = do
          diag_opts <- DynFlags -> DiagOpts
    initDiagOpts (DynFlags -> DiagOpts)
    -> IOEnv (Env TcGblEnv TcLclEnv) DynFlags
    -> IOEnv (Env TcGblEnv TcLclEnv) DiagOpts
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IOEnv (Env TcGblEnv TcLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
          let severity = DiagOpts -> DiagnosticReason -> Severity
    diagReasonSeverity DiagOpts
    diag_opts (SolverReportErrCtxt -> DiagnosticReason
    cec_type_holes SolverReportErrCtxt
    ctxt)
              holes'   = (Hole -> Bool) -> [Hole] -> [Hole]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Severity -> Hole -> Bool
    keepThisHole Severity
    severity) [Hole]
    holes
          -- Zonk and tidy all the TcLclEnvs before calling `mkHoleError`
          -- because otherwise types will be zonked and tidied many times over.
          (tidy_env', lcl_name_cache) <- liftZonkM $
            zonkTidyTcLclEnvs (cec_tidy ctxt) (map (ctl_env . hole_loc) holes')
          let ctxt' = SolverReportErrCtxt
    ctxt { cec_tidy = tidy_env' }
          forM_ holes' $ \Hole
    hole -> do { msg <- NameEnv Type
    -> [ErrorItem]
    -> SolverReportErrCtxt
    -> Hole
    -> TcM (MsgEnvelope TcRnMessage)
    mkHoleError NameEnv Type
    lcl_name_cache [ErrorItem]
    tidy_items SolverReportErrCtxt
    ctxt' Hole
    hole
                                     ; reportDiagnostic msg }

    keepThisHole :: Severity -> Hole -> Bool
    -- See Note [Skip type holes rapidly]
    keepThisHole :: Severity -> Hole -> Bool
    keepThisHole Severity
    sev Hole
    hole
      = case Hole -> HoleSort
    hole_sort Hole
    hole of
           ExprHole {}    -> Bool
    True
           HoleSort
    TypeHole       -> Bool
    keep_type_hole
           HoleSort
    ConstraintHole -> Bool
    keep_type_hole
      where
        keep_type_hole :: Bool
    keep_type_hole = case Severity
    sev of
                             Severity
    SevIgnore -> Bool
    False
                             Severity
    _         -> Bool
    True

    -- | zonkTidyTcLclEnvs takes a bunch of 'CtLocEnv's, each from a Hole.
    -- It returns a ('Name' :-> 'Type') mapping which gives the zonked, tidied
    -- type for each Id in any of the binder stacks in the  'CtLocEnv's.
    -- Since there is a huge overlap between these stacks, is is much,
    -- much faster to do them all at once, avoiding duplication.
    zonkTidyTcLclEnvs :: TidyEnv -> [CtLocEnv] -> ZonkM (TidyEnv, NameEnv Type)
    zonkTidyTcLclEnvs :: TidyEnv -> [CtLocEnv] -> ZonkM (TidyEnv, NameEnv Type)
    zonkTidyTcLclEnvs TidyEnv
    tidy_env [CtLocEnv]
    lcls = ((TidyEnv, NameEnv Type)
     -> TcBinder -> ZonkM (TidyEnv, NameEnv Type))
    -> (TidyEnv, NameEnv Type)
    -> [TcBinder]
    -> ZonkM (TidyEnv, NameEnv Type)
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldM (TidyEnv, NameEnv Type)
    -> TcBinder -> ZonkM (TidyEnv, NameEnv Type)
    go (TidyEnv
    tidy_env, NameEnv Type
    forall a. NameEnv a
    emptyNameEnv) ((CtLocEnv -> [TcBinder]) -> [CtLocEnv] -> [TcBinder]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap CtLocEnv -> [TcBinder]
    ctl_bndrs [CtLocEnv]
    lcls)
      where
        go :: (TidyEnv, NameEnv Type)
    -> TcBinder -> ZonkM (TidyEnv, NameEnv Type)
    go (TidyEnv, NameEnv Type)
    envs TcBinder
    tc_bndr = case TcBinder
    tc_bndr of
              TcTvBndr {} -> (TidyEnv, NameEnv Type) -> ZonkM (TidyEnv, NameEnv Type)
    forall a. a -> ZonkM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv, NameEnv Type)
    envs
              TcIdBndr TcId
    id TopLevelFlag
    _top_lvl -> Name
    -> Type -> (TidyEnv, NameEnv Type) -> ZonkM (TidyEnv, NameEnv Type)
    go_one (TcId -> Name
    idName TcId
    id) (TcId -> Type
    idType TcId
    id) (TidyEnv, NameEnv Type)
    envs
              TcIdBndr_ExpType Name
    name ExpType
    et TopLevelFlag
    _top_lvl ->
                do { mb_ty <- IO (Maybe Type) -> ZonkM (Maybe Type)
    forall a. IO a -> ZonkM a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (Maybe Type) -> ZonkM (Maybe Type))
    -> IO (Maybe Type) -> ZonkM (Maybe Type)
    forall a b. (a -> b) -> a -> b
    $ ExpType -> IO (Maybe Type)
    forall (m :: * -> *). MonadIO m => ExpType -> m (Maybe Type)
    readExpType_maybe ExpType
    et
                       -- et really should be filled in by now. But there's a chance
                       -- it hasn't, if, say, we're reporting a kind error en route to
                       -- checking a term. See test indexed-types/should_fail/T8129
                       -- Or we are reporting errors from the ambiguity check on
                       -- a local type signature
                   ; case mb_ty of
                       Just Type
    ty -> Name
    -> Type -> (TidyEnv, NameEnv Type) -> ZonkM (TidyEnv, NameEnv Type)
    go_one Name
    name Type
    ty (TidyEnv, NameEnv Type)
    envs
                       Maybe Type
    Nothing -> (TidyEnv, NameEnv Type) -> ZonkM (TidyEnv, NameEnv Type)
    forall a. a -> ZonkM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv, NameEnv Type)
    envs
                   }
        go_one :: Name
    -> Type -> (TidyEnv, NameEnv Type) -> ZonkM (TidyEnv, NameEnv Type)
    go_one Name
    name Type
    ty (TidyEnv
    tidy_env, NameEnv Type
    name_env) = do
                if Name
    name Name -> NameEnv Type -> Bool
    forall a. Name -> NameEnv a -> Bool
    `elemNameEnv` NameEnv Type
    name_env
                  then (TidyEnv, NameEnv Type) -> ZonkM (TidyEnv, NameEnv Type)
    forall a. a -> ZonkM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    tidy_env, NameEnv Type
    name_env)
                  else do
                    (tidy_env', tidy_ty) <- TidyEnv -> Type -> ZonkM (TidyEnv, Type)
    zonkTidyTcType TidyEnv
    tidy_env Type
    ty
                    return (tidy_env',  extendNameEnv name_env name tidy_ty)

    reportNotConcreteErrs :: SolverReportErrCtxt -> [NotConcreteError] -> TcM ()
    reportNotConcreteErrs :: SolverReportErrCtxt -> [NotConcreteError] -> TcM ()
    reportNotConcreteErrs SolverReportErrCtxt
    _ [] = () -> TcM ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
    reportNotConcreteErrs SolverReportErrCtxt
    ctxt errs :: [NotConcreteError]
    errs@(NotConcreteError
    err0:[NotConcreteError]
    _)
      = do { msg <- CtLocEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport (CtLoc -> CtLocEnv
    ctLocEnv (NotConcreteError -> CtLoc
    nce_loc NotConcreteError
    err0)) TcRnMessage
    diag (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt) []
           ; reportDiagnostic msg }

      where

        frr_origins :: [FixedRuntimeRepErrorInfo]
    frr_origins = [NotConcreteError] -> [FixedRuntimeRepErrorInfo]
    acc_errors [NotConcreteError]
    errs
        diag :: TcRnMessage
    diag = SolverReportWithCtxt -> DiagnosticReason -> TcRnMessage
    TcRnSolverReport
                 (SolverReportErrCtxt -> TcSolverReportMsg -> SolverReportWithCtxt
    SolverReportWithCtxt SolverReportErrCtxt
    ctxt ([FixedRuntimeRepErrorInfo] -> TcSolverReportMsg
    FixedRuntimeRepError [FixedRuntimeRepErrorInfo]
    frr_origins))
                 DiagnosticReason
    ErrorWithoutFlag

        -- Accumulate the different kind of errors arising from syntactic equality.
        -- (Only SynEq_FRR origin for the moment.)
        acc_errors :: [NotConcreteError] -> [FixedRuntimeRepErrorInfo]
    acc_errors = [FixedRuntimeRepErrorInfo]
    -> [NotConcreteError] -> [FixedRuntimeRepErrorInfo]
    go []
          where
            go :: [FixedRuntimeRepErrorInfo]
    -> [NotConcreteError] -> [FixedRuntimeRepErrorInfo]
    go [FixedRuntimeRepErrorInfo]
    frr_errs [] = [FixedRuntimeRepErrorInfo]
    frr_errs
            go [FixedRuntimeRepErrorInfo]
    frr_errs (NotConcreteError
    err:[NotConcreteError]
    errs)
              | [FixedRuntimeRepErrorInfo]
    frr_errs <- [FixedRuntimeRepErrorInfo]
    -> [NotConcreteError] -> [FixedRuntimeRepErrorInfo]
    go [FixedRuntimeRepErrorInfo]
    frr_errs [NotConcreteError]
    errs
              = case NotConcreteError
    err of
                  NCE_FRR
                    { nce_frr_origin :: NotConcreteError -> FixedRuntimeRepOrigin
    nce_frr_origin = FixedRuntimeRepOrigin
    frr_orig
                    , nce_reasons :: NotConcreteError -> NonEmpty NotConcreteReason
    nce_reasons = NonEmpty NotConcreteReason
    _not_conc } ->
                    FRR_Info
                      { frr_info_origin :: FixedRuntimeRepOrigin
    frr_info_origin       = FixedRuntimeRepOrigin
    frr_orig
                      , frr_info_not_concrete :: Maybe (TcId, Type)
    frr_info_not_concrete = Maybe (TcId, Type)
    forall a. Maybe a
    Nothing }
                    FixedRuntimeRepErrorInfo
    -> [FixedRuntimeRepErrorInfo] -> [FixedRuntimeRepErrorInfo]
    forall a. a -> [a] -> [a]
    : [FixedRuntimeRepErrorInfo]
    frr_errs

    {- Note [Skip type holes rapidly]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Suppose we have module with a /lot/ of partial type signatures, and we
    compile it while suppressing partial-type-signature warnings.  Then
    we don't want to spend ages constructing error messages and lists of
    relevant bindings that we never display! This happened in #14766, in
    which partial type signatures in a Happy-generated parser cause a huge
    increase in compile time.

    The function ignoreThisHole short-circuits the error/warning generation
    machinery, in cases where it is definitely going to be a no-op.
    -}

    mkUserTypeErrorReporter :: Reporter
    mkUserTypeErrorReporter :: Reporter
    mkUserTypeErrorReporter SolverReportErrCtxt
    ctxt
      = (ErrorItem -> TcM ()) -> NonEmpty ErrorItem -> TcM ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ ((ErrorItem -> TcM ()) -> NonEmpty ErrorItem -> TcM ())
    -> (ErrorItem -> TcM ()) -> NonEmpty ErrorItem -> TcM ()
    forall a b. (a -> b) -> a -> b
    $ \ErrorItem
    item -> do { let err :: SolverReport
    err = SolverReportErrCtxt -> TcSolverReportMsg -> SolverReport
    important SolverReportErrCtxt
    ctxt (TcSolverReportMsg -> SolverReport)
    -> TcSolverReportMsg -> SolverReport
    forall a b. (a -> b) -> a -> b
    $ ErrorItem -> TcSolverReportMsg
    mkUserTypeError ErrorItem
    item
                            ; SolverReportErrCtxt -> NonEmpty ErrorItem -> SolverReport -> TcM ()
    maybeReportError SolverReportErrCtxt
    ctxt (ErrorItem
    item ErrorItem -> [ErrorItem] -> NonEmpty ErrorItem
    forall a. a -> [a] -> NonEmpty a
    :| []) SolverReport
    err
                            ; SolverReportErrCtxt -> SolverReport -> ErrorItem -> TcM ()
    addDeferredBinding SolverReportErrCtxt
    ctxt SolverReport
    err ErrorItem
    item }

    mkUserTypeError :: ErrorItem -> TcSolverReportMsg
    mkUserTypeError :: ErrorItem -> TcSolverReportMsg
    mkUserTypeError ErrorItem
    item
      | Just Type
    msg <- Type -> Maybe Type
    getUserTypeErrorMsg Type
    pty
      = Type -> TcSolverReportMsg
    UserTypeError Type
    msg
      | Just Type
    msg <- Type -> Maybe Type
    isUnsatisfiableCt_maybe Type
    pty
      = Type -> TcSolverReportMsg
    UnsatisfiableError Type
    msg
      | Bool
    otherwise
      = String -> SDoc -> TcSolverReportMsg
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "mkUserTypeError" (ErrorItem -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ErrorItem
    item)
      where
        pty :: Type
    pty = ErrorItem -> Type
    errorItemPred ErrorItem
    item

    mkGivenErrorReporter :: Reporter
    -- See Note [Given errors]
    mkGivenErrorReporter :: Reporter
    mkGivenErrorReporter SolverReportErrCtxt
    ctxt (ErrorItem
    item:|[ErrorItem]
    _)
      = do { (ctxt, relevant_binds, item) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item
           ; let (implic:_) = cec_encl ctxt
                     -- Always non-empty when mkGivenErrorReporter is called
                 loc'  = CtLoc -> CtLocEnv -> CtLoc
    setCtLocEnv (ErrorItem -> CtLoc
    ei_loc ErrorItem
    item) (Implication -> CtLocEnv
    ic_env Implication
    implic)
                 item' = ErrorItem
    item { ei_loc = loc' }
                       -- For given constraints we overwrite the env (and hence src-loc)
                       -- with one from the immediately-enclosing implication.
                       -- See Note [Inaccessible code]
           ; eq_err_msg <- mkEqErr_help ctxt item' ty1 ty2
           ; let supplementary = [ RelevantBindings -> SolverReportSupplementary
    SupplementaryBindings RelevantBindings
    relevant_binds ]
                 msg = Implication -> SolverReportWithCtxt -> TcRnMessage
    TcRnInaccessibleCode Implication
    implic (SolverReportErrCtxt -> TcSolverReportMsg -> SolverReportWithCtxt
    SolverReportWithCtxt SolverReportErrCtxt
    ctxt TcSolverReportMsg
    eq_err_msg)
           ; msg <- mkErrorReport (ctLocEnv loc') msg (Just ctxt) supplementary
           ; reportDiagnostic msg }
      where
        (Type
    ty1, Type
    ty2)   = Type -> (Type, Type)
    getEqPredTys (ErrorItem -> Type
    errorItemPred ErrorItem
    item)

    ignoreErrorReporter :: Reporter
    -- Discard Given errors that don't come from
    -- a pattern match; maybe we should warn instead?
    ignoreErrorReporter :: Reporter
    ignoreErrorReporter SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    items
      = do { String -> SDoc -> TcM ()
    traceTc String
    "mkGivenErrorReporter no" (NonEmpty ErrorItem -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr NonEmpty ErrorItem
    items SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ [Implication] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (SolverReportErrCtxt -> [Implication]
    cec_encl SolverReportErrCtxt
    ctxt))
           ; () -> TcM ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return () }

    {- Note [Given errors]
    ~~~~~~~~~~~~~~~~~~~~~~
    Given constraints represent things for which we have (or will have)
    evidence, so they aren't errors.  But if a Given constraint is
    insoluble, this code is inaccessible, and we might want to at least
    warn about that.  A classic case is

       data T a where
         T1 :: T Int
         T2 :: T a
         T3 :: T Bool

       f :: T Int -> Bool
       f T1 = ...
       f T2 = ...
       f T3 = ...  -- We want to report this case as inaccessible

    We'd like to point out that the T3 match is inaccessible. It
    will have a Given constraint [G] Int ~ Bool.

    But we don't want to report ALL insoluble Given constraints.  See Trac
    #12466 for a long discussion.  For example, if we aren't careful
    we'll complain about
       f :: ((Int ~ Bool) => a -> a) -> Int
    which arguably is OK.  It's more debatable for
       g :: (Int ~ Bool) => Int -> Int
    but it's tricky to distinguish these cases so we don't report
    either.

    The bottom line is this: has_gadt_match looks for an enclosing
    pattern match which binds some equality constraints.  If we
    find one, we report the insoluble Given.
    -}

    mkGroupReporter :: (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
                                 -- Make error message for a group
                    -> Reporter  -- Deal with lots of constraints
    -- Group together errors from same location,
    -- and report only the first (to avoid a cascade)
    mkGroupReporter :: (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mk_err SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    items
      = (NonEmpty ErrorItem -> TcM ()) -> [NonEmpty ErrorItem] -> TcM ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ ((SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    reportGroup SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mk_err SolverReportErrCtxt
    ctxt) ((ErrorItem -> ErrorItem -> Ordering)
    -> [ErrorItem] -> [NonEmpty ErrorItem]
    forall a. (a -> a -> Ordering) -> [a] -> [NonEmpty a]
    equivClasses ErrorItem -> ErrorItem -> Ordering
    cmp_loc (NonEmpty ErrorItem -> [ErrorItem]
    forall a. NonEmpty a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList NonEmpty ErrorItem
    items))

    eq_lhs_type :: ErrorItem -> ErrorItem -> Bool
    eq_lhs_type :: ErrorItem -> ErrorItem -> Bool
    eq_lhs_type ErrorItem
    item1 ErrorItem
    item2
      = case (Type -> Pred
    classifyPredType (ErrorItem -> Type
    errorItemPred ErrorItem
    item1), Type -> Pred
    classifyPredType (ErrorItem -> Type
    errorItemPred ErrorItem
    item2)) of
           (EqPred EqRel
    eq_rel1 Type
    ty1 Type
    _, EqPred EqRel
    eq_rel2 Type
    ty2 Type
    _) ->
             (EqRel
    eq_rel1 EqRel -> EqRel -> Bool
    forall a. Eq a => a -> a -> Bool
    == EqRel
    eq_rel2) Bool -> Bool -> Bool
    && (Type
    ty1 Type -> Type -> Bool
    `eqType` Type
    ty2)
           (Pred, Pred)
    _ -> String -> SDoc -> Bool
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "mkSkolReporter" (ErrorItem -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ErrorItem
    item1 SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ ErrorItem -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ErrorItem
    item2)

    cmp_loc :: ErrorItem -> ErrorItem -> Ordering
    cmp_loc :: ErrorItem -> ErrorItem -> Ordering
    cmp_loc ErrorItem
    item1 ErrorItem
    item2 = ErrorItem -> RealSrcLoc
    get ErrorItem
    item1 RealSrcLoc -> RealSrcLoc -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` ErrorItem -> RealSrcLoc
    get ErrorItem
    item2
      where
        get :: ErrorItem -> RealSrcLoc
    get ErrorItem
    ei = RealSrcSpan -> RealSrcLoc
    realSrcSpanStart (CtLoc -> RealSrcSpan
    ctLocSpan (ErrorItem -> CtLoc
    errorItemCtLoc ErrorItem
    ei))
                 -- Reduce duplication by reporting only one error from each
                 -- /starting/ location even if the end location differs

    reportGroup :: (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport) -> Reporter
    reportGroup :: (SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport)
    -> Reporter
    reportGroup SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mk_err SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    items
      = do { err <- SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mk_err SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    items
           ; traceTc "About to maybeReportErr" $
             vcat [ text "Constraint:"             <+> ppr items
                  , text "cec_suppress ="          <+> ppr (cec_suppress ctxt)
                  , text "cec_defer_type_errors =" <+> ppr (cec_defer_type_errors ctxt) ]
           ; maybeReportError ctxt items err
               -- But see Note [Always warn with -fdefer-type-errors]
           ; traceTc "reportGroup" (ppr items)
           ; mapM_ (addDeferredBinding ctxt err) items }
               -- Add deferred bindings for all
               -- Redundant if we are going to abort compilation,
               -- but that's hard to know for sure, and if we don't
               -- abort, we need bindings for all (e.g. #12156)

    -- See Note [No deferring for multiplicity errors]
    nonDeferrableOrigin :: CtOrigin -> Bool
    nonDeferrableOrigin :: CtOrigin -> Bool
    nonDeferrableOrigin (NonLinearPatternOrigin {}) = Bool
    True
    nonDeferrableOrigin (UsageEnvironmentOf {}) = Bool
    True
    nonDeferrableOrigin (FRROrigin {})          = Bool
    True
    nonDeferrableOrigin CtOrigin
    _                       = Bool
    False

    maybeReportError :: SolverReportErrCtxt
                     -> NonEmpty ErrorItem     -- items covered by the Report
                     -> SolverReport -> TcM ()
    maybeReportError :: SolverReportErrCtxt -> NonEmpty ErrorItem -> SolverReport -> TcM ()
    maybeReportError SolverReportErrCtxt
    ctxt items :: NonEmpty ErrorItem
    items@(ErrorItem
    item1:|[ErrorItem]
    _) (SolverReport { sr_important_msg :: SolverReport -> SolverReportWithCtxt
    sr_important_msg = SolverReportWithCtxt
    important
                                                         , sr_supplementary :: SolverReport -> [SolverReportSupplementary]
    sr_supplementary = [SolverReportSupplementary]
    supp })
      = Bool -> TcM () -> TcM ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (SolverReportErrCtxt -> Bool
    cec_suppress SolverReportErrCtxt
    ctxt  -- Some worse error has occurred, so suppress this diagnostic
             Bool -> Bool -> Bool
    || (ErrorItem -> Bool) -> NonEmpty ErrorItem -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all ErrorItem -> Bool
    ei_suppress NonEmpty ErrorItem
    items) (TcM () -> TcM ()) -> TcM () -> TcM ()
    forall a b. (a -> b) -> a -> b
    $
                               -- if they're all to be suppressed, report nothing
                               -- if at least one is not suppressed, do report:
                               -- the function that generates the error message
                               -- should look for an unsuppressed error item
        do let reason :: DiagnosticReason
    reason | (ErrorItem -> Bool) -> NonEmpty ErrorItem -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (CtOrigin -> Bool
    nonDeferrableOrigin (CtOrigin -> Bool) -> (ErrorItem -> CtOrigin) -> ErrorItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorItem -> CtOrigin
    errorItemOrigin) NonEmpty ErrorItem
    items = DiagnosticReason
    ErrorWithoutFlag
                      | Bool
    otherwise                                         = SolverReportErrCtxt -> DiagnosticReason
    cec_defer_type_errors SolverReportErrCtxt
    ctxt
                      -- See Note [No deferring for multiplicity errors]
               diag :: TcRnMessage
    diag = SolverReportWithCtxt -> DiagnosticReason -> TcRnMessage
    TcRnSolverReport SolverReportWithCtxt
    important DiagnosticReason
    reason
           msg <- CtLocEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport (CtLoc -> CtLocEnv
    ctLocEnv (ErrorItem -> CtLoc
    errorItemCtLoc ErrorItem
    item1)) TcRnMessage
    diag (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt) [SolverReportSupplementary]
    supp
           reportDiagnostic msg

    addDeferredBinding :: SolverReportErrCtxt -> SolverReport -> ErrorItem -> TcM ()
    -- See Note [Deferring coercion errors to runtime]
    addDeferredBinding :: SolverReportErrCtxt -> SolverReport -> ErrorItem -> TcM ()
    addDeferredBinding SolverReportErrCtxt
    ctxt SolverReport
    err (EI { ei_evdest :: ErrorItem -> Maybe TcEvDest
    ei_evdest = Just TcEvDest
    dest, ei_pred :: ErrorItem -> Type
    ei_pred = Type
    item_ty
                                    , ei_loc :: ErrorItem -> CtLoc
    ei_loc = CtLoc
    loc })
         -- if evdest is Just, then the constraint was from a wanted
      | SolverReportErrCtxt -> Bool
    deferringAnyBindings SolverReportErrCtxt
    ctxt
      = do { err_tm <- SolverReportErrCtxt -> CtLoc -> Type -> SolverReport -> TcM EvTerm
    mkErrorTerm SolverReportErrCtxt
    ctxt CtLoc
    loc Type
    item_ty SolverReport
    err
           ; let ev_binds_var = SolverReportErrCtxt -> EvBindsVar
    cec_binds SolverReportErrCtxt
    ctxt

           ; case dest of
               EvVarDest TcId
    evar
                 -> EvBindsVar -> EvBind -> TcM ()
    addTcEvBind EvBindsVar
    ev_binds_var (EvBind -> TcM ()) -> EvBind -> TcM ()
    forall a b. (a -> b) -> a -> b
    $ TcId -> Bool -> EvTerm -> EvBind
    mkWantedEvBind TcId
    evar Bool
    True EvTerm
    err_tm
               HoleDest CoercionHole
    hole
                 -> do { -- See Note [Deferred errors for coercion holes]
                         let co_var :: TcId
    co_var = CoercionHole -> TcId
    coHoleCoVar CoercionHole
    hole
                       ; EvBindsVar -> EvBind -> TcM ()
    addTcEvBind EvBindsVar
    ev_binds_var (EvBind -> TcM ()) -> EvBind -> TcM ()
    forall a b. (a -> b) -> a -> b
    $ TcId -> Bool -> EvTerm -> EvBind
    mkWantedEvBind TcId
    co_var Bool
    True EvTerm
    err_tm
                       ; CoercionHole -> TcCoercionN -> TcM ()
    fillCoercionHole CoercionHole
    hole (TcId -> TcCoercionN
    mkCoVarCo TcId
    co_var) } }
    addDeferredBinding SolverReportErrCtxt
    _ SolverReport
    _ ErrorItem
    _ = () -> TcM ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()    -- Do not set any evidence for Given

    mkErrorTerm :: SolverReportErrCtxt -> CtLoc -> Type  -- of the error term
                -> SolverReport -> TcM EvTerm
    mkErrorTerm :: SolverReportErrCtxt -> CtLoc -> Type -> SolverReport -> TcM EvTerm
    mkErrorTerm SolverReportErrCtxt
    ctxt CtLoc
    ct_loc Type
    ty (SolverReport { sr_important_msg :: SolverReport -> SolverReportWithCtxt
    sr_important_msg = SolverReportWithCtxt
    important, sr_supplementary :: SolverReport -> [SolverReportSupplementary]
    sr_supplementary = [SolverReportSupplementary]
    supp })
      = do { msg <- CtLocEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport
                      (CtLoc -> CtLocEnv
    ctLocEnv CtLoc
    ct_loc)
                      (SolverReportWithCtxt -> DiagnosticReason -> TcRnMessage
    TcRnSolverReport SolverReportWithCtxt
    important DiagnosticReason
    ErrorWithoutFlag) (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt) [SolverReportSupplementary]
    supp
             -- This will be reported at runtime, so we always want "error:" in the report, never "warning:"
           ; dflags <- getDynFlags
           ; let err_msg = DiagnosticOpts TcRnMessage -> MsgEnvelope TcRnMessage -> SDoc
    forall e. Diagnostic e => DiagnosticOpts e -> MsgEnvelope e -> SDoc
    pprLocMsgEnvelope (DynFlags -> DiagnosticOpts TcRnMessage
    initTcMessageOpts DynFlags
    dflags) MsgEnvelope TcRnMessage
    msg
                 err_str = DynFlags -> SDoc -> String
    showSDoc DynFlags
    dflags (SDoc -> String) -> SDoc -> String
    forall a b. (a -> b) -> a -> b
    $
                           SDoc
    err_msg SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "(deferred type error)"

           ; return $ evDelayedError ty err_str }

    tryReporters :: SolverReportErrCtxt -> [ReporterSpec] -> [ErrorItem] -> TcM (SolverReportErrCtxt, [ErrorItem])
    -- Use the first reporter in the list whose predicate says True
    tryReporters :: SolverReportErrCtxt
    -> [ReporterSpec]
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    tryReporters SolverReportErrCtxt
    ctxt [ReporterSpec]
    reporters [ErrorItem]
    items
      = do { let ([ErrorItem]
    vis_items, [ErrorItem]
    invis_items)
                   = (ErrorItem -> Bool) -> [ErrorItem] -> ([ErrorItem], [ErrorItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition (CtOrigin -> Bool
    isVisibleOrigin (CtOrigin -> Bool) -> (ErrorItem -> CtOrigin) -> ErrorItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorItem -> CtOrigin
    errorItemOrigin) [ErrorItem]
    items
           ; String -> SDoc -> TcM ()
    traceTc String
    "tryReporters {" ([ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    vis_items SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ [ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    invis_items)
           ; (ctxt', items') <- SolverReportErrCtxt
    -> [ReporterSpec]
    -> [ErrorItem]
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    go SolverReportErrCtxt
    ctxt [ReporterSpec]
    reporters [ErrorItem]
    vis_items [ErrorItem]
    invis_items
           ; traceTc "tryReporters }" (ppr items')
           ; return (ctxt', items') }
      where
        go :: SolverReportErrCtxt
    -> [ReporterSpec]
    -> [ErrorItem]
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    go SolverReportErrCtxt
    ctxt [] [ErrorItem]
    vis_items [ErrorItem]
    invis_items
          = (SolverReportErrCtxt, [ErrorItem])
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SolverReportErrCtxt
    ctxt, [ErrorItem]
    vis_items [ErrorItem] -> [ErrorItem] -> [ErrorItem]
    forall a. [a] -> [a] -> [a]
    ++ [ErrorItem]
    invis_items)

        go SolverReportErrCtxt
    ctxt (ReporterSpec
    r : [ReporterSpec]
    rs) [ErrorItem]
    vis_items [ErrorItem]
    invis_items
           -- always look at *visible* Origins before invisible ones
           -- this is the whole point of isVisibleOrigin
          = do { (ctxt', vis_items') <- SolverReportErrCtxt
    -> ReporterSpec
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    tryReporter SolverReportErrCtxt
    ctxt ReporterSpec
    r [ErrorItem]
    vis_items
               ; (ctxt'', invis_items') <- tryReporter ctxt' r invis_items
               ; go ctxt'' rs vis_items' invis_items' }
                    -- Carry on with the rest, because we must make
                    -- deferred bindings for them if we have -fdefer-type-errors
                    -- But suppress their error messages

    tryReporter :: SolverReportErrCtxt -> ReporterSpec -> [ErrorItem] -> TcM (SolverReportErrCtxt, [ErrorItem])
    tryReporter :: SolverReportErrCtxt
    -> ReporterSpec
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    tryReporter SolverReportErrCtxt
    ctxt (String
    str, ErrorItem -> Pred -> Bool
    keep_me,  Bool
    suppress_after, Reporter
    reporter) [ErrorItem]
    items = case [ErrorItem] -> Maybe (NonEmpty ErrorItem)
    forall a. [a] -> Maybe (NonEmpty a)
    nonEmpty [ErrorItem]
    yeses of
        Maybe (NonEmpty ErrorItem)
    Nothing -> (SolverReportErrCtxt, [ErrorItem])
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (SolverReportErrCtxt
    ctxt, [ErrorItem]
    items)
        Just NonEmpty ErrorItem
    yeses -> do
           { String -> SDoc -> TcM ()
    traceTc String
    "tryReporter{ " (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    str SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> NonEmpty ErrorItem -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr NonEmpty ErrorItem
    yeses)
           ; (_, no_errs) <- TcM () -> TcRn ((), Bool)
    forall a. TcRn a -> TcRn (a, Bool)
    askNoErrs (Reporter
    reporter SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    yeses)
           ; let suppress_now   = Bool -> Bool
    not Bool
    no_errs Bool -> Bool -> Bool
    && Bool
    suppress_after
                                -- See Note [Suppressing error messages]
                 ctxt' = SolverReportErrCtxt
    ctxt { cec_suppress = suppress_now || cec_suppress ctxt }
           ; traceTc "tryReporter end }" (text str <+> ppr (cec_suppress ctxt) <+> ppr suppress_after)
           ; return (ctxt', nos) }
      where
        ([ErrorItem]
    yeses, [ErrorItem]
    nos) = (ErrorItem -> Bool) -> [ErrorItem] -> ([ErrorItem], [ErrorItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition ErrorItem -> Bool
    keep [ErrorItem]
    items
        keep :: ErrorItem -> Bool
    keep ErrorItem
    item = ErrorItem -> Pred -> Bool
    keep_me ErrorItem
    item (Type -> Pred
    classifyPredType (ErrorItem -> Type
    errorItemPred ErrorItem
    item))

    -- | Wrap an input 'TcRnMessage' with additional contextual information,
    -- such as relevant bindings or valid hole fits.
    mkErrorReport :: CtLocEnv
                  -> TcRnMessage
                      -- ^ The main payload of the message.
                  -> Maybe SolverReportErrCtxt
                      -- ^ The context to add, after the main diagnostic
                      -- but before the supplementary information.
                      -- Nothing <=> don't add any context.
                  -> [SolverReportSupplementary]
                      -- ^ Supplementary information, to be added at the end of the message.
                  -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport :: CtLocEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport CtLocEnv
    tcl_env TcRnMessage
    msg Maybe SolverReportErrCtxt
    mb_ctxt [SolverReportSupplementary]
    supplementary
      = do { mb_context <- (SolverReportErrCtxt -> IOEnv (Env TcGblEnv TcLclEnv) SDoc)
    -> Maybe SolverReportErrCtxt
    -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe SDoc)
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Maybe a -> f (Maybe b)
    traverse (\ SolverReportErrCtxt
    ctxt -> TidyEnv -> [ErrCtxt] -> IOEnv (Env TcGblEnv TcLclEnv) SDoc
    mkErrInfo (SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt) (CtLocEnv -> [ErrCtxt]
    ctl_ctxt CtLocEnv
    tcl_env)) Maybe SolverReportErrCtxt
    mb_ctxt
           ; unit_state <- hsc_units <$> getTopEnv
           ; hfdc <- getHoleFitDispConfig
           ; let
               err_info =
                 SDoc -> SDoc -> ErrInfo
    ErrInfo
                   (SDoc -> Maybe SDoc -> SDoc
    forall a. a -> Maybe a -> a
    fromMaybe SDoc
    forall doc. IsOutput doc => doc
    empty Maybe SDoc
    mb_context)
                   ([SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
    forall a b. (a -> b) -> a -> b
    $ (SolverReportSupplementary -> SDoc)
    -> [SolverReportSupplementary] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (HoleFitDispConfig -> SolverReportSupplementary -> SDoc
    pprSolverReportSupplementary HoleFitDispConfig
    hfdc) [SolverReportSupplementary]
    supplementary)
           ; let detailed_msg = ErrInfo -> TcRnMessage -> TcRnMessageDetailed
    mkDetailedMessage ErrInfo
    err_info TcRnMessage
    msg
           ; mkTcRnMessage
               (RealSrcSpan (ctl_loc tcl_env) Strict.Nothing)
               (TcRnMessageWithInfo unit_state $ detailed_msg) }

    -- | Pretty-print supplementary information, to add to an error report.
    pprSolverReportSupplementary :: HoleFitDispConfig -> SolverReportSupplementary -> SDoc
    -- This function should be in "GHC.Tc.Errors.Ppr",
    -- but we need it here because 'TcRnMessageDetails' needs an 'SDoc'.
    pprSolverReportSupplementary :: HoleFitDispConfig -> SolverReportSupplementary -> SDoc
    pprSolverReportSupplementary HoleFitDispConfig
    hfdc = \case
      SupplementaryBindings RelevantBindings
    binds -> RelevantBindings -> SDoc
    pprRelevantBindings RelevantBindings
    binds
      SupplementaryHoleFits ValidHoleFits
    fits  -> HoleFitDispConfig -> ValidHoleFits -> SDoc
    pprValidHoleFits HoleFitDispConfig
    hfdc ValidHoleFits
    fits
      SupplementaryCts      [(Type, RealSrcSpan)]
    cts   -> [(Type, RealSrcSpan)] -> SDoc
    pprConstraintsInclude [(Type, RealSrcSpan)]
    cts

    -- | Display a collection of valid hole fits.
    pprValidHoleFits :: HoleFitDispConfig -> ValidHoleFits -> SDoc
    -- This function should be in "GHC.Tc.Errors.Ppr",
    -- but we need it here because 'TcRnMessageDetails' needs an 'SDoc'.
    pprValidHoleFits :: HoleFitDispConfig -> ValidHoleFits -> SDoc
    pprValidHoleFits HoleFitDispConfig
    hfdc (ValidHoleFits (Fits [HoleFit]
    fits Bool
    discarded_fits) (Fits [HoleFit]
    refs Bool
    discarded_refs))
      = SDoc
    fits_msg SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ SDoc
    refs_msg

      where
        fits_msg, refs_msg, fits_discard_msg, refs_discard_msg :: SDoc
        fits_msg :: SDoc
    fits_msg = Bool -> SDoc -> SDoc
    forall doc. IsOutput doc => Bool -> doc -> doc
    ppUnless ([HoleFit] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [HoleFit]
    fits) (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
                        SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Valid hole fits include") Int
    2 (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
                        [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat ((HoleFit -> SDoc) -> [HoleFit] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (HoleFitDispConfig -> HoleFit -> SDoc
    pprHoleFit HoleFitDispConfig
    hfdc) [HoleFit]
    fits)
                          SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Bool -> SDoc -> SDoc
    forall doc. IsOutput doc => Bool -> doc -> doc
    ppWhen  Bool
    discarded_fits SDoc
    fits_discard_msg
        refs_msg :: SDoc
    refs_msg = Bool -> SDoc -> SDoc
    forall doc. IsOutput doc => Bool -> doc -> doc
    ppUnless ([HoleFit] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [HoleFit]
    refs) (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
                      SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Valid refinement hole fits include") Int
    2 (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
                      [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat ((HoleFit -> SDoc) -> [HoleFit] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (HoleFitDispConfig -> HoleFit -> SDoc
    pprHoleFit HoleFitDispConfig
    hfdc) [HoleFit]
    refs)
                        SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Bool -> SDoc -> SDoc
    forall doc. IsOutput doc => Bool -> doc -> doc
    ppWhen Bool
    discarded_refs SDoc
    refs_discard_msg
        fits_discard_msg :: SDoc
    fits_discard_msg =
          String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "(Some hole fits suppressed;" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+>
          String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "use -fmax-valid-hole-fits=N" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+>
          String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "or -fno-max-valid-hole-fits)"
        refs_discard_msg :: SDoc
    refs_discard_msg =
          String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "(Some refinement hole fits suppressed;" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+>
          String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "use -fmax-refinement-hole-fits=N" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+>
          String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "or -fno-max-refinement-hole-fits)"

    -- | Add a "Constraints include..." message.
    --
    -- See Note [Constraints include ...]
    pprConstraintsInclude :: [(PredType, RealSrcSpan)] -> SDoc
    -- This function should be in "GHC.Tc.Errors.Ppr",
    -- but we need it here because 'TcRnMessageDetails' needs an 'SDoc'.
    pprConstraintsInclude :: [(Type, RealSrcSpan)] -> SDoc
    pprConstraintsInclude [(Type, RealSrcSpan)]
    cts
      = Bool -> SDoc -> SDoc
    forall doc. IsOutput doc => Bool -> doc -> doc
    ppUnless ([(Type, RealSrcSpan)] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(Type, RealSrcSpan)]
    cts) (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
         SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Constraints include")
            Int
    2 ([SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
    forall a b. (a -> b) -> a -> b
    $ ((Type, RealSrcSpan) -> SDoc) -> [(Type, RealSrcSpan)] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (Type, RealSrcSpan) -> SDoc
    forall {a} {a}. (Outputable a, Outputable a) => (a, a) -> SDoc
    pprConstraint [(Type, RealSrcSpan)]
    cts)
      where
        pprConstraint :: (a, a) -> SDoc
    pprConstraint (a
    constraint, a
    loc) =
          a -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr a
    constraint SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Int -> SDoc -> SDoc
    nest Int
    2 (SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    parens (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "from" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> a -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr a
    loc))

    {- Note [Always warn with -fdefer-type-errors]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    When -fdefer-type-errors is on we warn about *all* type errors, even
    if cec_suppress is on.  This can lead to a lot more warnings than you
    would get errors without -fdefer-type-errors, but if we suppress any of
    them you might get a runtime error that wasn't warned about at compile
    time.

    To be consistent, we should also report multiple warnings from a single
    location in mkGroupReporter, when -fdefer-type-errors is on.  But that
    is perhaps a bit *over*-consistent!

    With #10283, you can now opt out of deferred type error warnings.

    Note [No deferring for multiplicity errors]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    As explained in Note [Wrapper returned from tcSubMult] in GHC.Tc.Utils.Unify,
    linear types do not support casts and any nontrivial coercion will raise
    an error during desugaring.

    This means that even if we defer a multiplicity mismatch during typechecking,
    the desugarer will refuse to compile anyway. Worse: the error raised
    by the desugarer would shadow the type mismatch warnings (#20083).
    As a solution, we refuse to defer submultiplicity constraints. Test: T20083.

    To determine whether a constraint arose from a submultiplicity check, we
    look at the CtOrigin. All calls to tcSubMult use one of two origins,
    UsageEnvironmentOf and NonLinearPatternOrigin. Those origins are not
    used outside of linear types.

    In the future, we should compile 'WpMultCoercion' to a runtime error with
    -fdefer-type-errors, but the current implementation does not always
    place the wrapper in the right place and the resulting program can fail Lint.
    This plan is tracked in #20083.

    Note [Deferred errors for coercion holes]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Suppose we need to defer a type error where the destination for the evidence
    is a coercion hole. We can't just put the error in the hole, because we can't
    make an erroneous coercion. (Remember that coercions are erased for runtime.)
    Instead, we invent a new EvVar, bind it to an error and then make a coercion
    from that EvVar, filling the hole with that coercion. Because coercions'
    types are unlifted, the error is guaranteed to be hit before we get to the
    coercion.

    ************************************************************************
    *                                                                      *
                    Irreducible predicate errors
    *                                                                      *
    ************************************************************************
    -}

    mkIrredErr :: SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkIrredErr :: SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkIrredErr SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    items
      = do { (ctxt, binds, item1) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item1
           ; let msg = SolverReportErrCtxt -> TcSolverReportMsg -> SolverReport
    important SolverReportErrCtxt
    ctxt (TcSolverReportMsg -> SolverReport)
    -> TcSolverReportMsg -> SolverReport
    forall a b. (a -> b) -> a -> b
    $ MismatchMsg -> TcSolverReportMsg
    mkPlainMismatchMsg (MismatchMsg -> TcSolverReportMsg)
    -> MismatchMsg -> TcSolverReportMsg
    forall a b. (a -> b) -> a -> b
    $
                       [Implication]
    -> NonEmpty ErrorItem -> Maybe CND_Extra -> MismatchMsg
    CouldNotDeduce (SolverReportErrCtxt -> [Implication]
    getUserGivens SolverReportErrCtxt
    ctxt) (ErrorItem
    item1 ErrorItem -> [ErrorItem] -> NonEmpty ErrorItem
    forall a. a -> [a] -> NonEmpty a
    :| [ErrorItem]
    others) Maybe CND_Extra
    forall a. Maybe a
    Nothing
           ; return $ add_relevant_bindings binds msg  }
      where
        ErrorItem
    item1:|[ErrorItem]
    others = (ErrorItem -> Bool) -> NonEmpty ErrorItem -> NonEmpty ErrorItem
    forall a. (a -> Bool) -> NonEmpty a -> NonEmpty a
    tryFilter (Bool -> Bool
    not (Bool -> Bool) -> (ErrorItem -> Bool) -> ErrorItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorItem -> Bool
    ei_suppress) NonEmpty ErrorItem
    items

    {- Note [Constructing Hole Errors]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Whether or not 'mkHoleError' returns an error is not influenced by cec_suppress. In other terms,
    these "hole" errors are /not/ suppressed by cec_suppress. We want to see them!

    There are two cases to consider:

    1. For out-of-scope variables we always report an error, unless -fdefer-out-of-scope-variables is on,
       in which case the messages are discarded. See also #12170 and #12406. If deferring, report a warning
       only if -Wout-of-scope-variables is on.

    2. For the general case, when -XPartialTypeSignatures is on, warnings (instead of errors) are generated
       for holes in partial type signatures, unless -Wpartial-type-signatures is not on, in which case
       the messages are discarded. If deferring, report a warning only if -Wtyped-holes is on.

    The above can be summarised into the following table:

    | Hole Type    | Active Flags                                             | Outcome          |
    |--------------|----------------------------------------------------------|------------------|
    | out-of-scope | None                                                     | Error            |
    | out-of-scope | -fdefer-out-of-scope-variables, -Wout-of-scope-variables | Warning          |
    | out-of-scope | -fdefer-out-of-scope-variables                           | Ignore (discard) |
    | type         | None                                                     | Error            |
    | type         | -XPartialTypeSignatures, -Wpartial-type-signatures       | Warning          |
    | type         | -XPartialTypeSignatures                                  | Ignore (discard) |
    | expression   | None                                                     | Error            |
    | expression   | -Wdefer-typed-holes, -Wtyped-holes                       | Warning          |
    | expression   | -Wdefer-typed-holes                                      | Ignore (discard) |

    See also 'reportUnsolved'.

    -}

    ----------------
    -- | Constructs a new hole error, unless this is deferred. See Note [Constructing Hole Errors].
    mkHoleError :: NameEnv Type -> [ErrorItem] -> SolverReportErrCtxt -> Hole -> TcM (MsgEnvelope TcRnMessage)
    mkHoleError :: NameEnv Type
    -> [ErrorItem]
    -> SolverReportErrCtxt
    -> Hole
    -> TcM (MsgEnvelope TcRnMessage)
    mkHoleError NameEnv Type
    _ [ErrorItem]
    _tidy_simples SolverReportErrCtxt
    ctxt hole :: Hole
    hole@(Hole { hole_occ :: Hole -> RdrName
    hole_occ = RdrName
    occ, hole_loc :: Hole -> CtLoc
    hole_loc = CtLoc
    ct_loc })
      | Hole -> Bool
    isOutOfScopeHole Hole
    hole
      = do { (imp_errs, hints)
               <- LocalRdrEnv
    -> WhatLooking -> RdrName -> RnM ([ImportError], [GhcHint])
    unknownNameSuggestions (CtLocEnv -> LocalRdrEnv
    ctl_rdr CtLocEnv
    lcl_env) WhatLooking
    WL_Anything RdrName
    occ
           ; let
                 err    = SolverReportErrCtxt -> TcSolverReportMsg -> SolverReportWithCtxt
    SolverReportWithCtxt SolverReportErrCtxt
    ctxt
                        (TcSolverReportMsg -> SolverReportWithCtxt)
    -> TcSolverReportMsg -> SolverReportWithCtxt
    forall a b. (a -> b) -> a -> b
    $ Hole -> HoleError -> TcSolverReportMsg
    ReportHoleError Hole
    hole
                        (HoleError -> TcSolverReportMsg) -> HoleError -> TcSolverReportMsg
    forall a b. (a -> b) -> a -> b
    $ [ImportError] -> [GhcHint] -> HoleError
    OutOfScopeHole [ImportError]
    imp_errs [GhcHint]
    hints
                 report = SolverReportWithCtxt -> [SolverReportSupplementary] -> SolverReport
    SolverReport SolverReportWithCtxt
    err []

           ; maybeAddDeferredBindings ctxt hole report
           ; mkErrorReport lcl_env (TcRnSolverReport err (cec_out_of_scope_holes ctxt))
               Nothing []
              -- Pass the value 'Nothing' for the context, as it's generally not helpful
              -- to include the context here.
           }
      where
        lcl_env :: CtLocEnv
    lcl_env = CtLoc -> CtLocEnv
    ctLocEnv CtLoc
    ct_loc

     -- general case: not an out-of-scope error
    mkHoleError NameEnv Type
    lcl_name_cache [ErrorItem]
    tidy_simples SolverReportErrCtxt
    ctxt
      hole :: Hole
    hole@(Hole { hole_ty :: Hole -> Type
    hole_ty = Type
    hole_ty
                 , hole_sort :: Hole -> HoleSort
    hole_sort = HoleSort
    sort
                 , hole_loc :: Hole -> CtLoc
    hole_loc = CtLoc
    ct_loc })
      = do { rel_binds
               <- Bool
    -> CtLocEnv -> NameEnv Type -> TyCoVarSet -> TcM RelevantBindings
    relevant_bindings Bool
    False CtLocEnv
    lcl_env NameEnv Type
    lcl_name_cache (Type -> TyCoVarSet
    tyCoVarsOfType Type
    hole_ty)
                   -- The 'False' means "don't filter the bindings"; see #8191

           ; show_hole_constraints <- goptM Opt_ShowHoleConstraints
           ; let relevant_cts
                   | ExprHole HoleExprRef
    _ <- HoleSort
    sort, Bool
    show_hole_constraints
                   = SolverReportErrCtxt -> [(Type, RealSrcSpan)]
    givenConstraints SolverReportErrCtxt
    ctxt
                   | Bool
    otherwise
                   = []

           ; show_valid_hole_fits <- goptM Opt_ShowValidHoleFits
           ; (ctxt, hole_fits) <- if show_valid_hole_fits
                                  then validHoleFits ctxt tidy_simples hole
                                  else return (ctxt, noValidHoleFits)
           ; (grouped_skvs, other_tvs) <- liftZonkM $ zonkAndGroupSkolTvs hole_ty
           ; let reason | ExprHole HoleExprRef
    _ <- HoleSort
    sort = SolverReportErrCtxt -> DiagnosticReason
    cec_expr_holes SolverReportErrCtxt
    ctxt
                        | Bool
    otherwise          = SolverReportErrCtxt -> DiagnosticReason
    cec_type_holes SolverReportErrCtxt
    ctxt
                 err  = SolverReportErrCtxt -> TcSolverReportMsg -> SolverReportWithCtxt
    SolverReportWithCtxt SolverReportErrCtxt
    ctxt
                      (TcSolverReportMsg -> SolverReportWithCtxt)
    -> TcSolverReportMsg -> SolverReportWithCtxt
    forall a b. (a -> b) -> a -> b
    $ Hole -> HoleError -> TcSolverReportMsg
    ReportHoleError Hole
    hole
                      (HoleError -> TcSolverReportMsg) -> HoleError -> TcSolverReportMsg
    forall a b. (a -> b) -> a -> b
    $ HoleSort -> [TcId] -> [(SkolemInfoAnon, [TcId])] -> HoleError
    HoleError HoleSort
    sort [TcId]
    other_tvs [(SkolemInfoAnon, [TcId])]
    grouped_skvs
                 supp = [ RelevantBindings -> SolverReportSupplementary
    SupplementaryBindings RelevantBindings
    rel_binds
                        , [(Type, RealSrcSpan)] -> SolverReportSupplementary
    SupplementaryCts      [(Type, RealSrcSpan)]
    relevant_cts
                        , ValidHoleFits -> SolverReportSupplementary
    SupplementaryHoleFits ValidHoleFits
    hole_fits ]

           ; maybeAddDeferredBindings ctxt hole (SolverReport err supp)

           ; mkErrorReport lcl_env (TcRnSolverReport err reason) (Just ctxt) supp
           }

      where
        lcl_env :: CtLocEnv
    lcl_env = CtLoc -> CtLocEnv
    ctLocEnv CtLoc
    ct_loc

    -- | For all the skolem type variables in a type, zonk the skolem info and group together
    -- all the type variables with the same origin.
    zonkAndGroupSkolTvs :: Type -> ZonkM ([(SkolemInfoAnon, [TcTyVar])], [TcTyVar])
    zonkAndGroupSkolTvs :: Type -> ZonkM ([(SkolemInfoAnon, [TcId])], [TcId])
    zonkAndGroupSkolTvs Type
    hole_ty = do
      zonked_info <- ((SkolemInfo, [(TcId, Int)]) -> ZonkM (SkolemInfoAnon, [TcId]))
    -> [(SkolemInfo, [(TcId, Int)])]
    -> ZonkM [(SkolemInfoAnon, [TcId])]
    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 (SkolemInfo, [(TcId, Int)]) -> ZonkM (SkolemInfoAnon, [TcId])
    forall {f :: * -> *} {b} {b}.
    Functor f =>
    (SkolemInfo, f (b, b)) -> ZonkM (SkolemInfoAnon, f b)
    zonk_skolem_info [(SkolemInfo, [(TcId, Int)])]
    skolem_list
      return (zonked_info, other_tvs)
      where
        zonk_skolem_info :: (SkolemInfo, f (b, b)) -> ZonkM (SkolemInfoAnon, f b)
    zonk_skolem_info (SkolemInfo
    sk, f (b, b)
    tv) =
          do { sk <- SkolemInfoAnon -> ZonkM SkolemInfoAnon
    zonkSkolemInfoAnon (SkolemInfoAnon -> ZonkM SkolemInfoAnon)
    -> SkolemInfoAnon -> ZonkM SkolemInfoAnon
    forall a b. (a -> b) -> a -> b
    $ SkolemInfo -> SkolemInfoAnon
    getSkolemInfo SkolemInfo
    sk
             ; return (sk, fst <$> tv) }
        tvs :: [TcId]
    tvs = Type -> [TcId]
    tyCoVarsOfTypeList Type
    hole_ty
        ([TcId]
    skol_tvs, [TcId]
    other_tvs) = (TcId -> Bool) -> [TcId] -> ([TcId], [TcId])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition (TcId -> Bool
    isTcTyVar (TcId -> Bool) -> (TcId -> Bool) -> TcId -> Bool
    forall (f :: * -> *). Applicative f => f Bool -> f Bool -> f Bool
    <&&> TcId -> Bool
    isSkolemTyVar) [TcId]
    tvs

        group_skolems :: UM.UniqMap SkolemInfo ([(TcTyVar, Int)])
        group_skolems :: UniqMap SkolemInfo [(TcId, Int)]
    group_skolems = Bag (TcId, Int) -> [(TcId, Int)]
    forall a. Bag a -> [a]
    bagToList (Bag (TcId, Int) -> [(TcId, Int)])
    -> UniqMap SkolemInfo (Bag (TcId, Int))
    -> UniqMap SkolemInfo [(TcId, Int)]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
          (Bag (TcId, Int) -> Bag (TcId, Int) -> Bag (TcId, Int))
    -> [(SkolemInfo, Bag (TcId, Int))]
    -> UniqMap SkolemInfo (Bag (TcId, Int))
    forall k a. Uniquable k => (a -> a -> a) -> [(k, a)] -> UniqMap k a
    UM.listToUniqMap_C Bag (TcId, Int) -> Bag (TcId, Int) -> Bag (TcId, Int)
    forall a. Bag a -> Bag a -> Bag a
    unionBags
            [(TcId -> SkolemInfo
    skolemSkolInfo TcId
    tv, (TcId, Int) -> Bag (TcId, Int)
    forall a. a -> Bag a
    unitBag (TcId
    tv, Int
    n)) | TcId
    tv <- [TcId]
    skol_tvs | Int
    n <- [Int
    0..]]

        skolem_list :: [(SkolemInfo, [(TcId, Int)])]
    skolem_list = ((SkolemInfo, [(TcId, Int)])
     -> (SkolemInfo, [(TcId, Int)]) -> Ordering)
    -> [(SkolemInfo, [(TcId, Int)])] -> [(SkolemInfo, [(TcId, Int)])]
    forall a. (a -> a -> Ordering) -> [a] -> [a]
    sortBy (((SkolemInfo, [(TcId, Int)]) -> [Int])
    -> (SkolemInfo, [(TcId, Int)])
    -> (SkolemInfo, [(TcId, Int)])
    -> Ordering
    forall a b. Ord a => (b -> a) -> b -> b -> Ordering
    comparing ([Int] -> [Int]
    forall a. Ord a => [a] -> [a]
    sort ([Int] -> [Int])
    -> ((SkolemInfo, [(TcId, Int)]) -> [Int])
    -> (SkolemInfo, [(TcId, Int)])
    -> [Int]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((TcId, Int) -> Int) -> [(TcId, Int)] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map (TcId, Int) -> Int
    forall a b. (a, b) -> b
    snd ([(TcId, Int)] -> [Int])
    -> ((SkolemInfo, [(TcId, Int)]) -> [(TcId, Int)])
    -> (SkolemInfo, [(TcId, Int)])
    -> [Int]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (SkolemInfo, [(TcId, Int)]) -> [(TcId, Int)]
    forall a b. (a, b) -> b
    snd))
                    ([(SkolemInfo, [(TcId, Int)])] -> [(SkolemInfo, [(TcId, Int)])])
    -> [(SkolemInfo, [(TcId, Int)])] -> [(SkolemInfo, [(TcId, Int)])]
    forall a b. (a -> b) -> a -> b
    $ UniqMap SkolemInfo [(TcId, Int)] -> [(SkolemInfo, [(TcId, Int)])]
    forall k a. UniqMap k a -> [(k, a)]
    UM.nonDetUniqMapToList UniqMap SkolemInfo [(TcId, Int)]
    group_skolems

    {- Note [Adding deferred bindings]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    When working with typed holes we have to deal with the case where
    we want holes to be reported as warnings to users during compile time but
    as errors during runtime. Therefore, we have to call 'maybeAddDeferredBindings'
    so that the correct 'Severity' can be computed out of that later on.
    -}

    -- | Adds deferred bindings (as errors).
    -- See Note [Adding deferred bindings].
    maybeAddDeferredBindings :: SolverReportErrCtxt
                             -> Hole
                             -> SolverReport
                             -> TcM ()
    maybeAddDeferredBindings :: SolverReportErrCtxt -> Hole -> SolverReport -> TcM ()
    maybeAddDeferredBindings SolverReportErrCtxt
    ctxt Hole
    hole SolverReport
    report = do
      case Hole -> HoleSort
    hole_sort Hole
    hole of
        ExprHole (HER IORef EvTerm
    ref Type
    ref_ty Unique
    _) -> do
          -- Only add bindings for holes in expressions
          -- not for holes in partial type signatures
          -- cf. addDeferredBinding
          Bool -> TcM () -> TcM ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (SolverReportErrCtxt -> Bool
    deferringAnyBindings SolverReportErrCtxt
    ctxt) (TcM () -> TcM ()) -> TcM () -> TcM ()
    forall a b. (a -> b) -> a -> b
    $ do
            err_tm <- SolverReportErrCtxt -> CtLoc -> Type -> SolverReport -> TcM EvTerm
    mkErrorTerm SolverReportErrCtxt
    ctxt (Hole -> CtLoc
    hole_loc Hole
    hole) Type
    ref_ty SolverReport
    report
              -- NB: ref_ty, not hole_ty. hole_ty might be rewritten.
              -- See Note [Holes] in GHC.Tc.Types.Constraint
            writeMutVar ref err_tm
        HoleSort
    _ -> () -> TcM ()
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()

    -- We unwrap the SolverReportErrCtxt here, to avoid introducing a loop in module
    -- imports
    validHoleFits :: SolverReportErrCtxt    -- ^ The context we're in, i.e. the
                                            -- implications and the tidy environment
                  -> [ErrorItem]      -- ^ Unsolved simple constraints
                  -> Hole             -- ^ The hole
                  -> TcM (SolverReportErrCtxt, ValidHoleFits)
                    -- ^ We return the new context
                    -- with a possibly updated
                    -- tidy environment, and
                    -- the valid hole fits.
    validHoleFits :: SolverReportErrCtxt
    -> [ErrorItem] -> Hole -> TcM (SolverReportErrCtxt, ValidHoleFits)
    validHoleFits ctxt :: SolverReportErrCtxt
    ctxt@(CEC { cec_encl :: SolverReportErrCtxt -> [Implication]
    cec_encl = [Implication]
    implics
                            , cec_tidy :: SolverReportErrCtxt -> TidyEnv
    cec_tidy = TidyEnv
    lcl_env}) [ErrorItem]
    simps Hole
    hole
      = do { (tidy_env, fits) <- TidyEnv
    -> [Implication]
    -> [CtEvidence]
    -> Hole
    -> TcM (TidyEnv, ValidHoleFits)
    findValidHoleFits TidyEnv
    lcl_env [Implication]
    implics ((ErrorItem -> Maybe CtEvidence) -> [ErrorItem] -> [CtEvidence]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe ErrorItem -> Maybe CtEvidence
    mk_wanted [ErrorItem]
    simps) Hole
    hole
           ; return (ctxt {cec_tidy = tidy_env}, fits) }
      where
        mk_wanted :: ErrorItem -> Maybe CtEvidence
        mk_wanted :: ErrorItem -> Maybe CtEvidence
    mk_wanted (EI { ei_pred :: ErrorItem -> Type
    ei_pred = Type
    pred, ei_evdest :: ErrorItem -> Maybe TcEvDest
    ei_evdest = Maybe TcEvDest
    m_dest, ei_loc :: ErrorItem -> CtLoc
    ei_loc = CtLoc
    loc })
          | Just TcEvDest
    dest <- Maybe TcEvDest
    m_dest
          = CtEvidence -> Maybe CtEvidence
    forall a. a -> Maybe a
    Just (CtWanted { ctev_pred :: Type
    ctev_pred      = Type
    pred
                           , ctev_dest :: TcEvDest
    ctev_dest      = TcEvDest
    dest
                           , ctev_loc :: CtLoc
    ctev_loc       = CtLoc
    loc
                           , ctev_rewriters :: RewriterSet
    ctev_rewriters = RewriterSet
    emptyRewriterSet })
          | Bool
    otherwise
          = Maybe CtEvidence
    forall a. Maybe a
    Nothing   -- The ErrorItem was a Given

    -- See Note [Constraints include ...]
    givenConstraints :: SolverReportErrCtxt -> [(Type, RealSrcSpan)]
    givenConstraints :: SolverReportErrCtxt -> [(Type, RealSrcSpan)]
    givenConstraints SolverReportErrCtxt
    ctxt
      = do { implic@Implic{ ic_given = given } <- SolverReportErrCtxt -> [Implication]
    cec_encl SolverReportErrCtxt
    ctxt
           ; constraint <- given
           ; return (varType constraint, getCtLocEnvLoc (ic_env implic)) }

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

    mkIPErr :: SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    -- What would happen if an item is suppressed because of
    -- Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint? Very unclear
    -- what's best. Let's not worry about this.
    mkIPErr :: SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkIPErr SolverReportErrCtxt
    ctxt (ErrorItem
    item1:|[ErrorItem]
    others)
      = do { (ctxt, binds, item1) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item1
           ; let msg = SolverReportErrCtxt -> TcSolverReportMsg -> SolverReport
    important SolverReportErrCtxt
    ctxt (TcSolverReportMsg -> SolverReport)
    -> TcSolverReportMsg -> SolverReport
    forall a b. (a -> b) -> a -> b
    $ NonEmpty ErrorItem -> TcSolverReportMsg
    UnboundImplicitParams (ErrorItem
    item1 ErrorItem -> [ErrorItem] -> NonEmpty ErrorItem
    forall a. a -> [a] -> NonEmpty a
    :| [ErrorItem]
    others)
           ; return $ add_relevant_bindings binds msg }

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

    -- | Report a representation-polymorphism error to the user:
    -- a type is required to have a fixed runtime representation,
    -- but doesn't.
    --
    -- See Note [Reporting representation-polymorphism errors] in GHC.Tc.Types.Origin.
    mkFRRErr :: HasDebugCallStack => SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkFRRErr :: HasDebugCallStack =>
    SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkFRRErr SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    items
      = do { -- Process the error items.
           ; (_tidy_env, frr_infos) <-
              ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo])
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    forall a. ZonkM a -> TcM a
    liftZonkM (ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo])
     -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo]))
    -> ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo])
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    forall a b. (a -> b) -> a -> b
    $ TidyEnv
    -> [FixedRuntimeRepErrorInfo]
    -> ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo])
    zonkTidyFRRInfos (SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt) ([FixedRuntimeRepErrorInfo]
     -> ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo]))
    -> [FixedRuntimeRepErrorInfo]
    -> ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo])
    forall a b. (a -> b) -> a -> b
    $
                -- Zonk/tidy to show useful variable names.
              (FixedRuntimeRepErrorInfo -> FixedRuntimeRepErrorInfo -> Ordering)
    -> [FixedRuntimeRepErrorInfo] -> [FixedRuntimeRepErrorInfo]
    forall a. (a -> a -> Ordering) -> [a] -> [a]
    nubOrdBy (Type -> Type -> Ordering
    nonDetCmpType (Type -> Type -> Ordering)
    -> (FixedRuntimeRepErrorInfo -> Type)
    -> FixedRuntimeRepErrorInfo
    -> FixedRuntimeRepErrorInfo
    -> Ordering
    forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
    `on` (FixedRuntimeRepOrigin -> Type
    frr_type (FixedRuntimeRepOrigin -> Type)
    -> (FixedRuntimeRepErrorInfo -> FixedRuntimeRepOrigin)
    -> FixedRuntimeRepErrorInfo
    -> Type
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FixedRuntimeRepErrorInfo -> FixedRuntimeRepOrigin
    frr_info_origin)) ([FixedRuntimeRepErrorInfo] -> [FixedRuntimeRepErrorInfo])
    -> [FixedRuntimeRepErrorInfo] -> [FixedRuntimeRepErrorInfo]
    forall a b. (a -> b) -> a -> b
    $
                -- Remove duplicates: only one representation-polymorphism error per type.
              (ErrorItem -> FixedRuntimeRepErrorInfo)
    -> [ErrorItem] -> [FixedRuntimeRepErrorInfo]
    forall a b. (a -> b) -> [a] -> [b]
    map (String
    -> Maybe FixedRuntimeRepErrorInfo -> FixedRuntimeRepErrorInfo
    forall a. HasCallStack => String -> Maybe a -> a
    expectJust String
    "mkFRRErr" (Maybe FixedRuntimeRepErrorInfo -> FixedRuntimeRepErrorInfo)
    -> (ErrorItem -> Maybe FixedRuntimeRepErrorInfo)
    -> ErrorItem
    -> FixedRuntimeRepErrorInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HasDebugCallStack => ErrorItem -> Maybe FixedRuntimeRepErrorInfo
    ErrorItem -> Maybe FixedRuntimeRepErrorInfo
    fixedRuntimeRepOrigin_maybe) ([ErrorItem] -> [FixedRuntimeRepErrorInfo])
    -> [ErrorItem] -> [FixedRuntimeRepErrorInfo]
    forall a b. (a -> b) -> a -> b
    $
              NonEmpty ErrorItem -> [ErrorItem]
    forall a. NonEmpty a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList NonEmpty ErrorItem
    items
           ; return $ important ctxt $ FixedRuntimeRepError frr_infos }

    -- | Whether to report something using the @FixedRuntimeRep@ mechanism.
    fixedRuntimeRepOrigin_maybe :: HasDebugCallStack => ErrorItem -> Maybe FixedRuntimeRepErrorInfo
    fixedRuntimeRepOrigin_maybe :: HasDebugCallStack => ErrorItem -> Maybe FixedRuntimeRepErrorInfo
    fixedRuntimeRepOrigin_maybe ErrorItem
    item
      -- An error that arose directly from a representation-polymorphism check.
      | FRROrigin FixedRuntimeRepOrigin
    frr_orig <- ErrorItem -> CtOrigin
    errorItemOrigin ErrorItem
    item
      = FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a. a -> Maybe a
    Just (FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo)
    -> FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a b. (a -> b) -> a -> b
    $ FRR_Info { frr_info_origin :: FixedRuntimeRepOrigin
    frr_info_origin = FixedRuntimeRepOrigin
    frr_orig
                        , frr_info_not_concrete :: Maybe (TcId, Type)
    frr_info_not_concrete = Maybe (TcId, Type)
    forall a. Maybe a
    Nothing }
      -- A nominal equality involving a concrete type variable,
      -- such as @alpha[conc] ~# rr[sk]@ or @beta[conc] ~# RR@ for a
      -- type family application @RR@.
      | EqPred EqRel
    NomEq Type
    ty1 Type
    ty2 <- Type -> Pred
    classifyPredType (ErrorItem -> Type
    errorItemPred ErrorItem
    item)
      = if | Just (TcId
    tv1, ConcreteFRR FixedRuntimeRepOrigin
    frr1) <- Type -> Maybe (TcId, ConcreteTvOrigin)
    isConcreteTyVarTy_maybe Type
    ty1
           -> FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a. a -> Maybe a
    Just (FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo)
    -> FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a b. (a -> b) -> a -> b
    $ FixedRuntimeRepOrigin
    -> Maybe (TcId, Type) -> FixedRuntimeRepErrorInfo
    FRR_Info FixedRuntimeRepOrigin
    frr1 ((TcId, Type) -> Maybe (TcId, Type)
    forall a. a -> Maybe a
    Just (TcId
    tv1, Type
    ty2))
           | Just (TcId
    tv2, ConcreteFRR FixedRuntimeRepOrigin
    frr2) <- Type -> Maybe (TcId, ConcreteTvOrigin)
    isConcreteTyVarTy_maybe Type
    ty2
           -> FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a. a -> Maybe a
    Just (FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo)
    -> FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a b. (a -> b) -> a -> b
    $ FixedRuntimeRepOrigin
    -> Maybe (TcId, Type) -> FixedRuntimeRepErrorInfo
    FRR_Info FixedRuntimeRepOrigin
    frr2 ((TcId, Type) -> Maybe (TcId, Type)
    forall a. a -> Maybe a
    Just (TcId
    tv2, Type
    ty1))
           | Bool
    otherwise
           -> Maybe FixedRuntimeRepErrorInfo
    forall a. Maybe a
    Nothing
      | Bool
    otherwise
      = Maybe FixedRuntimeRepErrorInfo
    forall a. Maybe a
    Nothing

    {-
    Note [Constraints include ...]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    'givenConstraintsMsg' returns the "Constraints include ..." message enabled by
    -fshow-hole-constraints. For example, the following hole:

        foo :: (Eq a, Show a) => a -> String
        foo x = _

    would generate the message:

        Constraints include
          Eq a (from foo.hs:1:1-36)
          Show a (from foo.hs:1:1-36)

    Constraints are displayed in order from innermost (closest to the hole) to
    outermost. There's currently no filtering or elimination of duplicates.

    ************************************************************************
    *                                                                      *
                    Equality errors
    *                                                                      *
    ************************************************************************

    Note [Inaccessible code]
    ~~~~~~~~~~~~~~~~~~~~~~~~
    Consider
       data T a where
         T1 :: T a
         T2 :: T Bool

       f :: (a ~ Int) => T a -> Int
       f T1 = 3
       f T2 = 4   -- Unreachable code

    Here the second equation is unreachable. The original constraint
    (a~Int) from the signature gets rewritten by the pattern-match to
    (Bool~Int), so the danger is that we report the error as coming from
    the *signature* (#7293).  So, for Given errors we replace the
    env (and hence src-loc) on its CtLoc with that from the immediately
    enclosing implication.

    Note [Error messages for untouchables]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider (#9109)
      data G a where { GBool :: G Bool }
      foo x = case x of GBool -> True

    Here we can't solve (t ~ Bool), where t is the untouchable result
    meta-var 't', because of the (a ~ Bool) from the pattern match.
    So we infer the type
       f :: forall a t. G a -> t
    making the meta-var 't' into a skolem.  So when we come to report
    the unsolved (t ~ Bool), t won't look like an untouchable meta-var
    any more.  So we don't assert that it is.
    -}

    -- Don't have multiple equality errors from the same location
    -- E.g.   (Int,Bool) ~ (Bool,Int)   one error will do!
    mkEqErr :: SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkEqErr :: SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkEqErr SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    items
      | ErrorItem
    item1 :| [ErrorItem]
    _ <- (ErrorItem -> Bool) -> NonEmpty ErrorItem -> NonEmpty ErrorItem
    forall a. (a -> Bool) -> NonEmpty a -> NonEmpty a
    tryFilter (Bool -> Bool
    not (Bool -> Bool) -> (ErrorItem -> Bool) -> ErrorItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorItem -> Bool
    ei_suppress) NonEmpty ErrorItem
    items
      = SolverReportErrCtxt -> ErrorItem -> TcM SolverReport
    mkEqErr1 SolverReportErrCtxt
    ctxt ErrorItem
    item1

    mkEqErr1 :: SolverReportErrCtxt -> ErrorItem -> TcM SolverReport
    mkEqErr1 :: SolverReportErrCtxt -> ErrorItem -> TcM SolverReport
    mkEqErr1 SolverReportErrCtxt
    ctxt ErrorItem
    item   -- Wanted only
                         -- givens handled in mkGivenErrorReporter
      = do { (ctxt, binds, item) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item
           ; traceTc "mkEqErr1" (ppr item $$ pprCtOrigin (errorItemOrigin item))
           ; err_msg <- mkEqErr_help ctxt item ty1 ty2
           ; let
               report = RelevantBindings -> SolverReport -> SolverReport
    add_relevant_bindings RelevantBindings
    binds
                      (SolverReport -> SolverReport) -> SolverReport -> SolverReport
    forall a b. (a -> b) -> a -> b
    $ SolverReportErrCtxt -> TcSolverReportMsg -> SolverReport
    important SolverReportErrCtxt
    ctxt TcSolverReportMsg
    err_msg
           ; return report }
      where
        (Type
    ty1, Type
    ty2) = Type -> (Type, Type)
    getEqPredTys (ErrorItem -> Type
    errorItemPred ErrorItem
    item)

    -- | This function tries to reconstruct why a "Coercible ty1 ty2" constraint
    -- is left over.
    mkCoercibleExplanation :: GlobalRdrEnv -> FamInstEnvs
                           -> TcType -> TcType -> Maybe CoercibleMsg
    mkCoercibleExplanation :: GlobalRdrEnv -> FamInstEnvs -> Type -> Type -> Maybe CoercibleMsg
    mkCoercibleExplanation GlobalRdrEnv
    rdr_env FamInstEnvs
    fam_envs Type
    ty1 Type
    ty2
      | Just (TyCon
    tc, [Type]
    tys) <- HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe Type
    ty1
      , (TyCon
    rep_tc, [Type]
    _, TcCoercionN
    _) <- FamInstEnvs -> TyCon -> [Type] -> (TyCon, [Type], TcCoercionN)
    tcLookupDataFamInst FamInstEnvs
    fam_envs TyCon
    tc [Type]
    tys
      , Just CoercibleMsg
    msg <- TyCon -> Maybe CoercibleMsg
    coercible_msg_for_tycon TyCon
    rep_tc
      = CoercibleMsg -> Maybe CoercibleMsg
    forall a. a -> Maybe a
    Just CoercibleMsg
    msg
      | Just (TyCon
    tc, [Type]
    tys) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    splitTyConApp_maybe Type
    ty2
      , (TyCon
    rep_tc, [Type]
    _, TcCoercionN
    _) <- FamInstEnvs -> TyCon -> [Type] -> (TyCon, [Type], TcCoercionN)
    tcLookupDataFamInst FamInstEnvs
    fam_envs TyCon
    tc [Type]
    tys
      , Just CoercibleMsg
    msg <- TyCon -> Maybe CoercibleMsg
    coercible_msg_for_tycon TyCon
    rep_tc
      = CoercibleMsg -> Maybe CoercibleMsg
    forall a. a -> Maybe a
    Just CoercibleMsg
    msg
      | Just (Type
    s1, Type
    _) <- Type -> Maybe (Type, Type)
    tcSplitAppTy_maybe Type
    ty1
      , Just (Type
    s2, Type
    _) <- Type -> Maybe (Type, Type)
    tcSplitAppTy_maybe Type
    ty2
      , Type
    s1 Type -> Type -> Bool
    `eqType` Type
    s2
      , Type -> Bool
    has_unknown_roles Type
    s1
      = CoercibleMsg -> Maybe CoercibleMsg
    forall a. a -> Maybe a
    Just (CoercibleMsg -> Maybe CoercibleMsg)
    -> CoercibleMsg -> Maybe CoercibleMsg
    forall a b. (a -> b) -> a -> b
    $ Type -> CoercibleMsg
    UnknownRoles Type
    s1
      | Bool
    otherwise
      = Maybe CoercibleMsg
    forall a. Maybe a
    Nothing
      where
        coercible_msg_for_tycon :: TyCon -> Maybe CoercibleMsg
    coercible_msg_for_tycon TyCon
    tc
            | TyCon -> Bool
    isAbstractTyCon TyCon
    tc
            = CoercibleMsg -> Maybe CoercibleMsg
    forall a. a -> Maybe a
    Just (CoercibleMsg -> Maybe CoercibleMsg)
    -> CoercibleMsg -> Maybe CoercibleMsg
    forall a b. (a -> b) -> a -> b
    $ TyCon -> CoercibleMsg
    TyConIsAbstract TyCon
    tc
            | TyCon -> Bool
    isNewTyCon TyCon
    tc
            , [DataCon
    data_con] <- TyCon -> [DataCon]
    tyConDataCons TyCon
    tc
            , let dc_name :: Name
    dc_name = DataCon -> Name
    dataConName DataCon
    data_con
            , Maybe (GlobalRdrEltX GREInfo) -> Bool
    forall a. Maybe a -> Bool
    isNothing (GlobalRdrEnv -> Name -> Maybe (GlobalRdrEltX GREInfo)
    forall info.
    Outputable info =>
    GlobalRdrEnvX info -> Name -> Maybe (GlobalRdrEltX info)
    lookupGRE_Name GlobalRdrEnv
    rdr_env Name
    dc_name)
            = CoercibleMsg -> Maybe CoercibleMsg
    forall a. a -> Maybe a
    Just (CoercibleMsg -> Maybe CoercibleMsg)
    -> CoercibleMsg -> Maybe CoercibleMsg
    forall a b. (a -> b) -> a -> b
    $ TyCon -> DataCon -> CoercibleMsg
    OutOfScopeNewtypeConstructor TyCon
    tc DataCon
    data_con
            | Bool
    otherwise = Maybe CoercibleMsg
    forall a. Maybe a
    Nothing

        has_unknown_roles :: Type -> Bool
    has_unknown_roles Type
    ty
          | Just (TyCon
    tc, [Type]
    tys) <- HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe Type
    ty
          = [Type]
    tys [Type] -> Int -> Bool
    forall a. [a] -> Int -> Bool
    `lengthAtLeast` TyCon -> Int
    tyConArity TyCon
    tc  -- oversaturated tycon
          | Just (Type
    s, Type
    _) <- Type -> Maybe (Type, Type)
    tcSplitAppTy_maybe Type
    ty
          = Type -> Bool
    has_unknown_roles Type
    s
          | Type -> Bool
    isTyVarTy Type
    ty
          = Bool
    True
          | Bool
    otherwise
          = Bool
    False

    mkEqErr_help :: SolverReportErrCtxt
                 -> ErrorItem
                 -> TcType -> TcType -> TcM TcSolverReportMsg
    mkEqErr_help :: SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM TcSolverReportMsg
    mkEqErr_help SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
      | Just (TcId, TcCoercionN)
    casted_tv1 <- Type -> Maybe (TcId, TcCoercionN)
    getCastedTyVar_maybe Type
    ty1
      = SolverReportErrCtxt
    -> ErrorItem
    -> (TcId, TcCoercionN)
    -> Type
    -> TcM TcSolverReportMsg
    mkTyVarEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId, TcCoercionN)
    casted_tv1 Type
    ty2

      -- ToDo: explain..  Cf T2627b   Dual (Dual a) ~ a
      | Just (TcId, TcCoercionN)
    casted_tv2 <- Type -> Maybe (TcId, TcCoercionN)
    getCastedTyVar_maybe Type
    ty2
      = SolverReportErrCtxt
    -> ErrorItem
    -> (TcId, TcCoercionN)
    -> Type
    -> TcM TcSolverReportMsg
    mkTyVarEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId, TcCoercionN)
    casted_tv2 Type
    ty1

      | Bool
    otherwise
      = SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM TcSolverReportMsg
    reportEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2

    reportEqErr :: SolverReportErrCtxt
                -> ErrorItem
                -> TcType -> TcType
                -> TcM TcSolverReportMsg
    reportEqErr :: SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM TcSolverReportMsg
    reportEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
      = do
        mb_coercible_info <- if ErrorItem -> EqRel
    errorItemEqRel ErrorItem
    item EqRel -> EqRel -> Bool
    forall a. Eq a => a -> a -> Bool
    == EqRel
    ReprEq
                             then Type -> Type -> TcM (Maybe CoercibleMsg)
    coercible_msg Type
    ty1 Type
    ty2
                             else Maybe CoercibleMsg -> TcM (Maybe CoercibleMsg)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe CoercibleMsg
    forall a. Maybe a
    Nothing
        tv_info <- case getTyVar_maybe ty2 of
                     Maybe TcId
    Nothing  -> Maybe TyVarInfo -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TyVarInfo)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe TyVarInfo
    forall a. Maybe a
    Nothing
                     Just TcId
    tv2 -> TyVarInfo -> Maybe TyVarInfo
    forall a. a -> Maybe a
    Just (TyVarInfo -> Maybe TyVarInfo)
    -> IOEnv (Env TcGblEnv TcLclEnv) TyVarInfo
    -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TyVarInfo)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (TcId, Maybe Implication)
    -> Type -> IOEnv (Env TcGblEnv TcLclEnv) TyVarInfo
    extraTyVarEqInfo (TcId
    tv2, Maybe Implication
    forall a. Maybe a
    Nothing) Type
    ty1
        return $ Mismatch { mismatchMsg           = mismatch
                          , mismatchTyVarInfo     = tv_info
                          , mismatchAmbiguityInfo = eqInfos
                          , mismatchCoercibleInfo = mb_coercible_info }
      where
        mismatch :: MismatchMsg
    mismatch = SolverReportErrCtxt -> ErrorItem -> Type -> Type -> MismatchMsg
    misMatchOrCND SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
        eqInfos :: [AmbiguityInfo]
    eqInfos  = Type -> Type -> [AmbiguityInfo]
    eqInfoMsgs Type
    ty1 Type
    ty2

    coercible_msg :: TcType -> TcType -> TcM (Maybe CoercibleMsg)
    coercible_msg :: Type -> Type -> TcM (Maybe CoercibleMsg)
    coercible_msg Type
    ty1 Type
    ty2
      = do
        rdr_env  <- TcRn GlobalRdrEnv
    getGlobalRdrEnv
        fam_envs <- tcGetFamInstEnvs
        return $ mkCoercibleExplanation rdr_env fam_envs ty1 ty2

    mkTyVarEqErr :: SolverReportErrCtxt -> ErrorItem
                 -> (TcTyVar, TcCoercionN) -> TcType -> TcM TcSolverReportMsg
    -- tv1 and ty2 are already tidied
    mkTyVarEqErr :: SolverReportErrCtxt
    -> ErrorItem
    -> (TcId, TcCoercionN)
    -> Type
    -> TcM TcSolverReportMsg
    mkTyVarEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId, TcCoercionN)
    casted_tv1 Type
    ty2
      = do { String -> SDoc -> TcM ()
    traceTc String
    "mkTyVarEqErr" (ErrorItem -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ErrorItem
    item SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ (TcId, TcCoercionN) -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (TcId, TcCoercionN)
    casted_tv1 SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Type -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Type
    ty2)
           ; SolverReportErrCtxt
    -> ErrorItem
    -> (TcId, TcCoercionN)
    -> Type
    -> TcM TcSolverReportMsg
    mkTyVarEqErr' SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId, TcCoercionN)
    casted_tv1 Type
    ty2 }

    mkTyVarEqErr' :: SolverReportErrCtxt -> ErrorItem
                  -> (TcTyVar, TcCoercionN) -> TcType -> TcM TcSolverReportMsg
    mkTyVarEqErr' :: SolverReportErrCtxt
    -> ErrorItem
    -> (TcId, TcCoercionN)
    -> Type
    -> TcM TcSolverReportMsg
    mkTyVarEqErr' SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId
    tv1, TcCoercionN
    co1) Type
    ty2

      -- Is this a representation-polymorphism error, e.g.
      -- alpha[conc] ~# rr[sk] ? If so, handle that first.
      | Just FixedRuntimeRepErrorInfo
    frr_info <- Maybe FixedRuntimeRepErrorInfo
    mb_concrete_reason
      = do
          (_, infos) <- ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo])
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    forall a. ZonkM a -> TcM a
    liftZonkM (ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo])
     -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo]))
    -> ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo])
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    forall a b. (a -> b) -> a -> b
    $ TidyEnv
    -> [FixedRuntimeRepErrorInfo]
    -> ZonkM (TidyEnv, [FixedRuntimeRepErrorInfo])
    zonkTidyFRRInfos (SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt) [FixedRuntimeRepErrorInfo
    frr_info]
          return $ FixedRuntimeRepError infos

      -- Impredicativity is a simple error to understand;
      -- try it before anything more complicated.
      | CheckTyEqResult
    check_eq_result CheckTyEqResult -> CheckTyEqProblem -> Bool
    `cterHasProblem` CheckTyEqProblem
    cteImpredicative
      = do
        tyvar_eq_info <- (TcId, Maybe Implication)
    -> Type -> IOEnv (Env TcGblEnv TcLclEnv) TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Maybe Implication
    forall a. Maybe a
    Nothing) Type
    ty2
        let
            poly_msg = ErrorItem
    -> TcId -> Type -> Maybe TyVarInfo -> CannotUnifyVariableReason
    CannotUnifyWithPolytype ErrorItem
    item TcId
    tv1 Type
    ty2 Maybe TyVarInfo
    mb_tv_info
            mb_tv_info
              | TcId -> Bool
    isSkolemTyVar TcId
    tv1
              = TyVarInfo -> Maybe TyVarInfo
    forall a. a -> Maybe a
    Just TyVarInfo
    tyvar_eq_info
              | Bool
    otherwise
              = Maybe TyVarInfo
    forall a. Maybe a
    Nothing
            main_msg =
              CannotUnifyVariable
                { mismatchMsg :: MismatchMsg
    mismatchMsg       = MismatchMsg
    headline_msg
                , cannotUnifyReason :: CannotUnifyVariableReason
    cannotUnifyReason = CannotUnifyVariableReason
    poly_msg }
            -- Unlike the other reports, this discards the old 'report_important'
            -- instead of augmenting it.  This is because the details are not likely
            -- to be helpful since this is just an unimplemented feature.
        return main_msg

      -- Incompatible kinds
      -- This is wrinkle (EIK2) in Note [Equalities with incompatible kinds]
      -- in GHC.Tc.Solver.Equality
      | TcCoercionN -> Bool
    hasCoercionHoleCo TcCoercionN
    co1 Bool -> Bool -> Bool
    || Type -> Bool
    hasCoercionHoleTy Type
    ty2
      = TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg -> TcM TcSolverReportMsg)
    -> TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a b. (a -> b) -> a -> b
    $ ErrorItem -> TcSolverReportMsg
    mkBlockedEqErr ErrorItem
    item

      | TcId -> Bool
    isSkolemTyVar TcId
    tv1  -- ty2 won't be a meta-tyvar; we would have
                           -- swapped in Solver.Equality.canEqTyVarHomo
        Bool -> Bool -> Bool
    || TcId -> Bool
    isTyVarTyVar TcId
    tv1 Bool -> Bool -> Bool
    && Bool -> Bool
    not (Type -> Bool
    isTyVarTy Type
    ty2)
        Bool -> Bool -> Bool
    || ErrorItem -> EqRel
    errorItemEqRel ErrorItem
    item EqRel -> EqRel -> Bool
    forall a. Eq a => a -> a -> Bool
    == EqRel
    ReprEq
         -- The cases below don't really apply to ReprEq (except occurs check)
      = do
        tv_extra <- (TcId, Maybe Implication)
    -> Type -> IOEnv (Env TcGblEnv TcLclEnv) TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Maybe Implication
    forall a. Maybe a
    Nothing) Type
    ty2
        reason <- if errorItemEqRel item == ReprEq
                  then RepresentationalEq tv_extra <$> coercible_msg ty1 ty2
                  else return $ DifferentTyVars tv_extra
        let main_msg = CannotUnifyVariable
                         { mismatchMsg :: MismatchMsg
    mismatchMsg       = MismatchMsg
    headline_msg
                         , cannotUnifyReason :: CannotUnifyVariableReason
    cannotUnifyReason = CannotUnifyVariableReason
    reason }
        return main_msg

      | TcId
    tv1 TcId -> TyCoVarSet -> Bool
    `elemVarSet` Type -> TyCoVarSet
    tyCoVarsOfType Type
    ty2
        -- We report an "occurs check" even for  a ~ F t a, where F is a type
        -- function; it's not insoluble (because in principle F could reduce)
        -- but we have certainly been unable to solve it
        --
        -- Use tyCoVarsOfType because it might have begun as the canonical
        -- constraint (Dual (Dual a)) ~ a, and been swizzled by mkEqnErr_help
      = let ambiguity_infos :: [AmbiguityInfo]
    ambiguity_infos = Type -> Type -> [AmbiguityInfo]
    eqInfoMsgs Type
    ty1 Type
    ty2

            interesting_tyvars :: [TcId]
    interesting_tyvars = (TcId -> Bool) -> [TcId] -> [TcId]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (TcId -> Bool) -> TcId -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Type -> Bool
    noFreeVarsOfType (Type -> Bool) -> (TcId -> Type) -> TcId -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TcId -> Type
    tyVarKind) ([TcId] -> [TcId]) -> [TcId] -> [TcId]
    forall a b. (a -> b) -> a -> b
    $
                                 (TcId -> Bool) -> [TcId] -> [TcId]
    forall a. (a -> Bool) -> [a] -> [a]
    filter TcId -> Bool
    isTyVar ([TcId] -> [TcId]) -> [TcId] -> [TcId]
    forall a b. (a -> b) -> a -> b
    $
                                 FV -> [TcId]
    fvVarList (FV -> [TcId]) -> FV -> [TcId]
    forall a b. (a -> b) -> a -> b
    $
                                 Type -> FV
    tyCoFVsOfType Type
    ty1 FV -> FV -> FV
    `unionFV` Type -> FV
    tyCoFVsOfType Type
    ty2

            occurs_err :: CannotUnifyVariableReason
    occurs_err =
              OccursCheck
                { occursCheckInterestingTyVars :: [TcId]
    occursCheckInterestingTyVars = [TcId]
    interesting_tyvars
                , occursCheckAmbiguityInfos :: [AmbiguityInfo]
    occursCheckAmbiguityInfos    = [AmbiguityInfo]
    ambiguity_infos }
            main_msg :: TcSolverReportMsg
    main_msg =
              CannotUnifyVariable
                { mismatchMsg :: MismatchMsg
    mismatchMsg       = MismatchMsg
    headline_msg
                , cannotUnifyReason :: CannotUnifyVariableReason
    cannotUnifyReason = CannotUnifyVariableReason
    occurs_err }

        in TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TcSolverReportMsg
    main_msg

      -- If the immediately-enclosing implication has 'tv' a skolem, and
      -- we know by now its an InferSkol kind of skolem, then presumably
      -- it started life as a TyVarTv, else it'd have been unified, given
      -- that there's no occurs-check or forall problem
      | (Implication
    implic:[Implication]
    _) <- SolverReportErrCtxt -> [Implication]
    cec_encl SolverReportErrCtxt
    ctxt
      , Implic { ic_skols :: Implication -> [TcId]
    ic_skols = [TcId]
    skols } <- Implication
    implic
      , TcId
    tv1 TcId -> [TcId] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [TcId]
    skols
      = do
        tv_extra <- (TcId, Maybe Implication)
    -> Type -> IOEnv (Env TcGblEnv TcLclEnv) TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Maybe Implication
    forall a. Maybe a
    Nothing) Type
    ty2
        let msg = Mismatch
                   { mismatchMsg :: MismatchMsg
    mismatchMsg           = MismatchMsg
    mismatch_msg
                   , mismatchTyVarInfo :: Maybe TyVarInfo
    mismatchTyVarInfo     = TyVarInfo -> Maybe TyVarInfo
    forall a. a -> Maybe a
    Just TyVarInfo
    tv_extra
                   , mismatchAmbiguityInfo :: [AmbiguityInfo]
    mismatchAmbiguityInfo = []
                   , mismatchCoercibleInfo :: Maybe CoercibleMsg
    mismatchCoercibleInfo = Maybe CoercibleMsg
    forall a. Maybe a
    Nothing }
        return msg

      -- Check for skolem escape
      | (Implication
    implic:[Implication]
    _) <- SolverReportErrCtxt -> [Implication]
    cec_encl SolverReportErrCtxt
    ctxt   -- Get the innermost context
      , Implic { ic_skols :: Implication -> [TcId]
    ic_skols = [TcId]
    skols } <- Implication
    implic
      , let esc_skols :: [TcId]
    esc_skols = (TcId -> Bool) -> [TcId] -> [TcId]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (TcId -> TyCoVarSet -> Bool
    `elemVarSet` (Type -> TyCoVarSet
    tyCoVarsOfType Type
    ty2)) [TcId]
    skols
      , Bool -> Bool
    not ([TcId] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TcId]
    esc_skols)
      = let main_msg :: TcSolverReportMsg
    main_msg =
              CannotUnifyVariable
                { mismatchMsg :: MismatchMsg
    mismatchMsg       = MismatchMsg
    mismatch_msg
                , cannotUnifyReason :: CannotUnifyVariableReason
    cannotUnifyReason = ErrorItem -> Implication -> [TcId] -> CannotUnifyVariableReason
    SkolemEscape ErrorItem
    item Implication
    implic [TcId]
    esc_skols }

      in TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TcSolverReportMsg
    main_msg

      -- Nastiest case: attempt to unify an untouchable variable
      -- So tv is a meta tyvar (or started that way before we
      -- generalised it).  So presumably it is an *untouchable*
      -- meta tyvar or a TyVarTv, else it'd have been unified
      -- See Note [Error messages for untouchables]
      | (Implication
    implic:[Implication]
    _) <- SolverReportErrCtxt -> [Implication]
    cec_encl SolverReportErrCtxt
    ctxt   -- Get the innermost context
      , Implic { ic_tclvl :: Implication -> TcLevel
    ic_tclvl = TcLevel
    lvl } <- Implication
    implic
      = Bool -> SDoc -> TcM TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (Bool -> Bool
    not (TcLevel -> TcId -> Bool
    isTouchableMetaTyVar TcLevel
    lvl TcId
    tv1))
                  (TcId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TcId
    tv1 SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ TcLevel -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TcLevel
    lvl) (TcM TcSolverReportMsg -> TcM TcSolverReportMsg)
    -> TcM TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a b. (a -> b) -> a -> b
    $ do -- See Note [Error messages for untouchables]
        tv_extra <- (TcId, Maybe Implication)
    -> Type -> IOEnv (Env TcGblEnv TcLclEnv) TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Implication -> Maybe Implication
    forall a. a -> Maybe a
    Just Implication
    implic) Type
    ty2
        let tv_extra' = TyVarInfo
    tv_extra { thisTyVarIsUntouchable = Just implic }
            msg = Mismatch
                   { mismatchMsg :: MismatchMsg
    mismatchMsg           = MismatchMsg
    mismatch_msg
                   , mismatchTyVarInfo :: Maybe TyVarInfo
    mismatchTyVarInfo     = TyVarInfo -> Maybe TyVarInfo
    forall a. a -> Maybe a
    Just TyVarInfo
    tv_extra'
                   , mismatchAmbiguityInfo :: [AmbiguityInfo]
    mismatchAmbiguityInfo = []
                   , mismatchCoercibleInfo :: Maybe CoercibleMsg
    mismatchCoercibleInfo = Maybe CoercibleMsg
    forall a. Maybe a
    Nothing }
        return msg

      | Bool
    otherwise
      = SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM TcSolverReportMsg
    reportEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId -> Type
    mkTyVarTy TcId
    tv1) Type
    ty2
            -- This *can* happen (#6123)
            -- Consider an ambiguous top-level constraint (a ~ F a)
            -- Not an occurs check, because F is a type function.
      where
        headline_msg :: MismatchMsg
    headline_msg = SolverReportErrCtxt -> ErrorItem -> Type -> Type -> MismatchMsg
    misMatchOrCND SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
        mismatch_msg :: MismatchMsg
    mismatch_msg = ErrorItem -> Type -> Type -> MismatchMsg
    mkMismatchMsg ErrorItem
    item Type
    ty1 Type
    ty2

        -- The following doesn't use the cterHasProblem mechanism because
        -- we need to retrieve the ConcreteTvOrigin. Just knowing whether
        -- there is an error is not sufficient. See #21430.
        mb_concrete_reason :: Maybe FixedRuntimeRepErrorInfo
    mb_concrete_reason
          | Just ConcreteTvOrigin
    frr_orig <- TcId -> Maybe ConcreteTvOrigin
    isConcreteTyVar_maybe TcId
    tv1
          , Bool -> Bool
    not (Type -> Bool
    isConcreteType Type
    ty2)
          = FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a. a -> Maybe a
    Just (FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo)
    -> FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a b. (a -> b) -> a -> b
    $ ConcreteTvOrigin -> TcId -> Type -> FixedRuntimeRepErrorInfo
    frr_reason ConcreteTvOrigin
    frr_orig TcId
    tv1 Type
    ty2
          | Just (TcId
    tv2, ConcreteTvOrigin
    frr_orig) <- Type -> Maybe (TcId, ConcreteTvOrigin)
    isConcreteTyVarTy_maybe Type
    ty2
          , Bool -> Bool
    not (TcId -> Bool
    isConcreteTyVar TcId
    tv1)
          = FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a. a -> Maybe a
    Just (FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo)
    -> FixedRuntimeRepErrorInfo -> Maybe FixedRuntimeRepErrorInfo
    forall a b. (a -> b) -> a -> b
    $ ConcreteTvOrigin -> TcId -> Type -> FixedRuntimeRepErrorInfo
    frr_reason ConcreteTvOrigin
    frr_orig TcId
    tv2 Type
    ty1
          -- NB: if it's an unsolved equality in which both sides are concrete
          -- (e.g. a concrete type variable on both sides), then it's not a
          -- representation-polymorphism problem.
          | Bool
    otherwise
          = Maybe FixedRuntimeRepErrorInfo
    forall a. Maybe a
    Nothing
        frr_reason :: ConcreteTvOrigin -> TcId -> Type -> FixedRuntimeRepErrorInfo
    frr_reason (ConcreteFRR FixedRuntimeRepOrigin
    frr_orig) TcId
    conc_tv Type
    not_conc
          = FRR_Info { frr_info_origin :: FixedRuntimeRepOrigin
    frr_info_origin = FixedRuntimeRepOrigin
    frr_orig
                     , frr_info_not_concrete :: Maybe (TcId, Type)
    frr_info_not_concrete = (TcId, Type) -> Maybe (TcId, Type)
    forall a. a -> Maybe a
    Just (TcId
    conc_tv, Type
    not_conc) }

        ty1 :: Type
    ty1 = TcId -> Type
    mkTyVarTy TcId
    tv1

        check_eq_result :: CheckTyEqResult
    check_eq_result = case ErrorItem -> Maybe CtIrredReason
    ei_m_reason ErrorItem
    item of
          Just (NonCanonicalReason CheckTyEqResult
    result) -> CheckTyEqResult
    result
          Maybe CtIrredReason
    _                                -> CheckTyEqResult
    cteOK

    eqInfoMsgs :: TcType -> TcType -> [AmbiguityInfo]
    -- Report (a) ambiguity if either side is a type function application
    --            e.g. F a0 ~ Int
    --        (b) warning about injectivity if both sides are the same
    --            type function application   F a ~ F b
    --            See Note [Non-injective type functions]
    eqInfoMsgs :: Type -> Type -> [AmbiguityInfo]
    eqInfoMsgs Type
    ty1 Type
    ty2
      = [Maybe AmbiguityInfo] -> [AmbiguityInfo]
    forall a. [Maybe a] -> [a]
    catMaybes [Maybe AmbiguityInfo
    tyfun_msg, Maybe AmbiguityInfo
    ambig_msg]
      where
        mb_fun1 :: Maybe TyCon
    mb_fun1 = Type -> Maybe TyCon
    isTyFun_maybe Type
    ty1
        mb_fun2 :: Maybe TyCon
    mb_fun2 = Type -> Maybe TyCon
    isTyFun_maybe Type
    ty2

          -- if a type isn't headed by a type function, then any ambiguous
          -- variables need not be reported as such. e.g.: F a ~ t0 -> t0, where a is a skolem
        ambig_tkvs1 :: ([TcId], [TcId])
    ambig_tkvs1 = ([TcId], [TcId])
    -> (TyCon -> ([TcId], [TcId])) -> Maybe TyCon -> ([TcId], [TcId])
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe ([TcId], [TcId])
    forall a. Monoid a => a
    mempty (\TyCon
    _ -> Type -> ([TcId], [TcId])
    ambigTkvsOfTy Type
    ty1) Maybe TyCon
    mb_fun1
        ambig_tkvs2 :: ([TcId], [TcId])
    ambig_tkvs2 = ([TcId], [TcId])
    -> (TyCon -> ([TcId], [TcId])) -> Maybe TyCon -> ([TcId], [TcId])
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe ([TcId], [TcId])
    forall a. Monoid a => a
    mempty (\TyCon
    _ -> Type -> ([TcId], [TcId])
    ambigTkvsOfTy Type
    ty2) Maybe TyCon
    mb_fun2

        ambig_tkvs :: ([TcId], [TcId])
    ambig_tkvs@([TcId]
    ambig_kvs, [TcId]
    ambig_tvs) = ([TcId], [TcId])
    ambig_tkvs1 ([TcId], [TcId]) -> ([TcId], [TcId]) -> ([TcId], [TcId])
    forall a. Semigroup a => a -> a -> a
    S.<> ([TcId], [TcId])
    ambig_tkvs2

        ambig_msg :: Maybe AmbiguityInfo
    ambig_msg | Maybe TyCon -> Bool
    forall a. Maybe a -> Bool
    isJust Maybe TyCon
    mb_fun1 Bool -> Bool -> Bool
    || Maybe TyCon -> Bool
    forall a. Maybe a -> Bool
    isJust Maybe TyCon
    mb_fun2
                  , Bool -> Bool
    not ([TcId] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TcId]
    ambig_kvs Bool -> Bool -> Bool
    && [TcId] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TcId]
    ambig_tvs)
                  = AmbiguityInfo -> Maybe AmbiguityInfo
    forall a. a -> Maybe a
    Just (AmbiguityInfo -> Maybe AmbiguityInfo)
    -> AmbiguityInfo -> Maybe AmbiguityInfo
    forall a b. (a -> b) -> a -> b
    $ Bool -> ([TcId], [TcId]) -> AmbiguityInfo
    Ambiguity Bool
    False ([TcId], [TcId])
    ambig_tkvs
                  | Bool
    otherwise
                  = Maybe AmbiguityInfo
    forall a. Maybe a
    Nothing

        tyfun_msg :: Maybe AmbiguityInfo
    tyfun_msg | Just TyCon
    tc1 <- Maybe TyCon
    mb_fun1
                  , Just TyCon
    tc2 <- Maybe TyCon
    mb_fun2
                  , TyCon
    tc1 TyCon -> TyCon -> Bool
    forall a. Eq a => a -> a -> Bool
    == TyCon
    tc2
                  , Bool -> Bool
    not (TyCon -> Role -> Bool
    isInjectiveTyCon TyCon
    tc1 Role
    Nominal)
                  = AmbiguityInfo -> Maybe AmbiguityInfo
    forall a. a -> Maybe a
    Just (AmbiguityInfo -> Maybe AmbiguityInfo)
    -> AmbiguityInfo -> Maybe AmbiguityInfo
    forall a b. (a -> b) -> a -> b
    $ TyCon -> AmbiguityInfo
    NonInjectiveTyFam TyCon
    tc1
                  | Bool
    otherwise
                  = Maybe AmbiguityInfo
    forall a. Maybe a
    Nothing

    misMatchOrCND :: SolverReportErrCtxt -> ErrorItem
                  -> TcType -> TcType -> MismatchMsg
    -- If oriented then ty1 is actual, ty2 is expected
    misMatchOrCND :: SolverReportErrCtxt -> ErrorItem -> Type -> Type -> MismatchMsg
    misMatchOrCND SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
      | Bool
    insoluble_item   -- See Note [Insoluble mis-match]
        Bool -> Bool -> Bool
    || (Type -> Bool
    isRigidTy Type
    ty1 Bool -> Bool -> Bool
    && Type -> Bool
    isRigidTy Type
    ty2)
        Bool -> Bool -> Bool
    || (ErrorItem -> CtFlavour
    ei_flavour ErrorItem
    item CtFlavour -> CtFlavour -> Bool
    forall a. Eq a => a -> a -> Bool
    == CtFlavour
    Given)
        Bool -> Bool -> Bool
    || [Implication] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Implication]
    givens
      = -- If the equality is unconditionally insoluble
        -- or there is no context, don't report the context
        ErrorItem -> Type -> Type -> MismatchMsg
    mkMismatchMsg ErrorItem
    item Type
    ty1 Type
    ty2

      | Bool
    otherwise
      = [Implication]
    -> NonEmpty ErrorItem -> Maybe CND_Extra -> MismatchMsg
    CouldNotDeduce [Implication]
    givens (ErrorItem
    item ErrorItem -> [ErrorItem] -> NonEmpty ErrorItem
    forall a. a -> [a] -> NonEmpty a
    :| []) (CND_Extra -> Maybe CND_Extra
    forall a. a -> Maybe a
    Just (CND_Extra -> Maybe CND_Extra) -> CND_Extra -> Maybe CND_Extra
    forall a b. (a -> b) -> a -> b
    $ TypeOrKind -> Type -> Type -> CND_Extra
    CND_Extra TypeOrKind
    level Type
    ty1 Type
    ty2)

      where
        insoluble_item :: Bool
    insoluble_item = case ErrorItem -> Maybe CtIrredReason
    ei_m_reason ErrorItem
    item of
                           Maybe CtIrredReason
    Nothing -> Bool
    False
                           Just CtIrredReason
    r  -> CtIrredReason -> Bool
    isInsolubleReason CtIrredReason
    r

        level :: TypeOrKind
    level   = CtLoc -> Maybe TypeOrKind
    ctLocTypeOrKind_maybe (ErrorItem -> CtLoc
    errorItemCtLoc ErrorItem
    item) Maybe TypeOrKind -> TypeOrKind -> TypeOrKind
    forall a. Maybe a -> a -> a
    `orElse` TypeOrKind
    TypeLevel
        givens :: [Implication]
    givens  = [ Implication
    given | Implication
    given <- SolverReportErrCtxt -> [Implication]
    getUserGivens SolverReportErrCtxt
    ctxt, Implication -> HasGivenEqs
    ic_given_eqs Implication
    given HasGivenEqs -> HasGivenEqs -> Bool
    forall a. Eq a => a -> a -> Bool
    /= HasGivenEqs
    NoGivenEqs ]
                  -- Keep only UserGivens that have some equalities.
                  -- See Note [Suppress redundant givens during error reporting]

    -- These are for the "blocked" equalities, as described in GHC.Tc.Solver.Equality
    -- Note [Equalities with incompatible kinds], wrinkle (EIK2). There should
    -- always be another unsolved wanted around, which will ordinarily suppress
    -- this message. But this can still be printed out with -fdefer-type-errors
    -- (sigh), so we must produce a message.
    mkBlockedEqErr :: ErrorItem -> TcSolverReportMsg
    mkBlockedEqErr :: ErrorItem -> TcSolverReportMsg
    mkBlockedEqErr ErrorItem
    item = ErrorItem -> TcSolverReportMsg
    BlockedEquality ErrorItem
    item

    {-
    Note [Suppress redundant givens during error reporting]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    When GHC is unable to solve a constraint and prints out an error message, it
    will print out what given constraints are in scope to provide some context to
    the programmer. But we shouldn't print out /every/ given, since some of them
    are not terribly helpful to diagnose type errors. Consider this example:

      foo :: Int :~: Int -> a :~: b -> a :~: c
      foo Refl Refl = Refl

    When reporting that GHC can't solve (a ~ c), there are two givens in scope:
    (Int ~ Int) and (a ~ b). But (Int ~ Int) is trivially soluble (i.e.,
    redundant), so it's not terribly useful to report it in an error message.
    To accomplish this, we discard any Implications that do not bind any
    equalities by filtering the `givens` selected in `misMatchOrCND` (based on
    the `ic_given_eqs` field of the Implication). Note that we discard givens
    that have no equalities whatsoever, but we want to keep ones with only *local*
    equalities, as these may be helpful to the user in understanding what went
    wrong.

    But this is not enough to avoid all redundant givens! Consider this example,
    from #15361:

      goo :: forall (a :: Type) (b :: Type) (c :: Type).
             a :~~: b -> a :~~: c
      goo HRefl = HRefl

    Matching on HRefl brings the /single/ given (* ~ *, a ~ b) into scope.
    The (* ~ *) part arises due the kinds of (:~~:) being unified. More
    importantly, (* ~ *) is redundant, so we'd like not to report it. However,
    the Implication (* ~ *, a ~ b) /does/ bind an equality (as reported by its
    ic_given_eqs field), so the test above will keep it wholesale.

    To refine this given, we apply mkMinimalBySCs on it to extract just the (a ~ b)
    part. This works because mkMinimalBySCs eliminates reflexive equalities in
    addition to superclasses (see Note [Remove redundant provided dicts]
    in GHC.Tc.TyCl.PatSyn).
    -}

    extraTyVarEqInfo :: (TcTyVar, Maybe Implication) -> TcType -> TcM TyVarInfo
    -- Add on extra info about skolem constants
    -- NB: The types themselves are already tidied
    extraTyVarEqInfo :: (TcId, Maybe Implication)
    -> Type -> IOEnv (Env TcGblEnv TcLclEnv) TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Maybe Implication
    mb_implic) Type
    ty2
      = do
          tv1_info <- TcId -> TcM TcId
    extraTyVarInfo TcId
    tv1
          ty2_info <- ty_extra ty2
          return $
            TyVarInfo
              { thisTyVar              = tv1_info
              , thisTyVarIsUntouchable = mb_implic
              , otherTy                = ty2_info }
      where
        ty_extra :: Type -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TcId)
    ty_extra Type
    ty = case Type -> Maybe (TcId, TcCoercionN)
    getCastedTyVar_maybe Type
    ty of
                        Just (TcId
    tv, TcCoercionN
    _) -> TcId -> Maybe TcId
    forall a. a -> Maybe a
    Just (TcId -> Maybe TcId)
    -> TcM TcId -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TcId)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> TcId -> TcM TcId
    extraTyVarInfo TcId
    tv
                        Maybe (TcId, TcCoercionN)
    Nothing      -> Maybe TcId -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TcId)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe TcId
    forall a. Maybe a
    Nothing

    extraTyVarInfo :: TcTyVar -> TcM TyVar
    extraTyVarInfo :: TcId -> TcM TcId
    extraTyVarInfo TcId
    tv = Bool -> SDoc -> TcM TcId -> TcM TcId
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (TcId -> Bool
    isTyVar TcId
    tv) (TcId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TcId
    tv) (TcM TcId -> TcM TcId) -> TcM TcId -> TcM TcId
    forall a b. (a -> b) -> a -> b
    $
      case TcId -> TcTyVarDetails
    tcTyVarDetails TcId
    tv of
        SkolemTv SkolemInfo
    skol_info TcLevel
    lvl Bool
    overlaps -> do
          new_skol_info <- ZonkM SkolemInfo -> TcM SkolemInfo
    forall a. ZonkM a -> TcM a
    liftZonkM (ZonkM SkolemInfo -> TcM SkolemInfo)
    -> ZonkM SkolemInfo -> TcM SkolemInfo
    forall a b. (a -> b) -> a -> b
    $ SkolemInfo -> ZonkM SkolemInfo
    zonkSkolemInfo SkolemInfo
    skol_info
          return $ mkTcTyVar (tyVarName tv) (tyVarKind tv) (SkolemTv new_skol_info lvl overlaps)
        TcTyVarDetails
    _ -> TcId -> TcM TcId
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TcId
    tv

    --------------------
    mkMismatchMsg :: ErrorItem -> Type -> Type -> MismatchMsg
    mkMismatchMsg :: ErrorItem -> Type -> Type -> MismatchMsg
    mkMismatchMsg ErrorItem
    item Type
    ty1 Type
    ty2 =
      case CtOrigin
    orig of
        TypeEqOrigin { Type
    uo_actual :: Type
    uo_actual :: CtOrigin -> Type
    uo_actual, Type
    uo_expected :: Type
    uo_expected :: CtOrigin -> Type
    uo_expected, uo_thing :: CtOrigin -> Maybe TypedThing
    uo_thing = Maybe TypedThing
    mb_thing } ->
          (TypeEqMismatch
            { teq_mismatch_item :: ErrorItem
    teq_mismatch_item     = ErrorItem
    item
            , teq_mismatch_ty1 :: Type
    teq_mismatch_ty1      = Type
    ty1
            , teq_mismatch_ty2 :: Type
    teq_mismatch_ty2      = Type
    ty2
            , teq_mismatch_actual :: Type
    teq_mismatch_actual   = Type
    uo_actual
            , teq_mismatch_expected :: Type
    teq_mismatch_expected = Type
    uo_expected
            , teq_mismatch_what :: Maybe TypedThing
    teq_mismatch_what     = Maybe TypedThing
    mb_thing
            , teq_mb_same_occ :: Maybe SameOccInfo
    teq_mb_same_occ       = Type -> Type -> Maybe SameOccInfo
    sameOccExtras Type
    ty2 Type
    ty1 })
        KindEqOrigin Type
    cty1 Type
    cty2 CtOrigin
    sub_o Maybe TypeOrKind
    mb_sub_t_or_k -> BasicMismatch
          { mismatch_ea :: MismatchEA
    mismatch_ea           = MismatchEA
    NoEA
          , mismatch_item :: ErrorItem
    mismatch_item         = ErrorItem
    item
          , mismatch_ty1 :: Type
    mismatch_ty1          = Type
    ty1
          , mismatch_ty2 :: Type
    mismatch_ty2          = Type
    ty2
          , mismatch_whenMatching :: Maybe WhenMatching
    mismatch_whenMatching = WhenMatching -> Maybe WhenMatching
    forall a. a -> Maybe a
    Just (WhenMatching -> Maybe WhenMatching)
    -> WhenMatching -> Maybe WhenMatching
    forall a b. (a -> b) -> a -> b
    $ Type -> Type -> CtOrigin -> Maybe TypeOrKind -> WhenMatching
    WhenMatching Type
    cty1 Type
    cty2 CtOrigin
    sub_o Maybe TypeOrKind
    mb_sub_t_or_k
          , mismatch_mb_same_occ :: Maybe SameOccInfo
    mismatch_mb_same_occ  = Maybe SameOccInfo
    mb_same_occ
          }
        CtOrigin
    _ -> BasicMismatch
          { mismatch_ea :: MismatchEA
    mismatch_ea           = MismatchEA
    NoEA
          , mismatch_item :: ErrorItem
    mismatch_item         = ErrorItem
    item
          , mismatch_ty1 :: Type
    mismatch_ty1          = Type
    ty1
          , mismatch_ty2 :: Type
    mismatch_ty2          = Type
    ty2
          , mismatch_whenMatching :: Maybe WhenMatching
    mismatch_whenMatching = Maybe WhenMatching
    forall a. Maybe a
    Nothing
          , mismatch_mb_same_occ :: Maybe SameOccInfo
    mismatch_mb_same_occ  = Maybe SameOccInfo
    mb_same_occ
          }
      where
        orig :: CtOrigin
    orig = ErrorItem -> CtOrigin
    errorItemOrigin ErrorItem
    item
        mb_same_occ :: Maybe SameOccInfo
    mb_same_occ = Type -> Type -> Maybe SameOccInfo
    sameOccExtras Type
    ty2 Type
    ty1

    {- Note [Insoluble mis-match]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider [G] a ~ [a],  [W] a ~ [a] (#13674).  The Given is insoluble
    so we don't use it for rewriting.  The Wanted is also insoluble, and
    we don't solve it from the Given.  It's very confusing to say
        Cannot solve a ~ [a] from given constraints a ~ [a]

    And indeed even thinking about the Givens is silly; [W] a ~ [a] is
    just as insoluble as Int ~ Bool.

    Exactly the same is true if we have [G] Int ~ Bool, [W] Int ~ Bool.

    Conclusion: if there's an insoluble constraint (isInsolubleReason),
    then report it directly, not in the "cannot deduce X from Y" form.
    This is done in misMatchOrCND (via the insoluble_occurs_check arg)

    (NB: there are potentially-soluble ones, like (a ~ F a b), and we don't
    want to be as draconian with them.)
    -}

    sameOccExtras :: TcType -> TcType -> Maybe SameOccInfo
    -- See Note [Disambiguating (X ~ X) errors]
    sameOccExtras :: Type -> Type -> Maybe SameOccInfo
    sameOccExtras Type
    ty1 Type
    ty2
      | Just (TyCon
    tc1, [Type]
    _) <- HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe Type
    ty1
      , Just (TyCon
    tc2, [Type]
    _) <- HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe Type
    ty2
      , let n1 :: Name
    n1 = TyCon -> Name
    tyConName TyCon
    tc1
            n2 :: Name
    n2 = TyCon -> Name
    tyConName TyCon
    tc2
            same_occ :: Bool
    same_occ = Name -> OccName
    nameOccName Name
    n1                   OccName -> OccName -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name -> OccName
    nameOccName Name
    n2
            same_pkg :: Bool
    same_pkg = GenModule Unit -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit (HasDebugCallStack => Name -> GenModule Unit
    Name -> GenModule Unit
    nameModule Name
    n1) Unit -> Unit -> Bool
    forall a. Eq a => a -> a -> Bool
    == GenModule Unit -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit (HasDebugCallStack => Name -> GenModule Unit
    Name -> GenModule Unit
    nameModule Name
    n2)
      , Name
    n1 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Name
    n2   -- Different Names
      , Bool
    same_occ   -- but same OccName
      = SameOccInfo -> Maybe SameOccInfo
    forall a. a -> Maybe a
    Just (SameOccInfo -> Maybe SameOccInfo)
    -> SameOccInfo -> Maybe SameOccInfo
    forall a b. (a -> b) -> a -> b
    $ Bool -> Name -> Name -> SameOccInfo
    SameOcc Bool
    same_pkg Name
    n1 Name
    n2
      | Bool
    otherwise
      = Maybe SameOccInfo
    forall a. Maybe a
    Nothing

    {- Note [Disambiguating (X ~ X) errors]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    See #8278

    Note [Reporting occurs-check errors]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Given (a ~ [a]), if 'a' is a rigid type variable bound by a user-supplied
    type signature, then the best thing is to report that we can't unify
    a with [a], because a is a skolem variable.  That avoids the confusing
    "occur-check" error message.

    But nowadays when inferring the type of a function with no type signature,
    even if there are errors inside, we still generalise its signature and
    carry on. For example
       f x = x:x
    Here we will infer something like
       f :: forall a. a -> [a]
    with a deferred error of (a ~ [a]).  So in the deferred unsolved constraint
    'a' is now a skolem, but not one bound by the programmer in the context!
    Here we really should report an occurs check.

    So isUserSkolem distinguishes the two.

    Note [Non-injective type functions]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    It's very confusing to get a message like
         Couldn't match expected type `Depend s'
                against inferred type `Depend s1'
    so mkTyFunInfoMsg adds:
           NB: `Depend' is type function, and hence may not be injective

    Warn of loopy local equalities that were dropped.

    ************************************************************************
    *                                                                      *
                     Type-class errors
    *                                                                      *
    ************************************************************************
    -}

    mkDictErr :: HasDebugCallStack => SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkDictErr :: HasDebugCallStack =>
    SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    mkDictErr SolverReportErrCtxt
    ctxt NonEmpty ErrorItem
    orig_items
      = do { inst_envs <- TcM InstEnvs
    tcGetInstEnvs
           ; let min_items = NonEmpty ErrorItem -> [ErrorItem]
    elim_superclasses NonEmpty ErrorItem
    items
                 lookups = (ErrorItem -> (ErrorItem, ClsInstLookupResult))
    -> [ErrorItem] -> [(ErrorItem, ClsInstLookupResult)]
    forall a b. (a -> b) -> [a] -> [b]
    map (InstEnvs -> ErrorItem -> (ErrorItem, ClsInstLookupResult)
    lookup_cls_inst InstEnvs
    inst_envs) [ErrorItem]
    min_items
                 (no_inst_items, overlap_items) = partition is_no_inst lookups

           -- Report definite no-instance errors,
           -- or (iff there are none) overlap errors
           -- But we report only one of them (hence 'head') because they all
           -- have the same source-location origin, to try avoid a cascade
           -- of error from one location
           ; err <- mk_dict_err ctxt (head (no_inst_items ++ overlap_items))
           ; return $ important ctxt err }
      where
        items :: NonEmpty ErrorItem
    items = (ErrorItem -> Bool) -> NonEmpty ErrorItem -> NonEmpty ErrorItem
    forall a. (a -> Bool) -> NonEmpty a -> NonEmpty a
    tryFilter (Bool -> Bool
    not (Bool -> Bool) -> (ErrorItem -> Bool) -> ErrorItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorItem -> Bool
    ei_suppress) NonEmpty ErrorItem
    orig_items

        no_givens :: Bool
    no_givens = [Implication] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (SolverReportErrCtxt -> [Implication]
    getUserGivens SolverReportErrCtxt
    ctxt)

        is_no_inst :: (ErrorItem, ClsInstLookupResult) -> Bool
    is_no_inst (ErrorItem
    item, ([InstMatch]
    matches, PotentialUnifiers
    unifiers, [InstMatch]
    _))
          =  Bool
    no_givens
          Bool -> Bool -> Bool
    && [InstMatch] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [InstMatch]
    matches
          Bool -> Bool -> Bool
    && (PotentialUnifiers -> Bool
    nullUnifiers PotentialUnifiers
    unifiers Bool -> Bool -> Bool
    || (TcId -> Bool) -> [TcId] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (Bool -> Bool
    not (Bool -> Bool) -> (TcId -> Bool) -> TcId -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TcId -> Bool
    isAmbiguousTyVar) (Type -> [TcId]
    tyCoVarsOfTypeList (ErrorItem -> Type
    errorItemPred ErrorItem
    item)))

        lookup_cls_inst :: InstEnvs -> ErrorItem -> (ErrorItem, ClsInstLookupResult)
    lookup_cls_inst InstEnvs
    inst_envs ErrorItem
    item
          = (ErrorItem
    item, Bool -> InstEnvs -> Class -> [Type] -> ClsInstLookupResult
    lookupInstEnv Bool
    True InstEnvs
    inst_envs Class
    clas [Type]
    tys)
          where
            (Class
    clas, [Type]
    tys) = HasDebugCallStack => Type -> (Class, [Type])
    Type -> (Class, [Type])
    getClassPredTys (ErrorItem -> Type
    errorItemPred ErrorItem
    item)

        -- When simplifying [W] Ord (Set a), we need
        --    [W] Eq a, [W] Ord a
        -- but we really only want to report the latter
        elim_superclasses :: NonEmpty ErrorItem -> [ErrorItem]
    elim_superclasses = (ErrorItem -> Type) -> [ErrorItem] -> [ErrorItem]
    forall a. (a -> Type) -> [a] -> [a]
    mkMinimalBySCs ErrorItem -> Type
    errorItemPred ([ErrorItem] -> [ErrorItem])
    -> (NonEmpty ErrorItem -> [ErrorItem])
    -> NonEmpty ErrorItem
    -> [ErrorItem]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NonEmpty ErrorItem -> [ErrorItem]
    forall a. NonEmpty a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList

    -- Note [mk_dict_err]
    -- ~~~~~~~~~~~~~~~~~~~
    -- Different dictionary error messages are reported depending on the number of
    -- matches and unifiers:
    --
    --   - No matches, regardless of unifiers: report "No instance for ...".
    --   - Two or more matches, regardless of unifiers: report "Overlapping instances for ...",
    --     and show the matching and unifying instances.
    --   - One match, one or more unifiers: report "Overlapping instances for", show the
    --     matching and unifying instances, and say "The choice depends on the instantion of ...,
    --     and the result of evaluating ...".
    mk_dict_err :: HasCallStack => SolverReportErrCtxt -> (ErrorItem, ClsInstLookupResult)
                -> TcM TcSolverReportMsg
    mk_dict_err :: HasCallStack =>
    SolverReportErrCtxt
    -> (ErrorItem, ClsInstLookupResult) -> TcM TcSolverReportMsg
    mk_dict_err SolverReportErrCtxt
    ctxt (ErrorItem
    item, ([InstMatch]
    matches, PotentialUnifiers
    unifiers, [InstMatch]
    unsafe_overlapped)) = case ([InstMatch] -> Maybe (NonEmpty InstMatch)
    forall a. [a] -> Maybe (NonEmpty a)
    NE.nonEmpty [InstMatch]
    matches, [InstMatch] -> Maybe (NonEmpty InstMatch)
    forall a. [a] -> Maybe (NonEmpty a)
    NE.nonEmpty [InstMatch]
    unsafe_overlapped) of
      (Maybe (NonEmpty InstMatch)
    Nothing, Maybe (NonEmpty InstMatch)
    _)  -> do -- No matches but perhaps several unifiers
        { (_, rel_binds, item) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item
        ; candidate_insts <- get_candidate_instances
        ; (imp_errs, field_suggestions) <- record_field_suggestions item
        ; return (cannot_resolve_msg item candidate_insts rel_binds imp_errs field_suggestions) }

      -- Some matches => overlap errors
      (Just NonEmpty InstMatch
    matchesNE, Maybe (NonEmpty InstMatch)
    Nothing) -> TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg -> TcM TcSolverReportMsg)
    -> TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a b. (a -> b) -> a -> b
    $
        ErrorItem -> NonEmpty ClsInst -> [ClsInst] -> TcSolverReportMsg
    OverlappingInstances ErrorItem
    item ((InstMatch -> ClsInst) -> NonEmpty InstMatch -> NonEmpty ClsInst
    forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
    NE.map InstMatch -> ClsInst
    forall a b. (a, b) -> a
    fst NonEmpty InstMatch
    matchesNE) (PotentialUnifiers -> [ClsInst]
    getPotentialUnifiers PotentialUnifiers
    unifiers)

      (Just (InstMatch
    match :| []), Just NonEmpty InstMatch
    unsafe_overlappedNE) -> TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg -> TcM TcSolverReportMsg)
    -> TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a b. (a -> b) -> a -> b
    $
        ErrorItem -> ClsInst -> NonEmpty ClsInst -> TcSolverReportMsg
    UnsafeOverlap ErrorItem
    item (InstMatch -> ClsInst
    forall a b. (a, b) -> a
    fst InstMatch
    match) ((InstMatch -> ClsInst) -> NonEmpty InstMatch -> NonEmpty ClsInst
    forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
    NE.map InstMatch -> ClsInst
    forall a b. (a, b) -> a
    fst NonEmpty InstMatch
    unsafe_overlappedNE)
      (Just matches :: NonEmpty InstMatch
    matches@(InstMatch
    _ :| [InstMatch]
    _), Just NonEmpty InstMatch
    overlaps) -> String -> SDoc -> TcM TcSolverReportMsg
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "mk_dict_err: multiple matches with overlap" (SDoc -> TcM TcSolverReportMsg) -> SDoc -> TcM TcSolverReportMsg
    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
    "matches:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> NonEmpty InstMatch -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr NonEmpty InstMatch
    matches, String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "overlaps:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> NonEmpty InstMatch -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr NonEmpty InstMatch
    overlaps ]
      where
        orig :: CtOrigin
    orig          = ErrorItem -> CtOrigin
    errorItemOrigin ErrorItem
    item
        pred :: Type
    pred          = ErrorItem -> Type
    errorItemPred ErrorItem
    item
        (Class
    clas, [Type]
    tys)   = HasDebugCallStack => Type -> (Class, [Type])
    Type -> (Class, [Type])
    getClassPredTys Type
    pred

        get_candidate_instances :: TcM [ClsInst]
        -- See Note [Report candidate instances]
        get_candidate_instances :: TcM [ClsInst]
    get_candidate_instances
          | [Type
    ty] <- [Type]
    tys   -- Only try for single-parameter classes
          = do { instEnvs <- TcM InstEnvs
    tcGetInstEnvs
               ; return (filter (is_candidate_inst ty)
                                (classInstances instEnvs clas)) }
          | Bool
    otherwise = [ClsInst] -> TcM [ClsInst]
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []

        is_candidate_inst :: Type -> ClsInst -> Bool
    is_candidate_inst Type
    ty ClsInst
    inst -- See Note [Report candidate instances]
          | [Type
    other_ty] <- ClsInst -> [Type]
    is_tys ClsInst
    inst
          , Just (TyCon
    tc1, [Type]
    _) <- HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe Type
    ty
          , Just (TyCon
    tc2, [Type]
    _) <- HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe Type
    other_ty
          = let n1 :: Name
    n1 = TyCon -> Name
    tyConName TyCon
    tc1
                n2 :: Name
    n2 = TyCon -> Name
    tyConName TyCon
    tc2
                different_names :: Bool
    different_names = Name
    n1 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Name
    n2
                same_occ_names :: Bool
    same_occ_names = Name -> OccName
    nameOccName Name
    n1 OccName -> OccName -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name -> OccName
    nameOccName Name
    n2
            in Bool
    different_names Bool -> Bool -> Bool
    && Bool
    same_occ_names
          | Bool
    otherwise = Bool
    False

        -- See Note [Out-of-scope fields with -XOverloadedRecordDot]
        record_field_suggestions :: ErrorItem -> TcM ([ImportError], [GhcHint])
        record_field_suggestions :: ErrorItem -> RnM ([ImportError], [GhcHint])
    record_field_suggestions ErrorItem
    item = ((OccName -> RnM ([ImportError], [GhcHint]))
     -> Maybe OccName -> RnM ([ImportError], [GhcHint]))
    -> Maybe OccName
    -> (OccName -> RnM ([ImportError], [GhcHint]))
    -> RnM ([ImportError], [GhcHint])
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (RnM ([ImportError], [GhcHint])
    -> (OccName -> RnM ([ImportError], [GhcHint]))
    -> Maybe OccName
    -> RnM ([ImportError], [GhcHint])
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (RnM ([ImportError], [GhcHint])
     -> (OccName -> RnM ([ImportError], [GhcHint]))
     -> Maybe OccName
     -> RnM ([ImportError], [GhcHint]))
    -> RnM ([ImportError], [GhcHint])
    -> (OccName -> RnM ([ImportError], [GhcHint]))
    -> Maybe OccName
    -> RnM ([ImportError], [GhcHint])
    forall a b. (a -> b) -> a -> b
    $ ([ImportError], [GhcHint]) -> RnM ([ImportError], [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([], [GhcHint]
    noHints)) Maybe OccName
    record_field ((OccName -> RnM ([ImportError], [GhcHint]))
     -> RnM ([ImportError], [GhcHint]))
    -> (OccName -> RnM ([ImportError], [GhcHint]))
    -> RnM ([ImportError], [GhcHint])
    forall a b. (a -> b) -> a -> b
    $ \OccName
    name ->
           do { glb_env <- TcRn GlobalRdrEnv
    getGlobalRdrEnv
              ; lcl_env <- getLocalRdrEnv
              ; let field_name_hints = ErrorItem -> [GhcHint]
    report_no_fieldnames ErrorItem
    item
              ; (errs, hints) <- if occ_name_in_scope glb_env lcl_env name
                  then return ([], noHints)
                  else unknownNameSuggestions emptyLocalRdrEnv WL_RecField (mkRdrUnqual name)
              ; pure (errs, hints ++ field_name_hints)
              }

        -- get type names from instance
        -- resolve the type - if it's in scope is it a record?
        -- if it's a record, report an error - the record name + the field that could not be found
        report_no_fieldnames :: ErrorItem -> [GhcHint]
        report_no_fieldnames :: ErrorItem -> [GhcHint]
    report_no_fieldnames ErrorItem
    item
           | Just (EvVarDest TcId
    evvar) <- ErrorItem -> Maybe TcEvDest
    ei_evdest ErrorItem
    item
           -- we can assume that here we have a `HasField @Symbol x r a` instance
           -- because of HasFieldOrigin in record_field
           , Just (TyCon
    _, [Type
    _symbol, Type
    x, Type
    r, Type
    a]) <- HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe (TcId -> Type
    varType TcId
    evvar)
           , Just (TyCon
    r_tycon, [Type]
    _) <- HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe Type
    r
           , Just FastString
    x_name <- Type -> Maybe FastString
    isStrLitTy Type
    x
           -- we check that this is a record type by checking whether it has any
           -- fields (in scope)
           , Bool -> Bool
    not (Bool -> Bool) -> ([FieldLabel] -> Bool) -> [FieldLabel] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [FieldLabel] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([FieldLabel] -> Bool) -> [FieldLabel] -> Bool
    forall a b. (a -> b) -> a -> b
    $ TyCon -> [FieldLabel]
    tyConFieldLabels TyCon
    r_tycon
           = [FastString -> Type -> Type -> GhcHint
    RemindRecordMissingField FastString
    x_name Type
    r Type
    a]
           | Bool
    otherwise = []

        occ_name_in_scope :: GlobalRdrEnv -> LocalRdrEnv -> OccName -> Bool
    occ_name_in_scope GlobalRdrEnv
    glb_env LocalRdrEnv
    lcl_env OccName
    occ_name = Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $
          [GlobalRdrEltX GREInfo] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (GlobalRdrEnv -> LookupGRE GREInfo -> [GlobalRdrEltX GREInfo]
    forall info.
    GlobalRdrEnvX info -> LookupGRE info -> [GlobalRdrEltX info]
    lookupGRE GlobalRdrEnv
    glb_env (OccName -> WhichGREs GREInfo -> LookupGRE GREInfo
    forall info. OccName -> WhichGREs info -> LookupGRE info
    LookupOccName OccName
    occ_name (FieldsOrSelectors -> WhichGREs GREInfo
    RelevantGREsFOS FieldsOrSelectors
    WantNormal))) Bool -> Bool -> Bool
    &&
          Maybe Name -> Bool
    forall a. Maybe a -> Bool
    isNothing (LocalRdrEnv -> OccName -> Maybe Name
    lookupLocalRdrOcc LocalRdrEnv
    lcl_env OccName
    occ_name)

        record_field :: Maybe OccName
    record_field = case CtOrigin
    orig of
          HasFieldOrigin FastString
    name -> OccName -> Maybe OccName
    forall a. a -> Maybe a
    Just (FastString -> OccName
    mkVarOccFS FastString
    name)
          CtOrigin
    _                   -> Maybe OccName
    forall a. Maybe a
    Nothing

        cannot_resolve_msg :: ErrorItem -> [ClsInst] -> RelevantBindings
                           -> [ImportError] -> [GhcHint] -> TcSolverReportMsg
        cannot_resolve_msg :: ErrorItem
    -> [ClsInst]
    -> RelevantBindings
    -> [ImportError]
    -> [GhcHint]
    -> TcSolverReportMsg
    cannot_resolve_msg ErrorItem
    item [ClsInst]
    candidate_insts RelevantBindings
    binds [ImportError]
    imp_errs [GhcHint]
    field_suggestions
          = ErrorItem
    -> [ClsInst]
    -> [ClsInst]
    -> [ImportError]
    -> [GhcHint]
    -> RelevantBindings
    -> TcSolverReportMsg
    CannotResolveInstance ErrorItem
    item (PotentialUnifiers -> [ClsInst]
    getPotentialUnifiers PotentialUnifiers
    unifiers) [ClsInst]
    candidate_insts [ImportError]
    imp_errs [GhcHint]
    field_suggestions RelevantBindings
    binds

    {- Note [Report candidate instances]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If we have an unsolved (Num Int), where `Int` is not the Prelude Int,
    but comes from some other module, then it may be helpful to point out
    that there are some similarly named instances elsewhere.  So we get
    something like
        No instance for (Num Int) arising from the literal ‘3’
        There are instances for similar types:
          instance Num GHC.Types.Int -- Defined in ‘GHC.Num’
    Discussion in #9611.

    Note [Highlighting ambiguous type variables]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    When we encounter ambiguous type variables (i.e. type variables
    that remain metavariables after type inference), we need a few more
    conditions before we can reason that *ambiguity* prevents constraints
    from being solved:
      - We can't have any givens, as encountering a typeclass error
        with given constraints just means we couldn't deduce
        a solution satisfying those constraints and as such couldn't
        bind the type variable to a known type.
      - If we don't have any unifiers, we don't even have potential
        instances from which an ambiguity could arise.
      - Lastly, I don't want to mess with error reporting for
        unknown runtime types so we just fall back to the old message there.
    Once these conditions are satisfied, we can safely say that ambiguity prevents
    the constraint from being solved.

    Note [Out-of-scope fields with -XOverloadedRecordDot]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    With -XOverloadedRecordDot, when a field isn't in scope, the error that appears
    is produces here, and it says
        No instance for (GHC.Record.HasField "<fieldname>" ...).

    Additionally, though, we want to suggest similar field names that are in scope
    or could be in scope with different import lists.

    However, we can still get an error about a missing HasField instance when a
    field is in scope (if the types are wrong), and so it's important that we don't
    suggest similar names here if the record field is in scope, either qualified or
    unqualified, since qualification doesn't matter for -XOverloadedRecordDot.

    Example:

        import Data.Monoid (Alt(..))

        foo = undefined.getAll

    results in

         No instance for (GHC.Records.HasField "getAll" r0 a0)
            arising from selecting the field ‘getAll’
          Perhaps you meant ‘getAlt’ (imported from Data.Monoid)
          Perhaps you want to add ‘getAll’ to the import list
          in the import of ‘Data.Monoid’
    -}

    -----------------------
    -- relevantBindings looks at the value environment and finds values whose
    -- types mention any of the offending type variables.  It has to be
    -- careful to zonk the Id's type first, so it has to be in the monad.
    -- We must be careful to pass it a zonked type variable, too.
    --
    -- We always remove closed top-level bindings, though,
    -- since they are never relevant (cf #8233)

    relevantBindings :: Bool  -- True <=> filter by tyvar; False <=> no filtering
                              -- See #8191
                     -> SolverReportErrCtxt -> ErrorItem
                     -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    -- Also returns the zonked and tidied CtOrigin of the constraint
    relevantBindings :: Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    want_filtering SolverReportErrCtxt
    ctxt ErrorItem
    item
      = do { String -> SDoc -> TcM ()
    traceTc String
    "relevantBindings" (ErrorItem -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ErrorItem
    item)
           ; (env1, tidy_orig) <- ZonkM (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a. ZonkM a -> TcM a
    liftZonkM (ZonkM (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin))
    -> ZonkM (TidyEnv, CtOrigin) -> TcM (TidyEnv, CtOrigin)
    forall a b. (a -> b) -> a -> b
    $ TidyEnv -> CtOrigin -> ZonkM (TidyEnv, CtOrigin)
    zonkTidyOrigin (SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt) (CtLoc -> CtOrigin
    ctLocOrigin CtLoc
    loc)

                 -- For *kind* errors, report the relevant bindings of the
                 -- enclosing *type* equality, because that's more useful for the programmer
           ; let extra_tvs = case CtOrigin
    tidy_orig of
                                 KindEqOrigin Type
    t1 Type
    t2 CtOrigin
    _ Maybe TypeOrKind
    _ -> [Type] -> TyCoVarSet
    tyCoVarsOfTypes [Type
    t1,Type
    t2]
                                 CtOrigin
    _                      -> TyCoVarSet
    emptyVarSet
                 ct_fvs = Type -> TyCoVarSet
    tyCoVarsOfType (ErrorItem -> Type
    errorItemPred ErrorItem
    item) TyCoVarSet -> TyCoVarSet -> TyCoVarSet
    `unionVarSet` TyCoVarSet
    extra_tvs

                 -- Put a zonked, tidied CtOrigin into the ErrorItem
                 loc'   = CtLoc -> CtOrigin -> CtLoc
    setCtLocOrigin CtLoc
    loc CtOrigin
    tidy_orig
                 item'  = ErrorItem
    item { ei_loc = loc' }

           ; (env2, lcl_name_cache) <- liftZonkM $ zonkTidyTcLclEnvs env1 [lcl_env]

           ; relev_bds <- relevant_bindings want_filtering lcl_env lcl_name_cache ct_fvs
           ; let ctxt'  = SolverReportErrCtxt
    ctxt { cec_tidy = env2 }
           ; return (ctxt', relev_bds, item') }
      where
        loc :: CtLoc
    loc     = ErrorItem -> CtLoc
    errorItemCtLoc ErrorItem
    item
        lcl_env :: CtLocEnv
    lcl_env = CtLoc -> CtLocEnv
    ctLocEnv CtLoc
    loc

    -- slightly more general version, to work also with holes
    relevant_bindings :: Bool
                      -> CtLocEnv
                      -> NameEnv Type -- Cache of already zonked and tidied types
                      -> TyCoVarSet
                      -> TcM RelevantBindings
    relevant_bindings :: Bool
    -> CtLocEnv -> NameEnv Type -> TyCoVarSet -> TcM RelevantBindings
    relevant_bindings Bool
    want_filtering CtLocEnv
    lcl_env NameEnv Type
    lcl_name_env TyCoVarSet
    ct_tvs
      = do { dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
           ; traceTc "relevant_bindings" $
               vcat [ ppr ct_tvs
                    , pprWithCommas id [ ppr id <+> dcolon <+> ppr (idType id)
                                       | TcIdBndr id _ <- ctl_bndrs lcl_env ]
                    , pprWithCommas id
                        [ ppr id | TcIdBndr_ExpType id _ _ <- ctl_bndrs lcl_env ] ]

           ; go dflags (maxRelevantBinds dflags)
                        emptyVarSet (RelevantBindings [] False)
                        (removeBindingShadowing $ ctl_bndrs lcl_env)
             -- tcl_bndrs has the innermost bindings first,
             -- which are probably the most relevant ones
      }
      where
        run_out :: Maybe Int -> Bool
        run_out :: Maybe Int -> Bool
    run_out Maybe Int
    Nothing = Bool
    False
        run_out (Just Int
    n) = Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    0

        dec_max :: Maybe Int -> Maybe Int
        dec_max :: Maybe Int -> Maybe Int
    dec_max = (Int -> Int) -> Maybe Int -> Maybe Int
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\Int
    n -> Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1)

        go :: DynFlags -> Maybe Int -> TcTyVarSet
           -> RelevantBindings
           -> [TcBinder]
           -> TcM RelevantBindings
        go :: DynFlags
    -> Maybe Int
    -> TyCoVarSet
    -> RelevantBindings
    -> [TcBinder]
    -> TcM RelevantBindings
    go DynFlags
    _ Maybe Int
    _ TyCoVarSet
    _ (RelevantBindings [(Name, Type)]
    bds Bool
    discards) []
          = RelevantBindings -> TcM RelevantBindings
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (RelevantBindings -> TcM RelevantBindings)
    -> RelevantBindings -> TcM RelevantBindings
    forall a b. (a -> b) -> a -> b
    $ [(Name, Type)] -> Bool -> RelevantBindings
    RelevantBindings ([(Name, Type)] -> [(Name, Type)]
    forall a. [a] -> [a]
    reverse [(Name, Type)]
    bds) Bool
    discards
        go DynFlags
    dflags Maybe Int
    n_left TyCoVarSet
    tvs_seen rels :: RelevantBindings
    rels@(RelevantBindings [(Name, Type)]
    bds Bool
    discards) (TcBinder
    tc_bndr : [TcBinder]
    tc_bndrs)
          = case TcBinder
    tc_bndr of
              TcTvBndr {} -> TcM RelevantBindings
    discard_it
              TcIdBndr TcId
    id TopLevelFlag
    top_lvl -> Name -> TopLevelFlag -> TcM RelevantBindings
    go2 (TcId -> Name
    idName TcId
    id) TopLevelFlag
    top_lvl
              TcIdBndr_ExpType Name
    name ExpType
    et TopLevelFlag
    top_lvl ->
                do { mb_ty <- IO (Maybe Type) -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe Type)
    forall a. IO a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (Maybe Type) -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe Type))
    -> IO (Maybe Type) -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe Type)
    forall a b. (a -> b) -> a -> b
    $ ExpType -> IO (Maybe Type)
    forall (m :: * -> *). MonadIO m => ExpType -> m (Maybe Type)
    readExpType_maybe ExpType
    et
                       -- et really should be filled in by now. But there's a chance
                       -- it hasn't, if, say, we're reporting a kind error en route to
                       -- checking a term. See test indexed-types/should_fail/T8129
                       -- Or we are reporting errors from the ambiguity check on
                       -- a local type signature
                   ; case mb_ty of
                       Just Type
    _ty -> Name -> TopLevelFlag -> TcM RelevantBindings
    go2 Name
    name TopLevelFlag
    top_lvl
                       Maybe Type
    Nothing -> TcM RelevantBindings
    discard_it  -- No info; discard
                   }
          where
            discard_it :: TcM RelevantBindings
    discard_it = DynFlags
    -> Maybe Int
    -> TyCoVarSet
    -> RelevantBindings
    -> [TcBinder]
    -> TcM RelevantBindings
    go DynFlags
    dflags Maybe Int
    n_left TyCoVarSet
    tvs_seen RelevantBindings
    rels [TcBinder]
    tc_bndrs
            go2 :: Name -> TopLevelFlag -> TcM RelevantBindings
    go2 Name
    id_name TopLevelFlag
    top_lvl
              = do { let tidy_ty :: Type
    tidy_ty = case NameEnv Type -> Name -> Maybe Type
    forall a. NameEnv a -> Name -> Maybe a
    lookupNameEnv NameEnv Type
    lcl_name_env Name
    id_name of
                                      Just Type
    tty -> Type
    tty
                                      Maybe Type
    Nothing -> String -> SDoc -> Type
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "relevant_bindings" (Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    id_name)
                   ; String -> SDoc -> TcM ()
    traceTc String
    "relevantBindings 1" (Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    id_name SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc
    dcolon SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Type -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Type
    tidy_ty)
                   ; let id_tvs :: TyCoVarSet
    id_tvs = Type -> TyCoVarSet
    tyCoVarsOfType Type
    tidy_ty
                         bd :: (Name, Type)
    bd = (Name
    id_name, Type
    tidy_ty)
                         new_seen :: TyCoVarSet
    new_seen = TyCoVarSet
    tvs_seen TyCoVarSet -> TyCoVarSet -> TyCoVarSet
    `unionVarSet` TyCoVarSet
    id_tvs

                   ; if (Bool
    want_filtering Bool -> Bool -> Bool
    && Bool -> Bool
    not (DynFlags -> Bool
    hasPprDebug DynFlags
    dflags)
                                        Bool -> Bool -> Bool
    && TyCoVarSet
    id_tvs TyCoVarSet -> TyCoVarSet -> Bool
    `disjointVarSet` TyCoVarSet
    ct_tvs)
                              -- We want to filter out this binding anyway
                              -- so discard it silently
                     then TcM RelevantBindings
    discard_it

                     else if TopLevelFlag -> Bool
    isTopLevel TopLevelFlag
    top_lvl Bool -> Bool -> Bool
    && Bool -> Bool
    not (Maybe Int -> Bool
    forall a. Maybe a -> Bool
    isNothing Maybe Int
    n_left)
                              -- It's a top-level binding and we have not specified
                              -- -fno-max-relevant-bindings, so discard it silently
                     then TcM RelevantBindings
    discard_it

                     else if Maybe Int -> Bool
    run_out Maybe Int
    n_left Bool -> Bool -> Bool
    && TyCoVarSet
    id_tvs TyCoVarSet -> TyCoVarSet -> Bool
    `subVarSet` TyCoVarSet
    tvs_seen
                              -- We've run out of n_left fuel and this binding only
                              -- mentions already-seen type variables, so discard it
                     then DynFlags
    -> Maybe Int
    -> TyCoVarSet
    -> RelevantBindings
    -> [TcBinder]
    -> TcM RelevantBindings
    go DynFlags
    dflags Maybe Int
    n_left TyCoVarSet
    tvs_seen ([(Name, Type)] -> Bool -> RelevantBindings
    RelevantBindings [(Name, Type)]
    bds Bool
    True) -- Record that we have now discarded something
                             [TcBinder]
    tc_bndrs

                              -- Keep this binding, decrement fuel
                     else DynFlags
    -> Maybe Int
    -> TyCoVarSet
    -> RelevantBindings
    -> [TcBinder]
    -> TcM RelevantBindings
    go DynFlags
    dflags (Maybe Int -> Maybe Int
    dec_max Maybe Int
    n_left) TyCoVarSet
    new_seen
                             ([(Name, Type)] -> Bool -> RelevantBindings
    RelevantBindings ((Name, Type)
    bd(Name, Type) -> [(Name, Type)] -> [(Name, Type)]
    forall a. a -> [a] -> [a]
    :[(Name, Type)]
    bds) Bool
    discards) [TcBinder]
    tc_bndrs }

    -----------------------
    warnDefaulting :: [Ct] -> TcTyVar -> Type -> TcM ()
    warnDefaulting :: [Ct] -> TcId -> Type -> TcM ()
    warnDefaulting [] TcId
    _ Type
    _
      = String -> TcM ()
    forall a. HasCallStack => String -> a
    panic String
    "warnDefaulting: empty Wanteds"
    warnDefaulting wanteds :: [Ct]
    wanteds@(Ct
    ct:[Ct]
    _) TcId
    the_tv Type
    default_ty
      = do { warn_default <- WarningFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. WarningFlag -> TcRnIf gbl lcl Bool
    woptM WarningFlag
    Opt_WarnTypeDefaults
           ; env0 <- liftZonkM $ tcInitTidyEnv
                -- don't want to report all the superclass constraints, which
                -- add unhelpful clutter
           ; let filtered = (Ct -> Bool) -> [Ct] -> [Ct]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (Ct -> Bool) -> Ct -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CtOrigin -> Bool
    isWantedSuperclassOrigin (CtOrigin -> Bool) -> (Ct -> CtOrigin) -> Ct -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ct -> CtOrigin
    ctOrigin) [Ct]
    wanteds
                 tidy_env = TidyEnv -> [TcId] -> TidyEnv
    tidyFreeTyCoVars TidyEnv
    env0 ([TcId] -> TidyEnv) -> [TcId] -> TidyEnv
    forall a b. (a -> b) -> a -> b
    $
                            Cts -> [TcId]
    tyCoVarsOfCtsList ([Ct] -> Cts
    forall a. [a] -> Bag a
    listToBag [Ct]
    filtered)
                 tidy_wanteds = (Ct -> Ct) -> [Ct] -> [Ct]
    forall a b. (a -> b) -> [a] -> [b]
    map (TidyEnv -> Ct -> Ct
    tidyCt TidyEnv
    tidy_env) [Ct]
    filtered
                 tidy_tv = UniqFM TcId TcId -> TcId -> Maybe TcId
    forall a. VarEnv a -> TcId -> Maybe a
    lookupVarEnv (TidyEnv -> UniqFM TcId TcId
    forall a b. (a, b) -> b
    snd TidyEnv
    tidy_env) TcId
    the_tv
                 diag = [Ct] -> Maybe TcId -> Type -> TcRnMessage
    TcRnWarnDefaulting [Ct]
    tidy_wanteds Maybe TcId
    tidy_tv Type
    default_ty
                 loc = Ct -> CtLoc
    ctLoc Ct
    ct
           ; setCtLocM loc $ diagnosticTc warn_default diag }

    {-
    Note [Runtime skolems]
    ~~~~~~~~~~~~~~~~~~~~~~
    We want to give a reasonably helpful error message for ambiguity
    arising from *runtime* skolems in the debugger.  These
    are created by in GHC.Runtime.Heap.Inspect.zonkRTTIType.
    -}

    {-**********************************************************************
    *                                                                      *
                          GHC API helper functions
    *                                                                      *
    **********************************************************************-}

    -- | If the 'TcSolverReportMsg' is a type mismatch between
    -- an actual and an expected type, return the actual and expected types
    -- (in that order).
    --
    -- Prefer using this over manually inspecting the 'TcSolverReportMsg' datatype
    -- if you just want this information, as the datatype itself is subject to change
    -- across GHC versions.
    solverReportMsg_ExpectedActuals :: TcSolverReportMsg -> Maybe (Type, Type)
    solverReportMsg_ExpectedActuals :: TcSolverReportMsg -> Maybe (Type, Type)
    solverReportMsg_ExpectedActuals
      = \case
        Mismatch { mismatchMsg :: TcSolverReportMsg -> MismatchMsg
    mismatchMsg = MismatchMsg
    mismatch_msg } ->
          MismatchMsg -> Maybe (Type, Type)
    mismatchMsg_ExpectedActuals MismatchMsg
    mismatch_msg
        TcSolverReportMsg
    _ -> Maybe (Type, Type)
    forall a. Maybe a
    Nothing

    -- | Filter the list by the given predicate, but if that would be empty,
    -- just give back the original list.
    -- We use this as we must report something for fdefer-type-errors.
    tryFilter :: (a -> Bool) -> NonEmpty a -> NonEmpty a
    tryFilter :: forall a. (a -> Bool) -> NonEmpty a -> NonEmpty a
    tryFilter a -> Bool
    f NonEmpty a
    as = NonEmpty a -> Maybe (NonEmpty a) -> NonEmpty a
    forall a. a -> Maybe a -> a
    fromMaybe NonEmpty a
    as (Maybe (NonEmpty a) -> NonEmpty a)
    -> Maybe (NonEmpty a) -> NonEmpty a
    forall a b. (a -> b) -> a -> b
    $ [a] -> Maybe (NonEmpty a)
    forall a. [a] -> Maybe (NonEmpty a)
    nonEmpty ((a -> Bool) -> [a] -> [a]
    forall a. (a -> Bool) -> [a] -> [a]
    filter a -> Bool
    f (NonEmpty a -> [a]
    forall a. NonEmpty a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList NonEmpty a
    as))