diff --git a/compiler/GHC/Runtime/Eval.hs b/compiler/GHC/Runtime/Eval.hs
index dcb6b98410e6642b004dc5b3e42739bb853c91b5..ed28f19ab67812edd5386e1ad4bb596a9f0b3a81 100644
--- a/compiler/GHC/Runtime/Eval.hs
+++ b/compiler/GHC/Runtime/Eval.hs
@@ -1084,7 +1084,7 @@ getDictionaryBindings theta = do
   let dict_var = mkVanillaGlobal dictName theta
   loc <- getCtLocM (GivenOrigin (getSkolemInfo unkSkol)) Nothing
 
-  return CtWanted {
+  return $ CtWanted $ WantedCt {
     ctev_pred = varType dict_var,
     ctev_dest = EvVarDest dict_var,
     ctev_loc = loc,
diff --git a/compiler/GHC/Tc/Errors.hs b/compiler/GHC/Tc/Errors.hs
index 742d3f4e7050fb832a2d1a905a4dba0d5b6ab800..ef0450a62b51af048fdb1f9b4a5e7bec1769ce23 100644
--- a/compiler/GHC/Tc/Errors.hs
+++ b/compiler/GHC/Tc/Errors.hs
@@ -1,11 +1,11 @@
-
-{-# LANGUAGE FlexibleContexts    #-}
-{-# LANGUAGE LambdaCase          #-}
-{-# LANGUAGE MultiWayIf          #-}
-{-# LANGUAGE NamedFieldPuns      #-}
-{-# LANGUAGE ParallelListComp    #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TupleSections       #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE LambdaCase            #-}
+{-# LANGUAGE MultiWayIf            #-}
+{-# LANGUAGE NamedFieldPuns        #-}
+{-# LANGUAGE ParallelListComp      #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE TupleSections         #-}
 
 module GHC.Tc.Errors(
        reportUnsolved, reportAllUnsolved, warnAllUnsolved,
@@ -470,7 +470,7 @@ mkErrorItem ct
          -- For this `suppress` stuff
          -- see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint
            CtGiven {} -> return (False, Nothing)
-           CtWanted { ctev_rewriters = rewriters, ctev_dest = dest }
+           CtWanted (WantedCt { ctev_rewriters = rewriters, ctev_dest = dest })
              -> do { rewriters' <- zonkRewriterSet rewriters
                    ; return (not (isEmptyRewriterSet rewriters'), Just dest) }
 
@@ -1550,10 +1550,11 @@ validHoleFits ctxt@(CEC { cec_encl = implics
     mk_wanted :: ErrorItem -> Maybe CtEvidence
     mk_wanted (EI { ei_pred = pred, ei_evdest = m_dest, ei_loc = loc })
       | Just dest <- m_dest
-      = Just (CtWanted { ctev_pred      = pred
-                       , ctev_dest      = dest
-                       , ctev_loc       = loc
-                       , ctev_rewriters = emptyRewriterSet })
+      = Just $ CtWanted $
+          WantedCt { ctev_pred      = pred
+                   , ctev_dest      = dest
+                   , ctev_loc       = loc
+                   , ctev_rewriters = emptyRewriterSet }
       | otherwise
       = Nothing   -- The ErrorItem was a Given
 
diff --git a/compiler/GHC/Tc/Plugin.hs b/compiler/GHC/Tc/Plugin.hs
index 638e2848844149c4a2109b8f229812906ba2254b..7b6dc06ce380d81a472dda53474c941e86f65e8a 100644
--- a/compiler/GHC/Tc/Plugin.hs
+++ b/compiler/GHC/Tc/Plugin.hs
@@ -1,4 +1,3 @@
-
 -- | This module provides an interface for typechecker plugins to
 -- access select functions of the 'TcM', principally those to do with
 -- reading parts of the state.
@@ -67,7 +66,7 @@ import GHC.Core.FamInstEnv     ( FamInstEnv )
 import GHC.Tc.Utils.Monad      ( TcGblEnv, TcLclEnv, TcPluginM
                                , unsafeTcPluginTcM
                                , liftIO, traceTc )
-import GHC.Tc.Types.Constraint ( Ct, CtEvidence(..) )
+import GHC.Tc.Types.Constraint ( Ct, CtEvidence(..), GivenCtEvidence(..) )
 import GHC.Tc.Types.CtLoc      ( CtLoc )
 
 import GHC.Tc.Utils.TcMType    ( TcTyVar, TcType )
@@ -186,7 +185,8 @@ newGiven :: EvBindsVar -> CtLoc -> PredType -> EvExpr -> TcPluginM CtEvidence
 newGiven tc_evbinds loc pty evtm = do
    new_ev <- newEvVar pty
    setEvBind tc_evbinds $ mkGivenEvBind new_ev (EvExpr evtm)
-   return CtGiven { ctev_pred = pty, ctev_evar = new_ev, ctev_loc = loc }
+   return $ CtGiven $
+     GivenCt { ctev_pred = pty, ctev_evar = new_ev, ctev_loc = loc }
 
 -- | Create a fresh evidence variable.
 --
diff --git a/compiler/GHC/Tc/Solver/Default.hs b/compiler/GHC/Tc/Solver/Default.hs
index d1320e051ebfd6cbc52bd3032de175137e175934..072105f683580ec8028a145d36077940681c184f 100644
--- a/compiler/GHC/Tc/Solver/Default.hs
+++ b/compiler/GHC/Tc/Solver/Default.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE MultiWayIf #-}
 
 module GHC.Tc.Solver.Default(
@@ -258,9 +259,9 @@ solveImplicationUsingUnsatGiven
            ; return $ wc { wc_simple = emptyBag, wc_impl = impls } }
     go_simple :: Ct -> TcS ()
     go_simple ct = case ctEvidence ct of
-      CtWanted { ctev_pred = pty, ctev_dest = dst }
+      CtWanted (WantedCt { ctev_pred = pty, ctev_dest = dest })
         -> do { ev_expr <- unsatisfiableEvExpr unsat_given pty
-              ; setWantedEvTerm dst EvNonCanonical $ EvExpr ev_expr }
+              ; setWantedEvTerm dest EvNonCanonical $ EvExpr ev_expr }
       _ -> return ()
 
 -- | Create an evidence expression for an arbitrary constraint using
@@ -1063,14 +1064,16 @@ tryDefaultGroup wanteds (Proposal assignments)
           = do { lcl_env <- TcS.getLclEnv
                ; tc_lvl <- TcS.getTcLevel
                ; let loc = mkGivenLoc tc_lvl (getSkolemInfo unkSkol) (mkCtLocEnv lcl_env)
-               -- Equality constraints are possible due to type defaulting plugins
-               ; wanted_evs <- sequence [ newWantedNC loc rewriters pred'
-                                        | wanted <- wanteds
-                                        , CtWanted { ctev_pred = pred
-                                                   , ctev_rewriters = rewriters }
-                                            <- return (ctEvidence wanted)
-                                        , let pred' = substTy subst pred ]
-               ; residual_wc <- solveSimpleWanteds $ listToBag $ map mkNonCanonical wanted_evs
+                     new_wtd_ct :: WantedCtEvidence -> TcS Ct
+                     new_wtd_ct (WantedCt { ctev_pred = wtd_pred, ctev_rewriters = rws }) =
+                       mkNonCanonical . CtWanted <$>
+                         -- NB: equality constraints are possible,
+                         -- due to type defaulting plugins
+                         newWantedNC loc rws (substTy subst wtd_pred)
+               ; new_wanteds <- sequence [ new_wtd_ct wtd
+                                         | CtWanted wtd <- map ctEvidence wanteds
+                                         ]
+               ; residual_wc <- solveSimpleWanteds (listToBag new_wanteds)
                ; return $ if isEmptyWC residual_wc then Just (tvs, subst) else Nothing }
 
           | otherwise
diff --git a/compiler/GHC/Tc/Solver/Dict.hs b/compiler/GHC/Tc/Solver/Dict.hs
index fd2e596b292a571afa95c180397289b4025575c4..514ea803e10bb8a7a440017df80a00f29453d5b0 100644
--- a/compiler/GHC/Tc/Solver/Dict.hs
+++ b/compiler/GHC/Tc/Solver/Dict.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE MultiWayIf #-}
 
 -- | Solving Class constraints CDictCan
@@ -117,7 +118,7 @@ canDictCt ev cls tys
          -- doNotExpand: We have already expanded superclasses for /this/ dict
          -- so set the fuel to doNotExpand to avoid repeating expansion
 
-  | CtWanted { ctev_rewriters = rewriters } <- ev
+  | CtWanted (WantedCt { ctev_rewriters = rws }) <- ev
   , Just ip_name <- isCallStackPred cls tys
   , Just fun_fs  <- isPushCallStackOrigin_maybe orig
   -- If we're given a CallStack constraint that arose from a function
@@ -134,7 +135,7 @@ canDictCt ev cls tys
                             -- See Note [Overview of implicit CallStacks]
                             -- in GHC.Tc.Types.Evidence
 
-       ; new_ev <- newWantedEvVarNC new_loc rewriters pred
+       ; new_ev <- CtWanted <$> newWantedEvVarNC new_loc rws pred
 
          -- Then we solve the wanted by pushing the call-site
          -- onto the newly emitted CallStack
@@ -393,7 +394,7 @@ There is a bit of special treatment: search for isCTupleClass.
 solveEqualityDict :: CtEvidence -> Class -> [Type] -> SolverStage Void
 -- Precondition: (isEqualityClass cls) True, so cls is (~), (~~), or Coercible
 solveEqualityDict ev cls tys
-  | CtWanted { ctev_dest = dest } <- ev
+  | CtWanted (WantedCt { ctev_dest = dest }) <- ev
   = Stage $
     do { let (data_con, role, t1, t2) = matchEqualityInst cls tys
          -- Unify t1~t2, putting anything that can't be solved
@@ -405,13 +406,14 @@ solveEqualityDict ev cls tys
          evDataConApp data_con tys [Coercion co]
        ; stopWith ev "Solved wanted lifted equality" }
 
-  | CtGiven { ctev_evar = ev_id, ctev_loc = loc } <- ev
+  | CtGiven (GivenCt { ctev_evar = ev_id }) <- ev
   , [sel_id] <- classSCSelIds cls  -- Equality classes have just one superclass
   = Stage $
-    do { let sc_pred = classMethodInstTy sel_id tys
+    do { let loc = ctEvLoc ev
+             sc_pred = classMethodInstTy sel_id tys
              ev_expr = EvExpr $ Var sel_id `mkTyApps` tys `App` evId ev_id
        ; given_ev <- newGivenEvVar loc (sc_pred, ev_expr)
-       ; startAgainWith (mkNonCanonical given_ev) }
+       ; startAgainWith (mkNonCanonical $ CtGiven given_ev) }
   | otherwise
   = pprPanic "solveEqualityDict" (ppr cls)
 
@@ -739,8 +741,8 @@ shortCutSolver :: DynFlags
                -> CtEvidence -- Inert we want to try to replace
                -> TcS Bool   -- True <=> success
 shortCutSolver dflags ev_w ev_i
-  | isWanted ev_w
-  , isGiven ev_i
+  | CtWanted wanted <- ev_w
+  , CtGiven  {}     <- ev_i
     -- We are about to solve a [W] constraint from a [G] constraint. We take
     -- a moment to see if we can get a better solution using an instance.
     -- Note that we only do this for the sake of performance. Exactly the same
@@ -764,7 +766,7 @@ shortCutSolver dflags ev_w ev_i
        ; solved_dicts <- getSolvedDicts
 
        ; mb_stuff <- runMaybeT $
-                     try_solve_from_instance (ev_binds, solved_dicts) ev_w
+                     try_solve_from_instance (ev_binds, solved_dicts) wanted
 
        ; case mb_stuff of
            Nothing -> return False
@@ -782,11 +784,10 @@ shortCutSolver dflags ev_w ev_i
     loc_w = ctEvLoc ev_w
 
     try_solve_from_instance   -- See Note [Shortcut try_solve_from_instance]
-      :: (EvBindMap, DictMap DictCt) -> CtEvidence
+      :: (EvBindMap, DictMap DictCt) -> WantedCtEvidence
       -> MaybeT TcS (EvBindMap, DictMap DictCt)
-    try_solve_from_instance (ev_binds, solved_dicts) ev
-      | let pred = ctEvPred ev
-      , ClassPred cls tys <- classifyPredType pred
+    try_solve_from_instance (ev_binds, solved_dicts) wtd@(WantedCt { ctev_loc = loc, ctev_pred = pred })
+      | ClassPred cls tys <- classifyPredType pred
       = do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w
            ; lift $ warn_custom_warn_instance inst_res loc_w
                  -- See Note [Implementation of deprecated instances]
@@ -797,7 +798,7 @@ shortCutSolver dflags ev_w ev_i
                        , cir_what        = what }
                  | safeOverlap what
                  , all isTyFamFree preds  -- Note [Shortcut solving: type families]
-                 -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls
+                 -> do { let dict_ct = DictCt { di_ev = CtWanted wtd, di_cls = cls
                                               , di_tys = tys, di_pend_sc = doNotExpand }
                              solved_dicts' = addSolvedDict dict_ct solved_dicts
                              -- solved_dicts': it is important that we add our goal
@@ -805,17 +806,17 @@ shortCutSolver dflags ev_w ev_i
                              -- up in a loop while solving recursive dictionaries.
 
                        ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds)
-                       ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred
+                       ; loc' <- lift $ checkInstanceOK loc what pred
                        ; lift $ checkReductionDepth loc' pred
 
 
-                       ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds
+                       ; evc_vs <- mapM (new_wanted_cached wtd loc' solved_dicts') preds
                                   -- Emit work for subgoals but use our local cache
                                   -- so we can solve recursive dictionaries.
 
                        ; let ev_tm     = mk_ev (map getEvExpr evc_vs)
                              ev_binds' = extendEvBinds ev_binds $
-                                         mkWantedEvBind (ctEvEvId ev) canonical ev_tm
+                                         mkWantedEvBind (wantedCtEvEvId wtd) canonical ev_tm
 
                        ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $
                          freshGoals evc_vs }
@@ -829,13 +830,13 @@ shortCutSolver dflags ev_w ev_i
     -- Use a local cache of solved dicts while emitting EvVars for new work
     -- We bail out of the entire computation if we need to emit an EvVar for
     -- a subgoal that isn't a ClassPred.
-    new_wanted_cached :: CtEvidence -> CtLoc
+    new_wanted_cached :: WantedCtEvidence -> CtLoc
                       -> DictMap DictCt -> TcPredType -> MaybeT TcS MaybeNew
-    new_wanted_cached ev_w loc cache pty
+    new_wanted_cached (WantedCt { ctev_rewriters = rws }) loc cache pty
       | ClassPred cls tys <- classifyPredType pty
       = lift $ case findDict cache loc_w cls tys of
           Just dict_ct -> return $ Cached (ctEvExpr (dictCtEvidence dict_ct))
-          Nothing      -> Fresh <$> newWantedNC loc (ctEvRewriters ev_w) pty
+          Nothing      -> Fresh <$> newWantedNC loc rws pty
       | otherwise = mzero
 
 {- *******************************************************************
@@ -888,7 +889,7 @@ chooseInstance work_item
                     (ppr work_item)
        ; evc_vars <- mapM (newWanted deeper_loc (ctEvRewriters work_item)) theta
        ; setEvBindIfWanted work_item canonical (mk_ev (map getEvExpr evc_vars))
-       ; emitWorkNC (freshGoals evc_vars)
+       ; emitWorkNC (map CtWanted $ freshGoals evc_vars)
        ; stopWith work_item "Dict/Top (solved wanted)" }
   where
      pred = ctEvPred work_item
@@ -971,7 +972,7 @@ noMatchableGivenDicts inerts@(IS { inert_cans = inert_cans }) loc_w clas tys
 
     matchable_given :: DictCt -> Bool
     matchable_given (DictCt { di_ev = ev })
-      | CtGiven { ctev_loc = loc_g, ctev_pred = pred_g } <- ev
+      | CtGiven (GivenCt { ctev_loc = loc_g, ctev_pred = pred_g }) <- ev
       = isJust $ mightEqualLater inerts pred_g loc_g pred_w loc_w
 
       | otherwise
@@ -1137,10 +1138,10 @@ nullary case of what's happening here.
 matchLocalInst :: TcPredType -> CtLoc -> TcS ClsInstResult
 -- Look up the predicate in Given quantified constraints,
 -- which are effectively just local instance declarations.
-matchLocalInst pred loc
+matchLocalInst body_pred loc
   = do { inerts@(IS { inert_cans = ics }) <- getInertSet
        ; case match_local_inst inerts (inert_insts ics) of
-          { ([], []) -> do { traceTcS "No local instance for" (ppr pred)
+          { ([], []) -> do { traceTcS "No local instance for" (ppr body_pred)
                            ; return NoInstance }
           ; (matches, unifs) ->
     do { matches <- mapM mk_instDFun matches
@@ -1155,7 +1156,7 @@ matchLocalInst pred loc
                                       , cir_canonical   = EvCanonical
                                       , cir_what        = LocalInstance }
                ; traceTcS "Best local instance found:" $
-                  vcat [ text "pred:" <+> ppr pred
+                  vcat [ text "body_pred:" <+> ppr body_pred
                        , text "result:" <+> ppr result
                        , text "matches:" <+> ppr matches
                        , text "unifs:" <+> ppr unifs ]
@@ -1163,13 +1164,13 @@ matchLocalInst pred loc
 
           ; mb_best ->
             do { traceTcS "Multiple local instances; not committing to any"
-                  $ vcat [ text "pred:" <+> ppr pred
+                  $ vcat [ text "body_pred:" <+> ppr body_pred
                          , text "matches:" <+> ppr matches
                          , text "unifs:" <+> ppr unifs
                          , text "best_match:" <+> ppr mb_best ]
                ; return NotSure }}}}}
   where
-    pred_tv_set = tyCoVarsOfType pred
+    body_pred_tv_set = tyCoVarsOfType body_pred
 
     mk_instDFun :: (CtEvidence, [DFunInstType]) -> TcS InstDFun
     mk_instDFun (ev, tys) =
@@ -1185,18 +1186,18 @@ matchLocalInst pred loc
     match_local_inst _inerts []
       = ([], [])
     match_local_inst inerts (qci@(QCI { qci_tvs  = qtvs
-                                      , qci_pred = qpred
+                                      , qci_body = qbody
                                       , qci_ev   = qev })
                             :qcis)
-      | let in_scope = mkInScopeSet (qtv_set `unionVarSet` pred_tv_set)
+      | let in_scope = mkInScopeSet (qtv_set `unionVarSet` body_pred_tv_set)
       , Just tv_subst <- ruleMatchTyKiX qtv_set (mkRnEnv2 in_scope)
-                                        emptyTvSubstEnv qpred pred
+                                        emptyTvSubstEnv qbody body_pred
       , let match = (qev, map (lookupVarEnv tv_subst) qtvs)
       = (match:matches, unifs)
 
       | otherwise
-      = assertPpr (disjointVarSet qtv_set (tyCoVarsOfType pred))
-                  (ppr qci $$ ppr pred)
+      = assertPpr (disjointVarSet qtv_set (tyCoVarsOfType body_pred))
+                  (ppr qci $$ ppr body_pred)
             -- ASSERT: unification relies on the
             -- quantified variables being fresh
         (matches, this_unif `combine` unifs)
@@ -1205,7 +1206,7 @@ matchLocalInst pred loc
         qtv_set = mkVarSet qtvs
         (matches, unifs) = match_local_inst inerts qcis
         this_unif
-          | Just subst <- mightEqualLater inerts qpred qloc pred loc
+          | Just subst <- mightEqualLater inerts qbody qloc body_pred loc
           = Just (qev, map  (lookupTyVar subst) qtvs)
           | otherwise
           = Nothing
@@ -1983,10 +1984,9 @@ makeSuperClasses cts = concatMapM go cts
     go (CDictCan (DictCt { di_ev = ev, di_cls = cls, di_tys = tys, di_pend_sc = fuel }))
       = assertFuelPreconditionStrict fuel $ -- fuel needs to be more than 0 always
         mkStrictSuperClasses fuel ev [] [] cls tys
-    go (CQuantCan (QCI { qci_pred = pred, qci_ev = ev, qci_pend_sc = fuel }))
-      = assertPpr (isClassPred pred) (ppr pred) $  -- The cts should all have
-                                                   -- class pred heads
-        assertFuelPreconditionStrict fuel $ -- fuel needs to be more than 0 always
+    go (CQuantCan (QCI { qci_body = body_pred, qci_ev = ev, qci_pend_sc = fuel }))
+      = assertPpr (isClassPred body_pred) (ppr body_pred) $ -- The cts should all have class pred heads
+        assertFuelPreconditionStrict fuel $                 -- fuel needs to be more than 0, always
         mkStrictSuperClasses fuel ev tvs theta cls tys
       where
         (tvs, theta, cls, tys) = tcSplitDFunTy (ctEvPred ev)
@@ -2017,13 +2017,12 @@ mk_strict_superclasses _ _ _ _ _ cls _
   | isEqualityClass cls
   = return []
 
-mk_strict_superclasses fuel rec_clss
-                       ev@(CtGiven { ctev_evar = evar, ctev_loc = loc })
-                       tvs theta cls tys
+mk_strict_superclasses fuel rec_clss ev@(CtGiven (GivenCt { ctev_evar = evar })) tvs theta cls tys
   = -- Given case
     do { traceTcS "mk_strict" (ppr ev $$ ppr (ctLocOrigin loc))
        ; concatMapM do_one_given (classSCSelIds cls) }
   where
+    loc  = ctEvLoc ev
     dict_ids  = mkTemplateLocals theta
     this_size = pSizeClassPred cls tys
 
@@ -2038,7 +2037,7 @@ mk_strict_superclasses fuel rec_clss
       = do { given_ev <- newGivenEvVar sc_loc $
                          mk_given_desc sel_id sc_pred
            ; assertFuelPrecondition fuel $
-             mk_superclasses fuel rec_clss given_ev tvs theta sc_pred }
+             mk_superclasses fuel rec_clss (CtGiven given_ev) tvs theta sc_pred }
       where
         sc_pred = classMethodInstTy sel_id tys
 
@@ -2094,7 +2093,9 @@ mk_strict_superclasses fuel rec_clss
     newly_blocked _                      = False
 
 -- Wanted case
-mk_strict_superclasses fuel rec_clss ev tvs theta cls tys
+mk_strict_superclasses fuel rec_clss
+  (CtWanted (WantedCt { ctev_pred = pty, ctev_loc = loc0, ctev_rewriters = rws }))
+  tvs theta cls tys
   | all noFreeVarsOfType tys
   = return [] -- Wanteds with no variables yield no superclass constraints.
               -- See Note [Improvement from Ground Wanteds]
@@ -2104,12 +2105,12 @@ mk_strict_superclasses fuel rec_clss ev tvs theta cls tys
   = assertPpr (null tvs && null theta) (ppr tvs $$ ppr theta) $
     concatMapM do_one (immSuperClasses cls tys)
   where
-    loc = ctEvLoc ev `updateCtLocOrigin` WantedSuperclassOrigin (ctEvPred ev)
+    loc = loc0 `updateCtLocOrigin` WantedSuperclassOrigin pty
 
     do_one sc_pred
       = do { traceTcS "mk_strict_superclasses Wanted" (ppr (mkClassPred cls tys) $$ ppr sc_pred)
-           ; sc_ev <- newWantedNC loc (ctEvRewriters ev) sc_pred
-           ; mk_superclasses fuel rec_clss sc_ev [] [] sc_pred }
+           ; sc_ev <- newWantedNC loc rws sc_pred
+           ; mk_superclasses fuel rec_clss (CtWanted sc_ev) [] [] sc_pred }
 
 {- Note [Improvement from Ground Wanteds]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2170,7 +2171,7 @@ mk_superclasses_of fuel rec_clss ev tvs theta cls tys
                     -- NB: If there is a loop, we cut off, so we have not
                     --     added the superclasses, hence cc_pend_sc = fuel
                     | otherwise
-                    = CQuantCan (QCI { qci_tvs = tvs, qci_pred = mkClassPred cls tys
+                    = CQuantCan (QCI { qci_tvs = tvs, qci_body = mkClassPred cls tys
                                      , qci_ev = ev, qci_pend_sc = fuel })
 
 
diff --git a/compiler/GHC/Tc/Solver/Equality.hs b/compiler/GHC/Tc/Solver/Equality.hs
index af697da65831df1e4c49d98275dbcc6cd49fce8d..126c7848915eb97a9952aba5a36b975b69420378 100644
--- a/compiler/GHC/Tc/Solver/Equality.hs
+++ b/compiler/GHC/Tc/Solver/Equality.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE MultiWayIf #-}
 
 module GHC.Tc.Solver.Equality(
@@ -464,7 +465,7 @@ can_eq_nc_forall :: CtEvidence -> EqRel
 -- See Note [Solving forall equalities]
 
 can_eq_nc_forall ev eq_rel s1 s2
- | CtWanted { ctev_dest = orig_dest } <- ev
+ | CtWanted (WantedCt { ctev_dest = orig_dest }) <- ev
  = do { let (bndrs1, phi1, bndrs2, phi2) = split_foralls s1 s2
             flags1 = binderFlags bndrs1
             flags2 = binderFlags bndrs2
@@ -749,7 +750,7 @@ can_eq_app :: CtEvidence       -- :: s1 t1 ~N s2 t2
 -- to an irreducible constraint; see typecheck/should_compile/T10494
 -- See Note [Decomposing AppTy equalities]
 can_eq_app ev s1 t1 s2 t2
-  | CtWanted { ctev_dest = dest } <- ev
+  | CtWanted (WantedCt { ctev_dest = dest }) <- ev
   = do { traceTcS "can_eq_app" (vcat [ text "s1:" <+> ppr s1, text "t1:" <+> ppr t1
                                      , text "s2:" <+> ppr s2, text "t2:" <+> ppr t2
                                      , text "vis:" <+> ppr (isNextArgVisible s1) ])
@@ -772,7 +773,7 @@ can_eq_app ev s1 t1 s2 t2
   | s1k `mismatches` s2k
   = canEqHardFailure ev (s1 `mkAppTy` t1) (s2 `mkAppTy` t2)
 
-  | CtGiven { ctev_evar = evar } <- ev
+  | CtGiven (GivenCt { ctev_evar = evar }) <- ev
   = do { let co   = mkCoVarCo evar
              co_s = mkLRCo CLeft  co
              co_t = mkLRCo CRight co
@@ -780,8 +781,8 @@ can_eq_app ev s1 t1 s2 t2
                                      , evCoercion co_s )
        ; evar_t <- newGivenEvVar loc ( mkTcEqPredLikeEv ev t1 t2
                                      , evCoercion co_t )
-       ; emitWorkNC [evar_t]
-       ; startAgainWith (mkNonCanonical evar_s) }
+       ; emitWorkNC [CtGiven evar_t]
+       ; startAgainWith (mkNonCanonical $ CtGiven evar_s) }
 
   where
     loc = ctEvLoc ev
@@ -1322,7 +1323,7 @@ canDecomposableTyConAppOK ev eq_rel tc (ty1,tys1) (ty2,tys2)
     do { traceTcS "canDecomposableTyConAppOK"
                   (ppr ev $$ ppr eq_rel $$ ppr tc $$ ppr tys1 $$ ppr tys2)
        ; case ev of
-           CtWanted { ctev_dest = dest }
+           CtWanted (WantedCt { ctev_dest = dest })
              -- new_locs and tc_roles are both infinite, so we are
              -- guaranteed that cos has the same length as tys1 and tys2
              -- See Note [Fast path when decomposing TyConApps]
@@ -1333,7 +1334,7 @@ canDecomposableTyConAppOK ev eq_rel tc (ty1,tys1) (ty2,tys2)
                            ; return (mkTyConAppCo role tc cos) }
                    ; setWantedEq dest co }
 
-           CtGiven { ctev_evar = evar }
+           CtGiven (GivenCt { ctev_evar = evar })
              | let pred_ty = mkEqPred eq_rel ty1 ty2
                    ev_co   = mkCoVarCo (setVarType evar pred_ty)
                    -- setVarType: satisfy Note [mkSelCo precondition] in Coercion.hs
@@ -1381,7 +1382,7 @@ canDecomposableFunTy ev eq_rel af f1@(ty1,m1,a1,r1) f2@(ty2,m2,a2,r2)
   = do { traceTcS "canDecomposableFunTy"
                   (ppr ev $$ ppr eq_rel $$ ppr f1 $$ ppr f2)
        ; case ev of
-           CtWanted { ctev_dest = dest }
+           CtWanted (WantedCt { ctev_dest = dest })
              -> do { (co, _, _) <- wrapUnifierTcS ev Nominal $ \ uenv ->
                         do { let mult_env = uenv `updUEnvLoc` toInvisibleLoc
                                                  `setUEnvRole` funRole role SelMult
@@ -1391,7 +1392,7 @@ canDecomposableFunTy ev eq_rel af f1@(ty1,m1,a1,r1) f2@(ty2,m2,a2,r2)
                            ; return (mkNakedFunCo role af mult arg res) }
                    ; setWantedEq dest co }
 
-           CtGiven { ctev_evar = evar }
+           CtGiven (GivenCt { ctev_evar = evar })
              | let pred_ty = mkEqPred eq_rel ty1 ty2
                    ev_co   = mkCoVarCo (setVarType evar pred_ty)
                    -- setVarType: satisfy Note [mkSelCo precondition] in Coercion.hs
@@ -1643,13 +1644,13 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2
     -- Returned kind_co has kind (k1 ~ k2) if NotSwapped, (k2 ~ k1) if Swapped
     -- Returned Bool = True if unifications happened, so we should retry
     mk_kind_eq = case ev of
-      CtGiven { ctev_evar = evar }
+      CtGiven (GivenCt { ctev_evar = evar, ctev_loc = loc })
         -> do { let kind_co  = mkKindCo (mkCoVarCo evar)
                     pred_ty  = unSwap swapped mkNomEqPred ki1 ki2
-                    kind_loc = mkKindEqLoc xi1 xi2 (ctev_loc ev)
+                    kind_loc = mkKindEqLoc xi1 xi2 loc
               ; kind_ev <- newGivenEvVar kind_loc (pred_ty, evCoercion kind_co)
-              ; emitWorkNC [kind_ev]
-              ; return (ctEvCoercion kind_ev, emptyRewriterSet, False) }
+              ; emitWorkNC [CtGiven kind_ev]
+              ; return (givenCtEvCoercion kind_ev, emptyRewriterSet, False) }
 
       CtWanted {}
         -> do { (kind_co, cts, unifs) <- wrapUnifierTcS ev Nominal $ \uenv ->
@@ -2536,16 +2537,15 @@ rewriteEqEvidence new_rewriters old_ev swapped (Reduction lhs_co nlhs) (Reductio
   , isReflCo rhs_co
   = return (setCtEvPredType old_ev new_pred)
 
-  | CtGiven { ctev_evar = old_evar } <- old_ev
+  | CtGiven (GivenCt { ctev_evar = old_evar }) <- old_ev
   = do { let new_tm = evCoercion ( mkSymCo lhs_co
                                   `mkTransCo` maybeSymCo swapped (mkCoVarCo old_evar)
                                   `mkTransCo` rhs_co)
-       ; newGivenEvVar loc (new_pred, new_tm) }
+       ; CtGiven <$> newGivenEvVar loc (new_pred, new_tm) }
 
-  | CtWanted { ctev_dest = dest
-             , ctev_rewriters = rewriters } <- old_ev
-  , let rewriters' = rewriters S.<> new_rewriters
-  = do { (new_ev, hole_co) <- newWantedEq loc rewriters' (ctEvRewriteRole old_ev) nlhs nrhs
+  | CtWanted (WantedCt { ctev_dest = dest, ctev_rewriters = rewriters }) <- old_ev
+  = do { let rewriters' = rewriters S.<> new_rewriters
+       ; (new_ev, hole_co) <- newWantedEq loc rewriters' (ctEvRewriteRole old_ev) nlhs nrhs
        ; let co = maybeSymCo swapped $
                   lhs_co `mkTransCo` hole_co `mkTransCo` mkSymCo rhs_co
        ; setWantedEq dest co
@@ -2554,7 +2554,7 @@ rewriteEqEvidence new_rewriters old_ev swapped (Reduction lhs_co nlhs) (Reductio
                                             , ppr nrhs
                                             , ppr co
                                             , ppr new_rewriters ])
-       ; return new_ev }
+       ; return $ CtWanted new_ev }
 
   where
     new_pred = mkTcEqPredLikeEv old_ev nlhs nrhs
diff --git a/compiler/GHC/Tc/Solver/InertSet.hs b/compiler/GHC/Tc/Solver/InertSet.hs
index 6612cf260df3eb9f2a3095625ebbf903607c3c1c..102215a5143da802257c194beaacef0b105b0862 100644
--- a/compiler/GHC/Tc/Solver/InertSet.hs
+++ b/compiler/GHC/Tc/Solver/InertSet.hs
@@ -1940,7 +1940,7 @@ solveOneFromTheOther :: Ct  -- Inert    (Dict or Irred)
 -- two wanteds into one by solving one from the other
 
 solveOneFromTheOther ct_i ct_w
-  | CtWanted { ctev_loc = loc_w } <- ev_w
+  | CtWanted {} <- ev_w
   , prohibitedSuperClassSolve loc_i loc_w
   -- See Note [Solving superclass constraints] in GHC.Tc.TyCl.Instance
   = -- Inert must be Given
@@ -1976,7 +1976,7 @@ solveOneFromTheOther ct_i ct_w
 
   -- From here on the work-item is Given
 
-  | CtWanted { ctev_loc = loc_i } <- ev_i
+  | CtWanted {} <- ev_i
   , prohibitedSuperClassSolve loc_w loc_i
   = KeepInert   -- Just discard the un-usable Given
                 -- This never actually happens because
diff --git a/compiler/GHC/Tc/Solver/Monad.hs b/compiler/GHC/Tc/Solver/Monad.hs
index b2854e17bc16ddb0d75ce4b3bf55c0630e69bff0..f664527cb132f9b58b2097839ea6fa7d0196e73f 100644
--- a/compiler/GHC/Tc/Solver/Monad.hs
+++ b/compiler/GHC/Tc/Solver/Monad.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE DeriveFunctor #-}
 {-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE MultiWayIf #-}
 {-# LANGUAGE RankNTypes #-}
@@ -336,10 +337,10 @@ addInertForAll new_qci
 
        -- Update given equalities. C.f updateGivenEqs
        ; tclvl <- getTcLevel
-       ; let pred         = qci_pred new_qci
-             not_equality = isClassPred pred && not (isEqClassPred pred)
+       ; let body_pred    = qci_body new_qci
+             not_equality = isClassPred body_pred && not (isEqClassPred body_pred)
                   -- True <=> definitely not an equality
-                  -- A qci_pred like (f a) might be an equality
+                  -- A qci_body like (f a) might be an equality
 
              ics2 | not_equality = ics1
                   | otherwise    = ics1 { inert_given_eq_lvl = tclvl
@@ -428,7 +429,7 @@ kickOutRewritable ko_spec new_fr
               -- from the cache, too.
             ; let kicked_given_ev_vars = foldr add_one emptyVarSet kicked_out
                   add_one :: Ct -> VarSet -> VarSet
-                  add_one ct vs | CtGiven { ctev_evar = ev_var } <- ctEvidence ct
+                  add_one ct vs | CtGiven (GivenCt { ctev_evar = ev_var }) <- ctEvidence ct
                                 = vs `extendVarSet` ev_var
                                 | otherwise = vs
 
@@ -497,7 +498,7 @@ kickOutAfterFillingCoercionHole hole
          -- True: kick out; False: keep.
     kick_ct ct
       | IrredCt { ir_ev = ev, ir_reason = reason } <- ct
-      , CtWanted { ctev_rewriters = RewriterSet rewriters } <- ev
+      , CtWanted (WantedCt { ctev_rewriters = RewriterSet rewriters }) <- ev
       , NonCanonicalReason ctyeq <- reason
       , ctyeq `cterHasProblem` cteCoercionHole
       , hole `elementOfUniqSet` rewriters
@@ -1859,17 +1860,17 @@ tcInstSkolTyVarsX skol_info subst tvs = wrapTcS $ TcM.tcInstSkolTyVarsX skol_inf
 -- Creating and setting evidence variables and CtFlavors
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-data MaybeNew = Fresh CtEvidence | Cached EvExpr
+data MaybeNew = Fresh WantedCtEvidence | Cached EvExpr
 
 isFresh :: MaybeNew -> Bool
 isFresh (Fresh {})  = True
 isFresh (Cached {}) = False
 
-freshGoals :: [MaybeNew] -> [CtEvidence]
+freshGoals :: [MaybeNew] -> [WantedCtEvidence]
 freshGoals mns = [ ctev | Fresh ctev <- mns ]
 
 getEvExpr :: MaybeNew -> EvExpr
-getEvExpr (Fresh ctev) = ctEvExpr ctev
+getEvExpr (Fresh ctev) = ctEvExpr (CtWanted ctev)
 getEvExpr (Cached evt) = evt
 
 setEvBind :: EvBind -> TcS ()
@@ -1936,8 +1937,8 @@ fillCoercionHole hole co
 setEvBindIfWanted :: CtEvidence -> CanonicalEvidence -> EvTerm -> TcS ()
 setEvBindIfWanted ev canonical tm
   = case ev of
-      CtWanted { ctev_dest = dest } -> setWantedEvTerm dest canonical tm
-      _                             -> return ()
+      CtWanted (WantedCt { ctev_dest = dest }) -> setWantedEvTerm dest canonical tm
+      _                                        -> return ()
 
 newTcEvBinds :: TcS EvBindsVar
 newTcEvBinds = wrapTcS TcM.newTcEvBinds
@@ -1948,14 +1949,14 @@ newNoTcEvBinds = wrapTcS TcM.newNoTcEvBinds
 newEvVar :: TcPredType -> TcS EvVar
 newEvVar pred = wrapTcS (TcM.newEvVar pred)
 
-newGivenEvVar :: CtLoc -> (TcPredType, EvTerm) -> TcS CtEvidence
+newGivenEvVar :: CtLoc -> (TcPredType, EvTerm) -> TcS GivenCtEvidence
 -- Make a new variable of the given PredType,
 -- immediately bind it to the given term
 -- and return its CtEvidence
 -- See Note [Bind new Givens immediately] in GHC.Tc.Types.Constraint
 newGivenEvVar loc (pred, rhs)
   = do { new_ev <- newBoundEvVarId pred rhs
-       ; return (CtGiven { ctev_pred = pred, ctev_evar = new_ev, ctev_loc = loc }) }
+       ; return $ GivenCt { ctev_pred = pred, ctev_evar = new_ev, ctev_loc = loc } }
 
 -- | Make a new 'Id' of the given type, bound (in the monad's EvBinds) to the
 -- given term
@@ -1968,31 +1969,31 @@ newBoundEvVarId pred rhs
 emitNewGivens :: CtLoc -> [(Role,TcCoercion)] -> TcS ()
 emitNewGivens loc pts
   = do { traceTcS "emitNewGivens" (ppr pts)
-       ; evs <- mapM (newGivenEvVar loc) $
+       ; gs <- mapM (newGivenEvVar loc) $
                 [ (mkEqPredRole role ty1 ty2, evCoercion co)
                 | (role, co) <- pts
                 , let Pair ty1 ty2 = coercionKind co
                 , not (ty1 `tcEqType` ty2) ] -- Kill reflexive Givens at birth
-       ; emitWorkNC evs }
+       ; emitWorkNC (map CtGiven gs) }
 
 emitNewWantedEq :: CtLoc -> RewriterSet -> Role -> TcType -> TcType -> TcS Coercion
 -- | Emit a new Wanted equality into the work-list
 emitNewWantedEq loc rewriters role ty1 ty2
-  = do { (ev, co) <- newWantedEq loc rewriters role ty1 ty2
-       ; updWorkListTcS (extendWorkListEq rewriters (mkNonCanonical ev))
+  = do { (wtd, co) <- newWantedEq loc rewriters role ty1 ty2
+       ; updWorkListTcS (extendWorkListEq rewriters (mkNonCanonical $ CtWanted wtd))
        ; return co }
 
 -- | Create a new Wanted constraint holding a coercion hole
 -- for an equality between the two types at the given 'Role'.
 newWantedEq :: CtLoc -> RewriterSet -> Role -> TcType -> TcType
-            -> TcS (CtEvidence, Coercion)
+            -> TcS (WantedCtEvidence, Coercion)
 newWantedEq loc rewriters role ty1 ty2
   = do { hole <- wrapTcS $ TcM.newCoercionHole loc pty
-       ; return ( CtWanted { ctev_pred      = pty
-                           , ctev_dest      = HoleDest hole
-                           , ctev_loc       = loc
-                           , ctev_rewriters = rewriters }
-                , mkHoleCo hole ) }
+       ; let wtd = WantedCt { ctev_pred      = pty
+                            , ctev_dest      = HoleDest hole
+                            , ctev_loc       = loc
+                            , ctev_rewriters = rewriters }
+       ; return (wtd, mkHoleCo hole) }
   where
     pty = mkEqPredRole role ty1 ty2
 
@@ -2000,17 +2001,19 @@ newWantedEq loc rewriters role ty1 ty2
 --
 -- Don't use this for equality constraints: use 'newWantedEq' instead.
 newWantedEvVarNC :: CtLoc -> RewriterSet
-                 -> TcPredType -> TcS CtEvidence
+                 -> TcPredType -> TcS WantedCtEvidence
 -- Don't look up in the solved/inerts; we know it's not there
 newWantedEvVarNC loc rewriters pty
   = assertPpr (not (isEqPred pty)) (ppr pty) $
     do { new_ev <- newEvVar pty
        ; traceTcS "Emitting new wanted" (ppr new_ev <+> dcolon <+> ppr pty $$
                                          pprCtLoc loc)
-       ; return (CtWanted { ctev_pred      = pty
-                          , ctev_dest      = EvVarDest new_ev
-                          , ctev_loc       = loc
-                          , ctev_rewriters = rewriters })}
+       ; return $
+           WantedCt { ctev_pred      = pty
+                    , ctev_dest      = EvVarDest new_ev
+                    , ctev_loc       = loc
+                    , ctev_rewriters = rewriters }
+       }
 
 -- | Like 'newWantedEvVarNC', except it might look up in the inert set
 -- to see if an inert already exists, and uses that instead of creating
@@ -2051,7 +2054,7 @@ newWanted loc rewriters pty
 --
 -- Does not attempt to re-use non-equality constraints that already
 -- exist in the inert set.
-newWantedNC :: CtLoc -> RewriterSet -> PredType -> TcS CtEvidence
+newWantedNC :: CtLoc -> RewriterSet -> PredType -> TcS WantedCtEvidence
 newWantedNC loc rewriters pty
   | Just (role, ty1, ty2) <- getEqPredTys_maybe pty
   = fst <$> newWantedEq loc rewriters role ty1 ty2
@@ -2370,7 +2373,7 @@ checkTypeEq ev eq_rel lhs rhs
     ---------------------------
     mk_new_given :: (TcTyVar, TcType) -> TcS Ct
     mk_new_given (new_tv, fam_app)
-      = mkNonCanonical <$> newGivenEvVar cb_loc (given_pred, given_term)
+      = mkNonCanonical . CtGiven <$> newGivenEvVar cb_loc (given_pred, given_term)
       where
         new_ty     = mkTyVarTy new_tv
         given_pred = mkNomEqPred fam_app new_ty
diff --git a/compiler/GHC/Tc/Solver/Rewrite.hs b/compiler/GHC/Tc/Solver/Rewrite.hs
index 9f091b36786113890441839fd7e283dd0b5c5701..d52a4260db1f3cdeafd5cdf67109e83a95773f24 100644
--- a/compiler/GHC/Tc/Solver/Rewrite.hs
+++ b/compiler/GHC/Tc/Solver/Rewrite.hs
@@ -151,15 +151,15 @@ bumpDepth (RewriteM thing_inside)
       ; thing_inside env' }
 
 -- See Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint
--- Precondition: the CtEvidence is a CtWanted of an equality
-recordRewriter :: CtEvidence -> RewriteM ()
-recordRewriter (CtWanted { ctev_dest = HoleDest hole })
+-- Precondition: the WantedCtEvidence is for an equality constraint
+recordRewriter :: WantedCtEvidence -> RewriteM ()
+recordRewriter (WantedCt { ctev_dest = HoleDest hole })
   = RewriteM $ \env -> updTcRef (re_rewriters env) (`addRewriter` hole)
-recordRewriter other = pprPanic "recordRewriter" (ppr other)
+recordRewriter other =
+  pprPanic "recordRewriter: non-equality constraint" (ppr other)
 
-{-
-Note [Rewriter EqRels]
-~~~~~~~~~~~~~~~~~~~~~~~
+{- Note [Rewriter EqRels]
+~~~~~~~~~~~~~~~~~~~~~~~~~
 When rewriting, we need to know which equality relation -- nominal
 or representational -- we should be respecting.  This is controlled
 by the `re_eq_rel` field of RewriteEnv.
@@ -1021,12 +1021,14 @@ rewrite_tyvar2 tv fr@(_, eq_rel)
              | Just ct <- find can_rewrite equal_ct_list
              , EqCt { eq_ev = ctev, eq_lhs = TyVarLHS tv
                     , eq_rhs = rhs_ty, eq_eq_rel = ct_eq_rel } <- ct
-             -> do { let wrw = isWanted ctev
-                   ; traceRewriteM "Following inert tyvar" $
+             -> do { traceRewriteM "Following inert tyvar" $
                         vcat [ ppr tv <+> equals <+> ppr rhs_ty
-                             , ppr ctev
-                             , text "wanted_rewrite_wanted:" <+> ppr wrw ]
-                   ; when wrw $ recordRewriter ctev
+                             , ppr ctev ]
+                   ; case ctev of
+                       CtGiven {} -> return ()
+                       CtWanted wtd ->
+                         -- See Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint
+                         recordRewriter wtd
 
                    ; let rewriting_co1 = ctEvCoercion ctev
                          rewriting_co  = case (ct_eq_rel, eq_rel) of
diff --git a/compiler/GHC/Tc/Solver/Solve.hs b/compiler/GHC/Tc/Solver/Solve.hs
index 771493bfe80b6c58567f21a1c6ea5c23abf11e46..8693dc3596e7f07451e4023cac2ae53e27f22bdc 100644
--- a/compiler/GHC/Tc/Solver/Solve.hs
+++ b/compiler/GHC/Tc/Solver/Solve.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE MultiWayIf #-}
 {-# LANGUAGE RecursiveDo #-}
 
@@ -1225,15 +1226,15 @@ solveForAll ev tvs theta body_pred fuel =
       -- See Note [Solving a Given forall-constraint]
       do { addInertForAll qci
          ; stopWith ev "Given forall-constraint" }
-    CtWanted {} ->
+    CtWanted wtd ->
       -- See Note [Solving a Wanted forall-constraint]
       runSolverStage $
       do { tryInertQCs qci
-         ; Stage $ solveWantedForAll_implic ev tvs theta body_pred
+         ; Stage $ solveWantedForAll_implic wtd tvs theta body_pred
          }
   where
     qci = QCI { qci_ev = ev, qci_tvs = tvs
-              , qci_pred = body_pred, qci_pend_sc = fuel }
+              , qci_body = body_pred, qci_pend_sc = fuel }
 
 
 tryInertQCs :: QCInst -> SolverStage ()
@@ -1260,15 +1261,15 @@ try_inert_qcs (QCI { qci_ev = ev_w }) inerts =
 -- | Solve a (canonical) Wanted quantified constraint by emitting an implication.
 --
 -- See Note [Solving a Wanted forall-constraint]
-solveWantedForAll_implic :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType -> TcS (StopOrContinue Void)
+solveWantedForAll_implic :: WantedCtEvidence -> [TcTyVar] -> TcThetaType -> PredType -> TcS (StopOrContinue Void)
 solveWantedForAll_implic
-  ev@(CtWanted { ctev_dest = dest, ctev_loc = loc, ctev_rewriters = rewriters })
+  wtd@(WantedCt { ctev_dest = dest, ctev_loc = loc, ctev_rewriters = rewriters })
   tvs theta body_pred =
     -- We are about to do something irreversible (turning a quantified constraint
     -- into an implication), so wrap the inner call in solveCompletelyIfRequired
     -- to ensure we can roll back if we can't solve the implication fully.
     -- See Note [TcSSpecPrag] in GHC.Tc.Solver.Monad.
-    solveCompletelyIfRequired (mkNonCanonical ev) $
+    solveCompletelyIfRequired (mkNonCanonical $ CtWanted wtd) $
 
     -- This setSrcSpan is important: the emitImplicationTcS uses that
     -- TcLclEnv for the implication, and that in turn sets the location
@@ -1296,8 +1297,8 @@ solveWantedForAll_implic
                          -- See (QC-INV) in Note [Solving a Wanted forall-constraint]
                    ; wanted_ev <- newWantedNC loc' rewriters inst_pred
                          -- NB: inst_pred can be an equality
-                   ; return ( ctEvEvId wanted_ev
-                            , unitBag (mkNonCanonical wanted_ev)) }
+                   ; return ( wantedCtEvEvId wanted_ev
+                            , unitBag (mkNonCanonical $ CtWanted wanted_ev)) }
 
       ; traceTcS "solveForAll" (ppr given_ev_vars $$ ppr wanteds $$ ppr w_id)
       ; ev_binds <- emitImplicationTcS lvl skol_info_anon skol_tvs given_ev_vars wanteds
@@ -1306,7 +1307,7 @@ solveWantedForAll_implic
         EvFun { et_tvs = skol_tvs, et_given = given_ev_vars
               , et_binds = ev_binds, et_body = w_id }
 
-      ; stopWith ev "Wanted forall-constraint (implication)"
+      ; stopWith (CtWanted wtd) "Wanted forall-constraint (implication)"
       }
   where
     -- Getting the size of the head is a bit horrible
@@ -1314,8 +1315,6 @@ solveWantedForAll_implic
     get_size pred = case classifyPredType pred of
                       ClassPred cls tys -> pSizeClassPred cls tys
                       _                 -> pSizeType pred
-solveWantedForAll_implic (CtGiven {}) _ _ _ =
-  panic "solveWantedForAll_implic: CtGiven"
 
 {- Note [Solving a Wanted forall-constraint]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1450,33 +1449,35 @@ finish_rewrite old_ev (Reduction co new_pred) rewriters
   = assert (isEmptyRewriterSet rewriters) $
     continueWith (setCtEvPredType old_ev new_pred)
 
-finish_rewrite ev@(CtGiven { ctev_evar = old_evar, ctev_loc = loc })
-                (Reduction co new_pred) rewriters
+finish_rewrite
+  ev@(CtGiven (GivenCt { ctev_evar = old_evar }))
+  (Reduction co new_pred)
+  rewriters
   = assert (isEmptyRewriterSet rewriters) $ -- this is a Given, not a wanted
-    do { new_ev <- newGivenEvVar loc (new_pred, new_tm)
-       ; continueWith new_ev }
-  where
-    -- mkEvCast optimises ReflCo
-    ev_rw_role = ctEvRewriteRole ev
-    new_tm = assert (coercionRole co == ev_rw_role)
-             mkEvCast (evId old_evar)
-                (downgradeRole Representational ev_rw_role co)
-
-finish_rewrite ev@(CtWanted { ctev_dest = dest
-                             , ctev_loc = loc
-                             , ctev_rewriters = rewriters })
-                (Reduction co new_pred) new_rewriters
-  = do { mb_new_ev <- newWanted loc rewriters' new_pred
-       ; let ev_rw_role = ctEvRewriteRole ev
+    do { let loc = ctEvLoc ev
+             -- mkEvCast optimises ReflCo
+             ev_rw_role = ctEvRewriteRole ev
+             new_tm = assert (coercionRole co == ev_rw_role)
+                      mkEvCast (evId old_evar)
+                         (downgradeRole Representational ev_rw_role co)
+       ; new_ev <- newGivenEvVar loc (new_pred, new_tm)
+       ; continueWith $ CtGiven new_ev }
+
+finish_rewrite
+  ev@(CtWanted (WantedCt { ctev_rewriters = rewriters, ctev_dest = dest }))
+  (Reduction co new_pred)
+  new_rewriters
+  = do { let loc = ctEvLoc ev
+             rewriters' = rewriters S.<> new_rewriters
+             ev_rw_role = ctEvRewriteRole ev
+       ; mb_new_ev <- newWanted loc rewriters' new_pred
        ; massert (coercionRole co == ev_rw_role)
        ; setWantedEvTerm dest EvCanonical $
             mkEvCast (getEvExpr mb_new_ev)
                      (downgradeRole Representational ev_rw_role (mkSymCo co))
        ; case mb_new_ev of
-            Fresh  new_ev -> continueWith new_ev
+            Fresh  new_ev -> continueWith $ CtWanted new_ev
             Cached _      -> stopWith ev "Cached wanted" }
-  where
-    rewriters' = rewriters S.<> new_rewriters
 
 {- *******************************************************************
 *                                                                    *
@@ -1544,7 +1545,7 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1 })
   where
     setEv :: (EvTerm,Ct) -> TcS ()
     setEv (ev,ct) = case ctEvidence ct of
-      CtWanted { ctev_dest = dest } -> setWantedEvTerm dest EvCanonical ev
+      CtWanted (WantedCt { ctev_dest = dest }) -> setWantedEvTerm dest EvCanonical ev
            -- TODO: plugins should be able to signal non-canonicity
       _ -> panic "runTcPluginsWanted.setEv: attempt to solve non-wanted!"
 
diff --git a/compiler/GHC/Tc/Types/Constraint.hs b/compiler/GHC/Tc/Types/Constraint.hs
index 695be54d85994c5883b72c749577dd0a342b7505..76274bad0f6e56ffae7abb44bd734138300e9c76 100644
--- a/compiler/GHC/Tc/Types/Constraint.hs
+++ b/compiler/GHC/Tc/Types/Constraint.hs
@@ -1,5 +1,5 @@
-
 {-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE TypeApplications #-}
 
@@ -75,11 +75,16 @@ module GHC.Tc.Types.Constraint (
         CtEvidence(..), TcEvDest(..),
         isWanted, isGiven,
         ctEvPred, ctEvLoc, ctEvOrigin, ctEvEqRel,
-        ctEvExpr, ctEvTerm, ctEvCoercion, ctEvEvId,
-        ctEvRewriters, ctEvUnique, tcEvDestUnique,
+        ctEvExpr, ctEvTerm,
+        ctEvCoercion, givenCtEvCoercion,
+        ctEvEvId, wantedCtEvEvId,
+        ctEvRewriters, setWantedCtEvRewriters, ctEvUnique, tcEvDestUnique,
         ctEvRewriteRole, ctEvRewriteEqRel, setCtEvPredType, setCtEvLoc,
         tyCoVarsOfCtEvList, tyCoVarsOfCtEv, tyCoVarsOfCtEvsList,
 
+        -- CtEvidence constructors
+        GivenCtEvidence(..), WantedCtEvidence(..),
+
         -- RewriterSet
         RewriterSet(..), emptyRewriterSet, isEmptyRewriterSet,
            -- exported concretely only for zonkRewriterSet
@@ -189,15 +194,24 @@ assertFuelPreconditionStrict :: ExpansionFuel -> a -> a
 {-# INLINE assertFuelPreconditionStrict #-}
 assertFuelPreconditionStrict fuel = assertPpr (pendingFuel fuel) insufficientFuelError
 
+-- | Constraint
 data Ct
+  -- | A dictionary constraint (canonical)
   = CDictCan      DictCt
-  | CIrredCan     IrredCt      -- A "irreducible" constraint (non-canonical)
-  | CEqCan        EqCt         -- A canonical equality constraint
-  | CQuantCan     QCInst       -- A quantified constraint
-  | CNonCanonical CtEvidence   -- See Note [NonCanonical Semantics] in GHC.Tc.Solver.Monad
+  -- | An irreducible constraint (non-canonical)
+  | CIrredCan     IrredCt
+  -- | An equality constraint (canonical)
+  | CEqCan        EqCt
+  -- | A quantified constraint (canonical)
+  | CQuantCan     QCInst
+  -- | A non-canonical constraint
+  --
+  -- See Note [NonCanonical Semantics] in GHC.Tc.Solver.Monad
+  | CNonCanonical CtEvidence
 
 --------------- DictCt --------------
 
+-- | A canonical dictionary constraint
 data DictCt   -- e.g.  Num ty
   = DictCt { di_ev  :: CtEvidence  -- See Note [Ct/evidence invariant]
 
@@ -279,7 +293,10 @@ and forms condition T3 in Note [Extending the inert equalities]
 in GHC.Tc.Solver.InertSet.
 -}
 
-data EqCt -- An equality constraint; see Note [Canonical equalities]
+-- | A canonical equality constraint.
+--
+-- See Note [Canonical equalities] in GHC.Tc.Types.Constraint.
+data EqCt
   = EqCt {  -- CanEqLHS ~ rhs
       eq_ev     :: CtEvidence, -- See Note [Ct/evidence invariant]
       eq_lhs    :: CanEqLHS,
@@ -319,18 +336,23 @@ instance Outputable IrredCt where
 
 --------------- QCInst --------------
 
-data QCInst  -- A much simplified version of ClsInst
-             -- See Note [Quantified constraints] in GHC.Tc.Solver.Solve
-  = QCI { qci_ev   :: CtEvidence -- Always of type forall tvs. context => ty
-                                 -- Always Given
-        , qci_tvs  :: [TcTyVar]  -- The tvs
-        , qci_pred :: TcPredType -- The ty
+-- | A quantified constraint, also called a "local instance"
+-- (a simplified version of 'ClsInst').
+--
+-- See Note [Quantified constraints] in GHC.Tc.Solver.Solve
+data QCInst
+  -- | A quantified constraint, of type @forall tvs. context => ty@
+  = QCI { qci_ev   :: CtEvidence
+        , qci_tvs  :: [TcTyVar]  -- ^ @tvs@
+        , qci_body :: TcPredType -- ^ the body of the @forall@, i.e. @ty@
         , qci_pend_sc :: ExpansionFuel
-             -- Invariants: qci_pend_sc > 0 =>
-             --       (a) qci_pred is a ClassPred
-             --       (b) this class has superclass(es), and
-             --       (c) the superclass(es) are not explored yet
-             -- Same as di_pend_sc flag in DictCt
+             -- ^ Invariants: qci_pend_sc > 0 =>
+             --
+             --    (a) 'qci_body' is a ClassPred
+             --    (b) this class has superclass(es), and
+             --    (c) the superclass(es) are not explored yet
+             --
+             -- Same as 'di_pend_sc' flag in 'DictCt'
              -- See Note [Expanding Recursive Superclasses and ExpansionFuel] in GHC.Tc.Solver
     }
 
@@ -682,9 +704,9 @@ mkGivens :: CtLoc -> [EvId] -> [Ct]
 mkGivens loc ev_ids
   = map mk ev_ids
   where
-    mk ev_id = mkNonCanonical (CtGiven { ctev_evar = ev_id
-                                       , ctev_pred = evVarPred ev_id
-                                       , ctev_loc = loc })
+    mk ev_id = mkNonCanonical (CtGiven (GivenCt { ctev_evar = ev_id
+                                               , ctev_pred = evVarPred ev_id
+                                               , ctev_loc = loc }))
 
 ctEvidence :: Ct -> CtEvidence
 ctEvidence (CQuantCan (QCI { qci_ev = ev }))    = ev
@@ -1279,7 +1301,7 @@ insolubleWantedCt ct
   | CIrredCan ir_ct <- ct
       -- CIrredCan: see (IW1) in Note [Insoluble Wanteds]
   , IrredCt { ir_ev = ev } <- ir_ct
-  , CtWanted { ctev_loc = loc, ctev_rewriters = rewriters }  <- ev
+  , CtWanted (WantedCt { ctev_loc = loc, ctev_rewriters = rewriters })  <- ev
       -- It's a Wanted
   , insolubleIrredCt ir_ct
       -- It's insoluble
@@ -2180,24 +2202,32 @@ data TcEvDest
               -- See Note [Coercion holes] in GHC.Core.TyCo.Rep
 
 data CtEvidence
-  = CtGiven    -- Truly given, not depending on subgoals
-      { ctev_pred :: TcPredType      -- See Note [Ct/evidence invariant]
-      , ctev_evar :: EvVar           -- See Note [CtEvidence invariants]
-      , ctev_loc  :: CtLoc }
-
-
-  | CtWanted   -- Wanted goal
-      { ctev_pred      :: TcPredType     -- See Note [Ct/evidence invariant]
-      , ctev_dest      :: TcEvDest       -- See Note [CtEvidence invariants]
-      , ctev_loc       :: CtLoc
-      , ctev_rewriters :: RewriterSet }  -- See Note [Wanteds rewrite Wanteds]
+  = CtGiven  GivenCtEvidence
+  | CtWanted WantedCtEvidence
+
+-- | Evidence for a Given constraint
+data GivenCtEvidence =
+  GivenCt
+    { ctev_pred :: TcPredType      -- See Note [Ct/evidence invariant]
+    , ctev_evar :: EvVar           -- See Note [CtEvidence invariants]
+    , ctev_loc  :: CtLoc }
+
+-- | Evidence for a Wanted constraint
+data WantedCtEvidence =
+  WantedCt
+    { ctev_pred      :: TcPredType     -- See Note [Ct/evidence invariant]
+    , ctev_dest      :: TcEvDest       -- See Note [CtEvidence invariants]
+    , ctev_loc       :: CtLoc
+    , ctev_rewriters :: RewriterSet }  -- See Note [Wanteds rewrite Wanteds]
 
 ctEvPred :: CtEvidence -> TcPredType
 -- The predicate of a flavor
-ctEvPred = ctev_pred
+ctEvPred (CtGiven (GivenCt { ctev_pred = pred }))  = pred
+ctEvPred (CtWanted (WantedCt { ctev_pred = pred })) = pred
 
 ctEvLoc :: CtEvidence -> CtLoc
-ctEvLoc = ctev_loc
+ctEvLoc (CtGiven (GivenCt { ctev_loc = loc }))  = loc
+ctEvLoc (CtWanted (WantedCt { ctev_loc = loc })) = loc
 
 ctEvOrigin :: CtEvidence -> CtOrigin
 ctEvOrigin = ctLocOrigin . ctEvLoc
@@ -2225,20 +2255,30 @@ ctEvTerm ev = EvExpr (ctEvExpr ev)
 -- If the provided CtEvidence is not for a Wanted, just
 -- return an empty set.
 ctEvRewriters :: CtEvidence -> RewriterSet
-ctEvRewriters (CtWanted { ctev_rewriters = rewriters }) = rewriters
-ctEvRewriters (CtGiven {})                              = emptyRewriterSet
+ctEvRewriters (CtWanted (WantedCt { ctev_rewriters = rws })) = rws
+ctEvRewriters (CtGiven {})  = emptyRewriterSet
+
+-- | Set the rewriter set of a Wanted constraint.
+setWantedCtEvRewriters :: WantedCtEvidence -> RewriterSet -> WantedCtEvidence
+setWantedCtEvRewriters ev rs = ev { ctev_rewriters = rs }
 
 ctEvExpr :: HasDebugCallStack => CtEvidence -> EvExpr
-ctEvExpr ev@(CtWanted { ctev_dest = HoleDest _ })
-            = Coercion $ ctEvCoercion ev
+ctEvExpr (CtWanted ev@(WantedCt { ctev_dest = HoleDest _ }))
+            = Coercion $ ctEvCoercion (CtWanted ev)
 ctEvExpr ev = evId (ctEvEvId ev)
 
+givenCtEvCoercion :: GivenCtEvidence -> TcCoercion
+givenCtEvCoercion _given@(GivenCt { ctev_evar = ev_id })
+  = assertPpr (isCoVar ev_id)
+    (text "givenCtEvCoercion used on non-equality Given constraint:" <+> ppr _given)
+  $ mkCoVarCo ev_id
+
 ctEvCoercion :: HasDebugCallStack => CtEvidence -> TcCoercion
-ctEvCoercion _given@(CtGiven { ctev_evar = ev_id })
+ctEvCoercion (CtGiven _given@(GivenCt { ctev_evar = ev_id }))
   = assertPpr (isCoVar ev_id)
-    (text "ctEvCoercion used on non-equality Given constraint:" <+> ppr _given)
+    (text "ctEvCoercion used on non-equality Given constraint:" <+> ppr (CtGiven _given))
   $ mkCoVarCo ev_id
-ctEvCoercion (CtWanted { ctev_dest = dest })
+ctEvCoercion (CtWanted (WantedCt { ctev_dest = dest }))
   | HoleDest hole <- dest
   = -- ctEvCoercion is only called on type equalities
     -- and they always have HoleDests
@@ -2247,20 +2287,24 @@ ctEvCoercion ev
   = pprPanic "ctEvCoercion" (ppr ev)
 
 ctEvEvId :: CtEvidence -> EvVar
-ctEvEvId (CtWanted { ctev_dest = EvVarDest ev }) = ev
-ctEvEvId (CtWanted { ctev_dest = HoleDest h })   = coHoleCoVar h
-ctEvEvId (CtGiven  { ctev_evar = ev })           = ev
+ctEvEvId (CtWanted wtd)                         = wantedCtEvEvId wtd
+ctEvEvId (CtGiven (GivenCt { ctev_evar = ev })) = ev
+
+wantedCtEvEvId :: WantedCtEvidence -> EvVar
+wantedCtEvEvId (WantedCt { ctev_dest = EvVarDest ev }) = ev
+wantedCtEvEvId (WantedCt { ctev_dest = HoleDest h })   = coHoleCoVar h
 
 ctEvUnique :: CtEvidence -> Unique
-ctEvUnique (CtGiven { ctev_evar = ev })    = varUnique ev
-ctEvUnique (CtWanted { ctev_dest = dest }) = tcEvDestUnique dest
+ctEvUnique (CtGiven (GivenCt { ctev_evar = ev }))     = varUnique ev
+ctEvUnique (CtWanted (WantedCt { ctev_dest = dest })) = tcEvDestUnique dest
 
 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 }
+setCtEvLoc (CtGiven (GivenCt pred evar _)) loc = CtGiven (GivenCt pred evar loc)
+setCtEvLoc (CtWanted (WantedCt pred dest _ rwrs)) loc = CtWanted (WantedCt pred dest loc rwrs)
 
 -- | Set the type of CtEvidence.
 --
@@ -2268,13 +2312,13 @@ setCtEvLoc ctev loc = ctev { ctev_loc = loc }
 -- the evidence and the ctev_pred in sync with each other.
 -- See Note [CtEvidence invariants].
 setCtEvPredType :: HasDebugCallStack => CtEvidence -> Type -> CtEvidence
-setCtEvPredType old_ctev@(CtGiven { ctev_evar = ev }) new_pred
-  = old_ctev { ctev_pred = new_pred
-             , ctev_evar = setVarType ev new_pred }
+setCtEvPredType (CtGiven old_ev@(GivenCt { ctev_evar = ev })) new_pred
+  = CtGiven (old_ev { ctev_pred = new_pred
+                    , ctev_evar = setVarType ev new_pred })
 
-setCtEvPredType old_ctev@(CtWanted { ctev_dest = dest }) new_pred
-  = old_ctev { ctev_pred = new_pred
-             , ctev_dest = new_dest }
+setCtEvPredType (CtWanted old_ev@(WantedCt { ctev_dest = dest })) new_pred
+  = CtWanted (old_ev { ctev_pred = new_pred
+                     , ctev_dest = new_dest })
   where
     new_dest = case dest of
       EvVarDest ev -> EvVarDest (setVarType ev new_pred)
@@ -2284,6 +2328,11 @@ instance Outputable TcEvDest where
   ppr (HoleDest h)   = text "hole" <> ppr h
   ppr (EvVarDest ev) = ppr ev
 
+instance Outputable GivenCtEvidence where
+  ppr = ppr . CtGiven
+instance Outputable WantedCtEvidence where
+  ppr = ppr . CtWanted
+
 instance Outputable CtEvidence where
   ppr ev = ppr (ctEvFlavour ev)
            <+> pp_ev <+> braces (ppr (ctl_depth (ctEvLoc ev)) <> pp_rewriters)
@@ -2291,8 +2340,8 @@ instance Outputable CtEvidence where
                <> dcolon <+> ppr (ctEvPred ev)
     where
       pp_ev = case ev of
-             CtGiven { ctev_evar = v } -> ppr v
-             CtWanted {ctev_dest = d } -> ppr d
+             CtGiven ev -> ppr (ctev_evar ev)
+             CtWanted ev -> ppr (ctev_dest ev)
 
       rewriters = ctEvRewriters ev
       pp_rewriters | isEmptyRewriterSet rewriters = empty
@@ -2339,9 +2388,10 @@ rewriterSetFromCts :: Bag Ct -> RewriterSet
 rewriterSetFromCts cts
   = foldr add emptyRewriterSet cts
   where
-    add ct rw_set = case ctEvidence ct of
-         CtWanted { ctev_dest = HoleDest hole } -> rw_set `addRewriter` hole
-         _                                      -> rw_set
+    add ct rw_set =
+      case ctEvidence ct of
+        CtWanted (WantedCt { ctev_dest = HoleDest hole }) -> rw_set `addRewriter` hole
+        _                                                 -> rw_set
 
 {-
 ************************************************************************
@@ -2618,4 +2668,3 @@ eqCanRewriteFR (Given,  r1)    (_,      r2)     = eqCanRewrite r1 r2
 eqCanRewriteFR (Wanted, NomEq) (Wanted, ReprEq) = False
 eqCanRewriteFR (Wanted, r1)    (Wanted, r2)     = eqCanRewrite r1 r2
 eqCanRewriteFR (Wanted, _)     (Given, _)       = False
-
diff --git a/compiler/GHC/Tc/Utils/Backpack.hs b/compiler/GHC/Tc/Utils/Backpack.hs
index 0ff3bc528c12f1926c0f423a81b51ff7a8412b39..73c5719c580065a05cf1529d7c5572c34fc94033 100644
--- a/compiler/GHC/Tc/Utils/Backpack.hs
+++ b/compiler/GHC/Tc/Utils/Backpack.hs
@@ -1,4 +1,5 @@
 
+{-# LANGUAGE DuplicateRecordFields    #-}
 {-# LANGUAGE NondecreasingIndentation #-}
 {-# LANGUAGE ScopedTypeVariables      #-}
 {-# LANGUAGE TypeFamilies             #-}
@@ -221,7 +222,8 @@ check_inst sig_inst@(ClsInst { is_dfun = dfun_id }) = do
     (tclvl,cts) <- pushTcLevelM $ do
        given_ids <- mapM newEvVar inst_theta
        let given_loc = mkGivenLoc topTcLevel skol_info (mkCtLocEnv lcl_env)
-           givens = [ CtGiven { ctev_pred = idType given_id
+           givens = [ CtGiven $
+                      GivenCt { ctev_pred = idType given_id
                               -- Doesn't matter, make something up
                               , ctev_evar = given_id
                               , ctev_loc  = given_loc  }
diff --git a/compiler/GHC/Tc/Utils/TcMType.hs b/compiler/GHC/Tc/Utils/TcMType.hs
index 0bba873b65c12dc48bae08e566a9b29c3939d839..ea7c6cfff3517967918f453be56b9660b6a883c7 100644
--- a/compiler/GHC/Tc/Utils/TcMType.hs
+++ b/compiler/GHC/Tc/Utils/TcMType.hs
@@ -1,7 +1,8 @@
-{-# LANGUAGE LambdaCase      #-}
-{-# LANGUAGE MultiWayIf      #-}
-{-# LANGUAGE RecursiveDo     #-}
-{-# LANGUAGE TupleSections   #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE LambdaCase            #-}
+{-# LANGUAGE MultiWayIf            #-}
+{-# LANGUAGE RecursiveDo           #-}
+{-# LANGUAGE TupleSections         #-}
 
 {-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
 {-
@@ -203,10 +204,11 @@ newWantedWithLoc loc pty
   = do dst <- case classifyPredType pty of
                 EqPred {} -> HoleDest  <$> newCoercionHole loc pty
                 _         -> EvVarDest <$> newEvVar pty
-       return $ CtWanted { ctev_dest      = dst
-                         , ctev_pred      = pty
-                         , ctev_loc       = loc
-                         , ctev_rewriters = emptyRewriterSet }
+       return $ CtWanted $
+         WantedCt { ctev_dest      = dst
+                  , ctev_pred      = pty
+                  , ctev_loc       = loc
+                  , ctev_rewriters = emptyRewriterSet }
 
 -- | Create a new Wanted constraint with the given 'CtOrigin', and
 -- location information taken from the 'TcM' environment.
@@ -226,10 +228,10 @@ newWanteds orig = mapM (newWanted orig Nothing)
 ----------------------------------------------
 
 cloneWantedCtEv :: CtEvidence -> TcM CtEvidence
-cloneWantedCtEv ctev@(CtWanted { ctev_pred = pty, ctev_dest = HoleDest _, ctev_loc = loc })
+cloneWantedCtEv (CtWanted ctev@(WantedCt { ctev_pred = pty, ctev_dest = HoleDest _, ctev_loc = loc }))
   | isEqPred pty
   = do { co_hole <- newCoercionHole loc pty
-       ; return (ctev { ctev_dest = HoleDest co_hole }) }
+       ; return $ CtWanted (ctev { ctev_dest = HoleDest co_hole }) }
   | otherwise
   = pprPanic "cloneWantedCtEv" (ppr pty)
 cloneWantedCtEv ctev = return ctev
@@ -278,11 +280,11 @@ emitWantedEq :: CtOrigin -> TypeOrKind -> Role -> TcType -> TcType -> TcM Coerci
 emitWantedEq origin t_or_k role ty1 ty2
   = do { hole <- newCoercionHoleO origin pty
        ; loc  <- getCtLocM origin (Just t_or_k)
-       ; emitSimple $ mkNonCanonical $
-         CtWanted { ctev_pred      = pty
-                  , ctev_dest      = HoleDest hole
-                  , ctev_loc       = loc
-                  , ctev_rewriters = emptyRewriterSet }
+       ; emitSimple $ mkNonCanonical $ CtWanted $
+           WantedCt { ctev_pred      = pty
+                    , ctev_dest      = HoleDest hole
+                    , ctev_loc       = loc
+                    , ctev_rewriters = emptyRewriterSet }
        ; return (HoleCo hole) }
   where
     pty = mkEqPredRole role ty1 ty2
@@ -293,11 +295,11 @@ emitWantedEvVar :: CtOrigin -> TcPredType -> TcM EvVar
 emitWantedEvVar origin ty
   = do { new_cv <- newEvVar ty
        ; loc <- getCtLocM origin Nothing
-       ; let ctev = CtWanted { ctev_pred      = ty
+       ; let ctev = WantedCt { ctev_pred      = ty
                              , ctev_dest      = EvVarDest new_cv
                              , ctev_loc       = loc
                              , ctev_rewriters = emptyRewriterSet }
-       ; emitSimple $ mkNonCanonical ctev
+       ; emitSimple $ mkNonCanonical $ CtWanted ctev
        ; return new_cv }
 
 emitWantedEvVars :: CtOrigin -> [TcPredType] -> TcM [EvVar]
diff --git a/compiler/GHC/Tc/Utils/Unify.hs b/compiler/GHC/Tc/Utils/Unify.hs
index 839ad4f54f4620e795bf987fef0ebc316f34d431..806b0678d2ec12a7ffbba9c2c44c1f25c8fc13f3 100644
--- a/compiler/GHC/Tc/Utils/Unify.hs
+++ b/compiler/GHC/Tc/Utils/Unify.hs
@@ -2145,11 +2145,11 @@ uType_defer (UE { u_loc = loc, u_defer = ref
             ty1 ty2  -- ty1 is "actual", ty2 is "expected"
   = do { let pred_ty = mkEqPredRole role ty1 ty2
        ; hole <- newCoercionHole loc pred_ty
-       ; let ct = mkNonCanonical $
-                  CtWanted { ctev_pred      = pred_ty
-                           , ctev_dest      = HoleDest hole
-                           , ctev_loc       = loc
-                           , ctev_rewriters = rewriters }
+       ; let ct = mkNonCanonical $ CtWanted $
+                    WantedCt { ctev_pred      = pred_ty
+                             , ctev_dest      = HoleDest hole
+                             , ctev_loc       = loc
+                             , ctev_rewriters = rewriters }
              co = HoleCo hole
        ; updTcRef ref (`snocBag` ct)
          -- snocBag: see Note [Work-list ordering] in GHC.Tc.Solver.Equality
@@ -3403,11 +3403,11 @@ famAppBreaker (BreakWanted ev lhs_tv) fam_app
 
        ; let pty = mkNomEqPred fam_app new_tv_ty
        ; hole <- TcM.newVanillaCoercionHole pty
-       ; let new_ev = CtWanted { ctev_pred      = pty
+       ; let new_ev = WantedCt { ctev_pred      = pty
                                , ctev_dest      = HoleDest hole
                                , ctev_loc       = cb_loc
                                , ctev_rewriters = ctEvRewriters ev }
-       ; return (PuOK (singleCt (mkNonCanonical new_ev))
+       ; return (PuOK (singleCt (mkNonCanonical $ CtWanted new_ev))
                       (mkReduction (HoleCo hole) new_tv_ty)) } }
   where
     (lhs_tv_info, lhs_tv_lvl) =
@@ -4114,8 +4114,8 @@ makeTypeConcrete occ_fs conc_orig ty =
                       pty = mkEqPredRole Nominal ty' conc_ty
                 ; hole <- newCoercionHoleO orig pty
                 ; loc <- getCtLocM orig (Just KindLevel)
-                ; let ct = mkNonCanonical
-                         $ CtWanted { ctev_pred      = pty
+                ; let ct = mkNonCanonical $ CtWanted
+                         $ WantedCt { ctev_pred      = pty
                                     , ctev_dest      = HoleDest hole
                                     , ctev_loc       = loc
                                     , ctev_rewriters = emptyRewriterSet }
diff --git a/compiler/GHC/Tc/Zonk/TcType.hs b/compiler/GHC/Tc/Zonk/TcType.hs
index 68d957bac07ebec152c82e6c4a427aabb1f94b0d..ab8ba3db7215a6199d38989d9c5ac9609323d620 100644
--- a/compiler/GHC/Tc/Zonk/TcType.hs
+++ b/compiler/GHC/Tc/Zonk/TcType.hs
@@ -1,4 +1,3 @@
-
 {-
 (c) The University of Glasgow 2006
 (c) The AQUA Project, Glasgow University, 1996-1998
@@ -496,8 +495,7 @@ zonkCt ct
 
 zonkCtEvidence :: CtEvidence -> ZonkM CtEvidence
 zonkCtEvidence ctev
-  = do { let pred = ctev_pred ctev
-       ; pred' <- zonkTcType pred
+  = do { pred' <- zonkTcType (ctEvPred ctev)
        ; return (setCtEvPredType ctev pred') }
 
 zonkSkolemInfo :: SkolemInfo -> ZonkM SkolemInfo
@@ -661,7 +659,7 @@ tidyCtEvidence :: TidyEnv -> CtEvidence -> CtEvidence
      -- NB: we do not tidy the ctev_evar field because we don't
      --     show it in error messages
 tidyCtEvidence env ctev
-  = ctev { ctev_pred = tidyOpenType env $ ctev_pred ctev }
+  = setCtEvPredType ctev (tidyOpenType env (ctEvPred ctev))
   -- tidyOpenType: for (beta ~ (forall a. a->a), don't gratuitously
   -- rename the 'forall a' just because of an 'a' in scope somewhere
   -- else entirely.
diff --git a/compiler/GHC/Tc/Zonk/Type.hs b/compiler/GHC/Tc/Zonk/Type.hs
index e4c98454cf44bb8c5492e56f9ad4e5e7ccc25c85..88266d69578874a1948206e12948e43b2fc2c1f3 100644
--- a/compiler/GHC/Tc/Zonk/Type.hs
+++ b/compiler/GHC/Tc/Zonk/Type.hs
@@ -2002,9 +2002,9 @@ zonkCtRewriterSet ct
 zonkCtEvRewriterSet :: CtEvidence -> TcM CtEvidence
 zonkCtEvRewriterSet ev@(CtGiven {})
   = return ev
-zonkCtEvRewriterSet ev@(CtWanted { ctev_rewriters = rewriters })
-  = do { rewriters' <- zonkRewriterSet rewriters
-       ; return (ev { ctev_rewriters = rewriters' }) }
+zonkCtEvRewriterSet ev@(CtWanted wtd)
+  = do { rewriters' <- zonkRewriterSet (ctEvRewriters ev)
+       ; return (CtWanted $ setWantedCtEvRewriters wtd rewriters') }
 
 -- | Check whether any coercion hole in a RewriterSet is still unsolved.
 -- Does this by recursively looking through filled coercion holes until