+--------------------------------------
+data DsEvBind
+ = LetEvBind -- Dictionary or coercion
+ CoreBind -- recursive or non-recursive
+
+ | CaseEvBind -- Coercion binding by superclass selection
+ -- Desugars to case d of d { K _ g _ _ _ -> ... }
+ DictId -- b The dictionary
+ AltCon -- K Its constructor
+ [CoreBndr] -- _ g _ _ _ The binders in the alternative
+
+wrapDsEvBinds :: [DsEvBind] -> CoreExpr -> CoreExpr
+wrapDsEvBinds ds_ev_binds body = foldr wrap_one body ds_ev_binds
+ where
+ body_ty = exprType body
+ wrap_one (LetEvBind b) body = Let b body
+ wrap_one (CaseEvBind x k xs) body = Case (Var x) x body_ty [(k,xs,body)]
+
+dsTcEvBinds :: TcEvBinds -> DsM [DsEvBind]
+dsTcEvBinds (TcEvBinds {}) = panic "dsEvBinds" -- Zonker has got rid of this
+dsTcEvBinds (EvBinds bs) = dsEvBinds bs
+
+dsEvBinds :: Bag EvBind -> DsM [DsEvBind]
+dsEvBinds bs = return (map dsEvGroup sccs)
+ where
+ sccs :: [SCC EvBind]
+ sccs = stronglyConnCompFromEdgedVertices edges
+
+ edges :: [(EvBind, EvVar, [EvVar])]
+ edges = foldrBag ((:) . mk_node) [] bs
+
+ mk_node :: EvBind -> (EvBind, EvVar, [EvVar])
+ mk_node b@(EvBind var term) = (b, var, free_vars_of term)
+
+ free_vars_of :: EvTerm -> [EvVar]
+ free_vars_of (EvId v) = [v]
+ free_vars_of (EvCast v co) = v : varSetElems (tyVarsOfType co)
+ free_vars_of (EvCoercion co) = varSetElems (tyVarsOfType co)
+ free_vars_of (EvDFunApp _ _ vs) = vs
+ free_vars_of (EvSuperClass d _) = [d]
+
+dsEvGroup :: SCC EvBind -> DsEvBind
+dsEvGroup (AcyclicSCC (EvBind co_var (EvSuperClass dict n)))
+ | isCoVar co_var -- An equality superclass
+ = ASSERT( null other_data_cons )
+ CaseEvBind dict (DataAlt data_con) bndrs
+ where
+ (cls, tys) = getClassPredTys (evVarPred dict)
+ (data_con:other_data_cons) = tyConDataCons (classTyCon cls)
+ (ex_tvs, theta, rho) = tcSplitSigmaTy (applyTys (dataConRepType data_con) tys)
+ (arg_tys, _) = splitFunTys rho
+ bndrs = ex_tvs ++ map mk_wild_pred (theta `zip` [0..])
+ ++ map mkWildValBinder arg_tys
+ mk_wild_pred (p, i) | i==n = ASSERT( p `tcEqPred` (coVarPred co_var))
+ co_var
+ | otherwise = mkWildEvBinder p
+
+dsEvGroup (AcyclicSCC (EvBind v r))
+ = LetEvBind (NonRec v (dsEvTerm r))
+
+dsEvGroup (CyclicSCC bs)
+ = LetEvBind (Rec (map ds_pair bs))
+ where
+ ds_pair (EvBind v r) = (v, dsEvTerm r)
+
+dsEvTerm :: EvTerm -> CoreExpr
+dsEvTerm (EvId v) = Var v
+dsEvTerm (EvCast v co) = Cast (Var v) co
+dsEvTerm (EvDFunApp df tys vars) = Var df `mkTyApps` tys `mkVarApps` vars
+dsEvTerm (EvCoercion co) = Type co
+dsEvTerm (EvSuperClass d n)
+ = ASSERT( isClassPred (classSCTheta cls !! n) )
+ -- We can only select *dictionary* superclasses
+ -- in terms. Equality superclasses are dealt with
+ -- in dsEvGroup, where they can generate a case expression
+ Var sc_sel_id `mkTyApps` tys `App` Var d
+ where
+ sc_sel_id = classSCSelId cls n -- Zero-indexed
+ (cls, tys) = getClassPredTys (evVarPred d)
+