SYN_IE(RenamedInstDecl), SYN_IE(RenamedFixityDecl), SYN_IE(RenamedHsExpr),
SYN_IE(RenamedSig), SYN_IE(RenamedSpecInstSig), SYN_IE(RenamedHsDecl)
)
-import TcHsSyn ( TcIdOcc(..), SYN_IE(TcIdBndr), SYN_IE(TcHsBinds),
+import TcHsSyn ( SYN_IE(TcHsBinds),
SYN_IE(TcMonoBinds), SYN_IE(TcExpr), tcIdType,
mkHsTyLam, mkHsTyApp,
mkHsDictLam, mkHsDictApp )
-import TcBinds ( tcBindWithSigs, TcSigInfo(..) )
+import TcBinds ( tcBindWithSigs, tcPragmaSigs, TcSigInfo(..), checkSigTyVars )
import TcMonad
import RnMonad ( SYN_IE(RnNameSupply) )
import Inst ( Inst, InstOrigin(..), SYN_IE(InstanceMapper),
instToId, newDicts, newMethod, SYN_IE(LIE), emptyLIE, plusLIE )
-import TcBinds ( tcPragmaSigs, checkSigTyVars )
import PragmaInfo ( PragmaInfo(..) )
import TcDeriv ( tcDeriving )
-import TcEnv ( tcLookupClass, newLocalId, tcExtendGlobalTyVars, tcGetGlobalTyVars )
+import TcEnv ( tcLookupClass, newLocalId, tcExtendGlobalTyVars, tcGetGlobalTyVars,
+ tcExtendGlobalValEnv, tcAddImportedIdInfo
+ )
import SpecEnv ( SpecEnv )
import TcGRHSs ( tcGRHSsAndBinds )
import TcInstUtil ( InstInfo(..), mkInstanceRelatedIds, buildInstanceEnvs )
import TcMatches ( tcMatchesFun )
import TcMonoType ( tcTyVarScope, tcContext, tcHsTypeKind )
import TcSimplify ( tcSimplifyAndCheck )
-import TcType ( SYN_IE(TcType), SYN_IE(TcTyVar), SYN_IE(TcTyVarSet),
+import TcType ( TcIdOcc(..), SYN_IE(TcIdBndr), SYN_IE(TcType), SYN_IE(TcTyVar), SYN_IE(TcTyVarSet),
tcInstSigTyVars, tcInstType, tcInstSigTcType,
tcInstTheta, tcInstTcType, tcInstSigType
)
concatBag, foldBag, bagToList, listToBag,
Bag )
import CmdLineOpts ( opt_GlasgowExts, opt_CompilingGhcInternals,
- opt_OmitDefaultInstanceMethods,
+ opt_OmitDefaultInstanceMethods, opt_PprUserLength,
opt_SpecialiseOverloaded
)
-import Class ( GenClass, GenClassOp,
- classBigSig, classOps, classOpLocalType,
+import Class ( GenClass,
+ classBigSig,
classDefaultMethodId, SYN_IE(Class)
)
-import Id ( GenId, idType, isDefaultMethodId_maybe,
+import Id ( GenId, idType, replacePragmaInfo,
isNullaryDataCon, dataConArgTys, SYN_IE(Id) )
import ListSetOps ( minusList )
-import Maybes ( maybeToBool, expectJust, seqMaybe )
-import Name ( nameOccName, getOccString, occNameString, moduleString, getOccName,
+import Maybes ( maybeToBool, expectJust, seqMaybe, catMaybes )
+import Name ( nameOccName, getOccString, occNameString, moduleString, getSrcLoc,
isLocallyDefined, OccName, Name{--O only-}, SYN_IE(Module),
NamedThing(..)
)
-import PrelVals ( nO_EXPLICIT_METHOD_ERROR_ID )
-import PprType ( GenType, GenTyVar, GenClass, GenClassOp, TyCon,
+import PrelVals ( nO_EXPLICIT_METHOD_ERROR_ID, nO_DEFAULT_METHOD_ERROR_ID )
+import PprType ( GenType, GenTyVar, GenClass, TyCon,
pprParendGenType
)
-import PprStyle
import Outputable
import SrcLoc ( SrcLoc, noSrcLoc )
import Pretty
-import TyCon ( isSynTyCon, derivedFor )
+import TyCon ( isSynTyCon, isDataTyCon, derivedClasses )
import Type ( GenType(..), SYN_IE(ThetaType), mkTyVarTys, isPrimType,
splitSigmaTy, splitAppTys, isTyVarTy, matchTy, mkSigmaTy,
- getTyCon_maybe, maybeAppTyCon, SYN_IE(Type),
+ getTyCon_maybe, maybeAppTyCon, SYN_IE(Type), getTyVar,
maybeBoxedPrimType, maybeAppDataTyCon, splitRhoTy, eqTy
)
import TyVar ( GenTyVar, SYN_IE(GenTyVarSet), tyVarSetToList,
mkTyVarSet, unionTyVarSets, SYN_IE(TyVar) )
import TysPrim ( byteArrayPrimTyCon, mutableByteArrayPrimTyCon )
import TysWiredIn ( stringTy )
-import Unique ( Unique, cCallableClassKey, cReturnableClassKey )
-import UniqFM ( Uniquable(..) )
-import Util ( zipEqual, panic, pprPanic, pprTrace
+import Unique ( Unique, cCallableClassKey, cReturnableClassKey, Uniquable(..) )
+import Util ( zipEqual, panic, pprPanic, pprTrace, removeDups, Ord3(..)
#if __GLASGOW_HASKELL__ < 202
, trace
#endif
\end{enumerate}
\begin{code}
-tcInstDecls1 :: [RenamedHsDecl]
+tcInstDecls1 :: TcEnv s -- Contains IdInfo for dfun ids
+ -> [RenamedHsDecl]
-> Module -- module name for deriving
-> RnNameSupply -- for renaming derivings
-> TcM s (Bag InstInfo,
RenamedHsBinds,
PprStyle -> Doc)
-tcInstDecls1 decls mod_name rn_name_supply
+tcInstDecls1 unf_env decls mod_name rn_name_supply
= -- Do the ordinary instance declarations
- mapNF_Tc (tcInstDecl1 mod_name)
+ mapNF_Tc (tcInstDecl1 unf_env mod_name)
[inst_decl | InstD inst_decl <- decls] `thenNF_Tc` \ inst_info_bags ->
let
decl_inst_info = unionManyBags inst_info_bags
returnTc (full_inst_info, deriv_binds, ddump_deriv)
-tcInstDecl1 :: Module -> RenamedInstDecl -> NF_TcM s (Bag InstInfo)
+tcInstDecl1 :: TcEnv s -> Module -> RenamedInstDecl -> NF_TcM s (Bag InstInfo)
-tcInstDecl1 mod_name (InstDecl poly_ty binds uprags (Just dfun_name) src_loc)
+tcInstDecl1 unf_env mod_name (InstDecl poly_ty binds uprags (Just dfun_name) src_loc)
= -- Prime error recovery, set source location
recoverNF_Tc (returnNF_Tc emptyBag) $
tcAddSrcLoc src_loc $
`thenTc` \ (inst_tycon,arg_tys) ->
-- Make the dfun id and constant-method ids
- mkInstanceRelatedIds dfun_name
- clas inst_tyvars inst_tau inst_theta
- `thenNF_Tc` \ (dfun_id, dfun_theta) ->
-
+ let
+ (dfun_id, dfun_theta) = mkInstanceRelatedIds dfun_name
+ clas inst_tyvars inst_tau inst_theta
+ -- Add info from interface file
+ final_dfun_id = tcAddImportedIdInfo unf_env dfun_id
+ in
returnTc (unitBag (InstInfo clas inst_tyvars inst_tau inst_theta
- dfun_theta dfun_id
+ dfun_theta final_dfun_id
binds src_loc uprags))
where
(tyvar_names, context, dict_ty) = case poly_ty of
other -> ([], [], poly_ty)
(class_name, inst_ty) = case dict_ty of
MonoDictTy cls ty -> (cls,ty)
- other -> pprPanic "Malformed intance decl" (ppr PprDebug poly_ty)
+ other -> pprPanic "Malformed instance decl" (ppr PprDebug poly_ty)
\end{code}
\begin{code}
tcInstDecls2 :: Bag InstInfo
- -> NF_TcM s (LIE s, TcHsBinds s)
+ -> NF_TcM s (LIE s, TcMonoBinds s)
tcInstDecls2 inst_decls
- = foldBag combine tcInstDecl2 (returnNF_Tc (emptyLIE, EmptyBinds)) inst_decls
+ = foldBag combine tcInstDecl2 (returnNF_Tc (emptyLIE, EmptyMonoBinds)) inst_decls
where
combine tc1 tc2 = tc1 `thenNF_Tc` \ (lie1, binds1) ->
tc2 `thenNF_Tc` \ (lie2, binds2) ->
returnNF_Tc (lie1 `plusLIE` lie2,
- binds1 `ThenBinds` binds2)
+ binds1 `AndMonoBinds` binds2)
\end{code}
First comes the easy case of a non-local instance decl.
\begin{code}
-tcInstDecl2 :: InstInfo -> NF_TcM s (LIE s, TcHsBinds s)
+tcInstDecl2 :: InstInfo -> NF_TcM s (LIE s, TcMonoBinds s)
tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
inst_decl_theta dfun_theta
dfun_id monobinds
locn uprags)
| not (isLocallyDefined dfun_id)
- = returnNF_Tc (emptyLIE, EmptyBinds)
+ = returnNF_Tc (emptyLIE, EmptyMonoBinds)
{-
-- I deleted this "optimisation" because when importing these
| otherwise
= -- Prime error recovery
- recoverNF_Tc (returnNF_Tc (emptyLIE, EmptyBinds)) $
- tcAddSrcLoc locn $
+ recoverNF_Tc (returnNF_Tc (emptyLIE, EmptyMonoBinds)) $
+ tcAddSrcLoc locn $
-- Get the class signature
tcInstSigTyVars inst_tyvars `thenNF_Tc` \ (inst_tyvars', _, tenv) ->
origin = InstanceDeclOrigin
(class_tyvar,
super_classes, sc_sel_ids,
- class_ops, op_sel_ids, defm_ids) = classBigSig clas
+ op_sel_ids, defm_ids) = classBigSig clas
in
tcInstType tenv inst_ty `thenNF_Tc` \ inst_ty' ->
tcInstTheta tenv dfun_theta `thenNF_Tc` \ dfun_theta' ->
newDicts origin inst_decl_theta' `thenNF_Tc` \ (inst_decl_dicts, _) ->
newDicts origin [(clas,inst_ty')] `thenNF_Tc` \ (this_dict, [this_dict_id]) ->
+ -- Now process any INLINE or SPECIALIZE pragmas for the methods
+ -- ...[NB May 97; all ignored except INLINE]
+ tcPragmaSigs uprags `thenTc` \ (prag_fn, spec_binds, spec_lie) ->
+
-- Check the method bindings
let
inst_tyvars_set' = mkTyVarSet inst_tyvars'
in
mapTc check_from_this_class (bagToList (collectMonoBinders monobinds)) `thenTc_`
tcExtendGlobalTyVars inst_tyvars_set' (
- mapAndUnzip3Tc (tcMethodBind (getDefmRhs clas) inst_ty' monobinds)
- (op_sel_ids `zip` [0..])
+ tcExtendGlobalValEnv (catMaybes defm_ids) $
+ -- Default-method Ids may be mentioned in synthesised RHSs
+ mapAndUnzip3Tc (tcMethodBind clas inst_ty' monobinds)
+ (op_sel_ids `zip` defm_ids)
) `thenTc` \ (method_binds_s, insts_needed_s, meth_lies_w_ids) ->
-- Check the overloading constraints of the methods and superclasses
avail_insts -- These insts are in scope; quite a few, eh?
= this_dict `plusLIE` dfun_arg_dicts `plusLIE` unionManyBags meth_lies
in
- tcAddErrCtxt (bindSigCtxt meth_ids) (
- tcSimplifyAndCheck
+ tcAddErrCtxt bindSigCtxt (
+ tcSimplifyAndCheck
inst_tyvars_set' -- Local tyvars
avail_insts
(sc_dicts `unionBags`
-- Ignore the result; we're only doing
-- this to make sure it can be done.
- -- Now process any SPECIALIZE pragmas for the methods
- let
- spec_sigs = [ s | s@(SpecSig _ _ _ _) <- uprags ]
- in
- tcPragmaSigs spec_sigs `thenTc` \ (_, spec_binds, spec_lie) ->
-
-- Create the result bindings
let
dict_bind = VarMonoBind this_dict_id (Dictionary sc_dict_ids meth_ids)
method_binds = andMonoBinds method_binds_s
main_bind
- = MonoBind (
- AbsBinds
+ = AbsBinds
inst_tyvars'
dfun_arg_dicts_ids
[(inst_tyvars', RealId dfun_id, this_dict_id)]
(super_binds `AndMonoBinds`
method_binds `AndMonoBinds`
- dict_bind))
- [] recursive -- Recursive to play safe
+ dict_bind)
in
returnTc (const_lie `plusLIE` spec_lie,
- main_bind `ThenBinds` spec_binds)
-\end{code}
-
-The next function looks for a method binding; if there isn't one it
-manufactures one that just calls the global default method.
-
-See the notes under default decls in TcClassDcl.lhs.
-
-\begin{code}
-getDefmRhs :: Class -> Int -> RenamedHsExpr
-getDefmRhs clas idx = HsVar (getName (classDefaultMethodId clas idx))
+ main_bind `AndMonoBinds` spec_binds)
\end{code}
\begin{code}
tcMethodBind
- :: (Int -> RenamedHsExpr) -- Function mapping a tag to default RHS
+ :: Class
-> TcType s -- Instance type
-> RenamedMonoBinds -- Method binding
- -> (Id, Int) -- Selector ID (and its 0-indexed tag)
- -- for which binding is wanted
+ -> (Id, Maybe Id) -- Selector id and default-method id
-> TcM s (TcMonoBinds s, LIE s, (LIE s, TcIdOcc s))
-tcMethodBind deflt_fn inst_ty meth_binds (sel_id, idx)
- = newMethod origin (RealId sel_id) [inst_ty] `thenNF_Tc` \ meth@(_, TcId meth_id) ->
- tcInstSigTcType (idType meth_id) `thenNF_Tc` \ (tyvars', rho_ty') ->
+tcMethodBind clas inst_ty meth_binds (sel_id, maybe_dm_id)
+ = newMethod origin (RealId sel_id) [inst_ty] `thenNF_Tc` \ meth@(_, TcId local_meth_id) ->
+ tcInstSigTcType (idType local_meth_id) `thenNF_Tc` \ (tyvars', rho_ty') ->
let
- meth_name = getName meth_id
- default_bind = PatMonoBind (VarPatIn meth_name)
- (GRHSsAndBindsIn [OtherwiseGRHS (deflt_fn idx) noSrcLoc] EmptyBinds)
- noSrcLoc
+ meth_name = getName local_meth_id
- (op_name, op_bind) = case go (getOccName sel_id) meth_binds of
- Just stuff -> stuff
- Nothing -> (meth_name, default_bind)
+ maybe_meth_bind = go (getOccName sel_id) meth_binds
+ (bndr_name, op_bind) = case maybe_meth_bind of
+ Just stuff -> stuff
+ Nothing -> (meth_name, mk_default_bind meth_name)
- (theta', tau') = splitRhoTy rho_ty'
- sig_info = TySigInfo op_name meth_id tyvars' theta' tau' noSrcLoc
+ (theta', tau') = splitRhoTy rho_ty'
+ sig_info = TySigInfo bndr_name local_meth_id tyvars' theta' tau' noSrcLoc
in
- tcBindWithSigs [op_name] op_bind [sig_info]
+
+ -- Warn if no method binding
+ warnTc (not (maybeToBool maybe_meth_bind) && not (maybeToBool maybe_dm_id))
+ (omittedMethodWarn sel_id clas) `thenNF_Tc_`
+
+ tcBindWithSigs [bndr_name] op_bind [sig_info]
nonRecursive (\_ -> NoPragmaInfo) `thenTc` \ (binds, insts, _) ->
returnTc (binds, insts, meth)
go occ b@(PatMonoBind (VarPatIn op_name) _ locn) | nameOccName op_name == occ = Just (op_name, b)
| otherwise = Nothing
go occ other = panic "Urk! Bad instance method binding"
+
+
+ mk_default_bind local_meth_name
+ = PatMonoBind (VarPatIn local_meth_name)
+ (GRHSsAndBindsIn [OtherwiseGRHS default_expr noSrcLoc] EmptyBinds)
+ noSrcLoc
+
+ default_expr = case maybe_dm_id of
+ Just dm_id -> HsVar (getName dm_id) -- There's a default method
+ Nothing -> error_expr -- No default method
+
+ error_expr = HsApp (HsVar (getName nO_DEFAULT_METHOD_ERROR_ID))
+ (HsLit (HsString (_PK_ error_msg)))
+
+ error_msg = show (hcat [ppr (PprForUser opt_PprUserLength) (getSrcLoc sel_id), text "|",
+ ppr (PprForUser opt_PprUserLength) sel_id
+ ])
\end{code}
= returnTc (inst_tycon,arg_tys)
-- TYVARS CHECK
- | not (all isTyVarTy arg_tys ||
- opt_GlasgowExts)
+ | not (opt_GlasgowExts ||
+ (all isTyVarTy arg_tys && null tyvar_dups)
+ )
= failTc (instTypeErr inst_tau)
-- DERIVING CHECK
-- for something that we are also planning to `derive'
-- Though we can have an explicit instance which is more
-- specific than the derived instance
- | clas `derivedFor` inst_tycon
+ | clas `elem` (derivedClasses inst_tycon)
&& all isTyVarTy arg_tys
= failTc (derivingWhenInstanceExistsErr clas inst_tycon)
(possible_tycon, arg_tys) = splitAppTys inst_tau
inst_tycon_maybe = getTyCon_maybe possible_tycon
inst_tycon = expectJust "tcInstDecls1:inst_tycon" inst_tycon_maybe
+ (_, tyvar_dups) = removeDups cmp (map (getTyVar "tcInstDecls1:getTyVarTy") arg_tys)
-- These conditions come directly from what the DsCCall is capable of.
-- Totally grotesque. Green card should solve this.
byte_arr_thing
where
byte_arr_thing = case maybeAppDataTyCon ty of
- Just (tycon, ty_args, [data_con]) ->
--- pprTrace "cc1" (sep [ppr PprDebug tycon, ppr PprDebug data_con,
--- sep (map (ppr PprDebug) data_con_arg_tys)])(
+ Just (tycon, ty_args, [data_con]) | isDataTyCon tycon ->
length data_con_arg_tys == 2 &&
maybeToBool maybe_arg2_tycon &&
--- pprTrace "cc2" (sep [ppr PprDebug arg2_tycon]) (
(arg2_tycon == byteArrayPrimTyCon ||
arg2_tycon == mutableByteArrayPrimTyCon)
--- ))
where
data_con_arg_tys = dataConArgTys data_con ty_args
(data_con_arg_ty1 : data_con_arg_ty2 : _) = data_con_arg_tys
instTypeErr ty sty
= case ty of
- SynTy tc _ _ -> hcat [ptext SLIT("The type synonym `"), ppr sty tc, rest_of_msg]
- TyVarTy tv -> hcat [ptext SLIT("The type variable `"), ppr sty tv, rest_of_msg]
- other -> hcat [ptext SLIT("The type `"), ppr sty ty, rest_of_msg]
+ SynTy tc _ _ -> hsep [ptext SLIT("The type synonym"), ppr sty tc, rest_of_msg]
+ TyVarTy tv -> hsep [ptext SLIT("The type variable"), ppr sty tv, rest_of_msg]
+ other -> sep [ptext SLIT("The type"), nest 4 (ppr sty ty), rest_of_msg]
where
- rest_of_msg = ptext SLIT("' cannot be used as an instance type.")
+ rest_of_msg = ptext SLIT("cannot be used as an instance type")
instBndrErr bndr clas sty
= hsep [ptext SLIT("Class"), ppr sty clas, ptext SLIT("does not have a method"), ppr sty bndr]
ptext SLIT("type"), ppr sty tycon])
4 (ptext SLIT("when an explicit instance exists"))
-derivingWhenInstanceImportedErr inst_mod clas tycon sty
- = hang (hsep [ptext SLIT("Deriving class"),
- ppr sty clas,
- ptext SLIT("type"), ppr sty tycon])
- 4 (hsep [ptext SLIT("when an instance declared in module"),
- pp_mod, ptext SLIT("has been imported")])
- where
- pp_mod = hsep [ptext SLIT("module"), ptext inst_mod]
-
nonBoxedPrimCCallErr clas inst_ty sty
= hang (ptext SLIT("Unacceptable instance type for ccall-ish class"))
4 (hsep [ ptext SLIT("class"), ppr sty clas, ptext SLIT("type"),
ppr sty inst_ty])
-omitDefaultMethodWarn clas_op clas_name inst_ty sty
- = hsep [ptext SLIT("Warning: Omitted default method for"),
- ppr sty clas_op, ptext SLIT("in instance"),
- text clas_name, pprParendGenType sty inst_ty]
+omittedMethodWarn sel_id clas sty
+ = sep [ptext SLIT("No explicit method nor default method for") <+> ppr sty sel_id,
+ ptext SLIT("in an instance declaration for") <+> ppr sty clas]
instMethodNotInClassErr occ clas sty
= hang (ptext SLIT("Instance mentions a method not in the class"))
ppr sty name, ptext SLIT("to its signature :") ])
4 (ppr sty ty)
-bindSigCtxt method_ids sty
- = hang (ptext SLIT("When checking type signatures for: "))
- 4 (hsep (punctuate comma (map (ppr sty) method_ids)))
+bindSigCtxt sty
+ = ptext SLIT("When checking methods of an instance declaration")
superClassSigCtxt sty
- = ptext SLIT("When checking superclass constraints on instance declaration")
-
+ = ptext SLIT("When checking superclass constraints of an instance declaration")
\end{code}