- let -- These insts are in scope; quite a few, eh?
- dfun_insts = dfun_eqs ++ dfun_dicts
- wanted_sc_insts = wanted_sc_eqs ++ sc_dicts
- this_dict_id = instToId this_dict
- sc_dict_ids = map instToId sc_dicts
- dfun_dict_ids = map instToId dfun_dicts
- prag_fn = mkPragFun uprags
- tc_meth = tcInstanceMethod loc clas inst_tyvars'
- (dfun_covars ++ dfun_dict_ids)
- dfun_theta' inst_tys'
- this_dict_id
- monobinds prag_fn
- (meth_exprs, meth_binds) <- mapAndUnzipM tc_meth op_items
-
- -- Figure out bindings for the superclass context
- -- Don't include this_dict in the 'givens', else
- -- wanted_sc_insts get bound by just selecting from this_dict!!
- sc_binds <- addErrCtxt superClassCtxt
- (tcSimplifySuperClasses inst_loc dfun_insts wanted_sc_insts)
-
- -- It's possible that the superclass stuff might unified one
- -- of the inst_tyavars' with something in the envt
- checkSigTyVars inst_tyvars'
-
- -- Deal with 'SPECIALISE instance' pragmas
- prags <- tcPrags dfun_id (filter isSpecInstLSig uprags)
-
- -- Create the result bindings
- let
- dict_constr = classDataCon clas
- inline_prag | null dfun_insts = []
- | otherwise = [L loc (InlinePrag (Inline AlwaysActive True))]
- -- Always inline the dfun; this is an experimental decision
- -- because it makes a big performance difference sometimes.
- -- Often it means we can do the method selection, and then
- -- inline the method as well. Marcin's idea; see comments below.
- --
- -- BUT: don't inline it if it's a constant dictionary;
- -- we'll get all the benefit without inlining, and we get
- -- a **lot** of code duplication if we inline it
- --
- -- See Note [Inline dfuns] below
-
- dict_rhs = mkHsConApp dict_constr (inst_tys' ++ mkTyVarTys sc_covars)
- (map HsVar sc_dict_ids ++ meth_exprs)
- -- We don't produce a binding for the dict_constr; instead we
- -- rely on the simplifier to unfold this saturated application
- -- We do this rather than generate an HsCon directly, because
- -- it means that the special cases (e.g. dictionary with only one
- -- member) are dealt with by the common MkId.mkDataConWrapId code rather
- -- than needing to be repeated here.
-
- dict_bind = noLoc (VarBind this_dict_id dict_rhs)
-
- main_bind = noLoc $ AbsBinds
- (inst_tyvars' ++ dfun_covars)
- dfun_dict_ids
- [(inst_tyvars' ++ dfun_covars, dfun_id, this_dict_id, inline_prag ++ prags)]
- (dict_bind `consBag` sc_binds)
-
- showLIE (text "instance")
- return (main_bind `consBag` unionManyBags meth_binds)
-
-mkCoVars :: [PredType] -> TcM [TyVar]
-mkCoVars = newCoVars . map unEqPred
- where
- unEqPred (EqPred ty1 ty2) = (ty1, ty2)
- unEqPred _ = panic "TcInstDcls.mkCoVars"
+ ; let prag_fn = mkPragFun uprags
+ tc_meth = tcInstanceMethod loc standalone_deriv
+ clas inst_tyvars'
+ dfun_dicts inst_tys'
+ nested_this_pair
+ prag_fn spec_inst_prags monobinds
+
+ ; (meth_ids, meth_binds) <- tcExtendTyVarEnv inst_tyvars' $
+ mapAndUnzipM tc_meth op_items
+
+ -- Figure out bindings for the superclass context
+ ; sc_loc <- getInstLoc InstScOrigin
+ ; sc_dicts <- newDictOccs sc_loc sc_theta' -- These are wanted
+ ; let tc_sc = tcSuperClass inst_loc inst_tyvars' dfun_dicts nested_this_pair
+ ; (sc_ids, sc_binds) <- mapAndUnzipM tc_sc (sc_sels `zip` sc_dicts)
+
+ -- It's possible that the superclass stuff might unified
+ -- something in the envt with one of the inst_tyvars'
+ ; checkSigTyVars inst_tyvars'
+
+ -- Create the result bindings
+ ; let dict_constr = classDataCon clas
+ this_dict_id = instToId this_dict
+ dict_bind = mkVarBind this_dict_id dict_rhs
+ dict_rhs = foldl mk_app inst_constr (sc_ids ++ meth_ids)
+ inst_constr = L loc $ wrapId (mkWpTyApps inst_tys')
+ (dataConWrapId dict_constr)
+ -- We don't produce a binding for the dict_constr; instead we
+ -- rely on the simplifier to unfold this saturated application
+ -- We do this rather than generate an HsCon directly, because
+ -- it means that the special cases (e.g. dictionary with only one
+ -- member) are dealt with by the common MkId.mkDataConWrapId code rather
+ -- than needing to be repeated here.
+
+ mk_app :: LHsExpr Id -> Id -> LHsExpr Id
+ mk_app fun arg_id = L loc (HsApp fun (L loc (wrapId arg_wrapper arg_id)))
+ arg_wrapper = mkWpApps dfun_lam_vars <.> mkWpTyApps (mkTyVarTys inst_tyvars')
+
+ dfun_id_w_fun = dfun_id
+ `setIdUnfolding` mkDFunUnfolding dict_constr (sc_ids ++ meth_ids)
+ `setInlinePragma` dfunInlinePragma
+
+ main_bind = noLoc $ AbsBinds
+ inst_tyvars'
+ dfun_lam_vars
+ [(inst_tyvars', dfun_id_w_fun, this_dict_id, spec_inst_prags)]
+ (unitBag dict_bind)
+
+ ; showLIE (text "instance")
+ ; return (unitBag main_bind `unionBags`
+ listToBag meth_binds `unionBags`
+ listToBag sc_binds) }
+
+
+------------------------------
+tcSuperClass :: InstLoc -> [TyVar] -> [Inst]
+ -> (Inst, LHsBinds Id)
+ -> (Id, Inst) -> TcM (Id, LHsBind Id)
+-- Build a top level decl like
+-- sc_op = /\a \d. let this = ... in
+-- let sc = ... in
+-- sc
+-- The "this" part is just-in-case (discarded if not used)
+-- See Note [Recursive superclasses]
+tcSuperClass inst_loc tyvars dicts (this_dict, this_bind)
+ (sc_sel, sc_dict)
+ = addErrCtxt superClassCtxt $
+ do { sc_binds <- tcSimplifySuperClasses inst_loc
+ this_dict dicts [sc_dict]
+ -- Don't include this_dict in the 'givens', else
+ -- sc_dicts get bound by just selecting from this_dict!!
+
+ ; uniq <- newUnique
+ ; let sc_op_ty = mkSigmaTy tyvars (map dictPred dicts)
+ (mkPredTy (dictPred sc_dict))
+ sc_op_name = mkDerivedInternalName mkClassOpAuxOcc uniq
+ (getName sc_sel)
+ sc_op_id = mkLocalId sc_op_name sc_op_ty
+ sc_id = instToVar sc_dict
+ sc_op_bind = AbsBinds tyvars
+ (map instToVar dicts)
+ [(tyvars, sc_op_id, sc_id, [])]
+ (this_bind `unionBags` sc_binds)
+
+ ; return (sc_op_id, noLoc sc_op_bind) }
+\end{code}
+
+Note [Recursive superclasses]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+See Trac #1470 for why we would *like* to add "this_dict" to the
+available instances here. But we can't do so because then the superclases
+get satisfied by selection from this_dict, and that leads to an immediate
+loop. What we need is to add this_dict to Avails without adding its
+superclasses, and we currently have no way to do that.
+
+Note [SPECIALISE instance pragmas]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider
+
+ instance (Ix a, Ix b) => Ix (a,b) where
+ {-# SPECIALISE instance Ix (Int,Int) #-}
+ range (x,y) = ...
+
+We do *not* want to make a specialised version of the dictionary
+function. Rather, we want specialised versions of each method.
+Thus we should generate something like this: