+\begin{code}
+data WantedConstraints
+ = WC { wc_flat :: Bag WantedEvVar -- Unsolved constraints, all wanted
+ , wc_impl :: Bag Implication
+ , wc_insol :: Bag FlavoredEvVar -- Insoluble constraints, can be
+ -- wanted, given, or derived
+ -- See Note [Insoluble constraints]
+ }
+
+emptyWC :: WantedConstraints
+emptyWC = WC { wc_flat = emptyBag, wc_impl = emptyBag, wc_insol = emptyBag }
+
+mkFlatWC :: Bag WantedEvVar -> WantedConstraints
+mkFlatWC wevs = WC { wc_flat = wevs, wc_impl = emptyBag, wc_insol = emptyBag }
+
+isEmptyWC :: WantedConstraints -> Bool
+isEmptyWC (WC { wc_flat = f, wc_impl = i, wc_insol = n })
+ = isEmptyBag f && isEmptyBag i && isEmptyBag n
+
+insolubleWC :: WantedConstraints -> Bool
+-- True if there are any insoluble constraints in the wanted bag
+insolubleWC wc = not (isEmptyBag (wc_insol wc))
+ || anyBag ic_insol (wc_impl wc)
+
+andWC :: WantedConstraints -> WantedConstraints -> WantedConstraints
+andWC (WC { wc_flat = f1, wc_impl = i1, wc_insol = n1 })
+ (WC { wc_flat = f2, wc_impl = i2, wc_insol = n2 })
+ = WC { wc_flat = f1 `unionBags` f2
+ , wc_impl = i1 `unionBags` i2
+ , wc_insol = n1 `unionBags` n2 }
+
+addFlats :: WantedConstraints -> Bag WantedEvVar -> WantedConstraints
+addFlats wc wevs = wc { wc_flat = wc_flat wc `unionBags` wevs }
+
+addImplics :: WantedConstraints -> Bag Implication -> WantedConstraints
+addImplics wc implic = wc { wc_impl = wc_impl wc `unionBags` implic }
+
+instance Outputable WantedConstraints where
+ ppr (WC {wc_flat = f, wc_impl = i, wc_insol = n})
+ = ptext (sLit "WC") <+> braces (vcat
+ [ if isEmptyBag f then empty else
+ ptext (sLit "wc_flat =") <+> pprBag pprWantedEvVar f
+ , if isEmptyBag i then empty else
+ ptext (sLit "wc_impl =") <+> pprBag ppr i
+ , if isEmptyBag n then empty else
+ ptext (sLit "wc_insol =") <+> pprBag ppr n ])
+
+pprBag :: (a -> SDoc) -> Bag a -> SDoc
+pprBag pp b = foldrBag (($$) . pp) empty b
+\end{code}
+
+
+\begin{code}
+data Untouchables = NoUntouchables
+ | TouchableRange
+ Unique -- Low end
+ Unique -- High end
+ -- A TcMetaTyvar is *touchable* iff its unique u satisfies
+ -- u >= low
+ -- u < high
+
+instance Outputable Untouchables where
+ ppr NoUntouchables = ptext (sLit "No untouchables")
+ ppr (TouchableRange low high) = ptext (sLit "Touchable range:") <+>
+ ppr low <+> char '-' <+> ppr high
+
+isNoUntouchables :: Untouchables -> Bool
+isNoUntouchables NoUntouchables = True
+isNoUntouchables (TouchableRange {}) = False
+
+inTouchableRange :: Untouchables -> TcTyVar -> Bool
+inTouchableRange NoUntouchables _ = True
+inTouchableRange (TouchableRange low high) tv
+ = uniq >= low && uniq < high
+ where
+ uniq = varUnique tv