Note [Solving tuple constraints]

GHC/Tc/Solver/Dict.hs:435 compiler 2 tickets

I tried treating tuple constraints, such as (% Eq a, Show a %), rather like
equality-class constraints (see Note [Solving equality classes]). That is, by
eagerly decomposing tuple-constraints into their component (Eq a) and (Show a).

But discarding the tuple Given (which "replacing" does) means that we may
have to reconstruct it for a recursive call.  For example
    f :: (% Eq a, Show a %) => blah
    f x = ....(f x')....
If we decomposed eagerly we'd get
    f = \(d : (% Eq a, Show a %)).
         let de = fst d
             ds = snd d
         in ....(f (% de, ds %))...
and the optimiser may not be clever enough to transform (f (% de, ds %)) into
(f d). See #10359 and its test case, and #23398.  (This issue is less pressing for
equality classes because they have to be unpacked strictly, so CSE-ing away
the reconstruction works fine.

So at the moment we don't decompose tuple constraints eagerly; instead we mostly
just treat them like other constraints.
* Given tuples are decomposed via their superclasses, in `canDictCt`.  So
    [G] (% Eq a, Show a %)
  has superclasses
    [G] Eq a,  [G] Show a

* Wanted tuples are decomposed via a built-in "instance". See
  `GHC.Tc.Instance.Class.matchCTuple`

There is a bit of special treatment: search for isCTupleClass.

References 1

Referenced by 2