#define WARN(e,msg)
#endif
+-- temporary usage assertion control KSW 2000-10
+#ifdef DO_USAGES
+#define UASSERT(e) ASSERT(e)
+#define UASSERT2(e,msg) ASSERT2(e,msg)
+#else
+#define UASSERT(e)
+#define UASSERT2(e,msg)
+#endif
+
#if __STDC__
#define CAT2(a,b)a##b
#else
setIdArityInfo,
setIdDemandInfo,
setIdStrictness,
+ setIdTyGenInfo,
setIdWorkerInfo,
setIdSpecialisation,
setIdCafInfo,
idFlavour,
idDemandInfo,
idStrictness,
+ idTyGenInfo,
idWorkerInfo,
idUnfolding,
idSpecialisation,
)
import VarSet
import Type ( Type, tyVarsOfType, typePrimRep, addFreeTyVars,
- seqType, splitTyConApp_maybe )
+ usOnce, seqType, splitTyConApp_maybe )
import IdInfo
import Demand ( Demand )
import Name ( Name, OccName,
mkSysLocalName, mkLocalName,
- isUserExportedName, getOccName, isIPOcc
+ isUserExportedName, nameIsLocallyDefined,
+ getOccName, isIPOcc
)
import OccName ( UserFS )
import PrimRep ( PrimRep )
import SrcLoc ( SrcLoc )
import Unique ( Unique, mkBuiltinUnique, getBuiltinUniques,
getNumBuiltinUniques )
+import Outputable
infixl 1 `setIdUnfolding`,
`setIdArityInfo`,
`setIdDemandInfo`,
`setIdStrictness`,
+ `setIdTyGenInfo`,
`setIdWorkerInfo`,
`setIdSpecialisation`,
`setInlinePragma`,
\begin{code}
omitIfaceSigForId :: Id -> Bool
omitIfaceSigForId id
- | otherwise
+ = ASSERT2( not (omit && nameIsLocallyDefined (idName id)
+ && idTyGenInfo id /= TyGenNever),
+ ppr id )
+ -- mustn't omit type signature for a name whose type might change!
+ omit
+ where
+ omit = omitIfaceSigForId' id
+
+omitIfaceSigForId' id
= case idFlavour id of
RecordSelId _ -> True -- Includes dictionary selectors
PrimOpId _ -> True
isBottomingId id = isBottomingStrictness (idStrictness id)
---------------------------------
+ -- TYPE GENERALISATION
+idTyGenInfo :: Id -> TyGenInfo
+idTyGenInfo id = tyGenInfo (idInfo id)
+
+setIdTyGenInfo :: Id -> TyGenInfo -> Id
+setIdTyGenInfo id tygen_info = modifyIdInfo (`setTyGenInfo` tygen_info) id
+
+ ---------------------------------
-- WORKER ID
idWorkerInfo :: Id -> WorkerInfo
idWorkerInfo id = workerInfo (idInfo id)
idLBVarInfo id = lbvarInfo (idInfo id)
isOneShotLambda :: Id -> Bool
-isOneShotLambda id = case idLBVarInfo id of
- IsOneShotLambda -> True
- NoLBVarInfo -> case splitTyConApp_maybe (idType id) of
- Just (tycon,_) -> tycon == statePrimTyCon
- other -> False
+isOneShotLambda id = analysis || hack
+ where analysis = case idLBVarInfo id of
+ LBVarInfo u | u == usOnce -> True
+ other -> False
+ hack = case splitTyConApp_maybe (idType id) of
+ Just (tycon,_) | tycon == statePrimTyCon -> True
+ other -> False
+
-- The last clause is a gross hack. It claims that
-- every function over realWorldStatePrimTy is a one-shot
-- function. This is pretty true in practice, and makes a big
-- spot that fill_in has arity 2 (and when Keith is done, we will) but we can't yet.
setOneShotLambda :: Id -> Id
-setOneShotLambda id = modifyIdInfo (`setLBVarInfo` IsOneShotLambda) id
+setOneShotLambda id = modifyIdInfo (`setLBVarInfo` LBVarInfo usOnce) id
clearOneShotLambda :: Id -> Id
clearOneShotLambda id
zapLamIdInfo id = maybeModifyIdInfo zapLamInfo id
\end{code}
-
-
-
-
-
-
-
-
-
-
StrictnessInfo(..),
mkStrictnessInfo, noStrictnessInfo,
ppStrictnessInfo,isBottomingStrictness,
-
strictnessInfo, setStrictnessInfo,
+ -- Usage generalisation
+ TyGenInfo(..),
+ tyGenInfo, setTyGenInfo,
+ noTyGenInfo, isNoTyGenInfo, ppTyGenInfo, tyGenInfoString,
+
-- Worker
WorkerInfo(..), workerExists, wrapperArity, workerId,
workerInfo, setWorkerInfo, ppWorkerInfo,
import CoreSyn
+import Type ( Type, usOnce )
import PrimOp ( PrimOp )
import Var ( Id )
import BasicTypes ( OccInfo(..), isFragileOcc, isDeadOcc, seqOccInfo, isLoopBreaker,
)
import DataCon ( DataCon )
import FieldLabel ( FieldLabel )
+import Type ( usOnce, usMany )
import Demand -- Lots of stuff
import Outputable
+import Util ( seqList )
infixl 1 `setDemandInfo`,
+ `setTyGenInfo`,
`setStrictnessInfo`,
`setSpecInfo`,
`setArityInfo`,
`setUnfoldingInfo`,
`setCprInfo`,
`setWorkerInfo`,
+ `setLBVarInfo`,
`setCafInfo`,
`setOccInfo`
-- infixl so you can say (id `set` a `set` b)
arityInfo :: ArityInfo, -- Its arity
demandInfo :: Demand, -- Whether or not it is definitely demanded
specInfo :: CoreRules, -- Specialisations of this function which exist
+ tyGenInfo :: TyGenInfo, -- Restrictions on usage-generalisation of this Id
strictnessInfo :: StrictnessInfo, -- Strictness properties
workerInfo :: WorkerInfo, -- Pointer to Worker Function
unfoldingInfo :: Unfolding, -- Its unfolding
seqArity (arityInfo info) `seq`
seqDemand (demandInfo info) `seq`
seqRules (specInfo info) `seq`
+ seqTyGenInfo (tyGenInfo info) `seq`
seqStrictnessInfo (strictnessInfo info) `seq`
seqWorker (workerInfo info) `seq`
\begin{code}
setWorkerInfo info wk = wk `seq` info { workerInfo = wk }
setSpecInfo info sp = PSEQ sp (info { specInfo = sp })
+setTyGenInfo info tg = tg `seq` info { tyGenInfo = tg }
setInlinePragInfo info pr = pr `seq` info { inlinePragInfo = pr }
setOccInfo info oc = oc `seq` info { occInfo = oc }
setStrictnessInfo info st = st `seq` info { strictnessInfo = st }
arityInfo = UnknownArity,
demandInfo = wwLazy,
specInfo = emptyCoreRules,
+ tyGenInfo = noTyGenInfo,
workerInfo = NoWorker,
strictnessInfo = NoStrictnessInfo,
unfoldingInfo = noUnfolding,
%************************************************************************
+%* *
+\subsection[TyGen-IdInfo]{Type generalisation info about an @Id@}
+%* *
+%************************************************************************
+
+Certain passes (notably usage inference) may change the type of an
+identifier, modifying all in-scope uses of that identifier
+appropriately to maintain type safety.
+
+However, some identifiers must not have their types changed in this
+way, because their types are conjured up in the front end of the
+compiler rather than being read from the interface file. Default
+methods, dictionary functions, record selectors, and others are in
+this category. (see comment at TcClassDcl.tcClassSig).
+
+To indicate this property, such identifiers are marked TyGenNever.
+
+Furthermore, if the usage inference generates a usage-specialised
+variant of a function, we must NOT re-infer a fully-generalised type
+at the next inference. This finer property is indicated by a
+TyGenUInfo on the identifier.
+
+\begin{code}
+data TyGenInfo
+ = NoTyGenInfo -- no restriction on type generalisation
+
+ | TyGenUInfo [Maybe Type] -- restrict generalisation of this Id to
+ -- preserve specified usage annotations
+
+ | TyGenNever -- never generalise the type of this Id
+
+ deriving ( Eq )
+\end{code}
+
+For TyGenUInfo, the list has one entry for each usage annotation on
+the type of the Id, in left-to-right pre-order (annotations come
+before the type they annotate). Nothing means no restriction; Just
+usOnce or Just usMany forces that annotation to that value. Other
+usage annotations are illegal.
+
+\begin{code}
+seqTyGenInfo :: TyGenInfo -> ()
+seqTyGenInfo NoTyGenInfo = ()
+seqTyGenInfo (TyGenUInfo us) = seqList us ()
+seqTyGenInfo TyGenNever = ()
+
+noTyGenInfo :: TyGenInfo
+noTyGenInfo = NoTyGenInfo
+
+isNoTyGenInfo :: TyGenInfo -> Bool
+isNoTyGenInfo NoTyGenInfo = True
+isNoTyGenInfo _ = False
+
+-- NB: There's probably no need to write this information out to the interface file.
+-- Why? Simply because imported identifiers never get their types re-inferred.
+-- But it's definitely nice to see in dumps, it for debugging purposes.
+
+ppTyGenInfo :: TyGenInfo -> SDoc
+ppTyGenInfo NoTyGenInfo = empty
+ppTyGenInfo (TyGenUInfo us) = ptext SLIT("__G") <+> text (tyGenInfoString us)
+ppTyGenInfo TyGenNever = ptext SLIT("__G N")
+
+tyGenInfoString us = map go us
+ where go Nothing = 'x' -- for legibility, choose
+ go (Just u) | u == usOnce = '1' -- chars with identity
+ | u == usMany = 'M' -- Z-encoding.
+ go other = pprPanic "IdInfo.tyGenInfoString: unexpected annotation" (ppr other)
+
+instance Outputable TyGenInfo where
+ ppr = ppTyGenInfo
+
+instance Show TyGenInfo where
+ showsPrec p c = showsPrecSDoc p (ppr c)
+\end{code}
+
+
+%************************************************************************
%* *
\subsection[worker-IdInfo]{Worker info about an @Id@}
%* *
data LBVarInfo
= NoLBVarInfo
- | IsOneShotLambda -- The lambda that binds this Id is applied
- -- at most once
+ | LBVarInfo Type -- The lambda that binds this Id has this usage
+ -- annotation (i.e., if ==usOnce, then the
+ -- lambda is applied at most once).
+ -- The annotation's kind must be `$'
-- HACK ALERT! placing this info here is a short-term hack,
-- but it minimises changes to the rest of the compiler.
-- Hack agreed by SLPJ/KSW 1999-04.
-- not safe to print or parse LBVarInfo because it is not really a
-- property of the definition, but a property of the context.
pprLBVarInfo NoLBVarInfo = empty
-pprLBVarInfo IsOneShotLambda = getPprStyle $ \ sty ->
- if ifaceStyle sty then empty
- else ptext SLIT("OneShot")
+pprLBVarInfo (LBVarInfo u) | u == usOnce
+ = getPprStyle $ \ sty ->
+ if ifaceStyle sty
+ then empty
+ else ptext SLIT("OneShot")
+ | otherwise
+ = empty
instance Outputable LBVarInfo where
ppr = pprLBVarInfo
import Type ( Type, ThetaType, mkDictTy, mkDictTys, mkTyConApp, mkTyVarTys,
mkFunTys, mkFunTy, mkSigmaTy,
isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType,
- splitFunTys, splitForAllTys, unUsgTy,
- mkUsgTy, UsageAnn(..)
+ splitFunTys, splitForAllTys
)
import Module ( Module )
import CoreUtils ( exprType, mkInlineMe )
)
import IdInfo ( IdInfo, vanillaIdInfo, mkIdInfo,
exactArity, setUnfoldingInfo, setCafInfo, setCprInfo,
- setArityInfo, setSpecInfo,
+ setArityInfo, setSpecInfo, setTyGenInfo,
mkStrictnessInfo, setStrictnessInfo,
- IdFlavour(..), CafInfo(..), CprInfo(..)
+ IdFlavour(..), CafInfo(..), CprInfo(..), TyGenInfo(..)
)
import FieldLabel ( mkFieldLabel, fieldLabelName,
firstFieldLabelTag, allFieldLabelTags, fieldLabelType
-- Maybe a SysLocal? But then we'd lose the location
mkDefaultMethodId dm_name rec_c ty
- = mkVanillaId dm_name ty
+ = mkId dm_name ty info
+ where
+ info = vanillaIdInfo `setTyGenInfo` TyGenNever
+ -- type is wired-in (see comment at TcClassDcl.tcClassSig), so
+ -- do not generalise it
mkWorkerId uniq unwrkr ty
= mkVanillaId (mkDerivedName mkWorkerOcc (getName unwrkr) uniq) ty
-- The wrapper Id ends up in STG code as an argument,
-- sometimes before its definition, so we want to
-- signal that it has no CAFs
+ `setTyGenInfo` TyGenNever
+ -- No point generalising its type, since it gets eagerly inlined
+ -- away anyway
wrap_ty = mkForAllTys all_tyvars $
mkFunTys all_arg_tys
`setArityInfo` exactArity (1 + length dict_tys)
`setUnfoldingInfo` unfolding
`setCafInfo` NoCafRefs
+ `setTyGenInfo` TyGenNever
-- ToDo: consider adding further IdInfo
unfolding = mkTopUnfolding sel_rhs
mkLams dict_ids $ Lam data_id $
sel_body
- sel_body | isNewTyCon tycon = Note (Coerce (unUsgTy field_tau) (unUsgTy data_ty)) (Var data_id)
+ sel_body | isNewTyCon tycon = Note (Coerce field_tau data_ty) (Var data_id)
| otherwise = Case (Var data_id) data_id (the_alts ++ default_alt)
mk_maybe_alt data_con
maybe_the_arg_id = assocMaybe (field_lbls `zip` arg_ids) field_label
field_lbls = dataConFieldLabels data_con
- error_expr = mkApps (Var rEC_SEL_ERROR_ID) [Type (unUsgTy field_tau), err_string]
- -- preserves invariant that type args are *not* usage-annotated on top. KSW 1999-04.
+ error_expr = mkApps (Var rEC_SEL_ERROR_ID) [Type field_tau, err_string]
err_string
| all safeChar full_msg
= App (Var unpack_id) (Lit (MachStr (_PK_ full_msg)))
`setArityInfo` exactArity 1
`setUnfoldingInfo` unfolding
`setCafInfo` NoCafRefs
+ `setTyGenInfo` TyGenNever
-- We no longer use 'must-inline' on record selectors. They'll
-- inline like crazy if they scrutinise a constructor
-> Id
mkDictFunId dfun_name clas inst_tyvars inst_tys dfun_theta
- = mkVanillaId dfun_name dfun_ty
+ = mkId dfun_name dfun_ty info
where
dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
+ info = vanillaIdInfo `setTyGenInfo` TyGenNever
+ -- type is wired-in (see comment at TcClassDcl.tcClassSig), so
+ -- do not generalise it
{- 1 dec 99: disable the Mark Jones optimisation for the sake
of compatibility with Hugs.
openBetaTy = mkTyVarTy openBetaTyVar
errorTy :: Type
-errorTy = mkUsgTy UsMany $
- mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkUsgTy UsOnce (mkListTy charTy)]
- (mkUsgTy UsMany openAlphaTy))
+errorTy = mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkListTy charTy]
+ openAlphaTy)
-- Notice the openAlphaTyVar. It says that "error" can be applied
-- to unboxed as well as boxed types. This is OK because it never
-- returns, so the return type is irrelevant.
module OccName (
-- The NameSpace type; abstact
NameSpace, tcName, clsName, tcClsName, dataName, varName, ipName,
- tvName, uvName, nameSpaceString,
+ tvName, nameSpaceString,
-- The OccName type
OccName, -- Abstract, instance of Outputable
mkDerivedTyConOcc, mkClassTyConOcc, mkClassDataConOcc, mkSpecOcc,
mkGenOcc1, mkGenOcc2,
- isSysOcc, isTvOcc, isUvOcc, isDataOcc, isDataSymOcc, isSymOcc, isIPOcc, isValOcc,
+ isSysOcc, isTvOcc, isDataOcc, isDataSymOcc, isSymOcc, isIPOcc, isValOcc,
occNameFS, occNameString, occNameUserString, occNameSpace, occNameFlavour,
setOccNameSpace,
| IPName -- Implicit Parameters
| DataName -- Data constructors
| TvName -- Type variables
- | UvName -- Usage variables
| TcClsName -- Type constructors and classes; Haskell has them
-- in the same name space for now.
deriving( Eq, Ord )
dataName = DataName
tvName = TvName
-uvName = UvName
varName = VarName
ipName = IPName
nameSpaceString VarName = "Variable"
nameSpaceString IPName = "Implicit Param"
nameSpaceString TvName = "Type variable"
-nameSpaceString UvName = "Usage variable"
nameSpaceString TcClsName = "Type constructor or class"
\end{code}
-- But then alreadyEncoded complains about the braces!
mkCCallOcc str = OccName varName (_PK_ str)
--- Kind constructors get a speical function. Uniquely, they are not encoded,
+-- Kind constructors get a special function. Uniquely, they are not encoded,
-- so that they have names like '*'. This means that *even in interface files*
-- we'll get kinds like (* -> (* -> *)). We can't use mkSysOcc because it
-- has an ASSERT that doesn't hold.
\end{code}
\begin{code}
-isTvOcc, isDataSymOcc, isSymOcc, isUvOcc :: OccName -> Bool
+isTvOcc, isDataSymOcc, isSymOcc :: OccName -> Bool
isTvOcc (OccName TvName _) = True
isTvOcc other = False
-isUvOcc (OccName UvName _) = True
-isUvOcc other = False
-
isValOcc (OccName VarName _) = True
isValOcc (OccName DataName _) = True
isValOcc other = False
-- Used by Name
1 type Id = Var ;
1 type TyVar = Var ;
-1 type UVar = Var ;
1 data Var ;
1 setIdName _:_ Id -> Name.Name -> Id ;;
-- Used by Name
1 type Id = Var;
1 type TyVar = Var;
-1 type UVar = Var;
1 data Var ;
1 setIdName :: Id -> Name.Name -> Id ;
newMutTyVar, newSigTyVar,
readMutTyVar, writeMutTyVar, isMutTyVar, makeTyVarImmutable,
- -- UVars
- UVar,
- isUVar,
- mkUVar, mkNamedUVar,
-
-- Ids
Id, DictId,
idName, idType, idUnique, idInfo, modifyIdInfo, maybeModifyIdInfo,
| MutTyVar (IORef (Maybe Type)) -- Used during unification;
Bool -- True <=> this is a type signature variable, which
-- should not be unified with a non-tyvar type
- | UVar -- Usage variable
-- For a long time I tried to keep mutable Vars statically type-distinct
-- from immutable Vars, but I've finally given up. It's just too painful.
%************************************************************************
%* *
-\subsection{Usage variables}
-%* *
-%************************************************************************
-
-\begin{code}
-type UVar = Var
-\end{code}
-
-\begin{code}
-mkUVar :: Unique -> UVar
-mkUVar unique = Var { varName = name
- , realUnique = getKey unique
- , varDetails = UVar
- , varType = pprPanic "mkUVar (varType)" (ppr name)
- , varInfo = pprPanic "mkUVar (varInfo)" (ppr name)
- }
- where name = mkSysLocalName unique SLIT("u")
-
-mkNamedUVar :: Name -> UVar
-mkNamedUVar name = Var { varName = name
- , realUnique = getKey (nameUnique name)
- , varDetails = UVar
- , varType = pprPanic "mkNamedUVar (varType)" (ppr name)
- , varInfo = pprPanic "mkNamedUVar (varInfo)" (ppr name)
- }
-\end{code}
-
-\begin{code}
-isUVar :: Var -> Bool
-isUVar (Var {varDetails = details}) = case details of
- UVar -> True
- other -> False
-\end{code}
-
-
-%************************************************************************
-%* *
\subsection{Id Construction}
%* *
%************************************************************************
\begin{code}
module VarSet (
- VarSet, IdSet, TyVarSet, UVarSet,
+ VarSet, IdSet, TyVarSet,
emptyVarSet, unitVarSet, mkVarSet,
extendVarSet, extendVarSet_C,
elemVarSet, varSetElems, subVarSet,
#include "HsVersions.h"
-import Var ( Var, Id, TyVar, UVar )
+import Var ( Var, Id, TyVar )
import Unique ( Unique )
import UniqSet
import UniqFM ( delFromUFM_Directly, addToUFM_C )
type VarSet = UniqSet Var
type IdSet = UniqSet Id
type TyVarSet = UniqSet TyVar
-type UVarSet = UniqSet UVar
emptyVarSet :: VarSet
intersectVarSet :: VarSet -> VarSet -> VarSet
%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
-% $Id: CgCase.lhs,v 1.47 2000/11/07 13:12:22 simonpj Exp $
+% $Id: CgCase.lhs,v 1.48 2000/11/07 15:21:39 simonmar Exp $
%
%********************************************************
%* *
freeStackSlots [slot] `thenC`
returnFC (CCallProfCCMacro SLIT("RESTORE_CCCS") [CVal sp_rel CostCentreRep])
-- we use the RESTORE_CCCS macro, rather than just
- -- assigning into CurCostCentre, in case RESTORE_CCC
+ -- assigning into CurCostCentre, in case RESTORE_CCCS
-- has some sanity-checking in it.
\end{code}
import CostCentre ( CostCentre, noCostCentre )
import Var ( Var, Id, TyVar, isTyVar, isId )
-import Type ( Type, UsageAnn, mkTyVarTy, seqType )
+import Type ( Type, mkTyVarTy, seqType )
import Literal ( Literal, mkMachInt )
import DataCon ( DataCon, dataConId )
import VarSet
| InlineMe -- Instructs simplifer to treat the enclosed expression
-- as very small, and inline it at its call sites
-
- | TermUsg -- A term-level usage annotation
- UsageAnn -- (should not be a variable except during UsageSP inference)
\end{code}
megaSeqIdInfo )
import Demand ( appIsBottom )
import Type ( Type, mkFunTy, mkForAllTy,
- splitFunTy_maybe,
- isNotUsgTy, mkUsgTy, unUsgTy, UsageAnn(..),
- applyTys, isUnLiftedType, seqType
+ splitFunTy_maybe, tyVarsOfType, tyVarsOfTypes,
+ applyTys, isUnLiftedType, seqType,
+ mkUTy
)
import TysWiredIn ( boolTy, trueDataCon, falseDataCon )
import CostCentre ( CostCentre )
exprType (Let _ body) = exprType body
exprType (Case _ _ alts) = coreAltsType alts
exprType (Note (Coerce ty _) e) = ty -- **! should take usage from e
-exprType (Note (TermUsg u) e) = mkUsgTy u (unUsgTy (exprType e))
exprType (Note other_note e) = exprType e
exprType (Lam binder expr) = mkPiType binder (exprType expr)
exprType e@(App _ _)
\begin{code}
mkPiType :: Var -> Type -> Type -- The more polymorphic version doesn't work...
mkPiType v ty | isId v = (case idLBVarInfo v of
- IsOneShotLambda -> mkUsgTy UsOnce
- otherwise -> id) $
+ LBVarInfo u -> mkUTy u
+ otherwise -> id) $
mkFunTy (idType v) ty
| isTyVar v = mkForAllTy v ty
\end{code}
applyTypeToArgs e op_ty (Type ty : args)
= -- Accumulate type arguments so we can instantiate all at once
- ASSERT2( all isNotUsgTy tys,
- ppr e <+> text "of" <+> ppr op_ty <+> text "to" <+>
- ppr (Type ty : args) <+> text "i.e." <+> ppr tys )
applyTypeToArgs e (applyTys op_ty tys) rest_args
where
(tys, rest_args) = go [ty] args
noteSize (Coerce t1 t2) = seqType t1 `seq` seqType t2 `seq` 1
noteSize InlineCall = 1
noteSize InlineMe = 1
-noteSize (TermUsg usg) = usg `seq` 1
varSize :: Var -> Int
varSize b | isTyVar b = 1
arityInfo, ppArityInfo, ppFlavourInfo, flavourInfo,
specInfo, cprInfo, ppCprInfo,
strictnessInfo, ppStrictnessInfo, cafInfo, ppCafInfo,
- workerInfo, ppWorkerInfo
+ cprInfo, ppCprInfo, lbvarInfo,
+ workerInfo, ppWorkerInfo,
+ tyGenInfo, ppTyGenInfo
)
import DataCon ( dataConTyCon )
import TyCon ( tupleTyConBoxity, isTupleTyCon )
ppr_expr add_par pe (Note InlineMe expr)
= add_par $ ptext SLIT("__inline_me") <+> ppr_parend_expr pe expr
-ppr_expr add_par pe (Note (TermUsg u) expr)
- = getPprStyle $ \ sty ->
- if ifaceStyle sty then
- ppr_expr add_par pe expr
- else
- add_par (ppr u <+> ppr_noparend_expr pe expr)
-
ppr_case_pat pe con@(DataAlt dc) args
| isTupleTyCon tc
= tupleParens (tupleTyConBoxity tc) (hsep (punctuate comma (map ppr_bndr args))) <+> arrow
= hsep [
ppFlavourInfo (flavourInfo info),
ppArityInfo a,
+ ppTyGenInfo g,
ppWorkerInfo (workerInfo info),
ppStrictnessInfo s,
ppCafInfo c,
]
where
a = arityInfo info
+ g = tyGenInfo info
s = strictnessInfo info
c = cafInfo info
m = cprInfo info
isEmptyCoreRules, seqRules
)
import CoreFVs ( exprFreeVars, mustHaveLocalBinding )
-import TypeRep ( Type(..), TyNote(..),
- ) -- friend
+import TypeRep ( Type(..), TyNote(..) ) -- friend
import Type ( ThetaType, PredType(..), ClassContext,
- tyVarsOfType, tyVarsOfTypes, mkAppTy
+ tyVarsOfType, tyVarsOfTypes, mkAppTy, mkUTy, isUTy
)
import VarSet
import VarEnv
import Var ( setVarUnique, isId )
-import Id ( idType, setIdType, idOccInfo, zapFragileIdInfo )
+import Id ( idType, setIdType, idOccInfo, zapFragileIdInfo, maybeModifyIdInfo )
import IdInfo ( IdInfo, isFragileOcc,
specInfo, setSpecInfo,
- WorkerInfo(..), workerExists, workerInfo, setWorkerInfo, WorkerInfo
+ WorkerInfo(..), workerExists, workerInfo, setWorkerInfo, WorkerInfo,
+ lbvarInfo, LBVarInfo(..), setLBVarInfo
)
import Unique ( Uniquable(..), deriveUnique )
import UniqSet ( elemUniqSet_Directly )
zapSubstEnv (Subst in_scope env) = Subst in_scope emptySubstEnv
extendSubst :: Subst -> Var -> SubstResult -> Subst
-extendSubst (Subst in_scope env) v r = Subst in_scope (extendSubstEnv env v r)
+extendSubst (Subst in_scope env) v r = UASSERT( case r of { DoneTy ty -> not (isUTy ty) ; _ -> True } )
+ Subst in_scope (extendSubstEnv env v r)
extendSubstList :: Subst -> [Var] -> [SubstResult] -> Subst
-extendSubstList (Subst in_scope env) v r = Subst in_scope (extendSubstEnvList env v r)
+extendSubstList (Subst in_scope env) v r = UASSERT( all (\ r1 -> case r1 of { DoneTy ty -> not (isUTy ty) ; _ -> True }) r )
+ Subst in_scope (extendSubstEnvList env v r)
lookupSubst :: Subst -> Var -> Maybe SubstResult
lookupSubst (Subst _ env) v = lookupSubstEnv env v
mkTopTyVarSubst tyvars tys = Subst emptyInScopeSet (zip_ty_env tyvars tys emptySubstEnv)
zip_ty_env [] [] env = env
-zip_ty_env (tv:tvs) (ty:tys) env = zip_ty_env tvs tys (extendSubstEnv env tv (DoneTy ty))
+zip_ty_env (tv:tvs) (ty:tys) env = UASSERT( not (isUTy ty) )
+ zip_ty_env tvs tys (extendSubstEnv env tv (DoneTy ty))
\end{code}
substTy works with general Substs, so that it can be called from substExpr too.
go (NoteTy (SynNote ty1) ty2) = NoteTy (SynNote $! (go ty1)) $! (go ty2)
go (NoteTy (FTVNote _) ty2) = go ty2 -- Discard the free tyvar note
- go (NoteTy (UsgNote usg) ty2) = (NoteTy $! UsgNote usg) $! go ty2 -- Keep usage annot
- go (NoteTy (UsgForAll uv) ty2) = (NoteTy $! UsgForAll uv) $! go ty2 -- Keep uvar bdr
go (FunTy arg res) = (FunTy $! (go arg)) $! (go res)
go (AppTy fun arg) = mkAppTy (go fun) $! (go arg)
go (ForAllTy tv ty) = case substTyVar subst tv of
(subst', tv') -> ForAllTy tv' $! (subst_ty subst' ty)
+
+ go (UsageTy u ty) = mkUTy (go u) $! (go ty)
\end{code}
Here is where we invent a new binder if necessary.
-- id2 has its IdInfo zapped
id2 = zapFragileIdInfo id1
- -- new_id is cloned if necessary
- new_id = uniqAway in_scope id2
+ -- id3 has its LBVarInfo zapped
+ id3 = maybeModifyIdInfo (\ info -> go info (lbvarInfo info)) id2
+ where go info (LBVarInfo u@(TyVarTy _)) = Just $ setLBVarInfo info $
+ LBVarInfo (subst_ty subst u)
+ go info _ = Nothing
+ -- new_id is cloned if necessary
+ new_id = uniqAway in_scope id3
-- Extend the substitution if the unique has changed,
-- or there's some useful occurrence information
-- See the notes with substTyVar for the delSubstEnv
get_unused_cons used_cons = unused_cons
where
(ConPat _ ty _ _ _) = head used_cons
- Just (ty_con,_) = splitTyConApp_maybe ty
+ Just (ty_con,_) = sTyConApp_maybe used_cons ty
all_cons = tyConDataCons ty_con
used_cons_as_id = map (\ (ConPat d _ _ _ _) -> d) used_cons
unused_cons = uniqSetToList
(mkUniqSet all_cons `minusUniqSet` mkUniqSet used_cons_as_id)
+sTyConApp_maybe used_cons ty =
+ case splitTyConApp_maybe ty of
+ Just x -> Just x
+ Nothing -> pprTrace "splitTyConApp_maybe" (ppr (used_cons, ty)) $ Nothing
all_vars :: [TypecheckedPat] -> Bool
all_vars [] = True
import Literal ( Literal(..) )
import Type ( splitFunTys,
splitAlgTyConApp, splitAlgTyConApp_maybe, splitTyConApp_maybe,
- isNotUsgTy, unUsgTy,
splitAppTy, isUnLiftedType, Type
)
import TysWiredIn ( tupleCon, listTyCon, charDataCon, intDataCon, isIntegerTy )
go [] = returnDs (mkNilExpr ty)
go (x:xs) = dsExpr x `thenDs` \ core_x ->
go xs `thenDs` \ core_xs ->
- ASSERT( isNotUsgTy ty )
returnDs (mkConsExpr ty core_x core_xs)
dsExpr (ExplicitTuple expr_list boxity)
= mapDs dsExpr expr_list `thenDs` \ core_exprs ->
returnDs (mkConApp (tupleCon boxity (length expr_list))
- (map (Type . unUsgTy . exprType) core_exprs ++ core_exprs))
- -- the above unUsgTy is *required* -- KSW 1999-04-07
+ (map (Type . exprType) core_exprs ++ core_exprs))
dsExpr (ArithSeqOut expr (From from))
= dsExpr expr `thenDs` \ expr2 ->
go (GuardStmt expr locn : stmts)
= do_expr expr locn `thenDs` \ expr2 ->
go stmts `thenDs` \ rest ->
- let msg = ASSERT( isNotUsgTy b_ty )
- "Pattern match failure in do expression, " ++ showSDoc (ppr locn)
+ let msg = "Pattern match failure in do expression, " ++ showSDoc (ppr locn)
in
mkStringLit msg `thenDs` \ core_msg ->
returnDs (mkIfThenElse expr2
(_, a_ty) = splitAppTy (exprType expr2) -- Must be of form (m a)
fail_expr = HsApp (TyApp (HsVar fail_id) [b_ty])
(HsLit (HsString (_PK_ msg)))
- msg = ASSERT2( isNotUsgTy a_ty, ppr a_ty )
- ASSERT2( isNotUsgTy b_ty, ppr b_ty )
- "Pattern match failure in do expression, " ++ showSDoc (ppr locn)
+ msg = "Pattern match failure in do expression, " ++ showSDoc (ppr locn)
main_match = mkSimpleMatch [pat]
(HsDoOut do_or_lc stmts return_id then_id
fail_id result_ty locn)
mkForeignExportOcc, isLocalName,
NamedThing(..),
)
-import Type ( unUsgTy, repType,
+import Type ( repType,
splitTyConApp_maybe, splitFunTys, splitForAllTys,
Type, mkFunTys, mkForAllTys, mkTyConApp,
mkFunTy, splitAppTy, applyTy, funResultTy
import PrimOp ( CCall(..), CCallTarget(..), dynamicTarget )
import TysWiredIn ( unitTy, addrTy, stablePtrTyCon )
import TysPrim ( addrPrimTy )
-import PrelNames ( hasKey, ioTyConKey, deRefStablePtrName,
- bindIOName, returnIOName, makeStablePtrName
+import PrelNames ( hasKey, ioTyConKey, deRefStablePtrName, newStablePtrName,
+ bindIOName, returnIOName
)
import Outputable
f :: (Addr -> Int -> IO Int) -> IO Addr
f cback =
- bindIO (makeStablePtr cback)
+ bindIO (newStablePtr cback)
(\StablePtr sp# -> IO (\s1# ->
case _ccall_ createAdjustor cconv sp# ``f_helper'' s1# of
(# s2#, a# #) -> (# s2#, A# a# #)))
dsFExport i export_ty mod_name fe_ext_name cconv True
`thenDs` \ (feb, fe, h_code, c_code) ->
newSysLocalDs arg_ty `thenDs` \ cback ->
- dsLookupGlobalValue makeStablePtrName `thenDs` \ makeStablePtrId ->
+ dsLookupGlobalValue newStablePtrName `thenDs` \ newStablePtrId ->
let
- mk_stbl_ptr_app = mkApps (Var makeStablePtrId) [ Type arg_ty, Var cback ]
+ mk_stbl_ptr_app = mkApps (Var newStablePtrId) [ Type arg_ty, Var cback ]
in
dsLookupGlobalValue bindIOName `thenDs` \ bindIOId ->
newSysLocalDs (mkTyConApp stablePtrTyCon [arg_ty]) `thenDs` \ stbl_value ->
dsCCall adjustor adj_args False False io_res_ty `thenDs` \ ccall_adj ->
let ccall_adj_ty = exprType ccall_adj
ccall_io_adj = mkLams [stbl_value] $
- Note (Coerce io_res_ty (unUsgTy ccall_adj_ty))
+ Note (Coerce io_res_ty ccall_adj_ty)
ccall_adj
in
let io_app = mkLams tvs $
unpackHObj t = text "rts_get" <> text (showFFIType t)
showStgType :: Type -> SDoc
-showStgType t = text "Stg" <> text (showFFIType t)
+showStgType t = text "Hs" <> text (showFFIType t)
showFFIType :: Type -> String
showFFIType t = getOccString (getName tc)
import {-# SOURCE #-} DsExpr ( dsExpr, dsLet )
-import HsSyn ( Stmt(..) )
+import BasicTypes ( Boxity(..) )
+import HsSyn ( OutPat(..), HsExpr(..), Stmt(..) )
import TcHsSyn ( TypecheckedStmt )
import DsHsSyn ( outPatType )
import CoreSyn
import Var ( Id )
import Type ( mkTyVarTy, mkFunTys, mkFunTy, Type )
import TysPrim ( alphaTyVar )
-import TysWiredIn ( nilDataCon, consDataCon )
+import TysWiredIn ( nilDataCon, consDataCon, unitDataConId, tupleCon, mkListTy, mkTupleTy )
import Match ( matchSimply )
import PrelNames ( foldrName, buildName )
+import List ( zip4 )
\end{code}
List comprehensions may be desugared in one of two ways: ``ordinary''
is the TE translation scheme. Note that we carry around the @L@ list
already desugared. @dsListComp@ does the top TE rule mentioned above.
+To the above, we add an additional rule to deal with parallel list
+comprehensions. The translation goes roughly as follows:
+ [ e | p1 <- e11, let v1 = e12, p2 <- e13
+ | q1 <- e21, let v2 = e22, q2 <- e23]
+ =>
+ [ e | ((p1,v1,p2), (q1,v2,q2)) <-
+ zip [(p1,v1,p2) | p1 <- e11, let v1 = e12, p2 <- e13]
+ [(q1,v2,q2) | q1 <- e21, let v2 = e22, q2 <- e23]]
+In the translation below, the ParStmtOut branch translates each parallel branch
+into a sub-comprehension, and desugars each independently. The resulting lists
+are fed to a zip function, we create a binding for all the variables bound in all
+the comprehensions, and then we hand things off the the desugarer for bindings.
+The zip function is generated here a) because it's small, and b) because then we
+don't have to deal with arbitrary limits on the number of zip functions in the
+prelude, nor which library the zip function came from.
+The introduced tuples are Boxed, but only because I couldn't get it to work
+with the Unboxed variety.
\begin{code}
+
deListComp :: [TypecheckedStmt] -> CoreExpr -> DsM CoreExpr
+deListComp (ParStmtOut bndrstmtss : quals) list
+ = mapDs doListComp qualss `thenDs` \ exps ->
+ mapDs genAS bndrss `thenDs` \ ass ->
+ mapDs genA bndrss `thenDs` \ as ->
+ mapDs genAS' bndrss `thenDs` \ as's ->
+ let retTy = myTupleTy Boxed (length bndrss) qualTys
+ zipTy = foldr mkFunTy (mkListTy retTy) (map mkListTy qualTys)
+ in
+ newSysLocalDs zipTy `thenDs` \ zipFn ->
+ let target = mkConsExpr retTy (mkTupleExpr as) (foldl App (Var zipFn) (map Var as's))
+ zipExp = mkLet zipFn (zip4 (map fst bndrstmtss) ass as as's) exps target
+ in
+ deBindComp pat zipExp quals list
+ where (bndrss, stmtss) = unzip bndrstmtss
+ pats = map (\ps -> mkTuplePat (map VarPat ps)) bndrss
+ mkTuplePat [p] = p
+ mkTuplePat ps = TuplePat ps Boxed
+ pat = TuplePat pats Boxed
+
+ qualss = map mkQuals bndrstmtss
+ mkQuals (bndrs, stmts) = (bndrs, stmts ++ [ReturnStmt (myTupleExpr bndrs)])
+
+ qualTys = map mkBndrsTy bndrss
+ mkBndrsTy bndrs = myTupleTy Boxed (length bndrs) (map idType bndrs)
+
+ doListComp (bndrs, stmts)
+ = dsListComp stmts (mkBndrsTy bndrs)
+ genA bndrs = newSysLocalDs (mkBndrsTy bndrs)
+ genAS bndrs = newSysLocalDs (mkListTy (mkBndrsTy bndrs))
+ genAS' bndrs = newSysLocalDs (mkListTy (mkBndrsTy bndrs))
+
+ mkLet zipFn vars exps target
+ = Let (Rec [(zipFn,
+ foldr Lam (mkBody target vars) (map getAs vars))])
+ (foldl App (Var zipFn) exps)
+ getAs (_, as, _, _) = as
+ mkBody target vars
+ = foldr mkCase (foldr mkTuplCase target vars) vars
+ mkCase (ps, as, a, as') rest
+ = Case (Var as) as [(DataAlt nilDataCon, [], mkConApp nilDataCon []),
+ (DataAlt consDataCon, [a, as'], rest)]
+ mkTuplCase ([p], as, a, as') rest
+ = App (Lam p rest) (Var a)
+ mkTuplCase (ps, as, a, as') rest
+ = Case (Var a) a [(DataAlt (tupleCon Boxed (length ps)), ps, rest)]
+
+ myTupleTy boxity arity [ty] = ty
+ myTupleTy boxity arity tys = mkTupleTy boxity arity tys
+ myTupleExpr [] = HsVar unitDataConId
+ myTupleExpr [id] = HsVar id
+ myTupleExpr ids = ExplicitTuple [ HsVar i | i <- ids ] Boxed
+
deListComp [ReturnStmt expr] list -- Figure 7.4, SLPJ, p 135, rule C above
= dsExpr expr `thenDs` \ core_expr ->
returnDs (mkConsExpr (exprType core_expr) core_expr list)
deListComp (BindStmt pat list1 locn : quals) core_list2 -- rule A' above
= dsExpr list1 `thenDs` \ core_list1 ->
- let
+ deBindComp pat core_list1 quals core_list2
+
+deBindComp pat core_list1 quals core_list2
+ = let
u3_ty@u1_ty = exprType core_list1 -- two names, same thing
-- u1_ty is a [alpha] type, and u2_ty = alpha
import DataCon ( DataCon, StrictnessMark, maybeMarkedUnboxed,
dataConStrictMarks, dataConId, splitProductType_maybe
)
-import Type ( mkFunTy, isUnLiftedType, splitAlgTyConApp, unUsgTy,
+import Type ( mkFunTy, isUnLiftedType, splitAlgTyConApp,
Type
)
import TysPrim ( intPrimTy, charPrimTy, floatPrimTy, doublePrimTy )
-- Stuff for newtype
(_, arg_ids, match_result) = head match_alts
arg_id = head arg_ids
- coercion_bind = NonRec arg_id (Note (Coerce (unUsgTy (idType arg_id))
- (unUsgTy scrut_ty))
+ coercion_bind = NonRec arg_id (Note (Coerce (idType arg_id)
+ scrut_ty)
(Var var))
newtype_sanity = null (tail match_alts) && null (tail arg_ids)
full_msg = showSDoc (hcat [ppr src_loc, text "|", text msg])
in
mkStringLit full_msg `thenDs` \ core_msg ->
- returnDs (mkApps (Var err_id) [(Type . unUsgTy) ty, core_msg])
- -- unUsgTy *required* -- KSW 1999-04-07
+ returnDs (mkApps (Var err_id) [Type ty, core_msg])
\end{code}
@mkTupleExpr@ builds a tuple; the inverse to @mkTupleSelector@. If it
-has only one element, it is the identity function. Notice we must
-throw out any usage annotation on the outside of an Id.
+has only one element, it is the identity function.
\begin{code}
mkTupleExpr :: [Id] -> CoreExpr
mkTupleExpr [] = Var unitDataConId
mkTupleExpr [id] = Var id
mkTupleExpr ids = mkConApp (tupleCon Boxed (length ids))
- (map (Type . unUsgTy . idType) ids ++ [ Var i | i <- ids ])
+ (map (Type . idType) ids ++ [ Var i | i <- ids ])
\end{code}
#include "HsVersions.h"
-#if __GLASGOW_HASKELL__ <= 408
-
-import Panic ( panic )
-import RdrName ( RdrName )
-import PrelAddr ( Addr )
-import FiniteMap ( FiniteMap )
-import InterpSyn ( HValue )
-
-type ItblEnv = FiniteMap RdrName Addr
-type ClosureEnv = FiniteMap RdrName HValue
-linkIModules = panic "StgInterp.linkIModules: this hsc was not built with an interpreter"
-stgToInterpSyn = panic "StgInterp.linkIModules: this hsc was not built with an interpreter"
-
-#else
-
import Linker
import Id ( Id, idPrimRep )
import Outputable
-- indexPtrOffClosure#, indexWordOffClosure# )
import PrelAddr ( Addr(..) )
import PrelFloat ( Float(..), Double(..) )
-import Word
import Bits
-import Storable
-import CTypes
import FastString
import GlaExts ( Int(..) )
import Module ( moduleNameFS )
import Panic ( panic )
import OccName ( occNameString )
+import Foreign
+import CTypes
-- ---------------------------------------------------------------------------
-- Environments needed by the linker
-- ---------------------------------------------------------------------------
-type ItblEnv = FiniteMap RdrName Addr
+type ItblEnv = FiniteMap RdrName (Ptr StgInfoTable)
type ClosureEnv = FiniteMap RdrName HValue
-- ---------------------------------------------------------------------------
-- Addr#. So, copy the string into C land and introduce a
-- memory leak at the same time.
let n = I# l in
- case unsafePerformIO (do a <- malloc (n+1);
+ case unsafePerformIO (do a <- mallocBytes (n+1);
strncpy a ba (fromIntegral n);
- writeCharOffAddr a n '\0'
- return a)
+ pokeByteOff a n '\0'
+ case a of { Ptr a -> return a })
of A# a -> LitI (addr2Int# a)
_ -> error "StgInterp.lit2expr: unhandled string constant type"
lookupCon ie con =
case lookupFM ie con of
- Just addr -> addr
+ Just (Ptr addr) -> addr
Nothing ->
-- try looking up in the object files.
case {-HACK!!!-}
--- Manufacturing of info tables for DataCons defined in this module ---
------------------------------------------------------------------------
+#if __GLASGOW_HASKELL__ <= 408
+type ItblPtr = Addr
+#else
+type ItblPtr = Ptr StgInfoTable
+#endif
+
-- Make info tables for the data decls in this module
mkITbls :: [TyCon] -> IO ItblEnv
mkITbls [] = return emptyFM
mk_dirret_itbl (dcon, conNo)
= mk_itbl dcon conNo mci_constr_entry
- mk_itbl :: DataCon -> Int -> Addr -> IO (RdrName,Addr)
+ mk_itbl :: DataCon -> Int -> Addr -> IO (RdrName,ItblPtr)
mk_itbl dcon conNo entry_addr
= let (tot_wds, ptr_wds, _)
= mkVirtHeapOffsets typePrimRep (dataConRepArgTys dcon)
entry_addr_w :: Word32
entry_addr_w = fromIntegral (addrToInt entry_addr)
in
- do addr <- mallocElem itbl
+ do addr <- malloc
putStrLn ("SIZE of itbl is " ++ show (sizeOf itbl))
putStrLn ("# ptrs of itbl is " ++ show ptrs)
putStrLn ("# nptrs of itbl is " ++ show nptrs)
poke addr itbl
- return (toRdrName dcon, intToAddr (addrToInt addr + 8))
+ return (toRdrName dcon, addr `plusPtr` 8)
byte :: Int -> Word32 -> Word32
fieldAl code4, fieldAl code5, fieldAl code6, fieldAl code7]
poke a0 itbl
- = do a1 <- store (ptrs itbl) a0
+ = do a1 <- store (ptrs itbl) (castPtr a0)
a2 <- store (nptrs itbl) a1
a3 <- store (tipe itbl) a2
a4 <- store (srtlen itbl) a3
return ()
peek a0
- = do (a1,ptrs) <- load a0
+ = do (a1,ptrs) <- load (castPtr a0)
(a2,nptrs) <- load a1
(a3,tipe) <- load a2
(a4,srtlen) <- load a3
fieldAl :: (Storable a, Storable b) => (a -> b) -> a -> Int
fieldAl sel x = alignment (sel x)
-store :: Storable a => a -> Addr -> IO Addr
+store :: Storable a => a -> Ptr a -> IO (Ptr b)
store x addr = do poke addr x
- return (addr `plusAddr` fromIntegral (sizeOf x))
+ return (castPtr (addr `plusPtr` sizeOf x))
-load :: Storable a => Addr -> IO (Addr, a)
+load :: Storable a => Ptr a -> IO (Ptr b, a)
load addr = do x <- peek addr
- return (addr `plusAddr` fromIntegral (sizeOf x), x)
+ return (castPtr (addr `plusPtr` sizeOf x), x)
-----------------------------------------------------------------------------q
-foreign import "strncpy" strncpy :: Addr -> ByteArray# -> CInt -> IO ()
-
-#endif /* #if __GLASGOW_HASKELL__ <= 408 */
+foreign import "strncpy" strncpy :: Ptr a -> ByteArray# -> CInt -> IO ()
\end{code}
UfBinding(..), UfConAlt(..),
HsIdInfo(..), pprHsIdInfo,
- eq_ufExpr, eq_ufBinders, pprUfExpr,
+ eq_ufExpr, eq_ufBinders, pprUfExpr, pprHsIdInfo,
toUfExpr, toUfBndr, ufBinderName
) where
-- friends:
import HsTypes ( HsType, pprParendHsType, pprHsTyVarBndr, toHsType,
- HsTupCon(..), hsTupParens,
+ HsTupCon(..), EqHsEnv, hsTupParens,
emptyEqHsEnv, extendEqHsEnv, eqListBy,
- eq_hsType, eq_hsVar, eq_hsVars
+ eq_hsType, eq_hsVars
)
-- others:
import IdInfo ( ArityInfo, InlinePragInfo,
pprInlinePragInfo, ppArityInfo, ppStrictnessInfo
)
-import Name ( Name, getName )
+import Name ( Name, NamedThing(..), getName, toRdrName )
+import RdrName ( RdrName, rdrNameOcc )
+import OccName ( isTvOcc )
import CoreSyn
import CostCentre ( pprCostCentreCore )
import PrimOp ( PrimOp(CCallOp) )
import DataCon ( dataConTyCon )
import TyCon ( isTupleTyCon, tupleTyConBoxity )
import Type ( Kind )
+import FiniteMap ( lookupFM )
import CostCentre
import Outputable
\end{code}
%************************************************************************
\begin{code}
-instance Outputable name => Outputable (UfExpr name) where
+instance (NamedThing name, Outputable name) => Outputable (UfExpr name) where
ppr e = pprUfExpr noParens e
+
+-- Small-hack alert: this instance allows us to do a getOccName on RdrNames.
+-- Important because we want to pretty-print UfExprs, and we have to
+-- print an '@' before tyvar-binders in a case alternative.
+instance NamedThing RdrName where
+ getOccName n = rdrNameOcc n
+ getName n = pprPanic "instance NamedThing RdrName" (ppr n)
+
noParens :: SDoc -> SDoc
noParens pp = pp
-pprUfExpr :: Outputable name => (SDoc -> SDoc) -> UfExpr name -> SDoc
+pprUfExpr :: (NamedThing name, Outputable name) => (SDoc -> SDoc) -> UfExpr name -> SDoc
-- The function adds parens in context that need
-- an atomic value (e.g. function args)
braces (hsep (map pp_alt alts))])
where
pp_alt (UfTupleAlt tup_con, bs, rhs) = hsTupParens tup_con (interpp'SP bs) <+> ppr_rhs rhs
- pp_alt (c, bs, rhs) = ppr c <+> interppSP bs <+> ppr_rhs rhs
+ pp_alt (c, bs, rhs) = ppr c <+> hsep (map pp_bndr bs) <+> ppr_rhs rhs
ppr_rhs rhs = ptext SLIT("->") <+> pprUfExpr noParens rhs <> semi
+ -- This use of getOccName is the sole reason for the NamedThing in pprUfExpr's type
+ pp_bndr v | isTvOcc (getOccName v) = char '@' <+> ppr v
+ | otherwise = ppr v
+
pprUfExpr add_par (UfLet (UfNonRec b rhs) body)
= add_par (hsep [ptext SLIT("let"),
braces (ppr b <+> equals <+> pprUfExpr noParens rhs),
pprUfExpr add_par (UfNote note body) = add_par (ppr note <+> pprUfExpr parens body)
+
collectUfBndrs :: UfExpr name -> ([UfBinder name], UfExpr name)
collectUfBndrs expr
= go [] expr
%* *
%************************************************************************
+ ----------------------------------------
+ HACK ALERT
+ ----------------------------------------
+
+Whe comparing UfExprs, we compare names by converting to RdrNames and comparing
+those. Reason: this is used when comparing ufoldings in interface files, and the
+uniques can differ. Converting to RdrNames makes it more like comparing the file
+contents directly. But this is bad: version numbers can change when only alpha-conversion
+has happened.
+
+ The hack shows up in eq_ufVar
+ There are corresponding getOccName calls in MkIface.diffDecls
+
+ ----------------------------------------
+ END OF HACK ALERT
+ ----------------------------------------
+
+
\begin{code}
-instance Ord name => Eq (UfExpr name) where
+instance (NamedThing name, Ord name) => Eq (UfExpr name) where
(==) a b = eq_ufExpr emptyEqHsEnv a b
-----------------
eq_ufBinders env _ _ _ = False
-----------------
-eq_ufExpr env (UfVar v1) (UfVar v2) = eq_hsVar env v1 v2
+eq_ufVar :: (NamedThing name, Ord name) => EqHsEnv name -> name -> name -> Bool
+-- Compare *Rdr* names. A real hack to avoid gratuitous
+-- differences when comparing interface files
+eq_ufVar env n1 n2 = case lookupFM env n1 of
+ Just n1 -> toRdrName n1 == toRdrName n2
+ Nothing -> toRdrName n1 == toRdrName n2
+
+
+-----------------
+eq_ufExpr :: (NamedThing name, Ord name) => EqHsEnv name -> UfExpr name -> UfExpr name -> Bool
+eq_ufExpr env (UfVar v1) (UfVar v2) = eq_ufVar env v1 v2
eq_ufExpr env (UfLit l1) (UfLit l2) = l1 == l2
eq_ufExpr env (UfLitLit l1 ty1) (UfLitLit l2 ty2) = l1==l2 && eq_hsType env ty1 ty2
eq_ufExpr env (UfCCall c1 ty1) (UfCCall c2 ty2) = c1==c2 && eq_hsType env ty1 ty2
%************************************************************************
\begin{code}
+pprHsIdInfo :: (NamedThing n, Outputable n) => [HsIdInfo n] -> SDoc
pprHsIdInfo [] = empty
-pprHsIdInfo info = ptext SLIT("{-##") <+> hsep (map ppr info) <+> ptext SLIT("##-}")
+pprHsIdInfo info = ptext SLIT("{-##") <+> hsep (map ppr_hs_info info) <+> ptext SLIT("##-}")
data HsIdInfo name
= HsArity ArityInfo
-- NB: Specialisations and rules come in separately and are
-- only later attached to the Id. Partial reason: some are orphans.
-instance Outputable name => Outputable (HsIdInfo name) where
- ppr (HsUnfold prag unf) = ptext SLIT("__U") <> pprInlinePragInfo prag <+> parens (ppr unf)
- ppr (HsArity arity) = ppArityInfo arity
- ppr (HsStrictness str) = ptext SLIT("__S") <+> ppStrictnessInfo str
- ppr HsNoCafRefs = ptext SLIT("__C")
- ppr HsCprInfo = ptext SLIT("__M")
- ppr (HsWorker w) = ptext SLIT("__P") <+> ppr w
+ppr_hs_info (HsUnfold prag unf) = ptext SLIT("__U") <> pprInlinePragInfo prag <+> parens (pprUfExpr noParens unf)
+ppr_hs_info (HsArity arity) = ppArityInfo arity
+ppr_hs_info (HsStrictness str) = ptext SLIT("__S") <+> ppStrictnessInfo str
+ppr_hs_info HsNoCafRefs = ptext SLIT("__C")
+ppr_hs_info HsCprInfo = ptext SLIT("__M")
+ppr_hs_info (HsWorker w) = ptext SLIT("__P") <+> ppr w
\end{code}
hsDeclName, instDeclName, tyClDeclName, tyClDeclNames,
isClassDecl, isSynDecl, isDataDecl, isIfaceSigDecl, countTyClDecls,
mkClassDeclSysNames, isIfaceRuleDecl, ifaceRuleDeclName,
- getClassDeclSysNames
+ getClassDeclSysNames, conDetailsTys
) where
#include "HsVersions.h"
import CallConv ( CallConv, pprCallConv )
-- others:
+import Name ( NamedThing )
import FunDeps ( pprFundeps )
import Class ( FunDep, DefMeth(..) )
import CStrings ( CLabelString, pprCLabelString )
\begin{code}
#ifdef DEBUG
-hsDeclName :: (Outputable name, Outputable pat)
+hsDeclName :: (NamedThing name, Outputable name, Outputable pat)
=> HsDecl name pat -> name
#endif
hsDeclName (TyClD decl) = tyClDeclName decl
\end{code}
\begin{code}
-instance (Outputable name, Outputable pat)
+instance (NamedThing name, Outputable name, Outputable pat)
=> Outputable (HsDecl name pat) where
ppr (TyClD dcl) = ppr dcl
ppr (DeprecD dd) = ppr dd
\end{code}
-\begin{code}
-instance Ord name => Eq (HsDecl name pat) where
- -- Used only when comparing interfaces,
- -- at which time only signature and type/class decls
- (TyClD d1) == (TyClD d2) = d1 == d2
- _ == _ = False
-\end{code}
-
%************************************************************************
%* *
\end{code}
\begin{code}
-instance Ord name => Eq (TyClDecl name pat) where
+instance (NamedThing name, Ord name) => Eq (TyClDecl name pat) where
-- Used only when building interface files
(==) (IfaceSig n1 t1 i1 _)
(IfaceSig n2 t2 i2 _) = n1==n2 && t1==t2 && i1==i2
\end{code}
\begin{code}
-instance (Outputable name, Outputable pat)
+instance (NamedThing name, Outputable name, Outputable pat)
=> Outputable (TyClDecl name pat) where
ppr (IfaceSig var ty info _) = hsep [ppr var, dcolon, ppr ty, pprHsIdInfo info]
\end{code}
\begin{code}
+conDetailsTys :: ConDetails name -> [HsType name]
+conDetailsTys (VanillaCon btys) = map getBangType btys
+conDetailsTys (InfixCon bty1 bty2) = [getBangType bty1, getBangType bty2]
+conDetailsTys (RecCon fields) = [getBangType bty | (_, bty) <- fields]
+
+
eq_ConDecl env (ConDecl n1 _ tvs1 cxt1 cds1 _)
(ConDecl n2 _ tvs2 cxt2 cds2 _)
= n1 == n2 &&
= RuleBndr name
| RuleBndrSig name (HsType name)
-instance Ord name => Eq (RuleDecl name pat) where
+instance (NamedThing name, Ord name) => Eq (RuleDecl name pat) where
-- Works for IfaceRules only; used when comparing interface file versions
(IfaceRule n1 bs1 f1 es1 rhs1 _) == (IfaceRule n2 bs2 f2 es2 rhs2 _)
= n1==n2 && f1 == f2 &&
eq_ufBinders emptyEqHsEnv bs1 bs2 (\env ->
eqListBy (eq_ufExpr env) (rhs1:es1) (rhs2:es2))
-instance (Outputable name, Outputable pat)
+instance (NamedThing name, Outputable name, Outputable pat)
=> Outputable (RuleDecl name pat) where
ppr (HsRule name tvs ns lhs rhs loc)
= sep [text "{-# RULES" <+> doubleQuotes (ptext name),
\begin{code}
data Stmt id pat
- = BindStmt pat
+ = ParStmt [[Stmt id pat]] -- List comp only: parallel set of quals
+ | ParStmtOut [([id], [Stmt id pat])] -- PLC after renaming
+ | BindStmt pat
(HsExpr id pat)
SrcLoc
Outputable (Stmt id pat) where
ppr stmt = pprStmt stmt
+pprStmt (ParStmt stmtss)
+ = hsep (map (\stmts -> ptext SLIT("| ") <> ppr stmts) stmtss)
+pprStmt (ParStmtOut stmtss)
+ = hsep (map (\stmts -> ptext SLIT("| ") <> ppr stmts) stmtss)
pprStmt (BindStmt pat expr _)
= hsep [ppr pat, ptext SLIT("<-"), ppr expr]
pprStmt (LetStmt binds)
import BasicTypes ( Fixity, Version, NewOrData )
-- others:
+import Name ( NamedThing )
import Outputable
import SrcLoc ( SrcLoc )
import Bag
\end{code}
\begin{code}
-instance (Outputable name, Outputable pat)
+instance (NamedThing name, Outputable name, Outputable pat)
=> Outputable (HsModule name pat) where
ppr (HsModule name iface_version exports imports
\begin{code}
module HsTypes (
- HsType(..), HsUsageAnn(..), HsTyVarBndr(..),
+ HsType(..), HsTyVarBndr(..),
, HsContext, HsPred(..)
, HsTupCon(..), hsTupParens, mkHsTupCon,
+ , hsUsOnce, hsUsMany
- , mkHsForAllTy, mkHsUsForAllTy, mkHsDictTy, mkHsIParamTy
+ , mkHsForAllTy, mkHsDictTy, mkHsIParamTy
, hsTyVarName, hsTyVarNames, replaceTyVarName
-- Printing
import Class ( FunDep )
import Type ( Type, Kind, PredType(..), ClassContext,
- splitSigmaTy, unUsgTy, boxedTypeKind
+ splitSigmaTy, boxedTypeKind
)
import TypeRep ( Type(..), TyNote(..) ) -- toHsType sees the representation
-import TyCon ( isTupleTyCon, tupleTyConBoxity, tyConArity )
-import RdrName ( RdrName )
-import Name ( Name, getName )
-import OccName ( NameSpace )
+import TyCon ( isTupleTyCon, tupleTyConBoxity, tyConArity, getSynTyConDefn )
+import RdrName ( RdrName, mkUnqual )
+import Name ( Name, getName, setLocalNameSort )
+import OccName ( NameSpace, tvName )
import Var ( TyVar, tyVarKind )
+import Subst ( mkTyVarSubst, substTy )
import PprType ( {- instance Outputable Kind -}, pprParendKind )
import BasicTypes ( Boxity(..), tupleParens )
-import PrelNames ( mkTupConRdrName, listTyConKey, hasKey )
+import PrelNames ( mkTupConRdrName, listTyConKey, usOnceTyConKey, usManyTyConKey, hasKey,
+ usOnceTyConName, usManyTyConName
+ )
import FiniteMap
import Outputable
| HsNumTy Integer
-- these next two are only used in interfaces
| HsPredTy (HsPred name)
+
+ | HsUsageTy (HsType name) -- Usage annotation
+ (HsType name) -- Annotated type
- | HsUsgTy (HsUsageAnn name)
- (HsType name)
- | HsUsgForAllTy name
- (HsType name)
+-----------------------
+hsUsOnce, hsUsMany :: HsType RdrName
+hsUsOnce = HsTyVar (mkUnqual tvName SLIT(".")) -- deep magic
+hsUsMany = HsTyVar (mkUnqual tvName SLIT("!")) -- deep magic
-data HsUsageAnn name
- = HsUsOnce
- | HsUsMany
- | HsUsVar name
-
+hsUsOnce_Name, hsUsMany_Name :: HsType Name
+-- Fudge the TyConName so that it prints unqualified
+-- I hate it! I hate it!
+hsUsOnce_Name = HsTyVar (setLocalNameSort usOnceTyConName False)
+hsUsMany_Name = HsTyVar (setLocalNameSort usManyTyConName False)
-----------------------
data HsTupCon name = HsTupCon name Boxity
(Just tvs1) `plus` (Just tvs2) = Just (tvs1 ++ tvs2)
mkHsForAllTy tvs ctxt ty = HsForAllTy tvs ctxt ty
-mkHsUsForAllTy uvs ty = foldr (\ uv ty -> HsUsgForAllTy uv ty)
- ty uvs
-
mkHsDictTy cls tys = HsPredTy (HsPClass cls tys)
mkHsIParamTy v ty = HsPredTy (HsPIParam v ty)
= getPprStyle $ \ sty ->
if userStyle sty then
ptext SLIT("forall") <+> interppSP tvs <> dot <+>
+ -- **! ToDo: want to hide uvars from user, but not enough info
+ -- in a HsTyVarBndr name (see PprType). KSW 2000-10.
(if null cxt then
empty
else
\end{code}
\begin{code}
-pREC_TOP = (0 :: Int)
-pREC_FUN = (1 :: Int)
-pREC_CON = (2 :: Int)
+pREC_TOP = (0 :: Int) -- type in ParseIface.y
+pREC_FUN = (1 :: Int) -- btype in ParseIface.y
+pREC_CON = (2 :: Int) -- atype in ParseIface.y
maybeParen :: Bool -> SDoc -> SDoc
maybeParen True p = parens p
= maybeParen (ctxt_prec >= pREC_FUN) $
braces (ppr pred)
-ppr_mono_ty ctxt_prec ty@(HsUsgForAllTy _ _)
- =
- sep [ ptext SLIT("__fuall") <+> brackets pp_uvars <+> ptext SLIT("=>"),
- ppr_mono_ty pREC_TOP sigma
- ]
- where
- (uvars,sigma) = split [] ty
- pp_uvars = interppSP uvars
-
- split uvs (HsUsgForAllTy uv ty') = split (uv:uvs) ty'
- split uvs ty' = (reverse uvs,ty')
+ppr_mono_ty ctxt_prec (HsUsageTy u ty)
+ = maybeParen (ctxt_prec >= pREC_CON)
+ (sep [ptext SLIT("__u") <+> ppr_mono_ty pREC_CON u,
+ ppr_mono_ty pREC_CON ty])
+ -- pREC_FUN would be logical for u, but it yields a reduce/reduce conflict with AppTy
-ppr_mono_ty ctxt_prec (HsUsgTy u ty)
- = maybeParen (ctxt_prec >= pREC_CON) $
- ptext SLIT("__u") <+> pp_ua <+> ppr_mono_ty pREC_CON ty
- where
- pp_ua = case u of
- HsUsOnce -> ptext SLIT("-")
- HsUsMany -> ptext SLIT("!")
- HsUsVar uv -> ppr uv
-- Generics
ppr_mono_ty ctxt_prec (HsNumTy n) = integer n
ppr_mono_ty ctxt_prec (HsOpTy ty1 op ty2) = ppr ty1 <+> ppr op <+> ppr ty2
toHsTyVars tvs = map toHsTyVar tvs
toHsType :: Type -> HsType Name
-toHsType ty = toHsType' (unUsgTy ty)
- -- For now we just discard the usage
-
-toHsType' :: Type -> HsType Name
--- Called after the usage is stripped off
-- This function knows the representation of types
-toHsType' (TyVarTy tv) = HsTyVar (getName tv)
-toHsType' (FunTy arg res) = HsFunTy (toHsType arg) (toHsType res)
-toHsType' (AppTy fun arg) = HsAppTy (toHsType fun) (toHsType arg)
-
-toHsType' (NoteTy (SynNote ty) _) = toHsType ty -- Use synonyms if possible!!
-toHsType' (NoteTy _ ty) = toHsType ty
-
-toHsType' (PredTy p) = HsPredTy (toHsPred p)
-
-toHsType' ty@(TyConApp tc tys) -- Must be saturated because toHsType's arg is of kind *
- | not saturated = generic_case
- | isTupleTyCon tc = HsTupleTy (HsTupCon (getName tc) (tupleTyConBoxity tc)) tys'
- | tc `hasKey` listTyConKey = HsListTy (head tys')
- | otherwise = generic_case
+toHsType (TyVarTy tv) = HsTyVar (getName tv)
+toHsType (FunTy arg res) = HsFunTy (toHsType arg) (toHsType res)
+toHsType (AppTy fun arg) = HsAppTy (toHsType fun) (toHsType arg)
+
+toHsType (NoteTy (SynNote syn_ty) real_ty)
+ | syn_matches = toHsType syn_ty -- Use synonyms if possible!!
+ | otherwise =
+#ifdef DEBUG
+ pprTrace "WARNING: synonym info lost in .hi file for " (ppr syn_ty) $
+#endif
+ toHsType real_ty -- but drop it if not.
+ where
+ syn_matches = ty_from_syn == real_ty
+
+ TyConApp syn_tycon tyargs = syn_ty
+ (tyvars,ty) = getSynTyConDefn syn_tycon
+ ty_from_syn = substTy (mkTyVarSubst tyvars tyargs) ty
+
+ -- We only use the type synonym in the file if this doesn't cause
+ -- us to lose important information. This matters for usage
+ -- annotations. It's an issue if some of the args to the synonym
+ -- have arrows in them, or if the synonym's RHS has an arrow; for
+ -- example, with nofib/real/ebnf2ps/ in Parsers.using.
+
+ -- **! It would be nice if when this test fails we could still
+ -- write the synonym in as a Note, so we don't lose the info for
+ -- error messages, but it's too much work for right now.
+ -- KSW 2000-07.
+
+toHsType (NoteTy _ ty) = toHsType ty
+
+toHsType (PredTy p) = HsPredTy (toHsPred p)
+
+toHsType ty@(TyConApp tc tys) -- Must be saturated because toHsType's arg is of kind *
+ | not saturated = generic_case
+ | isTupleTyCon tc = HsTupleTy (HsTupCon (getName tc) (tupleTyConBoxity tc)) tys'
+ | tc `hasKey` listTyConKey = HsListTy (head tys')
+ | tc `hasKey` usOnceTyConKey = hsUsOnce_Name -- must print !, . unqualified
+ | tc `hasKey` usManyTyConKey = hsUsMany_Name -- must print !, . unqualified
+ | otherwise = generic_case
where
generic_case = foldl HsAppTy (HsTyVar (getName tc)) tys'
tys' = map toHsType tys
saturated = length tys == tyConArity tc
-toHsType' ty@(ForAllTy _ _) = case splitSigmaTy ty of
+toHsType ty@(ForAllTy _ _) = case splitSigmaTy ty of
(tvs, preds, tau) -> HsForAllTy (Just (map toHsTyVar tvs))
(map toHsPred preds)
(toHsType tau)
+toHsType (UsageTy u ty) = HsUsageTy (toHsType u) (toHsType ty)
+ -- **! consider dropping usMany annotations ToDo KSW 2000-10
+
toHsPred (Class cls tys) = HsPClass (getName cls) (map toHsType tys)
toHsPred (IParam n ty) = HsPIParam (getName n) (toHsType ty)
eq_hsType env (HsPredTy p1) (HsPredTy p2)
= eq_hsPred env p1 p2
+eq_hsType env (HsUsageTy u1 ty1) (HsUsageTy u2 ty2)
+ = eq_hsType env u1 u2 && eq_hsType env ty1 ty2
+
eq_hsType env (HsOpTy lty1 op1 rty1) (HsOpTy lty2 op2 rty2)
= eq_hsVar env op1 op2 && eq_hsType env lty1 lty2 && eq_hsType env rty1 rty2
-eq_hsType env (HsUsgTy u1 ty1) (HsUsgTy u2 ty2)
- = eqUsg u1 u2 && eq_hsType env ty1 ty2
-
eq_hsType env ty1 ty2 = False
eq_hsPred env _ _ = False
-------------------
-eqUsg HsUsOnce HsUsOnce = True
-eqUsg HsUsMany HsUsMany = True
-eqUsg (HsUsVar u1) (HsUsVar u2) = u1 == u2
-eqUsg _ _ = False
-
--------------------
eqListBy :: (a->a->Bool) -> [a] -> [a] -> Bool
eqListBy eq [] [] = True
eqListBy eq (x:xs) (y:ys) = eq x y && eqListBy eq xs ys
isStaticHscFlag,
opt_PprStyle_NoPrags,
+ opt_PprStyle_RawTypes,
opt_PprUserLength,
opt_PprStyle_Debug,
-- debugging opts
opt_PprStyle_NoPrags = lookUp SLIT("-dppr-noprags")
opt_PprStyle_Debug = lookUp SLIT("-dppr-debug")
+opt_PprStyle_RawTypes = lookUp SLIT("-dppr-rawtypes")
opt_PprUserLength = lookup_def_int "-dppr-user-length" 5 --ToDo: give this a name
-- profiling opts
import Outputable
import CmdLineOpts ( DynFlags, HscLang(..), dopt_OutName )
import TmpFiles ( newTempName )
+import UniqSupply ( mkSplitUniqSupply )
import IO ( IOMode(..), hClose, openFile, Handle )
\end{code}
| is_header = "h_stub"
| otherwise = "c_stub"
include_prefix
- | is_header = "#include \"Rts.h\"\n"
+ | is_header = "#include \"HsFFI.h\"\n"
| otherwise = "#include \"RtsAPI.h\"\n"
\end{code}
{-
-----------------------------------------------------------------------------
-$Id: Parser.y,v 1.46 2000/10/31 17:30:17 simonpj Exp $
+$Id: Parser.y,v 1.47 2000/11/07 15:21:40 simonmar Exp $
Haskell grammar.
| exp ',' exp '..' { ArithSeqIn (FromThen $1 $3) }
| exp '..' exp { ArithSeqIn (FromTo $1 $3) }
| exp ',' exp '..' exp { ArithSeqIn (FromThenTo $1 $3 $5) }
- | exp srcloc '|' quals { HsDo ListComp (reverse
- (ReturnStmt $1 : $4)) $2 }
+ | exp srcloc pquals {% let { body [qs] = qs;
+ body qss = [ParStmt (map reverse qss)] }
+ in
+ returnP ( HsDo ListComp
+ (reverse (ReturnStmt $1 : body $3))
+ $2
+ )
+ }
lexps :: { [RdrNameHsExpr] }
: lexps ',' exp { $3 : $1 }
-----------------------------------------------------------------------------
-- List Comprehensions
+pquals :: { [[RdrNameStmt]] }
+ : pquals '|' quals { $3 : $1 }
+ | '|' quals { [$2] }
+
quals :: { [RdrNameStmt] }
: quals ',' qual { $3 : $1 }
| qual { [$1] }
extract_ty (HsTupleTy _ tys) acc = foldr extract_ty acc tys
extract_ty (HsFunTy ty1 ty2) acc = extract_ty ty1 (extract_ty ty2 acc)
extract_ty (HsPredTy p) acc = extract_pred p acc
-extract_ty (HsUsgTy usg ty) acc = extract_ty ty acc
-extract_ty (HsUsgForAllTy uv ty) acc = extract_ty ty acc
extract_ty (HsTyVar tv) acc = tv : acc
extract_ty (HsForAllTy Nothing ctxt ty) acc = extract_ctxt ctxt (extract_ty ty acc)
-- Generics
#include "HsVersions.h"
import Module ( ModuleName, mkPrelModule, mkModuleName )
-import OccName ( NameSpace, UserFS, varName, dataName, tcName, clsName )
-import RdrName ( RdrName, mkOrig )
+import OccName ( NameSpace, UserFS, varName, dataName, tcName, clsName, mkKindOccFS )
+import RdrName ( RdrName, mkOrig, mkRdrOrig )
import UniqFM
import Unique ( Unique, Uniquable(..), hasKey,
mkPreludeMiscIdUnique, mkPreludeDataConUnique,
fromRationalName,
deRefStablePtrName,
- makeStablePtrName,
+ newStablePtrName,
bindIOName,
returnIOName,
mainName = varQual mAIN_Name SLIT("main") mainKey
-- Stuff from PrelGHC
-funTyConName = tcQual pREL_GHC_Name SLIT("(->)") funTyConKey
-cCallableClassName = clsQual pREL_GHC_Name SLIT("CCallable") cCallableClassKey
-cReturnableClassName = clsQual pREL_GHC_Name SLIT("CReturnable") cReturnableClassKey
+usOnceTyConName = kindQual SLIT(".") usOnceTyConKey
+usManyTyConName = kindQual SLIT("!") usManyTyConKey
+superKindName = kindQual SLIT("KX") kindConKey
+superBoxityName = kindQual SLIT("BX") boxityConKey
+boxedConName = kindQual SLIT("*") boxedConKey
+unboxedConName = kindQual SLIT("#") unboxedConKey
+openKindConName = kindQual SLIT("?") anyBoxConKey
+usageKindConName = kindQual SLIT("$") usageConKey
+typeConName = kindQual SLIT("Type") typeConKey
+
+funTyConName = tcQual pREL_GHC_Name SLIT("(->)") funTyConKey
+charPrimTyConName = tcQual pREL_GHC_Name SLIT("Char#") charPrimTyConKey
+intPrimTyConName = tcQual pREL_GHC_Name SLIT("Int#") intPrimTyConKey
+int64PrimTyConName = tcQual pREL_GHC_Name SLIT("Int64#") int64PrimTyConKey
+wordPrimTyConName = tcQual pREL_GHC_Name SLIT("Word#") wordPrimTyConKey
+word64PrimTyConName = tcQual pREL_GHC_Name SLIT("Word64#") word64PrimTyConKey
+addrPrimTyConName = tcQual pREL_GHC_Name SLIT("Addr#") addrPrimTyConKey
+floatPrimTyConName = tcQual pREL_GHC_Name SLIT("Float#") floatPrimTyConKey
+doublePrimTyConName = tcQual pREL_GHC_Name SLIT("Double#") doublePrimTyConKey
+statePrimTyConName = tcQual pREL_GHC_Name SLIT("State#") statePrimTyConKey
+realWorldTyConName = tcQual pREL_GHC_Name SLIT("RealWorld") realWorldTyConKey
+arrayPrimTyConName = tcQual pREL_GHC_Name SLIT("Array#") arrayPrimTyConKey
+byteArrayPrimTyConName = tcQual pREL_GHC_Name SLIT("ByteArray#") byteArrayPrimTyConKey
+mutableArrayPrimTyConName = tcQual pREL_GHC_Name SLIT("MutableArray#") mutableArrayPrimTyConKey
+mutableByteArrayPrimTyConName = tcQual pREL_GHC_Name SLIT("MutableByteArray#") mutableByteArrayPrimTyConKey
+mutVarPrimTyConName = tcQual pREL_GHC_Name SLIT("MutVar#") mutVarPrimTyConKey
+mVarPrimTyConName = tcQual pREL_GHC_Name SLIT("MVar#") mVarPrimTyConKey
+stablePtrPrimTyConName = tcQual pREL_GHC_Name SLIT("StablePtr#") stablePtrPrimTyConKey
+stableNamePrimTyConName = tcQual pREL_GHC_Name SLIT("StableName#") stableNamePrimTyConKey
+foreignObjPrimTyConName = tcQual pREL_GHC_Name SLIT("ForeignObj#") foreignObjPrimTyConKey
+bcoPrimTyConName = tcQual pREL_GHC_Name SLIT("BCO#") bcoPrimTyConKey
+weakPrimTyConName = tcQual pREL_GHC_Name SLIT("Weak#") weakPrimTyConKey
+threadIdPrimTyConName = tcQual pREL_GHC_Name SLIT("ThreadId#") threadIdPrimTyConKey
+cCallableClassName = clsQual pREL_GHC_Name SLIT("CCallable") cCallableClassKey
+cReturnableClassName = clsQual pREL_GHC_Name SLIT("CReturnable") cReturnableClassKey
-- PrelBase data types and constructors
charTyConName = tcQual pREL_BASE_Name SLIT("Char") charTyConKey
-- Forign objects and weak pointers
foreignObjTyConName = tcQual pREL_IO_BASE_Name SLIT("ForeignObj") foreignObjTyConKey
foreignObjDataConName = dataQual pREL_IO_BASE_Name SLIT("ForeignObj") foreignObjDataConKey
-bcoPrimTyConName = tcQual pREL_BASE_Name SLIT("BCO#") bcoPrimTyConKey
stablePtrTyConName = tcQual pREL_STABLE_Name SLIT("StablePtr") stablePtrTyConKey
stablePtrDataConName = dataQual pREL_STABLE_Name SLIT("StablePtr") stablePtrDataConKey
deRefStablePtrName = varQual pREL_STABLE_Name SLIT("deRefStablePtr") deRefStablePtrIdKey
-makeStablePtrName = varQual pREL_STABLE_Name SLIT("makeStablePtr") makeStablePtrIdKey
+newStablePtrName = varQual pREL_STABLE_Name SLIT("newStablePtr") newStablePtrIdKey
errorName = varQual pREL_ERR_Name SLIT("error") errorIdKey
assertName = varQual pREL_GHC_Name SLIT("assert") assertIdKey
unpackCStringFoldr_RDR = nameRdrName unpackCStringFoldrName
unpackCStringUtf8_RDR = nameRdrName unpackCStringUtf8Name
deRefStablePtr_RDR = nameRdrName deRefStablePtrName
-makeStablePtr_RDR = nameRdrName makeStablePtrName
+newStablePtr_RDR = nameRdrName newStablePtrName
bindIO_RDR = nameRdrName bindIOName
returnIO_RDR = nameRdrName returnIOName
main_RDR = nameRdrName mainName
tcQual mod str uq = mkKnownKeyGlobal (tcQual_RDR mod str) uq
clsQual mod str uq = mkKnownKeyGlobal (clsQual_RDR mod str) uq
+kindQual str uq = mkKnownKeyGlobal (mkRdrOrig pREL_GHC_Name (mkKindOccFS tcName str)) uq
+ -- Kinds are not z-encoded in interface file, hence mkKindOccFS
+ -- And they all come from PrelGHC
+
varQual_RDR mod str = mkOrig varName mod str
tcQual_RDR mod str = mkOrig tcName mod str
clsQual_RDR mod str = mkOrig clsName mod str
threadIdPrimTyConKey = mkPreludeTyConUnique 70
bcoPrimTyConKey = mkPreludeTyConUnique 71
+-- Usage type constructors
+usageConKey = mkPreludeTyConUnique 72
+usOnceTyConKey = mkPreludeTyConUnique 73
+usManyTyConKey = mkPreludeTyConUnique 74
+
-- Generic Type Constructors
-crossTyConKey = mkPreludeTyConUnique 72
-plusTyConKey = mkPreludeTyConUnique 73
-genUnitTyConKey = mkPreludeTyConUnique 74
+crossTyConKey = mkPreludeTyConUnique 75
+plusTyConKey = mkPreludeTyConUnique 76
+genUnitTyConKey = mkPreludeTyConUnique 77
\end{code}
%************************************************************************
bindIOIdKey = mkPreludeMiscIdUnique 36
returnIOIdKey = mkPreludeMiscIdUnique 37
deRefStablePtrIdKey = mkPreludeMiscIdUnique 38
-makeStablePtrIdKey = mkPreludeMiscIdUnique 39
+newStablePtrIdKey = mkPreludeMiscIdUnique 39
getTagIdKey = mkPreludeMiscIdUnique 40
plusIntegerIdKey = mkPreludeMiscIdUnique 41
timesIntegerIdKey = mkPreludeMiscIdUnique 42
import Type ( Type, mkForAllTys, mkFunTy, mkFunTys, mkTyVarTys,
mkTyConApp, typePrimRep,
splitFunTy_maybe, splitAlgTyConApp_maybe, splitTyConApp_maybe,
- UsageAnn(..), mkUsgTy
+ mkUTy, usOnce, usMany
)
import Unique ( Unique, mkPrimOpIdUnique )
import BasicTypes ( Arity, Boxity(..) )
-- Helper bits & pieces for usage info.
-mkZ = mkUsgTy UsOnce -- pointed argument used zero
-mkO = mkUsgTy UsOnce -- pointed argument used once
-mkM = mkUsgTy UsMany -- pointed argument used multiply
-mkP = mkUsgTy UsOnce -- unpointed argument
-mkR = mkUsgTy UsMany -- unpointed result
+mkZ = mkUTy usOnce -- pointed argument used zero
+mkO = mkUTy usOnce -- pointed argument used once
+mkM = mkUTy usMany -- pointed argument used multiply
+mkP = mkUTy usOnce -- unpointed argument
+mkR = mkUTy usMany -- unpointed result
nomangle op
= case primOpSig op of
#include "HsVersions.h"
import Var ( TyVar, mkSysTyVar )
-import OccName ( tcName )
+import Name ( Name )
import PrimRep ( PrimRep(..), isFollowableRep )
-import TyCon ( mkPrimTyCon, TyCon, ArgVrcs )
+import TyCon ( TyCon, ArgVrcs, mkPrimTyCon )
import Type ( mkTyConApp, mkTyConTy, mkTyVarTys, mkTyVarTy,
unboxedTypeKind, boxedTypeKind, openTypeKind, mkArrowKinds
)
-import Unique ( Unique, mkAlphaTyVarUnique )
-import Name ( mkKnownKeyGlobal )
-import RdrName ( mkOrig )
+import Unique ( mkAlphaTyVarUnique )
import PrelNames
import Outputable
\end{code}
\begin{code}
-- only used herein
-pcPrimTyCon :: Unique{-TyConKey-} -> FAST_STRING -> Int -> ArgVrcs -> PrimRep -> TyCon
-pcPrimTyCon key str arity arg_vrcs rep
+pcPrimTyCon :: Name -> Int -> ArgVrcs -> PrimRep -> TyCon
+pcPrimTyCon name arity arg_vrcs rep
= the_tycon
where
- name = mkKnownKeyGlobal (mkOrig tcName pREL_GHC_Name str) key
the_tycon = mkPrimTyCon name kind arity arg_vrcs rep
kind = mkArrowKinds (take arity (repeat boxedTypeKind)) result_kind
result_kind | isFollowableRep rep = boxedTypeKind -- Represented by a GC-ish ptr
| otherwise = unboxedTypeKind -- Represented by a non-ptr
charPrimTy = mkTyConTy charPrimTyCon
-charPrimTyCon = pcPrimTyCon charPrimTyConKey SLIT("Char#") 0 [] CharRep
+charPrimTyCon = pcPrimTyCon charPrimTyConName 0 [] CharRep
intPrimTy = mkTyConTy intPrimTyCon
-intPrimTyCon = pcPrimTyCon intPrimTyConKey SLIT("Int#") 0 [] IntRep
+intPrimTyCon = pcPrimTyCon intPrimTyConName 0 [] IntRep
int64PrimTy = mkTyConTy int64PrimTyCon
-int64PrimTyCon = pcPrimTyCon int64PrimTyConKey SLIT("Int64#") 0 [] Int64Rep
+int64PrimTyCon = pcPrimTyCon int64PrimTyConName 0 [] Int64Rep
wordPrimTy = mkTyConTy wordPrimTyCon
-wordPrimTyCon = pcPrimTyCon wordPrimTyConKey SLIT("Word#") 0 [] WordRep
+wordPrimTyCon = pcPrimTyCon wordPrimTyConName 0 [] WordRep
word64PrimTy = mkTyConTy word64PrimTyCon
-word64PrimTyCon = pcPrimTyCon word64PrimTyConKey SLIT("Word64#") 0 [] Word64Rep
+word64PrimTyCon = pcPrimTyCon word64PrimTyConName 0 [] Word64Rep
addrPrimTy = mkTyConTy addrPrimTyCon
-addrPrimTyCon = pcPrimTyCon addrPrimTyConKey SLIT("Addr#") 0 [] AddrRep
+addrPrimTyCon = pcPrimTyCon addrPrimTyConName 0 [] AddrRep
floatPrimTy = mkTyConTy floatPrimTyCon
-floatPrimTyCon = pcPrimTyCon floatPrimTyConKey SLIT("Float#") 0 [] FloatRep
+floatPrimTyCon = pcPrimTyCon floatPrimTyConName 0 [] FloatRep
doublePrimTy = mkTyConTy doublePrimTyCon
-doublePrimTyCon = pcPrimTyCon doublePrimTyConKey SLIT("Double#") 0 [] DoubleRep
+doublePrimTyCon = pcPrimTyCon doublePrimTyConName 0 [] DoubleRep
\end{code}
\begin{code}
mkStatePrimTy ty = mkTyConApp statePrimTyCon [ty]
-statePrimTyCon = pcPrimTyCon statePrimTyConKey SLIT("State#") 1 vrcsZ VoidRep
+statePrimTyCon = pcPrimTyCon statePrimTyConName 1 vrcsZ VoidRep
\end{code}
@_RealWorld@ is deeply magical. It {\em is primitive}, but it
\begin{code}
realWorldTy = mkTyConTy realWorldTyCon
-realWorldTyCon = pcPrimTyCon realWorldTyConKey SLIT("RealWorld") 0 [] PrimPtrRep
+realWorldTyCon = pcPrimTyCon realWorldTyConName 0 [] PrimPtrRep
realWorldStatePrimTy = mkStatePrimTy realWorldTy -- State# RealWorld
\end{code}
%************************************************************************
\begin{code}
-arrayPrimTyCon = pcPrimTyCon arrayPrimTyConKey SLIT("Array#") 1 vrcsP ArrayRep
-
-byteArrayPrimTyCon = pcPrimTyCon byteArrayPrimTyConKey SLIT("ByteArray#") 0 [] ByteArrayRep
-
-mutableArrayPrimTyCon = pcPrimTyCon mutableArrayPrimTyConKey SLIT("MutableArray#")
- 2 vrcsZP ArrayRep
-
-mutableByteArrayPrimTyCon = pcPrimTyCon mutableByteArrayPrimTyConKey SLIT("MutableByteArray#")
- 1 vrcsZ ByteArrayRep
+arrayPrimTyCon = pcPrimTyCon arrayPrimTyConName 1 vrcsP ArrayRep
+byteArrayPrimTyCon = pcPrimTyCon byteArrayPrimTyConName 0 [] ByteArrayRep
+mutableArrayPrimTyCon = pcPrimTyCon mutableArrayPrimTyConName 2 vrcsZP ArrayRep
+mutableByteArrayPrimTyCon = pcPrimTyCon mutableByteArrayPrimTyConName 1 vrcsZ ByteArrayRep
mkArrayPrimTy elt = mkTyConApp arrayPrimTyCon [elt]
byteArrayPrimTy = mkTyConTy byteArrayPrimTyCon
%************************************************************************
\begin{code}
-mutVarPrimTyCon = pcPrimTyCon mutVarPrimTyConKey SLIT("MutVar#")
- 2 vrcsZP PrimPtrRep
+mutVarPrimTyCon = pcPrimTyCon mutVarPrimTyConName 2 vrcsZP PrimPtrRep
mkMutVarPrimTy s elt = mkTyConApp mutVarPrimTyCon [s, elt]
\end{code}
%************************************************************************
\begin{code}
-mVarPrimTyCon = pcPrimTyCon mVarPrimTyConKey SLIT("MVar#")
- 2 vrcsZP PrimPtrRep
+mVarPrimTyCon = pcPrimTyCon mVarPrimTyConName 2 vrcsZP PrimPtrRep
mkMVarPrimTy s elt = mkTyConApp mVarPrimTyCon [s, elt]
\end{code}
%************************************************************************
\begin{code}
-stablePtrPrimTyCon = pcPrimTyCon stablePtrPrimTyConKey SLIT("StablePtr#")
- 1 vrcsP StablePtrRep
+stablePtrPrimTyCon = pcPrimTyCon stablePtrPrimTyConName 1 vrcsP StablePtrRep
mkStablePtrPrimTy ty = mkTyConApp stablePtrPrimTyCon [ty]
\end{code}
%************************************************************************
\begin{code}
-stableNamePrimTyCon = pcPrimTyCon stableNamePrimTyConKey SLIT("StableName#")
- 1 vrcsP StableNameRep
+stableNamePrimTyCon = pcPrimTyCon stableNamePrimTyConName 1 vrcsP StableNameRep
mkStableNamePrimTy ty = mkTyConApp stableNamePrimTyCon [ty]
\end{code}
\begin{code}
foreignObjPrimTy = mkTyConTy foreignObjPrimTyCon
-foreignObjPrimTyCon = pcPrimTyCon foreignObjPrimTyConKey SLIT("ForeignObj#") 0 [] ForeignObjRep
+foreignObjPrimTyCon = pcPrimTyCon foreignObjPrimTyConName 0 [] ForeignObjRep
\end{code}
%************************************************************************
\begin{code}
bcoPrimTy = mkTyConTy bcoPrimTyCon
-bcoPrimTyCon = pcPrimTyCon bcoPrimTyConKey SLIT("BCO#") 0 [] BCORep
+bcoPrimTyCon = pcPrimTyCon bcoPrimTyConName 0 [] BCORep
\end{code}
%************************************************************************
%************************************************************************
\begin{code}
-weakPrimTyCon = pcPrimTyCon weakPrimTyConKey SLIT("Weak#") 1 vrcsP WeakPtrRep
+weakPrimTyCon = pcPrimTyCon weakPrimTyConName 1 vrcsP WeakPtrRep
mkWeakPrimTy v = mkTyConApp weakPrimTyCon [v]
\end{code}
\begin{code}
threadIdPrimTy = mkTyConTy threadIdPrimTyCon
-threadIdPrimTyCon = pcPrimTyCon threadIdPrimTyConKey SLIT("ThreadId#") 0 [] ThreadIdRep
+threadIdPrimTyCon = pcPrimTyCon threadIdPrimTyConName 0 [] ThreadIdRep
\end{code}
%************************************************************************
-----------------------------------------------------------------------
--- $Id: primops.txt,v 1.5 2000/09/26 16:45:34 simonpj Exp $
+-- $Id: primops.txt,v 1.6 2000/11/07 15:21:40 simonmar Exp $
--
-- Primitive Operations
--
primop IntegerToWord64Op "integerToWord64#" GenPrimOp
Int# -> ByteArr# -> Word64#
+primop IntegerAndOp "andInteger#" GenPrimOp
+ Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
+ with out_of_line = True
+
+primop IntegerOrOp "orInteger#" GenPrimOp
+ Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
+ with out_of_line = True
+
+primop IntegerXorOp "xorInteger#" GenPrimOp
+ Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
+ with out_of_line = True
+
+primop IntegerComplementOp "complementInteger#" GenPrimOp
+ Int# -> ByteArr# -> (# Int#, ByteArr# #)
+ with out_of_line = True
+
------------------------------------------------------------------------
--- Word# ---
------------------------------------------------------------------------
import HsSyn -- quite a bit of stuff
import RdrHsSyn -- oodles of synonyms
-import HsTypes ( mkHsForAllTy, mkHsUsForAllTy, mkHsTupCon )
+import HsTypes ( mkHsForAllTy, mkHsTupCon )
import HsCore
import Demand ( mkStrictnessInfo )
import Literal ( Literal(..), mkMachInt, mkMachInt64, mkMachWord, mkMachWord64 )
)
import CostCentre ( CostCentre(..), IsCafCC(..), IsDupdCC(..) )
import CallConv ( cCallConv )
-import Type ( Kind, mkArrowKind, boxedTypeKind, openTypeKind )
+import Type ( Kind, mkArrowKind, boxedTypeKind, openTypeKind, usageTypeKind )
import IdInfo ( exactArity, InlinePragInfo(..) )
import PrimOp ( CCall(..), CCallTarget(..) )
import Lex
import RdrName ( RdrName, mkRdrUnqual, mkIfaceOrig )
import Name ( OccName )
import OccName ( mkSysOccFS,
- tcName, varName, ipName, dataName, clsName, tvName, uvName,
+ tcName, varName, ipName, dataName, clsName, tvName,
EncodedFS
)
import Module ( ModuleName, PackageName, mkSysModuleNameFS, mkModule )
import SrcLoc ( SrcLoc )
import CmdLineOpts ( opt_InPackage, opt_IgnoreIfacePragmas )
import Outputable
-import List ( insert )
import Class ( DefMeth (..) )
import GlaExts
'__sccC' { ITsccAllCafs }
'__u' { ITusage }
- '__fuall' { ITfuall }
'__A' { ITarity }
'__P' { ITspecialise }
'<-' { ITlarrow }
'->' { ITrarrow }
'@' { ITat }
- '~' { ITtilde }
'=>' { ITdarrow }
'-' { ITminus }
'!' { ITbang }
- '/\\' { ITbiglam } -- GHC-extension symbols
-
'{' { ITocurly } -- special symbols
'}' { ITccurly }
'{|' { ITocurlybar } -- special symbols
'#)' { ITcubxparen }
';' { ITsemi }
',' { ITcomma }
+ '.' { ITdot }
VARID { ITvarid $$ } -- identifiers
CONID { ITconid $$ }
| batype batypes { $1 : $2 }
batype :: { RdrNameBangType }
-batype : atype { Unbanged $1 }
- | '!' atype { Banged $2 }
- | '!' '!' atype { Unpacked $3 }
+batype : tatype { Unbanged $1 }
+ | '!' tatype { Banged $2 }
+ | '!' '!' tatype { Unpacked $3 }
fields1 :: { [([RdrName], RdrNameBangType)] }
fields1 : field { [$1] }
| field ',' fields1 { $1 : $3 }
field :: { ([RdrName], RdrNameBangType) }
-field : qvar_names1 '::' type { ($1, Unbanged $3) }
- | qvar_names1 '::' '!' type { ($1, Banged $4) }
- | qvar_names1 '::' '!' '!' type { ($1, Unpacked $5) }
+field : qvar_names1 '::' ttype { ($1, Unbanged $3) }
+ | qvar_names1 '::' '!' ttype { ($1, Banged $4) }
+ | qvar_names1 '::' '!' '!' ttype { ($1, Unpacked $5) }
+
--------------------------------------------------------------------------
type :: { RdrNameHsType }
-type : '__fuall' fuall '=>' type { mkHsUsForAllTy $2 $4 }
- | '__forall' tv_bndrs
+type : '__forall' tv_bndrs
opt_context '=>' type { mkHsForAllTy (Just $2) $3 $5 }
| btype '->' type { HsFunTy $1 $3 }
| btype { $1 }
-fuall :: { [RdrName] }
-fuall : '[' uv_bndrs ']' { $2 }
-
opt_context :: { RdrNameContext }
opt_context : { [] }
| context { $1 }
btype :: { RdrNameHsType }
btype : atype { $1 }
| btype atype { HsAppTy $1 $2 }
- | '__u' usage atype { HsUsgTy $2 $3 }
-
-usage :: { HsUsageAnn RdrName }
-usage : '-' { HsUsOnce }
- | '!' { HsUsMany }
- | uv_name { HsUsVar $1 }
+ | '__u' atype atype { HsUsageTy $2 $3 }
atype :: { RdrNameHsType }
atype : qtc_name { HsTyVar $1 }
| tv_name { HsTyVar $1 }
+ | '.' { hsUsOnce }
+ | '!' { hsUsMany }
| '(' ')' { HsTupleTy (mkHsTupCon tcName Boxed []) [] }
| '(' types2 ')' { HsTupleTy (mkHsTupCon tcName Boxed $2) $2 }
| '(#' types0 '#)' { HsTupleTy (mkHsTupCon tcName Unboxed $2) $2 }
atypes :: { [RdrNameHsType] {- Zero or more -} }
atypes : { [] }
| atype atypes { $1 : $2 }
+--------------------------------------------------------------------------
+
+-- versions of type/btype/atype that cant begin with '!' (or '.')
+-- for use where the kind is definitely known NOT to be '$'
+
+ttype :: { RdrNameHsType }
+ttype : '__forall' tv_bndrs
+ opt_context '=>' type { mkHsForAllTy (Just $2) $3 $5 }
+ | tbtype '->' type { HsFunTy $1 $3 }
+ | tbtype { $1 }
+
+tbtype :: { RdrNameHsType }
+tbtype : tatype { $1 }
+ | tbtype atype { HsAppTy $1 $2 }
+ | '__u' atype atype { HsUsageTy $2 $3 }
+
+tatype :: { RdrNameHsType }
+tatype : qtc_name { HsTyVar $1 }
+ | tv_name { HsTyVar $1 }
+ | '(' ')' { HsTupleTy (mkHsTupCon tcName Boxed []) [] }
+ | '(' types2 ')' { HsTupleTy (mkHsTupCon tcName Boxed $2) $2 }
+ | '(#' types0 '#)' { HsTupleTy (mkHsTupCon tcName Unboxed $2) $2 }
+ | '[' type ']' { HsListTy $2 }
+ | '{' qcls_name atypes '}' { mkHsDictTy $2 $3 }
+ | '{' ipvar_name '::' type '}' { mkHsIParamTy $2 $4 }
+ | '(' type ')' { $2 }
---------------------------------------------------------------------
+
package :: { PackageName }
: STRING { $1 }
| {- empty -} { opt_InPackage } -- Useful for .hi-boot files,
| qdata_fs { mkIfaceOrig clsName $1 }
---------------------------------------------------
-uv_name :: { RdrName }
- : VARID { mkRdrUnqual (mkSysOccFS uvName $1) }
-
-uv_bndr :: { RdrName }
- : uv_name { $1 }
-
-uv_bndrs :: { [RdrName] }
- : { [] }
- | uv_bndr uv_bndrs { $1 : $2 }
-
----------------------------------------------------
tv_name :: { RdrName }
: VARID { mkRdrUnqual (mkSysOccFS tvName $1) }
- | VARSYM { mkRdrUnqual (mkSysOccFS tvName $1) {- Allow t2 as a tyvar -} }
tv_bndr :: { HsTyVarBndr RdrName }
: tv_name '::' akind { IfaceTyVar $1 $3 }
| tv_name { IfaceTyVar $1 boxedTypeKind }
tv_bndrs :: { [HsTyVarBndr RdrName] }
-tv_bndrs : tv_bndrs1 { $1 }
+ : tv_bndrs1 { $1 }
| '[' tv_bndrs1 ']' { $2 } -- Backward compatibility
tv_bndrs1 :: { [HsTyVarBndr RdrName] }
boxedTypeKind
else if $1 == SLIT("?") then
openTypeKind
- else panic "ParseInterface: akind"
+ else if $1 == SLIT("\36") then
+ usageTypeKind -- dollar
+ else panic "ParseInterface: akind"
}
| '(' kind ')' { $2 }
where
pairs = [(mkRdrUnqual (nameOccName n), n) | n <- names]
+bindLocalNamesFV names enclosed_scope
+ = bindLocalNames names $
+ enclosed_scope `thenRn` \ (thing, fvs) ->
+ returnRn (thing, delListFromNameSet fvs names)
+
+
-------------------------------------
bindLocalRn doc rdr_name enclosed_scope
= getSrcLocRn `thenRn` \ loc ->
returnRn (thing, delListFromNameSet fvs names)
-------------------------------------
-bindUVarRn :: RdrName -> (Name -> RnMS a) -> RnMS a
-bindUVarRn = bindCoreLocalRn
-
--------------------------------------
extendTyVarEnvFVRn :: [Name] -> RnMS (a, FreeVars) -> RnMS (a, FreeVars)
-- This tiresome function is used only in rnDecl on InstDecl
extendTyVarEnvFVRn tyvars enclosed_scope
import UniqFM ( isNullUFM )
import FiniteMap ( elemFM )
import UniqSet ( emptyUniqSet )
+import List ( intersectBy )
import ListSetOps ( unionLists, removeDups )
import Maybes ( maybeToBool )
import Outputable
returnRn ()
) `thenRn_`
- rnStmts rnExpr guarded `thenRn` \ (guarded', fvs) ->
+ rnStmts rnExpr guarded `thenRn` \ ((_, guarded'), fvs) ->
returnRn (GRHS guarded' locn, fvs)
where
-- Standard Haskell 1.4 guards are just a single boolean
rnExpr e@(HsDo do_or_lc stmts src_loc)
= pushSrcLocRn src_loc $
lookupOrigNames implicit_rdr_names `thenRn` \ implicit_fvs ->
- rnStmts rnExpr stmts `thenRn` \ (stmts', fvs) ->
+ rnStmts rnExpr stmts `thenRn` \ ((_, stmts'), fvs) ->
-- check the statement list ends in an expression
case last stmts' of {
ExprStmt _ _ -> returnRn () ;
ReturnStmt _ -> returnRn () ; -- for list comprehensions
_ -> addErrRn (doStmtListErr e)
- } `thenRn_`
+ } `thenRn_`
returnRn (HsDo do_or_lc stmts' src_loc, fvs `plusFV` implicit_fvs)
where
implicit_rdr_names = [foldr_RDR, build_RDR, monadClass_RDR]
type RnExprTy = RdrNameHsExpr -> RnMS (RenamedHsExpr, FreeVars)
rnStmts :: RnExprTy
- -> [RdrNameStmt]
- -> RnMS ([RenamedStmt], FreeVars)
+ -> [RdrNameStmt]
+ -> RnMS (([Name], [RenamedStmt]), FreeVars)
rnStmts rn_expr []
- = returnRn ([], emptyFVs)
+ = returnRn (([], []), emptyFVs)
rnStmts rn_expr (stmt:stmts)
- = rnStmt rn_expr stmt $ \ stmt' ->
- rnStmts rn_expr stmts `thenRn` \ (stmts', fvs) ->
- returnRn (stmt' : stmts', fvs)
+ = getLocalNameEnv `thenRn` \ name_env ->
+ rnStmt rn_expr stmt $ \ stmt' ->
+ rnStmts rn_expr stmts `thenRn` \ ((binders, stmts'), fvs) ->
+ returnRn ((binders, stmt' : stmts'), fvs)
rnStmt :: RnExprTy -> RdrNameStmt
- -> (RenamedStmt -> RnMS (a, FreeVars))
- -> RnMS (a, FreeVars)
+ -> (RenamedStmt -> RnMS (([Name], a), FreeVars))
+ -> RnMS (([Name], a), FreeVars)
-- Because of mutual recursion we have to pass in rnExpr.
+rnStmt rn_expr (ParStmt stmtss) thing_inside
+ = mapFvRn (rnStmts rn_expr) stmtss `thenRn` \ (bndrstmtss, fv_stmtss) ->
+ let (binderss, stmtss') = unzip bndrstmtss
+ checkBndrs all_bndrs bndrs
+ = checkRn (null (intersectBy eqOcc all_bndrs bndrs)) err `thenRn_`
+ returnRn (bndrs ++ all_bndrs)
+ eqOcc n1 n2 = nameOccName n1 == nameOccName n2
+ err = text "duplicate binding in parallel list comprehension"
+ in
+ foldlRn checkBndrs [] binderss `thenRn` \ binders ->
+ bindLocalNamesFV binders $
+ thing_inside (ParStmtOut bndrstmtss)`thenRn` \ ((rest_bndrs, result), fv_rest) ->
+ returnRn ((rest_bndrs ++ binders, result), fv_stmtss `plusFV` fv_rest)
+
rnStmt rn_expr (BindStmt pat expr src_loc) thing_inside
= pushSrcLocRn src_loc $
- rn_expr expr `thenRn` \ (expr', fv_expr) ->
- bindLocalsFVRn doc binders $ \ new_binders ->
- rnPat pat `thenRn` \ (pat', fv_pat) ->
- thing_inside (BindStmt pat' expr' src_loc) `thenRn` \ (result, fvs) ->
- returnRn (result, fv_expr `plusFV` fvs `plusFV` fv_pat)
+ rn_expr expr `thenRn` \ (expr', fv_expr) ->
+ bindLocalsFVRn doc binders $ \ new_binders ->
+ rnPat pat `thenRn` \ (pat', fv_pat) ->
+ thing_inside (BindStmt pat' expr' src_loc) `thenRn` \ ((rest_binders, result), fvs) ->
+ -- ZZ is shadowing handled correctly?
+ returnRn ((rest_binders ++ new_binders, result),
+ fv_expr `plusFV` fvs `plusFV` fv_pat)
where
binders = collectPatBinders pat
doc = text "a pattern in do binding"
returnRn (result, fv_expr `plusFV` fvs)
rnStmt rn_expr (LetStmt binds) thing_inside
- = rnBinds binds $ \ binds' ->
+ = rnBinds binds $ \ binds' ->
thing_inside (LetStmt binds')
+
\end{code}
%************************************************************************
`unionNameSets` extractHsTyNames_s tys
get (HsFunTy ty1 ty2) = get ty1 `unionNameSets` get ty2
get (HsPredTy p) = extractHsPredTyNames p
- get (HsUsgForAllTy uv ty) = get ty
- get (HsUsgTy u ty) = get ty
get (HsOpTy ty1 tycon ty2) = get ty1 `unionNameSets` get ty2 `unionNameSets`
unitNameSet tycon
get (HsNumTy n) = emptyNameSet
go_outer decls fvs all_gates refs -- refs are not necessarily slurped yet
= traceRn (text "go_outer" <+> ppr refs) `thenRn_`
- getImportedInstDecls all_gates `thenRn` \ inst_decls ->
foldlRn go_inner (decls, fvs, emptyFVs) refs `thenRn` \ (decls1, fvs1, gates1) ->
+ getImportedInstDecls (all_gates `plusFV` gates1) `thenRn` \ inst_decls ->
rnIfaceInstDecls decls1 fvs1 gates1 inst_decls `thenRn` \ (decls2, fvs2, gates2) ->
go_outer decls2 fvs2 (all_gates `plusFV` gates2)
(nameSetToList (gates2 `minusNameSet` all_gates))
import RnBinds ( rnTopBinds, rnMethodBinds, renameSigs, renameSigsFVs )
import RnEnv ( lookupTopBndrRn, lookupOccRn, newIPName, lookupIfaceName,
lookupOrigNames, lookupSysBinder, newLocalsRn,
- bindLocalsFVRn, bindUVarRn,
+ bindLocalsFVRn,
bindTyVarsRn, bindTyVars2Rn,
bindTyVarsFV2Rn, extendTyVarEnvFVRn,
bindCoreLocalRn, bindCoreLocalsRn, bindLocalNames,
import Name ( Name, OccName, nameOccName, NamedThing(..) )
import NameSet
import PrelInfo ( derivableClassKeys, cCallishClassKeys )
-import PrelNames ( deRefStablePtr_RDR, makeStablePtr_RDR,
+import PrelNames ( deRefStablePtr_RDR, newStablePtr_RDR,
bindIO_RDR, returnIO_RDR
)
import List ( partition, nub )
lookupOccRn name `thenRn` \ name' ->
let
extra_fvs FoExport
- | isDyn = lookupOrigNames [makeStablePtr_RDR, deRefStablePtr_RDR,
+ | isDyn = lookupOrigNames [newStablePtr_RDR, deRefStablePtr_RDR,
bindIO_RDR, returnIO_RDR]
| otherwise =
lookupOrigNames [bindIO_RDR, returnIO_RDR] `thenRn` \ fvs ->
= rnPred doc pred `thenRn` \ pred' ->
returnRn (HsPredTy pred')
-rnHsType doc (HsUsgForAllTy uv_rdr ty)
- = bindUVarRn uv_rdr $ \ uv_name ->
- rnHsType doc ty `thenRn` \ ty' ->
- returnRn (HsUsgForAllTy uv_name ty')
-
-rnHsType doc (HsUsgTy usg ty)
- = newUsg usg `thenRn` \ usg' ->
- rnHsType doc ty `thenRn` \ ty' ->
- -- A for-all can occur inside a usage annotation
- returnRn (HsUsgTy usg' ty')
- where
- newUsg usg = case usg of
- HsUsOnce -> returnRn HsUsOnce
- HsUsMany -> returnRn HsUsMany
- HsUsVar uv_rdr -> lookupOccRn uv_rdr `thenRn` \ uv_name ->
- returnRn (HsUsVar uv_name)
-
rnHsTypes doc tys = mapRn (rnHsType doc) tys
\end{code}
fiExpr to_drop (_, AnnNote note@(Coerce _ _) expr)
= -- Just float in past coercion
Note note (fiExpr to_drop expr)
-
-fiExpr to_drop (_, AnnNote note@(TermUsg _) expr)
- = -- Float in past term usage annotation
- -- (for now; not sure if this is correct: KSW 1999-05)
- Note note (fiExpr to_drop expr)
\end{code}
For @Lets@, the possible ``drop points'' for the \tr{to_drop}
-- where x* has an INLINE prag on it. Now, once x* is inlined,
-- the occurrences of x' will be just the occurrences originally
-- pinned on x.
- -- poly_info = vanillaIdInfo `setOccInfo` idOccInfo var
in
returnSmpl (poly_id, mkTyApps (Var poly_id) (mkTyVarTys tyvars_here))
- mk_silly_bind var rhs = NonRec var rhs
+ mk_silly_bind var rhs = NonRec var (Note InlineMe rhs)
-- Suppose we start with:
--
- -- x = let g = /\a -> \x -> f x x
- -- in
- -- /\ b -> let g* = g b in E
+ -- x = /\ a -> let g = G in E
--
- -- Then: * the binding for g gets floated out
- -- * but then it MIGHT get inlined into the rhs of g*
- -- * then the binding for g* is floated out of the /\b
- -- * so we're back to square one
- -- We rely on the simplifier not to inline g into the RHS of g*,
- -- because it's a "lone" occurrence, and there is no benefit in
- -- inlining. But it's a slightly delicate property; hence this comment
+ -- Then we'll float to get
+ --
+ -- x = let poly_g = /\ a -> G
+ -- in /\ a -> let g = poly_g a in E
+ --
+ -- But now the occurrence analyser will see just one occurrence
+ -- of poly_g, not inside a lambda, so the simplifier will
+ -- PreInlineUnconditionally poly_g back into g! Badk to square 1!
+ -- (I used to think that the "don't inline lone occurrences" stuff
+ -- would stop this happening, but since it's the *only* occurrence,
+ -- PreInlineUnconditionally kicks in first!)
+ --
+ -- Solution: put an INLINE note on g's RHS, so that poly_g seems
+ -- to appear many times. (NB: mkInlineMe eliminates
+ -- such notes on trivial RHSs, so do it manually.)
\end{code}
(a) some might appear as a function argument, so we simply
replace static allocation with dynamic allocation:
l = <...>
- x = f x
+ x = f l
becomes
x = f <...>
----------------------------------------
match_ty ty1 ty2 tpl_vars kont subst
- = case Unify.match ty1 ty2 tpl_vars Just (substEnv subst) of
+ = case Unify.match False {- for now: KSW 2000-10 -} ty1 ty2 tpl_vars Just (substEnv subst) of
Nothing -> match_fail
Just senv' -> kont (setSubstEnv subst senv')
import VarEnv
import PrimOp ( PrimOp(..), setCCallUnique )
import Type ( isUnLiftedType, isUnboxedTupleType, Type, splitFunTy_maybe,
- UsageAnn(..), tyUsg, applyTy, repType, seqType,
- splitRepFunTys, mkFunTys
+ applyTy, repType, seqType,
+ splitRepFunTys, mkFunTys,
+ uaUTy, usOnce, usMany, isTyVarTy
)
import UniqSupply -- all of it, really
import BasicTypes ( TopLevelFlag(..), isNotTopLevel )
#ifdef USMANY
opt_UsageSPOn && -- can't expect annotations if -fusagesp is off
#endif
- case tyUsg ty of
- UsOnce -> True
- UsMany -> False
- UsVar uv -> pprPanic "CoreToStg: unexpected uvar annot:" (ppr uv)
+ once
+ where
+ u = uaUTy ty
+ once | u == usOnce = True
+ | u == usMany = False
+ | isTyVarTy u = False -- if unknown at compile-time, is Top ie usMany
bdrDem :: Id -> RhsDemand
bdrDem id = mkDem (idDemandInfo id) (isOnceTy (idType id))
-- isDllConApp checks for LitLit args too
= StgRhsCon noCCS con args
-exprToRhs dem _ expr
+exprToRhs dem toplev expr
= upd `seq`
StgRhsClosure noCCS -- No cost centre (ToDo?)
stgArgOcc -- safe
[]
expr
where
- upd = if isOnceDem dem then SingleEntry else Updatable
- -- HA! Paydirt for "dem"
+ upd = if isOnceDem dem
+ then (if isNotTopLevel toplev
+ then SingleEntry -- HA! Paydirt for "dem"
+ else
+#ifdef DEBUG
+ trace "WARNING: SE CAFs unsupported, forcing UPD instead" $
+#endif
+ Updatable)
+ else Updatable
+ -- For now we forbid SingleEntry CAFs; they tickle the
+ -- ASSERT in rts/Storage.c line 215 at newCAF() re mut_link,
+ -- and I don't understand why. There's only one SE_CAF (well,
+ -- only one that tickled a great gaping bug in an earlier attempt
+ -- at ClosureInfo.getEntryConvention) in the whole of nofib,
+ -- specifically Main.lvl6 in spectral/cryptarithm2.
+ -- So no great loss. KSW 2000-07.
\end{code}
(binders, body) = collectBinders expr
id_binders = filter isId binders
in
- if null id_binders then -- It was all type/usage binders; tossed
+ if null id_binders then -- It was all type binders; tossed
coreExprToStgFloat env body
else
-- At least some value binders
collect_args (Note (Coerce ty _) e) = let (the_fun,ads,_,ss) = collect_args e
in (the_fun,ads,ty,ss)
collect_args (Note InlineCall e) = collect_args e
- collect_args (Note (TermUsg _) e) = collect_args e
collect_args (App fun (Type tyarg)) = let (the_fun,ads,fun_ty,ss) = collect_args fun
in (the_fun,ads,applyTy fun_ty tyarg,ss)
tcExtendLocalValEnv, tcExtendTyVarEnv, newDefaultMethodName
)
import TcBinds ( tcBindWithSigs, tcSpecSigs )
-import TcMonoType ( tcHsSigType, tcClassContext, checkSigTyVars, checkAmbiguity, sigCtxt, mkTcSig )
+import TcMonoType ( tcHsRecType, tcRecClassContext, checkSigTyVars, checkAmbiguity, sigCtxt, mkTcSig )
import TcSimplify ( tcSimplifyAndCheck, bindInstsOfLocalFuns )
import TcType ( TcType, TcTyVar, tcInstTyVars, zonkTcSigTyVars )
import TcMonad
import Generics ( mkGenericRhs, validGenericMethodType )
import PrelInfo ( nO_METHOD_BINDING_ERROR_ID )
-import Class ( classTyVars, classBigSig, classSelIds, classTyCon, classTvsFds,
- Class, ClassOpItem, DefMeth (..), FunDep )
+import Class ( classTyVars, classBigSig, classSelIds, classTyCon,
+ Class, ClassOpItem, DefMeth (..) )
import MkId ( mkDictSelId, mkDataConId, mkDataConWrapId, mkDefaultMethodId )
import DataCon ( mkDataCon, notMarkedStrict )
import Id ( Id, idType, idName )
%************************************************************************
\begin{code}
-tcClassDecl1 :: RecTcEnv -> RenamedTyClDecl -> TcM (Name, TyThingDetails)
-tcClassDecl1 rec_env
+
+tcClassDecl1 :: RecFlag -> RecTcEnv -> RenamedTyClDecl -> TcM (Name, TyThingDetails)
+tcClassDecl1 is_rec rec_env
(ClassDecl context class_name
tyvar_names fundeps class_sigs def_methods
sys_names src_loc)
-- LOOK THINGS UP IN THE ENVIRONMENT
tcLookupClass class_name `thenTc` \ clas ->
let
- (tyvars, fds) = classTvsFds clas
+ tyvars = classTyVars clas
op_sigs = filter isClassOpSig class_sigs
op_names = [n | ClassOpSig n _ _ _ <- op_sigs]
(_, datacon_name, datacon_wkr_name, sc_sel_names) = getClassDeclSysNames sys_names
checkGenericClassIsUnary clas dm_info `thenTc_`
-- CHECK THE CONTEXT
- tcSuperClasses clas context sc_sel_names `thenTc` \ (sc_theta, sc_sel_ids) ->
+ tcSuperClasses is_rec clas context sc_sel_names `thenTc` \ (sc_theta, sc_sel_ids) ->
-- CHECK THE CLASS SIGNATURES,
- mapTc (tcClassSig rec_env clas tyvars fds dm_info)
- op_sigs `thenTc` \ sig_stuff ->
+ mapTc (tcClassSig is_rec rec_env clas tyvars dm_info) op_sigs `thenTc` \ sig_stuff ->
-- MAKE THE CLASS DETAILS
let
\begin{code}
-tcSuperClasses :: Class
+tcSuperClasses :: RecFlag -> Class
-> RenamedContext -- class context
-> [Name] -- Names for superclass selectors
-> TcM (ClassContext, -- the superclass context
[Id]) -- superclass selector Ids
-tcSuperClasses clas context sc_sel_names
+tcSuperClasses is_rec clas context sc_sel_names
= -- Check the context.
-- The renamer has already checked that the context mentions
-- only the type variable of the class decl.
) `thenTc_`
-- Context is already kind-checked
- tcClassContext context `thenTc` \ sc_theta ->
+ tcRecClassContext is_rec context `thenTc` \ sc_theta ->
let
sc_sel_ids = [mkDictSelId sc_name clas | sc_name <- sc_sel_names]
in
is_tyvar other = False
-tcClassSig :: RecTcEnv
+tcClassSig :: RecFlag -> RecTcEnv -- Knot tying only!
-> Class -- ...ditto...
-> [TyVar] -- The class type variable, used for error check only
- -> [FunDep TyVar]
-> NameEnv (DefMeth Name) -- Info about default methods
-> RenamedClassOpSig
-> TcM (Type, -- Type of the method
-- so we distinguish them in checkDefaultBinds, and pass this knowledge in the
-- Class.DefMeth data structure.
-tcClassSig unf_env clas clas_tyvars fds dm_info
+tcClassSig is_rec unf_env clas clas_tyvars dm_info
(ClassOpSig op_name maybe_dm op_ty src_loc)
= tcAddSrcLoc src_loc $
-- Check the type signature. NB that the envt *already has*
-- bindings for the type variables; see comments in TcTyAndClassDcls.
- tcHsSigType op_ty `thenTc` \ local_ty ->
+ tcHsRecType is_rec op_ty `thenTc` \ local_ty ->
+
+ -- Check for ambiguous class op types
let
theta = [mkClassPred clas (mkTyVarTys clas_tyvars)]
in
- -- Check for ambiguous class op types
- checkAmbiguity True clas_tyvars theta local_ty `thenTc` \ global_ty ->
+ checkAmbiguity is_rec True clas_tyvars theta local_ty `thenTc` \ global_ty ->
+ -- The default method's type should really come from the
+ -- iface file, since it could be usage-generalised, but this
+ -- requires altering the mess of knots in TcModule and I'm
+ -- too scared to do that. Instead, I have disabled generalisation
+ -- of types of default methods (and dict funs) by annotating them
+ -- TyGenNever (in MkId). Ugh! KSW 1999-09.
let
-- Build the selector id and default method id
)
import Name ( Name, getName )
import Type ( mkFunTy, mkAppTy, mkTyVarTys, ipName_maybe,
- splitFunTy_maybe, splitFunTys, isNotUsgTy,
+ splitFunTy_maybe, splitFunTys,
mkTyConApp, splitSigmaTy,
splitRhoTy,
isTauTy, tyVarsOfType, tyVarsOfTypes,
-- Figure out the tycon and data cons from the first field name
let
(Just (AnId sel_id) : _) = maybe_sel_ids
- (_, _, tau) = ASSERT( isNotUsgTy (idType sel_id) )
- splitSigmaTy (idType sel_id) -- Selectors can be overloaded
+ (_, _, tau) = splitSigmaTy (idType sel_id) -- Selectors can be overloaded
-- when the data type has a context
Just (data_ty, _) = splitFunTy_maybe tau -- Must succeed since sel_id is a selector
(tycon, _, data_cons) = splitAlgTyConApp data_ty
%* *
%************************************************************************
-Between the renamer and the first invocation of the UsageSP inference,
-identifiers read from interface files will have usage information in
-their types, whereas other identifiers will not. The unannotTy here
-in @tcId@ prevents this information from pointlessly propagating
-further prior to the first usage inference.
-
\begin{code}
tcId :: Name -> NF_TcM (TcExpr, LIE, TcType)
ATcId tc_id -> instantiate_it (OccurrenceOf tc_id) tc_id (idType tc_id)
AGlobal (AnId id) -> tcInstId id `thenNF_Tc` \ (tyvars, theta, tau) ->
instantiate_it2 (OccurrenceOf id) id tyvars theta tau
-
where
-- The instantiate_it loop runs round instantiating the Id.
-- It has to be a loop because we are now prepared to entertain
ListComp -> unifyListTy res_ty `thenTc_` returnTc ()
_ -> returnTc ()) `thenTc_`
- tcStmts do_or_lc (mkAppTy m) stmts elt_ty `thenTc` \ (stmts', stmts_lie) ->
+ tcStmts do_or_lc (mkAppTy m) elt_ty src_loc stmts `thenTc` \ ((stmts', _), stmts_lie) ->
-- Build the then and zero methods in case we need them
-- It's important that "then" and "return" appear just once in the final LIE,
zonkStmts [] = returnNF_Tc []
+zonkStmts (ParStmtOut bndrstmtss : stmts)
+ = mapNF_Tc (mapNF_Tc zonkId) bndrss `thenNF_Tc` \ new_bndrss ->
+ let new_binders = concat new_bndrss in
+ mapNF_Tc zonkStmts stmtss `thenNF_Tc` \ new_stmtss ->
+ tcExtendGlobalValEnv new_binders $
+ zonkStmts stmts `thenNF_Tc` \ new_stmts ->
+ returnNF_Tc (ParStmtOut (zip new_bndrss new_stmtss) : new_stmts)
+ where (bndrss, stmtss) = unzip bndrstmtss
+
zonkStmts [ReturnStmt expr]
= zonkExpr expr `thenNF_Tc` \ new_expr ->
returnNF_Tc [ReturnStmt new_expr]
import MkId ( mkCCallOpId )
import IdInfo
import DataCon ( dataConSig, dataConArgTys )
-import Type ( mkTyVarTys, splitAlgTyConApp_maybe, unUsgTy )
+import Type ( mkTyVarTys, splitAlgTyConApp_maybe )
import Var ( mkTyVar, tyVarKind )
import Name ( Name, isLocallyDefined )
import Demand ( wwLazy )
mapTc tcCoreExpr args `thenTc` \ args' ->
let
-- Put the missing type arguments back in
- con_args = map (Type . unUsgTy . exprType) args' ++ args'
+ con_args = map (Type . exprType) args' ++ args'
in
returnTc (mkApps (Var con_id) con_args)
= tcCoreExpr expr `thenTc` \ expr' ->
case note of
UfCoerce to_ty -> tcHsType to_ty `thenTc` \ to_ty' ->
- returnTc (Note (Coerce (unUsgTy to_ty')
- (unUsgTy (exprType expr'))) expr')
+ returnTc (Note (Coerce to_ty'
+ (exprType expr')) expr')
UfInlineCall -> returnTc (Note InlineCall expr')
UfInlineMe -> returnTc (Note InlineMe expr')
UfSCC cc -> returnTc (Note (SCC cc) expr')
import Type ( splitDFunTy, isTyVarTy,
splitTyConApp_maybe, splitDictTy,
splitAlgTyConApp_maybe, splitForAllTys,
- unUsgTy, tyVarsOfTypes, mkClassPred, mkTyVarTy,
+ tyVarsOfTypes, mkClassPred, mkTyVarTy,
getClassTys_maybe
)
import Subst ( mkTopTyVarSubst, substClasses )
= plusAssoc_C AndMonoBinds (getGenericBinds m1) (getGenericBinds m2)
getGenericBinds (FunMonoBind id infixop matches loc)
- = mapAssoc wrap (foldr add emptyAssoc matches)
+ = mapAssoc wrap (foldl add emptyAssoc matches)
+ -- Using foldl not foldr is vital, else
+ -- we reverse the order of the bindings!
where
- add match env = case maybeGenericMatch match of
+ add env match = case maybeGenericMatch match of
Nothing -> env
Just (ty, match') -> extendAssoc_C (++) env (ty, [match'])
-- emit an error message. This in turn means that we don't
-- mention the constructor, which doesn't exist for CCallable, CReturnable
-- Hardly beautiful, but only three extra lines.
- HsApp (TyApp (HsVar eRROR_ID) [(unUsgTy . idType) this_dict_id])
+ HsApp (TyApp (HsVar eRROR_ID) [idType this_dict_id])
(HsLit (HsString msg))
| otherwise -- The common case
import TcMonad
import TcMonoType ( kcHsSigType, tcTyVars, checkSigTyVars, tcHsSigType, sigPatCtxt )
import Inst ( LIE, plusLIE, emptyLIE, plusLIEs )
-import TcEnv ( tcExtendTyVarEnv, tcExtendLocalValEnv, tcExtendGlobalTyVars )
+import TcEnv ( TcId, tcExtendTyVarEnv, tcExtendLocalValEnv, tcExtendGlobalTyVars )
import TcPat ( tcPat, tcPatBndr_NoSigs, polyPatSig )
import TcType ( TcType, newTyVarTy )
import TcBinds ( tcBindsAndThen )
import TcSimplify ( tcSimplifyAndCheck, bindInstsOfLocalFuns )
-import TcUnify ( unifyFunTy, unifyTauTy )
+import TcUnify ( unifyFunTy, unifyTauTy, unifyListTy )
import Name ( Name )
import TysWiredIn ( boolTy )
import BasicTypes ( RecFlag(..) )
-import Type ( tyVarsOfType, isTauTy, mkFunTy, boxedTypeKind, openTypeKind )
+import Type ( tyVarsOfType, isTauTy, mkArrowKind, mkAppTy, mkFunTy,
+ boxedTypeKind, openTypeKind )
+import SrcLoc ( SrcLoc )
import VarSet
import Var ( Id )
import Bag
= tcBindsAndThen glue_on binds (tc_grhss grhss)
where
tc_grhss grhss
- = mapAndUnzipTc tc_grhs grhss `thenTc` \ (grhss', lies) ->
+ = mapAndUnzipTc tc_grhs grhss `thenTc` \ (grhss', lies) ->
returnTc (GRHSs grhss' EmptyBinds (Just expected_ty), plusLIEs lies)
tc_grhs (GRHS guarded locn)
= tcAddSrcLoc locn $
- tcStmts ctxt (\ty -> ty) guarded expected_ty `thenTc` \ (guarded', lie) ->
+ tcStmts ctxt (\ty -> ty) expected_ty locn guarded
+ `thenTc` \ ((guarded', _), lie) ->
returnTc (GRHS guarded' locn, lie)
\end{code}
\begin{code}
+tcParStep src_loc stmts
+ = newTyVarTy (mkArrowKind boxedTypeKind boxedTypeKind) `thenTc` \ m ->
+ newTyVarTy boxedTypeKind `thenTc` \ elt_ty ->
+ unifyListTy (mkAppTy m elt_ty) `thenTc_`
+
+ tcStmts ListComp (mkAppTy m) elt_ty src_loc stmts `thenTc` \ ((stmts', val_env), stmts_lie) ->
+ returnTc (stmts', val_env, stmts_lie)
+
tcStmts :: StmtCtxt
- -> (TcType -> TcType) -- m, the relationship type of pat and rhs in pat <- rhs
- -> [RenamedStmt]
+ -> (TcType -> TcType) -- m, the relationship type of pat and rhs in pat <- rhs
-> TcType -- elt_ty, where type of the comprehension is (m elt_ty)
- -> TcM ([TcStmt], LIE)
+ -> SrcLoc
+ -> [RenamedStmt]
+ -> TcM (([TcStmt], [(Name, TcId)]), LIE)
+
+tcStmts do_or_lc m elt_ty loc (ParStmtOut bndrstmtss : stmts)
+ = let (bndrss, stmtss) = unzip bndrstmtss in
+ mapAndUnzip3Tc (tcParStep loc) stmtss `thenTc` \ (stmtss', val_envs, lies) ->
+ let outstmts = zip (map (map snd) val_envs) stmtss'
+ lie = plusLIEs lies
+ new_val_env = concat val_envs
+ in
+ tcExtendLocalValEnv new_val_env (
+ tcStmts do_or_lc m elt_ty loc stmts) `thenTc` \ ((stmts', rest_val_env), stmts_lie) ->
+ returnTc ((ParStmtOut outstmts : stmts', rest_val_env ++ new_val_env), lie `plusLIE` stmts_lie)
-tcStmts do_or_lc m (stmt@(ReturnStmt exp) : stmts) elt_ty
+tcStmts do_or_lc m elt_ty loc (stmt@(ReturnStmt exp) : stmts)
= ASSERT( null stmts )
tcSetErrCtxt (stmtCtxt do_or_lc stmt) $
tcExpr exp elt_ty `thenTc` \ (exp', exp_lie) ->
- returnTc ([ReturnStmt exp'], exp_lie)
+ returnTc (([ReturnStmt exp'], []), exp_lie)
-- ExprStmt at the end
-tcStmts do_or_lc m [stmt@(ExprStmt exp src_loc)] elt_ty
+tcStmts do_or_lc m elt_ty loc [stmt@(ExprStmt exp src_loc)]
= tcSetErrCtxt (stmtCtxt do_or_lc stmt) $
tcExpr exp (m elt_ty) `thenTc` \ (exp', exp_lie) ->
- returnTc ([ExprStmt exp' src_loc], exp_lie)
+ returnTc (([ExprStmt exp' src_loc], []), exp_lie)
-- ExprStmt not at the end
-tcStmts do_or_lc m (stmt@(ExprStmt exp src_loc) : stmts) elt_ty
+tcStmts do_or_lc m elt_ty loc (stmt@(ExprStmt exp src_loc) : stmts)
= ASSERT( isDoStmt do_or_lc )
tcAddSrcLoc src_loc (
tcSetErrCtxt (stmtCtxt do_or_lc stmt) $
newTyVarTy openTypeKind `thenNF_Tc` \ any_ty ->
tcExpr exp (m any_ty)
) `thenTc` \ (exp', exp_lie) ->
- tcStmts do_or_lc m stmts elt_ty `thenTc` \ (stmts', stmts_lie) ->
- returnTc (ExprStmt exp' src_loc : stmts',
+ tcStmts do_or_lc m elt_ty loc stmts `thenTc` \ ((stmts', rest_val_env), stmts_lie) ->
+ returnTc ((ExprStmt exp' src_loc : stmts', rest_val_env),
exp_lie `plusLIE` stmts_lie)
-tcStmts do_or_lc m (stmt@(GuardStmt exp src_loc) : stmts) elt_ty
+tcStmts do_or_lc m elt_ty loc (stmt@(GuardStmt exp src_loc) : stmts)
= ASSERT( not (isDoStmt do_or_lc) )
tcSetErrCtxt (stmtCtxt do_or_lc stmt) (
tcAddSrcLoc src_loc $
tcExpr exp boolTy
) `thenTc` \ (exp', exp_lie) ->
- tcStmts do_or_lc m stmts elt_ty `thenTc` \ (stmts', stmts_lie) ->
- returnTc (GuardStmt exp' src_loc : stmts',
+ tcStmts do_or_lc m elt_ty loc stmts `thenTc` \ ((stmts', rest_val_env), stmts_lie) ->
+ -- ZZ is this right?
+ returnTc ((GuardStmt exp' src_loc : stmts', rest_val_env),
exp_lie `plusLIE` stmts_lie)
-tcStmts do_or_lc m (stmt@(BindStmt pat exp src_loc) : stmts) elt_ty
+tcStmts do_or_lc m elt_ty loc (stmt@(BindStmt pat exp src_loc) : stmts)
= tcAddSrcLoc src_loc (
tcSetErrCtxt (stmtCtxt do_or_lc stmt) $
newTyVarTy boxedTypeKind `thenNF_Tc` \ pat_ty ->
-- Do the rest; we don't need to add the pat_tvs to the envt
-- because they all appear in the pat_ids's types
tcExtendLocalValEnv new_val_env (
- tcStmts do_or_lc m stmts elt_ty
- ) `thenTc` \ (stmts', stmts_lie) ->
+ tcStmts do_or_lc m elt_ty loc stmts
+ ) `thenTc` \ ((stmts', rest_val_env), stmts_lie) ->
-- Reinstate context for existential checks
(mkVarSet zonked_pat_tvs)
lie_avail stmts_lie `thenTc` \ (final_lie, dict_binds) ->
- returnTc (BindStmt pat' exp' src_loc :
- consLetStmt (mkMonoBind dict_binds [] Recursive) stmts',
- lie_req `plusLIE` final_lie)
+ -- ZZ we have to be sure that concating the val_env lists preserves
+ -- shadowing properly...
+ returnTc ((BindStmt pat' exp' src_loc :
+ consLetStmt (mkMonoBind dict_binds [] Recursive) stmts',
+ rest_val_env ++ new_val_env),
+ lie_req `plusLIE` final_lie)
-tcStmts do_or_lc m (LetStmt binds : stmts) elt_ty
+tcStmts do_or_lc m elt_ty loc (LetStmt binds : stmts)
= tcBindsAndThen -- No error context, but a binding group is
combine -- rather a large thing for an error context anyway
binds
- (tcStmts do_or_lc m stmts elt_ty)
+ (tcStmts do_or_lc m elt_ty loc stmts) `thenTc` \ ((stmts', rest_val_env), lie) ->
+ -- ZZ fix val_env
+ returnTc ((stmts', rest_val_env), lie)
where
- combine is_rec binds' stmts' = consLetStmt (mkMonoBind binds' [] is_rec) stmts'
+ combine is_rec binds' (stmts', val_env) = (consLetStmt (mkMonoBind binds' [] is_rec) stmts', undefined)
+tcStmts do_or_lc m elt_ty loc [] = returnTc (([], []), emptyLIE)
isDoStmt DoStmt = True
isDoStmt other = False
tcModule pcs hst get_fixity this_mod decls unf_env
= -- Type-check the type and class decls
- traceTc (text "Tc1") `thenTc_`
tcTyAndClassDecls unf_env decls `thenTc` \ env ->
tcSetEnv env $
let
in
-- Typecheck the instance decls, includes deriving
- traceTc (text "Tc2") `thenTc_`
tcInstDecls1 (pcs_insts pcs) (pcs_PRS pcs)
hst unf_env get_fixity this_mod
tycons decls `thenTc` \ (new_pcs_insts, inst_env, local_inst_info, deriv_binds) ->
tcSetInstEnv inst_env $
-- Default declarations
- traceTc (text "Tc3") `thenTc_`
tcDefaults decls `thenTc` \ defaulting_tys ->
tcSetDefaultTys defaulting_tys $
-- We must do this before mkImplicitDataBinds (which comes next), since
-- the latter looks up unpackCStringId, for example, which is usually
-- imported
- traceTc (text "Tc3") `thenTc_`
tcInterfaceSigs unf_env decls `thenTc` \ sig_ids ->
- traceTc (text "Tc5") `thenTc_` (
tcExtendGlobalValEnv sig_ids $
tcGetEnv `thenTc` \ unf_env ->
tcExtendGlobalValEnv cls_ids $
-- Foreign import declarations next
- traceTc (text "Tc6") `thenTc_`
tcForeignImports decls `thenTc` \ (fo_ids, foi_decls) ->
tcExtendGlobalValEnv fo_ids $
-- Value declarations next.
-- We also typecheck any extra binds that came out of the "deriving" process
- traceTc (text "Tc7") `thenTc_`
tcTopBinds (get_binds decls `ThenBinds` deriv_binds) `thenTc` \ ((val_binds, env), lie_valdecls) ->
tcSetEnv env $
-- Foreign export declarations next
- traceTc (text "Tc8") `thenTc_`
tcForeignExports decls `thenTc` \ (lie_fodecls, foe_binds, foe_decls) ->
-- Second pass over class and instance declarations,
\section[TcMonoType]{Typechecking user-specified @MonoTypes@}
\begin{code}
-module TcMonoType ( tcHsType, tcHsSigType, tcHsBoxedSigType,
- tcContext, tcClassContext, checkAmbiguity,
+module TcMonoType ( tcHsType, tcHsRecType,
+ tcHsSigType, tcHsBoxedSigType,
+ tcRecClassContext, checkAmbiguity,
-- Kind checking
kcHsTyVar, kcHsTyVars, mkTyClTyVars,
import TcHsSyn ( TcId )
import TcMonad
-import TcEnv ( tcExtendTyVarEnv, tcExtendKindEnv,
- tcLookupGlobal, tcLookup,
- tcEnvTcIds, tcEnvTyVars,
- tcGetGlobalTyVars,
- TyThing(..), TcTyThing(..)
+import TcEnv ( tcExtendTyVarEnv, tcLookup, tcLookupGlobal,
+ tcGetGlobalTyVars, tcEnvTcIds, tcEnvTyVars,
+ TyThing(..), TcTyThing(..), tcExtendKindEnv
)
-import TcType ( TcType, TcKind, TcTyVar, TcThetaType, TcTauType,
+import TcType ( TcKind, TcTyVar, TcThetaType, TcTauType,
newKindVar, tcInstSigVar,
zonkKindEnv, zonkTcType, zonkTcTyVars, zonkTcTyVar
)
mkArrowKinds, getTyVar_maybe, getTyVar, splitFunTy_maybe,
tidyOpenType, tidyOpenTypes, tidyTyVar, tidyTyVars,
tyVarsOfType, tyVarsOfPred, mkForAllTys,
- classesOfPreds,
+ classesOfPreds, isUnboxedTupleType, isForAllTy
)
import PprType ( pprType, pprPred )
import Subst ( mkTopTyVarSubst, substTy )
-import Id ( Id, mkVanillaId, idName, idType, idFreeTyVars )
-import Var ( Var, TyVar, mkTyVar, tyVarKind )
+import Id ( mkVanillaId, idName, idType, idFreeTyVars )
+import Var ( Id, Var, TyVar, mkTyVar, tyVarKind )
import VarEnv
import VarSet
import ErrUtils ( Message )
import TyCon ( TyCon, isSynTyCon, tyConArity, tyConKind )
import Class ( ClassContext, classArity, classTyCon )
-import Name ( Name )
+import Name ( Name, isLocallyDefined )
import TysWiredIn ( mkListTy, mkTupleTy, genUnitTyCon )
import UniqFM ( elemUFM )
-import BasicTypes ( Boxity(..) )
+import BasicTypes ( Boxity(..), RecFlag(..), isRec )
import SrcLoc ( SrcLoc )
import Util ( mapAccumL, isSingleton )
import Outputable
-import HscTypes ( TyThing(..) )
+
\end{code}
---------------------------
kcHsType :: RenamedHsType -> TcM TcKind
kcHsType (HsTyVar name) = kcTyVar name
-kcHsType (HsUsgTy _ ty) = kcHsType ty
-kcHsType (HsUsgForAllTy _ ty) = kcHsType ty
kcHsType (HsListTy ty)
= kcBoxedType ty `thenTc` \ tau_ty ->
returnTc boxedTypeKind
-kcHsType (HsTupleTy (HsTupCon _ Boxed) tys)
- = mapTc kcBoxedType tys `thenTc_`
- returnTc boxedTypeKind
-
-kcHsType ty@(HsTupleTy (HsTupCon _ Unboxed) tys)
- = failWithTc (unboxedTupleErr ty)
- -- Unboxed tuples are illegal everywhere except
- -- just after a function arrow (see kcFunResType)
+kcHsType (HsTupleTy (HsTupCon _ boxity) tys)
+ = mapTc kcTypeType tys `thenTc_`
+ returnTc (case boxity of
+ Boxed -> boxedTypeKind
+ Unboxed -> unboxedTypeKind)
kcHsType (HsFunTy ty1 ty2)
= kcTypeType ty1 `thenTc_`
- kcFunResType ty2 `thenTc_`
+ kcTypeType ty2 `thenTc_`
returnTc boxedTypeKind
kcHsType ty@(HsOpTy ty1 op ty2)
= kcHsTyVars tv_names `thenNF_Tc` \ kind_env ->
tcExtendKindEnv kind_env $
kcHsContext context `thenTc_`
-
- -- Context behaves like a function type
- -- This matters. Return-unboxed-tuple analysis can
- -- give overloaded functions like
- -- f :: forall a. Num a => (# a->a, a->a #)
- -- And we want these to get through the type checker
- if null context then
- kcHsType ty
- else
- kcFunResType ty `thenTc_`
- returnTc boxedTypeKind
-
----------------------------
-kcFunResType :: RenamedHsType -> TcM TcKind
--- The only place an unboxed tuple type is allowed
--- is at the right hand end of an arrow
-kcFunResType (HsTupleTy (HsTupCon _ Unboxed) tys)
- = mapTc kcTypeType tys `thenTc_`
- returnTc unboxedTypeKind
-
-kcFunResType ty = kcHsType ty
+ kcHsType ty `thenTc_`
+ returnTc boxedTypeKind
---------------------------
kcAppKind fun_kind arg_kind
mapTc kcHsType tys `thenTc` \ arg_kinds ->
unifyKind kind (mkArrowKinds arg_kinds boxedTypeKind)
----------------------------
+ ---------------------------
kcTyVar name -- Could be a tyvar or a tycon
= tcLookup name `thenTc` \ thing ->
case thing of
so the kind returned is indeed a Kind not a TcKind
\begin{code}
-tcHsSigType :: RenamedHsType -> TcM TcType
-tcHsSigType ty
- = kcTypeType ty `thenTc_`
- tcHsType ty `thenTc` \ ty' ->
- returnTc (hoistForAllTys ty')
-
-tcHsBoxedSigType :: RenamedHsType -> TcM Type
-tcHsBoxedSigType ty
- = kcBoxedType ty `thenTc_`
- tcHsType ty `thenTc` \ ty' ->
- returnTc (hoistForAllTys ty')
+tcHsSigType, tcHsBoxedSigType :: RenamedHsType -> TcM Type
+ -- Do kind checking, and hoist for-alls to the top
+tcHsSigType ty = kcTypeType ty `thenTc_` tcHsType ty
+tcHsBoxedSigType ty = kcBoxedType ty `thenTc_` tcHsType ty
+
+tcHsType :: RenamedHsType -> TcM Type
+tcHsRecType :: RecFlag -> RenamedHsType -> TcM Type
+ -- Don't do kind checking, but do hoist for-alls to the top
+tcHsType ty = tc_type NonRecursive ty `thenTc` \ ty' -> returnTc (hoistForAllTys ty')
+tcHsRecType wimp_out ty = tc_type wimp_out ty `thenTc` \ ty' -> returnTc (hoistForAllTys ty')
\end{code}
-tcHsType, the main work horse
+%************************************************************************
+%* *
+\subsection{tc_type}
+%* *
+%************************************************************************
+
+tc_type, the main work horse
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ -------------------
+ *** BIG WARNING ***
+ -------------------
+
+tc_type is used to typecheck the types in the RHS of data
+constructors. In the case of recursive data types, that means that
+the type constructors themselves are (partly) black holes. e.g.
+
+ data T a = MkT a [T a]
+
+While typechecking the [T a] on the RHS, T itself is not yet fully
+defined. That in turn places restrictions on what you can check in
+tcHsType; if you poke on too much you get a black hole. I keep
+forgetting this, hence this warning!
+
+The wimp_out argument tells when we are in a mutually-recursive
+group of type declarations, so omit various checks else we
+get a black hole. They'll be done again later, in TcTyClDecls.tcGroup.
+
+ --------------------------
+ *** END OF BIG WARNING ***
+ --------------------------
+
+
\begin{code}
-tcHsType :: RenamedHsType -> TcM Type
-tcHsType ty@(HsTyVar name)
- = tc_app ty []
+tc_type :: RecFlag -> RenamedHsType -> TcM Type
+
+tc_type wimp_out ty@(HsTyVar name)
+ = tc_app wimp_out ty []
-tcHsType (HsListTy ty)
- = tcHsType ty `thenTc` \ tau_ty ->
+tc_type wimp_out (HsListTy ty)
+ = tc_arg_type wimp_out ty `thenTc` \ tau_ty ->
returnTc (mkListTy tau_ty)
-tcHsType (HsTupleTy (HsTupCon _ boxity) tys)
- = mapTc tcHsType tys `thenTc` \ tau_tys ->
+tc_type wimp_out (HsTupleTy (HsTupCon _ boxity) tys)
+ = mapTc tc_tup_arg tys `thenTc` \ tau_tys ->
returnTc (mkTupleTy boxity (length tys) tau_tys)
-
-tcHsType (HsFunTy ty1 ty2)
- = tcHsType ty1 `thenTc` \ tau_ty1 ->
- tcHsType ty2 `thenTc` \ tau_ty2 ->
+ where
+ tc_tup_arg = case boxity of
+ Boxed -> tc_arg_type wimp_out
+ Unboxed -> tc_type wimp_out
+ -- Unboxed tuples can have polymorphic or unboxed args.
+ -- This happens in the workers for functions returning
+ -- product types with polymorphic components
+
+tc_type wimp_out (HsFunTy ty1 ty2)
+ = tc_type wimp_out ty1 `thenTc` \ tau_ty1 ->
+ -- Function argument can be polymorphic, but
+ -- must not be an unboxed tuple
+ checkTc (not (isUnboxedTupleType tau_ty1))
+ (ubxArgTyErr ty1) `thenTc_`
+ tc_type wimp_out ty2 `thenTc` \ tau_ty2 ->
returnTc (mkFunTy tau_ty1 tau_ty2)
-tcHsType (HsNumTy n)
+tc_type wimp_out (HsNumTy n)
= ASSERT(n== 1)
returnTc (mkTyConApp genUnitTyCon [])
-tcHsType (HsOpTy ty1 op ty2) =
- tcHsType ty1 `thenTc` \ tau_ty1 ->
- tcHsType ty2 `thenTc` \ tau_ty2 ->
+tc_type wimp_out (HsOpTy ty1 op ty2) =
+ tc_arg_type wimp_out ty1 `thenTc` \ tau_ty1 ->
+ tc_arg_type wimp_out ty2 `thenTc` \ tau_ty2 ->
tc_fun_type op [tau_ty1,tau_ty2]
-tcHsType (HsAppTy ty1 ty2)
- = tc_app ty1 [ty2]
+tc_type wimp_out (HsAppTy ty1 ty2)
+ = tc_app wimp_out ty1 [ty2]
-tcHsType (HsPredTy pred)
- = tcClassAssertion True pred `thenTc` \ pred' ->
+tc_type wimp_out (HsPredTy pred)
+ = tc_pred wimp_out pred `thenTc` \ pred' ->
returnTc (mkPredTy pred')
-tcHsType full_ty@(HsForAllTy (Just tv_names) ctxt ty)
+tc_type wimp_out full_ty@(HsForAllTy (Just tv_names) ctxt ty)
= let
- kind_check = kcHsContext ctxt `thenTc_` kcFunResType ty
+ kind_check = kcHsContext ctxt `thenTc_` kcHsType ty
in
- tcHsTyVars tv_names kind_check $ \ tyvars ->
- tcContext ctxt `thenTc` \ theta ->
- tcHsType ty `thenTc` \ tau ->
- checkAmbiguity is_source tyvars theta tau
+ tcHsTyVars tv_names kind_check $ \ tyvars ->
+ tc_context wimp_out ctxt `thenTc` \ theta ->
+
+ -- Context behaves like a function type
+ -- This matters. Return-unboxed-tuple analysis can
+ -- give overloaded functions like
+ -- f :: forall a. Num a => (# a->a, a->a #)
+ -- And we want these to get through the type checker
+ (if null theta then
+ tc_arg_type wimp_out ty
+ else
+ tc_type wimp_out ty
+ ) `thenTc` \ tau ->
+
+ checkAmbiguity wimp_out is_source tyvars theta tau
where
is_source = case tv_names of
(UserTyVar _ : _) -> True
other -> False
-checkAmbiguity :: Bool -> [TyVar] -> ThetaType -> Type -> TcM Type
- -- Check for ambiguity
- -- forall V. P => tau
- -- is ambiguous if P contains generic variables
- -- (i.e. one of the Vs) that are not mentioned in tau
+
+ -- tc_arg_type checks that the argument of a
+ -- type appplication isn't a for-all type or an unboxed tuple type
+ -- For example, we want to reject things like:
--
- -- However, we need to take account of functional dependencies
- -- when we speak of 'mentioned in tau'. Example:
- -- class C a b | a -> b where ...
- -- Then the type
- -- forall x y. (C x y) => x
- -- is not ambiguous because x is mentioned and x determines y
+ -- instance Ord a => Ord (forall s. T s a)
+ -- and
+ -- g :: T s (forall b.b)
--
- -- NOTE: In addition, GHC insists that at least one type variable
- -- in each constraint is in V. So we disallow a type like
- -- forall a. Eq b => b -> b
- -- even in a scope where b is in scope.
- -- This is the is_free test below.
-
- -- Notes on the 'is_source_polytype' test above
- -- Check ambiguity only for source-program types, not
- -- for types coming from inteface files. The latter can
- -- legitimately have ambiguous types. Example
- -- class S a where s :: a -> (Int,Int)
- -- instance S Char where s _ = (1,1)
- -- f:: S a => [a] -> Int -> (Int,Int)
- -- f (_::[a]) x = (a*x,b)
- -- where (a,b) = s (undefined::a)
- -- Here the worker for f gets the type
- -- fw :: forall a. S a => Int -> (# Int, Int #)
- --
- -- If the list of tv_names is empty, we have a monotype,
- -- and then we don't need to check for ambiguity either,
- -- because the test can't fail (see is_ambig).
-
-checkAmbiguity is_source_polytype forall_tyvars theta tau
- = mapTc_ check_pred theta `thenTc_`
- returnTc sigma_ty
- where
- sigma_ty = mkSigmaTy forall_tyvars theta tau
- tau_vars = tyVarsOfType tau
- fds = instFunDepsOfTheta theta
- tvFundep = tyVarFunDep fds
- extended_tau_vars = oclose tvFundep tau_vars
+ -- Other unboxed types are very occasionally allowed as type
+ -- arguments depending on the kind of the type constructor
- is_ambig ct_var = (ct_var `elem` forall_tyvars) &&
- not (ct_var `elemUFM` extended_tau_vars)
- is_free ct_var = not (ct_var `elem` forall_tyvars)
-
- check_pred pred = checkTc (not any_ambig) (ambigErr pred sigma_ty) `thenTc_`
- checkTc (not all_free) (freeErr pred sigma_ty)
- where
- ct_vars = varSetElems (tyVarsOfPred pred)
- all_free = all is_free ct_vars
- any_ambig = is_source_polytype && any is_ambig ct_vars
+tc_arg_type wimp_out arg_ty
+ | isRec wimp_out
+ = tc_type wimp_out arg_ty
+
+ | otherwise
+ = tc_type wimp_out arg_ty `thenTc` \ arg_ty' ->
+ checkTc (not (isForAllTy arg_ty')) (polyArgTyErr arg_ty) `thenTc_`
+ checkTc (not (isUnboxedTupleType arg_ty')) (ubxArgTyErr arg_ty) `thenTc_`
+ returnTc arg_ty'
+
+tc_arg_types wimp_out arg_tys = mapTc (tc_arg_type wimp_out) arg_tys
\end{code}
Help functions for type applications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{code}
-tc_app :: RenamedHsType -> [RenamedHsType] -> TcM Type
-tc_app (HsAppTy ty1 ty2) tys
- = tc_app ty1 (ty2:tys)
+tc_app :: RecFlag -> RenamedHsType -> [RenamedHsType] -> TcM Type
+tc_app wimp_out (HsAppTy ty1 ty2) tys
+ = tc_app wimp_out ty1 (ty2:tys)
-tc_app ty tys
+tc_app wimp_out ty tys
= tcAddErrCtxt (appKindCtxt pp_app) $
- mapTc tcHsType tys `thenTc` \ arg_tys ->
+ tc_arg_types wimp_out tys `thenTc` \ arg_tys ->
case ty of
HsTyVar fun -> tc_fun_type fun arg_tys
- other -> tcHsType ty `thenTc` \ fun_ty ->
+ other -> tc_type wimp_out ty `thenTc` \ fun_ty ->
returnNF_Tc (mkAppTys fun_ty arg_tys)
where
pp_app = ppr ty <+> sep (map pprParendHsType tys)
AGlobal (ATyCon tc)
| isSynTyCon tc -> checkTc arity_ok err_msg `thenTc_`
returnTc (mkAppTys (mkSynTy tc (take arity arg_tys))
- (drop arity arg_tys))
+ (drop arity arg_tys))
- | otherwise -> returnTc (mkTyConApp tc arg_tys)
+ | otherwise -> returnTc (mkTyConApp tc arg_tys)
where
arity_ok = arity <= n_args
Contexts
~~~~~~~~
\begin{code}
-tcClassContext :: RenamedContext -> TcM ClassContext
+tcRecClassContext :: RecFlag -> RenamedContext -> TcM ClassContext
-- Used when we are expecting a ClassContext (i.e. no implicit params)
-tcClassContext context
- = tcContext context `thenTc` \ theta ->
+tcRecClassContext wimp_out context
+ = tc_context wimp_out context `thenTc` \ theta ->
returnTc (classesOfPreds theta)
-tcContext :: RenamedContext -> TcM ThetaType
-tcContext context = mapTc (tcClassAssertion False) context
+tc_context :: RecFlag -> RenamedContext -> TcM ThetaType
+tc_context wimp_out context = mapTc (tc_pred wimp_out) context
-tcClassAssertion ccall_ok assn@(HsPClass class_name tys)
+tc_pred wimp_out assn@(HsPClass class_name tys)
= tcAddErrCtxt (appKindCtxt (ppr assn)) $
- mapTc tcHsType tys `thenTc` \ arg_tys ->
+ tc_arg_types wimp_out tys `thenTc` \ arg_tys ->
tcLookupGlobal class_name `thenTc` \ thing ->
case thing of
- AClass clas -> checkTc (arity == n_tys) err `thenTc_`
+ AClass clas -> checkTc (arity == n_tys) err `thenTc_`
returnTc (Class clas arg_tys)
where
arity = classArity clas
other -> failWithTc (wrongThingErr "class" (AGlobal thing) class_name)
-tcClassAssertion ccall_ok assn@(HsPIParam name ty)
+tc_pred wimp_out assn@(HsPIParam name ty)
= tcAddErrCtxt (appKindCtxt (ppr assn)) $
- tcHsType ty `thenTc` \ arg_ty ->
+ tc_arg_type wimp_out ty `thenTc` \ arg_ty ->
returnTc (IParam name arg_ty)
\end{code}
+Check for ambiguity
+~~~~~~~~~~~~~~~~~~~
+ forall V. P => tau
+is ambiguous if P contains generic variables
+(i.e. one of the Vs) that are not mentioned in tau
+
+However, we need to take account of functional dependencies
+when we speak of 'mentioned in tau'. Example:
+ class C a b | a -> b where ...
+Then the type
+ forall x y. (C x y) => x
+is not ambiguous because x is mentioned and x determines y
+
+NOTE: In addition, GHC insists that at least one type variable
+in each constraint is in V. So we disallow a type like
+ forall a. Eq b => b -> b
+even in a scope where b is in scope.
+This is the is_free test below.
+
+Notes on the 'is_source_polytype' test above
+Check ambiguity only for source-program types, not
+for types coming from inteface files. The latter can
+legitimately have ambiguous types. Example
+ class S a where s :: a -> (Int,Int)
+ instance S Char where s _ = (1,1)
+ f:: S a => [a] -> Int -> (Int,Int)
+ f (_::[a]) x = (a*x,b)
+ where (a,b) = s (undefined::a)
+Here the worker for f gets the type
+ fw :: forall a. S a => Int -> (# Int, Int #)
+
+If the list of tv_names is empty, we have a monotype,
+and then we don't need to check for ambiguity either,
+because the test can't fail (see is_ambig).
+
+\begin{code}
+checkAmbiguity wimp_out is_source_polytype forall_tyvars theta tau
+ | isRec wimp_out = returnTc sigma_ty
+ | otherwise = mapTc_ check_pred theta `thenTc_`
+ returnTc sigma_ty
+ where
+ sigma_ty = mkSigmaTy forall_tyvars theta tau
+ tau_vars = tyVarsOfType tau
+ fds = instFunDepsOfTheta theta
+ tvFundep = tyVarFunDep fds
+ extended_tau_vars = oclose tvFundep tau_vars
+
+ is_ambig ct_var = (ct_var `elem` forall_tyvars) &&
+ not (ct_var `elemUFM` extended_tau_vars)
+ is_free ct_var = not (ct_var `elem` forall_tyvars)
+
+ check_pred pred = checkTc (not any_ambig) (ambigErr pred sigma_ty) `thenTc_`
+ checkTc (is_ip pred || not all_free) (freeErr pred sigma_ty)
+ where
+ ct_vars = varSetElems (tyVarsOfPred pred)
+ all_free = all is_free ct_vars
+ any_ambig = is_source_polytype && any is_ambig ct_vars
+ is_ip (IParam _ _) = True
+ is_ip _ = False
+\end{code}
+
%************************************************************************
%* *
\subsection{Type variables, with knot tying!}
-- from the zonked tyvar to the in-scope one
-- If any of the in-scope tyvars zonk to a type, then ignore them;
-- that'll be caught later when we back up to their type sig
- tcGetEnv `thenNF_Tc` \ env ->
- let
- in_scope_tvs = tcEnvTyVars env
- in
+ tcGetEnv `thenNF_Tc` \ env ->
+ let
+ in_scope_tvs = tcEnvTyVars env
+ in
zonkTcTyVars in_scope_tvs `thenNF_Tc` \ in_scope_tys ->
let
in_scope_assoc = [ (zonked_tv, in_scope_tv)
-- a) get the local TcIds from the environment,
-- and pass them to find_globals (they might have tv free)
-- b) similarly, find any free_tyvars that mention tv
- then tcGetEnv `thenNF_Tc` \ tc_env ->
- find_globals tv tidy_env [] (tcEnvTcIds tc_env) `thenNF_Tc` \ (tidy_env1, globs) ->
+ then tcGetEnv `thenNF_Tc` \ ve ->
+ find_globals tv tidy_env [] (tcEnvTcIds ve) `thenNF_Tc` \ (tidy_env1, globs) ->
find_frees tv tidy_env1 [] (varSetElems free_tyvars) `thenNF_Tc` \ (tidy_env2, frees) ->
returnNF_Tc (tidy_env2, acc, escape_msg sig_tyvar tv globs frees : msgs)
= returnNF_Tc (tidy_env, acc)
find_globals tv tidy_env acc (id:ids)
- | isEmptyVarSet (idFreeTyVars id)
+ | not (isLocallyDefined id) ||
+ isEmptyVarSet (idFreeTyVars id)
= find_globals tv tidy_env acc ids
| otherwise
nest 4 (ptext SLIT("in the type") <+> quotes (ppr ty))
]
-unboxedTupleErr ty
- = sep [ptext (SLIT("Illegal unboxed tuple as a function or contructor argument:")), nest 4 (ppr ty)]
+polyArgTyErr ty = ptext SLIT("Illegal polymorphic type as argument:") <+> ppr ty
+ubxArgTyErr ty = ptext SLIT("Illegal unboxed tuple type as argument:") <+> ppr ty
\end{code}
isIfaceSigDecl, isClassDecl, isSynDecl, isClassOpSig
)
import RnHsSyn ( RenamedHsDecl, RenamedTyClDecl, tyClDeclFVs )
-import BasicTypes ( RecFlag(..), NewOrData(..) )
+import BasicTypes ( RecFlag(..), NewOrData(..), isRec )
import TcMonad
import TcEnv ( TcEnv, RecTcEnv, TcTyThing(..), TyThing(..), TyThingDetails(..),
Step 5: tcTyClDecl1
In this environment, walk over the decls, constructing the TyCons and Classes.
This uses in a strict way items (a)-(c) above, which is why they must
- be constructed in Step 4.
- Feed the results back to Step 4.
+ be constructed in Step 4. Feed the results back to Step 4.
+ For this step, pass the is-recursive flag as the wimp-out flag
+ to tcTyClDecl1.
+
+Step 6: tcTyClDecl1 again
+ For a recursive group only, check all the decls again, just
+ but this time with the wimp flag off. Now we can check things
+ like whether a function argument is an unboxed tuple, looking
+ through type synonyms properly. We can't do that in Step 5.
+
The knot-tying parameters: @rec_details_list@ is an alist mapping @Name@s to
@TyThing@s. @rec_vrcs@ is a finite map from @Name@s to @ArgVrcs@s.
rec_vrcs = calcTyConArgVrcs [tc | (_, ATyCon tc) <- all_tyclss]
in
-- Step 5
- tcExtendGlobalEnv all_tyclss $
- mapTc (tcTyClDecl1 unf_env) decls `thenTc` \ tycls_details ->
- tcGetEnv `thenNF_Tc` \ env ->
+ tcExtendGlobalEnv all_tyclss $
+ mapTc (tcTyClDecl1 is_rec unf_env) decls `thenTc` \ tycls_details ->
+
+ -- Return results
+ tcGetEnv `thenNF_Tc` \ env ->
returnTc (tycls_details, env)
) `thenTc` \ (_, env) ->
+
+ -- Step 6
+ -- For a recursive group, check all the types again,
+ -- this time with the wimp flag off
+ (if isRec is_rec then
+ tcSetEnv env (mapTc_ (tcTyClDecl1 NonRecursive unf_env) decls)
+ else
+ returnTc ()
+ ) `thenTc_`
+
returnTc env
where
is_rec = case scc of
AcyclicSCC decl -> [decl]
CyclicSCC decls -> decls
-tcTyClDecl1 unf_env decl
- = tcAddDeclCtxt decl $
- if isClassDecl decl then
- tcClassDecl1 unf_env decl
- else
- tcTyDecl1 decl
+tcTyClDecl1 is_rec unf_env decl
+ | isClassDecl decl = tcAddDeclCtxt decl (tcClassDecl1 is_rec unf_env decl)
+ | otherwise = tcAddDeclCtxt decl (tcTyDecl1 is_rec decl)
\end{code}
kcHsType rhs `thenTc` \ rhs_kind ->
unifyKind result_kind rhs_kind
-kcTyClDecl decl@(TyData _ context tycon_name hs_tyvars con_decls _ _ loc _ _)
+kcTyClDecl decl@(TyData new_or_data context tycon_name hs_tyvars con_decls _ _ loc _ _)
= tcAddDeclCtxt decl $
kcTyClDeclBody tycon_name hs_tyvars $ \ result_kind ->
kcHsContext context `thenTc_`
= tcAddSrcLoc loc $
kcHsTyVars ex_tvs `thenNF_Tc` \ kind_env ->
tcExtendKindEnv kind_env $
- kcConDetails ex_ctxt details
+ kcConDetails new_or_data ex_ctxt details
kcTyClDecl decl@(ClassDecl context class_name
hs_tyvars fundeps class_sigs
mkClassEdges decl@(ClassDecl ctxt name _ _ _ _ _ _) = Just (decl, name, [c | HsPClass c _ <- ctxt])
mkClassEdges other_decl = Nothing
-----------------------------------------------------
mkEdges :: RenamedTyClDecl -> (RenamedTyClDecl, Name, [Name])
mkEdges decl = (decl, tyClDeclName decl, tyClDeclFTVs decl)
\end{code}
import HsSyn ( MonoBinds(..),
TyClDecl(..), ConDecl(..), ConDetails(..), BangType(..),
- getBangType
+ getBangType, conDetailsTys
)
import RnHsSyn ( RenamedTyClDecl, RenamedConDecl, RenamedContext )
import TcHsSyn ( TcMonoBinds, idsToMonoBinds )
-import BasicTypes ( NewOrData(..) )
+import BasicTypes ( NewOrData(..), RecFlag )
-import TcMonoType ( tcHsType, tcHsSigType, tcHsBoxedSigType, tcHsTyVars, tcClassContext,
- kcHsContext, kcHsSigType
+import TcMonoType ( tcHsRecType, tcHsTyVars, tcRecClassContext,
+ kcHsContext, kcHsSigType, kcHsBoxedSigType
)
import TcEnv ( tcExtendTyVarEnv,
tcLookupTyCon, tcLookupGlobalId,
%************************************************************************
\begin{code}
-tcTyDecl1 :: RenamedTyClDecl -> TcM (Name, TyThingDetails)
-tcTyDecl1 (TySynonym tycon_name tyvar_names rhs src_loc)
+tcTyDecl1 :: RecFlag -> RenamedTyClDecl -> TcM (Name, TyThingDetails)
+tcTyDecl1 is_rec (TySynonym tycon_name tyvar_names rhs src_loc)
= tcLookupTyCon tycon_name `thenNF_Tc` \ tycon ->
tcExtendTyVarEnv (tyConTyVars tycon) $
- tcHsType rhs `thenTc` \ rhs_ty ->
- -- Note tcHsType not tcHsSigType; we allow type synonyms
+ tcHsRecType is_rec rhs `thenTc` \ rhs_ty ->
+ -- Note tcHsRecType not tcHsRecSigType; we allow type synonyms
-- that aren't types; e.g. type List = []
--
-- If the RHS mentions tyvars that aren't in scope, we'll
returnTc (tycon_name, SynTyDetails rhs_ty)
-tcTyDecl1 (TyData new_or_data context tycon_name _ con_decls _ derivings src_loc name1 name2)
+tcTyDecl1 is_rec (TyData new_or_data context tycon_name _ con_decls _ derivings src_loc name1 name2)
= tcLookupTyCon tycon_name `thenNF_Tc` \ tycon ->
let
tyvars = tyConTyVars tycon
tcExtendTyVarEnv tyvars $
-- Typecheck the pieces
- tcClassContext context `thenTc` \ ctxt ->
- mapTc (tcConDecl new_or_data tycon tyvars ctxt) con_decls `thenTc` \ data_cons ->
-
+ tcRecClassContext is_rec context `thenTc` \ ctxt ->
+ mapTc (tcConDecl is_rec new_or_data tycon tyvars ctxt) con_decls `thenTc` \ data_cons ->
returnTc (tycon_name, DataTyDetails ctxt data_cons)
\end{code}
%************************************************************************
\begin{code}
-kcConDetails :: RenamedContext -> ConDetails Name -> TcM ()
-kcConDetails ex_ctxt details
+kcConDetails :: NewOrData -> RenamedContext -> ConDetails Name -> TcM ()
+kcConDetails new_or_data ex_ctxt details
= kcHsContext ex_ctxt `thenTc_`
- kc_con_details details
+ mapTc_ kc_sig_type (conDetailsTys details)
where
- kc_con_details (VanillaCon btys) = mapTc_ kc_bty btys
- kc_con_details (InfixCon bty1 bty2) = mapTc_ kc_bty [bty1,bty2]
- kc_con_details (RecCon flds) = mapTc_ kc_field flds
-
- kc_field (_, bty) = kc_bty bty
+ kc_sig_type = case new_or_data of
+ DataType -> kcHsSigType
+ NewType -> kcHsBoxedSigType
+ -- Can't allow an unboxed type here, because we're effectively
+ -- going to remove the constructor while coercing it to a boxed type.
- kc_bty bty = kcHsSigType (getBangType bty)
-tcConDecl :: NewOrData -> TyCon -> [TyVar] -> ClassContext -> RenamedConDecl -> TcM DataCon
+tcConDecl :: RecFlag -> NewOrData -> TyCon -> [TyVar] -> ClassContext -> RenamedConDecl -> TcM DataCon
-tcConDecl new_or_data tycon tyvars ctxt (ConDecl name wkr_name ex_tvs ex_ctxt details src_loc)
- = tcAddSrcLoc src_loc $
- tcHsTyVars ex_tvs (kcConDetails ex_ctxt details) $ \ ex_tyvars ->
- tcClassContext ex_ctxt `thenTc` \ ex_theta ->
+tcConDecl is_rec new_or_data tycon tyvars ctxt (ConDecl name wkr_name ex_tvs ex_ctxt details src_loc)
+ = tcAddSrcLoc src_loc $
+ tcHsTyVars ex_tvs (kcConDetails new_or_data ex_ctxt details) $ \ ex_tyvars ->
+ tcRecClassContext is_rec ex_ctxt `thenTc` \ ex_theta ->
case details of
VanillaCon btys -> tc_datacon ex_tyvars ex_theta btys
InfixCon bty1 bty2 -> tc_datacon ex_tyvars ex_theta [bty1,bty2]
RecCon fields -> tc_rec_con ex_tyvars ex_theta fields
where
- tc_sig_type = case new_or_data of
- DataType -> tcHsSigType
- NewType -> tcHsBoxedSigType
- -- Can't allow an unboxed type here, because we're effectively
- -- going to remove the constructor while coercing it to a boxed type.
-
tc_datacon ex_tyvars ex_theta btys
= let
arg_stricts = map getBangStrictness btys
tys = map getBangType btys
in
- mapTc tc_sig_type tys `thenTc` \ arg_tys ->
+ mapTc (tcHsRecType is_rec) tys `thenTc` \ arg_tys ->
mk_data_con ex_tyvars ex_theta arg_stricts arg_tys []
tc_rec_con ex_tyvars ex_theta fields
(map fieldLabelType field_labels) field_labels
tc_field ((field_label_names, bty), tag)
- = tc_sig_type (getBangType bty) `thenTc` \ field_ty ->
+ = tcHsRecType is_rec (getBangType bty) `thenTc` \ field_ty ->
returnTc [mkFieldLabel (getName name) tycon field_ty tag | name <- field_label_names]
mk_data_con ex_tyvars ex_theta arg_stricts arg_tys fields
-- friends:
import TypeRep ( Type(..), Kind, TyNote(..) ) -- friend
import Type ( PredType(..),
- getTyVar, mkAppTy,
- splitPredTy_maybe, splitForAllTys, isNotUsgTy,
+ getTyVar, mkAppTy, mkUTy,
+ splitPredTy_maybe, splitForAllTys,
isTyVarTy, mkTyVarTy, mkTyVarTys,
openTypeKind, boxedTypeKind,
superKind, superBoxity,
case maybe_ty of
Just ty | not (isTyVarTy ty) -> go syn_t ty ts
other -> returnNF_Tc (reverse ts, syn_t)
+ go syn_t (UsageTy _ t) ts = go syn_t t ts
go syn_t t ts = returnNF_Tc (reverse ts, syn_t)
\end{code}
Putting is easy:
\begin{code}
-tcPutTyVar tyvar ty = tcWriteMutTyVar tyvar (Just ty) `thenNF_Tc_`
+tcPutTyVar tyvar ty = UASSERT2( not (isUTy ty), ppr tyvar <+> ppr ty )
+ tcWriteMutTyVar tyvar (Just ty) `thenNF_Tc_`
returnNF_Tc ty
\end{code}
go (NoteTy (FTVNote _) ty2) = go ty2 -- Discard free-tyvar annotations
- go (NoteTy (UsgNote usg) ty2) = go ty2 `thenNF_Tc` \ ty2' ->
- returnNF_Tc (NoteTy (UsgNote usg) ty2')
-
- go (NoteTy (UsgForAll uv) ty2)= go ty2 `thenNF_Tc` \ ty2' ->
- returnNF_Tc (NoteTy (UsgForAll uv) ty2')
-
go (PredTy p) = go_pred p `thenNF_Tc` \ p' ->
returnNF_Tc (PredTy p')
go arg `thenNF_Tc` \ arg' ->
returnNF_Tc (mkAppTy fun' arg')
+ go (UsageTy u ty) = go u `thenNF_Tc` \ u' ->
+ go ty `thenNF_Tc` \ ty' ->
+ returnNF_Tc (mkUTy u' ty')
+
-- The two interesting cases!
go (TyVarTy tyvar) = zonkTyVar unbound_var_fn tyvar
= tcGetTyVar tyvar `thenNF_Tc` \ maybe_ty ->
case maybe_ty of
Nothing -> unbound_var_fn tyvar -- Mutable and unbound
- Just other_ty -> ASSERT( isNotUsgTy other_ty )
- zonkType unbound_var_fn other_ty -- Bound
+ Just other_ty -> zonkType unbound_var_fn other_ty -- Bound
\end{code}
typeCon, openKindCon, hasMoreBoxityInfo,
tyVarsOfType, typeKind,
mkFunTy, splitFunTy_maybe, splitTyConApp_maybe,
- isNotUsgTy, splitAppTy_maybe, mkTyConApp,
+ splitAppTy_maybe, mkTyConApp,
tidyOpenType, tidyOpenTypes, tidyTyVar
)
import TyCon ( TyCon, isTupleTyCon, tupleTyConBoxity, tyConArity )
-> TcM ()
-- Always expand synonyms (see notes at end)
- -- (this also throws away FTVs and usage annots)
+ -- (this also throws away FTVs)
uTys ps_ty1 (NoteTy _ ty1) ps_ty2 ty2 = uTys ps_ty1 ty1 ps_ty2 ty2
uTys ps_ty1 ty1 ps_ty2 (NoteTy _ ty2) = uTys ps_ty1 ty1 ps_ty2 ty2
+ -- Ignore usage annotations inside typechecker
+uTys ps_ty1 (UsageTy _ ty1) ps_ty2 ty2 = uTys ps_ty1 ty1 ps_ty2 ty2
+uTys ps_ty1 ty1 ps_ty2 (UsageTy _ ty2) = uTys ps_ty1 ty1 ps_ty2 ty2
+
-- Variables; go for uVar
uTys ps_ty1 (TyVarTy tyvar1) ps_ty2 ty2 = uVar False tyvar1 ps_ty2 ty2
uTys ps_ty1 ty1 ps_ty2 (TyVarTy tyvar2) = uVar True tyvar2 ps_ty1 ty1
| otherwise -> uTys ty1 ty1 ps_ty2 ty2 -- Same order
other -> uUnboundVar swapped tv1 maybe_ty1 ps_ty2 ty2
- -- Expand synonyms; ignore FTVs; ignore usage annots
+ -- Expand synonyms; ignore FTVs
uUnboundVar swapped tv1 maybe_ty1 ps_ty2 (NoteTy _ ty2)
= uUnboundVar swapped tv1 maybe_ty1 ps_ty2 ty2
| otherwise
-> WARN( not (k2 `hasMoreBoxityInfo` k1), (ppr tv2 <+> ppr k2) $$ (ppr tv1 <+> ppr k1) )
- (ASSERT( isNotUsgTy ps_ty2 )
- tcPutTyVar tv1 ps_ty2 `thenNF_Tc_`
+ (tcPutTyVar tv1 ps_ty2 `thenNF_Tc_`
returnTc ())
where
k1 = tyVarKind tv1
import HsSyn ( HsExpr(..), InPat(..), mkSimpleMatch )
import Type ( Type, isUnLiftedType, applyTys, tyVarsOfType, tyVarsOfTypes,
- mkTyVarTys, mkForAllTys, mkTyConApp, splitFunTys,
- mkFunTy, isTyVarTy,
- splitSigmaTy, getTyVar, splitTyConApp_maybe, funTyCon
+ mkTyVarTys, mkForAllTys, mkTyConApp,
+ mkFunTy, isTyVarTy, getTyVar_maybe,
+ splitSigmaTy, splitTyConApp_maybe, funTyCon
)
-import DataCon ( DataCon, dataConOrigArgTys, dataConWrapId, dataConId )
+import DataCon ( DataCon, dataConOrigArgTys, dataConWrapId, dataConId, isExistentialDataCon )
import TyCon ( TyCon, tyConTyVars, tyConDataConsIfAvailable,
tyConGenInfo, isNewTyCon, newTyConRep, isBoxedTupleTyCon
mkConApp, Alt, mkTyApps, mkVarApps )
import BasicTypes ( EP(..), Boxity(..) )
import Var ( TyVar )
-import VarSet ( isEmptyVarSet )
+import VarSet ( varSetElems )
import Id ( Id, mkTemplateLocal, idType, idName,
mkTemplateLocalsNum, mkId
)
-- * function arrow
-- * boxed tuples
-- * an arbitrary type not involving the class type variables
-validGenericMethodType ty = valid ty
-
-valid ty
- | isTyVarTy ty = True
- | not (null arg_tys) = all valid arg_tys && valid res_ty
- | no_tyvars_in_ty = True
- | otherwise = isBoxedTupleTyCon tc && all valid tys
+ -- e.g. this is ok: forall b. Ord b => [b] -> a
+ -- where a is the class variable
+validGenericMethodType ty
+ = valid tau
where
- (arg_tys, res_ty) = splitFunTys ty
- no_tyvars_in_ty = isEmptyVarSet (tyVarsOfType ty)
- Just (tc,tys) = splitTyConApp_maybe ty
+ (local_tvs, _, tau) = splitSigmaTy ty
+
+ valid ty
+ | isTyVarTy ty = True
+ | no_tyvars_in_ty = True
+ | otherwise = case splitTyConApp_maybe ty of
+ Just (tc,tys) -> valid_tycon tc && all valid tys
+ Nothing -> False
+ where
+ no_tyvars_in_ty = all (`elem` local_tvs) (varSetElems (tyVarsOfType ty))
+
+ valid_tycon tc = tc == funTyCon || isBoxedTupleTyCon tc
+ -- Compare bimapApp, below
\end{code}
| null datacons -- Abstractly imported types don't have
= Nothing -- to/from operations, (and should not need them)
- -- If any of the constructor has an unboxed type as argument
+ -- If any of the constructor has an unboxed type as argument,
-- then we can't build the embedding-projection pair, because
-- it relies on instantiating *polymorphic* sum and product types
-- at the argument types of the constructors
- | any (any isUnLiftedType . dataConOrigArgTys) datacons
+ -- Nor can we do the job if it's an existential data constructor,
+ | or [ any isUnLiftedType (dataConOrigArgTys dc) || isExistentialDataCon dc
+ | dc <- datacons ]
= Nothing
| otherwise
Generating the Generic default method. Uses the bimaps to generate the
actual method. All of this is rather incomplete, but it would be nice
-to make even this work.
+to make even this work. Example
+
+ class Foo a where
+ op :: Op a
+
+ instance Foo T
+
+Then we fill in the RHS for op, RenamedHsExpr, by calling mkGenericRhs:
+
+ instance Foo T where
+ op = <mkGenericRhs op a T>
+
+To do this, we generate a pair of RenamedHsExprs (EP toOp fromOp), where
+
+ toOp :: Op Trep -> Op T
+ fromOp :: Op T -> Op Trep
+
+(the bimap) and then fill in the RHS with
+
+ instance Foo T where
+ op = toOp op
+
+Remember, we're generating a RenamedHsExpr, so the result of all this
+will be fed to the type checker. So the 'op' on the RHS will be
+at the representation type for T, Trep.
+
+
+A note about polymorphism. Suppose the class op is polymorphic:
+
+ class Baz a where
+ op :: forall b. Ord b => a -> b -> b
+
+Then we can still generate a bimap with
+
+ toOP :: forall b. (Trep -> b -> b) -> (T -> b -> b)
+
+and fill in the instance decl thus
+
+ instance Foo T where
+ op = toOp op
+
+By the time the type checker has done its stuff we'll get
+
+ instance Foo T where
+ op = \b. \dict::Ord b. toOp b (op Trep b dict)
\begin{code}
mkGenericRhs :: Id -> TyVar -> TyCon -> RenamedHsExpr
Just (EP from to) = tyConGenInfo tycon -- Caller checked this will succeed
ep = EP (HsVar (idName from)) (HsVar (idName to))
- -- Takes out the ForAll and the Class rstrictions in front of the
- -- type of the method.
+ -- Takes out the ForAll and the Class restrictions
+ -- in front of the type of the method.
(_,_,op_ty) = splitSigmaTy (idType sel_id)
+ -- Do it again! This deals with the case where the method type
+ -- is polymorphic -- see notes above
+ (local_tvs,_,final_ty) = splitSigmaTy op_ty
+
-- Now we probably have a tycon in front
-- of us, quite probably a FunTyCon.
- bimap = generate_bimap (tyvar, ep) op_ty
+ bimap = generate_bimap (tyvar, ep, local_tvs) final_ty
--- EP is the environment of to/from bimaps, but as we only have one type
--- variable at the moment, there is only one EP.
+type EPEnv = (TyVar, -- The class type variable
+ EP RenamedHsExpr, -- The EP it maps to
+ [TyVar] -- Other in-scope tyvars; they have an identity EP
+ )
-------------------
-generate_bimap :: (TyVar, EP RenamedHsExpr) -> Type -> EP RenamedHsExpr
+generate_bimap :: EPEnv
+ -> Type
+ -> EP RenamedHsExpr
-- Top level case - splitting the TyCon.
-generate_bimap (tv,ep) ty | isTyVarTy ty = ASSERT( getTyVar "Generics.generate_bimap" ty == tv) ep
- | otherwise = bimapApp (tv,ep) (splitTyConApp_maybe ty)
+generate_bimap env@(tv,ep,local_tvs) ty
+ = case getTyVar_maybe ty of
+ Just tv1 | tv == tv1 -> ep -- The class tyvar
+ | otherwise -> ASSERT( tv1 `elem` local_tvs) -- One of the polymorphic tyvars of the method
+ idEP
+ Nothing -> bimapApp env (splitTyConApp_maybe ty)
-------------------
-bimapApp :: (TyVar, EP RenamedHsExpr) -> Maybe (TyCon, [Type]) -> EP RenamedHsExpr
-bimapApp ep Nothing = panic "TcClassDecl: Type Application!"
-bimapApp ep (Just (tycon, ty_args))
+bimapApp :: EPEnv -> Maybe (TyCon, [Type]) -> EP RenamedHsExpr
+bimapApp env Nothing = panic "TcClassDecl: Type Application!"
+bimapApp env (Just (tycon, ty_args))
| tycon == funTyCon = bimapArrow arg_eps
| isBoxedTupleTyCon tycon = bimapTuple arg_eps
| otherwise = -- Otherwise validGenericMethodType will
-- have checked that the type is a constant type
- ASSERT( isEmptyVarSet (tyVarsOfTypes ty_args) )
- EP idexpr idexpr
+ ASSERT( all (`elem` local_tvs) (varSetElems (tyVarsOfTypes ty_args)) )
+ idEP
where
- arg_eps = map (generate_bimap ep) ty_args
+ arg_eps = map (generate_bimap env) ty_args
+ (_,_,local_tvs) = env
-------------------
+-- bimapArrow :: [EP a a', EP b b'] -> EP (a->b) (a'->b')
bimapArrow [ep1, ep2]
= EP { fromEP = mk_hs_lam [VarPatIn g1, VarPatIn g2] from_body,
toEP = mk_hs_lam [VarPatIn g1, VarPatIn g2] to_body }
(g1:g2:g3:_) = genericNames
mk_hs_lam pats body = HsPar (HsLam (mkSimpleMatch pats body Nothing builtinSrcLoc))
-idexpr = mk_hs_lam [VarPatIn g3] (HsVar g3)
+
+idEP :: EP RenamedHsExpr
+idEP = EP idexpr idexpr
+ where
+ idexpr = mk_hs_lam [VarPatIn g3] (HsVar g3)
\end{code}
-- friends:
-- (PprType can see all the representations it's trying to print)
-import TypeRep ( Type(..), TyNote(..), Kind, UsageAnn(..),
- boxedTypeKind,
- ) -- friend
+import TypeRep ( Type(..), TyNote(..), Kind, boxedTypeKind ) -- friend
import Type ( PredType(..), ThetaType,
splitPredTy_maybe,
splitForAllTys, splitSigmaTy, splitRhoTy,
isDictTy, splitTyConApp_maybe, splitFunTy_maybe,
- splitUsForAllTys, predRepTy
+ predRepTy, isUTyVar
)
import Var ( TyVar, tyVarKind )
import TyCon ( TyCon, isPrimTyCon, isTupleTyCon, isUnboxedTupleTyCon,
maybeTyConSingleCon, isEnumerationTyCon,
- tyConArity
+ tyConArity, tyConName
)
import Class ( Class )
-- others:
+import CmdLineOpts ( opt_PprStyle_RawTypes )
import Maybes ( maybeToBool )
import Name ( getOccString, getOccName )
import Outputable
\begin{code}
-tOP_PREC = (0 :: Int)
-fUN_PREC = (1 :: Int)
-tYCON_PREC = (2 :: Int)
+tOP_PREC = (0 :: Int) -- type in ParseIface.y
+fUN_PREC = (1 :: Int) -- btype in ParseIface.y
+tYCON_PREC = (2 :: Int) -- atype in ParseIface.y
maybeParen ctxt_prec inner_prec pretty
| ctxt_prec < inner_prec = pretty
TyConApp bx [] -> ppr (getOccName bx) -- Always unqualified
other -> maybeParen ctxt_prec tYCON_PREC
(sep [ppr tycon, nest 4 tys_w_spaces])
-
+
+ -- USAGE CASE
+ | (tycon `hasKey` usOnceTyConKey || tycon `hasKey` usManyTyConKey) && n_tys == 0
+ = -- For usages (! and .), always print bare OccName, without pkg/mod/uniq
+ ppr (getOccName (tyConName tycon))
+
-- TUPLE CASE (boxed and unboxed)
| isTupleTyCon tycon
&& length tys == tyConArity tycon -- no magic if partially applied
ppr_ty env ctxt_prec ty@(ForAllTy _ _)
= getPprStyle $ \ sty ->
maybeParen ctxt_prec fUN_PREC $
- sep [ ptext SLIT("forall") <+> pp_tyvars <> ptext SLIT("."),
+ sep [ ptext SLIT("forall") <+> pp_tyvars sty <> ptext SLIT("."),
ppr_theta theta,
ppr_ty env tOP_PREC tau
]
where
- (tyvars, rho) = splitForAllTys ty -- don't treat theta specially any more (KSW 1999-04)
+ (tyvars, rho) = splitForAllTys ty
(theta, tau) = splitRhoTy rho
- pp_tyvars = hsep (map (pBndr env LambdaBind) tyvars)
+ pp_tyvars sty = hsep (map (pBndr env LambdaBind) some_tyvars)
+ where
+ some_tyvars | userStyle sty && not opt_PprStyle_RawTypes
+ = filter (not . isUTyVar) tyvars -- hide uvars from user
+ | otherwise
+ = tyvars
ppr_theta [] = empty
ppr_theta theta = parens (hsep (punctuate comma (map (ppr_pred env) theta)))
ppr_ty env ctxt_prec (FunTy ty1 ty2)
- = maybeParen ctxt_prec fUN_PREC (sep (ppr_ty env fUN_PREC ty1 : pp_rest ty2))
-- we don't want to lose usage annotations or synonyms,
-- so we mustn't use splitFunTys here.
- where
- pp_rest (FunTy ty1 ty2) = pp_codom ty1 : pp_rest ty2
- pp_rest ty = [pp_codom ty]
- pp_codom ty = ptext SLIT("->") <+> ppr_ty env fUN_PREC ty
+ = maybeParen ctxt_prec fUN_PREC $
+ sep [ ppr_ty env fUN_PREC ty1
+ , ptext SLIT("->") <+> ppr_ty env tOP_PREC ty2
+ ]
ppr_ty env ctxt_prec (AppTy ty1 ty2)
= maybeParen ctxt_prec tYCON_PREC $
- ppr_ty env tOP_PREC ty1 <+> ppr_ty env tYCON_PREC ty2
+ ppr_ty env fUN_PREC ty1 <+> ppr_ty env tYCON_PREC ty2
+
+ppr_ty env ctxt_prec (UsageTy u ty)
+ = maybeParen ctxt_prec tYCON_PREC $
+ ptext SLIT("__u") <+> ppr_ty env tYCON_PREC u
+ <+> ppr_ty env tYCON_PREC ty
+ -- fUN_PREC would be logical for u, but it yields a reduce/reduce conflict with AppTy
ppr_ty env ctxt_prec (NoteTy (SynNote ty) expansion)
= ppr_ty env ctxt_prec ty
ppr_ty env ctxt_prec (NoteTy (FTVNote _) ty) = ppr_ty env ctxt_prec ty
-ppr_ty env ctxt_prec ty@(NoteTy (UsgForAll _) _)
- = maybeParen ctxt_prec fUN_PREC $
- sep [ ptext SLIT("__fuall") <+> brackets pp_uvars <+> ptext SLIT("=>"),
- ppr_ty env tOP_PREC sigma
- ]
- where
- (uvars,sigma) = splitUsForAllTys ty
- pp_uvars = hsep (map ppr uvars)
-
-ppr_ty env ctxt_prec (NoteTy (UsgNote u) ty)
- = maybeParen ctxt_prec tYCON_PREC $
- ptext SLIT("__u") <+> ppr u <+> ppr_ty env tYCON_PREC ty
-
ppr_ty env ctxt_prec (PredTy p) = braces (ppr_pred env p)
ppr_pred env (Class clas tys) = ppr clas <+>
b = panic "PprType:init_ppr_env"
\end{code}
-\begin{code}
-instance Outputable UsageAnn where
- ppr UsOnce = ptext SLIT("-")
- ppr UsMany = ptext SLIT("!")
- ppr (UsVar uv) = ppr uv
-\end{code}
-
%************************************************************************
%* *
TyConApp tycon _ -> getOccString tycon
NoteTy (FTVNote _) ty -> getTyDescription ty
NoteTy (SynNote ty1) _ -> getTyDescription ty1
- NoteTy (UsgNote _) ty -> getTyDescription ty
PredTy p -> getTyDescription (predRepTy p)
ForAllTy _ ty -> getTyDescription ty
}
}
type ArgVrcs = [(Bool,Bool)] -- Tyvar variance info: [(occPos,occNeg)]
- -- *NB*: this is tyvar variance info, *not*
- -- termvar usage info.
data AlgTyConFlavour
= DataTyCon -- Data type
funTyCon,
+ usageKindCon, -- :: KX
+ usageTypeKind, -- :: KX
+ usOnceTyCon, usManyTyCon, -- :: $
+ usOnce, usMany, -- :: $
+
-- exports from this module:
hasMoreBoxityInfo, defaultKind,
mkTyConApp, mkTyConTy, splitTyConApp_maybe,
splitAlgTyConApp_maybe, splitAlgTyConApp,
+ mkUTy, splitUTy, splitUTy_maybe,
+ isUTy, uaUTy, unUTy, liftUTy, mkUTyM,
+ isUsageKind, isUsage, isUTyVar,
+
-- Predicates and the like
mkDictTy, mkDictTys, mkPredTy, splitPredTy_maybe,
splitDictTy, splitDictTy_maybe, isDictTy, predRepTy, splitDFunTy,
- mkSynTy, isSynTy, deNoteType,
+ mkSynTy, deNoteType,
repType, splitRepFunTys, splitNewType_maybe, typePrimRep,
- UsageAnn(..), mkUsgTy, isUsgTy{- dont use -}, isNotUsgTy, splitUsgTy, unUsgTy, tyUsg,
- mkUsForAllTy, mkUsForAllTys, splitUsForAllTys, substUsTy,
-
mkForAllTy, mkForAllTys, splitForAllTy_maybe, splitForAllTys,
- applyTy, applyTys, hoistForAllTys,
+ applyTy, applyTys, hoistForAllTys, isForAllTy,
TauType, RhoType, SigmaType, PredType(..), ThetaType,
ClassPred, ClassContext, mkClassPred,
-- Free variables
tyVarsOfType, tyVarsOfTypes, tyVarsOfPred, tyVarsOfTheta,
- namesOfType, typeKind, addFreeTyVars,
+ namesOfType, usageAnnOfType, typeKind, addFreeTyVars,
-- Tidying up for printing
tidyType, tidyTypes,
import {-# SOURCE #-} Subst ( mkTyVarSubst, substTy )
-- friends:
-import Var ( TyVar, UVar,
- tyVarKind, tyVarName, setTyVarName,
- )
+import Var ( Var, TyVar, tyVarKind, tyVarName, setTyVarName )
import VarEnv
import VarSet
)
-- others
+import Maybes ( maybeToBool )
import SrcLoc ( noSrcLoc )
import PrimRep ( PrimRep(..), isFollowableRep )
import Unique ( Uniquable(..) )
getTyVar msg (TyVarTy tv) = tv
getTyVar msg (PredTy p) = getTyVar msg (predRepTy p)
getTyVar msg (NoteTy _ t) = getTyVar msg t
+getTyVar msg ty@(UsageTy _ _) = pprPanic "getTyVar: UTy:" (text msg $$ pprType ty)
getTyVar msg other = panic ("getTyVar: " ++ msg)
getTyVar_maybe :: Type -> Maybe TyVar
getTyVar_maybe (TyVarTy tv) = Just tv
getTyVar_maybe (NoteTy _ t) = getTyVar_maybe t
getTyVar_maybe (PredTy p) = getTyVar_maybe (predRepTy p)
+getTyVar_maybe ty@(UsageTy _ _) = pprPanic "getTyVar_maybe: UTy:" (pprType ty)
getTyVar_maybe other = Nothing
isTyVarTy :: Type -> Bool
isTyVarTy (TyVarTy tv) = True
isTyVarTy (NoteTy _ ty) = isTyVarTy ty
isTyVarTy (PredTy p) = isTyVarTy (predRepTy p)
+isTyVarTy ty@(UsageTy _ _) = pprPanic "isTyVarTy: UTy:" (pprType ty)
isTyVarTy other = False
\end{code}
\begin{code}
mkAppTy orig_ty1 orig_ty2
- = ASSERT2( isNotUsgTy orig_ty1 && isNotUsgTy orig_ty2, pprType orig_ty1 <+> text "to" <+> pprType orig_ty2 )
- ASSERT( not (isPredTy orig_ty1) ) -- Predicates are of kind *
+ = ASSERT( not (isPredTy orig_ty1) ) -- Predicates are of kind *
+ UASSERT2( not (isUTy orig_ty2), pprType orig_ty1 <+> pprType orig_ty2 )
+ -- argument must be unannotated
mk_app orig_ty1
where
mk_app (NoteTy _ ty1) = mk_app ty1
mk_app (TyConApp tc tys) = mkTyConApp tc (tys ++ [orig_ty2])
+ mk_app ty@(UsageTy _ _) = pprPanic "mkAppTy: UTy:" (pprType ty)
mk_app ty1 = AppTy orig_ty1 orig_ty2
mkAppTys :: Type -> [Type] -> Type
mkAppTys orig_ty1 [] = orig_ty1
-- This check for an empty list of type arguments
- -- avoids the needless of a type synonym constructor.
+ -- avoids the needless loss of a type synonym constructor.
-- For example: mkAppTys Rational []
-- returns to (Ratio Integer), which has needlessly lost
-- the Rational part.
mkAppTys orig_ty1 orig_tys2
- = ASSERT2( isNotUsgTy orig_ty1, pprType orig_ty1 )
- ASSERT( not (isPredTy orig_ty1) ) -- Predicates are of kind *
+ = ASSERT( not (isPredTy orig_ty1) ) -- Predicates are of kind *
+ UASSERT2( not (any isUTy orig_tys2), pprType orig_ty1 <+> fsep (map pprType orig_tys2) )
+ -- arguments must be unannotated
mk_app orig_ty1
where
mk_app (NoteTy _ ty1) = mk_app ty1
mk_app (TyConApp tc tys) = mkTyConApp tc (tys ++ orig_tys2)
- mk_app ty1 = ASSERT2( all isNotUsgTy orig_tys2, pprType orig_ty1 <+> text "to" <+> hsep (map pprType orig_tys2) )
- foldl AppTy orig_ty1 orig_tys2
+ mk_app ty@(UsageTy _ _) = pprPanic "mkAppTys: UTy:" (pprType ty)
+ mk_app ty1 = foldl AppTy orig_ty1 orig_tys2
splitAppTy_maybe :: Type -> Maybe (Type, Type)
-splitAppTy_maybe (FunTy ty1 ty2) = Just (TyConApp funTyCon [ty1], ty2)
+splitAppTy_maybe (FunTy ty1 ty2) = Just (TyConApp funTyCon [unUTy ty1], unUTy ty2)
splitAppTy_maybe (AppTy ty1 ty2) = Just (ty1, ty2)
splitAppTy_maybe (NoteTy _ ty) = splitAppTy_maybe ty
splitAppTy_maybe (PredTy p) = splitAppTy_maybe (predRepTy p)
split [ty2] acc = Just (TyConApp tc (reverse acc), ty2)
split (ty:tys) acc = split tys (ty:acc)
+splitAppTy_maybe ty@(UsageTy _ _) = pprPanic "splitAppTy_maybe: UTy:" (pprType ty)
splitAppTy_maybe other = Nothing
splitAppTy :: Type -> (Type, Type)
split orig_ty (NoteTy _ ty) args = split orig_ty ty args
split orig_ty (PredTy p) args = split orig_ty (predRepTy p) args
split orig_ty (FunTy ty1 ty2) args = ASSERT( null args )
- (TyConApp funTyCon [], [ty1,ty2])
+ (TyConApp funTyCon [], [unUTy ty1,unUTy ty2])
split orig_ty (TyConApp tc tc_args) args = (TyConApp tc [], tc_args ++ args)
+ split orig_ty (UsageTy _ _) args = pprPanic "splitAppTys: UTy:" (pprType orig_ty)
split orig_ty ty args = (orig_ty, args)
\end{code}
\begin{code}
mkFunTy :: Type -> Type -> Type
-mkFunTy arg res = FunTy arg res
+mkFunTy arg res = UASSERT2( isUTy arg && isUTy res, pprType arg <+> pprType res )
+ FunTy arg res
mkFunTys :: [Type] -> Type -> Type
-mkFunTys tys ty = foldr FunTy ty tys
+mkFunTys tys ty = UASSERT2( all isUTy (ty:tys), fsep (map pprType (tys++[ty])) )
+ foldr FunTy ty tys
splitFunTy :: Type -> (Type, Type)
splitFunTy (FunTy arg res) = (arg, res)
splitFunTy (NoteTy _ ty) = splitFunTy ty
splitFunTy (PredTy p) = splitFunTy (predRepTy p)
+splitFunTy ty@(UsageTy _ _) = pprPanic "splitFunTy: UTy:" (pprType ty)
splitFunTy_maybe :: Type -> Maybe (Type, Type)
splitFunTy_maybe (FunTy arg res) = Just (arg, res)
splitFunTy_maybe (NoteTy _ ty) = splitFunTy_maybe ty
splitFunTy_maybe (PredTy p) = splitFunTy_maybe (predRepTy p)
+splitFunTy_maybe ty@(UsageTy _ _) = pprPanic "splitFunTy_maybe: UTy:" (pprType ty)
splitFunTy_maybe other = Nothing
splitFunTys :: Type -> ([Type], Type)
split args orig_ty (FunTy arg res) = split (arg:args) res res
split args orig_ty (NoteTy _ ty) = split args orig_ty ty
split args orig_ty (PredTy p) = split args orig_ty (predRepTy p)
+ split args orig_ty (UsageTy _ _) = pprPanic "splitFunTys: UTy:" (pprType orig_ty)
split args orig_ty ty = (reverse args, orig_ty)
splitFunTysN :: String -> Int -> Type -> ([Type], Type)
split n args syn_ty (FunTy arg res) = split (n-1) (arg:args) res res
split n args syn_ty (NoteTy _ ty) = split n args syn_ty ty
split n args syn_ty (PredTy p) = split n args syn_ty (predRepTy p)
+ split n args syn_ty (UsageTy _ _) = pprPanic "splitFunTysN: UTy:" (pprType orig_ty)
split n args syn_ty ty = pprPanic ("splitFunTysN: " ++ msg) (int orig_n <+> pprType orig_ty)
zipFunTys :: Outputable a => [a] -> Type -> ([(a,Type)], Type)
split acc (x:xs) nty (FunTy arg res) = split ((x,arg):acc) xs res res
split acc xs nty (NoteTy _ ty) = split acc xs nty ty
split acc xs nty (PredTy p) = split acc xs nty (predRepTy p)
+ split acc xs nty (UsageTy _ _) = pprPanic "zipFunTys: UTy:" (ppr orig_xs <+> pprType orig_ty)
split acc (x:xs) nty ty = pprPanic "zipFunTys" (ppr orig_xs <+> pprType orig_ty)
funResultTy :: Type -> Type
funResultTy (FunTy arg res) = res
funResultTy (NoteTy _ ty) = funResultTy ty
funResultTy (PredTy p) = funResultTy (predRepTy p)
+funResultTy (UsageTy _ ty) = funResultTy ty
funResultTy ty = pprPanic "funResultTy" (pprType ty)
funArgTy :: Type -> Type
funArgTy (FunTy arg res) = arg
funArgTy (NoteTy _ ty) = funArgTy ty
funArgTy (PredTy p) = funArgTy (predRepTy p)
+funArgTy (UsageTy _ ty) = funArgTy ty
funArgTy ty = pprPanic "funArgTy" (pprType ty)
\end{code}
mkTyConApp tycon tys
| isFunTyCon tycon && length tys == 2
= case tys of
- (ty1:ty2:_) -> FunTy ty1 ty2
+ (ty1:ty2:_) -> FunTy (mkUTyM ty1) (mkUTyM ty2)
| otherwise
= ASSERT(not (isSynTyCon tycon))
+ UASSERT2( not (any isUTy tys), ppr tycon <+> fsep (map pprType tys) )
TyConApp tycon tys
mkTyConTy :: TyCon -> Type
splitTyConApp_maybe :: Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe (TyConApp tc tys) = Just (tc, tys)
-splitTyConApp_maybe (FunTy arg res) = Just (funTyCon, [arg,res])
+splitTyConApp_maybe (FunTy arg res) = Just (funTyCon, [unUTy arg,unUTy res])
splitTyConApp_maybe (NoteTy _ ty) = splitTyConApp_maybe ty
splitTyConApp_maybe (PredTy p) = splitTyConApp_maybe (predRepTy p)
+splitTyConApp_maybe (UsageTy _ ty) = splitTyConApp_maybe ty
splitTyConApp_maybe other = Nothing
-- splitAlgTyConApp_maybe looks for
tyConArity tc == length tys = Just (tc, tys, tyConDataCons tc)
splitAlgTyConApp_maybe (NoteTy _ ty) = splitAlgTyConApp_maybe ty
splitAlgTyConApp_maybe (PredTy p) = splitAlgTyConApp_maybe (predRepTy p)
+splitAlgTyConApp_maybe (UsageTy _ ty)= splitAlgTyConApp_maybe ty
splitAlgTyConApp_maybe other = Nothing
splitAlgTyConApp :: Type -> (TyCon, [Type], [DataCon])
(tc, tys, tyConDataCons tc)
splitAlgTyConApp (NoteTy _ ty) = splitAlgTyConApp ty
splitAlgTyConApp (PredTy p) = splitAlgTyConApp (predRepTy p)
+splitAlgTyConApp (UsageTy _ ty) = splitAlgTyConApp ty
#ifdef DEBUG
splitAlgTyConApp ty = pprPanic "splitAlgTyConApp" (pprType ty)
#endif
\begin{code}
mkSynTy syn_tycon tys
= ASSERT( isSynTyCon syn_tycon )
- ASSERT( isNotUsgTy body )
ASSERT( length tyvars == length tys )
NoteTy (SynNote (TyConApp syn_tycon tys))
(substTy (mkTyVarSubst tyvars tys) body)
where
(tyvars, body) = getSynTyConDefn syn_tycon
-isSynTy (NoteTy (SynNote _) _) = True
-isSynTy other = False
-
deNoteType :: Type -> Type
-- Remove synonyms, but not Preds
deNoteType ty@(TyVarTy tyvar) = ty
deNoteType (TyConApp tycon tys) = TyConApp tycon (map deNoteType tys)
-deNoteType (PredTy p) = PredTy p
+deNoteType (PredTy p) = PredTy (deNotePred p)
deNoteType (NoteTy _ ty) = deNoteType ty
deNoteType (AppTy fun arg) = AppTy (deNoteType fun) (deNoteType arg)
deNoteType (FunTy fun arg) = FunTy (deNoteType fun) (deNoteType arg)
deNoteType (ForAllTy tv ty) = ForAllTy tv (deNoteType ty)
+deNoteType (UsageTy u ty) = UsageTy u (deNoteType ty)
+
+deNotePred :: PredType -> PredType
+deNotePred (Class c tys) = Class c (map deNoteType tys)
+deNotePred (IParam n ty) = IParam n (deNoteType ty)
\end{code}
Notes on type synonyms
(b) newtypes
(c) synonyms
(d) predicates
+ (e) usage annotations
It's useful in the back end where we're not
interested in newtypes anymore.
repType (ForAllTy _ ty) = repType ty
repType (NoteTy _ ty) = repType ty
repType (PredTy p) = repType (predRepTy p)
+repType (UsageTy _ ty) = repType ty
repType ty = case splitNewType_maybe ty of
Just ty' -> repType ty' -- Still re-apply repType in case of for-all
Nothing -> ty
-- Looks through multiple levels of newtype, but does not look through for-alls
splitNewType_maybe (NoteTy _ ty) = splitNewType_maybe ty
splitNewType_maybe (PredTy p) = splitNewType_maybe (predRepTy p)
+splitNewType_maybe (UsageTy _ ty) = splitNewType_maybe ty
splitNewType_maybe (TyConApp tc tys) = case newTyConRep tc of
Just rep_ty -> ASSERT( length tys == tyConArity tc )
-- The assert should hold because repType should
---------------------------------------------------------------------
- UsgNote
- ~~~~~~~
-
-NB: Invariant: if present, usage note is at the very top of the type.
-This should be carefully preserved.
-
-In some parts of the compiler, comments use the _Once Upon a
-Polymorphic Type_ (POPL'99) usage of "rho = generalised
-usage-annotated type; sigma = usage-annotated type; tau =
-usage-annotated type except on top"; unfortunately this conflicts with
-the rho/tau/theta/sigma usage in the rest of the compiler. (KSW
-1999-07)
-
-\begin{code}
-mkUsgTy :: UsageAnn -> Type -> Type
-#ifndef USMANY
-mkUsgTy UsMany ty = ASSERT2( isNotUsgTy ty, pprType ty )
- ty
-#endif
-mkUsgTy usg ty = ASSERT2( isNotUsgTy ty, pprType ty )
- NoteTy (UsgNote usg) ty
-
--- The isUsgTy function is utterly useless if UsManys are omitted.
--- Be warned! KSW 1999-04.
-isUsgTy :: Type -> Bool
-#ifndef USMANY
-isUsgTy _ = True
-#else
-isUsgTy (NoteTy (UsgForAll _) ty) = isUsgTy ty
-isUsgTy (NoteTy (UsgNote _) _ ) = True
-isUsgTy other = False
-#endif
-
--- The isNotUsgTy function may return a false True if UsManys are omitted;
--- in other words, A SSERT( isNotUsgTy ty ) may be useful but
--- A SSERT( not (isNotUsg ty) ) is asking for trouble. KSW 1999-04.
-isNotUsgTy :: Type -> Bool
-isNotUsgTy (NoteTy (UsgForAll _) _) = False
-isNotUsgTy (NoteTy (UsgNote _) _) = False
-isNotUsgTy other = True
-
--- splitUsgTy_maybe is not exported, since it is meaningless if
--- UsManys are omitted. It is used in several places in this module,
--- however. KSW 1999-04.
-splitUsgTy_maybe :: Type -> Maybe (UsageAnn,Type)
-splitUsgTy_maybe (NoteTy (UsgNote usg) ty2) = ASSERT( isNotUsgTy ty2 )
- Just (usg,ty2)
-splitUsgTy_maybe ty@(NoteTy (UsgForAll _) _) = pprPanic "splitUsgTy_maybe:" $ pprType ty
-splitUsgTy_maybe ty = Nothing
-
-splitUsgTy :: Type -> (UsageAnn,Type)
-splitUsgTy ty = case splitUsgTy_maybe ty of
- Just ans -> ans
- Nothing ->
-#ifndef USMANY
- (UsMany,ty)
-#else
- pprPanic "splitUsgTy: no usage annot:" $ pprType ty
-#endif
-
-tyUsg :: Type -> UsageAnn
-tyUsg = fst . splitUsgTy
-
-unUsgTy :: Type -> Type
--- strip outer usage annotation if present
-unUsgTy ty = case splitUsgTy_maybe ty of
- Just (_,ty1) -> ASSERT2( isNotUsgTy ty1, pprType ty )
- ty1
- Nothing -> ty
-
-mkUsForAllTy :: UVar -> Type -> Type
-mkUsForAllTy uv ty = NoteTy (UsgForAll uv) ty
-
-mkUsForAllTys :: [UVar] -> Type -> Type
-mkUsForAllTys uvs ty = foldr (NoteTy . UsgForAll) ty uvs
-
-splitUsForAllTys :: Type -> ([UVar],Type)
-splitUsForAllTys ty = split ty []
- where split (NoteTy (UsgForAll u) ty) uvs = split ty (u:uvs)
- split other_ty uvs = (reverse uvs, other_ty)
-
-substUsTy :: VarEnv UsageAnn -> Type -> Type
--- assumes range is fresh uvars, so no conflicts
-substUsTy ve (NoteTy note@(UsgNote (UsVar u))
- ty ) = NoteTy (case lookupVarEnv ve u of
- Just ua -> UsgNote ua
- Nothing -> note)
- (substUsTy ve ty)
-substUsTy ve (NoteTy (SynNote ty1) ty2) = NoteTy (SynNote (substUsTy ve ty1)) (substUsTy ve ty2)
-substUsTy ve (NoteTy note ty) = NoteTy note (substUsTy ve ty)
-
-substUsTy ve (PredTy (Class c tys)) = PredTy (Class c (map (substUsTy ve) tys))
-substUsTy ve (PredTy (IParam n ty)) = PredTy (IParam n (substUsTy ve ty))
-substUsTy ve (TyVarTy tv) = TyVarTy tv
-substUsTy ve (AppTy ty1 ty2) = AppTy (substUsTy ve ty1) (substUsTy ve ty2)
-substUsTy ve (FunTy ty1 ty2) = FunTy (substUsTy ve ty1) (substUsTy ve ty2)
-substUsTy ve (TyConApp tyc tys) = TyConApp tyc (map (substUsTy ve) tys)
-substUsTy ve (ForAllTy yv ty ) = ForAllTy yv (substUsTy ve ty)
-\end{code}
-
-
----------------------------------------------------------------------
ForAllTy
~~~~~~~~
-We need to be clever here with usage annotations; they need to be
-lifted or lowered through the forall as appropriate.
-
\begin{code}
mkForAllTy :: TyVar -> Type -> Type
-mkForAllTy tyvar ty = case splitUsgTy_maybe ty of
- Just (usg,ty') -> NoteTy (UsgNote usg)
- (ForAllTy tyvar ty')
- Nothing -> ForAllTy tyvar ty
+mkForAllTy tyvar ty
+ = mkForAllTys [tyvar] ty
mkForAllTys :: [TyVar] -> Type -> Type
-mkForAllTys tyvars ty = case splitUsgTy_maybe ty of
- Just (usg,ty') -> NoteTy (UsgNote usg)
- (foldr ForAllTy ty' tyvars)
- Nothing -> foldr ForAllTy ty tyvars
+mkForAllTys tyvars ty
+ = case splitUTy_maybe ty of
+ Just (u,ty1) -> UASSERT2( not (mkVarSet tyvars `intersectsVarSet` tyVarsOfType u),
+ ptext SLIT("mkForAllTys: usage scope")
+ <+> ppr tyvars <+> pprType ty )
+ mkUTy u (foldr ForAllTy ty1 tyvars) -- we lift usage annotations over foralls
+ Nothing -> foldr ForAllTy ty tyvars
+
+isForAllTy :: Type -> Bool
+isForAllTy (NoteTy _ ty) = isForAllTy ty
+isForAllTy (ForAllTy _ _) = True
+isForAllTy (UsageTy _ ty) = isForAllTy ty
+isForAllTy other_ty = False
splitForAllTy_maybe :: Type -> Maybe (TyVar, Type)
-splitForAllTy_maybe ty = case splitUsgTy_maybe ty of
- Just (usg,ty') -> do (tyvar,ty'') <- splitFAT_m ty'
- return (tyvar, NoteTy (UsgNote usg) ty'')
- Nothing -> splitFAT_m ty
+splitForAllTy_maybe ty = splitFAT_m ty
where
splitFAT_m (NoteTy _ ty) = splitFAT_m ty
splitFAT_m (PredTy p) = splitFAT_m (predRepTy p)
splitFAT_m (ForAllTy tyvar ty) = Just(tyvar, ty)
+ splitFAT_m (UsageTy _ ty) = splitFAT_m ty
splitFAT_m _ = Nothing
splitForAllTys :: Type -> ([TyVar], Type)
-splitForAllTys ty = case splitUsgTy_maybe ty of
- Just (usg,ty') -> let (tvs,ty'') = split ty' ty' []
- in (tvs, NoteTy (UsgNote usg) ty'')
- Nothing -> split ty ty []
+splitForAllTys ty = split ty ty []
where
split orig_ty (ForAllTy tv ty) tvs = split ty ty (tv:tvs)
split orig_ty (NoteTy _ ty) tvs = split orig_ty ty tvs
split orig_ty (PredTy p) tvs = split orig_ty (predRepTy p) tvs
+ split orig_ty (UsageTy _ ty) tvs = split orig_ty ty tvs
split orig_ty t tvs = (reverse tvs, orig_ty)
\end{code}
-- (mkPiType now in CoreUtils)
-Applying a for-all to its arguments
+Applying a for-all to its arguments. Lift usage annotation as required.
\begin{code}
applyTy :: Type -> Type -> Type
-applyTy (NoteTy note@(UsgNote _) fun) arg = NoteTy note (applyTy fun arg)
-applyTy (NoteTy note@(UsgForAll _) fun) arg = NoteTy note (applyTy fun arg)
applyTy (PredTy p) arg = applyTy (predRepTy p) arg
applyTy (NoteTy _ fun) arg = applyTy fun arg
-applyTy (ForAllTy tv ty) arg = ASSERT( isNotUsgTy arg )
+applyTy (ForAllTy tv ty) arg = UASSERT2( not (isUTy arg),
+ ptext SLIT("applyTy")
+ <+> pprType ty <+> pprType arg )
substTy (mkTyVarSubst [tv] [arg]) ty
+applyTy (UsageTy u ty) arg = UsageTy u (applyTy ty arg)
applyTy other arg = panic "applyTy"
applyTys :: Type -> [Type] -> Type
applyTys fun_ty arg_tys
- = substTy (mkTyVarSubst tvs arg_tys) ty
+ = UASSERT2( not (any isUTy arg_tys), ptext SLIT("applyTys") <+> pprType fun_ty )
+ (case mu of
+ Just u -> UsageTy u
+ Nothing -> id) $
+ substTy (mkTyVarSubst tvs arg_tys) ty
where
- (tvs, ty) = split fun_ty arg_tys
+ (mu, tvs, ty) = split fun_ty arg_tys
- split fun_ty [] = ([], fun_ty)
- split (NoteTy note@(UsgNote _) fun_ty)
- args = case split fun_ty args of
- (tvs, ty) -> (tvs, NoteTy note ty)
- split (NoteTy note@(UsgForAll _) fun_ty)
- args = case split fun_ty args of
- (tvs, ty) -> (tvs, NoteTy note ty)
+ split fun_ty [] = (Nothing, [], fun_ty)
split (NoteTy _ fun_ty) args = split fun_ty args
split (PredTy p) args = split (predRepTy p) args
- split (ForAllTy tv fun_ty) (arg:args) = ASSERT2( isNotUsgTy arg, vcat (map pprType arg_tys) $$
- text "in application of" <+> pprType fun_ty)
- case split fun_ty args of
- (tvs, ty) -> (tv:tvs, ty)
+ split (ForAllTy tv fun_ty) (arg:args) = case split fun_ty args of
+ (mu, tvs, ty) -> (mu, tv:tvs, ty)
+ split (UsageTy u ty) args = case split ty args of
+ (Nothing, tvs, ty) -> (Just u, tvs, ty)
+ (Just _ , _ , _ ) -> pprPanic "applyTys:"
+ (pprType fun_ty)
split other_ty args = panic "applyTys"
\end{code}
-Note that we allow applications to be of usage-annotated- types, as an
-extension: we handle them by lifting the annotation outside. The
-argument, however, must still be unannotated.
-
\begin{code}
hoistForAllTys :: Type -> Type
-- Move all the foralls to the top
-- e.g. T -> forall a. a ==> forall a. T -> a
+ -- Careful: LOSES USAGE ANNOTATIONS!
hoistForAllTys ty
= case hoist ty of { (tvs, body) -> mkForAllTys tvs body }
where
\end{code}
+---------------------------------------------------------------------
+ UsageTy
+ ~~~~~~~
+
+Constructing and taking apart usage types.
+
+\begin{code}
+mkUTy :: Type -> Type -> Type
+mkUTy u ty
+ = ASSERT2( typeKind u == usageTypeKind, ptext SLIT("mkUTy:") <+> pprType u <+> pprType ty )
+ UASSERT2( not (isUTy ty), ptext SLIT("mkUTy:") <+> pprType u <+> pprType ty )
+ -- if u == usMany then ty else : ToDo? KSW 2000-10
+#ifdef DO_USAGES
+ UsageTy u ty
+#else
+ ty
+#endif
+
+splitUTy :: Type -> (Type {- :: $ -}, Type)
+splitUTy orig_ty
+ = case splitUTy_maybe orig_ty of
+ Just (u,ty) -> (u,ty)
+#ifdef DO_USAGES
+ Nothing -> pprPanic "splitUTy:" (pprType orig_ty)
+#else
+ Nothing -> (usMany,orig_ty) -- default annotation ToDo KSW 2000-10
+#endif
+
+splitUTy_maybe :: Type -> Maybe (Type {- :: $ -}, Type)
+splitUTy_maybe (UsageTy u ty) = Just (u,ty)
+splitUTy_maybe (NoteTy _ ty) = splitUTy_maybe ty
+splitUTy_maybe other_ty = Nothing
+
+isUTy :: Type -> Bool
+ -- has usage annotation
+isUTy = maybeToBool . splitUTy_maybe
+
+uaUTy :: Type -> Type
+ -- extract annotation
+uaUTy = fst . splitUTy
+
+unUTy :: Type -> Type
+ -- extract unannotated type
+unUTy = snd . splitUTy
+\end{code}
+
+\begin{code}
+liftUTy :: (Type -> Type) -> Type -> Type
+ -- lift outer usage annot over operation on unannotated types
+liftUTy f ty
+ = let
+ (u,ty') = splitUTy ty
+ in
+ mkUTy u (f ty')
+\end{code}
+
+\begin{code}
+mkUTyM :: Type -> Type
+ -- put TOP (no info) annotation on unannotated type
+mkUTyM ty = mkUTy usMany ty
+\end{code}
+
+\begin{code}
+isUsageKind :: Kind -> Bool
+isUsageKind k
+ = ASSERT( typeKind k == superKind )
+ k == usageTypeKind
+
+isUsage :: Type -> Bool
+isUsage ty
+ = isUsageKind (typeKind ty)
+
+isUTyVar :: Var -> Bool
+isUTyVar v
+ = isUsageKind (tyVarKind v)
+\end{code}
+
+
%************************************************************************
%* *
\subsection{Stuff to do with the source-language types}
tell from the type constructor whether it's a dictionary or not.
\begin{code}
-mkClassPred clas tys = Class clas tys
+mkClassPred clas tys = UASSERT2( not (any isUTy tys), ppr clas <+> fsep (map pprType tys) )
+ Class clas tys
mkDictTy :: Class -> [Type] -> Type
-mkDictTy clas tys = mkPredTy (Class clas tys)
+mkDictTy clas tys = UASSERT2( not (any isUTy tys), ppr clas <+> fsep (map pprType tys) )
+ mkPredTy (Class clas tys)
mkDictTys :: ClassContext -> [Type]
mkDictTys cxt = [mkDictTy cls tys | (cls,tys) <- cxt]
isPredTy :: Type -> Bool
isPredTy (NoteTy _ ty) = isPredTy ty
isPredTy (PredTy _) = True
+isPredTy (UsageTy _ ty)= isPredTy ty
isPredTy _ = False
isDictTy :: Type -> Bool
isDictTy (NoteTy _ ty) = isDictTy ty
isDictTy (PredTy (Class _ _)) = True
+isDictTy (UsageTy _ ty) = isDictTy ty
isDictTy other = False
splitPredTy_maybe :: Type -> Maybe PredType
splitPredTy_maybe (NoteTy _ ty) = splitPredTy_maybe ty
splitPredTy_maybe (PredTy p) = Just p
+splitPredTy_maybe (UsageTy _ ty)= splitPredTy_maybe ty
splitPredTy_maybe other = Nothing
splitDictTy :: Type -> (Class, [Type])
isTauTy (FunTy a b) = isTauTy a && isTauTy b
isTauTy (PredTy p) = isTauTy (predRepTy p)
isTauTy (NoteTy _ ty) = isTauTy ty
+isTauTy (UsageTy _ ty) = isTauTy ty
isTauTy other = False
\end{code}
\begin{code}
mkRhoTy :: [PredType] -> Type -> Type
-mkRhoTy theta ty = foldr (\p r -> FunTy (mkPredTy p) r) ty theta
+mkRhoTy theta ty = UASSERT2( not (isUTy ty), pprType ty )
+ foldr (\p r -> FunTy (mkUTyM (mkPredTy p)) (mkUTyM r)) ty theta
splitRhoTy :: Type -> ([PredType], Type)
splitRhoTy ty = split ty ty []
Just p -> split res res (p:ts)
Nothing -> (reverse ts, orig_ty)
split orig_ty (NoteTy _ ty) ts = split orig_ty ty ts
+ split orig_ty (UsageTy _ ty) ts = split orig_ty ty ts
split orig_ty ty ts = (reverse ts, orig_ty)
\end{code}
isSigmaTy (ForAllTy tyvar ty) = True
isSigmaTy (FunTy a b) = isPredTy a
isSigmaTy (NoteTy _ ty) = isSigmaTy ty
+isSigmaTy (UsageTy _ ty) = isSigmaTy ty
isSigmaTy _ = False
splitSigmaTy :: Type -> ([TyVar], [PredType], Type)
getDFunTyKey (NoteTy _ t) = getDFunTyKey t
getDFunTyKey (FunTy arg _) = getOccName funTyCon
getDFunTyKey (ForAllTy _ t) = getDFunTyKey t
+getDFunTyKey (UsageTy _ t) = getDFunTyKey t
-- PredTy shouldn't happen
\end{code}
-- a strange kind like (*->*).
typeKind (ForAllTy tv ty) = typeKind ty
+typeKind (UsageTy _ ty) = typeKind ty -- we don't have separate kinds for ann/unann
\end{code}
tyVarsOfType (TyConApp tycon tys) = tyVarsOfTypes tys
tyVarsOfType (NoteTy (FTVNote tvs) ty2) = tvs
tyVarsOfType (NoteTy (SynNote ty1) ty2) = tyVarsOfType ty1
-tyVarsOfType (NoteTy (UsgNote _) ty) = tyVarsOfType ty
-tyVarsOfType (NoteTy (UsgForAll _) ty) = tyVarsOfType ty
tyVarsOfType (PredTy p) = tyVarsOfPred p
tyVarsOfType (FunTy arg res) = tyVarsOfType arg `unionVarSet` tyVarsOfType res
tyVarsOfType (AppTy fun arg) = tyVarsOfType fun `unionVarSet` tyVarsOfType arg
tyVarsOfType (ForAllTy tyvar ty) = tyVarsOfType ty `minusVarSet` unitVarSet tyvar
+tyVarsOfType (UsageTy u ty) = tyVarsOfType u `unionVarSet` tyVarsOfType ty
tyVarsOfTypes :: [Type] -> TyVarSet
tyVarsOfTypes tys = foldr (unionVarSet.tyVarsOfType) emptyVarSet tys
tyVarsOfTheta = foldr (unionVarSet . tyVarsOfPred) emptyVarSet
-- Add a Note with the free tyvars to the top of the type
--- (but under a usage if there is one)
addFreeTyVars :: Type -> Type
-addFreeTyVars (NoteTy note@(UsgNote _) ty) = NoteTy note (addFreeTyVars ty)
-addFreeTyVars (NoteTy note@(UsgForAll _) ty) = NoteTy note (addFreeTyVars ty)
addFreeTyVars ty@(NoteTy (FTVNote _) _) = ty
addFreeTyVars ty = NoteTy (FTVNote (tyVarsOfType ty)) ty
namesOfType (FunTy arg res) = namesOfType arg `unionNameSets` namesOfType res
namesOfType (AppTy fun arg) = namesOfType fun `unionNameSets` namesOfType arg
namesOfType (ForAllTy tyvar ty) = namesOfType ty `delFromNameSet` getName tyvar
+namesOfType (UsageTy u ty) = namesOfType u `unionNameSets` namesOfType ty
namesOfTypes tys = foldr (unionNameSets . namesOfType) emptyNameSet tys
\end{code}
+Usage annotations of a type
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Get a list of usage annotations of a type, *in left-to-right pre-order*.
+
+\begin{code}
+usageAnnOfType :: Type -> [Type]
+usageAnnOfType ty
+ = goS ty
+ where
+ goT (TyVarTy _) = []
+ goT (AppTy ty1 ty2) = goT ty1 ++ goT ty2
+ goT (TyConApp tc tys) = concatMap goT tys
+ goT (FunTy sty1 sty2) = goS sty1 ++ goS sty2
+ goT (ForAllTy mv ty) = goT ty
+ goT (PredTy p) = goT (predRepTy p)
+ goT ty@(UsageTy _ _) = pprPanic "usageAnnOfType: unexpected usage:" (pprType ty)
+ goT (NoteTy note ty) = goT ty
+
+ goS sty = case splitUTy sty of
+ (u,tty) -> u : goT tty
+\end{code}
+
%************************************************************************
%* *
go (ForAllTy tv ty) = ForAllTy tvp SAPPLY (tidyType envp ty)
where
(envp, tvp) = tidyTyVar env tv
+ go (UsageTy u ty) = (UsageTy SAPPLY (go u)) SAPPLY (go ty)
go_note (SynNote ty) = SynNote SAPPLY (go ty)
go_note note@(FTVNote ftvs) = note -- No need to tidy the free tyvars
- go_note note@(UsgNote _) = note -- Usage annotation is already tidy
- go_note note@(UsgForAll _) = note -- Uvar binder is already tidy
go_pred (Class c tys) = Class c (tidyTypes env tys)
go_pred (IParam n ty) = IParam n (go ty)
isUnLiftedType (ForAllTy tv ty) = isUnLiftedType ty
isUnLiftedType (NoteTy _ ty) = isUnLiftedType ty
isUnLiftedType (TyConApp tc _) = isUnLiftedTyCon tc
+isUnLiftedType (UsageTy _ ty) = isUnLiftedType ty
isUnLiftedType other = False
isUnboxedTupleType :: Type -> Bool
seqType (PredTy p) = seqPred p
seqType (TyConApp tc tys) = tc `seq` seqTypes tys
seqType (ForAllTy tv ty) = tv `seq` seqType ty
+seqType (UsageTy u ty) = seqType u `seq` seqType ty
seqTypes :: [Type] -> ()
seqTypes [] = ()
seqNote :: TyNote -> ()
seqNote (SynNote ty) = seqType ty
seqNote (FTVNote set) = sizeUniqSet set `seq` ()
-seqNote (UsgNote usg) = usg `seq` ()
seqPred :: PredType -> ()
seqPred (Class c tys) = c `seq` seqTypes tys
%************************************************************************
-For the moment at least, type comparisons don't work if
-there are embedded for-alls.
-
\begin{code}
instance Eq Type where
ty1 == ty2 = case ty1 `compare` ty2 of { EQ -> True; other -> False }
cmpTy env (FunTy f1 a1) (FunTy f2 a2) = cmpTy env f1 f2 `thenCmp` cmpTy env a1 a2
cmpTy env (TyConApp tc1 tys1) (TyConApp tc2 tys2) = (tc1 `compare` tc2) `thenCmp` (cmpTys env tys1 tys2)
cmpTy env (ForAllTy tv1 t1) (ForAllTy tv2 t2) = cmpTy (extendVarEnv env tv1 tv2) t1 t2
+cmpTy env (UsageTy u1 t1) (UsageTy u2 t2) = cmpTy env u1 u2 `thenCmp` cmpTy env t1 t2
- -- Deal with the rest: TyVarTy < AppTy < FunTy < TyConApp < ForAllTy
+ -- Deal with the rest: TyVarTy < AppTy < FunTy < TyConApp < ForAllTy < UsageTy
cmpTy env (AppTy _ _) (TyVarTy _) = GT
cmpTy env (FunTy _ _) (TyVarTy _) = GT
cmpTy env (TyConApp _ _) (AppTy _ _) = GT
cmpTy env (TyConApp _ _) (FunTy _ _) = GT
-cmpTy env (ForAllTy _ _) other = GT
+cmpTy env (ForAllTy _ _) (TyVarTy _) = GT
+cmpTy env (ForAllTy _ _) (AppTy _ _) = GT
+cmpTy env (ForAllTy _ _) (FunTy _ _) = GT
+cmpTy env (ForAllTy _ _) (TyConApp _ _) = GT
+
+cmpTy env (UsageTy _ _) other = GT
cmpTy env _ _ = LT
\begin{code}
module TypeRep (
- Type(..), TyNote(..), PredType(..), UsageAnn(..), -- Representation visible to friends
+ Type(..), TyNote(..), PredType(..), -- Representation visible to friends
Kind, ThetaType, RhoType, TauType, SigmaType, -- Synonyms
TyVarSubst,
boxedTypeKind, unboxedTypeKind, openTypeKind, -- :: KX
mkArrowKind, mkArrowKinds, -- :: KX -> KX -> KX
+ usageKindCon, -- :: KX
+ usageTypeKind, -- :: KX
+ usOnceTyCon, usManyTyCon, -- :: $
+ usOnce, usMany, -- :: $
+
funTyCon
) where
#include "HsVersions.h"
-- friends:
-import Var ( TyVar, UVar )
+import Var ( TyVar )
import VarEnv
import VarSet
import Name ( Name, mkGlobalName, mkKindOccFS, tcName )
import OccName ( tcName )
-import TyCon ( TyCon, KindCon,
- mkFunTyCon, mkKindCon, mkSuperKindCon,
- )
+import TyCon ( TyCon, KindCon, mkFunTyCon, mkKindCon, mkSuperKindCon )
import Class ( Class )
-- others
import SrcLoc ( builtinSrcLoc )
-import PrelNames ( pREL_GHC, kindConKey, boxityConKey, boxedConKey,
- unboxedConKey, typeConKey, anyBoxConKey, funTyConName
+import PrelNames ( pREL_GHC, superKindName, superBoxityName, boxedConName,
+ unboxedConName, typeConName, openKindConName, funTyConName,
+ usageKindConName, usOnceTyConName, usManyTyConName
)
\end{code}
| PredTy -- A Haskell predicate
PredType
+ | UsageTy -- A usage-annotated type
+ Type -- - Annotation of kind $ (i.e., usage annotation)
+ Type -- - Annotated type
+
| NoteTy -- A type with a note attached
TyNote
Type -- The expanded version
data TyNote
= SynNote Type -- The unexpanded version of the type synonym; always a TyConApp
| FTVNote TyVarSet -- The free type variables of the noted expression
- | UsgNote UsageAnn -- The usage annotation at this node
- | UsgForAll UVar -- Annotation variable binder
-
-data UsageAnn
- = UsOnce -- Used at most once
- | UsMany -- Used possibly many times (no info; this annotation can be omitted)
- | UsVar UVar -- Annotation is variable (unbound OK only inside analysis)
-
type ThetaType = [PredType]
type RhoType = Type
type SigmaType = Type
\end{code}
+INVARIANT: UsageTys are optional, but may *only* appear immediately
+under a FunTy (either argument), or at top-level of a Type permitted
+to be annotated (such as the type of an Id). NoteTys are transparent
+for the purposes of this rule.
-------------------------------------
Predicates
Kinds
~~~~~
kind :: KX = kind -> kind
+
| Type boxity -- (Type *) is printed as just *
-- (Type #) is printed as just #
+ | UsageKind -- Printed '$'; used for usage annotations
+
| OpenKind -- Can be boxed or unboxed
-- Printed '?'
\begin{code}
superKind :: SuperKind -- KX, the type of all kinds
-superKindName = mk_kind_name kindConKey SLIT("KX")
superKind = TyConApp (mkSuperKindCon superKindName) []
superBoxity :: SuperKind -- BX, the type of all boxities
-superBoxityName = mk_kind_name boxityConKey SLIT("BX")
superBoxity = TyConApp (mkSuperKindCon superBoxityName) []
\end{code}
\begin{code}
boxedBoxity, unboxedBoxity :: Kind -- :: BX
-
-boxedConName = mk_kind_name boxedConKey SLIT("*")
boxedBoxity = TyConApp (mkKindCon boxedConName superBoxity) []
-unboxedConName = mk_kind_name unboxedConKey SLIT("#")
unboxedBoxity = TyConApp (mkKindCon unboxedConName superBoxity) []
\end{code}
------------------------------------------
-Define kinds: Type, Type *, Type #, and OpenKind
+Define kinds: Type, Type *, Type #, OpenKind, and UsageKind
\begin{code}
typeCon :: KindCon -- :: BX -> KX
-typeConName = mk_kind_name typeConKey SLIT("Type")
typeCon = mkKindCon typeConName (superBoxity `FunTy` superKind)
boxedTypeKind, unboxedTypeKind, openTypeKind :: Kind -- Of superkind superKind
boxedTypeKind = TyConApp typeCon [boxedBoxity]
unboxedTypeKind = TyConApp typeCon [unboxedBoxity]
-openKindConName = mk_kind_name anyBoxConKey SLIT("?")
openKindCon = mkKindCon openKindConName superKind
openTypeKind = TyConApp openKindCon []
+
+usageKindCon = mkKindCon usageKindConName superKind
+usageTypeKind = TyConApp usageKindCon []
\end{code}
------------------------------------------
funTyCon = mkFunTyCon funTyConName (mkArrowKinds [boxedTypeKind, boxedTypeKind] boxedTypeKind)
\end{code}
+------------------------------------------
+Usage tycons @.@ and @!@
+
+The usage tycons are of kind usageTypeKind (`$'). The types contain
+no values, and are used purely for usage annotation. mk_kind_name is
+used (hackishly) to avoid z-encoding of the names.
+
+\begin{code}
+usOnceTyCon = mkKindCon usOnceTyConName usageTypeKind
+usOnce = TyConApp usOnceTyCon []
+
+usManyTyCon = mkKindCon usManyTyConName usageTypeKind
+usMany = TyConApp usManyTyCon []
+\end{code}
match, matchTy, matchTys
) where
+#include "HsVersions.h"
+
import TypeRep ( Type(..) ) -- friend
-import Type ( typeKind, tyVarsOfType, splitAppTy_maybe )
+import Type ( typeKind, tyVarsOfType, splitAppTy_maybe,
+ splitUTy, isUTy, deNoteType
+ )
import PprType () -- Instances
-- This import isn't strictly necessary, but it makes sure that
SubstResult(..)
)
-import Outputable( panic )
+import Outputable
\end{code}
%************************************************************************
%* *
-\subsection{Unification wih a explicit substitution}
+\subsection{Unification with an explicit substitution}
%* *
%************************************************************************
Unify types with an explicit substitution and no monad.
+Ignore usage annotations.
\begin{code}
type MySubst
uTysX ty1 (ForAllTy _ _) k subst = panic "Unify.uTysX subst:ForAllTy (2nd arg)"
#endif
+ -- Ignore usages
+uTysX (UsageTy _ t1) t2 k subst = uTysX t1 t2 k subst
+uTysX t1 (UsageTy _ t2) k subst = uTysX t1 t2 k subst
+
-- Anything else fails
uTysX ty1 ty2 k subst = Nothing
| typeKind ty2 == tyVarKind tv1
&& occur_check_ok ty2
-> -- No kind mismatch nor occur check
- k (tmpls, extendSubstEnv env tv1 (DoneTy ty2))
+ UASSERT( not (isUTy ty2) )
+ k (tmpls, extendSubstEnv env tv1 (DoneTy ty2))
| otherwise -> Nothing -- Fail if kind mis-match or occur check
where
types. It also fails on nested foralls.
@matchTys@ matches corresponding elements of a list of templates and
-types.
+types. It and @matchTy@ both ignore usage annotations, unlike the
+main function @match@.
\begin{code}
matchTy :: TyVarSet -- Template tyvars
-> Maybe (TyVarSubstEnv, -- Matching substitution
[Type]) -- Left over instance types
-matchTy tmpls ty1 ty2 = match ty1 ty2 tmpls (\ senv -> Just senv) emptySubstEnv
+matchTy tmpls ty1 ty2 = match False ty1 ty2 tmpls (\ senv -> Just senv) emptySubstEnv
-matchTys tmpls tys1 tys2 = match_list tys1 tys2 tmpls
+matchTys tmpls tys1 tys2 = match_list False tys1 tys2 tmpls
(\ (senv,tys) -> Just (senv,tys))
emptySubstEnv
\end{code}
-@match@ is the main function.
+@match@ is the main function. It takes a flag indicating whether
+usage annotations are to be respected.
\begin{code}
-match :: Type -> Type -- Current match pair
+match :: Bool -- Respect usages?
+ -> Type -> Type -- Current match pair
-> TyVarSet -- Template vars
-> (TyVarSubstEnv -> Maybe result) -- Continuation
-> TyVarSubstEnv -- Current subst
-- has already been bound. If so, check that what it's bound to
-- is the same as ty; if not, bind it and carry on.
-match (TyVarTy v) ty tmpls k senv
+match uflag (TyVarTy v) ty tmpls k senv
| v `elemVarSet` tmpls
= -- v is a template variable
case lookupSubstEnv senv v of
- Nothing -> k (extendSubstEnv senv v (DoneTy ty))
+ Nothing -> UASSERT( not (isUTy ty) )
+ k (extendSubstEnv senv v (DoneTy ty))
Just (DoneTy ty') | ty' == ty -> k senv -- Succeeds
| otherwise -> Nothing -- Fails
| otherwise
= -- v is not a template variable; ty had better match
-- Can't use (==) because types differ
- case ty of
+ case deNoteType ty of
TyVarTy v' | v == v' -> k senv -- Success
other -> Nothing -- Failure
+ -- This deNoteType is *required* and cost me much pain. I guess
+ -- the reason the Note-stripping case is *last* rather than first
+ -- is to preserve type synonyms etc., so I'm not moving it to the
+ -- top; but this means that (without the deNotetype) a type
+ -- variable may not match the pattern (TyVarTy v') as one would
+ -- expect, due to an intervening Note. KSW 2000-06.
-match (FunTy arg1 res1) (FunTy arg2 res2) tmpls k senv
- = match arg1 arg2 tmpls (match res1 res2 tmpls k) senv
+match uflag (FunTy arg1 res1) (FunTy arg2 res2) tmpls k senv
+ = match uflag arg1 arg2 tmpls (match uflag res1 res2 tmpls k) senv
-match (AppTy fun1 arg1) ty2 tmpls k senv
+match uflag (AppTy fun1 arg1) ty2 tmpls k senv
= case splitAppTy_maybe ty2 of
- Just (fun2,arg2) -> match fun1 fun2 tmpls (match arg1 arg2 tmpls k) senv
+ Just (fun2,arg2) -> match uflag fun1 fun2 tmpls (match uflag arg1 arg2 tmpls k) senv
Nothing -> Nothing -- Fail
-match (TyConApp tc1 tys1) (TyConApp tc2 tys2) tmpls k senv
+match uflag (TyConApp tc1 tys1) (TyConApp tc2 tys2) tmpls k senv
| tc1 == tc2
- = match_list tys1 tys2 tmpls k' senv
+ = match_list uflag tys1 tys2 tmpls k' senv
where
k' (senv', tys2') | null tys2' = k senv' -- Succeed
| otherwise = Nothing -- Fail
+match False (UsageTy _ ty1) ty2 tmpls k senv = match False ty1 ty2 tmpls k senv
+match False ty1 (UsageTy _ ty2) tmpls k senv = match False ty1 ty2 tmpls k senv
+
+match True (UsageTy u1 ty1) (UsageTy u2 ty2) tmpls k senv
+ = match True u1 u2 tmpls (match True ty1 ty2 tmpls k) senv
+match True ty1@(UsageTy _ _) ty2 tmpls k senv
+ = case splitUTy ty2 of { (u,ty2') -> match True ty1 ty2' tmpls k senv }
+match True ty1 ty2@(UsageTy _ _) tmpls k senv
+ = case splitUTy ty1 of { (u,ty1') -> match True ty1' ty2 tmpls k senv }
+
-- With type synonyms, we have to be careful for the exact
-- same reasons as in the unifier. Please see the
-- considerable commentary there before changing anything
-- here! (WDP 95/05)
-match (NoteTy _ ty1) ty2 tmpls k senv = match ty1 ty2 tmpls k senv
-match ty1 (NoteTy _ ty2) tmpls k senv = match ty1 ty2 tmpls k senv
+match uflag (NoteTy _ ty1) ty2 tmpls k senv = match uflag ty1 ty2 tmpls k senv
+match uflag ty1 (NoteTy _ ty2) tmpls k senv = match uflag ty1 ty2 tmpls k senv
-- Catch-all fails
-match _ _ _ _ _ = Nothing
+match _ _ _ _ _ _ = Nothing
-match_list [] tys2 tmpls k senv = k (senv, tys2)
-match_list (ty1:tys1) [] tmpls k senv = Nothing -- Not enough arg tys => failure
-match_list (ty1:tys1) (ty2:tys2) tmpls k senv = match ty1 ty2 tmpls (match_list tys1 tys2 tmpls k) senv
+match_list uflag [] tys2 tmpls k senv = k (senv, tys2)
+match_list uflag (ty1:tys1) [] tmpls k senv = Nothing -- Not enough arg tys => failure
+match_list uflag (ty1:tys1) (ty2:tys2) tmpls k senv
+ = match uflag ty1 ty2 tmpls (match_list uflag tys1 tys2 tmpls k) senv
\end{code}
initial_oi = foldl (\fm tc -> addToFM fm tc (initial tc)) emptyFM tycons
initial tc = if isAlgTyCon tc && null (tyConDataConsIfAvailable tc) then
-- make pessimistic assumption (and warn)
- take (tyConArity tc) abstractVrcs
+ abstractVrcs tc
else
replicate (tyConArity tc) (False,False)
tcaoIter oi tc | isAlgTyCon tc
= if null data_cons then
-- Abstract types get uninformative variances
- abstractVrcs
+ abstractVrcs tc
else
map (\v -> anyVrc (\ty -> vrcInTy myfao v ty) argtys)
vs
in map (\v -> vrcInTy myfao v ty) tyvs
-abstractVrcs :: ArgVrcs
--- we pull this out as a CAF so the warning only appears *once*
-abstractVrcs = trace ("WARNING: tyConArgVrc info inaccurate due to unavailable constructors.\n"
- ++ "\tUse -fno-prune-tydecls to fix.") $
- repeat (True,True)
+abstractVrcs :: TyCon -> ArgVrcs
+abstractVrcs tc =
+#ifdef DEBUG
+ pprTrace "Vrc: abstract tycon:" (ppr tc) $
+#endif
+ warn_abstract_vrcs `seq` replicate (tyConArity tc) (True,True)
+
+warn_abstract_vrcs
+-- we pull the message out as a CAF so the warning only appears *once*
+ = trace ("WARNING: tyConArgVrc info inaccurate due to unavailable constructors.\n"
+ ++ " Use -fno-prune-tydecls to fix.") $
+ ()
\end{code}
-> Type -- type to check for occ in
-> (Bool,Bool) -- (occurs positively, occurs negatively)
-vrcInTy fao v (NoteTy (UsgNote _) ty) = vrcInTy fao v ty
-
-vrcInTy fao v (NoteTy (UsgForAll _) ty) = vrcInTy fao v ty
-
vrcInTy fao v (NoteTy (SynNote _) ty) = vrcInTy fao v ty
-- SynTyCon doesn't neccessarily have vrcInfo at this point,
-- so don't try and use it
-- hence if v occurs in ty2 at all then it could occur with
-- either variance. Otherwise it occurs as it does in ty1.
-vrcInTy fao v (FunTy ty1 ty2) = let (p1,m1) = vrcInTy fao v ty1
- (p2,m2) = vrcInTy fao v ty2
- in (m1||p2,p1||m2)
+vrcInTy fao v (FunTy ty1 ty2) = negVrc (vrcInTy fao v ty1)
+ `orVrc`
+ vrcInTy fao v ty2
vrcInTy fao v (ForAllTy v' ty) = if v==v'
then (False,False)
vrcInTy fao v (TyConApp tc tys) = let pms1 = map (vrcInTy fao v) tys
pms2 = fao tc
in orVrcs (zipWith timesVrc pms1 pms2)
+
+vrcInTy fao v (UsageTy u ty) = vrcInTy fao v u `orVrc` vrcInTy fao v ty
\end{code}
orVrcs :: [(Bool,Bool)] -> (Bool,Bool)
orVrcs = foldl orVrc (False,False)
+negVrc :: (Bool,Bool) -> (Bool,Bool)
+negVrc (p1,m1) = (m1,p1)
+
anyVrc :: (a -> (Bool,Bool)) -> [a] -> (Bool,Bool)
anyVrc p as = foldl (\ pm a -> pm `orVrc` p a)
(False,False) as
Keith Wansbrough 1998-02-16..1999-04-29
\begin{code}
-module UConSet ( UConSet,
+module UConSet ( {- SEE BELOW: -- KSW 2000-10-13
+ UConSet,
emptyUConSet,
eqManyUConSet,
eqUConSet,
leqUConSet,
unionUCS,
unionUCSs,
- solveUCS,
+ solveUCS, -}
) where
#include "HsVersions.h"
import VarEnv
-import Type ( UsageAnn(..) )
-import Var ( UVar )
import Bag ( Bag, unitBag, emptyBag, unionBags, foldlBag, bagToList )
import Outputable
import PprType
+
+{- ENTIRE FILE COMMENTED OUT FOR NOW -- KSW 2000-10-13
+
+ This monomorphic version of the analysis is outdated. I'm
+ currently ripping out the old one and inserting the new one. For
+ now, I'm simply commenting out this entire file.
+
\end{code}
======================================================================
ppr (UConFail d)
= hang (text "UConSet inconsistent:")
4 d
+
+END OF ENTIRELY-COMMENTED-OUT FILE -- KSW 2000-10-13 -}
\end{code}
======================================================================
import CoreFVs ( mustHaveLocalBinding )
import Rules ( RuleBase )
import TypeRep ( Type(..), TyNote(..) ) -- friend
-import Type ( UsageAnn(..),
- applyTy, applyTys,
+import Type ( applyTy, applyTys,
splitFunTy_maybe, splitFunTys, splitTyConApp_maybe,
- mkUsgTy, splitUsgTy, isUsgTy, isNotUsgTy, unUsgTy, tyUsg,
- splitUsForAllTys, substUsTy,
mkFunTy, mkForAllTy )
import TyCon ( tyConArgVrcs_maybe, isFunTyCon )
import Literal ( Literal(..), literalType )
-import Var ( Var, UVar, varType, setVarType, mkUVar, modifyIdInfo )
+import Var ( Var, varType, setVarType, modifyIdInfo )
import IdInfo ( setLBVarInfo, LBVarInfo(..) )
import Id ( isExportedId )
import VarEnv
= do { printErrs (text "WARNING: ignoring requested -fusagesp pass; requires -fusagesp-on") ;
return binds
}
-
+
+{- ENTIRE PASS COMMENTED OUT FOR NOW -- KSW 2000-10-13
+
+ This monomorphic version of the analysis is outdated. I'm
+ currently ripping out the old one and inserting the new one. For
+ now, I'm simply commenting out this entire pass.
+
+
| otherwise
= do
let binds1 = doUnAnnotBinds binds
isUnAnnotated (TyConApp tc tys) = all isUnAnnotated tys
isUnAnnotated (FunTy ty1 ty2) = isUnAnnotated ty1 && isUnAnnotated ty2
isUnAnnotated (ForAllTy tyv ty) = isUnAnnotated ty
+
+
+END OF ENTIRELY-COMMENTED-OUT PASS -- KSW 2000-10-13 -}
\end{code}
======================================================================
Keith Wansbrough 1998-09-04..1999-06-25
\begin{code}
-module UsageSPLint ( doLintUSPAnnotsBinds,
+module UsageSPLint ( {- SEE BELOW: -- KSW 2000-10-13
+ doLintUSPAnnotsBinds,
doLintUSPConstBinds,
doLintUSPBinds,
- doCheckIfWorseUSP,
+ doCheckIfWorseUSP, -}
) where
#include "HsVersions.h"
import UsageSPUtils
import CoreSyn
import TypeRep ( Type(..), TyNote(..) ) -- friend
-import Type ( UsageAnn(..), isUsgTy, tyUsg )
+import Type ( )
import TyCon ( isAlgTyCon, isPrimTyCon, isSynTyCon, isFunTyCon )
import Var ( Var, varType )
import Id ( idLBVarInfo )
import Util ( zipWithEqual )
import Bag
import Outputable
+
+{- ENTIRE FILE COMMENTED OUT FOR NOW -- KSW 2000-10-13
+
+ This monomorphic version of the analysis is outdated. I'm
+ currently ripping out the old one and inserting the new one. For
+ now, I'm simply commenting out this entire file.
+
\end{code}
======================================================================
(_,errs) -> if isEmptyBag errs
then Nothing
else Just (vcat (map pprULintErr (bagToList errs)))
+
+END OF ENTIRELY-COMMENTED-OUT FILE -- KSW 2000-10-13 -}
\end{code}
======================================================================
Keith Wansbrough 1998-09-04..1999-07-07
\begin{code}
-module UsageSPUtils ( AnnotM(AnnotM), initAnnotM,
+module UsageSPUtils ( {- SEE BELOW: -- KSW 2000-10-13
+ AnnotM(AnnotM), initAnnotM,
genAnnotBinds,
MungeFlags(isSigma,isLocal,isExp,hasUsg,mfLoc),
newVarUs, newVarUSMM,
UniqSMM, usToUniqSMM, uniqSMMToUs,
- primOpUsgTys,
+ primOpUsgTys, -}
) where
#include "HsVersions.h"
+{- ENTIRE FILE COMMENTED OUT FOR NOW -- KSW 2000-10-13
import CoreSyn
import CoreFVs ( mustHaveLocalBinding )
import Var ( Var, varType, setVarType, mkUVar )
import Id ( isExportedId )
import Name ( isLocallyDefined )
import TypeRep ( Type(..), TyNote(..) ) -- friend
-import Type ( UsageAnn(..), isUsgTy, splitFunTys )
+import Type ( splitFunTys )
import Subst ( substTy, mkTyVarSubst )
import TyCon ( isAlgTyCon, isPrimTyCon, isSynTyCon, isFunTyCon )
import VarEnv
import PrimOp ( PrimOp, primOpUsg )
import UniqSupply ( UniqSupply, UniqSM, initUs, getUniqueUs, thenUs, returnUs )
import Outputable
+
+
+ This monomorphic version of the analysis is outdated. I'm
+ currently ripping out the old one and inserting the new one. For
+ now, I'm simply commenting out this entire file.
+
+
\end{code}
======================================================================
-- substitution may reveal more args
in ((map (substTy s) ty0us) ++ ty1us,
rty1u)
+
+
+END OF ENTIRELY-COMMENTED-OUT FILE -- KSW 2000-10-13 -}
\end{code}
======================================================================