#include "HsVersions.h"
import HsSyn
-import TcBinds ( tcSpecSigs )
+import TcBinds ( mkPragFun, tcPrags, badBootDeclErr )
import TcClassDcl ( tcMethodBind, mkMethodBind, badMethodErr,
tcClassDecl2, getGenericInstances )
import TcRnMonad
import TcType ( mkClassPred, tyVarsOfType,
tcSplitSigmaTy, tcSplitDFunHead, mkTyVarTys,
SkolemInfo(InstSkol), tcSplitDFunTy, pprClassPred )
-import Inst ( tcInstClassOp, newDicts, instToId, showLIE, tcExtendLocalInstEnv )
+import Inst ( tcInstClassOp, newDicts, instToId, showLIE,
+ getOverlapFlag, tcExtendLocalInstEnv )
+import InstEnv ( mkLocalInstance, instanceDFunId )
import TcDeriv ( tcDeriving )
-import TcEnv ( tcExtendGlobalValEnv, tcExtendTyVarEnv,
- InstInfo(..), InstBindings(..),
+import TcEnv ( InstInfo(..), InstBindings(..),
newDFunName, tcExtendIdEnv
)
import TcHsType ( kcHsSigType, tcHsKindedType )
import MkId ( mkDictFunId, rUNTIME_ERROR_ID )
import FunDeps ( checkInstFDs )
import Name ( Name, getSrcLoc )
-import NameSet ( unitNameSet, emptyNameSet )
import UnicodeUtil ( stringToUtf8 )
import Maybe ( catMaybes )
import SrcLoc ( srcLocSpan, unLoc, noLoc, Located(..), srcSpanStart )
import ListSetOps ( minusList )
import Outputable
import Bag
+import BasicTypes ( Activation( AlwaysActive ) )
import FastString
\end{code}
-> TcM (TcGblEnv, -- The full inst env
[InstInfo], -- Source-code instance decls to process;
-- contains all dfuns for this module
- [HsBindGroup Name]) -- Supporting bindings for derived instances
+ HsValBinds Name) -- Supporting bindings for derived instances
tcInstDecls1 tycl_decls inst_decls
= checkNoErrs $
clas_decls = filter (isClassDecl.unLoc) tycl_decls
in
-- (2) Instances from generic class declarations
- getGenericInstances clas_decls `thenM` \ generic_inst_info ->
+ getGenericInstances clas_decls `thenM` \ generic_inst_info ->
-- Next, construct the instance environment so far, consisting of
-- a) local instance decls
addInsts :: [InstInfo] -> TcM a -> TcM a
addInsts infos thing_inside
- = tcExtendLocalInstEnv (map iDFunId infos) thing_inside
+ = tcExtendLocalInstEnv (map iSpec infos) thing_inside
\end{code}
\begin{code}
checkTc (checkInstFDs theta clas inst_tys)
(instTypeErr (pprClassPred clas inst_tys) msg) `thenM_`
newDFunName clas inst_tys (srcSpanStart loc) `thenM` \ dfun_name ->
- returnM (Just (InstInfo { iDFunId = mkDictFunId dfun_name tyvars theta clas inst_tys,
- iBinds = VanillaInst binds uprags }))
+ getOverlapFlag `thenM` \ overlap_flag ->
+ let dfun = mkDictFunId dfun_name tyvars theta clas inst_tys
+ ispec = mkLocalInstance dfun overlap_flag
+ in
+
+ tcIsHsBoot `thenM` \ is_boot ->
+ checkTc (not is_boot || (isEmptyLHsBinds binds && null uprags))
+ badBootDeclErr `thenM_`
+
+ returnM (Just (InstInfo { iSpec = ispec, iBinds = VanillaInst binds uprags }))
where
msg = parens (ptext SLIT("the instance types do not agree with the functional dependencies of the class"))
\end{code}
\begin{code}
tcInstDecls2 :: [LTyClDecl Name] -> [InstInfo]
- -> TcM (TcLclEnv, LHsBinds Id)
+ -> TcM (LHsBinds Id, TcLclEnv)
-- (a) From each class declaration,
-- generate any default-method bindings
-- (b) From each instance decl
; inst_binds_s <- mappM tcInstDecl2 inst_decls
-- Done
- ; tcl_env <- getLclEnv
- ; returnM (tcl_env, unionManyBags dm_binds_s `unionBags`
- unionManyBags inst_binds_s) }
+ ; let binds = unionManyBags dm_binds_s `unionBags`
+ unionManyBags inst_binds_s
+ ; tcl_env <- getLclEnv -- Default method Ids in here
+ ; returnM (binds, tcl_env) }
\end{code}
======= New documentation starts here (Sept 92) ==============
\begin{code}
tcInstDecl2 :: InstInfo -> TcM (LHsBinds Id)
-tcInstDecl2 (InstInfo { iDFunId = dfun_id, iBinds = binds })
- = -- Prime error recovery
+tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = binds })
+ = 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
- let
- rigid_info = InstSkol dfun_id
- inst_ty = idType dfun_id
- in
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
-- of the inst_tyavars' with something in the envt
checkSigTyVars inst_tyvars' `thenM_`
- -- Deal with 'SPECIALISE instance' pragmas by making them
- -- look like SPECIALISE pragmas for the dfun
+ -- Deal with 'SPECIALISE instance' pragmas
let
- uprags = case binds of
- VanillaInst _ uprags -> uprags
- other -> []
- spec_prags = [ L loc (SpecSig (L loc (idName dfun_id)) ty)
- | L loc (SpecInstSig ty) <- uprags ]
+ specs = case binds of
+ VanillaInst _ prags -> filter isSpecInstLSig prags
+ other -> []
in
- tcExtendGlobalValEnv [dfun_id] (
- tcExtendTyVarEnv inst_tyvars' $
- tcSpecSigs spec_prags
- ) `thenM` \ prag_binds ->
-
+ tcPrags dfun_id specs `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
- inlines | null dfun_arg_dicts = emptyNameSet
- | otherwise = unitNameSet (idName dfun_id)
+ inline_prag | null dfun_arg_dicts = []
+ | otherwise = [InlinePrag True AlwaysActive]
-- 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
main_bind = noLoc $ AbsBinds
inst_tyvars'
(map instToId dfun_arg_dicts)
- [(inst_tyvars', dfun_id, this_dict_id)]
- inlines all_binds
+ [(inst_tyvars', dfun_id, this_dict_id,
+ inline_prag ++ prags)]
+ all_binds
in
showLIE (text "instance") `thenM_`
- returnM (unitBag main_bind `unionBags`
- prag_binds )
+ returnM (unitBag main_bind)
tcMethods origin clas inst_tyvars' dfun_theta' inst_tys'
-- 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
- tc_method_bind = tcMethodBind inst_tyvars' dfun_theta' all_insts uprags
+ tc_method_bind = tcMethodBind inst_tyvars' dfun_theta' all_insts prag_fn
meth_ids = [meth_id | (_,meth_id,_) <- meth_infos]
in