[Git][ghc/ghc][wip/derived-refactor] 2 commits: Don't produce Deriveds

Richard Eisenberg gitlab at gitlab.haskell.org
Fri Jun 19 22:54:58 UTC 2020



Richard Eisenberg pushed to branch wip/derived-refactor at Glasgow Haskell Compiler / GHC


Commits:
3e5514ec by Richard Eisenberg at 2020-06-19T11:54:15+01:00
Don't produce Deriveds

- - - - -
f5433f0b by Richard Eisenberg at 2020-06-19T23:54:41+01:00
Checkpoint. Want more CI.

- - - - -


23 changed files:

- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Canonical.hs
- compiler/GHC/Tc/Solver/Interact.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- testsuite/tests/indexed-types/should_fail/SimpleFail16.stderr
- testsuite/tests/indexed-types/should_fail/T13784.stderr
- testsuite/tests/partial-sigs/should_compile/T10403.stderr
- testsuite/tests/polykinds/T11142.stderr
- testsuite/tests/polykinds/T12444.stderr
- testsuite/tests/polykinds/T14172.stderr
- + testsuite/tests/typecheck/should_compile/FunDepOrigin1.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/hole_constraints.stderr
- + testsuite/tests/typecheck/should_fail/FunDepOrigin1b.hs
- + testsuite/tests/typecheck/should_fail/FunDepOrigin1b.stderr
- testsuite/tests/typecheck/should_fail/T14325.stderr
- testsuite/tests/typecheck/should_fail/T15767.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail204.stderr


Changes:

=====================================
compiler/GHC/Tc/Errors.hs
=====================================
@@ -22,7 +22,8 @@ import GHC.Tc.Utils.Monad
 import GHC.Tc.Types.Constraint
 import GHC.Core.Predicate
 import GHC.Tc.Utils.TcMType
-import GHC.Tc.Utils.Unify( occCheckForErrors, MetaTyVarUpdateResult(..), swapOverTyVars )
+import GHC.Tc.Utils.Unify( occCheckForErrors, MetaTyVarUpdateResult(..), swapOverTyVars
+                         , canSolveByUnification )
 import GHC.Tc.Utils.Env( tcInitTidyEnv )
 import GHC.Tc.Utils.TcType
 import GHC.Tc.Types.Origin
@@ -45,11 +46,12 @@ import GHC.Tc.Types.EvTerm
 import GHC.Hs.Binds ( PatSynBind(..) )
 import GHC.Types.Name
 import GHC.Types.Name.Reader ( lookupGRE_Name, GlobalRdrEnv, mkRdrUnqual )
-import GHC.Builtin.Names ( typeableClassName )
+import GHC.Builtin.Names
 import GHC.Types.Id
 import GHC.Types.Var
 import GHC.Types.Var.Set
 import GHC.Types.Var.Env
+import GHC.Types.Unique.Set
 import GHC.Types.Name.Set
 import GHC.Data.Bag
 import GHC.Utils.Error  ( ErrMsg, errDoc, pprLocErrMsg )
@@ -234,7 +236,8 @@ report_unsolved type_errors expr_holes
                                  -- See #15539 and c.f. setting ic_status
                                  -- in GHC.Tc.Solver.setImplicationStatus
                             , cec_warn_redundant = warn_redundant
-                            , cec_binds    = binds_var }
+                            , cec_binds    = binds_var
+                            , cec_already_reported = emptyUniqSet }
 
        ; tc_lvl <- getTcLevel
        ; reportWanteds err_ctxt tc_lvl wanted
@@ -342,6 +345,8 @@ data ReportErrCtxt
                                     --          so create bindings if need be, but
                                     --          don't issue any more errors/warnings
                                     -- See Note [Suppressing error messages]
+          , cec_already_reported :: UniqSet Unique
+                                    -- See Note [Avoid reporting duplicates]
       }
 
 instance Outputable ReportErrCtxt where
@@ -535,6 +540,8 @@ data ErrorItem
        , ei_evdest  :: Maybe TcEvDest   -- for Wanteds, where to put evidence
        , ei_flavour :: CtFlavour
        , ei_loc     :: CtLoc
+       , ei_unique  :: Unique
+         -- for deduplication; see Note [Avoid reporting duplicates]
        }
 
 instance Outputable ErrorItem where
@@ -553,17 +560,19 @@ mkErrorItem ct = EI { ei_pred    = tyvar_first pred
                     , ei_type    = ctPred ct
                     , ei_evdest  = m_evdest
                     , ei_flavour = ctFlavour ct
-                    , ei_loc     = loc }
+                    , ei_loc     = loc
+                    , ei_unique  = unique }
   where
     loc = ctLoc ct
-    (m_evdest, pred)
+    (m_evdest, pred, unique)
       | CtWanted { ctev_dest = dest
                  , ctev_report_as = report_as
                  , ctev_pred = ct_pred } <- ctEvidence ct
-      = (Just dest, ctPredToReport ct_pred report_as)
+      , (u, p) <- ctPredToReport dest ct_pred report_as
+      = (Just dest, p, u)
 
       | otherwise
-      = (Nothing, ctPred ct)
+      = (Nothing, ctPred ct, ctUnique ct)
 
       -- We reorient any tyvar equalities to put the tyvar first; this
       -- allows fewer cases when choosing how to treat errors. Forgetting
@@ -636,13 +645,17 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics
        ; reportHoles tidy_items ctxt_for_insols other_holes
           -- holes never suppress
 
-       ; (ctxt1, items1) <- tryReporters ctxt_for_insols report1 tidy_items
+          -- See Note [Suppressing confusing errors]
+       ; dflags <- getDynFlags
+       ; let (suppressed_items, items0) = partition (suppress dflags) tidy_items
+       ; traceTc "reportWanteds suppressed:" (ppr suppressed_items)
+       ; (ctxt1, items1) <- tryReporters ctxt_for_insols report1 items0
 
          -- Now all the other constraints.  We suppress errors here if
          -- any of the first batch failed, or if the enclosing context
          -- says to suppress
-       ; let ctxt2 = ctxt { cec_suppress = cec_suppress ctxt || cec_suppress ctxt1 }
-       ; (_, leftovers) <- tryReporters ctxt2 report2 items1
+       ; let ctxt2 = ctxt1 { cec_suppress = cec_suppress ctxt || cec_suppress ctxt1 }
+       ; (ctxt3, leftovers) <- tryReporters ctxt2 report2 items1
        ; MASSERT2( null leftovers, ppr leftovers )
 
             -- All the Derived ones have been filtered out of simples
@@ -650,49 +663,79 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics
             -- to report unsolved Derived goals as errors
             -- See Note [Do not report derived but soluble errors]
 
-     ; mapBagM_ (reportImplic ctxt2) implics }
+       ; let inner_ctxt = ctxt2 { cec_already_reported = cec_already_reported ctxt3 }
             -- 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)
+
+       ; mapBagM_ (reportImplic inner_ctxt) implics
+
+            -- Only now, if there are no errors, do we report suppressed ones
+            -- See Note [Suppressing confusing errors]
+            -- We don't need to update the context further because of the
+            -- whenNoErrs guard
+       ; whenNoErrs $
+         do { (_, more_leftovers) <- tryReporters ctxt3 report3 suppressed_items
+            ; MASSERT2( null more_leftovers, ppr more_leftovers ) } }
  where
     env        = cec_tidy ctxt
     tidy_items = bagToList (mapBag (mkErrorItem . tidyCt env)   simples)
     tidy_holes = bagToList (mapBag (tidyHole env) holes)
 
+      -- See Note [Suppressing confusing errors]
+    suppress :: DynFlags -> ErrorItem -> Bool
+    suppress dflags item@(EI { ei_pred = pred })
+      | badCoercionHole pred
+      = True
+
+         -- See Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical;
+         -- point (4c)
+      | Just (_, ty1, ty2) <- getEqPredTys_maybe pred
+      , Just tv1           <- getTyVar_maybe ty1
+      , canSolveByUnification tc_lvl tv1 ty2
+      , MTVU_OK ()         <- occCheckForErrors dflags tv1 ty2
+         -- this last line checks for e.g. impredicative situations; we don't
+         -- want to suppress an error if the problem is impredicativity
+      = True
+
+      | is_ww_fundep_item item
+      = True
+
+      | otherwise
+      = 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.insolubleCt) is caught here, otherwise
     -- we might suppress its error message, and proceed on past
     -- type checking to get a Lint error later
-    report1 = [ ("custom_error", unblocked is_user_type_error, True,  mkUserTypeErrorReporter)
+    report1 = [ ("custom_error", is_user_type_error, True,  mkUserTypeErrorReporter)
 
               , given_eq_spec
-              , ("insoluble2",   unblocked utterly_wrong,  True, mkGroupReporter mkEqErr)
-              , ("skolem eq1",   unblocked very_wrong,     True, mkSkolReporter)
-              , ("skolem eq2",   unblocked skolem_eq,      True, mkSkolReporter)
-              , ("non-tv eq",    unblocked non_tv_eq,      True, mkSkolReporter)
+              , ("insoluble2",   utterly_wrong,  True, mkGroupReporter mkEqErr)
+              , ("skolem eq1",   very_wrong,     True, mkSkolReporter)
+              , ("skolem eq2",   skolem_eq,      True, mkSkolReporter)
+              , ("non-tv eq",    non_tv_eq,      True, 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
-              , ("Homo eqs",      unblocked is_homo_equality,             True,  mkGroupReporter mkEqErr)
-              , ("Other eqs",     unblocked is_non_blocked_equality,      True,  mkGroupReporter mkEqErr)
-              , ("Blocked eqs",   is_equality,           False, mkSuppressReporter mkBlockedEqErr)]
+              , ("Homo eqs",      is_homo_equality,  True,  mkGroupReporter mkEqErr)
+              , ("Other eqs",     is_equality,       True,  mkGroupReporter mkEqErr)
+              ]
 
     -- report2: we suppress these if there are insolubles elsewhere in the tree
     report2 = [ ("Implicit params", is_ip,           False, mkGroupReporter mkIPErr)
               , ("Irreds",          is_irred,        False, mkGroupReporter mkIrredErr)
               , ("Dicts",           is_dict,         False, mkGroupReporter mkDictErr) ]
 
-    -- also checks to make sure the constraint isn't BlockedCIS
-    -- See GHC.Tc.Solver.Canonical Note [Equalities with incompatible kinds], (4)
-    unblocked :: (ErrorItem -> Pred -> Bool) -> ErrorItem -> Pred -> Bool
-    unblocked checker item pred
-      | badCoercionHole (ei_pred item) = False
-      | otherwise                      = checker item pred
+    -- report3: suppressed errors should be reported as categorized by either report1
+    -- or report2.
+    report3 = [ ("wanted/wanted fundeps", is_ww_fundep, True, mkGroupReporter mkEqErr)
+              , ("Blocked eqs",           is_equality,  True, mkGroupReporter mkBlockedEqErr) ]
 
     -- rigid_nom_eq, rigid_nom_tv_eq,
     is_dict, is_equality, is_ip, is_irred :: ErrorItem -> Pred -> Bool
@@ -723,15 +766,6 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics
     is_homo_equality _ (EqPred _ ty1 ty2) = tcTypeKind ty1 `tcEqType` tcTypeKind ty2
     is_homo_equality _ _                  = False
 
-      -- we've already checked homogeneous equalities, so this one must be hetero
-    is_non_blocked_equality _ (EqPred _ ty1 _)
-      | Just tv1 <- getTyVar_maybe ty1
-      , isTouchableMetaTyVar tc_lvl tv1
-      = False  -- See Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical,
-               -- wrinkle (4c).
-    is_non_blocked_equality _ (EqPred {}) = True
-    is_non_blocked_equality _ _           = False
-
     is_equality _ (EqPred {}) = True
     is_equality _ _           = False
 
@@ -744,6 +778,10 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics
     is_irred _ (IrredPred {}) = True
     is_irred _ _              = False
 
+     -- See situation (2) of Note [Suppress confusing errors]
+    is_ww_fundep item _ = is_ww_fundep_item item
+    is_ww_fundep_item = isWantedWantedFunDepOrigin . errorItemOrigin
+
     given_eq_spec  -- See Note [Given errors]
       | has_gadt_match (cec_encl ctxt)
       = ("insoluble1a", is_given_eq, True,  mkGivenErrorReporter)
@@ -785,6 +823,75 @@ isTyFun_maybe ty = case tcSplitTyConApp_maybe ty of
                       Just (tc,_) | isTypeFamilyTyCon tc -> Just tc
                       _ -> 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:
+
+1) Errors which are blocked by a coercion hole. This is described
+   in point (4) of Note [Equalities with incompatible kinds] in Tc.Solver.Canonical.
+
+2) 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 [Avoid reporting duplicates]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It would be embarrassing to report two identical errors to the user. We
+avoid doing so by logging a Unique associated with every error, in the
+cec_already_reported field of a ReportErrCtxt. These Uniques come from:
+
+ * For Givens: it's the Unique on the ctev_evar storing the Given evidence.
+
+ * For Wanteds with CtReportAsSame: it's the Unique associated with the
+   TcEvDest.
+
+ * For Wanteds with CtReportAsOther: it's the Unique in the CtReportAsOther,
+   which in turn comes from the TcEvDest of the originating Wanted, as placed
+   there in updateReportAs.
+
+We still must be sure to process all errors, including duplicates, because
+of the possibility of -fdefer-type-errors; each duplicate may carry its own
+evidence (in the case of several constraints sharing the same CtReportAsOther).
+But when an error appears already in the cec_already_reported, we suppress
+the user-visible error report.
+
+-}
+
+
+
 --------------------------------------------
 --      Reporters
 --------------------------------------------
@@ -822,7 +929,7 @@ reportHoles tidy_items ctxt
 mkUserTypeErrorReporter :: Reporter
 mkUserTypeErrorReporter ctxt
   = mapM_ $ \item -> do { err <- mkUserTypeError ctxt item
-                        ; maybeReportError ctxt err
+                        ; maybeReportError ctxt [item] err
                         ; addDeferredBinding ctxt err item }
 
 mkUserTypeError :: ReportErrCtxt -> ErrorItem -> TcM ErrMsg
@@ -910,11 +1017,6 @@ mkGroupReporter :: (ReportErrCtxt -> [ErrorItem] -> TcM ErrMsg)
 mkGroupReporter mk_err ctxt items
   = mapM_ (reportGroup mk_err ctxt . toList) (equivClasses cmp_loc items)
 
--- Like mkGroupReporter, but doesn't actually print error messages
-mkSuppressReporter :: (ReportErrCtxt -> [ErrorItem] -> TcM ErrMsg) -> Reporter
-mkSuppressReporter mk_err ctxt items
-  = mapM_ (suppressGroup mk_err ctxt . toList) (equivClasses cmp_loc items)
-
 eq_lhs_type :: ErrorItem -> ErrorItem -> Bool
 eq_lhs_type item1 item2
   = case (classifyPredType (ei_pred item1), classifyPredType (ei_pred item2)) of
@@ -933,7 +1035,7 @@ reportGroup mk_err ctxt items =
        vcat [ text "Constraint:"             <+> ppr items
             , text "cec_suppress ="          <+> ppr (cec_suppress ctxt)
             , text "cec_defer_type_errors =" <+> ppr (cec_defer_type_errors ctxt) ]
-     ; maybeReportError ctxt err
+     ; maybeReportError ctxt items err
          -- But see Note [Always warn with -fdefer-type-errors]
      ; traceTc "reportGroup" (ppr items)
      ; mapM_ (addDeferredBinding ctxt err) items }
@@ -942,14 +1044,6 @@ reportGroup mk_err ctxt items =
          -- but that's hard to know for sure, and if we don't
          -- abort, we need bindings for all (e.g. #12156)
 
--- like reportGroup, but does not actually report messages. It still adds
--- -fdefer-type-errors bindings, though.
-suppressGroup :: (ReportErrCtxt -> [ErrorItem] -> TcM ErrMsg) -> Reporter
-suppressGroup mk_err ctxt items
- = do { err <- mk_err ctxt items
-      ; traceTc "Suppressing errors for" (ppr items)
-      ; mapM_ (addDeferredBinding ctxt err) items }
-
 maybeReportHoleError :: ReportErrCtxt -> Hole -> ErrMsg -> TcM ()
 maybeReportHoleError ctxt hole err
   | isOutOfScopeHole hole
@@ -989,12 +1083,19 @@ maybeReportHoleError ctxt hole@(Hole { hole_sort = ExprHole _ }) err
        HoleWarn  -> reportWarning (Reason Opt_WarnTypedHoles) err
        HoleDefer -> return ()
 
-maybeReportError :: ReportErrCtxt -> ErrMsg -> TcM ()
+maybeReportError :: ReportErrCtxt -> [ErrorItem] -> ErrMsg -> TcM ()
 -- Report the error and/or make a deferred binding for it
-maybeReportError ctxt err
+maybeReportError ctxt items err
   | cec_suppress ctxt    -- Some worse error has occurred;
   = return ()            -- so suppress this error/warning
 
+  | any ((`elementOfUniqSet` cec_already_reported ctxt) . ei_unique) items
+  = return ()
+    -- suppress the group if any have been reported. Ideally, we'd like
+    -- to suppress exactly those that have been reported, but this is
+    -- awkward, and it's more embarrassing to report the same error
+    -- twice than to suppress too eagerly
+
   | otherwise
   = case cec_defer_type_errors ctxt of
       TypeDefer       -> return ()
@@ -1074,9 +1175,15 @@ tryReporter ctxt (str, keep_me,  suppress_after, reporter) items
   | otherwise
   = do { traceTc "tryReporter{ " (text str <+> ppr yeses)
        ; (_, no_errs) <- askNoErrs (reporter ctxt yeses)
-       ; let suppress_now = not no_errs && suppress_after
+       ; let suppress_these = cec_suppress ctxt
+             suppress_now   = not no_errs && suppress_after
                             -- See Note [Suppressing error messages]
-             ctxt' = ctxt { cec_suppress = suppress_now || cec_suppress ctxt }
+             already_reported = cec_already_reported ctxt
+             already_reported'
+               | suppress_these = already_reported
+               | otherwise      = addListToUniqSet already_reported (map ei_unique yeses)
+             ctxt' = ctxt { cec_suppress = suppress_now || suppress_these
+                          , cec_already_reported = already_reported' }
        ; traceTc "tryReporter end }" (text str <+> ppr (cec_suppress ctxt) <+> ppr suppress_after)
        ; return (ctxt', nos) }
   where
@@ -1364,7 +1471,7 @@ validHoleFits :: ReportErrCtxt -- The context we're in, i.e. the
                                                     -- with a possibly updated
                                                     -- tidy environment, and
                                                     -- the message.
-validHoleFits ctxt@(CEC {cec_encl = implics
+validHoleFits ctxt@(CEC { cec_encl = implics
                         , cec_tidy = lcl_env}) simps hole
   = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics (map mk_wanted simps) hole
        ; return (ctxt {cec_tidy = tidy_env}, msg) }
@@ -1632,7 +1739,7 @@ reportEqErr ctxt report item oriented ty1 ty2
 
 mkTyVarEqErr, mkTyVarEqErr'
   :: DynFlags -> ReportErrCtxt -> Report -> ErrorItem
-             -> Maybe SwapFlag -> TcTyVar -> TcType -> TcM ErrMsg
+              -> Maybe SwapFlag -> TcTyVar -> TcType -> TcM ErrMsg
 -- tv1 and ty2 are already tidied
 mkTyVarEqErr dflags ctxt report item oriented tv1 ty2
   = do { traceTc "mkTyVarEqErr" (ppr item $$ ppr tv1 $$ ppr ty2)


=====================================
compiler/GHC/Tc/Solver.hs
=====================================
@@ -1513,7 +1513,9 @@ solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }
        ; solved_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs
                                 (wc1 { wc_impl = implics2 })
 
-       ; let final_wc = solved_wc { wc_holes = holes }
+       ; holes' <- simplifyHoles holes
+       ; let final_wc = solved_wc { wc_holes = holes' }
+
        ; ev_binds_var <- getTcEvBindsVar
        ; bb <- TcS.getTcEvBindsMap ev_binds_var
        ; traceTcS "solveWanteds }" $
@@ -1880,6 +1882,15 @@ neededEvVars implic@(Implic { ic_given = givens
      | is_given  = needs  -- Add the rhs vars of the Wanted bindings only
      | otherwise = evVarsOfTerm rhs `unionVarSet` needs
 
+-------------------------------------------------
+simplifyHoles :: Bag Hole -> TcS (Bag Hole)
+simplifyHoles = mapBagM simpl_hole
+  where
+    simpl_hole :: Hole -> TcS Hole
+    simpl_hole h@(Hole { hole_ty = ty, hole_loc = loc })
+      = do { ty' <- flattenType loc ty
+           ; return (h { hole_ty = ty' }) }
+
 {- Note [Delete dead Given evidence bindings]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 As a result of superclass expansion, we speculatively


=====================================
compiler/GHC/Tc/Solver/Canonical.hs
=====================================
@@ -1894,7 +1894,7 @@ canCFunEqCan ev fn tys fsk
 
              flav    = ctEvFlavour ev
 
-             report_as = updateReportAs wrw (ctEvPred ev) (ctEvReportAs ev)
+             report_as = updateReportAs wrw (ctEvUnique ev) (ctEvPred ev) (ctEvReportAs ev)
        ; (ev', fsk')
            <- if isTcReflexiveCo kind_co   -- See Note [canCFunEqCan]
               then do { traceTcS "canCFunEqCan: refl" (ppr new_lhs)
@@ -2380,7 +2380,7 @@ rewriteEvidence wrw ev@(CtWanted { ctev_pred = old_pred
             Fresh  new_ev -> continueWith new_ev
             Cached _      -> stopWith ev "Cached wanted" }
   where
-    report_as' = updateReportAs wrw old_pred report_as
+    report_as' = updateReportAs wrw (tcEvDestUnique dest) old_pred report_as
 
 
 rewriteEqEvidence :: WRWFlag            -- YesWRW <=> a wanted rewrote a wanted
@@ -2425,7 +2425,7 @@ rewriteEqEvidence wrw old_ev swapped nlhs nrhs lhs_co rhs_co
              , ctev_dest = dest
              , ctev_nosh = si
              , ctev_report_as = report_as } <- old_ev
-  , let report_as' = updateReportAs wrw old_pred report_as
+  , let report_as' = updateReportAs wrw (tcEvDestUnique dest) old_pred report_as
   = case dest of
       HoleDest hole ->
         do { (new_ev, hole_co) <- newWantedEq_SI (ch_blocker hole) si loc' report_as'


=====================================
compiler/GHC/Tc/Solver/Interact.hs
=====================================
@@ -1587,7 +1587,7 @@ inertsCanDischarge inerts tv rhs fr
     keep_deriv ev_i
       | Wanted WOnly  <- ctEvFlavour ev_i  -- inert is [W]
       , (Wanted WDeriv, _) <- fr           -- work item is [WD]
-      = True   -- Keep a derived version of the work item
+      = False  -- "RAE" True   -- Keep a derived version of the work item
       | otherwise
       = False  -- Work item is fully discharged
 


=====================================
compiler/GHC/Tc/Solver/Monad.hs
=====================================
@@ -1416,17 +1416,17 @@ maybeEmitShadow :: InertCans -> Ct -> TcS Ct
 -- See Note [The improvement story and derived shadows]
 maybeEmitShadow ics ct
   | let ev = ctEvidence ct
-  , CtWanted { ctev_pred = pred, ctev_loc = loc
-             , ctev_nosh = WDeriv } <- ev
+  , CtWanted { {- "RAE" ctev_pred = pred, ctev_loc = loc
+             , -} ctev_nosh = WDeriv } <- ev
   , shouldSplitWD (inert_eqs ics) ct
-  = do { traceTcS "Emit derived shadow" (ppr ct)
-       ; let derived_ev = CtDerived { ctev_pred = pred
+  = do { traceTcS "RAE: NO: Emit derived shadow" (ppr ct)
+    {-   ; let derived_ev = CtDerived { ctev_pred = pred
                                     , ctev_loc  = loc }
              shadow_ct = ct { cc_ev = derived_ev }
                -- Te shadow constraint keeps the canonical shape.
                -- This just saves work, but is sometimes important;
                -- see Note [Keep CDictCan shadows as CDictCan]
-       ; emitWork [shadow_ct]
+       ; emitWork [shadow_ct] -}
 
        ; let ev' = ev { ctev_nosh = WOnly }
              ct' = ct { cc_ev = ev' }
@@ -3594,9 +3594,9 @@ emitNewDerivedEq loc role ty1 ty2
          -- See Note [Prioritise equalities] (Avoiding fundep iteration)
 
 newDerivedNC :: CtLoc -> TcPredType -> TcS CtEvidence
-newDerivedNC loc pred
+newDerivedNC = newWantedNC {- "RAE"
   = do { -- checkReductionDepth loc pred
-       ; return (CtDerived { ctev_pred = pred, ctev_loc = loc }) }
+       ; return (CtDerived { ctev_pred = pred, ctev_loc = loc }) } -}
 
 -- --------- Check done in GHC.Tc.Solver.Interact.selectNewWorkItem???? ---------
 -- | Checks if the depth of the given location is too much. Fails if


=====================================
compiler/GHC/Tc/Types/Constraint.hs
=====================================
@@ -22,7 +22,7 @@ module GHC.Tc.Types.Constraint (
         mkIrredCt,
         ctEvPred, ctEvLoc, ctEvOrigin, ctEvEqRel,
         ctEvExpr, ctEvTerm, ctEvCoercion, ctEvEvId,
-        ctReportAs,
+        ctReportAs, ctUnique,
         tyCoVarsOfCt, tyCoVarsOfCts,
         tyCoVarsOfCtList, tyCoVarsOfCtsList,
 
@@ -51,7 +51,7 @@ module GHC.Tc.Types.Constraint (
         isWanted, isGiven, isDerived, isGivenOrWDeriv,
         ctEvRole, setCtEvLoc, arisesFromGivens,
         tyCoVarsOfCtEvList, tyCoVarsOfCtEv, tyCoVarsOfCtEvsList,
-        ctEvReportAs,
+        ctEvReportAs, ctEvUnique, tcEvDestUnique,
 
         CtReportAs(..), ctPredToReport, substCtReportAs,
         updateReportAs, WRWFlag(..), wantedRewriteWanted,
@@ -97,6 +97,7 @@ import GHC.Utils.FV
 import GHC.Types.Var.Set
 import GHC.Driver.Session
 import GHC.Types.Basic
+import GHC.Types.Unique
 
 import GHC.Utils.Outputable
 import GHC.Types.SrcLoc
@@ -467,6 +468,10 @@ ctReportAs ct = case ctEvidence ct of
   CtWanted { ctev_report_as = report_as } -> report_as
   _                                       -> pprPanic "ctReportAs" (ppr ct)
 
+-- | Extract a Unique from a 'Ct'
+ctUnique :: Ct -> Unique
+ctUnique = ctEvUnique . ctEvidence
+
 instance Outputable Ct where
   ppr ct = ppr (ctEvidence ct) <+> parens pp_sort
     where
@@ -1024,10 +1029,11 @@ insolubleCt :: Ct -> Bool
 -- Definitely insoluble, in particular /excluding/ type-hole constraints
 -- Namely: a) an equality constraint
 --         b) that is insoluble
---         c) and does not arise from a Given
+--         c) and does not arise from a Given or a Wanted/Wanted fundep interaction
 insolubleCt ct
   | not (insolubleEqCt ct)                     = False
   | arisesFromGivens (ctFlavour ct) (ctLoc ct) = False  -- See Note [Given insolubles]
+  | isWantedWantedFunDepOrigin (ctOrigin ct)   = False
   | otherwise                                  = True
 
 insolubleEqCt :: Ct -> Bool
@@ -1410,8 +1416,9 @@ data TcEvDest
 -- | What should we report to the user when reporting this Wanted?
 -- See Note [Wanteds rewrite Wanteds]
 data CtReportAs
-  = CtReportAsSame               -- just report the predicate in the Ct
-  | CtReportAsOther TcPredType   -- report this other type
+  = CtReportAsSame                      -- just report the predicate in the Ct
+  | CtReportAsOther Unique TcPredType   -- report this other type
+     -- See GHC.Tc.Errors Note [Avoid reporting duplicates] about the Unique
 
 -- | Did a wanted rewrite a wanted?
 -- See Note [Wanteds rewrite Wanteds]
@@ -1488,12 +1495,21 @@ ctEvEvId (CtWanted { ctev_dest = HoleDest h })   = coHoleCoVar h
 ctEvEvId (CtGiven  { ctev_evar = ev })           = ev
 ctEvEvId ctev@(CtDerived {}) = pprPanic "ctEvId:" (ppr ctev)
 
+ctEvUnique :: CtEvidence -> Unique
+ctEvUnique (CtGiven { ctev_evar = ev })    = varUnique ev
+ctEvUnique (CtWanted { ctev_dest = dest }) = tcEvDestUnique dest
+ctEvUnique (CtDerived {})                  = mkUniqueGrimily 0  -- "RAE" this is evil.
+
+tcEvDestUnique :: TcEvDest -> Unique
+tcEvDestUnique (EvVarDest ev_var) = varUnique ev_var
+tcEvDestUnique (HoleDest co_hole) = varUnique (coHoleCoVar co_hole)
+
 setCtEvLoc :: CtEvidence -> CtLoc -> CtEvidence
 setCtEvLoc ctev loc = ctev { ctev_loc = loc }
 
 arisesFromGivens :: CtFlavour -> CtLoc -> Bool
 arisesFromGivens Given       _   = True
-arisesFromGivens (Wanted {}) _   = False
+arisesFromGivens (Wanted {}) loc = isGivenLoc loc  -- could be a Given FunDep
 arisesFromGivens Derived     loc = isGivenLoc loc
 
 -- | Return a 'CtReportAs' from a 'CtEvidence'. Returns
@@ -1504,31 +1520,31 @@ ctEvReportAs _                                         = CtReportAsSame
 
 -- | Given the pred in a CtWanted and its 'CtReportAs', get
 -- the pred to report. See Note [Wanteds rewrite Wanteds]
-ctPredToReport :: TcPredType -> CtReportAs -> TcPredType
-ctPredToReport pred CtReportAsSame         = pred
-ctPredToReport _    (CtReportAsOther pred) = pred
+ctPredToReport :: TcEvDest -> TcPredType -> CtReportAs -> (Unique, TcPredType)
+ctPredToReport dest pred CtReportAsSame           = (tcEvDestUnique dest, pred)
+ctPredToReport _    _    (CtReportAsOther u pred) = (u, pred)
 
 -- | Substitute in a 'CtReportAs'
 substCtReportAs :: TCvSubst -> CtReportAs -> CtReportAs
-substCtReportAs _     CtReportAsSame         = CtReportAsSame
-substCtReportAs subst (CtReportAsOther pred) = CtReportAsOther (substTy subst pred)
+substCtReportAs _     CtReportAsSame           = CtReportAsSame
+substCtReportAs subst (CtReportAsOther u pred) = CtReportAsOther u (substTy subst pred)
 
 -- | After rewriting a Wanted, update the 'CtReportAs' for the new Wanted.
 -- If the old CtReportAs is CtReportAsSame and a wanted rewrote a wanted,
 -- record the old pred as the new CtReportAs.
 -- See Note [Wanteds rewrite Wanteds]
-updateReportAs :: WRWFlag -> TcPredType   -- _old_ pred type
+updateReportAs :: WRWFlag -> Unique -> TcPredType   -- _old_ pred type
                -> CtReportAs -> CtReportAs
-updateReportAs YesWRW old_pred CtReportAsSame = CtReportAsOther old_pred
-updateReportAs _      _        report_as      = report_as
+updateReportAs YesWRW unique old_pred CtReportAsSame = CtReportAsOther unique old_pred
+updateReportAs _      _      _        report_as      = report_as
 
 instance Outputable TcEvDest where
   ppr (HoleDest h)   = text "hole" <> ppr h
   ppr (EvVarDest ev) = ppr ev
 
 instance Outputable CtReportAs where
-  ppr CtReportAsSame         = text "CtReportAsSame"
-  ppr (CtReportAsOther pred) = parens $ text "CtReportAsOther" <+> ppr pred
+  ppr CtReportAsSame           = text "CtReportAsSame"
+  ppr (CtReportAsOther u pred) = parens $ text "CtReportAsOther" <+> ppr u <+> ppr pred
 
 instance Outputable WRWFlag where
   ppr NoWRW  = text "NoWRW"
@@ -1676,6 +1692,9 @@ predicate with respect to any givens (only). That rewritten predicate
 is reported to the user. Simple, and it costs time only when errors
 are being reported.
 
+"RAE": Givens don't rewrite CtReportAs. But that's OK because givens
+get there first.
+
 Note [Deriveds do rewrite Deriveds]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 However we DO allow Deriveds to rewrite Deriveds, because that's how


=====================================
compiler/GHC/Tc/Types/Origin.hs
=====================================
@@ -16,7 +16,7 @@ module GHC.Tc.Types.Origin (
   -- CtOrigin
   CtOrigin(..), exprCtOrigin, lexprCtOrigin, matchesCtOrigin, grhssCtOrigin,
   isVisibleOrigin, toInvisibleOrigin,
-  pprCtOrigin, isGivenOrigin
+  pprCtOrigin, isGivenOrigin, isWantedWantedFunDepOrigin
 
   ) where
 
@@ -462,6 +462,12 @@ isGivenOrigin (FunDepOrigin1 _ o1 _ _ o2 _) = isGivenOrigin o1 && isGivenOrigin
 isGivenOrigin (FunDepOrigin2 _ o1 _ _)      = isGivenOrigin o1
 isGivenOrigin _                             = False
 
+-- See Note [Suppressing confusing errors] in GHC.Tc.Errors
+isWantedWantedFunDepOrigin :: CtOrigin -> Bool
+isWantedWantedFunDepOrigin (FunDepOrigin1 _ orig1 _ _ orig2 _)
+  = not (isGivenOrigin orig1) && not (isGivenOrigin orig2)
+isWantedWantedFunDepOrigin _ = False
+
 instance Outputable CtOrigin where
   ppr = pprCtOrigin
 


=====================================
compiler/GHC/Tc/Utils/TcMType.hs
=====================================
@@ -242,13 +242,7 @@ emitDerivedEqs origin pairs
   | null pairs
   = return ()
   | otherwise
-  = do { loc <- getCtLocM origin Nothing
-       ; emitSimples (listToBag (map (mk_one loc) pairs)) }
-  where
-    mk_one loc (ty1, ty2)
-       = mkNonCanonical $
-         CtDerived { ctev_pred = mkPrimEqPred ty1 ty2
-                   , ctev_loc = loc }
+  = mapM_ (uncurry (emitWantedEq origin TypeLevel Nominal)) pairs
 
 -- | Emits a new equality constraint
 emitWantedEq :: CtOrigin -> TypeOrKind -> Role -> TcType -> TcType -> TcM Coercion
@@ -2091,8 +2085,8 @@ zonkCtEvidence ctev@(CtWanted { ctev_pred = pred
                          -- necessary in simplifyInfer
                        HoleDest h   -> HoleDest h
        ; report_as' <- case report_as of
-           CtReportAsSame              -> return CtReportAsSame
-           CtReportAsOther report_pred -> CtReportAsOther <$> zonkTcType report_pred
+           CtReportAsSame                -> return CtReportAsSame
+           CtReportAsOther u report_pred -> CtReportAsOther u <$> zonkTcType report_pred
        ; return (ctev { ctev_pred = pred', ctev_dest = dest'
                       , ctev_report_as = report_as' }) }
 zonkCtEvidence ctev@(CtDerived { ctev_pred = pred })
@@ -2285,8 +2279,8 @@ tidyCtEvidence :: TidyEnv -> CtEvidence -> CtEvidence
 tidyCtEvidence env ctev@(CtWanted { ctev_pred = pred, ctev_report_as = report_as })
   = ctev { ctev_pred = tidyType env pred, ctev_report_as = tidy_report_as report_as }
   where tidy_report_as CtReportAsSame = CtReportAsSame
-        tidy_report_as (CtReportAsOther report_pred)
-          = CtReportAsOther (tidyType env report_pred)
+        tidy_report_as (CtReportAsOther u report_pred)
+          = CtReportAsOther u (tidyType env report_pred)
 tidyCtEvidence env ctev = ctev { ctev_pred = tidyType env ty }
   where
     ty  = ctev_pred ctev


=====================================
testsuite/tests/indexed-types/should_fail/SimpleFail16.stderr
=====================================
@@ -1,9 +1,9 @@
 
 SimpleFail16.hs:10:12: error:
-    Couldn't match expected type ‘p0 a0’ with actual type ‘F ()’
-    The type variables ‘p0’, ‘a0’ are ambiguous
-    In the first argument of ‘foo’, namely ‘(undefined :: F ())’
-    In the expression: foo (undefined :: F ())
-    In an equation for ‘bar’: bar = foo (undefined :: F ())
-    Relevant bindings include
-      bar :: p0 a0 (bound at SimpleFail16.hs:10:1)
+    • Couldn't match expected type ‘F ()’ with actual type ‘p0 a0’
+      The type variables ‘p0’, ‘a0’ are ambiguous
+    • In the first argument of ‘foo’, namely ‘(undefined :: F ())’
+      In the expression: foo (undefined :: F ())
+      In an equation for ‘bar’: bar = foo (undefined :: F ())
+    • Relevant bindings include
+        bar :: p0 a0 (bound at SimpleFail16.hs:10:1)


=====================================
testsuite/tests/indexed-types/should_fail/T13784.stderr
=====================================
@@ -1,6 +1,19 @@
 
 T13784.hs:29:28: error:
-    • Couldn't match type ‘as’ with ‘a : Divide a as’
+    • Occurs check: cannot construct the infinite type:
+        t0 ~ Divide a (a : t0)
+      The type variable ‘t0’ is ambiguous
+      Expected type: Product (Divide a (a : as))
+        Actual type: Product as1
+    • In the expression: as
+      In the expression: (a, as)
+      In an equation for ‘divide’: divide (a :* as) = (a, as)
+    • Relevant bindings include
+        divide :: Product (a : as) -> (a, Product (Divide a (a : as)))
+          (bound at T13784.hs:29:5)
+
+T13784.hs:29:28: error:
+    • Couldn't match type ‘as’ with ‘a : a : a : t0’
       ‘as’ is a rigid type variable bound by
         the instance declaration
         at T13784.hs:25:10-30


=====================================
testsuite/tests/partial-sigs/should_compile/T10403.stderr
=====================================
@@ -39,16 +39,17 @@ T10403.hs:22:15: warning: [-Wdeferred-type-errors (in -Wdefault)]
       In the expression: H . fmap (const ())
       In the expression: (H . fmap (const ())) (fmap f b)
 
-T10403.hs:28:8: warning: [-Wdeferred-type-errors (in -Wdefault)]
+T10403.hs:28:20: warning: [-Wdeferred-type-errors (in -Wdefault)]
     • Couldn't match type ‘f0’ with ‘B t’
         because type variable ‘t’ would escape its scope
       This (rigid, skolem) type variable is bound by
         the type signature for:
           app2 :: forall t. H (B t)
         at T10403.hs:27:1-15
-      Expected type: H (B t)
-        Actual type: H f0
-    • In the expression: h2 (H . I) (B ())
+      Expected type: f0 ()
+        Actual type: B t ()
+    • In the second argument of ‘h2’, namely ‘(B ())’
+      In the expression: h2 (H . I) (B ())
       In an equation for ‘app2’: app2 = h2 (H . I) (B ())
     • Relevant bindings include
         app2 :: H (B t) (bound at T10403.hs:28:1)


=====================================
testsuite/tests/polykinds/T11142.stderr
=====================================
@@ -4,14 +4,3 @@ T11142.hs:9:49: error:
     • In the second argument of ‘SameKind’, namely ‘b’
       In the type signature:
         foo :: forall b. (forall k (a :: k). SameKind a b) -> ()
-
-T11142.hs:10:7: error:
-    • Cannot instantiate unification variable ‘a0’
-      with a type involving polytypes:
-        (forall k1 (a :: k1). SameKind a b) -> ()
-        GHC doesn't yet support impredicative polymorphism
-    • In the expression: undefined
-      In an equation for ‘foo’: foo = undefined
-    • Relevant bindings include
-        foo :: (forall k1 (a :: k1). SameKind a b) -> ()
-          (bound at T11142.hs:10:1)


=====================================
testsuite/tests/polykinds/T12444.stderr
=====================================
@@ -1,6 +1,6 @@
 
 T12444.hs:19:11: error:
-    • Couldn't match type ‘b’ with ‘'Succ (c :+: b)’
+    • Couldn't match type ‘b’ with ‘'Succ t0’
       ‘b’ is a rigid type variable bound by
         the type signature for:
           foo :: forall (c :: Nat) (b :: Nat).


=====================================
testsuite/tests/polykinds/T14172.stderr
=====================================
@@ -11,12 +11,12 @@ T14172.hs:6:46: error:
       In the type ‘(a -> f b) -> g a -> f (h _)’
 
 T14172.hs:7:19: error:
-    • Occurs check: cannot construct the infinite type: a ~ g'0 a
-      Expected type: (f'0 a -> f (f'0 b))
-                     -> Compose f'0 g'0 a -> f (h a')
-        Actual type: (Unwrapped (Compose f'0 g'0 a)
-                      -> f (Unwrapped (h a')))
-                     -> Compose f'0 g'0 a -> f (h a')
+    • Couldn't match type ‘h’ with ‘Compose f'0 g'0’
+        arising from a use of ‘_Wrapping’
+      ‘h’ is a rigid type variable bound by
+        the inferred type of
+          traverseCompose :: (a -> f b) -> g a -> f (h a')
+        at T14172.hs:6:1-47
     • In the first argument of ‘(.)’, namely ‘_Wrapping Compose’
       In the expression: _Wrapping Compose . traverse
       In an equation for ‘traverseCompose’:
@@ -24,3 +24,15 @@ T14172.hs:7:19: error:
     • Relevant bindings include
         traverseCompose :: (a -> f b) -> g a -> f (h a')
           (bound at T14172.hs:7:1)
+
+T14172.hs:7:19: error:
+    • Couldn't match type ‘Compose f'0 g'1 a'0 -> f (h a')’
+                     with ‘g a -> f (h a')’
+      Expected type: (a -> f b) -> g a -> f (h a')
+        Actual type: (a -> f b) -> Compose f'0 g'1 a'0 -> f (h a')
+    • In the expression: _Wrapping Compose . traverse
+      In an equation for ‘traverseCompose’:
+          traverseCompose = _Wrapping Compose . traverse
+    • Relevant bindings include
+        traverseCompose :: (a -> f b) -> g a -> f (h a')
+          (bound at T14172.hs:7:1)


=====================================
testsuite/tests/typecheck/should_compile/FunDepOrigin1.hs
=====================================
@@ -0,0 +1,12 @@
+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts #-}
+
+module FunDepOrigin1 where
+
+class C a b | a -> b where
+  op :: a -> b -> b
+
+foo _ = op True Nothing
+
+bar _ = op False []
+
+-- See Note [Suppressing confusing errors] in GHC.Tc.Errors


=====================================
testsuite/tests/typecheck/should_compile/all.T
=====================================
@@ -705,3 +705,4 @@ test('T18005', normal, compile, [''])
 test('T18023', normal, compile, [''])
 test('T18036', normal, compile, [''])
 test('T18036a', normal, compile, [''])
+test('FunDepOrigin1', normal, compile, [''])


=====================================
testsuite/tests/typecheck/should_compile/hole_constraints.stderr
=====================================
@@ -47,8 +47,8 @@ hole_constraints.hs:16:35: warning: [-Wtyped-holes (in -Wdefault)]
         mempty :: forall a. Monoid a => a
 
 hole_constraints.hs:20:19: warning: [-Wtyped-holes (in -Wdefault)]
-    • Found hole: _ :: a
-      Where: ‘a’ is a rigid type variable bound by
+    • Found hole: _ :: b
+      Where: ‘b’ is a rigid type variable bound by
                the type signature for:
                  castWith :: forall a b. (a :~: b) -> a -> b
                at hole_constraints.hs:19:1-29


=====================================
testsuite/tests/typecheck/should_fail/FunDepOrigin1b.hs
=====================================
@@ -0,0 +1,10 @@
+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts #-}
+
+module FunDepOrigin1b where
+
+class C a b | a -> b where
+  op :: a -> b -> b
+
+foo _ = (op True Nothing, op False [])
+
+-- See Note [Suppressing confusing errors] in GHC.Tc.Errors


=====================================
testsuite/tests/typecheck/should_fail/FunDepOrigin1b.stderr
=====================================
@@ -0,0 +1,13 @@
+
+FunDepOrigin1b.hs:8:27: error:
+    • Couldn't match type ‘Maybe a’ with ‘[a1]’
+        arising from a functional dependency between constraints:
+          ‘C Bool [a1]’
+            arising from a use of ‘op’ at FunDepOrigin1b.hs:8:27-37
+          ‘C Bool (Maybe a)’
+            arising from a use of ‘op’ at FunDepOrigin1b.hs:8:10-24
+    • In the expression: op False []
+      In the expression: (op True Nothing, op False [])
+      In an equation for ‘foo’: foo _ = (op True Nothing, op False [])
+    • Relevant bindings include
+        foo :: p -> (Maybe a, [a1]) (bound at FunDepOrigin1b.hs:8:1)


=====================================
testsuite/tests/typecheck/should_fail/T14325.stderr
=====================================
@@ -1,9 +1,9 @@
 
 T14325.hs:11:9: error:
-    • Could not deduce (C b (f b)) arising from a use of ‘foo’
-      from the context: C (f b) b
-        bound by the type signature for:
-                   hm3 :: forall (f :: * -> *) b. C (f b) b => b -> f b
-        at T14325.hs:10:1-28
+    • Occurs check: cannot construct the infinite type: b ~ f b
+        arising from a use of ‘foo’
     • In the expression: foo x
       In an equation for ‘hm3’: hm3 x = foo x
+    • Relevant bindings include
+        x :: b (bound at T14325.hs:11:5)
+        hm3 :: b -> f b (bound at T14325.hs:11:1)


=====================================
testsuite/tests/typecheck/should_fail/T15767.stderr
=====================================
@@ -1,6 +1,6 @@
 
 T15767.hs:7:5: error:
-    • No instance for (C () b) arising from a use of ‘x’
+    • No instance for (C () b0) arising from a use of ‘x’
     • In the expression: x
       In an equation for ‘y’:
           y = x


=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -563,3 +563,4 @@ test('T17021', normal, compile_fail, [''])
 test('T17021b', normal, compile_fail, [''])
 test('T17955', normal, compile_fail, [''])
 test('T17173', normal, compile_fail, [''])
+test('FunDepOrigin1b', normal, compile_fail, [''])


=====================================
testsuite/tests/typecheck/should_fail/tcfail204.stderr
=====================================
@@ -5,5 +5,9 @@ tcfail204.hs:10:7: error: [-Wtype-defaults (in -Wall), -Werror=type-defaults]
           arising from a use of ‘ceiling’ at tcfail204.hs:10:7-17
         (Fractional a0)
           arising from the literal ‘6.3’ at tcfail204.hs:10:15-17
+        (Num a0) arising from the literal ‘6.3’ at tcfail204.hs:10:15-17
+        (Real a0) arising from a use of ‘ceiling’ at tcfail204.hs:10:7-17
+        (Ord a0) arising from a use of ‘ceiling’ at tcfail204.hs:10:7-17
+        (Eq a0) arising from a use of ‘ceiling’ at tcfail204.hs:10:7-17
     • In the expression: ceiling 6.3
       In an equation for ‘foo’: foo = ceiling 6.3



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e091141d11228f719a56681736d5c2d75e760407...f5433f0bc06f65deb96a44b62d47875ec4bc5b38

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e091141d11228f719a56681736d5c2d75e760407...f5433f0bc06f65deb96a44b62d47875ec4bc5b38
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20200619/6954a17f/attachment-0001.html>


More information about the ghc-commits mailing list