import CmdLineOpts ( DynFlag(..), dopt )
-import HsSyn ( HsDecl(..), InstDecl(..), TyClDecl(..),
- MonoBinds(..), HsExpr(..), HsLit(..), Sig(..),
+import HsSyn ( HsDecl(..), InstDecl(..), TyClDecl(..),
+ MonoBinds(..), HsExpr(..), HsLit(..), Sig(..),
andMonoBindList, collectMonoBinders, isClassDecl
)
-import HsTypes ( HsType (..), HsTyVarBndr(..), toHsTyVar )
-import HsPat ( InPat (..) )
-import HsMatches ( Match (..) )
-import RnHsSyn ( RenamedHsBinds, RenamedInstDecl, RenamedHsDecl,
- extractHsTyVars )
+import RnHsSyn ( RenamedHsBinds, RenamedInstDecl, RenamedHsDecl, RenamedMonoBinds,
+ RenamedTyClDecl, RenamedHsType,
+ extractHsTyVars, maybeGenericMatch
+ )
import TcHsSyn ( TcMonoBinds, mkHsConApp )
import TcBinds ( tcSpecSigs )
import TcClassDcl ( tcMethodBind, badMethodErr )
LIE, emptyLIE, plusLIE, plusLIEs )
import TcDeriv ( tcDeriving )
import TcEnv ( TcEnv, tcExtendGlobalValEnv,
- tcExtendTyVarEnvForMeths, TyThing (..),
+ tcExtendTyVarEnvForMeths,
tcAddImportedIdInfo, tcInstId, tcLookupClass,
+ InstInfo(..), pprInstInfo, simpleInstInfoTyCon, simpleInstInfoTy,
newDFunName, tcExtendTyVarEnv
)
-import InstEnv ( InstInfo(..), InstEnv, pprInstInfo, classDataCon,
- simpleInstInfoTyCon, simpleInstInfoTy, isLocalInst,
- extendInstEnv )
-import TcMonoType ( tcTyVars, tcHsSigType, tcHsType, kcHsSigType )
+import InstEnv ( InstEnv, extendInstEnv )
+import TcMonoType ( tcTyVars, tcHsSigType, kcHsSigType )
import TcSimplify ( tcSimplifyAndCheck )
import TcType ( zonkTcSigTyVars )
-import HscTypes ( PersistentCompilerState(..), HomeSymbolTable, DFunId,
- ModDetails(..) )
-
-import Bag ( emptyBag, unitBag, unionBags, unionManyBags,
- foldBag, Bag, listToBag
+import HscTypes ( HomeSymbolTable, DFunId,
+ ModDetails(..), PackageInstEnv, PersistentRenamerState
)
+
+import Bag ( unionManyBags )
+import DataCon ( classDataCon )
import Class ( Class, DefMeth(..), classBigSig )
import Var ( idName, idType )
-import Maybes ( maybeToBool, expectJust )
+import Maybes ( maybeToBool )
import MkId ( mkDictFunId )
import Generics ( validGenericInstanceType )
import Module ( Module, foldModuleEnv )
-import Name ( isLocallyDefined )
+import Name ( getSrcLoc )
import NameSet ( emptyNameSet, nameSetToList )
import PrelInfo ( eRROR_ID )
import PprType ( pprConstraint, pprPred )
-import TyCon ( TyCon, isSynTyCon, tyConDerivings )
-import Type ( mkTyVarTys, splitDFunTy, isTyVarTy,
+import TyCon ( TyCon, isSynTyCon )
+import Type ( splitDFunTy, isTyVarTy,
splitTyConApp_maybe, splitDictTy,
- splitAlgTyConApp_maybe, classesToPreds, classesOfPreds,
+ splitAlgTyConApp_maybe, splitForAllTys,
unUsgTy, tyVarsOfTypes, mkClassPred, mkTyVarTy,
getClassTys_maybe
)
-import Subst ( mkTopTyVarSubst, substClasses, substTheta )
+import Subst ( mkTopTyVarSubst, substClasses )
import VarSet ( mkVarSet, varSetElems )
import TysWiredIn ( genericTyCons, isFFIArgumentTy, isFFIResultTy )
import PrelNames ( cCallableClassKey, cReturnableClassKey, hasKey )
-import Name ( Name, NameEnv, extendNameEnv_C, emptyNameEnv,
- plusNameEnv_C, nameEnvElts )
-import FiniteMap ( mapFM )
+import Name ( Name )
import SrcLoc ( SrcLoc )
-import RnHsSyn -- ( RenamedMonoBinds )
import VarSet ( varSetElems )
-import UniqFM ( mapUFM )
import Unique ( Uniquable(..) )
-import BasicTypes ( NewOrData(..) )
+import BasicTypes ( NewOrData(..), Fixity )
import ErrUtils ( dumpIfSet_dyn )
import ListSetOps ( Assoc, emptyAssoc, plusAssoc_C, mapAssoc,
assocElts, extendAssoc_C,
equivClassesByUniq, minusList
)
-import List ( intersect, (\\), partition )
+import List ( partition )
import Outputable
\end{code}
Gather up the instance declarations from their various sources
\begin{code}
-tcInstDecls1 :: PersistentCompilerState
+tcInstDecls1 :: PackageInstEnv
+ -> PersistentRenamerState
-> HomeSymbolTable -- Contains instances
-> TcEnv -- Contains IdInfo for dfun ids
-> (Name -> Maybe Fixity) -- for deriving Show and Read
-> Module -- Module for deriving
-> [TyCon]
-> [RenamedHsDecl]
- -> TcM (PersistentCompilerState, InstEnv, [InstInfo], RenamedHsBinds)
+ -> TcM (PackageInstEnv, InstEnv, [InstInfo], RenamedHsBinds)
-tcInstDecls1 pcs hst unf_env get_fixity mod local_tycons decls
+tcInstDecls1 inst_env0 prs hst unf_env get_fixity mod tycons decls
= let
- inst_decls = [inst_decl | InstD inst_decl <- decls]
- clas_decls = [clas_decl | TyClD clas_decl <- decls, isClassDecl clas_decl]
+ inst_decls = [inst_decl | InstD inst_decl <- decls]
+ tycl_decls = [decl | TyClD decl <- decls]
+ clas_decls = filter isClassDecl tycl_decls
in
-- (1) Do the ordinary instance declarations
mapNF_Tc (tcInstDecl1 mod unf_env) inst_decls `thenNF_Tc` \ inst_infos ->
-- e) generic instances inst_env4
-- The result of (b) replaces the cached InstEnv in the PCS
let
- (local_inst_info, imported_inst_info)
- = partition isLocalInst (concat inst_infos)
+ (local_inst_info, imported_inst_info) = partition iLocal (concat inst_infos)
imported_dfuns = map (tcAddImportedIdInfo unf_env . iDFunId)
imported_inst_info
hst_dfuns = foldModuleEnv ((++) . md_insts) [] hst
in
- addInstDFuns (pcs_insts pcs) imported_dfuns `thenNF_Tc` \ inst_env1 ->
+ addInstDFuns inst_env0 imported_dfuns `thenNF_Tc` \ inst_env1 ->
addInstDFuns inst_env1 hst_dfuns `thenNF_Tc` \ inst_env2 ->
addInstInfos inst_env2 local_inst_info `thenNF_Tc` \ inst_env3 ->
addInstInfos inst_env3 generic_inst_info `thenNF_Tc` \ inst_env4 ->
-- we ignore deriving decls from interfaces!
-- This stuff computes a context for the derived instance decl, so it
-- needs to know about all the instances possible; hecne inst_env4
- tcDeriving (pcs_PRS pcs) mod inst_env4 get_fixity local_tycons
- `thenTc` \ (deriv_inst_info, deriv_binds) ->
- addInstInfos inst_env4 deriv_inst_info
- `thenNF_Tc` \ final_inst_env ->
+ tcDeriving prs mod inst_env4 get_fixity tycl_decls `thenTc` \ (deriv_inst_info, deriv_binds) ->
+ addInstInfos inst_env4 deriv_inst_info `thenNF_Tc` \ final_inst_env ->
- returnTc (pcs { pcs_insts = inst_env1 },
+ returnTc (inst_env1,
final_inst_env,
generic_inst_info ++ deriv_inst_info ++ local_inst_info,
deriv_binds)
-- Make the dfun id and return it
newDFunName mod clas inst_tys src_loc `thenNF_Tc` \ dfun_name ->
- returnNF_Tc (True, mkDictFunId dfun_name clas tyvars inst_tys theta)
+ returnNF_Tc (True, dfun_name)
Just dfun_name -> -- An interface-file instance declaration
-- Make the dfun id
- returnNF_Tc (False, mkDictFunId dfun_name clas tyvars inst_tys theta)
- ) `thenNF_Tc` \ (is_local, dfun_id) ->
+ returnNF_Tc (False, dfun_name)
+ ) `thenNF_Tc` \ (is_local, dfun_name) ->
- returnTc [InstInfo { iLocal = is_local,
- iClass = clas, iTyVars = tyvars, iTys = inst_tys,
- iTheta = theta, iDFunId = dfun_id,
- iBinds = binds, iLoc = src_loc, iPrags = uprags }]
+ let
+ dfun_id = mkDictFunId dfun_name clas tyvars inst_tys theta
+ in
+ returnTc [InstInfo { iLocal = is_local, iDFunId = dfun_id,
+ iBinds = binds, iPrags = uprags }]
\end{code}
-- f {| x+y |} ... = ...
-- Then at this point we'll have an InstInfo for each
let
- bad_groups = [group | group <- equivClassesByUniq get_uniq inst_infos,
+ tc_inst_infos :: [(TyCon, InstInfo)]
+ tc_inst_infos = [(simpleInstInfoTyCon i, i) | i <- inst_infos]
+
+ bad_groups = [group | group <- equivClassesByUniq get_uniq tc_inst_infos,
length group > 1]
- get_uniq inst = getUnique (simpleInstInfoTyCon inst)
+ get_uniq (tc,_) = getUnique tc
in
mapTc (addErrTc . dupGenericInsts) bad_groups `thenTc_`
-- Check that there is an InstInfo for each generic type constructor
let
- missing = genericTyCons `minusList` map simpleInstInfoTyCon inst_infos
+ missing = genericTyCons `minusList` [tc | (tc,_) <- tc_inst_infos]
in
checkTc (null missing) (missingGenericInstances missing) `thenTc_`
dfun_id = mkDictFunId dfun_name clas tyvars inst_tys inst_theta
in
- returnTc (InstInfo { iLocal = True,
- iClass = clas, iTyVars = tyvars, iTys = inst_tys,
- iTheta = inst_theta, iDFunId = dfun_id, iBinds = binds,
- iLoc = loc, iPrags = [] })
+ returnTc (InstInfo { iLocal = True, iDFunId = dfun_id,
+ iBinds = binds, iPrags = [] })
\end{code}
\begin{code}
tcInstDecl2 :: InstInfo -> NF_TcM (LIE, TcMonoBinds)
-tcInstDecl2 (InstInfo { iClass = clas, iTyVars = inst_tyvars, iTys = inst_tys,
- iTheta = inst_decl_theta, iDFunId = dfun_id,
- iBinds = monobinds, iLoc = locn, iPrags = uprags })
- | not (isLocallyDefined dfun_id)
+tcInstDecl2 (InstInfo { iLocal = is_local, iDFunId = dfun_id,
+ iBinds = monobinds, iPrags = uprags })
+ | not is_local
= returnNF_Tc (emptyLIE, EmptyMonoBinds)
| otherwise
= -- Prime error recovery
recoverNF_Tc (returnNF_Tc (emptyLIE, EmptyMonoBinds)) $
- tcAddSrcLoc locn $
+ tcAddSrcLoc (getSrcLoc dfun_id) $
-- Instantiate the instance decl with tc-style type variables
tcInstId dfun_id `thenNF_Tc` \ (inst_tyvars', dfun_theta', dict_ty') ->
dm_ids = [dm_id | (_, DefMeth dm_id) <- op_items]
sel_names = [idName sel_id | (sel_id, _) <- op_items]
- -- Instantiate the theta found in the original instance decl
- inst_decl_theta' = substTheta (mkTopTyVarSubst inst_tyvars (mkTyVarTys inst_tyvars'))
- inst_decl_theta
-
-- Instantiate the super-class context with inst_tys
sc_theta' = substClasses (mkTopTyVarSubst class_tyvars inst_tys') sc_theta
-- Find any definitions in monobinds that aren't from the class
bad_bndrs = collectMonoBinders monobinds `minusList` sel_names
+
+ -- The type variable from the dict fun actually scope
+ -- over the bindings. They were gotten from
+ -- the original instance declaration
+ (inst_tyvars, _) = splitForAllTys (idType dfun_id)
in
-- Check that all the method bindings come from this class
mapTc (addErrTc . badMethodErr clas) bad_bndrs `thenNF_Tc_`
-- Create dictionary Ids from the specified instance contexts.
newClassDicts origin sc_theta' `thenNF_Tc` \ (sc_dicts, sc_dict_ids) ->
newDicts origin dfun_theta' `thenNF_Tc` \ (dfun_arg_dicts, dfun_arg_dicts_ids) ->
- newDicts origin inst_decl_theta' `thenNF_Tc` \ (inst_decl_dicts, _) ->
newClassDicts origin [(clas,inst_tys')] `thenNF_Tc` \ (this_dict, [this_dict_id]) ->
tcExtendTyVarEnvForMeths inst_tyvars inst_tyvars' (
-- Default-method Ids may be mentioned in synthesised RHSs
mapAndUnzip3Tc (tcMethodBind clas origin inst_tyvars' inst_tys'
- inst_decl_theta'
+ dfun_theta'
monobinds uprags True)
op_items
)) `thenTc` \ (method_binds_s, insts_needed_s, meth_lies_w_ids) ->
methods_lie
) `thenTc` \ (const_lie1, lie_binds1) ->
- -- Check that we *could* construct the superclass dictionaries,
- -- even though we are *actually* going to pass the superclass dicts in;
- -- the check ensures that the caller will never have
- --a problem building them.
- tcAddErrCtxt superClassCtxt (
- tcSimplifyAndCheck
- (ptext SLIT("instance declaration context"))
- inst_tyvars_set -- Local tyvars
- inst_decl_dicts -- The instance dictionaries available
- sc_dicts -- The superclass dicationaries reqd
- ) `thenTc` \ _ ->
- -- Ignore the result; we're only doing
- -- this to make sure it can be done.
-
-- Now do the simplification again, this time to get the
-- bindings; this time we use an enhanced "avails"
-- Ignore errors because they come from the *previous* tcSimplify
&& not (creturnable_type first_inst_tau))
-> addErrTc (nonBoxedPrimCCallErr clas first_inst_tau)
- -- DERIVING CHECK
- -- It is obviously illegal to have an explicit instance
- -- for something that we are also planning to `derive'
- | maybeToBool alg_tycon_app_maybe && clas `elem` (tyConDerivings alg_tycon)
- -> addErrTc (derivingWhenInstanceExistsErr clas first_inst_tau)
- -- Kind check will have ensured inst_taus is of length 1
-
-- Allow anything for AllowUndecidableInstances
| dopt Opt_AllowUndecidableInstances dflags
-> returnNF_Tc ()
-dupGenericInsts inst_infos
+dupGenericInsts tc_inst_infos
= vcat [ptext SLIT("More than one type pattern for a single generic type constructor:"),
- nest 4 (vcat (map (ppr . simpleInstInfoTy) inst_infos)),
+ nest 4 (vcat (map ppr_inst_ty tc_inst_infos)),
ptext SLIT("All the type patterns for a generic type constructor must be identical")
]
+ where
+ ppr_inst_ty (tc,inst) = ppr (simpleInstInfoTy inst)
instTypeErr clas tys msg
= sep [ptext SLIT("Illegal instance declaration for") <+> quotes (pprConstraint clas tys),
nest 4 (parens msg)
]
-derivingWhenInstanceExistsErr clas tycon
- = hang (hsep [ptext SLIT("Deriving class"),
- quotes (ppr clas),
- ptext SLIT("type"), quotes (ppr tycon)])
- 4 (ptext SLIT("when an explicit instance exists"))
-
nonBoxedPrimCCallErr clas inst_ty
= hang (ptext SLIT("Unacceptable instance type for ccall-ish class"))
4 (hsep [ ptext SLIT("class"), ppr clas, ptext SLIT("type"),
ppr inst_ty])
methodCtxt = ptext SLIT("When checking the methods of an instance declaration")
-superClassCtxt = ptext SLIT("When checking the superclasses of an instance declaration")
\end{code}
+
+