- -- enclosing class/instance decl.
- -- They'll be signature tyvars, and we
- -- want to check that they don't get bound
- -> [TcType] -- Instance types
- -> TcThetaType -- Available theta; this could be used to check
- -- the method signature, but actually that's done by
- -- the caller; here, it's just used for the error message
- -> RenamedMonoBinds -- Method binding (pick the right one from in here)
- -> [RenamedSig] -- Pramgas (just for this one)
- -> Bool -- True <=> This method is from an instance declaration
- -> ClassOpItem -- The method selector and default-method Id
- -> TcM (TcMonoBinds, LIE, Inst)
-
-tcMethodBind clas origin inst_tyvars inst_tys inst_theta
- meth_binds prags is_inst_decl (sel_id, dm_info)
- = tcGetSrcLoc `thenNF_Tc` \ loc ->
- newMethod origin sel_id inst_tys `thenNF_Tc` \ meth ->
+ -- enclosing class/instance decl.
+ -- They'll be signature tyvars, and we
+ -- want to check that they don't get bound
+ -- Always equal the range of the type envt
+ -> TcThetaType -- Available theta; it's just used for the error message
+ -> [Inst] -- Available from context, used to simplify constraints
+ -- from the method body
+ -> [RenamedSig] -- Pragmas (e.g. inline pragmas)
+ -> MethodSpec -- Details of this method
+ -> TcM TcMonoBinds
+
+tcMethodBind xtve inst_tyvars inst_theta avail_insts prags
+ (sel_id, meth_id, meth_bind)
+ = -- Check the bindings; first adding inst_tyvars to the envt
+ -- so that we don't quantify over them in nested places
+ mkTcSig meth_id `thenM` \ meth_sig ->
+
+ tcExtendTyVarEnv2 xtve (
+ addErrCtxt (methodCtxt sel_id) $
+ getLIE $
+ tcMonoBinds meth_bind [meth_sig] NonRecursive
+ ) `thenM` \ ((meth_bind,_), meth_lie) ->
+
+ -- Now do context reduction. We simplify wrt both the local tyvars
+ -- and the ones of the class/instance decl, so that there is
+ -- no problem with
+ -- class C a where
+ -- op :: Eq a => a -> b -> a
+ --
+ -- We do this for each method independently to localise error messages
+
+ let
+ TySigInfo meth_id meth_tvs meth_theta _ local_meth_id _ _ = meth_sig
+ in
+ addErrCtxtM (sigCtxt sel_id inst_tyvars inst_theta (idType meth_id)) $
+ newDicts SignatureOrigin meth_theta `thenM` \ meth_dicts ->
+ let
+ all_tyvars = meth_tvs ++ inst_tyvars
+ all_insts = avail_insts ++ meth_dicts
+ in
+ tcSimplifyCheck
+ (ptext SLIT("class or instance method") <+> quotes (ppr sel_id))
+ all_tyvars all_insts meth_lie `thenM` \ lie_binds ->
+
+ checkSigTyVars all_tyvars `thenM` \ all_tyvars' ->
+
+ let
+ sel_name = idName sel_id
+ inline_prags = [ (is_inl, phase)
+ | InlineSig is_inl name phase _ <- prags,
+ name == sel_name ]
+ spec_prags = [ prag
+ | prag@(SpecSig name _ _) <- prags,
+ name == sel_name]
+
+ -- Attach inline pragmas as appropriate
+ (final_meth_id, inlines)
+ | ((is_inline, phase) : _) <- inline_prags
+ = (meth_id `setInlinePragma` phase,
+ if is_inline then unitNameSet (idName meth_id) else emptyNameSet)
+ | otherwise
+ = (meth_id, emptyNameSet)
+
+ meth_tvs' = take (length meth_tvs) all_tyvars'
+ poly_meth_bind = AbsBinds meth_tvs'
+ (map instToId meth_dicts)
+ [(meth_tvs', final_meth_id, local_meth_id)]
+ inlines
+ (lie_binds `andMonoBinds` meth_bind)
+
+ in
+ -- Deal with specialisation pragmas
+ -- The sel_name is what appears in the pragma
+ tcExtendLocalValEnv2 [(sel_name, final_meth_id)] (
+ getLIE (tcSpecSigs spec_prags) `thenM` \ (spec_binds1, prag_lie) ->
+
+ -- The prag_lie for a SPECIALISE pragma will mention the function itself,
+ -- so we have to simplify them away right now lest they float outwards!
+ bindInstsOfLocalFuns prag_lie [final_meth_id] `thenM` \ spec_binds2 ->
+ returnM (spec_binds1 `andMonoBinds` spec_binds2)
+ ) `thenM` \ spec_binds ->
+
+ returnM (poly_meth_bind `andMonoBinds` spec_binds)
+
+
+mkMethodBind :: InstOrigin
+ -> Class -> [TcType] -- Class and instance types
+ -> RenamedMonoBinds -- Method binding (pick the right one from in here)
+ -> ClassOpItem
+ -> TcM (Maybe Inst, -- Method inst
+ MethodSpec)
+-- Find the binding for the specified method, or make
+-- up a suitable default method if it isn't there
+
+mkMethodBind origin clas inst_tys meth_binds (sel_id, dm_info)
+ = mkMethId origin clas sel_id inst_tys `thenM` \ (mb_inst, meth_id) ->