- isConstMethodId,
- isConstMethodId_maybe,
- isDataCon,
- isDefaultMethodId,
- isDefaultMethodId_maybe,
- isDictFunId,
- isImportedId,
- isMethodSelId,
- isNullaryDataCon,
- isSpecPragmaId,
- isSuperDictSelId_maybe,
- isSysLocalId,
- isTopLevId,
- isTupleCon,
- isWorkerId,
- isWrapperId,
- toplevelishId,
- unfoldingUnfriendlyId,
-
- -- SUBSTITUTION
- applyTypeEnvToId,
- apply_to_Id,
-
- -- PRINTING and RENUMBERING
- addId,
- nmbrDataCon,
- nmbrId,
- pprId,
- showId,
-
- -- UNFOLDING, ARITY, UPDATE, AND STRICTNESS STUFF (etc)
- addIdArity,
- addIdDemandInfo,
- addIdStrictness,
- addIdUpdateInfo,
- getIdArity,
- getIdDemandInfo,
- getIdInfo,
- getIdStrictness,
- getIdUnfolding,
- getIdUpdateInfo,
- getPragmaInfo,
- replaceIdInfo,
-
- -- IdEnvs AND IdSets
- SYN_IE(IdEnv), SYN_IE(GenIdSet), SYN_IE(IdSet),
- addOneToIdEnv,
- addOneToIdSet,
- combineIdEnvs,
- delManyFromIdEnv,
- delOneFromIdEnv,
- elementOfIdSet,
- emptyIdSet,
- growIdEnv,
- growIdEnvList,
- idSetToList,
- intersectIdSets,
- isEmptyIdSet,
- isNullIdEnv,
- lookupIdEnv,
- lookupNoFailIdEnv,
- mapIdEnv,
- minusIdSet,
- mkIdEnv,
- mkIdSet,
- modifyIdEnv,
- nullIdEnv,
- rngIdEnv,
- unionIdSets,
- unionManyIdSets,
- unitIdEnv,
- unitIdSet
- ) where
-
-IMP_Ubiq()
-IMPORT_DELOOPER(IdLoop) -- for paranoia checking
-IMPORT_DELOOPER(TyLoop) -- for paranoia checking
-
-import Bag
-import Class ( classOpString, SYN_IE(Class), GenClass, SYN_IE(ClassOp), GenClassOp )
-import IdInfo
-import Maybes ( maybeToBool )
-import Name ( appendRdr, nameUnique, mkLocalName, isLocalName,
- isLocallyDefinedName,
- mkTupleDataConName, mkCompoundName, mkCompoundName2,
- isLexSym, isLexSpecialSym,
- isLocallyDefined, changeUnique,
- getOccName, origName, moduleOf,
- isExported, ExportFlag(..),
- RdrName(..), Name
- )
-import FieldLabel ( fieldLabelName, FieldLabel(..){-instances-} )
-import PragmaInfo ( PragmaInfo(..) )
-import PprEnv -- ( SYN_IE(NmbrM), NmbrEnv(..) )
-import PprType ( getTypeString, typeMaybeString, specMaybeTysSuffix,
- nmbrType, nmbrTyVar,
- GenType, GenTyVar
- )
-import PprStyle
-import Pretty
-import SrcLoc ( mkBuiltinSrcLoc )
-import TyCon ( TyCon, mkTupleTyCon, tyConDataCons )
-import Type ( mkSigmaTy, mkTyVarTys, mkFunTys, mkDictTy,
- applyTyCon, instantiateTy,
- tyVarsOfType, applyTypeEnvToTy, typePrimRep,
- GenType, SYN_IE(ThetaType), SYN_IE(TauType), SYN_IE(Type)
- )
-import TyVar ( alphaTyVars, isEmptyTyVarSet, SYN_IE(TyVarEnv) )
-import UniqFM
-import UniqSet -- practically all of it
-import Unique ( getBuiltinUniques, pprUnique, showUnique,
- incrUnique,
- Unique{-instance Ord3-}
- )
-import Util ( mapAccumL, nOfThem, zipEqual,
- panic, panic#, pprPanic, assertPanic
- )
-\end{code}
-
-Here are the @Id@ and @IdDetails@ datatypes; also see the notes that
-follow.
-
-Every @Id@ has a @Unique@, to uniquify it and for fast comparison, a
-@Type@, and an @IdInfo@ (non-essential info about it, e.g.,
-strictness). The essential info about different kinds of @Ids@ is
-in its @IdDetails@.
-
-ToDo: possibly cache other stuff in the single-constructor @Id@ type.
-
-\begin{code}
-data GenId ty = Id
- Unique -- Key for fast comparison
- Name
- ty -- Id's type; used all the time;
- IdDetails -- Stuff about individual kinds of Ids.
- PragmaInfo -- Properties of this Id requested by programmer
- -- eg specialise-me, inline-me
- IdInfo -- Properties of this Id deduced by compiler
-
-type Id = GenId Type
-
-data StrictnessMark = MarkedStrict | NotMarkedStrict
-
-data IdDetails
-
- ---------------- Local values
-
- = LocalId Bool -- Local name; mentioned by the user
- -- True <=> no free type vars
-
- | SysLocalId Bool -- Local name; made up by the compiler
- -- as for LocalId
-
- | SpecPragmaId -- Local name; introduced by the compiler
- (Maybe Id) -- for explicit specid in pragma
- Bool -- as for LocalId
-
- ---------------- Global values
-
- | ImportedId -- Global name (Imported or Implicit); Id imported from an interface
-
- | TopLevId -- Global name (LocalDef); Top-level in the orig source pgm
- -- (not moved there by transformations).
-
- -- a TopLevId's type may contain free type variables, if
- -- the monomorphism restriction applies.
-
- ---------------- Data constructors
-
- | DataConId ConTag
- [StrictnessMark] -- Strict args; length = arity
- [FieldLabel] -- Field labels for this constructor
-
- [TyVar] [(Class,Type)] [Type] TyCon
- -- the type is:
- -- forall tyvars . theta_ty =>
- -- unitype_1 -> ... -> unitype_n -> tycon tyvars
-
- | TupleConId Int -- Its arity
-
- | RecordSelId FieldLabel
-
- ---------------- Things to do with overloading
-
- | SuperDictSelId -- Selector for superclass dictionary
- Class -- The class (input dict)
- Class -- The superclass (result dict)
-
- | MethodSelId Class -- An overloaded class operation, with
- -- a fully polymorphic type. Its code
- -- just selects a method from the
- -- dictionary. The class.
- ClassOp -- The operation
-
- -- NB: The IdInfo for a MethodSelId has all the info about its
- -- related "constant method Ids", which are just
- -- specialisations of this general one.
-
- | DefaultMethodId -- Default method for a particular class op
- Class -- same class, <blah-blah> info as MethodSelId
- ClassOp -- (surprise, surprise)
- Bool -- True <=> I *know* this default method Id
- -- is a generated one that just says
- -- `error "No default method for <op>"'.
-
- -- see below
- | DictFunId Class -- A DictFun is uniquely identified
- Type -- by its class and type; this type has free type vars,
- -- whose identity is irrelevant. Eg Class = Eq
- -- Type = Tree a
- -- The "a" is irrelevant. As it is too painful to
- -- actually do comparisons that way, we kindly supply
- -- a Unique for that purpose.
- Module -- module where instance came from
-
- -- see below
- | ConstMethodId -- A method which depends only on the type of the
- -- instance, and not on any further dictionaries etc.
- Class -- Uniquely identified by:
- Type -- (class, type, classop) triple
- ClassOp
- Module -- module where instance came from
-
- | InstId -- An instance of a dictionary, class operation,
- -- or overloaded value (Local name)
- Bool -- as for LocalId
-
- | SpecId -- A specialisation of another Id
- Id -- Id of which this is a specialisation
- [Maybe Type] -- Types at which it is specialised;
- -- A "Nothing" says this type ain't relevant.
- Bool -- True <=> no free type vars; it's not enough
- -- to know about the unspec version, because
- -- we may specialise to a type w/ free tyvars
- -- (i.e., in one of the "Maybe Type" dudes).
-
- | WorkerId -- A "worker" for some other Id
- Id -- Id for which this is a worker
-
-type ConTag = Int
-type DictVar = Id
-type DictFun = Id
-type DataCon = Id
-\end{code}
-
-DictFunIds are generated from instance decls.
-\begin{verbatim}
- class Foo a where
- op :: a -> a -> Bool
-
- instance Foo a => Foo [a] where
- op = ...
-\end{verbatim}
-generates the dict fun id decl
-\begin{verbatim}
- dfun.Foo.[*] = \d -> ...
-\end{verbatim}
-The dfun id is uniquely named by the (class, type) pair. Notice, it
-isn't a (class,tycon) pair any more, because we may get manually or
-automatically generated specialisations of the instance decl:
-\begin{verbatim}
- instance Foo [Int] where
- op = ...
-\end{verbatim}
-generates
-\begin{verbatim}
- dfun.Foo.[Int] = ...
-\end{verbatim}
-The type variables in the name are irrelevant; we print them as stars.
-
-
-Constant method ids are generated from instance decls where
-there is no context; that is, no dictionaries are needed to
-construct the method. Example
-\begin{verbatim}
- instance Foo Int where
- op = ...
-\end{verbatim}
-Then we get a constant method
-\begin{verbatim}
- Foo.op.Int = ...
-\end{verbatim}
-
-It is possible, albeit unusual, to have a constant method
-for an instance decl which has type vars:
-\begin{verbatim}
- instance Foo [a] where
- op [] ys = True
- op (x:xs) ys = False
-\end{verbatim}
-We get the constant method
-\begin{verbatim}
- Foo.op.[*] = ...
-\end{verbatim}
-So a constant method is identified by a class/op/type triple.
-The type variables in the type are irrelevant.
-
-
-For Ids whose names must be known/deducible in other modules, we have
-to conjure up their worker's names (and their worker's worker's
-names... etc) in a known systematic way.
-
-
-%************************************************************************
-%* *
-\subsection[Id-documentation]{Documentation}
-%* *
-%************************************************************************
-
-[A BIT DATED [WDP]]
-
-The @Id@ datatype describes {\em values}. The basic things we want to
-know: (1)~a value's {\em type} (@idType@ is a very common
-operation in the compiler); and (2)~what ``flavour'' of value it might
-be---for example, it can be terribly useful to know that a value is a
-class method.
-
-\begin{description}
-%----------------------------------------------------------------------
-\item[@DataConId@:] For the data constructors declared by a @data@
-declaration. Their type is kept in {\em two} forms---as a regular
-@Type@ (in the usual place), and also in its constituent pieces (in
-the ``details''). We are frequently interested in those pieces.
-
-%----------------------------------------------------------------------
-\item[@TupleConId@:] This is just a special shorthand for @DataCons@ for
-the infinite family of tuples.
-
-%----------------------------------------------------------------------
-\item[@ImportedId@:] These are values defined outside this module.
-{\em Everything} we want to know about them must be stored here (or in
-their @IdInfo@).
-
-%----------------------------------------------------------------------
-\item[@TopLevId@:] These are values defined at the top-level in this
-module; i.e., those which {\em might} be exported (hence, a
-@Name@). It does {\em not} include those which are moved to the
-top-level through program transformations.
-
-We also guarantee that @TopLevIds@ will {\em stay} at top-level.
-Theoretically, they could be floated inwards, but there's no known
-advantage in doing so. This way, we can keep them with the same
-@Unique@ throughout (no cloning), and, in general, we don't have to be
-so paranoid about them.
-
-In particular, we had the following problem generating an interface:
-We have to ``stitch together'' info (1)~from the typechecker-produced
-global-values list (GVE) and (2)~from the STG code [which @Ids@ have
-what arities]. If the @Uniques@ on the @TopLevIds@ can {\em change}
-between (1) and (2), you're sunk!
-
-%----------------------------------------------------------------------
-\item[@MethodSelId@:] A selector from a dictionary; it may select either
-a method or a dictionary for one of the class's superclasses.
-
-%----------------------------------------------------------------------
-\item[@DictFunId@:]
-
-@mkDictFunId [a,b..] theta C T@ is the function derived from the
-instance declaration
-
- instance theta => C (T a b ..) where
- ...
-
-It builds function @Id@ which maps dictionaries for theta,
-to a dictionary for C (T a b ..).
-
-*Note* that with the ``Mark Jones optimisation'', the theta may
-include dictionaries for the immediate superclasses of C at the type
-(T a b ..).
-
-%----------------------------------------------------------------------
-\item[@InstId@:]
-
-%----------------------------------------------------------------------
-\item[@SpecId@:]
-
-%----------------------------------------------------------------------
-\item[@WorkerId@:]
-
-%----------------------------------------------------------------------
-\item[@LocalId@:] A purely-local value, e.g., a function argument,
-something defined in a @where@ clauses, ... --- but which appears in
-the original program text.
-
-%----------------------------------------------------------------------
-\item[@SysLocalId@:] Same as a @LocalId@, except does {\em not} appear in
-the original program text; these are introduced by the compiler in
-doing its thing.
-
-%----------------------------------------------------------------------
-\item[@SpecPragmaId@:] Introduced by the compiler to record
-Specialisation pragmas. It is dead code which MUST NOT be removed
-before specialisation.
-\end{description}
-
-Further remarks:
-\begin{enumerate}
-%----------------------------------------------------------------------
-\item
-
-@DataCons@ @TupleCons@, @Importeds@, @TopLevIds@, @SuperDictSelIds@,
-@MethodSelIds@, @DictFunIds@, and @DefaultMethodIds@ have the following
-properties:
-\begin{itemize}
-\item
-They have no free type variables, so if you are making a
-type-variable substitution you don't need to look inside them.
-\item
-They are constants, so they are not free variables. (When the STG
-machine makes a closure, it puts all the free variables in the
-closure; the above are not required.)
-\end{itemize}
-Note that @InstIds@, @Locals@ and @SysLocals@ {\em may} have the above
-properties, but they may not.
-\end{enumerate}
-
-%************************************************************************
-%* *
-\subsection[Id-general-funs]{General @Id@-related functions}
-%* *
-%************************************************************************
-
-\begin{code}
-unsafeGenId2Id :: GenId ty -> Id
-unsafeGenId2Id (Id u n ty d p i) = Id u n (panic "unsafeGenId2Id:ty") d p i
-
-isDataCon id = is_data (unsafeGenId2Id id)
- where
- is_data (Id _ _ _ (DataConId _ _ _ _ _ _ _) _ _) = True
- is_data (Id _ _ _ (TupleConId _) _ _) = True
- is_data (Id _ _ _ (SpecId unspec _ _) _ _) = is_data unspec
- is_data other = False
-
-
-isTupleCon id = is_tuple (unsafeGenId2Id id)
- where
- is_tuple (Id _ _ _ (TupleConId _) _ _) = True
- is_tuple (Id _ _ _ (SpecId unspec _ _) _ _) = is_tuple unspec
- is_tuple other = False
-
-{-LATER:
-isSpecId_maybe (Id _ _ _ (SpecId unspec ty_maybes _) _ _)
- = ASSERT(not (maybeToBool (isSpecId_maybe unspec)))
- Just (unspec, ty_maybes)
-isSpecId_maybe other_id
- = Nothing
-
-isSpecPragmaId_maybe (Id _ _ _ (SpecPragmaId specid _) _ _)
- = Just specid
-isSpecPragmaId_maybe other_id
- = Nothing
--}
-\end{code}
-
-@toplevelishId@ tells whether an @Id@ {\em may} be defined in a nested
-@let(rec)@ (returns @False@), or whether it is {\em sure} to be
-defined at top level (returns @True@). This is used to decide whether
-the @Id@ is a candidate free variable. NB: you are only {\em sure}
-about something if it returns @True@!
-
-\begin{code}
-toplevelishId :: Id -> Bool
-idHasNoFreeTyVars :: Id -> Bool
-
-toplevelishId (Id _ _ _ details _ _)
- = chk details
- where
- chk (DataConId _ _ _ _ _ _ _) = True
- chk (TupleConId _) = True
- chk (RecordSelId _) = True
- chk ImportedId = True
- chk TopLevId = True -- NB: see notes
- chk (SuperDictSelId _ _) = True
- chk (MethodSelId _ _) = True
- chk (DefaultMethodId _ _ _) = True
- chk (DictFunId _ _ _) = True
- chk (ConstMethodId _ _ _ _) = True
- chk (SpecId unspec _ _) = toplevelishId unspec
- -- depends what the unspecialised thing is
- chk (WorkerId unwrkr) = toplevelishId unwrkr
- chk (InstId _) = False -- these are local
- chk (LocalId _) = False
- chk (SysLocalId _) = False
- chk (SpecPragmaId _ _) = False
-
-idHasNoFreeTyVars (Id _ _ _ details _ info)
- = chk details
- where
- chk (DataConId _ _ _ _ _ _ _) = True
- chk (TupleConId _) = True
- chk (RecordSelId _) = True
- chk ImportedId = True
- chk TopLevId = True
- chk (SuperDictSelId _ _) = True
- chk (MethodSelId _ _) = True
- chk (DefaultMethodId _ _ _) = True
- chk (DictFunId _ _ _) = True
- chk (ConstMethodId _ _ _ _) = True
- chk (WorkerId unwrkr) = idHasNoFreeTyVars unwrkr
- chk (SpecId _ _ no_free_tvs) = no_free_tvs
- chk (InstId no_free_tvs) = no_free_tvs
- chk (LocalId no_free_tvs) = no_free_tvs
- chk (SysLocalId no_free_tvs) = no_free_tvs
- chk (SpecPragmaId _ no_free_tvs) = no_free_tvs
-\end{code}
-
-\begin{code}
-isTopLevId (Id _ _ _ TopLevId _ _) = True
-isTopLevId other = False