- -- The *caller* put the class/inst decl tyvars into the envt
- tcExtendGlobalTyVars (mkVarSet inst_tyvars) (
- tcAddErrCtxt (methodCtxt sel_id) $
- tcBindWithSigs NotTopLevel meth_bind [sig_info]
- NonRecursive prag_info_fn
- ) `thenTc` \ (binds, insts, _) ->
-
-
- -- 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 [meth_id] `thenTc` \ (prag_lie', prag_binds2) ->
-
-
- -- Now check that the instance type variables
- -- (or, in the case of a class decl, the class tyvars)
- -- have not been unified with anything in the environment
- tcAddErrCtxtM (sigCtxt sig_msg (mkSigmaTy inst_tyvars inst_theta (idType meth_id))) $
- checkSigTyVars inst_tyvars `thenTc_`
-
- returnTc (binds `AndMonoBinds` prag_binds1 `AndMonoBinds` prag_binds2,
- insts `plusLIE` prag_lie',
- meth)
- where
- sig_msg ty = sep [ptext SLIT("When checking the expected type for"),
- nest 4 (ppr sel_name <+> dcolon <+> ppr ty)]
-
- sel_name = idName sel_id
-
- -- The renamer just puts the selector ID as the binder in the method binding
- -- but we must use the method name; so we substitute it here. Crude but simple.
- find_bind meth_name (FunMonoBind op_name fix matches loc)
- | op_name == sel_name = Just (FunMonoBind meth_name fix matches loc)
- find_bind meth_name (PatMonoBind (VarPatIn op_name) grhss loc)
- | op_name == sel_name = Just (PatMonoBind (VarPatIn meth_name) grhss loc)
- find_bind meth_name (AndMonoBinds b1 b2)
- = find_bind meth_name b1 `seqMaybe` find_bind meth_name b2
- find_bind meth_name other = Nothing -- Default case
-
-
- -- Find the prags for this method, and replace the
- -- selector name with the method name
- find_prags meth_name [] = []
- find_prags meth_name (SpecSig name ty spec loc : prags)
- | name == sel_name = SpecSig meth_name ty spec loc : find_prags meth_name prags
- find_prags meth_name (InlineSig name loc : prags)
- | name == sel_name = InlineSig meth_name loc : find_prags meth_name prags
- find_prags meth_name (NoInlineSig name loc : prags)
- | name == sel_name = NoInlineSig meth_name loc : find_prags meth_name prags
- find_prags meth_name (prag:prags) = find_prags meth_name prags
-
- mk_default_bind local_meth_name loc
- = PatMonoBind (VarPatIn local_meth_name)
- (GRHSs (unguardedRHS (default_expr loc) loc) EmptyBinds Nothing)
- loc
-
- default_expr loc
- = case maybe_dm_id of
- Just dm_id -> HsVar (getName dm_id) -- There's a default method
- Nothing -> error_expr loc -- No default method
-
- error_expr loc = HsApp (HsVar (getName nO_METHOD_BINDING_ERROR_ID))
- (HsLit (HsString (_PK_ (error_msg loc))))
-
- error_msg loc = showSDoc (hcat [ppr loc, text "|", ppr sel_id ])
+ 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
+ -- Attach inline pragmas as appropriate
+ (final_meth_id, inlines)
+ | (InlineSig inl _ phase _ : _) <- filter is_inline prags
+ = (meth_id `setInlinePragma` phase,
+ if inl then unitNameSet (idName meth_id) else emptyNameSet)
+ | otherwise
+ = (meth_id, emptyNameSet)
+
+ is_inline (InlineSig _ name _ _) = name == idName sel_id
+ is_inline other = False
+
+ 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
+ returnM poly_meth_bind
+
+
+mkMethodBind :: InstOrigin
+ -> Class -> [TcType] -- Class and instance types
+ -> RenamedMonoBinds -- Method binding (pick the right one from in here)
+ -> ClassOpItem
+ -> TcM (Inst, -- Method inst
+ (Id, -- Global selector Id
+ TcSigInfo, -- Signature
+ RenamedMonoBinds)) -- Binding for the method
+
+mkMethodBind origin clas inst_tys meth_binds (sel_id, dm_info)
+ = getInstLoc origin `thenM` \ inst_loc ->
+ newMethodAtLoc inst_loc sel_id inst_tys `thenM` \ meth_inst ->
+ -- Do not dump anything into the LIE
+ let
+ meth_id = instToId meth_inst
+ meth_name = idName meth_id
+ in
+ -- Figure out what method binding to use
+ -- If the user suppplied one, use it, else construct a default one
+ getSrcLocM `thenM` \ loc ->
+ (case find_bind (idName sel_id) meth_name meth_binds of
+ Just user_bind -> returnM user_bind
+ Nothing -> mkDefMethRhs origin clas inst_tys sel_id loc dm_info `thenM` \ rhs ->
+ returnM (FunMonoBind meth_name False -- Not infix decl
+ [mkSimpleMatch [] rhs placeHolderType loc] loc)
+ ) `thenM` \ meth_bind ->
+
+ mkTcSig meth_id loc `thenM` \ meth_sig ->
+
+ returnM (meth_inst, (sel_id, meth_sig, meth_bind))
+
+
+ -- The user didn't supply a method binding,
+ -- so we have to make up a default binding
+ -- The RHS of a default method depends on the default-method info
+mkDefMethRhs origin clas inst_tys sel_id loc (DefMeth dm_name)
+ = -- An polymorphic default method
+ traceRn (text "mkDefMeth" <+> ppr dm_name) `thenM_`
+ returnM (HsVar dm_name)
+
+mkDefMethRhs origin clas inst_tys sel_id loc NoDefMeth
+ = -- No default method
+ -- Warn only if -fwarn-missing-methods
+ doptM Opt_WarnMissingMethods `thenM` \ warn ->
+ warnTc (isInstDecl origin && warn)
+ (omittedMethodWarn sel_id) `thenM_`
+ returnM error_rhs
+ where
+ error_rhs = HsLam (mkSimpleMatch wild_pats simple_rhs placeHolderType loc)
+ simple_rhs = HsApp (HsVar (getName nO_METHOD_BINDING_ERROR_ID))
+ (HsLit (HsStringPrim (mkFastString (stringToUtf8 error_msg))))
+ error_msg = showSDoc (hcat [ppr loc, text "|", ppr sel_id ])
+
+ -- When the type is of form t1 -> t2 -> t3
+ -- make a default method like (\ _ _ -> noMethBind "blah")
+ -- rather than simply (noMethBind "blah")
+ -- Reason: if t1 or t2 are higher-ranked types we get n
+ -- silly ambiguity messages.
+ -- Example: f :: (forall a. Eq a => a -> a) -> Int
+ -- f = error "urk"
+ -- Here, tcSub tries to force (error "urk") to have the right type,
+ -- thus: f = \(x::forall a. Eq a => a->a) -> error "urk" (x t)
+ -- where 't' is fresh ty var. This leads directly to "ambiguous t".
+ --
+ -- NB: technically this changes the meaning of the default-default
+ -- method slightly, because `seq` can see the lambdas. Oh well.
+ (_,_,tau1) = tcSplitSigmaTy (idType sel_id)
+ (_,_,tau2) = tcSplitSigmaTy tau1
+ -- Need two splits because the selector can have a type like
+ -- forall a. Foo a => forall b. Eq b => ...
+ (arg_tys, _) = tcSplitFunTys tau2
+ wild_pats = [WildPat placeHolderType | ty <- arg_tys]
+
+mkDefMethRhs origin clas inst_tys sel_id loc GenDefMeth
+ = -- A generic default method
+ -- If the method is defined generically, we can only do the job if the
+ -- instance declaration is for a single-parameter type class with
+ -- a type constructor applied to type arguments in the instance decl
+ -- (checkTc, so False provokes the error)
+ ASSERT( isInstDecl origin ) -- We never get here from a class decl
+
+ checkTc (isJust maybe_tycon)
+ (badGenericInstance sel_id (notSimple inst_tys)) `thenM_`
+ checkTc (isJust (tyConGenInfo tycon))
+ (badGenericInstance sel_id (notGeneric tycon)) `thenM_`
+
+ ioToTcRn (dumpIfSet opt_PprStyle_Debug "Generic RHS" stuff) `thenM_`
+ returnM rhs
+ where
+ rhs = mkGenericRhs sel_id clas_tyvar tycon
+
+ stuff = vcat [ppr clas <+> ppr inst_tys,
+ nest 4 (ppr sel_id <+> equals <+> ppr rhs)]
+
+ -- The tycon is only used in the generic case, and in that
+ -- case we require that the instance decl is for a single-parameter
+ -- type class with type variable arguments:
+ -- instance (...) => C (T a b)
+ clas_tyvar = head (classTyVars clas)
+ Just tycon = maybe_tycon
+ maybe_tycon = case inst_tys of
+ [ty] -> case tcSplitTyConApp_maybe ty of
+ Just (tycon, arg_tys) | all tcIsTyVarTy arg_tys -> Just tycon
+ other -> Nothing
+ other -> Nothing
+
+isInstDecl InstanceDeclOrigin = True
+isInstDecl ClassDeclOrigin = False