-%************************************************************************
-%* *
-\subsection{Typechecking a method}
-%* *
-%************************************************************************
-
-@tcMethodBind@ is used to type-check both default-method and
-instance-decl method declarations. We must type-check methods one at a
-time, because their signatures may have different contexts and
-tyvar sets.
-
-\begin{code}
-type MethodSpec = (Id, -- Global selector Id
- Id, -- Local Id (class tyvars instantiated)
- LHsBind Name) -- Binding for the method
-
-tcMethodBind
- :: InstOrigin
- -> [TcTyVar] -- Skolemised type variables for the
- -- enclosing class/instance decl.
- -- They'll be signature tyvars, and we
- -- want to check that they don't get bound
- -- Also they are scoped, so we bring them into scope
- -- Always equal the range of the type envt
- -> TcThetaType -- Available theta; it's just used for the error message
- -> Inst -- Current dictionary (this_dict)
- -> [Inst] -- Other stuff available from context, used to simplify
- -- constraints from the method body (exclude this_dict)
- -> TcSigFun -- For scoped tyvars, indexed by sel_name
- -> TcPragFun -- Pragmas (e.g. inline pragmas), indexed by sel_name
- -> LHsBinds Name -- Method binding (pick the right one from in here)
- -> ClassOpItem
- -> TcId -- The method Id
- -> TcM (LHsBinds Id)
-
-tcMethodBind origin inst_tyvars inst_theta
- this_dict extra_insts
- sig_fn prag_fn meth_binds
- (sel_id, dm_info) meth_id
- | Just user_bind <- find_bind sel_name meth_name meth_binds
- = -- If there is a user-supplied method binding, typecheck it
- tc_method_bind inst_tyvars inst_theta (this_dict:extra_insts)
- sig_fn prag_fn
- sel_id meth_id user_bind
-
- | otherwise -- The user didn't supply a method binding, so we have to make
- -- up a default binding, in a way depending on the default-method info
- = case dm_info of
- NoDefMeth -> do { warn <- doptM Opt_WarnMissingMethods
- ; warnTc (isInstDecl origin
- && warn -- Warn only if -fwarn-missing-methods
- && reportIfUnused (getOccName sel_id))
- -- Don't warn about _foo methods
- (omittedMethodWarn sel_id)
- ; return (unitBag $ L loc (VarBind meth_id error_rhs)) }
-
- DefMeth -> do { -- An polymorphic default method
- -- Might not be imported, but will be an OrigName
- dm_name <- lookupImportedName (mkDefMethRdrName sel_id)
- ; dm_id <- tcLookupId dm_name
- -- Note [Default methods in instances]
- ; return (unitBag $ L loc (VarBind meth_id (mk_dm_app dm_id))) }
-
- GenDefMeth -> ASSERT( isInstDecl origin ) -- We never get here from a class decl
- do { meth_bind <- mkGenericDefMethBind clas inst_tys sel_id meth_name
- ; tc_method_bind inst_tyvars inst_theta (this_dict:extra_insts)
- sig_fn prag_fn
- sel_id meth_id meth_bind }
-
- where
- meth_name = idName meth_id
- sel_name = idName sel_id
- loc = getSrcSpan meth_id
- (clas, inst_tys) = getDictClassTys this_dict
+---------------------------
+tcMethodBind :: [Name] -> [LSig Name] -> Id
+ -> LHsBind Name -> TcM (LHsBinds Id)
+tcMethodBind tyvars prags meth_id bind
+ = do { let sig_fn _ = Just tyvars
+ prag_fn _ = prags
+
+ -- Typecheck the binding, first extending the envt
+ -- so that when tcInstSig looks up the meth_id to find
+ -- its signature, we'll find it in the environment
+ --
+ -- If scoped type variables is on, they are brought
+ -- into scope by tcPolyBinds (via sig_fn)
+ --
+ -- See Note [Polymorphic methods]
+ ; traceTc (text "tcMethodBind" <+> ppr meth_id <+> ppr tyvars)
+ ; (tc_binds, ids) <- tcExtendIdEnv [meth_id] $
+ tcPolyBinds TopLevel sig_fn prag_fn
+ NonRecursive NonRecursive
+ (unitBag bind)
+
+ ; ASSERT( ids == [meth_id] ) -- Binding for ONE method
+ return (unionManyBags tc_binds) }
+\end{code}