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

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

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

           -- * GHC API helper functions
           solverReportMsg_ExpectedActuals,
      ) where

    import GHC.Prelude

    import GHC.Driver.Env (hsc_units)
    import GHC.Driver.Session
    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.Utils.Env( tcInitTidyEnv )
    import GHC.Tc.Utils.TcType
    import GHC.Tc.Utils.Unify ( checkTyVarEq )
    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 ( lookupGRE_Name, GlobalRdrEnv, mkRdrUnqual
                                 , emptyLocalRdrEnv, lookupGlobalRdrEnv , lookupLocalRdrOcc )
    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.Panic.Plain
    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(..) )
    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 { EvBindsVar
    binds_var <- TcM EvBindsVar
    newTcEvBinds
           ; Bool
    defer_errors <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
    goptM GeneralFlag
    Opt_DeferTypeErrors
           ; let type_errors :: DiagnosticReason
    type_errors | Bool -> Bool
    not Bool
    defer_errors = DiagnosticReason
    ErrorWithoutFlag
                             | Bool
    otherwise        = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnDeferredTypeErrors

           ; Bool
    defer_holes <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
    goptM GeneralFlag
    Opt_DeferTypedHoles
           ; let expr_holes :: DiagnosticReason
    expr_holes | Bool -> Bool
    not Bool
    defer_holes = DiagnosticReason
    ErrorWithoutFlag
                            | Bool
    otherwise       = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnTypedHoles

           ; Bool
    partial_sigs      <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
    xoptM Extension
    LangExt.PartialTypeSignatures
           ; let type_holes :: DiagnosticReason
    type_holes | Bool -> Bool
    not Bool
    partial_sigs
                            = DiagnosticReason
    ErrorWithoutFlag
                            | Bool
    otherwise
                            = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnPartialTypeSignatures

           ; Bool
    defer_out_of_scope <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
    goptM GeneralFlag
    Opt_DeferOutOfScopeVariables
           ; let out_of_scope_holes :: DiagnosticReason
    out_of_scope_holes | Bool -> Bool
    not Bool
    defer_out_of_scope
                                    = DiagnosticReason
    ErrorWithoutFlag
                                    | Bool
    otherwise
                                    = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnDeferredOutOfScopeVariables

           ; 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

           ; EvBindMap
    ev_binds <- EvBindsVar -> TcM EvBindMap
    getTcEvBindsMap EvBindsVar
    binds_var
           ; Bag EvBind -> TcM (Bag EvBind)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EvBindMap -> Bag EvBind
    evBindMapBinds EvBindMap
    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 { EvBindsVar
    ev_binds <- TcM EvBindsVar
    newNoTcEvBinds

           ; Bool
    partial_sigs      <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
    xoptM Extension
    LangExt.PartialTypeSignatures
           ; let type_holes :: DiagnosticReason
    type_holes | Bool -> Bool
    not Bool
    partial_sigs  = DiagnosticReason
    ErrorWithoutFlag
                            | Bool
    otherwise         = WarningFlag -> DiagnosticReason
    WarningWithFlag WarningFlag
    Opt_WarnPartialTypeSignatures

           ; DiagnosticReason
    -> DiagnosticReason
    -> DiagnosticReason
    -> DiagnosticReason
    -> EvBindsVar
    -> WantedConstraints
    -> TcM ()
    report_unsolved DiagnosticReason
    ErrorWithoutFlag
                             DiagnosticReason
    ErrorWithoutFlag DiagnosticReason
    type_holes DiagnosticReason
    ErrorWithoutFlag
                             EvBindsVar
    ev_binds WantedConstraints
    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 { EvBindsVar
    ev_binds <- TcM EvBindsVar
    newTcEvBinds
           ; DiagnosticReason
    -> DiagnosticReason
    -> DiagnosticReason
    -> DiagnosticReason
    -> EvBindsVar
    -> WantedConstraints
    -> TcM ()
    report_unsolved DiagnosticReason
    WarningWithoutFlag
                             DiagnosticReason
    WarningWithoutFlag
                             DiagnosticReason
    WarningWithoutFlag
                             DiagnosticReason
    WarningWithoutFlag
                             EvBindsVar
    ev_binds WantedConstraints
    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)

           ; WantedConstraints
    wanted <- WantedConstraints -> TcM WantedConstraints
    zonkWC WantedConstraints
    wanted   -- Zonk to reveal all information

           ; let tidy_env :: TidyEnv
    tidy_env = TidyEnv -> [TcId] -> TidyEnv
    tidyFreeTyCoVars TidyEnv
    emptyTidyEnv [TcId]
    free_tvs
                 free_tvs :: [TcId]
    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.

           ; String -> SDoc -> TcM ()
    traceTc String
    "reportUnsolved (after zonking):" (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
    "Free tyvars:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [TcId] -> SDoc
    pprTyVars [TcId]
    free_tvs
                  , 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 TidyEnv
    tidy_env
                  , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Wanted:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> WantedConstraints -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr WantedConstraints
    wanted ]

           ; Bool
    warn_redundant <- WarningFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. WarningFlag -> TcRnIf gbl lcl Bool
    woptM WarningFlag
    Opt_WarnRedundantConstraints
           ; Bool
    exp_syns <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
    goptM GeneralFlag
    Opt_PrintExpandedSynonyms
           ; let err_ctxt :: SolverReportErrCtxt
    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 }

           ; TcLevel
    tc_lvl <- TcM TcLevel
    getTcLevel
           ; SolverReportErrCtxt -> TcLevel -> WantedConstraints -> TcM ()
    reportWanteds SolverReportErrCtxt
    err_ctxt TcLevel
    tc_lvl WantedConstraints
    wanted
           ; String -> SDoc -> TcM ()
    traceTc String
    "reportUnsolved }" SDoc
    forall doc. IsOutput doc => doc
    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 = []
                     , sr_hints :: [GhcHint]
    sr_hints         = [] }

    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 }

    add_report_hints :: [GhcHint] -> SolverReport -> SolverReport
    add_report_hints :: [GhcHint] -> SolverReport -> SolverReport
    add_report_hints [GhcHint]
    hints report :: SolverReport
    report@(SolverReport { sr_hints :: SolverReport -> [GhcHint]
    sr_hints = [GhcHint]
    prev_hints })
      = SolverReport
    report { sr_hints = prev_hints ++ hints }

    -- | 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 -> TcLclEnv
    ic_env    = TcLclEnv
    tcl_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
    -> TcLclEnv -> SkolemInfoAnon -> [TcId] -> TcM ()
    reportBadTelescope SolverReportErrCtxt
    ctxt TcLclEnv
    tcl_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
    -> TcLclEnv -> SkolemInfoAnon -> [TcId] -> TcM ()
    warnRedundantConstraints SolverReportErrCtxt
    ctxt' TcLclEnv
    tcl_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 -> TcLclEnv -> SkolemInfoAnon -> [EvVar] -> TcM ()
    -- See Note [Tracking redundant constraints] in GHC.Tc.Solver
    warnRedundantConstraints :: SolverReportErrCtxt
    -> TcLclEnv -> SkolemInfoAnon -> [TcId] -> TcM ()
    warnRedundantConstraints SolverReportErrCtxt
    ctxt TcLclEnv
    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".
     = TcLclEnv -> TcM () -> TcM ()
    forall gbl a.
    TcLclEnv -> TcRnIf gbl TcLclEnv a -> TcRnIf gbl TcLclEnv a
    restoreLclEnv TcLclEnv
    env (TcM () -> TcM ()) -> TcM () -> TcM ()
    forall a b. (a -> b) -> a -> b
    $
       SrcSpan -> TcM () -> TcM ()
    forall a. SrcSpan -> TcRn a -> TcRn a
    setSrcSpan (UserTypeCtxt -> SrcSpan
    redundantConstraintsSpan UserTypeCtxt
    user_ctxt) (TcM () -> TcM ()) -> TcM () -> TcM ()
    forall a b. (a -> b) -> a -> b
    $
       Bool -> TcM ()
    report_redundant_msg Bool
    True
                      --  ^^^^ 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
     = TcLclEnv -> TcM () -> TcM ()
    forall gbl a.
    TcLclEnv -> TcRnIf gbl TcLclEnv a -> TcRnIf gbl TcLclEnv a
    restoreLclEnv TcLclEnv
    env
     (TcM () -> TcM ()) -> TcM () -> TcM ()
    forall a b. (a -> b) -> a -> b
    $ Bool -> TcM ()
    report_redundant_msg Bool
    False
                     --   ^^^^^ don't add "In the type signature..."
     where
       report_redundant_msg :: Bool -- whether to add "In the type signature..." to the diagnostic
                            -> TcRn ()
       report_redundant_msg :: Bool -> TcM ()
    report_redundant_msg Bool
    show_info
         = do { TcLclEnv
    lcl_env <- TcRnIf TcGblEnv TcLclEnv TcLclEnv
    forall gbl lcl. TcRnIf gbl lcl lcl
    getLclEnv
              ; MsgEnvelope TcRnMessage
    msg <-
                  TcLclEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport
                    TcLclEnv
    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)
                    []
              ; MsgEnvelope TcRnMessage -> TcM ()
    reportDiagnostic MsgEnvelope TcRnMessage
    msg }

    reportBadTelescope :: SolverReportErrCtxt -> TcLclEnv -> SkolemInfoAnon -> [TcTyVar] -> TcM ()
    reportBadTelescope :: SolverReportErrCtxt
    -> TcLclEnv -> SkolemInfoAnon -> [TcId] -> TcM ()
    reportBadTelescope SolverReportErrCtxt
    ctxt TcLclEnv
    env (ForAllSkol TyVarBndrs
    telescope) [TcId]
    skols
      = do { MsgEnvelope TcRnMessage
    msg <- TcLclEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport
                      TcLclEnv
    env
                      (SolverReportWithCtxt
    -> DiagnosticReason -> [GhcHint] -> TcRnMessage
    TcRnSolverReport SolverReportWithCtxt
    report DiagnosticReason
    ErrorWithoutFlag [GhcHint]
    noHints)
                      (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt)
                      []
           ; MsgEnvelope TcRnMessage -> TcM ()
    reportDiagnostic MsgEnvelope TcRnMessage
    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
    _ TcLclEnv
    _ 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

           ; (Bool
    suppress, Maybe TcEvDest
    m_evdest) <- case Ct -> CtEvidence
    ctEvidence Ct
    ct of
               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 { Bool
    supp <- RewriterSet -> TcRnIf TcGblEnv TcLclEnv Bool
    anyUnfilledCoercionHoles RewriterSet
    rewriters
                       ; (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
    supp, TcEvDest -> Maybe TcEvDest
    forall a. a -> Maybe a
    Just TcEvDest
    dest) }

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

           ; Maybe ErrorItem -> TcM (Maybe ErrorItem)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe ErrorItem -> TcM (Maybe ErrorItem))
    -> Maybe ErrorItem -> TcM (Maybe ErrorItem)
    forall a b. (a -> b) -> a -> b
    $ ErrorItem -> Maybe ErrorItem
    forall a. a -> Maybe a
    Just (ErrorItem -> Maybe ErrorItem) -> ErrorItem -> Maybe ErrorItem
    forall a b. (a -> b) -> a -> b
    $ EI { ei_pred :: Type
    ei_pred     = Ct -> Type
    ctPred Ct
    ct
                                , ei_evdest :: Maybe TcEvDest
    ei_evdest   = Maybe TcEvDest
    m_evdest
                                , ei_flavour :: CtFlavour
    ei_flavour  = CtFlavour
    flav
                                , ei_loc :: CtLoc
    ei_loc      = CtLoc
    loc
                                , ei_m_reason :: Maybe CtIrredReason
    ei_m_reason = Maybe CtIrredReason
    m_reason
                                , ei_suppress :: Bool
    ei_suppress = Bool
    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 { [ErrorItem]
    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
           ; String -> SDoc -> TcM ()
    traceTc String
    "reportWanteds 1" ([SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Simples =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Cts -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Cts
    simples
                                             , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Suppress =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Bool -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (SolverReportErrCtxt -> Bool
    cec_suppress SolverReportErrCtxt
    ctxt)
                                             , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "tidy_cts   =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [Ct] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [Ct]
    tidy_cts
                                             , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "tidy_items1 =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    tidy_items1
                                             , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "tidy_errs =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [DelayedError] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [DelayedError]
    tidy_errs ])

             -- Catch an awkward case in which /all/ errors are suppressed:
             -- see Wrinkle at end of Note [Wanteds rewrite Wanteds] 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)
           ; Bool
    errs_already <- TcRnIf TcGblEnv TcLclEnv Bool
    -> TcRnIf TcGblEnv TcLclEnv Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall r. TcRn r -> TcRn r -> TcRn r
    ifErrsM (Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True) (Bool -> TcRnIf TcGblEnv TcLclEnv Bool
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False)
           ; let tidy_items :: [ErrorItem]
    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 ([Hole]
    out_of_scope, [Hole]
    other_holes, [NotConcreteError]
    not_conc_errs) = [DelayedError] -> ([Hole], [Hole], [NotConcreteError])
    partition_errors [DelayedError]
    tidy_errs
                   -- don't suppress out-of-scope errors
                 ctxt_for_scope_errs :: SolverReportErrCtxt
    ctxt_for_scope_errs = SolverReportErrCtxt
    ctxt { cec_suppress = False }
           ; (()
    _, Bool
    no_out_of_scope) <- TcM () -> TcRn ((), Bool)
    forall a. TcRn a -> TcRn (a, Bool)
    askNoErrs (TcM () -> TcRn ((), Bool)) -> TcM () -> TcRn ((), Bool)
    forall a b. (a -> b) -> a -> b
    $
                                     [ErrorItem] -> SolverReportErrCtxt -> [Hole] -> TcM ()
    reportHoles [ErrorItem]
    tidy_items SolverReportErrCtxt
    ctxt_for_scope_errs [Hole]
    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_for_insols = SolverReportErrCtxt
    ctxt { cec_suppress = not no_out_of_scope }
           ; [ErrorItem] -> SolverReportErrCtxt -> [Hole] -> TcM ()
    reportHoles [ErrorItem]
    tidy_items SolverReportErrCtxt
    ctxt_for_insols [Hole]
    other_holes
              -- holes never suppress

           ; SolverReportErrCtxt -> [NotConcreteError] -> TcM ()
    reportNotConcreteErrs SolverReportErrCtxt
    ctxt_for_insols [NotConcreteError]
    not_conc_errs

              -- See Note [Suppressing confusing errors]
           ; let ([ErrorItem]
    suppressed_items, [ErrorItem]
    items0) = (ErrorItem -> Bool) -> [ErrorItem] -> ([ErrorItem], [ErrorItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition ErrorItem -> Bool
    suppress [ErrorItem]
    tidy_items
           ; String -> SDoc -> TcM ()
    traceTc String
    "reportWanteds suppressed:" ([ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    suppressed_items)
           ; (SolverReportErrCtxt
    ctxt1, [ErrorItem]
    items1) <- SolverReportErrCtxt
    -> [ReporterSpec]
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    tryReporters SolverReportErrCtxt
    ctxt_for_insols [ReporterSpec]
    report1 [ErrorItem]
    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
    ctxt2 = SolverReportErrCtxt
    ctxt1 { cec_suppress = cec_suppress ctxt || cec_suppress ctxt1 }
           ; (SolverReportErrCtxt
    ctxt3, [ErrorItem]
    leftovers) <- SolverReportErrCtxt
    -> [ReporterSpec]
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    tryReporters SolverReportErrCtxt
    ctxt2 [ReporterSpec]
    report2 [ErrorItem]
    items1
           ; Bool -> SDoc -> TcM ()
    forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr ([ErrorItem] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [ErrorItem]
    leftovers)
               (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "The following unsolved Wanted constraints \
                     \have not been reported to the user:"
               SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ [ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    leftovers)

           ; (Implication -> TcM ()) -> Bag Implication -> TcM ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> Bag a -> m ()
    mapBagM_ (SolverReportErrCtxt -> Implication -> TcM ()
    reportImplic SolverReportErrCtxt
    ctxt2) Bag Implication
    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
           ; TcM () -> TcM ()
    whenNoErrs (TcM () -> TcM ()) -> TcM () -> TcM ()
    forall a b. (a -> b) -> a -> b
    $
             do { (SolverReportErrCtxt
    _, [ErrorItem]
    more_leftovers) <- SolverReportErrCtxt
    -> [ReporterSpec]
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    tryReporters SolverReportErrCtxt
    ctxt3 [ReporterSpec]
    forall {p}. [(String, ErrorItem -> p -> Bool, Bool, Reporter)]
    report3 [ErrorItem]
    suppressed_items
                ; Bool -> SDoc -> TcM ()
    forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr ([ErrorItem] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [ErrorItem]
    more_leftovers) ([ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    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)

                  , ReporterSpec
    given_eq_spec
                  , (String
    "insoluble2",      ErrorItem -> Pred -> Bool
    forall {p}. p -> Pred -> Bool
    utterly_wrong,  Bool
    True, (SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> [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 -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    mkGroupReporter (() :: Constraint) =>
    SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    SolverReportErrCtxt -> [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.Canonical
                  , (String
    "Homo eqs",      ErrorItem -> Pred -> Bool
    forall {p}. p -> Pred -> Bool
    is_homo_equality,  Bool
    True,  (SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mkEqErr)
                  , (String
    "Other eqs",     ErrorItem -> Pred -> Bool
    is_equality,       Bool
    True,  (SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> [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 -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mkIPErr)
                  , (String
    "Irreds",          ErrorItem -> Pred -> Bool
    is_irred,        Bool
    False, (SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mkIrredErr)
                  , (String
    "Dicts",           ErrorItem -> Pred -> Bool
    is_dict,         Bool
    False, (SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    mkGroupReporter (() :: Constraint) =>
    SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    SolverReportErrCtxt -> [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 -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> [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
    $ (() :: Constraint) => 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

        is_user_type_error :: ErrorItem -> p -> Bool
    is_user_type_error ErrorItem
    item p
    _ = Type -> Bool
    isUserTypeError (ErrorItem -> Type
    errorItemPred ErrorItem
    item)

        is_homo_equality :: p -> Pred -> Bool
    is_homo_equality p
    _ (EqPred EqRel
    _ Type
    ty1 Type
    ty2)
          = (() :: Constraint) => Type -> Type
    Type -> Type
    typeKind Type
    ty1 (() :: Constraint) => Type -> Type -> Bool
    Type -> Type -> Bool
    `tcEqType` (() :: Constraint) => 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.

    -}

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

    type Reporter
      = SolverReportErrCtxt -> [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 [ErrorItem]
    items
      = ([ErrorItem] -> TcM ()) -> [[ErrorItem]] -> TcM ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ ((SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    reportGroup SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mkEqErr SolverReportErrCtxt
    ctxt) ([ErrorItem] -> [[ErrorItem]]
    group [ErrorItem]
    items)
      where
         group :: [ErrorItem] -> [[ErrorItem]]
    group [] = []
         group (ErrorItem
    item:[ErrorItem]
    items) = (ErrorItem
    item ErrorItem -> [ErrorItem] -> [ErrorItem]
    forall a. a -> [a] -> [a]
    : [ErrorItem]
    yeses) [ErrorItem] -> [[ErrorItem]] -> [[ErrorItem]]
    forall a. a -> [a] -> [a]
    : [ErrorItem] -> [[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
          DiagOpts
    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 :: Severity
    severity = DiagOpts -> DiagnosticReason -> Severity
    diagReasonSeverity DiagOpts
    diag_opts (SolverReportErrCtxt -> DiagnosticReason
    cec_type_holes SolverReportErrCtxt
    ctxt)
              holes' :: [Hole]
    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.
          (TidyEnv
    tidy_env', NameEnv Type
    lcl_name_cache) <- TidyEnv -> [TcLclEnv] -> TcM (TidyEnv, NameEnv Type)
    zonkTidyTcLclEnvs (SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt) ((Hole -> TcLclEnv) -> [Hole] -> [TcLclEnv]
    forall a b. (a -> b) -> [a] -> [b]
    map (CtLoc -> TcLclEnv
    ctl_env (CtLoc -> TcLclEnv) -> (Hole -> CtLoc) -> Hole -> TcLclEnv
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Hole -> CtLoc
    hole_loc) [Hole]
    holes')
          let ctxt' :: SolverReportErrCtxt
    ctxt' = SolverReportErrCtxt
    ctxt { cec_tidy = tidy_env' }
          [Hole] -> (Hole -> TcM ()) -> TcM ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ [Hole]
    holes' ((Hole -> TcM ()) -> TcM ()) -> (Hole -> TcM ()) -> TcM ()
    forall a b. (a -> b) -> a -> b
    $ \Hole
    hole -> do { MsgEnvelope TcRnMessage
    msg <- NameEnv Type
    -> [ErrorItem]
    -> SolverReportErrCtxt
    -> Hole
    -> TcM (MsgEnvelope TcRnMessage)
    mkHoleError NameEnv Type
    lcl_name_cache [ErrorItem]
    tidy_items SolverReportErrCtxt
    ctxt' Hole
    hole
                                     ; MsgEnvelope TcRnMessage -> TcM ()
    reportDiagnostic MsgEnvelope TcRnMessage
    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 'TcLclEnv'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  'TcLclEnv'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 -> [TcLclEnv] -> TcM (TidyEnv, NameEnv Type)
    zonkTidyTcLclEnvs :: TidyEnv -> [TcLclEnv] -> TcM (TidyEnv, NameEnv Type)
    zonkTidyTcLclEnvs TidyEnv
    tidy_env [TcLclEnv]
    lcls = ((TidyEnv, NameEnv Type)
     -> TcBinder -> TcM (TidyEnv, NameEnv Type))
    -> (TidyEnv, NameEnv Type)
    -> [TcBinder]
    -> TcM (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 -> TcM (TidyEnv, NameEnv Type)
    go (TidyEnv
    tidy_env, NameEnv Type
    forall a. NameEnv a
    emptyNameEnv) ((TcLclEnv -> [TcBinder]) -> [TcLclEnv] -> [TcBinder]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap TcLclEnv -> [TcBinder]
    tcl_bndrs [TcLclEnv]
    lcls)
      where
        go :: (TidyEnv, NameEnv Type) -> TcBinder -> TcM (TidyEnv, NameEnv Type)
    go (TidyEnv, NameEnv Type)
    envs TcBinder
    tc_bndr = case TcBinder
    tc_bndr of
              TcTvBndr {} -> (TidyEnv, NameEnv Type) -> TcM (TidyEnv, NameEnv Type)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) 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) -> TcM (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 { Maybe Type
    mb_ty <- ExpType -> TcM (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 Maybe Type
    mb_ty of
                       Just Type
    ty -> Name
    -> Type -> (TidyEnv, NameEnv Type) -> TcM (TidyEnv, NameEnv Type)
    go_one Name
    name Type
    ty (TidyEnv, NameEnv Type)
    envs
                       Maybe Type
    Nothing -> (TidyEnv, NameEnv Type) -> TcM (TidyEnv, NameEnv Type)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv, NameEnv Type)
    envs
                   }
        go_one :: Name
    -> Type -> (TidyEnv, NameEnv Type) -> TcM (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) -> TcM (TidyEnv, NameEnv Type)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    tidy_env, NameEnv Type
    name_env)
                  else do
                    (TidyEnv
    tidy_env', Type
    tidy_ty) <- TidyEnv -> Type -> TcM (TidyEnv, Type)
    zonkTidyTcType TidyEnv
    tidy_env Type
    ty
                    (TidyEnv, NameEnv Type) -> TcM (TidyEnv, NameEnv Type)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TidyEnv
    tidy_env',  NameEnv Type -> Name -> Type -> NameEnv Type
    forall a. NameEnv a -> Name -> a -> NameEnv a
    extendNameEnv NameEnv Type
    name_env Name
    name Type
    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 { MsgEnvelope TcRnMessage
    msg <- TcLclEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport (CtLoc -> TcLclEnv
    ctLocEnv (NotConcreteError -> CtLoc
    nce_loc NotConcreteError
    err0)) TcRnMessage
    diag (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt) []
           ; MsgEnvelope TcRnMessage -> TcM ()
    reportDiagnostic MsgEnvelope TcRnMessage
    msg }

      where

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

        -- 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 ()) -> [ErrorItem] -> TcM ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ ((ErrorItem -> TcM ()) -> [ErrorItem] -> TcM ())
    -> (ErrorItem -> TcM ()) -> [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 -> [ErrorItem] -> SolverReport -> TcM ()
    maybeReportError SolverReportErrCtxt
    ctxt [ErrorItem
    item] SolverReport
    err
                            ; SolverReportErrCtxt -> SolverReport -> ErrorItem -> TcM ()
    addDeferredBinding SolverReportErrCtxt
    ctxt SolverReport
    err ErrorItem
    item }

    mkUserTypeError :: ErrorItem -> TcSolverReportMsg
    mkUserTypeError :: ErrorItem -> TcSolverReportMsg
    mkUserTypeError ErrorItem
    item =
      case Type -> Maybe Type
    getUserTypeErrorMsg (ErrorItem -> Type
    errorItemPred ErrorItem
    item) of
        Just Type
    msg -> Type -> TcSolverReportMsg
    UserTypeError Type
    msg
        Maybe Type
    Nothing  -> String -> SDoc -> TcSolverReportMsg
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "mkUserTypeError" (ErrorItem -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ErrorItem
    item)

    mkGivenErrorReporter :: Reporter
    -- See Note [Given errors]
    mkGivenErrorReporter :: Reporter
    mkGivenErrorReporter SolverReportErrCtxt
    ctxt [ErrorItem]
    items
      = do { (SolverReportErrCtxt
    ctxt, RelevantBindings
    relevant_binds, ErrorItem
    item) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item
           ; let (Implication
    implic:[Implication]
    _) = SolverReportErrCtxt -> [Implication]
    cec_encl SolverReportErrCtxt
    ctxt
                     -- Always non-empty when mkGivenErrorReporter is called
                 loc' :: CtLoc
    loc'  = CtLoc -> TcLclEnv -> CtLoc
    setCtLocEnv (ErrorItem -> CtLoc
    ei_loc ErrorItem
    item) (Implication -> TcLclEnv
    ic_env Implication
    implic)
                 item' :: ErrorItem
    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]

           ; (TcSolverReportMsg
    eq_err_msg, [GhcHint]
    _hints) <- SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM (TcSolverReportMsg, [GhcHint])
    mkEqErr_help SolverReportErrCtxt
    ctxt ErrorItem
    item' Type
    ty1 Type
    ty2
           -- The hints wouldn't help in this situation, so we discard them.
           ; let supplementary :: [SolverReportSupplementary]
    supplementary = [ RelevantBindings -> SolverReportSupplementary
    SupplementaryBindings RelevantBindings
    relevant_binds ]
                 msg :: TcRnMessage
    msg = Implication -> SolverReportWithCtxt -> TcRnMessage
    TcRnInaccessibleCode Implication
    implic (SolverReportErrCtxt -> TcSolverReportMsg -> SolverReportWithCtxt
    SolverReportWithCtxt SolverReportErrCtxt
    ctxt TcSolverReportMsg
    eq_err_msg)
           ; MsgEnvelope TcRnMessage
    msg <- TcLclEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport (CtLoc -> TcLclEnv
    ctLocEnv CtLoc
    loc') TcRnMessage
    msg (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt) [SolverReportSupplementary]
    supplementary
           ; MsgEnvelope TcRnMessage -> TcM ()
    reportDiagnostic MsgEnvelope TcRnMessage
    msg }
      where
        (ErrorItem
    item : [ErrorItem]
    _ )  = [ErrorItem]
    items    -- Never empty
        (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 [ErrorItem]
    items
      = do { String -> SDoc -> TcM ()
    traceTc String
    "mkGivenErrorReporter no" ([ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [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 -> [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 -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    mkGroupReporter SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mk_err SolverReportErrCtxt
    ctxt [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 -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    reportGroup SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mk_err SolverReportErrCtxt
    ctxt ([ErrorItem] -> TcM ())
    -> (NonEmpty ErrorItem -> [ErrorItem])
    -> NonEmpty ErrorItem
    -> TcM ()
    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) ((ErrorItem -> ErrorItem -> Ordering)
    -> [ErrorItem] -> [NonEmpty ErrorItem]
    forall a. (a -> a -> Ordering) -> [a] -> [NonEmpty a]
    equivClasses ErrorItem -> ErrorItem -> Ordering
    cmp_loc [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 -> [ErrorItem] -> TcM SolverReport) -> Reporter
    reportGroup :: (SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport)
    -> Reporter
    reportGroup SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mk_err SolverReportErrCtxt
    ctxt [ErrorItem]
    items
      = do { SolverReport
    err <- SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mk_err SolverReportErrCtxt
    ctxt [ErrorItem]
    items
           ; String -> SDoc -> TcM ()
    traceTc String
    "About to maybeReportErr" (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
    "Constraint:"             SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    items
                  , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "cec_suppress ="          SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Bool -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (SolverReportErrCtxt -> Bool
    cec_suppress SolverReportErrCtxt
    ctxt)
                  , String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "cec_defer_type_errors =" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> DiagnosticReason -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (SolverReportErrCtxt -> DiagnosticReason
    cec_defer_type_errors SolverReportErrCtxt
    ctxt) ]
           ; SolverReportErrCtxt -> [ErrorItem] -> SolverReport -> TcM ()
    maybeReportError SolverReportErrCtxt
    ctxt [ErrorItem]
    items SolverReport
    err
               -- But see Note [Always warn with -fdefer-type-errors]
           ; String -> SDoc -> TcM ()
    traceTc String
    "reportGroup" ([ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    items)
           ; (ErrorItem -> TcM ()) -> [ErrorItem] -> TcM ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ (SolverReportErrCtxt -> SolverReport -> ErrorItem -> TcM ()
    addDeferredBinding SolverReportErrCtxt
    ctxt SolverReport
    err) [ErrorItem]
    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 CtOrigin
    NonLinearPatternOrigin  = Bool
    True
    nonDeferrableOrigin (UsageEnvironmentOf {}) = Bool
    True
    nonDeferrableOrigin (FRROrigin {})          = Bool
    True
    nonDeferrableOrigin CtOrigin
    _                       = Bool
    False

    maybeReportError :: SolverReportErrCtxt
                     -> [ErrorItem]     -- items covered by the Report
                     -> SolverReport -> TcM ()
    maybeReportError :: SolverReportErrCtxt -> [ErrorItem] -> SolverReport -> TcM ()
    maybeReportError SolverReportErrCtxt
    ctxt items :: [ErrorItem]
    items@(ErrorItem
    item1:[ErrorItem]
    _) (SolverReport { sr_important_msg :: SolverReport -> SolverReportWithCtxt
    sr_important_msg = SolverReportWithCtxt
    important
                                                        , sr_supplementary :: SolverReport -> [SolverReportSupplementary]
    sr_supplementary = [SolverReportSupplementary]
    supp
                                                        , sr_hints :: SolverReport -> [GhcHint]
    sr_hints = [GhcHint]
    hints })
      = 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) -> [ErrorItem] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all ErrorItem -> Bool
    ei_suppress [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) -> [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) [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 -> [GhcHint] -> TcRnMessage
    TcRnSolverReport SolverReportWithCtxt
    important DiagnosticReason
    reason [GhcHint]
    hints
           MsgEnvelope TcRnMessage
    msg <- TcLclEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport (CtLoc -> TcLclEnv
    ctLocEnv (ErrorItem -> CtLoc
    errorItemCtLoc ErrorItem
    item1)) TcRnMessage
    diag (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt) [SolverReportSupplementary]
    supp
           MsgEnvelope TcRnMessage -> TcM ()
    reportDiagnostic MsgEnvelope TcRnMessage
    msg
    maybeReportError SolverReportErrCtxt
    _ [ErrorItem]
    _ SolverReport
    _ = String -> TcM ()
    forall a. HasCallStack => String -> a
    panic String
    "maybeReportError"

    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 { EvTerm
    err_tm <- SolverReportErrCtxt -> CtLoc -> Type -> SolverReport -> TcM EvTerm
    mkErrorTerm SolverReportErrCtxt
    ctxt CtLoc
    loc Type
    item_ty SolverReport
    err
           ; let ev_binds_var :: EvBindsVar
    ev_binds_var = SolverReportErrCtxt -> EvBindsVar
    cec_binds SolverReportErrCtxt
    ctxt

           ; case TcEvDest
    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 -> EvTerm -> EvBind
    mkWantedEvBind TcId
    evar 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 -> EvTerm -> EvBind
    mkWantedEvBind TcId
    co_var 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 { MsgEnvelope TcRnMessage
    msg <- TcLclEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport
                      (CtLoc -> TcLclEnv
    ctLocEnv CtLoc
    ct_loc)
                      (SolverReportWithCtxt
    -> DiagnosticReason -> [GhcHint] -> TcRnMessage
    TcRnSolverReport SolverReportWithCtxt
    important DiagnosticReason
    ErrorWithoutFlag [GhcHint]
    noHints) (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:"
           ; DynFlags
    dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
           ; let err_msg :: SDoc
    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 :: String
    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)"

           ; EvTerm -> TcM EvTerm
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EvTerm -> TcM EvTerm) -> EvTerm -> TcM EvTerm
    forall a b. (a -> b) -> a -> b
    $ Type -> String -> EvTerm
    evDelayedError Type
    ty String
    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)
           ; (SolverReportErrCtxt
    ctxt', [ErrorItem]
    items') <- SolverReportErrCtxt
    -> [ReporterSpec]
    -> [ErrorItem]
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    go SolverReportErrCtxt
    ctxt [ReporterSpec]
    reporters [ErrorItem]
    vis_items [ErrorItem]
    invis_items
           ; String -> SDoc -> TcM ()
    traceTc String
    "tryReporters }" ([ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    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]
    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 { (SolverReportErrCtxt
    ctxt', [ErrorItem]
    vis_items') <- SolverReportErrCtxt
    -> ReporterSpec
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    tryReporter SolverReportErrCtxt
    ctxt ReporterSpec
    r [ErrorItem]
    vis_items
               ; (SolverReportErrCtxt
    ctxt'', [ErrorItem]
    invis_items') <- SolverReportErrCtxt
    -> ReporterSpec
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    tryReporter SolverReportErrCtxt
    ctxt' ReporterSpec
    r [ErrorItem]
    invis_items
               ; SolverReportErrCtxt
    -> [ReporterSpec]
    -> [ErrorItem]
    -> [ErrorItem]
    -> TcM (SolverReportErrCtxt, [ErrorItem])
    go SolverReportErrCtxt
    ctxt'' [ReporterSpec]
    rs [ErrorItem]
    vis_items' [ErrorItem]
    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
      | [ErrorItem] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [ErrorItem]
    yeses
      = (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]
    items)
      | Bool
    otherwise
      = 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
    <+> [ErrorItem] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [ErrorItem]
    yeses)
           ; (()
    _, Bool
    no_errs) <- TcM () -> TcRn ((), Bool)
    forall a. TcRn a -> TcRn (a, Bool)
    askNoErrs (Reporter
    reporter SolverReportErrCtxt
    ctxt [ErrorItem]
    yeses)
           ; let suppress_now :: Bool
    suppress_now   = Bool -> Bool
    not Bool
    no_errs Bool -> Bool -> Bool
    && Bool
    suppress_after
                                -- See Note [Suppressing error messages]
                 ctxt' :: SolverReportErrCtxt
    ctxt' = SolverReportErrCtxt
    ctxt { cec_suppress = suppress_now || cec_suppress ctxt }
           ; String -> SDoc -> TcM ()
    traceTc String
    "tryReporter end }" (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    str SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Bool -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (SolverReportErrCtxt -> Bool
    cec_suppress SolverReportErrCtxt
    ctxt) SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Bool -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Bool
    suppress_after)
           ; (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]
    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 :: TcLclEnv
                  -> 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 :: TcLclEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport TcLclEnv
    tcl_env TcRnMessage
    msg Maybe SolverReportErrCtxt
    mb_ctxt [SolverReportSupplementary]
    supplementary
      = do { Maybe SDoc
    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) (TcLclEnv -> [ErrCtxt]
    tcl_ctxt TcLclEnv
    tcl_env)) Maybe SolverReportErrCtxt
    mb_ctxt
           ; UnitState
    unit_state <- (() :: Constraint) => HscEnv -> UnitState
    HscEnv -> UnitState
    hsc_units (HscEnv -> UnitState)
    -> IOEnv (Env TcGblEnv TcLclEnv) HscEnv
    -> IOEnv (Env TcGblEnv TcLclEnv) UnitState
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IOEnv (Env TcGblEnv TcLclEnv) HscEnv
    forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
           ; HoleFitDispConfig
    hfdc <- TcM HoleFitDispConfig
    getHoleFitDispConfig
           ; let
               err_info :: ErrInfo
    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 :: TcRnMessageDetailed
    detailed_msg = ErrInfo -> TcRnMessage -> TcRnMessageDetailed
    mkDetailedMessage ErrInfo
    err_info TcRnMessage
    msg
           ; SrcSpan -> TcRnMessage -> TcM (MsgEnvelope TcRnMessage)
    mkTcRnMessage
               (RealSrcSpan -> Maybe BufSpan -> SrcSpan
    RealSrcSpan (TcLclEnv -> RealSrcSpan
    tcl_loc TcLclEnv
    tcl_env) Maybe BufSpan
    forall a. Maybe a
    Strict.Nothing)
               (UnitState -> TcRnMessageDetailed -> TcRnMessage
    TcRnMessageWithInfo UnitState
    unit_state (TcRnMessageDetailed -> TcRnMessage)
    -> TcRnMessageDetailed -> TcRnMessage
    forall a b. (a -> b) -> a -> b
    $ TcRnMessageDetailed
    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 -> [ErrorItem] -> TcM SolverReport
    mkIrredErr :: SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mkIrredErr SolverReportErrCtxt
    ctxt [ErrorItem]
    items
      = do { (SolverReportErrCtxt
    ctxt, RelevantBindings
    binds, ErrorItem
    item1) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item1
           ; let msg :: SolverReport
    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
           ; SolverReport -> TcM SolverReport
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SolverReport -> TcM SolverReport)
    -> SolverReport -> TcM SolverReport
    forall a b. (a -> b) -> a -> b
    $ RelevantBindings -> SolverReport -> SolverReport
    add_relevant_bindings RelevantBindings
    binds SolverReport
    msg  }
      where
        (ErrorItem
    item1:[ErrorItem]
    others) = [ErrorItem]
    final_items

        filtered_items :: [ErrorItem]
    filtered_items = (ErrorItem -> Bool) -> [ErrorItem] -> [ErrorItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (ErrorItem -> Bool) -> ErrorItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorItem -> Bool
    ei_suppress) [ErrorItem]
    items
        final_items :: [ErrorItem]
    final_items | [ErrorItem] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [ErrorItem]
    filtered_items = [ErrorItem]
    items
                        -- they're all suppressed; must report *something*
                        -- NB: even though reportWanteds asserts that not
                        -- all items are suppressed, it's possible all the
                        -- irreducibles are suppressed, and so this function
                        -- might get all suppressed items
                    | Bool
    otherwise           = [ErrorItem]
    filtered_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 { DynFlags
    dflags  <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
           ; GlobalRdrEnv
    rdr_env <- TcRn GlobalRdrEnv
    getGlobalRdrEnv
           ; ImportAvails
    imp_info <- TcRn ImportAvails
    getImports
           ; Module
    curr_mod <- IOEnv (Env TcGblEnv TcLclEnv) Module
    forall (m :: * -> *). HasModule m => m Module
    getModule
           ; HomePackageTable
    hpt <- TcRnIf TcGblEnv TcLclEnv HomePackageTable
    forall gbl lcl. TcRnIf gbl lcl HomePackageTable
    getHpt
           ; let ([ImportError]
    imp_errs, [GhcHint]
    hints)
                    = WhatLooking
    -> DynFlags
    -> HomePackageTable
    -> Module
    -> GlobalRdrEnv
    -> LocalRdrEnv
    -> ImportAvails
    -> RdrName
    -> ([ImportError], [GhcHint])
    unknownNameSuggestions WhatLooking
    WL_Anything
                        DynFlags
    dflags HomePackageTable
    hpt Module
    curr_mod GlobalRdrEnv
    rdr_env
                        (TcLclEnv -> LocalRdrEnv
    tcl_rdr TcLclEnv
    lcl_env) ImportAvails
    imp_info RdrName
    occ
                 err :: SolverReportWithCtxt
    err    = SolverReportErrCtxt -> TcSolverReportMsg -> SolverReportWithCtxt
    SolverReportWithCtxt SolverReportErrCtxt
    ctxt (Hole -> HoleError -> TcSolverReportMsg
    ReportHoleError Hole
    hole (HoleError -> TcSolverReportMsg) -> HoleError -> TcSolverReportMsg
    forall a b. (a -> b) -> a -> b
    $ [ImportError] -> HoleError
    OutOfScopeHole [ImportError]
    imp_errs)
                 report :: SolverReport
    report = SolverReportWithCtxt
    -> [SolverReportSupplementary] -> [GhcHint] -> SolverReport
    SolverReport SolverReportWithCtxt
    err [] [GhcHint]
    hints

           ; SolverReportErrCtxt -> Hole -> SolverReport -> TcM ()
    maybeAddDeferredBindings SolverReportErrCtxt
    ctxt Hole
    hole SolverReport
    report
           ; TcLclEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport TcLclEnv
    lcl_env (SolverReportWithCtxt
    -> DiagnosticReason -> [GhcHint] -> TcRnMessage
    TcRnSolverReport SolverReportWithCtxt
    err (SolverReportErrCtxt -> DiagnosticReason
    cec_out_of_scope_holes SolverReportErrCtxt
    ctxt) [GhcHint]
    hints) Maybe SolverReportErrCtxt
    forall a. Maybe a
    Nothing []
              -- Pass the value 'Nothing' for the context, as it's generally not helpful
              -- to include the context here.
           }
      where
        lcl_env :: TcLclEnv
    lcl_env = CtLoc -> TcLclEnv
    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 { RelevantBindings
    rel_binds
               <- Bool
    -> TcLclEnv -> NameEnv Type -> TyCoVarSet -> TcM RelevantBindings
    relevant_bindings Bool
    False TcLclEnv
    lcl_env NameEnv Type
    lcl_name_cache (Type -> TyCoVarSet
    tyCoVarsOfType Type
    hole_ty)
                   -- The 'False' means "don't filter the bindings"; see #8191

           ; Bool
    show_hole_constraints <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
    goptM GeneralFlag
    Opt_ShowHoleConstraints
           ; let relevant_cts :: [(Type, RealSrcSpan)]
    relevant_cts
                   | ExprHole HoleExprRef
    _ <- HoleSort
    sort, Bool
    show_hole_constraints
                   = SolverReportErrCtxt -> [(Type, RealSrcSpan)]
    givenConstraints SolverReportErrCtxt
    ctxt
                   | Bool
    otherwise
                   = []

           ; Bool
    show_valid_hole_fits <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
    goptM GeneralFlag
    Opt_ShowValidHoleFits
           ; (SolverReportErrCtxt
    ctxt, ValidHoleFits
    hole_fits) <- if Bool
    show_valid_hole_fits
                                  then SolverReportErrCtxt
    -> [ErrorItem] -> Hole -> TcM (SolverReportErrCtxt, ValidHoleFits)
    validHoleFits SolverReportErrCtxt
    ctxt [ErrorItem]
    tidy_simples Hole
    hole
                                  else (SolverReportErrCtxt, ValidHoleFits)
    -> TcM (SolverReportErrCtxt, ValidHoleFits)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SolverReportErrCtxt
    ctxt, ValidHoleFits
    noValidHoleFits)
           ; ([(SkolemInfoAnon, [TcId])]
    grouped_skvs, [TcId]
    other_tvs) <- Type -> TcM ([(SkolemInfoAnon, [TcId])], [TcId])
    zonkAndGroupSkolTvs Type
    hole_ty
           ; let reason :: DiagnosticReason
    reason | ExprHole HoleExprRef
    _ <- HoleSort
    sort = SolverReportErrCtxt -> DiagnosticReason
    cec_expr_holes SolverReportErrCtxt
    ctxt
                        | Bool
    otherwise          = SolverReportErrCtxt -> DiagnosticReason
    cec_type_holes SolverReportErrCtxt
    ctxt
                 err :: SolverReportWithCtxt
    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 :: [SolverReportSupplementary]
    supp = [ RelevantBindings -> SolverReportSupplementary
    SupplementaryBindings RelevantBindings
    rel_binds
                        , [(Type, RealSrcSpan)] -> SolverReportSupplementary
    SupplementaryCts      [(Type, RealSrcSpan)]
    relevant_cts
                        , ValidHoleFits -> SolverReportSupplementary
    SupplementaryHoleFits ValidHoleFits
    hole_fits ]

           ; SolverReportErrCtxt -> Hole -> SolverReport -> TcM ()
    maybeAddDeferredBindings SolverReportErrCtxt
    ctxt Hole
    hole (SolverReportWithCtxt
    -> [SolverReportSupplementary] -> [GhcHint] -> SolverReport
    SolverReport SolverReportWithCtxt
    err [SolverReportSupplementary]
    supp [])

           ; TcLclEnv
    -> TcRnMessage
    -> Maybe SolverReportErrCtxt
    -> [SolverReportSupplementary]
    -> TcM (MsgEnvelope TcRnMessage)
    mkErrorReport TcLclEnv
    lcl_env (SolverReportWithCtxt
    -> DiagnosticReason -> [GhcHint] -> TcRnMessage
    TcRnSolverReport SolverReportWithCtxt
    err DiagnosticReason
    reason [GhcHint]
    noHints) (SolverReportErrCtxt -> Maybe SolverReportErrCtxt
    forall a. a -> Maybe a
    Just SolverReportErrCtxt
    ctxt) [SolverReportSupplementary]
    supp
           }

      where
        lcl_env :: TcLclEnv
    lcl_env = CtLoc -> TcLclEnv
    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 -> TcM ([(SkolemInfoAnon, [TcTyVar])], [TcTyVar])
    zonkAndGroupSkolTvs :: Type -> TcM ([(SkolemInfoAnon, [TcId])], [TcId])
    zonkAndGroupSkolTvs Type
    hole_ty = do
      [(SkolemInfoAnon, [TcId])]
    zonked_info <- ((SkolemInfo, [(TcId, Int)])
     -> IOEnv (Env TcGblEnv TcLclEnv) (SkolemInfoAnon, [TcId]))
    -> [(SkolemInfo, [(TcId, Int)])]
    -> IOEnv (Env TcGblEnv TcLclEnv) [(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
    sk, [(TcId, Int)]
    tv) -> (,) (SkolemInfoAnon -> [TcId] -> (SkolemInfoAnon, [TcId]))
    -> IOEnv (Env TcGblEnv TcLclEnv) SkolemInfoAnon
    -> IOEnv
         (Env TcGblEnv TcLclEnv) ([TcId] -> (SkolemInfoAnon, [TcId]))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (SkolemInfoAnon -> IOEnv (Env TcGblEnv TcLclEnv) SkolemInfoAnon
    zonkSkolemInfoAnon (SkolemInfoAnon -> IOEnv (Env TcGblEnv TcLclEnv) SkolemInfoAnon)
    -> (SkolemInfo -> SkolemInfoAnon)
    -> SkolemInfo
    -> IOEnv (Env TcGblEnv TcLclEnv) SkolemInfoAnon
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SkolemInfo -> SkolemInfoAnon
    getSkolemInfo (SkolemInfo -> IOEnv (Env TcGblEnv TcLclEnv) SkolemInfoAnon)
    -> SkolemInfo -> IOEnv (Env TcGblEnv TcLclEnv) SkolemInfoAnon
    forall a b. (a -> b) -> a -> b
    $ SkolemInfo
    sk) IOEnv (Env TcGblEnv TcLclEnv) ([TcId] -> (SkolemInfoAnon, [TcId]))
    -> IOEnv (Env TcGblEnv TcLclEnv) [TcId]
    -> IOEnv (Env TcGblEnv TcLclEnv) (SkolemInfoAnon, [TcId])
    forall a b.
    IOEnv (Env TcGblEnv TcLclEnv) (a -> b)
    -> IOEnv (Env TcGblEnv TcLclEnv) a
    -> IOEnv (Env TcGblEnv TcLclEnv) b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> [TcId] -> IOEnv (Env TcGblEnv TcLclEnv) [TcId]
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ((TcId, Int) -> TcId
    forall a b. (a, b) -> a
    fst ((TcId, Int) -> TcId) -> [(TcId, Int)] -> [TcId]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [(TcId, Int)]
    tv)) [(SkolemInfo, [(TcId, Int)])]
    skolem_list
      ([(SkolemInfoAnon, [TcId])], [TcId])
    -> TcM ([(SkolemInfoAnon, [TcId])], [TcId])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(SkolemInfoAnon, [TcId])]
    zonked_info, [TcId]
    other_tvs)
      where
        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
    tv -> TcId -> Bool
    isTcTyVar TcId
    tv Bool -> Bool -> Bool
    && TcId -> Bool
    isSkolemTyVar TcId
    tv) [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)) (UniqMap SkolemInfo [(TcId, Int)] -> [(SkolemInfo, [(TcId, Int)])]
    forall k a. UniqMap k a -> [(k, a)]
    UM.nonDetEltsUniqMap 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
            EvTerm
    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
            IORef EvTerm -> EvTerm -> TcM ()
    forall a env. IORef a -> a -> IOEnv env ()
    writeMutVar IORef EvTerm
    ref EvTerm
    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 { (TidyEnv
    tidy_env, ValidHoleFits
    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
           ; (SolverReportErrCtxt, ValidHoleFits)
    -> TcM (SolverReportErrCtxt, ValidHoleFits)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SolverReportErrCtxt
    ctxt {cec_tidy = tidy_env}, ValidHoleFits
    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 :: Implication
    implic@Implic{ ic_given :: Implication -> [TcId]
    ic_given = [TcId]
    given } <- SolverReportErrCtxt -> [Implication]
    cec_encl SolverReportErrCtxt
    ctxt
           ; TcId
    constraint <- [TcId]
    given
           ; (Type, RealSrcSpan) -> [(Type, RealSrcSpan)]
    forall a. a -> [a]
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcId -> Type
    varType TcId
    constraint, TcLclEnv -> RealSrcSpan
    tcl_loc (Implication -> TcLclEnv
    ic_env Implication
    implic)) }

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

    mkIPErr :: SolverReportErrCtxt -> [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 -> [ErrorItem] -> TcM SolverReport
    mkIPErr SolverReportErrCtxt
    ctxt [ErrorItem]
    items
      = do { (SolverReportErrCtxt
    ctxt, RelevantBindings
    binds, ErrorItem
    item1) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item1
           ; let msg :: SolverReport
    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)
           ; SolverReport -> TcM SolverReport
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SolverReport -> TcM SolverReport)
    -> SolverReport -> TcM SolverReport
    forall a b. (a -> b) -> a -> b
    $ RelevantBindings -> SolverReport -> SolverReport
    add_relevant_bindings RelevantBindings
    binds SolverReport
    msg }
      where
        ErrorItem
    item1:[ErrorItem]
    others = [ErrorItem]
    items

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

    -- | 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 -> [ErrorItem] -> TcM SolverReport
    mkFRRErr :: (() :: Constraint) =>
    SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mkFRRErr SolverReportErrCtxt
    ctxt [ErrorItem]
    items
      = do { -- Process the error items.
           ; (TidyEnv
    _tidy_env, [FixedRuntimeRepErrorInfo]
    frr_infos) <-
              TidyEnv
    -> [FixedRuntimeRepErrorInfo]
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    zonkTidyFRRInfos (SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt) ([FixedRuntimeRepErrorInfo]
     -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo]))
    -> [FixedRuntimeRepErrorInfo]
    -> TcM (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
    . (() :: Constraint) => ErrorItem -> Maybe FixedRuntimeRepErrorInfo
    ErrorItem -> Maybe FixedRuntimeRepErrorInfo
    fixedRuntimeRepOrigin_maybe)
              [ErrorItem]
    items
           ; SolverReport -> TcM SolverReport
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SolverReport -> TcM SolverReport)
    -> SolverReport -> TcM SolverReport
    forall a b. (a -> b) -> a -> b
    $ SolverReportErrCtxt -> TcSolverReportMsg -> SolverReport
    important SolverReportErrCtxt
    ctxt (TcSolverReportMsg -> SolverReport)
    -> TcSolverReportMsg -> SolverReport
    forall a b. (a -> b) -> a -> b
    $ [FixedRuntimeRepErrorInfo] -> TcSolverReportMsg
    FixedRuntimeRepError [FixedRuntimeRepErrorInfo]
    frr_infos }

    -- | Whether to report something using the @FixedRuntimeRep@ mechanism.
    fixedRuntimeRepOrigin_maybe :: HasDebugCallStack => ErrorItem -> Maybe FixedRuntimeRepErrorInfo
    fixedRuntimeRepOrigin_maybe :: (() :: Constraint) => 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 }
      -- Unsolved nominal equalities involving a concrete type variable,
      -- such as @alpha[conc] ~# rr[sk]@ or @beta[conc] ~# RR@ for a
      -- type family application @RR@, are handled by 'mkTyVarEqErr''.
      | 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 -> [ErrorItem] -> TcM SolverReport
    mkEqErr :: SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mkEqErr SolverReportErrCtxt
    ctxt [ErrorItem]
    items
      | ErrorItem
    item:[ErrorItem]
    _ <- (ErrorItem -> Bool) -> [ErrorItem] -> [ErrorItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (ErrorItem -> Bool) -> ErrorItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorItem -> Bool
    ei_suppress) [ErrorItem]
    items
      = SolverReportErrCtxt -> ErrorItem -> TcM SolverReport
    mkEqErr1 SolverReportErrCtxt
    ctxt ErrorItem
    item

      | ErrorItem
    item:[ErrorItem]
    _ <- [ErrorItem]
    items  -- they're all suppressed. still need an error message
                         -- for -fdefer-type-errors though
      = SolverReportErrCtxt -> ErrorItem -> TcM SolverReport
    mkEqErr1 SolverReportErrCtxt
    ctxt ErrorItem
    item

      | Bool
    otherwise
      = String -> TcM SolverReport
    forall a. HasCallStack => String -> a
    panic String
    "mkEqErr"  -- guaranteed to have at least one item

    mkEqErr1 :: SolverReportErrCtxt -> ErrorItem -> TcM SolverReport
    mkEqErr1 :: SolverReportErrCtxt -> ErrorItem -> TcM SolverReport
    mkEqErr1 SolverReportErrCtxt
    ctxt ErrorItem
    item   -- Wanted only
                         -- givens handled in mkGivenErrorReporter
      = do { (SolverReportErrCtxt
    ctxt, RelevantBindings
    binds, ErrorItem
    item) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item
           ; String -> SDoc -> TcM ()
    traceTc String
    "mkEqErr1" (ErrorItem -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ErrorItem
    item SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ CtOrigin -> SDoc
    pprCtOrigin (ErrorItem -> CtOrigin
    errorItemOrigin ErrorItem
    item))
           ; (TcSolverReportMsg
    err_msg, [GhcHint]
    hints) <- SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM (TcSolverReportMsg, [GhcHint])
    mkEqErr_help SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
           ; let
               report :: SolverReport
    report = RelevantBindings -> SolverReport -> SolverReport
    add_relevant_bindings RelevantBindings
    binds
                      (SolverReport -> SolverReport) -> SolverReport -> SolverReport
    forall a b. (a -> b) -> a -> b
    $ [GhcHint] -> SolverReport -> SolverReport
    add_report_hints [GhcHint]
    hints
                      (SolverReport -> SolverReport) -> SolverReport -> SolverReport
    forall a b. (a -> b) -> a -> b
    $ SolverReportErrCtxt -> TcSolverReportMsg -> SolverReport
    important SolverReportErrCtxt
    ctxt TcSolverReportMsg
    err_msg
           ; SolverReport -> TcM SolverReport
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return SolverReport
    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) <- (() :: Constraint) => 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 GlobalRdrElt -> Bool
    forall a. Maybe a -> Bool
    isNothing (GlobalRdrEnv -> Name -> Maybe GlobalRdrElt
    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, [GhcHint])
    mkEqErr_help :: SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM (TcSolverReportMsg, [GhcHint])
    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, [GhcHint])
    mkTyVarEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId, TcCoercionN)
    casted_tv1 Type
    ty2
      | Just (TcId, TcCoercionN)
    casted_tv2 <- Type -> Maybe (TcId, TcCoercionN)
    getCastedTyVar_maybe Type
    ty2
      = SolverReportErrCtxt
    -> ErrorItem
    -> (TcId, TcCoercionN)
    -> Type
    -> TcM (TcSolverReportMsg, [GhcHint])
    mkTyVarEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId, TcCoercionN)
    casted_tv2 Type
    ty1
      | Bool
    otherwise
      = do
        TcSolverReportMsg
    err <- SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM TcSolverReportMsg
    reportEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
        (TcSolverReportMsg, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg
    err, [GhcHint]
    noHints)

    reportEqErr :: SolverReportErrCtxt
                -> ErrorItem
                -> TcType -> TcType
                -> TcM TcSolverReportMsg
    reportEqErr :: SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM TcSolverReportMsg
    reportEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
      = do
        Maybe CoercibleMsg
    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
        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
    $
          Mismatch
           { mismatchMsg :: MismatchMsg
    mismatchMsg           = MismatchMsg
    mismatch
           , mismatchTyVarInfo :: Maybe TyVarInfo
    mismatchTyVarInfo     = Maybe TyVarInfo
    forall a. Maybe a
    Nothing
           , mismatchAmbiguityInfo :: [AmbiguityInfo]
    mismatchAmbiguityInfo = [AmbiguityInfo]
    eqInfos
           , mismatchCoercibleInfo :: Maybe CoercibleMsg
    mismatchCoercibleInfo = Maybe CoercibleMsg
    mb_coercible_info }
      where
        mismatch :: MismatchMsg
    mismatch = Bool
    -> SolverReportErrCtxt -> ErrorItem -> Type -> Type -> MismatchMsg
    misMatchOrCND Bool
    False 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
        GlobalRdrEnv
    rdr_env  <- TcRn GlobalRdrEnv
    getGlobalRdrEnv
        FamInstEnvs
    fam_envs <- TcM FamInstEnvs
    tcGetFamInstEnvs
        Maybe CoercibleMsg -> TcM (Maybe CoercibleMsg)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe CoercibleMsg -> TcM (Maybe CoercibleMsg))
    -> Maybe CoercibleMsg -> TcM (Maybe CoercibleMsg)
    forall a b. (a -> b) -> a -> b
    $ GlobalRdrEnv -> FamInstEnvs -> Type -> Type -> Maybe CoercibleMsg
    mkCoercibleExplanation GlobalRdrEnv
    rdr_env FamInstEnvs
    fam_envs Type
    ty1 Type
    ty2

    mkTyVarEqErr :: SolverReportErrCtxt -> ErrorItem
                 -> (TcTyVar, TcCoercionN) -> TcType -> TcM (TcSolverReportMsg, [GhcHint])
    -- tv1 and ty2 are already tidied
    mkTyVarEqErr :: SolverReportErrCtxt
    -> ErrorItem
    -> (TcId, TcCoercionN)
    -> Type
    -> TcM (TcSolverReportMsg, [GhcHint])
    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, [GhcHint])
    mkTyVarEqErr' SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId, TcCoercionN)
    casted_tv1 Type
    ty2 }

    mkTyVarEqErr' :: SolverReportErrCtxt -> ErrorItem
                  -> (TcTyVar, TcCoercionN) -> TcType -> TcM (TcSolverReportMsg, [GhcHint])
    mkTyVarEqErr' :: SolverReportErrCtxt
    -> ErrorItem
    -> (TcId, TcCoercionN)
    -> Type
    -> TcM (TcSolverReportMsg, [GhcHint])
    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
          (TidyEnv
    _, [FixedRuntimeRepErrorInfo]
    infos) <- TidyEnv
    -> [FixedRuntimeRepErrorInfo]
    -> TcM (TidyEnv, [FixedRuntimeRepErrorInfo])
    zonkTidyFRRInfos (SolverReportErrCtxt -> TidyEnv
    cec_tidy SolverReportErrCtxt
    ctxt) [FixedRuntimeRepErrorInfo
    frr_info]
          (TcSolverReportMsg, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([FixedRuntimeRepErrorInfo] -> TcSolverReportMsg
    FixedRuntimeRepError [FixedRuntimeRepErrorInfo]
    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
        TyVarInfo
    tyvar_eq_info <- (TcId, Maybe Implication) -> Type -> TcM TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Maybe Implication
    forall a. Maybe a
    Nothing) Type
    ty2
        let
            poly_msg :: CannotUnifyVariableReason
    poly_msg = ErrorItem
    -> TcId -> Type -> Maybe TyVarInfo -> CannotUnifyVariableReason
    CannotUnifyWithPolytype ErrorItem
    item TcId
    tv1 Type
    ty2 Maybe TyVarInfo
    mb_tv_info
            mb_tv_info :: Maybe TyVarInfo
    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 :: TcSolverReportMsg
    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.
        (TcSolverReportMsg, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg
    main_msg, [])

      | TcId -> Bool
    isSkolemTyVar TcId
    tv1  -- ty2 won't be a meta-tyvar; we would have
                           -- swapped in Solver.Canonical.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
        TyVarInfo
    tv_extra <- (TcId, Maybe Implication) -> Type -> TcM TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Maybe Implication
    forall a. Maybe a
    Nothing) Type
    ty2
        CannotUnifyVariableReason
    reason <-
          if ErrorItem -> EqRel
    errorItemEqRel ErrorItem
    item EqRel -> EqRel -> Bool
    forall a. Eq a => a -> a -> Bool
    == EqRel
    ReprEq
          then TyVarInfo -> Maybe CoercibleMsg -> CannotUnifyVariableReason
    RepresentationalEq TyVarInfo
    tv_extra (Maybe CoercibleMsg -> CannotUnifyVariableReason)
    -> TcM (Maybe CoercibleMsg)
    -> IOEnv (Env TcGblEnv TcLclEnv) CannotUnifyVariableReason
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type -> Type -> TcM (Maybe CoercibleMsg)
    coercible_msg Type
    ty1 Type
    ty2
          else CannotUnifyVariableReason
    -> IOEnv (Env TcGblEnv TcLclEnv) CannotUnifyVariableReason
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CannotUnifyVariableReason
     -> IOEnv (Env TcGblEnv TcLclEnv) CannotUnifyVariableReason)
    -> CannotUnifyVariableReason
    -> IOEnv (Env TcGblEnv TcLclEnv) CannotUnifyVariableReason
    forall a b. (a -> b) -> a -> b
    $ TyVarInfo -> CannotUnifyVariableReason
    DifferentTyVars TyVarInfo
    tv_extra
        let main_msg :: TcSolverReportMsg
    main_msg =
              CannotUnifyVariable
                { mismatchMsg :: MismatchMsg
    mismatchMsg       = MismatchMsg
    headline_msg
                , cannotUnifyReason :: CannotUnifyVariableReason
    cannotUnifyReason = CannotUnifyVariableReason
    reason }
        (TcSolverReportMsg, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg
    main_msg, [GhcHint]
    add_sig)

      | CheckTyEqResult -> Bool
    cterHasOccursCheck CheckTyEqResult
    check_eq_result
        -- 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
      = 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, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg
    main_msg, [])

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

      -- 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
        TyVarInfo
    tv_extra <- (TcId, Maybe Implication) -> Type -> TcM TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Maybe Implication
    forall a. Maybe a
    Nothing) Type
    ty2
        let msg :: TcSolverReportMsg
    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 }
        (TcSolverReportMsg, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg
    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, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    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, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    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, [GhcHint])
     -> TcM (TcSolverReportMsg, [GhcHint]))
    -> TcM (TcSolverReportMsg, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    forall a b. (a -> b) -> a -> b
    $ do -- See Note [Error messages for untouchables]
        TyVarInfo
    tv_extra <- (TcId, Maybe Implication) -> Type -> TcM TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Implication -> Maybe Implication
    forall a. a -> Maybe a
    Just Implication
    implic) Type
    ty2
        let tv_extra' :: TyVarInfo
    tv_extra' = TyVarInfo
    tv_extra { thisTyVarIsUntouchable = Just implic }
            msg :: TcSolverReportMsg
    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 }
        (TcSolverReportMsg, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg
    msg, [GhcHint]
    add_sig)

      | Bool
    otherwise
      = do
        TcSolverReportMsg
    err <- SolverReportErrCtxt
    -> ErrorItem -> Type -> Type -> TcM TcSolverReportMsg
    reportEqErr SolverReportErrCtxt
    ctxt ErrorItem
    item (TcId -> Type
    mkTyVarTy TcId
    tv1) Type
    ty2
        (TcSolverReportMsg, [GhcHint])
    -> TcM (TcSolverReportMsg, [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcSolverReportMsg
    err, [])
            -- 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 = Bool
    -> SolverReportErrCtxt -> ErrorItem -> Type -> Type -> MismatchMsg
    misMatchOrCND Bool
    insoluble_occurs_check SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
        mismatch_msg :: MismatchMsg
    mismatch_msg = ErrorItem -> Type -> Type -> MismatchMsg
    mkMismatchMsg ErrorItem
    item Type
    ty1 Type
    ty2
        add_sig :: [GhcHint]
    add_sig      = Maybe GhcHint -> [GhcHint]
    forall a. Maybe a -> [a]
    maybeToList (Maybe GhcHint -> [GhcHint]) -> Maybe GhcHint -> [GhcHint]
    forall a b. (a -> b) -> a -> b
    $ SolverReportErrCtxt -> Type -> Type -> Maybe GhcHint
    suggestAddSig SolverReportErrCtxt
    ctxt 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
    isConcrete 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
    _ -> TcId -> Type -> CheckTyEqResult
    checkTyVarEq TcId
    tv1 Type
    ty2
            -- in T2627b, we report an error for F (F a0) ~ a0. Note that the type
            -- variable is on the right, so we don't get useful info for the CIrredCan,
            -- and have to compute the result of checkTyVarEq here.

        insoluble_occurs_check :: Bool
    insoluble_occurs_check = CheckTyEqResult
    check_eq_result CheckTyEqResult -> CheckTyEqProblem -> Bool
    `cterHasProblem` CheckTyEqProblem
    cteInsolubleOccurs

    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 :: Bool -> SolverReportErrCtxt -> ErrorItem
                  -> TcType -> TcType -> MismatchMsg
    -- If oriented then ty1 is actual, ty2 is expected
    misMatchOrCND :: Bool
    -> SolverReportErrCtxt -> ErrorItem -> Type -> Type -> MismatchMsg
    misMatchOrCND Bool
    insoluble_occurs_check SolverReportErrCtxt
    ctxt ErrorItem
    item Type
    ty1 Type
    ty2
      | Bool
    insoluble_occurs_check  -- See Note [Insoluble occurs check]
        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
        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 TcCanonical
    -- Note [Equalities with incompatible kinds], wrinkle (2). 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 -> TcM TyVarInfo
    extraTyVarEqInfo (TcId
    tv1, Maybe Implication
    mb_implic) Type
    ty2
      = do
          TcId
    tv1_info <- TcId -> TcM TcId
    extraTyVarInfo TcId
    tv1
          Maybe TcId
    ty2_info <- Type -> IOEnv (Env TcGblEnv TcLclEnv) (Maybe TcId)
    ty_extra Type
    ty2
          TyVarInfo -> TcM TyVarInfo
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVarInfo -> TcM TyVarInfo) -> TyVarInfo -> TcM TyVarInfo
    forall a b. (a -> b) -> a -> b
    $
            TyVarInfo
              { thisTyVar :: TcId
    thisTyVar              = TcId
    tv1_info
              , thisTyVarIsUntouchable :: Maybe Implication
    thisTyVarIsUntouchable = Maybe Implication
    mb_implic
              , otherTy :: Maybe TcId
    otherTy                = Maybe TcId
    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
          SkolemInfo
    new_skol_info <- SkolemInfo -> TcM SkolemInfo
    zonkSkolemInfo SkolemInfo
    skol_info
          TcId -> TcM TcId
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcId -> TcM TcId) -> TcId -> TcM TcId
    forall a b. (a -> b) -> a -> b
    $ Name -> Type -> TcTyVarDetails -> TcId
    mkTcTyVar (TcId -> Name
    tyVarName TcId
    tv) (TcId -> Type
    tyVarKind TcId
    tv) (SkolemInfo -> TcLevel -> Bool -> TcTyVarDetails
    SkolemTv SkolemInfo
    new_skol_info TcLevel
    lvl Bool
    overlaps)
        TcTyVarDetails
    _ -> TcId -> TcM TcId
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TcId
    tv

    suggestAddSig :: SolverReportErrCtxt -> TcType -> TcType -> Maybe GhcHint
    -- See Note [Suggest adding a type signature]
    suggestAddSig :: SolverReportErrCtxt -> Type -> Type -> Maybe GhcHint
    suggestAddSig SolverReportErrCtxt
    ctxt Type
    ty1 Type
    _ty2
      | Name
    bndr : [Name]
    bndrs <- [Name]
    inferred_bndrs
      = GhcHint -> Maybe GhcHint
    forall a. a -> Maybe a
    Just (GhcHint -> Maybe GhcHint) -> GhcHint -> Maybe GhcHint
    forall a b. (a -> b) -> a -> b
    $ AvailableBindings -> GhcHint
    SuggestAddTypeSignatures (AvailableBindings -> GhcHint) -> AvailableBindings -> GhcHint
    forall a b. (a -> b) -> a -> b
    $ NonEmpty Name -> AvailableBindings
    NamedBindings (Name
    bndr Name -> [Name] -> NonEmpty Name
    forall a. a -> [a] -> NonEmpty a
    :| [Name]
    bndrs)
      | Bool
    otherwise
      = Maybe GhcHint
    forall a. Maybe a
    Nothing
      where
        inferred_bndrs :: [Name]
    inferred_bndrs =
          case Type -> Maybe TcId
    getTyVar_maybe Type
    ty1 of
            Just TcId
    tv | TcId -> Bool
    isSkolemTyVar TcId
    tv -> [Implication] -> Bool -> TcId -> [Name]
    find (SolverReportErrCtxt -> [Implication]
    cec_encl SolverReportErrCtxt
    ctxt) Bool
    False TcId
    tv
            Maybe TcId
    _                          -> []

        -- 'find' returns the binders of an InferSkol for 'tv',
        -- provided there is an intervening implication with
        -- ic_given_eqs /= NoGivenEqs (i.e. a GADT match)
        find :: [Implication] -> Bool -> TcId -> [Name]
    find [] Bool
    _ TcId
    _ = []
        find (Implication
    implic:[Implication]
    implics) Bool
    seen_eqs TcId
    tv
           | TcId
    tv TcId -> [TcId] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` Implication -> [TcId]
    ic_skols Implication
    implic
           , InferSkol [(Name, Type)]
    prs <- Implication -> SkolemInfoAnon
    ic_info Implication
    implic
           , Bool
    seen_eqs
           = ((Name, Type) -> Name) -> [(Name, Type)] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map (Name, Type) -> Name
    forall a b. (a, b) -> a
    fst [(Name, Type)]
    prs
           | Bool
    otherwise
           = [Implication] -> Bool -> TcId -> [Name]
    find [Implication]
    implics (Bool
    seen_eqs Bool -> Bool -> Bool
    || Implication -> HasGivenEqs
    ic_given_eqs Implication
    implic HasGivenEqs -> HasGivenEqs -> Bool
    forall a. Eq a => a -> a -> Bool
    /= HasGivenEqs
    NoGivenEqs) 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_ppr_explicit_kinds :: Bool
    teq_mismatch_ppr_explicit_kinds = Bool
    ppr_explicit_kinds
            , 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 ->
          (MismatchEA -> ErrorItem -> Type -> Type -> MismatchMsg
    mkBasicMismatchMsg MismatchEA
    NoEA ErrorItem
    item Type
    ty1 Type
    ty2)
            { mismatch_whenMatching = Just $ WhenMatching cty1 cty2 sub_o mb_sub_t_or_k
            , mismatch_mb_same_occ  = mb_same_occ }
        CtOrigin
    _ ->
          (MismatchEA -> ErrorItem -> Type -> Type -> MismatchMsg
    mkBasicMismatchMsg MismatchEA
    NoEA ErrorItem
    item Type
    ty1 Type
    ty2)
            { mismatch_mb_same_occ  = 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
        ppr_explicit_kinds :: Bool
    ppr_explicit_kinds = Type -> Type -> CtOrigin -> Bool
    shouldPprWithExplicitKinds Type
    ty1 Type
    ty2 CtOrigin
    orig

    -- | Whether to print explicit kinds (with @-fprint-explicit-kinds@)
    -- in an 'SDoc' when a type mismatch occurs to due invisible kind arguments.
    --
    -- This function first checks to see if the 'CtOrigin' argument is a
    -- 'TypeEqOrigin'. If so, it first checks whether the equality is a visible
    -- equality; if it's not, definitely print the kinds. Even if the equality is
    -- a visible equality, check the expected/actual types to see if the types
    -- have equal visible components. If the 'CtOrigin' is
    -- not a 'TypeEqOrigin', fall back on the actual mismatched types themselves.
    shouldPprWithExplicitKinds :: Type -> Type -> CtOrigin -> Bool
    shouldPprWithExplicitKinds :: Type -> Type -> CtOrigin -> Bool
    shouldPprWithExplicitKinds Type
    _ty1 Type
    _ty2 (TypeEqOrigin { uo_actual :: CtOrigin -> Type
    uo_actual = Type
    act
                                                       , uo_expected :: CtOrigin -> Type
    uo_expected = Type
    exp
                                                       , uo_visible :: CtOrigin -> Bool
    uo_visible = Bool
    vis })
      | Bool -> Bool
    not Bool
    vis   = Bool
    True                  -- See tests T15870, T16204c
      | Bool
    otherwise = Type -> Type -> Bool
    tcEqTypeVis Type
    act Type
    exp   -- See tests T9171, T9144.
    shouldPprWithExplicitKinds Type
    ty1 Type
    ty2 CtOrigin
    _ct
      = Type -> Type -> Bool
    tcEqTypeVis Type
    ty1 Type
    ty2

    {- Note [Insoluble occurs check]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    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.

    Conclusion: if there's an insoluble occurs check (cteInsolubleOccurs)
    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 = Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit ((() :: Constraint) => Name -> Module
    Name -> Module
    nameModule Name
    n1) Unit -> Unit -> Bool
    forall a. Eq a => a -> a -> Bool
    == Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit ((() :: Constraint) => Name -> Module
    Name -> Module
    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 [Suggest adding a type signature]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The OutsideIn algorithm rejects GADT programs that don't have a principal
    type, and indeed some that do.  Example:
       data T a where
         MkT :: Int -> T Int

       f (MkT n) = n

    Does this have type f :: T a -> a, or f :: T a -> Int?
    The error that shows up tends to be an attempt to unify an
    untouchable type variable.  So suggestAddSig sees if the offending
    type variable is bound by an *inferred* signature, and suggests
    adding a declared signature instead.

    More specifically, we suggest adding a type sig if we have p ~ ty, and
    p is a skolem bound by an InferSkol.  Those skolems were created from
    unification variables in simplifyInfer.  Why didn't we unify?  It must
    have been because of an intervening GADT or existential, making it
    untouchable. Either way, a type signature would help.  For GADTs, it
    might make it typeable; for existentials the attempt to write a
    signature will fail -- or at least will produce a better error message
    next time

    This initially came up in #8968, concerning pattern synonyms.

    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 -> [ErrorItem] -> TcM SolverReport
    mkDictErr :: (() :: Constraint) =>
    SolverReportErrCtxt -> [ErrorItem] -> TcM SolverReport
    mkDictErr SolverReportErrCtxt
    ctxt [ErrorItem]
    orig_items
      = Bool -> TcM SolverReport -> TcM SolverReport
    forall a. HasCallStack => Bool -> a -> a
    assert (Bool -> Bool
    not ([ErrorItem] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [ErrorItem]
    items)) (TcM SolverReport -> TcM SolverReport)
    -> TcM SolverReport -> TcM SolverReport
    forall a b. (a -> b) -> a -> b
    $
        do { InstEnvs
    inst_envs <- TcM InstEnvs
    tcGetInstEnvs
           ; let min_items :: [ErrorItem]
    min_items = [ErrorItem] -> [ErrorItem]
    elim_superclasses [ErrorItem]
    items
                 lookups :: [(ErrorItem, ClsInstLookupResult)]
    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
                 ([(ErrorItem, ClsInstLookupResult)]
    no_inst_items, [(ErrorItem, ClsInstLookupResult)]
    overlap_items) = ((ErrorItem, ClsInstLookupResult) -> Bool)
    -> [(ErrorItem, ClsInstLookupResult)]
    -> ([(ErrorItem, ClsInstLookupResult)],
        [(ErrorItem, ClsInstLookupResult)])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition (ErrorItem, ClsInstLookupResult) -> Bool
    is_no_inst [(ErrorItem, ClsInstLookupResult)]
    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
           ; TcSolverReportMsg
    err <- HasCallStack =>
    SolverReportErrCtxt
    -> (ErrorItem, ClsInstLookupResult) -> TcM TcSolverReportMsg
    SolverReportErrCtxt
    -> (ErrorItem, ClsInstLookupResult) -> TcM TcSolverReportMsg
    mk_dict_err SolverReportErrCtxt
    ctxt ([(ErrorItem, ClsInstLookupResult)]
    -> (ErrorItem, ClsInstLookupResult)
    forall a. HasCallStack => [a] -> a
    head ([(ErrorItem, ClsInstLookupResult)]
    no_inst_items [(ErrorItem, ClsInstLookupResult)]
    -> [(ErrorItem, ClsInstLookupResult)]
    -> [(ErrorItem, ClsInstLookupResult)]
    forall a. [a] -> [a] -> [a]
    ++ [(ErrorItem, ClsInstLookupResult)]
    overlap_items))
           ; SolverReport -> TcM SolverReport
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SolverReport -> TcM SolverReport)
    -> SolverReport -> TcM SolverReport
    forall a b. (a -> b) -> a -> b
    $ SolverReportErrCtxt -> TcSolverReportMsg -> SolverReport
    important SolverReportErrCtxt
    ctxt TcSolverReportMsg
    err }
      where
        filtered_items :: [ErrorItem]
    filtered_items = (ErrorItem -> Bool) -> [ErrorItem] -> [ErrorItem]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (ErrorItem -> Bool) -> ErrorItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorItem -> Bool
    ei_suppress) [ErrorItem]
    orig_items
        items :: [ErrorItem]
    items | [ErrorItem] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [ErrorItem]
    filtered_items = [ErrorItem]
    orig_items  -- all suppressed, but must report
                                                  -- something for -fdefer-type-errors
              | Bool
    otherwise           = [ErrorItem]
    filtered_items  -- common case

        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) = (() :: Constraint) => 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 :: [ErrorItem] -> [ErrorItem]
    elim_superclasses [ErrorItem]
    items = (ErrorItem -> Type) -> [ErrorItem] -> [ErrorItem]
    forall a. (a -> Type) -> [a] -> [a]
    mkMinimalBySCs ErrorItem -> Type
    errorItemPred [ErrorItem]
    items

    -- 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
        { (SolverReportErrCtxt
    _, RelevantBindings
    rel_binds, ErrorItem
    item) <- Bool
    -> SolverReportErrCtxt
    -> ErrorItem
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    relevantBindings Bool
    True SolverReportErrCtxt
    ctxt ErrorItem
    item
        ; [ClsInst]
    candidate_insts <- TcM [ClsInst]
    get_candidate_instances
        ; ([ImportError]
    imp_errs, [GhcHint]
    field_suggestions) <- TcM ([ImportError], [GhcHint])
    record_field_suggestions
        ; TcSolverReportMsg -> TcM TcSolverReportMsg
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ErrorItem
    -> [ClsInst]
    -> RelevantBindings
    -> [ImportError]
    -> [GhcHint]
    -> TcSolverReportMsg
    cannot_resolve_msg ErrorItem
    item [ClsInst]
    candidate_insts RelevantBindings
    rel_binds [ImportError]
    imp_errs [GhcHint]
    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)   = (() :: Constraint) => 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
    instEnvs <- TcM InstEnvs
    tcGetInstEnvs
               ; [ClsInst] -> TcM [ClsInst]
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((ClsInst -> Bool) -> [ClsInst] -> [ClsInst]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Type -> ClsInst -> Bool
    is_candidate_inst Type
    ty)
                                (InstEnvs -> Class -> [ClsInst]
    classInstances InstEnvs
    instEnvs Class
    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 :: TcM ([ImportError], [GhcHint])
        record_field_suggestions :: TcM ([ImportError], [GhcHint])
    record_field_suggestions = ((OccName -> TcM ([ImportError], [GhcHint]))
     -> Maybe OccName -> TcM ([ImportError], [GhcHint]))
    -> Maybe OccName
    -> (OccName -> TcM ([ImportError], [GhcHint]))
    -> TcM ([ImportError], [GhcHint])
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (TcM ([ImportError], [GhcHint])
    -> (OccName -> TcM ([ImportError], [GhcHint]))
    -> Maybe OccName
    -> TcM ([ImportError], [GhcHint])
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (TcM ([ImportError], [GhcHint])
     -> (OccName -> TcM ([ImportError], [GhcHint]))
     -> Maybe OccName
     -> TcM ([ImportError], [GhcHint]))
    -> TcM ([ImportError], [GhcHint])
    -> (OccName -> TcM ([ImportError], [GhcHint]))
    -> Maybe OccName
    -> TcM ([ImportError], [GhcHint])
    forall a b. (a -> b) -> a -> b
    $ ([ImportError], [GhcHint]) -> TcM ([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 -> TcM ([ImportError], [GhcHint]))
     -> TcM ([ImportError], [GhcHint]))
    -> (OccName -> TcM ([ImportError], [GhcHint]))
    -> TcM ([ImportError], [GhcHint])
    forall a b. (a -> b) -> a -> b
    $ \OccName
    name ->
           do { GlobalRdrEnv
    glb_env <- TcRn GlobalRdrEnv
    getGlobalRdrEnv
              ; LocalRdrEnv
    lcl_env <- RnM LocalRdrEnv
    getLocalRdrEnv
              ; if GlobalRdrEnv -> LocalRdrEnv -> OccName -> Bool
    occ_name_in_scope GlobalRdrEnv
    glb_env LocalRdrEnv
    lcl_env OccName
    name
                then ([ImportError], [GhcHint]) -> TcM ([ImportError], [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([], [GhcHint]
    noHints)
                else do { DynFlags
    dflags   <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
                        ; ImportAvails
    imp_info <- TcRn ImportAvails
    getImports
                        ; Module
    curr_mod <- IOEnv (Env TcGblEnv TcLclEnv) Module
    forall (m :: * -> *). HasModule m => m Module
    getModule
                        ; HomePackageTable
    hpt      <- TcRnIf TcGblEnv TcLclEnv HomePackageTable
    forall gbl lcl. TcRnIf gbl lcl HomePackageTable
    getHpt
                        ; ([ImportError], [GhcHint]) -> TcM ([ImportError], [GhcHint])
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WhatLooking
    -> DynFlags
    -> HomePackageTable
    -> Module
    -> GlobalRdrEnv
    -> LocalRdrEnv
    -> ImportAvails
    -> RdrName
    -> ([ImportError], [GhcHint])
    unknownNameSuggestions WhatLooking
    WL_RecField DynFlags
    dflags HomePackageTable
    hpt Module
    curr_mod
                            GlobalRdrEnv
    glb_env LocalRdrEnv
    emptyLocalRdrEnv ImportAvails
    imp_info (OccName -> RdrName
    mkRdrUnqual OccName
    name)) } }

        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
    $
          [GlobalRdrElt] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (GlobalRdrEnv -> OccName -> [GlobalRdrElt]
    lookupGlobalRdrEnv GlobalRdrEnv
    glb_env OccName
    occ_name) 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’
    -}

    {-
    Note [Kind arguments in error messages]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    It can be terribly confusing to get an error message like (#9171)

        Couldn't match expected type ‘GetParam Base (GetParam Base Int)’
                    with actual type ‘GetParam Base (GetParam Base Int)’

    The reason may be that the kinds don't match up.  Typically you'll get
    more useful information, but not when it's as a result of ambiguity.

    To mitigate this, GHC attempts to enable the -fprint-explicit-kinds flag
    whenever any error message arises due to a kind mismatch. This means that
    the above error message would instead be displayed as:

        Couldn't match expected type
                      ‘GetParam @* @k2 @* Base (GetParam @* @* @k2 Base Int)’
                    with actual type
                      ‘GetParam @* @k20 @* Base (GetParam @* @* @k20 Base Int)’

    Which makes it clearer that the culprit is the mismatch between `k2` and `k20`.
    -}

    -----------------------
    -- 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)
           ; (TidyEnv
    env1, CtOrigin
    tidy_orig) <- TidyEnv -> CtOrigin -> TcM (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 :: TyCoVarSet
    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 :: TyCoVarSet
    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
    loc'   = CtLoc -> CtOrigin -> CtLoc
    setCtLocOrigin CtLoc
    loc CtOrigin
    tidy_orig
                 item' :: ErrorItem
    item'  = ErrorItem
    item { ei_loc = loc' }

           ; (TidyEnv
    env2, NameEnv Type
    lcl_name_cache) <- TidyEnv -> [TcLclEnv] -> TcM (TidyEnv, NameEnv Type)
    zonkTidyTcLclEnvs TidyEnv
    env1 [TcLclEnv
    lcl_env]

           ; RelevantBindings
    relev_bds <- Bool
    -> TcLclEnv -> NameEnv Type -> TyCoVarSet -> TcM RelevantBindings
    relevant_bindings Bool
    want_filtering TcLclEnv
    lcl_env NameEnv Type
    lcl_name_cache TyCoVarSet
    ct_fvs
           ; let ctxt' :: SolverReportErrCtxt
    ctxt'  = SolverReportErrCtxt
    ctxt { cec_tidy = env2 }
           ; (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    -> TcM (SolverReportErrCtxt, RelevantBindings, ErrorItem)
    forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SolverReportErrCtxt
    ctxt', RelevantBindings
    relev_bds, ErrorItem
    item') }
      where
        loc :: CtLoc
    loc     = ErrorItem -> CtLoc
    errorItemCtLoc ErrorItem
    item
        lcl_env :: TcLclEnv
    lcl_env = CtLoc -> TcLclEnv
    ctLocEnv CtLoc
    loc

    -- slightly more general version, to work also with holes
    relevant_bindings :: Bool
                      -> TcLclEnv
                      -> NameEnv Type -- Cache of already zonked and tidied types
                      -> TyCoVarSet
                      -> TcM RelevantBindings
    relevant_bindings :: Bool
    -> TcLclEnv -> NameEnv Type -> TyCoVarSet -> TcM RelevantBindings
    relevant_bindings Bool
    want_filtering TcLclEnv
    lcl_env NameEnv Type
    lcl_name_env TyCoVarSet
    ct_tvs
      = do { DynFlags
    dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
           ; String -> SDoc -> TcM ()
    traceTc String
    "relevant_bindings" (SDoc -> TcM ()) -> SDoc -> TcM ()
    forall a b. (a -> b) -> a -> b
    $
               [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat [ TyCoVarSet -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyCoVarSet
    ct_tvs
                    , (SDoc -> SDoc) -> [SDoc] -> SDoc
    forall a. (a -> SDoc) -> [a] -> SDoc
    pprWithCommas SDoc -> SDoc
    forall a. a -> a
    id [ TcId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TcId
    id 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 (TcId -> Type
    idType TcId
    id)
                                       | TcIdBndr TcId
    id TopLevelFlag
    _ <- TcLclEnv -> [TcBinder]
    tcl_bndrs TcLclEnv
    lcl_env ]
                    , (SDoc -> SDoc) -> [SDoc] -> SDoc
    forall a. (a -> SDoc) -> [a] -> SDoc
    pprWithCommas SDoc -> SDoc
    forall a. a -> a
    id
                        [ Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    id | TcIdBndr_ExpType Name
    id ExpType
    _ TopLevelFlag
    _ <- TcLclEnv -> [TcBinder]
    tcl_bndrs TcLclEnv
    lcl_env ] ]

           ; DynFlags
    -> Maybe Int
    -> TyCoVarSet
    -> RelevantBindings
    -> [TcBinder]
    -> TcM RelevantBindings
    go DynFlags
    dflags (DynFlags -> Maybe Int
    maxRelevantBinds DynFlags
    dflags)
                        TyCoVarSet
    emptyVarSet ([(Name, Type)] -> Bool -> RelevantBindings
    RelevantBindings [] Bool
    False)
                        ([TcBinder] -> [TcBinder]
    forall a. HasOccName a => [a] -> [a]
    removeBindingShadowing ([TcBinder] -> [TcBinder]) -> [TcBinder] -> [TcBinder]
    forall a b. (a -> b) -> a -> b
    $ TcLclEnv -> [TcBinder]
    tcl_bndrs TcLclEnv
    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 { Maybe Type
    mb_ty <- ExpType -> TcM (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 Maybe Type
    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 :: TcTyVar -> [Ct] -> Type -> TcM ()
    warnDefaulting :: TcId -> [Ct] -> Type -> TcM ()
    warnDefaulting TcId
    _ [] Type
    _
      = String -> TcM ()
    forall a. HasCallStack => String -> a
    panic String
    "warnDefaulting: empty Wanteds"
    warnDefaulting TcId
    the_tv wanteds :: [Ct]
    wanteds@(Ct
    ct:[Ct]
    _) Type
    default_ty
      = do { Bool
    warn_default <- WarningFlag -> TcRnIf TcGblEnv TcLclEnv Bool
    forall gbl lcl. WarningFlag -> TcRnIf gbl lcl Bool
    woptM WarningFlag
    Opt_WarnTypeDefaults
           ; TidyEnv
    env0 <- TcM TidyEnv
    tcInitTidyEnv
                -- don't want to report all the superclass constraints, which
                -- add unhelpful clutter
           ; let filtered :: [Ct]
    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
    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]
    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 :: Maybe TcId
    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 :: TcRnMessage
    diag = [Ct] -> Maybe TcId -> Type -> TcRnMessage
    TcRnWarnDefaulting [Ct]
    tidy_wanteds Maybe TcId
    tidy_tv Type
    default_ty
                 loc :: CtLoc
    loc = Ct -> CtLoc
    ctLoc Ct
    ct
           ; CtLoc -> TcM () -> TcM ()
    forall a. CtLoc -> TcM a -> TcM a
    setCtLocM CtLoc
    loc (TcM () -> TcM ()) -> TcM () -> TcM ()
    forall a b. (a -> b) -> a -> b
    $ Bool -> TcRnMessage -> TcM ()
    diagnosticTc Bool
    warn_default TcRnMessage
    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 -> [(Type, Type)]
    solverReportMsg_ExpectedActuals :: TcSolverReportMsg -> [(Type, Type)]
    solverReportMsg_ExpectedActuals
      = \case
        Mismatch { mismatchMsg :: TcSolverReportMsg -> MismatchMsg
    mismatchMsg = MismatchMsg
    mismatch_msg } ->
          case MismatchMsg
    mismatch_msg of
            BasicMismatch { mismatch_ty1 :: MismatchMsg -> Type
    mismatch_ty1 = Type
    exp, mismatch_ty2 :: MismatchMsg -> Type
    mismatch_ty2 = Type
    act } ->
              [(Type
    exp, Type
    act)]
            KindMismatch { kmismatch_expected :: MismatchMsg -> Type
    kmismatch_expected = Type
    exp, kmismatch_actual :: MismatchMsg -> Type
    kmismatch_actual = Type
    act } ->
              [(Type
    exp, Type
    act)]
            TypeEqMismatch { teq_mismatch_expected :: MismatchMsg -> Type
    teq_mismatch_expected = Type
    exp, teq_mismatch_actual :: MismatchMsg -> Type
    teq_mismatch_actual = Type
    act } ->
              [(Type
    exp,Type
    act)]
            CouldNotDeduce {} ->
              []
        TcSolverReportMsg
    _ -> []