- do_one inst_loc (sel_id, _)
- = -- The binding is like "op @ NewTy = op @ RepTy"
- -- Make the *binder*, like in mkMethodBind
- tcInstClassOp inst_loc sel_id inst_tys' `thenM` \ meth_inst ->
-
- -- Make the *occurrence on the rhs*
- tcInstClassOp inst_loc sel_id rep_tys' `thenM` \ rhs_inst ->
- let
- meth_id = instToId meth_inst
- in
- return (meth_id, noLoc (VarBind meth_id (nlHsVar (instToId rhs_inst))), rhs_inst)
-
- -- Instantiate rep_tys with the relevant type variables
- -- This looks a bit odd, because inst_tyvars' are the skolemised version
- -- of the type variables in the instance declaration; but rep_tys doesn't
- -- have the skolemised version, so we substitute them in here
- rep_tys' = substTys subst rep_tys
- subst = zipOpenTvSubst inst_tyvars' (mkTyVarTys inst_tyvars')
-
-
-
-tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = VanillaInst monobinds uprags })
- = let
- dfun_id = instanceDFunId ispec
- rigid_info = InstSkol dfun_id
- inst_ty = idType dfun_id
- in
- -- Prime error recovery
- recoverM (returnM emptyLHsBinds) $
- setSrcSpan (srcLocSpan (getSrcLoc dfun_id)) $
- addErrCtxt (instDeclCtxt2 (idType dfun_id)) $
-
- -- Instantiate the instance decl with skolem constants
- tcSkolSigType rigid_info inst_ty `thenM` \ (inst_tyvars', dfun_theta', inst_head') ->
- -- These inst_tyvars' scope over the 'where' part
- -- Those tyvars are inside the dfun_id's type, which is a bit
- -- bizarre, but OK so long as you realise it!
- let
- (clas, inst_tys') = tcSplitDFunHead inst_head'
- (class_tyvars, sc_theta, _, op_items) = classBigSig clas
-
- -- Instantiate the super-class context with inst_tys
- sc_theta' = substTheta (zipOpenTvSubst class_tyvars inst_tys') sc_theta
- origin = SigOrigin rigid_info
- in
- -- Create dictionary Ids from the specified instance contexts.
- newDicts InstScOrigin sc_theta' `thenM` \ sc_dicts ->
- newDicts origin dfun_theta' `thenM` \ dfun_arg_dicts ->
- newDicts origin [mkClassPred clas inst_tys'] `thenM` \ [this_dict] ->
- -- Default-method Ids may be mentioned in synthesised RHSs,
- -- but they'll already be in the environment.
-
- -- Typecheck the methods
- let -- These insts are in scope; quite a few, eh?
- avail_insts = [this_dict] ++ dfun_arg_dicts ++ sc_dicts
- in
- tcMethods origin clas inst_tyvars'
- dfun_theta' inst_tys' avail_insts
- op_items monobinds uprags `thenM` \ (meth_ids, meth_binds) ->
-
- -- Figure out bindings for the superclass context
- -- Don't include this_dict in the 'givens', else
- -- sc_dicts get bound by just selecting from this_dict!!
- addErrCtxt superClassCtxt
- (tcSimplifySuperClasses inst_tyvars'
- dfun_arg_dicts
- sc_dicts) `thenM` \ sc_binds ->
-
- -- It's possible that the superclass stuff might unified one
- -- of the inst_tyavars' with something in the envt
- checkSigTyVars inst_tyvars' `thenM_`
-
- -- Deal with 'SPECIALISE instance' pragmas
- tcPrags dfun_id (filter isSpecInstLSig prags) `thenM` \ prags ->
-
- -- Create the result bindings
- let
- dict_constr = classDataCon clas
- scs_and_meths = map instToId sc_dicts ++ meth_ids
- this_dict_id = instToId this_dict
- inline_prag | null dfun_arg_dicts = []
- | otherwise = [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' (map HsVar scs_and_meths)
- -- 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)
- all_binds = dict_bind `consBag` (sc_binds `unionBags` meth_binds)
-
- main_bind = noLoc $ AbsBinds
- inst_tyvars'
- (map instToId dfun_arg_dicts)
- [(inst_tyvars', dfun_id, this_dict_id,
- inline_prag ++ prags)]
- all_binds
- in
- showLIE (text "instance") `thenM_`
- returnM (unitBag main_bind)
-
-
-tcMethods origin clas inst_tyvars' dfun_theta' inst_tys'
- avail_insts op_items monobinds uprags
- = -- Check that all the method bindings come from this class
- let
- sel_names = [idName sel_id | (sel_id, _) <- op_items]
- bad_bndrs = collectHsBindBinders monobinds `minusList` sel_names
- in
- mappM (addErrTc . badMethodErr clas) bad_bndrs `thenM_`
-
- -- Make the method bindings
- let
- mk_method_bind = mkMethodBind origin clas inst_tys' monobinds
- in
- mapAndUnzipM mk_method_bind op_items `thenM` \ (meth_insts, meth_infos) ->
-
- -- And type check them
- -- It's really worth making meth_insts available to the tcMethodBind
- -- Consider instance Monad (ST s) where
- -- {-# INLINE (>>) #-}
- -- (>>) = ...(>>=)...
- -- If we don't include meth_insts, we end up with bindings like this:
- -- rec { dict = MkD then bind ...
- -- then = inline_me (... (GHC.Base.>>= dict) ...)
- -- bind = ... }
- -- The trouble is that (a) 'then' and 'dict' are mutually recursive,
- -- and (b) the inline_me prevents us inlining the >>= selector, which
- -- would unravel the loop. Result: (>>) ends up as a loop breaker, and
- -- is not inlined across modules. Rather ironic since this does not
- -- happen without the INLINE pragma!
- --
- -- Solution: make meth_insts available, so that 'then' refers directly
- -- to the local 'bind' rather than going via the dictionary.
- --
- -- BUT WATCH OUT! If the method type mentions the class variable, then
- -- this optimisation is not right. Consider
- -- class C a where
- -- op :: Eq a => a
- --
- -- instance C Int where
- -- op = op
- -- The occurrence of 'op' on the rhs gives rise to a constraint
- -- op at Int
- -- The trouble is that the 'meth_inst' for op, which is 'available', also
- -- looks like 'op at Int'. But they are not the same.
- let
- prag_fn = mkPragFun uprags
- all_insts = avail_insts ++ catMaybes meth_insts
- sig_fn n = Just [] -- No scoped type variables, but every method has
- -- a type signature, in effect, so that we check
- -- the method has the right type
- tc_method_bind = tcMethodBind inst_tyvars' dfun_theta' all_insts sig_fn prag_fn
- meth_ids = [meth_id | (_,meth_id,_) <- meth_infos]
- in
-
- mapM tc_method_bind meth_infos `thenM` \ meth_binds_s ->
-
- returnM (meth_ids, unionManyBags meth_binds_s)
+ spec_ctxt prag = hang (ptext (sLit "In the SPECIALISE pragma")) 2 (ppr prag)
+
+tcSpecInst _ _ = panic "tcSpecInst"
+\end{code}
+
+%************************************************************************
+%* *
+ Type-checking an instance method
+%* *
+%************************************************************************
+
+tcInstanceMethod
+- Make the method bindings, as a [(NonRec, HsBinds)], one per method
+- Remembering to use fresh Name (the instance method Name) as the binder
+- Bring the instance method Ids into scope, for the benefit of tcInstSig
+- Use sig_fn mapping instance method Name -> instance tyvars
+- Ditto prag_fn
+- Use tcValBinds to do the checking
+
+\begin{code}
+tcInstanceMethods :: DFunId -> Class -> [TcTyVar]
+ -> [EvVar]
+ -> [TcType]
+ -> EvBind -- "This" and its binding
+ -> ([Located TcSpecPrag], PragFun)
+ -> [(Id, DefMeth)]
+ -> InstBindings Name
+ -> TcM ([Id], [LHsBind Id])
+ -- The returned inst_meth_ids all have types starting
+ -- forall tvs. theta => ...
+tcInstanceMethods dfun_id clas tyvars dfun_ev_vars inst_tys
+ self_dict_ev (spec_inst_prags, prag_fn)
+ op_items (VanillaInst binds _ standalone_deriv)
+ = mapAndUnzipM tc_item op_items
+ where
+ ----------------------
+ tc_item :: (Id, DefMeth) -> TcM (Id, LHsBind Id)
+ tc_item (sel_id, dm_info)
+ = case findMethodBind (idName sel_id) binds of
+ Just user_bind -> tc_body sel_id standalone_deriv user_bind
+ Nothing -> tc_default sel_id dm_info
+
+ ----------------------
+ tc_body :: Id -> Bool -> LHsBind Name -> TcM (TcId, LHsBind Id)
+ tc_body sel_id generated_code rn_bind
+ = add_meth_ctxt generated_code rn_bind $
+ do { (meth_id, local_meth_id) <- mkMethIds clas tyvars dfun_ev_vars
+ inst_tys sel_id
+ ; (meth_id1, spec_prags) <- tcPrags NonRecursive False True
+ meth_id (prag_fn (idName sel_id))
+
+ ; bind <- tcInstanceMethodBody InstSkol
+ tyvars dfun_ev_vars
+ mb_dict_ev
+ meth_id1 local_meth_id
+ meth_sig_fn
+ (SpecPrags (spec_inst_prags ++ spec_prags))
+ rn_bind
+ ; return (meth_id1, bind) }
+
+ ----------------------
+ tc_default :: Id -> DefMeth -> TcM (TcId, LHsBind Id)
+ tc_default sel_id GenDefMeth -- Derivable type classes stuff
+ = do { meth_bind <- mkGenericDefMethBind clas inst_tys sel_id
+ ; tc_body sel_id False {- Not generated code? -} meth_bind }
+
+ tc_default sel_id NoDefMeth -- No default method at all
+ = do { warnMissingMethod sel_id
+ ; (meth_id, _) <- mkMethIds clas tyvars dfun_ev_vars
+ inst_tys sel_id
+ ; return (meth_id, mkVarBind meth_id $
+ mkLHsWrap lam_wrapper error_rhs) }
+ where
+ error_rhs = L loc $ HsApp error_fun error_msg
+ error_fun = L loc $ wrapId (WpTyApp meth_tau) nO_METHOD_BINDING_ERROR_ID
+ error_msg = L loc (HsLit (HsStringPrim (mkFastString error_string)))
+ meth_tau = funResultTy (applyTys (idType sel_id) inst_tys)
+ error_string = showSDoc (hcat [ppr loc, text "|", ppr sel_id ])
+ lam_wrapper = mkWpTyLams tyvars <.> mkWpLams dfun_ev_vars
+
+ tc_default sel_id (DefMeth dm_name) -- A polymorphic default method
+ = do { -- Build the typechecked version directly,
+ -- without calling typecheck_method;
+ -- see Note [Default methods in instances]
+ -- Generate /\as.\ds. let this = df as ds
+ -- in $dm inst_tys this
+ -- The 'let' is necessary only because HsSyn doesn't allow
+ -- you to apply a function to a dictionary *expression*.
+
+ ; (meth_id, local_meth_id) <- mkMethIds clas tyvars dfun_ev_vars
+ inst_tys sel_id
+ ; dm_id <- tcLookupId dm_name
+ ; let dm_inline_prag = idInlinePragma dm_id
+ EvBind self_dict _ = self_dict_ev
+ rhs = HsWrap (mkWpEvVarApps [self_dict] <.> mkWpTyApps inst_tys) $
+ HsVar dm_id
+
+ meth_bind = L loc $ VarBind { var_id = local_meth_id
+ , var_rhs = L loc rhs
+ , var_inline = False }
+ meth_id1 = meth_id `setInlinePragma` dm_inline_prag
+ -- Copy the inline pragma (if any) from the default
+ -- method to this version. Note [INLINE and default methods]
+
+ bind = AbsBinds { abs_tvs = tyvars, abs_ev_vars = dfun_ev_vars
+ , abs_exports = [( tyvars, meth_id1, local_meth_id
+ , SpecPrags spec_inst_prags)]
+ , abs_ev_binds = EvBinds (unitBag self_dict_ev)
+ , abs_binds = unitBag meth_bind }
+ -- Default methods in an instance declaration can't have their own
+ -- INLINE or SPECIALISE pragmas. It'd be possible to allow them, but
+ -- currently they are rejected with
+ -- "INLINE pragma lacks an accompanying binding"
+
+ ; return (meth_id1, L loc bind) }
+
+ ----------------------
+ loc = getSrcSpan dfun_id
+ meth_sig_fn _ = Just ([],loc) -- The 'Just' says "yes, there's a type sig"
+ -- But there are no scoped type variables from local_method_id
+ -- Only the ones from the instance decl itself, which are already
+ -- in scope. Example:
+ -- class C a where { op :: forall b. Eq b => ... }
+ -- instance C [c] where { op = <rhs> }
+ -- In <rhs>, 'c' is scope but 'b' is not!
+
+ mb_dict_ev = if null tyvars then Nothing else Just self_dict_ev
+ -- Only need the self_dict stuff if there are type
+ -- variables involved; otherwise overlap is not possible
+ -- See Note [Subtle interaction of recursion and overlap]
+ -- in TcInstDcls
+
+ -- For instance decls that come from standalone deriving clauses
+ -- we want to print out the full source code if there's an error
+ -- because otherwise the user won't see the code at all
+ add_meth_ctxt generated_code rn_bind thing
+ | generated_code = addLandmarkErrCtxt (derivBindCtxt clas inst_tys rn_bind) thing
+ | otherwise = thing
+
+
+tcInstanceMethods dfun_id clas tyvars dfun_ev_vars inst_tys
+ _ _ op_items (NewTypeDerived coi _)
+
+-- Running example:
+-- class Show b => Foo a b where
+-- op :: a -> b -> b
+-- newtype N a = MkN (Tree [a])
+-- deriving instance (Show p, Foo Int p) => Foo Int (N p)
+-- -- NB: standalone deriving clause means
+-- -- that the contex is user-specified
+-- Hence op :: forall a b. Foo a b => a -> b -> b
+--
+-- We're going to make an instance like
+-- instance (Show p, Foo Int p) => Foo Int (N p)
+-- op = $copT
+--
+-- $copT :: forall p. (Show p, Foo Int p) => Int -> N p -> N p
+-- $copT p (d1:Show p) (d2:Foo Int p)
+-- = op Int (Tree [p]) rep_d |> op_co
+-- where
+-- rep_d :: Foo Int (Tree [p]) = ...d1...d2...
+-- op_co :: (Int -> Tree [p] -> Tree [p]) ~ (Int -> T p -> T p)
+-- We get op_co by substituting [Int/a] and [co/b] in type for op
+-- where co : [p] ~ T p
+--
+-- Notice that the dictionary bindings "..d1..d2.." must be generated
+-- by the constraint solver, since the <context> may be
+-- user-specified.
+
+ = do { rep_d_stuff <- checkConstraints InstSkol emptyVarSet tyvars dfun_ev_vars $
+ emitWanted ScOrigin rep_pred
+
+ ; mapAndUnzipM (tc_item rep_d_stuff) op_items }
+ where
+ loc = getSrcSpan dfun_id
+
+ inst_tvs = fst (tcSplitForAllTys (idType dfun_id))
+ Just (init_inst_tys, _) = snocView inst_tys
+ rep_ty = fst (coercionKind co) -- [p]
+ rep_pred = mkClassPred clas (init_inst_tys ++ [rep_ty])
+
+ -- co : [p] ~ T p
+ co = substTyWith inst_tvs (mkTyVarTys tyvars) $
+ case coi of { IdCo ty -> ty ;
+ ACo co -> mkSymCoercion co }
+
+ ----------------
+ tc_item :: (TcEvBinds, EvVar) -> (Id, DefMeth) -> TcM (TcId, LHsBind TcId)
+ tc_item (rep_ev_binds, rep_d) (sel_id, _)
+ = do { (meth_id, local_meth_id) <- mkMethIds clas tyvars dfun_ev_vars
+ inst_tys sel_id
+
+ ; let meth_rhs = wrapId (mk_op_wrapper sel_id rep_d) sel_id
+ meth_bind = VarBind { var_id = local_meth_id
+ , var_rhs = L loc meth_rhs
+ , var_inline = False }
+
+ bind = AbsBinds { abs_tvs = tyvars, abs_ev_vars = dfun_ev_vars
+ , abs_exports = [(tyvars, meth_id,
+ local_meth_id, noSpecPrags)]
+ , abs_ev_binds = rep_ev_binds
+ , abs_binds = unitBag $ L loc meth_bind }
+
+ ; return (meth_id, L loc bind) }
+
+ ----------------
+ mk_op_wrapper :: Id -> EvVar -> HsWrapper
+ mk_op_wrapper sel_id rep_d
+ = WpCast (substTyWith sel_tvs (init_inst_tys ++ [co]) local_meth_ty)
+ <.> WpEvApp (EvId rep_d)
+ <.> mkWpTyApps (init_inst_tys ++ [rep_ty])
+ where
+ (sel_tvs, sel_rho) = tcSplitForAllTys (idType sel_id)
+ (_, local_meth_ty) = tcSplitPredFunTy_maybe sel_rho
+ `orElse` pprPanic "tcInstanceMethods" (ppr sel_id)
+
+----------------------
+mkMethIds :: Class -> [TcTyVar] -> [EvVar] -> [TcType] -> Id -> TcM (TcId, TcId)
+mkMethIds clas tyvars dfun_ev_vars inst_tys sel_id
+ = do { uniq <- newUnique
+ ; let meth_name = mkDerivedInternalName mkClassOpAuxOcc uniq sel_name
+ ; local_meth_name <- newLocalName sel_name
+ -- Base the local_meth_name on the selector name, becuase
+ -- type errors from tcInstanceMethodBody come from here
+
+ ; let meth_id = mkLocalId meth_name meth_ty
+ local_meth_id = mkLocalId local_meth_name local_meth_ty
+ ; return (meth_id, local_meth_id) }
+ where
+ local_meth_ty = instantiateMethod clas sel_id inst_tys
+ meth_ty = mkForAllTys tyvars $ mkPiTypes dfun_ev_vars local_meth_ty
+ sel_name = idName sel_id
+
+----------------------
+wrapId :: HsWrapper -> id -> HsExpr id
+wrapId wrapper id = mkHsWrap wrapper (HsVar id)
+
+derivBindCtxt :: Class -> [Type ] -> LHsBind Name -> SDoc
+derivBindCtxt clas tys bind
+ = vcat [ ptext (sLit "When typechecking a standalone-derived method for")
+ <+> quotes (pprClassPred clas tys) <> colon
+ , nest 2 $ pprSetDepth AllTheWay $ ppr bind ]
+
+warnMissingMethod :: Id -> TcM ()
+warnMissingMethod sel_id
+ = do { warn <- doptM Opt_WarnMissingMethods
+ ; warnTc (warn -- Warn only if -fwarn-missing-methods
+ && not (startsWithUnderscore (getOccName sel_id)))
+ -- Don't warn about _foo methods
+ (ptext (sLit "No explicit method nor default method for")
+ <+> quotes (ppr sel_id)) }