From 2269b0b4b06a110ad466b914037a763b4dca9190 Mon Sep 17 00:00:00 2001 From: simonm <unknown> Date: Mon, 20 Oct 1997 10:21:28 +0000 Subject: [PATCH] [project @ 1997-10-20 10:21:11 by simonm] fix for overloading-related space leak (typecheck/should_run/tcrun002) --- ghc/compiler/basicTypes/Id.lhs | 18 +--- ghc/compiler/typecheck/Inst.lhs | 97 ++++++++++----------- ghc/compiler/typecheck/TcBinds.lhs | 119 +++++++++++++++++++++----- ghc/compiler/typecheck/TcExpr.lhs | 4 +- ghc/compiler/typecheck/TcInstUtil.lhs | 4 +- ghc/compiler/typecheck/TcMonad.lhs | 5 +- ghc/compiler/typecheck/TcSimplify.lhs | 2 +- ghc/compiler/typecheck/TcType.lhs | 8 +- 8 files changed, 162 insertions(+), 95 deletions(-) diff --git a/ghc/compiler/basicTypes/Id.lhs b/ghc/compiler/basicTypes/Id.lhs index 1e72ae431980..3f4d8e170e76 100644 --- a/ghc/compiler/basicTypes/Id.lhs +++ b/ghc/compiler/basicTypes/Id.lhs @@ -20,7 +20,6 @@ module Id ( mkDictFunId, mkIdWithNewUniq, mkIdWithNewName, mkIdWithNewType, mkImported, - mkInstId, mkMethodSelId, mkRecordSelId, mkSameSpecCon, @@ -295,10 +294,6 @@ data IdDetails -- actually do comparisons that way, we kindly supply -- a Unique for that purpose. - | InstId -- An instance of a dictionary, class operation, - -- or overloaded value (Local name) - Bool -- as for LocalId - | SpecId -- A specialisation of another Id Id -- Id of which this is a specialisation [Maybe Type] -- Types at which it is specialised; @@ -422,9 +417,6 @@ to a dictionary for C (T a b ..). include dictionaries for the immediate superclasses of C at the type (T a b ..). -%---------------------------------------------------------------------- -\item[@InstId@:] - %---------------------------------------------------------------------- \item[@SpecId@:] @@ -461,7 +453,7 @@ They are constants, so they are not free variables. (When the STG machine makes a closure, it puts all the free variables in the closure; the above are not required.) \end{itemize} -Note that @InstIds@, @Locals@ and @SysLocals@ {\em may} have the above +Note that @Locals@ and @SysLocals@ {\em may} have the above properties, but they may not. \end{enumerate} @@ -515,7 +507,6 @@ toplevelishId (Id _ _ _ details _ _) chk (DictFunId _ _) = True chk (SpecId unspec _ _) = toplevelishId unspec -- depends what the unspecialised thing is - chk (InstId _) = False -- these are local chk (LocalId _) = False chk (SysLocalId _) = False chk (SpecPragmaId _ _) = False @@ -533,7 +524,6 @@ idHasNoFreeTyVars (Id _ _ _ details _ info) chk (DefaultMethodId _) = True chk (DictFunId _ _) = True chk (SpecId _ _ no_free_tvs) = no_free_tvs - chk (InstId no_free_tvs) = no_free_tvs chk (LocalId no_free_tvs) = no_free_tvs chk (SysLocalId no_free_tvs) = no_free_tvs chk (SpecPragmaId _ no_free_tvs) = no_free_tvs @@ -661,7 +651,7 @@ apply_to_Id ty_fn id@(Id u n ty details prag info) new_maybes = map apply_to_maybe ty_maybes in SpecId new_unspec new_maybes (no_free_tvs ty) - -- ToDo: gratuitous recalc no_ftvs???? (also InstId) + -- ToDo: gratuitous recalc no_ftvs???? where apply_to_maybe Nothing = Nothing apply_to_maybe (Just ty) = Just (ty_fn ty) @@ -722,9 +712,6 @@ mkWorkerId u unwrkr ty info details = LocalId (no_free_tvs ty) name = mkCompoundName name_fn u (getName unwrkr) name_fn wkr_str = SLIT("$w") _APPEND_ wkr_str - -mkInstId u ty name - = Id u name ty (InstId (no_free_tvs ty)) NoPragmaInfo noIdInfo \end{code} %************************************************************************ @@ -991,7 +978,6 @@ dataConFieldLabels x@(Id _ _ _ idt _ _) = MethodSelId _ -> "m" DefaultMethodId _ -> "d" DictFunId _ _ -> "di" - InstId _ -> "in" SpecId _ _ _ -> "spec")) #endif diff --git a/ghc/compiler/typecheck/Inst.lhs b/ghc/compiler/typecheck/Inst.lhs index 67688c014590..ffd9ec0e00c0 100644 --- a/ghc/compiler/typecheck/Inst.lhs +++ b/ghc/compiler/typecheck/Inst.lhs @@ -17,7 +17,7 @@ module Inst ( newDicts, newDictsAtLoc, newMethod, newMethodWithGivenTy, newOverloadedLit, - instType, tyVarsOfInst, lookupInst, lookupSimpleInst, + tyVarsOfInst, lookupInst, lookupSimpleInst, isDict, isTyVarDict, @@ -42,17 +42,18 @@ import TcHsSyn ( SYN_IE(TcExpr), import TcMonad import TcEnv ( tcLookupGlobalValueByKey, tcLookupTyConByKey ) -import TcType ( TcIdOcc(..), SYN_IE(TcIdBndr), +import TcType ( TcIdOcc(..), SYN_IE(TcIdBndr), SYN_IE(TcThetaType), SYN_IE(TcTauType), SYN_IE(TcType), SYN_IE(TcRhoType), TcMaybe, SYN_IE(TcTyVarSet), - tcInstType, zonkTcType, tcSplitForAllTy, tcSplitRhoTy ) - + tcInstType, zonkTcType, zonkTcTheta, + tcSplitForAllTy, tcSplitRhoTy + ) import Bag ( emptyBag, unitBag, unionBags, unionManyBags, bagToList, listToBag, consBag, Bag ) import Class ( classInstEnv, SYN_IE(Class), GenClass, SYN_IE(ClassInstEnv) ) import ErrUtils ( addErrLoc, SYN_IE(Error) ) -import Id ( GenId, idType, mkInstId, SYN_IE(Id) ) +import Id ( GenId, idType, mkUserLocal, mkSysLocal, SYN_IE(Id) ) import PrelInfo ( isCcallishClass, isNoDictClass ) import MatchEnv ( lookupMEnv, insertMEnv ) import Name ( OccName(..), Name, mkLocalName, @@ -145,15 +146,17 @@ data Inst s -- should be instantiated. -- These types must saturate the Id's foralls. - (TcRhoType s) -- Cached: (type-of-id applied to inst_tys) - -- If this type is (theta => tau) then the type of the Method - -- is tau, and the method can be built by saying - -- id inst_tys dicts - -- where dicts are constructed from theta + (TcThetaType s) -- The (types of the) dictionaries to which the function + -- must be applied to get the method + + (TcTauType s) -- The type of the method (InstOrigin s) SrcLoc + -- INVARIANT: in (Method u f tys theta tau loc) + -- type of (f tys dicts(from theta)) = tau + | LitInst Unique OverloadedLit @@ -165,9 +168,9 @@ data OverloadedLit = OverloadedIntegral Integer -- The number | OverloadedFractional Rational -- The number -getInstOrigin (Dict u clas ty origin loc) = origin -getInstOrigin (Method u clas ty rho origin loc) = origin -getInstOrigin (LitInst u lit ty origin loc) = origin +getInstOrigin (Dict u clas ty origin loc) = origin +getInstOrigin (Method u fn tys theta tau origin loc) = origin +getInstOrigin (LitInst u lit ty origin loc) = origin \end{code} Construction @@ -213,24 +216,29 @@ newMethod orig id tys (case id of RealId id -> let (tyvars, rho) = splitForAllTy (idType id) in - (if length tyvars /= length tys then pprTrace "newMethod" (ppr PprDebug (idType id)) else \x->x) $ - tcInstType (zip{-Equal "newMethod"-} tyvars tys) rho + tcInstType (zipEqual "newMethod" tyvars tys) rho + TcId id -> tcSplitForAllTy (idType id) `thenNF_Tc` \ (tyvars, rho) -> returnNF_Tc (instantiateTy (zipEqual "newMethod(2)" tyvars tys) rho) ) `thenNF_Tc` \ rho_ty -> + let + (theta, tau) = splitRhoTy rho_ty + in -- Our friend does the rest - newMethodWithGivenTy orig id tys rho_ty + newMethodWithGivenTy orig id tys theta tau -newMethodWithGivenTy orig id tys rho_ty +newMethodWithGivenTy orig id tys theta tau = tcGetSrcLoc `thenNF_Tc` \ loc -> tcGetUnique `thenNF_Tc` \ new_uniq -> let - meth_inst = Method new_uniq id tys rho_ty orig loc + meth_inst = Method new_uniq id tys theta tau orig loc in returnNF_Tc (unitLIE meth_inst, instToId meth_inst) -newMethodAtLoc :: InstOrigin s -> SrcLoc -> Id -> [TcType s] -> NF_TcM s (Inst s, TcIdOcc s) +newMethodAtLoc :: InstOrigin s -> SrcLoc + -> Id -> [TcType s] + -> NF_TcM s (Inst s, TcIdOcc s) newMethodAtLoc orig loc real_id tys -- Local function, similar to newMethod but with -- slightly different interface = -- Get the Id type and instantiate it at the specified types @@ -240,7 +248,8 @@ newMethodAtLoc orig loc real_id tys -- Local function, similar to newMethod but tcInstType (zipEqual "newMethodAtLoc" tyvars tys) rho `thenNF_Tc` \ rho_ty -> tcGetUnique `thenNF_Tc` \ new_uniq -> let - meth_inst = Method new_uniq (RealId real_id) tys rho_ty orig loc + (theta, tau) = splitRhoTy rho_ty + meth_inst = Method new_uniq (RealId real_id) tys theta tau orig loc in returnNF_Tc (meth_inst, instToId meth_inst) @@ -273,27 +282,15 @@ newOverloadedLit orig lit ty -- The general case \begin{code} instToId :: Inst s -> TcIdOcc s instToId (Dict u clas ty orig loc) - = TcId (mkInstId u (mkDictTy clas ty) (mkLocalName u str loc)) + = TcId (mkUserLocal occ u (mkDictTy clas ty) loc) where - str = VarOcc (SLIT("d.") _APPEND_ (occNameString (getOccName clas))) + occ = VarOcc (SLIT("d.") _APPEND_ (occNameString (getOccName clas))) -instToId (Method u id tys rho_ty orig loc) - = TcId (mkInstId u tau_ty (mkLocalName u occ loc)) - where - occ = getOccName id - (_, tau_ty) = splitRhoTy rho_ty - -- I hope we don't need tcSplitRhoTy... - -- NB The method Id has just the tau type +instToId (Method u id tys theta tau orig loc) + = TcId (mkUserLocal (getOccName id) u tau loc) instToId (LitInst u list ty orig loc) - = TcId (mkInstId u ty (mkSysLocalName u SLIT("lit") loc)) -\end{code} - -\begin{code} -instType :: Inst s -> TcType s -instType (Dict _ clas ty _ _) = mkDictTy clas ty -instType (LitInst _ _ ty _ _) = ty -instType (Method _ id tys ty _ _) = ty + = TcId (mkSysLocal SLIT("lit") u ty loc) \end{code} @@ -309,10 +306,11 @@ zonkInst (Dict u clas ty orig loc) = zonkTcType ty `thenNF_Tc` \ new_ty -> returnNF_Tc (Dict u clas new_ty orig loc) -zonkInst (Method u id tys rho orig loc) -- Doesn't zonk the id! +zonkInst (Method u id tys theta tau orig loc) -- Doesn't zonk the id! = mapNF_Tc zonkTcType tys `thenNF_Tc` \ new_tys -> - zonkTcType rho `thenNF_Tc` \ new_rho -> - returnNF_Tc (Method u id new_tys new_rho orig loc) + zonkTcTheta theta `thenNF_Tc` \ new_theta -> + zonkTcType tau `thenNF_Tc` \ new_tau -> + returnNF_Tc (Method u id new_tys new_theta new_tau orig loc) zonkInst (LitInst u lit ty orig loc) = zonkTcType ty `thenNF_Tc` \ new_ty -> @@ -322,8 +320,8 @@ zonkInst (LitInst u lit ty orig loc) \begin{code} tyVarsOfInst :: Inst s -> TcTyVarSet s -tyVarsOfInst (Dict _ _ ty _ _) = tyVarsOfType ty -tyVarsOfInst (Method _ id tys rho _ _) = tyVarsOfTypes tys `unionTyVarSets` tcIdTyVars id +tyVarsOfInst (Dict _ _ ty _ _) = tyVarsOfType ty +tyVarsOfInst (Method _ id tys _ _ _ _) = tyVarsOfTypes tys `unionTyVarSets` tcIdTyVars id -- The id might not be a RealId; in the case of -- locally-overloaded class methods, for example tyVarsOfInst (LitInst _ _ ty _ _) = tyVarsOfType ty @@ -338,7 +336,7 @@ matchesInst :: Inst s -> Inst s -> Bool matchesInst (Dict _ clas1 ty1 _ _) (Dict _ clas2 ty2 _ _) = clas1 == clas2 && ty1 `eqSimpleTy` ty2 -matchesInst (Method _ id1 tys1 _ _ _) (Method _ id2 tys2 _ _ _) +matchesInst (Method _ id1 tys1 _ _ _ _) (Method _ id2 tys2 _ _ _ _) = id1 == id2 && and (zipWith eqSimpleTy tys1 tys2) && length tys1 == length tys2 @@ -402,7 +400,7 @@ pprInst sty (LitInst u lit ty orig loc) pprInst sty (Dict u clas ty orig loc) = hsep [ppr sty clas, pprParendGenType sty ty, show_uniq sty u] -pprInst sty (Method u id tys rho orig loc) +pprInst sty (Method u id tys _ _ orig loc) = hsep [ppr sty id, ptext SLIT("at"), interppSP sty tys, show_uniq sty u] @@ -478,9 +476,8 @@ lookupInst dict@(Dict _ clas ty orig loc) -- Methods -lookupInst inst@(Method _ id tys rho orig loc) - = tcSplitRhoTy rho `thenNF_Tc` \ (theta, _) -> - newDictsAtLoc orig loc theta `thenNF_Tc` \ (dicts, dict_ids) -> +lookupInst inst@(Method _ id tys theta _ orig loc) + = newDictsAtLoc orig loc theta `thenNF_Tc` \ (dicts, dict_ids) -> returnTc (dicts, VarMonoBind (instToId inst) (mkHsDictApp (mkHsTyApp (HsVar id) tys) dict_ids)) -- Literals @@ -671,9 +668,9 @@ pprOrigin sty inst = hsep [text "arising from", pp_orig orig, text "at", ppr sty locn] where (orig, locn) = case inst of - Dict _ _ _ orig loc -> (orig,loc) - Method _ _ _ _ orig loc -> (orig,loc) - LitInst _ _ _ orig loc -> (orig,loc) + Dict _ _ _ orig loc -> (orig,loc) + Method _ _ _ _ _ orig loc -> (orig,loc) + LitInst _ _ _ orig loc -> (orig,loc) pp_orig (OccurrenceOf id) = hsep [ptext SLIT("use of"), ppr sty id] diff --git a/ghc/compiler/typecheck/TcBinds.lhs b/ghc/compiler/typecheck/TcBinds.lhs index 7486de561537..30500ba58ed2 100644 --- a/ghc/compiler/typecheck/TcBinds.lhs +++ b/ghc/compiler/typecheck/TcBinds.lhs @@ -29,10 +29,10 @@ import TcHsSyn ( SYN_IE(TcHsBinds), SYN_IE(TcMonoBinds), ) import TcMonad -import Inst ( Inst, SYN_IE(LIE), emptyLIE, plusLIE, InstOrigin(..), - newDicts, tyVarsOfInst, instToId +import Inst ( Inst, SYN_IE(LIE), emptyLIE, plusLIE, plusLIEs, InstOrigin(..), + newDicts, tyVarsOfInst, instToId, newMethodWithGivenTy ) -import TcEnv ( tcExtendLocalValEnv, tcLookupLocalValueOK, newMonoIds, +import TcEnv ( tcExtendLocalValEnv, tcLookupLocalValueOK, newLocalId, tcGetGlobalTyVars, tcExtendGlobalTyVars ) import SpecEnv ( SpecEnv ) @@ -44,13 +44,13 @@ import TcSimplify ( bindInstsOfLocalFuns ) import TcType ( TcIdOcc(..), SYN_IE(TcIdBndr), SYN_IE(TcType), SYN_IE(TcThetaType), SYN_IE(TcTauType), SYN_IE(TcTyVarSet), SYN_IE(TcTyVar), - newTyVarTy, zonkTcType, zonkSigTyVar, + newTyVarTy, zonkTcType, zonkTcTheta, zonkSigTyVar, newTcTyVar, tcInstSigType, newTyVarTys ) import Unify ( unifyTauTy, unifyTauTyLists ) import Kind ( isUnboxedTypeKind, mkTypeKind, isTypeKind, mkBoxedTypeKind ) -import Id ( GenId, idType, mkUserLocal, mkUserId ) +import Id ( GenId, idType, mkUserId ) import IdInfo ( noIdInfo ) import Maybes ( maybeToBool, assocMaybe, catMaybes ) import Name ( getOccName, getSrcLoc, Name ) @@ -230,11 +230,12 @@ tcBindWithSigs binder_names mbind tc_ty_sigs is_rec prag_info_fn -- Create a new identifier for each binder, with each being given -- a fresh unique, and a type-variable type. - tcGetUniques no_of_binders `thenNF_Tc` \ uniqs -> - mapNF_Tc mk_mono_id_ty binder_names `thenNF_Tc` \ mono_id_tys -> + -- For "mono_lies" see comments about polymorphic recursion at the + -- end of the function. + mapAndUnzipNF_Tc mk_mono_id binder_names `thenNF_Tc` \ (mono_lies, mono_ids) -> let - mono_ids = zipWith3Equal "tcBindAndSigs" mk_id binder_names uniqs mono_id_tys - mk_id name uniq ty = mkUserLocal (getOccName name) uniq ty (getSrcLoc name) + mono_lie = plusLIEs mono_lies + mono_id_tys = map idType mono_ids in -- TYPECHECK THE BINDINGS @@ -251,10 +252,12 @@ tcBindWithSigs binder_names mbind tc_ty_sigs is_rec prag_info_fn getTyVarsToGen is_unrestricted mono_id_tys lie `thenTc` \ (tyvars_not_to_gen, tyvars_to_gen) -> -- DEAL WITH TYPE VARIABLE KINDS - mapTc defaultUncommittedTyVar (tyVarSetToList tyvars_to_gen) `thenTc` \ real_tyvars_to_gen_list -> + mapTc defaultUncommittedTyVar + (tyVarSetToList tyvars_to_gen) `thenTc` \ real_tyvars_to_gen_list -> let real_tyvars_to_gen = mkTyVarSet real_tyvars_to_gen_list - -- It's important that the final list (real_tyvars_to_gen and real_tyvars_to_gen_list) is fully + -- It's important that the final list + -- (real_tyvars_to_gen and real_tyvars_to_gen_list) is fully -- zonked, *including boxity*, because they'll be included in the forall types of -- the polymorphic Ids, and instances of these Ids will be generated from them. -- @@ -268,21 +271,30 @@ tcBindWithSigs binder_names mbind tc_ty_sigs is_rec prag_info_fn tcExtendGlobalTyVars tyvars_not_to_gen ( if null tc_ty_sigs then -- No signatures, so just simplify the lie + -- NB: no signatures => no polymorphic recursion, so no + -- need to use mono_lies (which will be empty anyway) tcSimplify real_tyvars_to_gen lie `thenTc` \ (lie_free, dict_binds, lie_bound) -> returnTc (lie_free, dict_binds, map instToId (bagToList lie_bound)) else - zonk_theta sig_theta `thenNF_Tc` \ sig_theta' -> + zonkTcTheta sig_theta `thenNF_Tc` \ sig_theta' -> newDicts SignatureOrigin sig_theta' `thenNF_Tc` \ (dicts_sig, dict_ids) -> -- It's important that sig_theta is zonked, because -- dict_id is later used to form the type of the polymorphic thing, -- and forall-types must be zonked so far as their bound variables -- are concerned + let + -- The "givens" is the stuff available. We get that from + -- the context of the type signature, BUT ALSO the mono_lie + -- so that polymorphic recursion works right (see comments at end of fn) + givens = dicts_sig `plusLIE` mono_lie + in + -- Check that the needed dicts can be expressed in -- terms of the signature ones tcAddErrCtxt (sigsCtxt tysig_names) $ - tcSimplifyAndCheck real_tyvars_to_gen dicts_sig lie `thenTc` \ (lie_free, dict_binds) -> + tcSimplifyAndCheck real_tyvars_to_gen givens lie `thenTc` \ (lie_free, dict_binds) -> returnTc (lie_free, dict_binds, dict_ids) ) `thenTc` \ (lie_free, dict_binds, dicts_bound) -> @@ -326,23 +338,86 @@ tcBindWithSigs binder_names mbind tc_ty_sigs is_rec prag_info_fn where no_of_binders = length binder_names - mk_mono_id_ty binder_name = case maybeSig tc_ty_sigs binder_name of - Just (TySigInfo name _ _ _ tau_ty _) -> returnNF_Tc tau_ty -- There's a signature - otherwise -> newTyVarTy kind -- No signature + mk_mono_id binder_name + | theres_a_signature -- There's a signature; and it's overloaded, + && not (null sig_theta) -- so make a Method + = tcAddSrcLoc sig_loc $ + newMethodWithGivenTy SignatureOrigin + (TcId poly_id) (mkTyVarTys sig_tyvars) + sig_theta sig_tau `thenNF_Tc` \ (mono_lie, TcId mono_id) -> + -- A bit turgid to have to strip the TcId + returnNF_Tc (mono_lie, mono_id) + + | otherwise -- No signature or not overloaded; + = tcAddSrcLoc (getSrcLoc binder_name) $ + (if theres_a_signature then + returnNF_Tc sig_tau -- Non-overloaded signature; use its type + else + newTyVarTy kind -- No signature; use a new type variable + ) `thenNF_Tc` \ mono_id_ty -> + + newLocalId (getOccName binder_name) mono_id_ty `thenNF_Tc` \ mono_id -> + returnNF_Tc (emptyLIE, mono_id) + where + maybe_sig = maybeSig tc_ty_sigs binder_name + theres_a_signature = maybeToBool maybe_sig + Just (TySigInfo name poly_id sig_tyvars sig_theta sig_tau sig_loc) = maybe_sig tysig_names = [name | (TySigInfo name _ _ _ _ _) <- tc_ty_sigs] is_unrestricted = isUnRestrictedGroup tysig_names mbind kind | is_rec = mkBoxedTypeKind -- Recursive, so no unboxed types | otherwise = mkTypeKind -- Non-recursive, so we permit unboxed types - -zonk_theta theta = mapNF_Tc zonk theta - where - zonk (c,t) = zonkTcType t `thenNF_Tc` \ t' -> - returnNF_Tc (c,t') \end{code} -@getImplicitStuffToGen@ decides what type variables generalise over. +Polymorphic recursion +~~~~~~~~~~~~~~~~~~~~~ +The game plan for polymorphic recursion in the code above is + + * Bind any variable for which we have a type signature + to an Id with a polymorphic type. Then when type-checking + the RHSs we'll make a full polymorphic call. + +This fine, but if you aren't a bit careful you end up with a horrendous +amount of partial application and (worse) a huge space leak. For example: + + f :: Eq a => [a] -> [a] + f xs = ...f... + +If we don't take care, after typechecking we get + + f = /\a -> \d::Eq a -> let f' = f a d + in + \ys:[a] -> ...f'... + +Notice the the stupid construction of (f a d), which is of course +identical to the function we're executing. In this case, the +polymorphic recursion ins't being used (but that's a very common case). + +This can lead to a massive space leak, from the following top-level defn: + + ff :: [Int] -> [Int] + ff = f dEqInt + +Now (f dEqInt) evaluates to a lambda that has f' as a free variable; but +f' is another thunk which evaluates to the same thing... and you end +up with a chain of identical values all hung onto by the CAF ff. + +Solution: when typechecking the RHSs we always have in hand the +*monomorphic* Ids for each binding. So we just need to make sure that +if (Method f a d) shows up in the constraints emerging from (...f...) +we just use the monomorphic Id. We achieve this by adding monomorphic Ids +to the "givens" when simplifying constraints. Thats' what the "mono_lies" +is doing. + + +%************************************************************************ +%* * +\subsection{getTyVarsToGen} +%* * +%************************************************************************ + +@getTyVarsToGen@ decides what type variables generalise over. For a "restricted group" -- see the monomorphism restriction for a definition -- we bind no dictionaries, and diff --git a/ghc/compiler/typecheck/TcExpr.lhs b/ghc/compiler/typecheck/TcExpr.lhs index 6f2475852051..dbf3e6b5f6dc 100644 --- a/ghc/compiler/typecheck/TcExpr.lhs +++ b/ghc/compiler/typecheck/TcExpr.lhs @@ -754,8 +754,8 @@ tcId name else -- Yes, it's overloaded newMethodWithGivenTy (OccurrenceOf tc_id_occ) - tc_id_occ arg_tys rho `thenNF_Tc` \ (lie1, meth_id) -> - instantiate_it meth_id tau `thenNF_Tc` \ (expr, lie2, final_tau) -> + tc_id_occ arg_tys theta tau `thenNF_Tc` \ (lie1, meth_id) -> + instantiate_it meth_id tau `thenNF_Tc` \ (expr, lie2, final_tau) -> returnNF_Tc (expr, lie1 `plusLIE` lie2, final_tau) where diff --git a/ghc/compiler/typecheck/TcInstUtil.lhs b/ghc/compiler/typecheck/TcInstUtil.lhs index 0bebb37ab914..e8235cf4c0c4 100644 --- a/ghc/compiler/typecheck/TcInstUtil.lhs +++ b/ghc/compiler/typecheck/TcInstUtil.lhs @@ -32,7 +32,7 @@ import Id ( GenId, mkDictFunId, mkSysLocal, SYN_IE(Id) ) import MatchEnv ( nullMEnv, insertMEnv ) import Maybes ( MaybeErr(..), mkLookupFunDef ) import Name ( getSrcLoc, Name{--O only-} ) -import PprType ( GenClass, GenType, GenTyVar ) +import PprType ( GenClass, GenType, GenTyVar, pprParendType ) import Pretty import SpecEnv ( SpecEnv, nullSpecEnv, addOneToSpecEnv ) import SrcLoc ( SrcLoc ) @@ -209,7 +209,7 @@ dupInstFailure clas info1@(ty1, locn1) info2@(ty2, locn2) failTc (\sty -> ptext SLIT("Duplicate or overlapping instance declarations")) where ctxt sty = sep [hsep [ptext SLIT("for"), - pprQuote sty $ \ sty -> ppr sty clas <+> ppr sty ty1], + pprQuote sty $ \ sty -> ppr sty clas <+> pprParendType sty ty1], nest 4 (sep [ptext SLIT("at") <+> ppr sty locn1, ptext SLIT("and") <+> ppr sty locn2])] \end{code} diff --git a/ghc/compiler/typecheck/TcMonad.lhs b/ghc/compiler/typecheck/TcMonad.lhs index 8f81f0b59a65..a04c032d2b8c 100644 --- a/ghc/compiler/typecheck/TcMonad.lhs +++ b/ghc/compiler/typecheck/TcMonad.lhs @@ -432,7 +432,10 @@ tcGetDefaultTys down env = returnSST (getDefaultTys down) tcSetDefaultTys :: [Type] -> TcM s r -> TcM s r tcSetDefaultTys tys m down env = m (setDefaultTys down tys) env -tcAddSrcLoc :: SrcLoc -> TcM s a -> TcM s a +-- tcAddSrcLoc :: SrcLoc -> TcM s a -> TcM s a +-- tcAddSrcLoc :: SrcLoc -> NF_TcM s a -> NF_TcM s a +tcAddSrcLoc :: SrcLoc -> (TcDown s -> env -> result) + -> (TcDown s -> env -> result) tcAddSrcLoc loc m down env = m (setLoc down loc) env tcGetSrcLoc :: NF_TcM s SrcLoc diff --git a/ghc/compiler/typecheck/TcSimplify.lhs b/ghc/compiler/typecheck/TcSimplify.lhs index 14a82abe3b3d..e2737adef4d2 100644 --- a/ghc/compiler/typecheck/TcSimplify.lhs +++ b/ghc/compiler/typecheck/TcSimplify.lhs @@ -577,7 +577,7 @@ bindInstsOfLocalFuns :: LIE s -> [TcIdBndr s] -> TcM s (LIE s, TcMonoBinds s) bindInstsOfLocalFuns init_lie local_ids = foldrTc bind_inst (emptyBag, EmptyMonoBinds) (bagToList init_lie) where - bind_inst inst@(Method uniq (TcId id) tys rho orig loc) (insts, binds) + bind_inst inst@(Method uniq (TcId id) tys _ _ orig loc) (insts, binds) | id `is_elem` local_ids = lookupInst inst `thenTc` \ (dict_insts, bind) -> returnTc (listToBag dict_insts `plusLIE` insts, diff --git a/ghc/compiler/typecheck/TcType.lhs b/ghc/compiler/typecheck/TcType.lhs index a4b7474e96f4..3c10a45ad677 100644 --- a/ghc/compiler/typecheck/TcType.lhs +++ b/ghc/compiler/typecheck/TcType.lhs @@ -28,7 +28,7 @@ module TcType ( tcInstTheta, tcInstId, zonkTcTyVars, zonkSigTyVar, - zonkTcType, + zonkTcType, zonkTcTheta, zonkTcTypeToType, zonkTcTyVar, zonkTcTyVarToTyVar @@ -458,4 +458,10 @@ zonkTcType (FunTy ty1 ty2 u) zonkTcType (DictTy c ty u) = zonkTcType ty `thenNF_Tc` \ ty' -> returnNF_Tc (DictTy c ty' u) + + +zonkTcTheta theta = mapNF_Tc zonk theta + where + zonk (c,t) = zonkTcType t `thenNF_Tc` \ t' -> + returnNF_Tc (c,t') \end{code} -- GitLab