diff options
author | Edward Z. Yang <ezyang@cs.stanford.edu> | 2014-09-25 02:39:12 -0700 |
---|---|---|
committer | Edward Z. Yang <ezyang@cs.stanford.edu> | 2014-09-25 02:39:12 -0700 |
commit | 46a5b7cc64c971102cd3b56e6a2d6e993bd8c576 (patch) | |
tree | 1c9b7fb2b6581085eb1d0467837adf95d1202285 | |
parent | 55e04cb9cb78951cbcc2a30cccb965124b1a283d (diff) | |
download | haskell-46a5b7cc64c971102cd3b56e6a2d6e993bd8c576.tar.gz |
Detab DataCon
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
-rw-r--r-- | compiler/basicTypes/DataCon.lhs | 700 |
1 files changed, 347 insertions, 353 deletions
diff --git a/compiler/basicTypes/DataCon.lhs b/compiler/basicTypes/DataCon.lhs index 771aa303a1..fa9e2e9a97 100644 --- a/compiler/basicTypes/DataCon.lhs +++ b/compiler/basicTypes/DataCon.lhs @@ -6,45 +6,39 @@ \begin{code} {-# LANGUAGE CPP, DeriveDataTypeable #-} -{-# OPTIONS_GHC -fno-warn-tabs #-} --- The above warning supression flag is a temporary kludge. --- While working on this module you are encouraged to remove it and --- detab the module (please do the detabbing in a separate patch). See --- http://ghc.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces --- for details module DataCon ( -- * Main data types - DataCon, DataConRep(..), HsBang(..), StrictnessMark(..), - ConTag, - - -- ** Type construction - mkDataCon, fIRST_TAG, - buildAlgTyCon, - - -- ** Type deconstruction - dataConRepType, dataConSig, dataConFullSig, - dataConName, dataConIdentity, dataConTag, dataConTyCon, + DataCon, DataConRep(..), HsBang(..), StrictnessMark(..), + ConTag, + + -- ** Type construction + mkDataCon, fIRST_TAG, + buildAlgTyCon, + + -- ** Type deconstruction + dataConRepType, dataConSig, dataConFullSig, + dataConName, dataConIdentity, dataConTag, dataConTyCon, dataConOrigTyCon, dataConUserType, - dataConUnivTyVars, dataConExTyVars, dataConAllTyVars, - dataConEqSpec, eqSpecPreds, dataConTheta, - dataConStupidTheta, - dataConInstArgTys, dataConOrigArgTys, dataConOrigResTy, - dataConInstOrigArgTys, dataConRepArgTys, - dataConFieldLabels, dataConFieldType, - dataConStrictMarks, - dataConSourceArity, dataConRepArity, dataConRepRepArity, - dataConIsInfix, - dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitIds, - dataConRepStrictness, dataConRepBangs, dataConBoxer, - - splitDataProductType_maybe, + dataConUnivTyVars, dataConExTyVars, dataConAllTyVars, + dataConEqSpec, eqSpecPreds, dataConTheta, + dataConStupidTheta, + dataConInstArgTys, dataConOrigArgTys, dataConOrigResTy, + dataConInstOrigArgTys, dataConRepArgTys, + dataConFieldLabels, dataConFieldType, + dataConStrictMarks, + dataConSourceArity, dataConRepArity, dataConRepRepArity, + dataConIsInfix, + dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitIds, + dataConRepStrictness, dataConRepBangs, dataConBoxer, + + splitDataProductType_maybe, tyConsOfTyCon, - -- ** Predicates on DataCons - isNullarySrcDataCon, isNullaryRepDataCon, isTupleDataCon, isUnboxedTupleCon, - isVanillaDataCon, classDataCon, dataConCannotMatch, + -- ** Predicates on DataCons + isNullarySrcDataCon, isNullaryRepDataCon, isTupleDataCon, isUnboxedTupleCon, + isVanillaDataCon, classDataCon, dataConCannotMatch, isBanged, isMarkedStrict, eqHsBang, -- ** Promotion related functions @@ -87,30 +81,30 @@ Data constructor representation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration - data T = T !Int ![Int] + data T = T !Int ![Int] Using the strictness annotations, GHC will represent this as - data T = T Int# [Int] + data T = T Int# [Int] That is, the Int has been unboxed. Furthermore, the Haskell source construction - T e1 e2 + T e1 e2 is translated to - case e1 of { I# x -> - case e2 of { r -> - T x r }} + case e1 of { I# x -> + case e2 of { r -> + T x r }} That is, the first argument is unboxed, and the second is evaluated. Finally, pattern matching is translated too: - case e of { T a b -> ... } + case e of { T a b -> ... } becomes - case e of { T a' b -> let a = I# a' in ... } + case e of { T a' b -> let a = I# a' in ... } To keep ourselves sane, we name the different versions of the data constructor differently, as follows. @@ -120,13 +114,13 @@ Note [Data Constructor Naming] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each data constructor C has two, and possibly up to four, Names associated with it: - OccName Name space Name of Notes + OccName Name space Name of Notes --------------------------------------------------------------------------- - The "data con itself" C DataName DataCon In dom( GlobalRdrEnv ) - The "worker data con" C VarName Id The worker - The "wrapper data con" $WC VarName Id The wrapper + The "data con itself" C DataName DataCon In dom( GlobalRdrEnv ) + The "worker data con" C VarName Id The worker + The "wrapper data con" $WC VarName Id The wrapper The "newtype coercion" :CoT TcClsName TyCon - + EVERY data constructor (incl for newtypes) has the former two (the data con itself, and its worker. But only some data constructors have a wrapper (see Note [The need for a wrapper]). @@ -146,272 +140,272 @@ The "worker Id", is the actual data constructor. * For a *data* type, the worker *is* the data constructor; it has no unfolding -* For a *newtype*, the worker has a compulsory unfolding which +* For a *newtype*, the worker has a compulsory unfolding which does a cast, e.g. - newtype T = MkT Int - The worker for MkT has unfolding - \\(x:Int). x `cast` sym CoT + newtype T = MkT Int + The worker for MkT has unfolding + \\(x:Int). x `cast` sym CoT Here CoT is the type constructor, witnessing the FC axiom - axiom CoT : T = Int + axiom CoT : T = Int The "wrapper Id", \$WC, goes as follows -* Its type is exactly what it looks like in the source program. +* Its type is exactly what it looks like in the source program. -* It is an ordinary function, and it gets a top-level binding +* It is an ordinary function, and it gets a top-level binding like any other function. * The wrapper Id isn't generated for a data type if there is nothing for the wrapper to do. That is, if its defn would be - \$wC = C + \$wC = C Note [The need for a wrapper] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Why might the wrapper have anything to do? Two reasons: * Unboxing strict fields (with -funbox-strict-fields) - data T = MkT !(Int,Int) - \$wMkT :: (Int,Int) -> T - \$wMkT (x,y) = MkT x y - Notice that the worker has two fields where the wapper has + data T = MkT !(Int,Int) + \$wMkT :: (Int,Int) -> T + \$wMkT (x,y) = MkT x y + Notice that the worker has two fields where the wapper has just one. That is, the worker has type - MkT :: Int -> Int -> T + MkT :: Int -> Int -> T * Equality constraints for GADTs - data T a where { MkT :: a -> T [a] } + data T a where { MkT :: a -> T [a] } The worker gets a type with explicit equality constraints, thus: - MkT :: forall a b. (a=[b]) => b -> T a + MkT :: forall a b. (a=[b]) => b -> T a The wrapper has the programmer-specified type: - \$wMkT :: a -> T [a] - \$wMkT a x = MkT [a] a [a] x + \$wMkT :: a -> T [a] + \$wMkT a x = MkT [a] a [a] x The third argument is a coerion - [a] :: [a]~[a] + [a] :: [a]~[a] INVARIANT: the dictionary constructor for a class - never has a wrapper. + never has a wrapper. A note about the stupid context ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Data types can have a context: - - data (Eq a, Ord b) => T a b = T1 a b | T2 a + + data (Eq a, Ord b) => T a b = T1 a b | T2 a and that makes the constructors have a context too (notice that T2's context is "thinned"): - T1 :: (Eq a, Ord b) => a -> b -> T a b - T2 :: (Eq a) => a -> T a b + T1 :: (Eq a, Ord b) => a -> b -> T a b + T2 :: (Eq a) => a -> T a b Furthermore, this context pops up when pattern matching (though GHC hasn't implemented this, but it is in H98, and I've fixed GHC so that it now does): - f (T2 x) = x + f (T2 x) = x gets inferred type - f :: Eq a => T a b -> a + f :: Eq a => T a b -> a I say the context is "stupid" because the dictionaries passed are immediately discarded -- they do nothing and have no benefit. It's a flaw in the language. - Up to now [March 2002] I have put this stupid context into the - type of the "wrapper" constructors functions, T1 and T2, but - that turned out to be jolly inconvenient for generics, and - record update, and other functions that build values of type T - (because they don't have suitable dictionaries available). + Up to now [March 2002] I have put this stupid context into the + type of the "wrapper" constructors functions, T1 and T2, but + that turned out to be jolly inconvenient for generics, and + record update, and other functions that build values of type T + (because they don't have suitable dictionaries available). - So now I've taken the stupid context out. I simply deal with - it separately in the type checker on occurrences of a - constructor, either in an expression or in a pattern. + So now I've taken the stupid context out. I simply deal with + it separately in the type checker on occurrences of a + constructor, either in an expression or in a pattern. - [May 2003: actually I think this decision could evasily be - reversed now, and probably should be. Generics could be - disabled for types with a stupid context; record updates now - (H98) needs the context too; etc. It's an unforced change, so - I'm leaving it for now --- but it does seem odd that the - wrapper doesn't include the stupid context.] + [May 2003: actually I think this decision could evasily be + reversed now, and probably should be. Generics could be + disabled for types with a stupid context; record updates now + (H98) needs the context too; etc. It's an unforced change, so + I'm leaving it for now --- but it does seem odd that the + wrapper doesn't include the stupid context.] [July 04] With the advent of generalised data types, it's less obvious what the "stupid context" is. Consider - C :: forall a. Ord a => a -> a -> T (Foo a) + C :: forall a. Ord a => a -> a -> T (Foo a) Does the C constructor in Core contain the Ord dictionary? Yes, it must: - f :: T b -> Ordering - f = /\b. \x:T b. - case x of - C a (d:Ord a) (p:a) (q:a) -> compare d p q + f :: T b -> Ordering + f = /\b. \x:T b. + case x of + C a (d:Ord a) (p:a) (q:a) -> compare d p q Note that (Foo a) might not be an instance of Ord. %************************************************************************ -%* * +%* * \subsection{Data constructors} -%* * +%* * %************************************************************************ \begin{code} -- | A data constructor data DataCon = MkData { - dcName :: Name, -- This is the name of the *source data con* - -- (see "Note [Data Constructor Naming]" above) - dcUnique :: Unique, -- Cached from Name - dcTag :: ConTag, -- ^ Tag, used for ordering 'DataCon's - - -- Running example: - -- - -- *** As declared by the user - -- data T a where - -- MkT :: forall x y. (x~y,Ord x) => x -> y -> T (x,y) - - -- *** As represented internally - -- data T a where - -- MkT :: forall a. forall x y. (a~(x,y),x~y,Ord x) => x -> y -> T a - -- - -- The next six fields express the type of the constructor, in pieces - -- e.g. - -- - -- dcUnivTyVars = [a] - -- dcExTyVars = [x,y] - -- dcEqSpec = [a~(x,y)] - -- dcOtherTheta = [x~y, Ord x] - -- dcOrigArgTys = [x,y] - -- dcRepTyCon = T - - dcVanilla :: Bool, -- True <=> This is a vanilla Haskell 98 data constructor - -- Its type is of form - -- forall a1..an . t1 -> ... tm -> T a1..an - -- No existentials, no coercions, nothing. - -- That is: dcExTyVars = dcEqSpec = dcOtherTheta = [] - -- NB 1: newtypes always have a vanilla data con - -- NB 2: a vanilla constructor can still be declared in GADT-style - -- syntax, provided its type looks like the above. - -- The declaration format is held in the TyCon (algTcGadtSyntax) - - dcUnivTyVars :: [TyVar], -- Universally-quantified type vars [a,b,c] - -- INVARIANT: length matches arity of the dcRepTyCon - --- result type of (rep) data con is exactly (T a b c) - - dcExTyVars :: [TyVar], -- Existentially-quantified type vars - -- In general, the dcUnivTyVars are NOT NECESSARILY THE SAME AS THE TYVARS - -- FOR THE PARENT TyCon. With GADTs the data con might not even have - -- the same number of type variables. - -- [This is a change (Oct05): previously, vanilla datacons guaranteed to - -- have the same type variables as their parent TyCon, but that seems ugly.] - - -- INVARIANT: the UnivTyVars and ExTyVars all have distinct OccNames - -- Reason: less confusing, and easier to generate IfaceSyn - - dcEqSpec :: [(TyVar,Type)], -- Equalities derived from the result type, - -- _as written by the programmer_ - -- This field allows us to move conveniently between the two ways - -- of representing a GADT constructor's type: - -- MkT :: forall a b. (a ~ [b]) => b -> T a - -- MkT :: forall b. b -> T [b] - -- Each equality is of the form (a ~ ty), where 'a' is one of - -- the universally quantified type variables - - -- The next two fields give the type context of the data constructor - -- (aside from the GADT constraints, - -- which are given by the dcExpSpec) - -- In GADT form, this is *exactly* what the programmer writes, even if - -- the context constrains only universally quantified variables - -- MkT :: forall a b. (a ~ b, Ord b) => a -> T a b - dcOtherTheta :: ThetaType, -- The other constraints in the data con's type - -- other than those in the dcEqSpec - - dcStupidTheta :: ThetaType, -- The context of the data type declaration - -- data Eq a => T a = ... - -- or, rather, a "thinned" version thereof - -- "Thinned", because the Report says - -- to eliminate any constraints that don't mention - -- tyvars free in the arg types for this constructor - -- - -- INVARIANT: the free tyvars of dcStupidTheta are a subset of dcUnivTyVars - -- Reason: dcStupidTeta is gotten by thinning the stupid theta from the tycon - -- - -- "Stupid", because the dictionaries aren't used for anything. - -- Indeed, [as of March 02] they are no longer in the type of - -- the wrapper Id, because that makes it harder to use the wrap-id - -- to rebuild values after record selection or in generics. - - dcOrigArgTys :: [Type], -- Original argument types - -- (before unboxing and flattening of strict fields) - dcOrigResTy :: Type, -- Original result type, as seen by the user - -- NB: for a data instance, the original user result type may - -- differ from the DataCon's representation TyCon. Example - -- data instance T [a] where MkT :: a -> T [a] - -- The OrigResTy is T [a], but the dcRepTyCon might be :T123 - - -- Now the strictness annotations and field labels of the constructor + dcName :: Name, -- This is the name of the *source data con* + -- (see "Note [Data Constructor Naming]" above) + dcUnique :: Unique, -- Cached from Name + dcTag :: ConTag, -- ^ Tag, used for ordering 'DataCon's + + -- Running example: + -- + -- *** As declared by the user + -- data T a where + -- MkT :: forall x y. (x~y,Ord x) => x -> y -> T (x,y) + + -- *** As represented internally + -- data T a where + -- MkT :: forall a. forall x y. (a~(x,y),x~y,Ord x) => x -> y -> T a + -- + -- The next six fields express the type of the constructor, in pieces + -- e.g. + -- + -- dcUnivTyVars = [a] + -- dcExTyVars = [x,y] + -- dcEqSpec = [a~(x,y)] + -- dcOtherTheta = [x~y, Ord x] + -- dcOrigArgTys = [x,y] + -- dcRepTyCon = T + + dcVanilla :: Bool, -- True <=> This is a vanilla Haskell 98 data constructor + -- Its type is of form + -- forall a1..an . t1 -> ... tm -> T a1..an + -- No existentials, no coercions, nothing. + -- That is: dcExTyVars = dcEqSpec = dcOtherTheta = [] + -- NB 1: newtypes always have a vanilla data con + -- NB 2: a vanilla constructor can still be declared in GADT-style + -- syntax, provided its type looks like the above. + -- The declaration format is held in the TyCon (algTcGadtSyntax) + + dcUnivTyVars :: [TyVar], -- Universally-quantified type vars [a,b,c] + -- INVARIANT: length matches arity of the dcRepTyCon + --- result type of (rep) data con is exactly (T a b c) + + dcExTyVars :: [TyVar], -- Existentially-quantified type vars + -- In general, the dcUnivTyVars are NOT NECESSARILY THE SAME AS THE TYVARS + -- FOR THE PARENT TyCon. With GADTs the data con might not even have + -- the same number of type variables. + -- [This is a change (Oct05): previously, vanilla datacons guaranteed to + -- have the same type variables as their parent TyCon, but that seems ugly.] + + -- INVARIANT: the UnivTyVars and ExTyVars all have distinct OccNames + -- Reason: less confusing, and easier to generate IfaceSyn + + dcEqSpec :: [(TyVar,Type)], -- Equalities derived from the result type, + -- _as written by the programmer_ + -- This field allows us to move conveniently between the two ways + -- of representing a GADT constructor's type: + -- MkT :: forall a b. (a ~ [b]) => b -> T a + -- MkT :: forall b. b -> T [b] + -- Each equality is of the form (a ~ ty), where 'a' is one of + -- the universally quantified type variables + + -- The next two fields give the type context of the data constructor + -- (aside from the GADT constraints, + -- which are given by the dcExpSpec) + -- In GADT form, this is *exactly* what the programmer writes, even if + -- the context constrains only universally quantified variables + -- MkT :: forall a b. (a ~ b, Ord b) => a -> T a b + dcOtherTheta :: ThetaType, -- The other constraints in the data con's type + -- other than those in the dcEqSpec + + dcStupidTheta :: ThetaType, -- The context of the data type declaration + -- data Eq a => T a = ... + -- or, rather, a "thinned" version thereof + -- "Thinned", because the Report says + -- to eliminate any constraints that don't mention + -- tyvars free in the arg types for this constructor + -- + -- INVARIANT: the free tyvars of dcStupidTheta are a subset of dcUnivTyVars + -- Reason: dcStupidTeta is gotten by thinning the stupid theta from the tycon + -- + -- "Stupid", because the dictionaries aren't used for anything. + -- Indeed, [as of March 02] they are no longer in the type of + -- the wrapper Id, because that makes it harder to use the wrap-id + -- to rebuild values after record selection or in generics. + + dcOrigArgTys :: [Type], -- Original argument types + -- (before unboxing and flattening of strict fields) + dcOrigResTy :: Type, -- Original result type, as seen by the user + -- NB: for a data instance, the original user result type may + -- differ from the DataCon's representation TyCon. Example + -- data instance T [a] where MkT :: a -> T [a] + -- The OrigResTy is T [a], but the dcRepTyCon might be :T123 + + -- Now the strictness annotations and field labels of the constructor -- See Note [Bangs on data constructor arguments] - dcArgBangs :: [HsBang], - -- Strictness annotations as decided by the compiler. - -- Matches 1-1 with dcOrigArgTys - -- Hence length = dataConSourceArity dataCon - - dcFields :: [FieldLabel], - -- Field labels for this constructor, in the - -- same order as the dcOrigArgTys; - -- length = 0 (if not a record) or dataConSourceArity. - - -- The curried worker function that corresponds to the constructor: - -- It doesn't have an unfolding; the code generator saturates these Ids - -- and allocates a real constructor when it finds one. - dcWorkId :: Id, - - -- Constructor representation + dcArgBangs :: [HsBang], + -- Strictness annotations as decided by the compiler. + -- Matches 1-1 with dcOrigArgTys + -- Hence length = dataConSourceArity dataCon + + dcFields :: [FieldLabel], + -- Field labels for this constructor, in the + -- same order as the dcOrigArgTys; + -- length = 0 (if not a record) or dataConSourceArity. + + -- The curried worker function that corresponds to the constructor: + -- It doesn't have an unfolding; the code generator saturates these Ids + -- and allocates a real constructor when it finds one. + dcWorkId :: Id, + + -- Constructor representation dcRep :: DataConRep, -- Cached dcRepArity :: Arity, -- == length dataConRepArgTys dcSourceArity :: Arity, -- == length dcOrigArgTys - -- Result type of constructor is T t1..tn - dcRepTyCon :: TyCon, -- Result tycon, T + -- Result type of constructor is T t1..tn + dcRepTyCon :: TyCon, -- Result tycon, T - dcRepType :: Type, -- Type of the constructor - -- forall a x y. (a~(x,y), x~y, Ord x) => + dcRepType :: Type, -- Type of the constructor + -- forall a x y. (a~(x,y), x~y, Ord x) => -- x -> y -> T a - -- (this is *not* of the constructor wrapper Id: - -- see Note [Data con representation] below) - -- Notice that the existential type parameters come *second*. - -- Reason: in a case expression we may find: - -- case (e :: T t) of + -- (this is *not* of the constructor wrapper Id: + -- see Note [Data con representation] below) + -- Notice that the existential type parameters come *second*. + -- Reason: in a case expression we may find: + -- case (e :: T t) of -- MkT x y co1 co2 (d:Ord x) (v:r) (w:F s) -> ... - -- It's convenient to apply the rep-type of MkT to 't', to get - -- forall x y. (t~(x,y), x~y, Ord x) => x -> y -> T t - -- and use that to check the pattern. Mind you, this is really only - -- used in CoreLint. + -- It's convenient to apply the rep-type of MkT to 't', to get + -- forall x y. (t~(x,y), x~y, Ord x) => x -> y -> T t + -- and use that to check the pattern. Mind you, this is really only + -- used in CoreLint. - dcInfix :: Bool, -- True <=> declared infix - -- Used for Template Haskell and 'deriving' only - -- The actual fixity is stored elsewhere + dcInfix :: Bool, -- True <=> declared infix + -- Used for Template Haskell and 'deriving' only + -- The actual fixity is stored elsewhere dcPromoted :: Maybe TyCon -- The promoted TyCon if this DataCon is promotable -- See Note [Promoted data constructors] in TyCon } deriving Data.Typeable.Typeable -data DataConRep +data DataConRep = NoDataConRep -- No wrapper - | DCR { dcr_wrap_id :: Id -- Takes src args, unboxes/flattens, + | DCR { dcr_wrap_id :: Id -- Takes src args, unboxes/flattens, -- and constructs the representation , dcr_boxer :: DataConBoxer - , dcr_arg_tys :: [Type] -- Final, representation argument types, + , dcr_arg_tys :: [Type] -- Final, representation argument types, -- after unboxing and flattening, -- and *including* all evidence args , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] in MkId.lhs + -- See also Note [Data-con worker strictness] in MkId.lhs , dcr_bangs :: [HsBang] -- The actual decisions made (including failures) -- 1-1 with orig_arg_tys @@ -420,7 +414,7 @@ data DataConRep } -- Algebraic data types always have a worker, and -- may or may not have a wrapper, depending on whether --- the wrapper does anything. +-- the wrapper does anything. -- -- Data types have a worker with no unfolding -- Newtypes just have a worker, which has a compulsory unfolding (just a cast) @@ -436,7 +430,7 @@ data DataConRep -- but it also ensures that the wrapper is replaced -- by the worker (because it *is* the worker) -- even when there are no args. E.g. in --- f (:) x +-- f (:) x -- the (:) *is* the worker. -- This is really important in rule matching, -- (We could match on the wrappers, @@ -446,14 +440,14 @@ data DataConRep ------------------------- -- HsBang describes what the *programmer* wrote -- This info is retained in the DataCon.dcStrictMarks field -data HsBang +data HsBang = HsUserBang -- The user's source-code request (Maybe Bool) -- Just True {-# UNPACK #-} -- Just False {-# NOUNPACK #-} -- Nothing no pragma Bool -- True <=> '!' specified - | HsNoBang -- Lazy field + | HsNoBang -- Lazy field -- HsUserBang Nothing False means the same as HsNoBang | HsUnpack -- Definite commitment: this field is strict and unboxed @@ -463,9 +457,9 @@ data HsBang deriving (Data.Data, Data.Typeable) ------------------------- --- StrictnessMark is internal only, used to indicate strictness +-- StrictnessMark is internal only, used to indicate strictness -- of the DataCon *worker* fields -data StrictnessMark = MarkedStrict | NotMarkedStrict +data StrictnessMark = MarkedStrict | NotMarkedStrict \end{code} Note [Data con representation] @@ -473,17 +467,17 @@ Note [Data con representation] The dcRepType field contains the type of the representation of a contructor This may differ from the type of the contructor *Id* (built by MkId.mkDataConId) for two reasons: - a) the constructor Id may be overloaded, but the dictionary isn't stored - e.g. data Eq a => T a = MkT a a + a) the constructor Id may be overloaded, but the dictionary isn't stored + e.g. data Eq a => T a = MkT a a - b) the constructor may store an unboxed version of a strict field. + b) the constructor may store an unboxed version of a strict field. Here's an example illustrating both: - data Ord a => T a = MkT Int! a + data Ord a => T a = MkT Int! a Here - T :: Ord a => Int -> a -> T a + T :: Ord a => Int -> a -> T a but the rep type is - Trep :: Int# -> a -> T a + Trep :: Int# -> a -> T a Actually, the unboxed part isn't implemented yet! Note [Bangs on data constructor arguments] @@ -509,9 +503,9 @@ dcr_bangs field; we don't know what the user originally said. %************************************************************************ -%* * +%* * \subsection{Instances} -%* * +%* * %************************************************************************ \begin{code} @@ -521,9 +515,9 @@ instance Eq DataCon where instance Ord DataCon where a <= b = getUnique a <= getUnique b - a < b = getUnique a < getUnique b + a < b = getUnique a < getUnique b a >= b = getUnique a >= getUnique b - a > b = getUnique a > getUnique b + a > b = getUnique a > getUnique b compare a b = getUnique a `compare` getUnique b instance Uniquable DataCon where @@ -582,42 +576,42 @@ isMarkedStrict _ = True -- All others are strict %************************************************************************ -%* * +%* * \subsection{Construction} -%* * +%* * %************************************************************************ \begin{code} -- | Build a new data constructor -mkDataCon :: Name - -> Bool -- ^ Is the constructor declared infix? - -> [HsBang] -- ^ Strictness annotations written in the source file - -> [FieldLabel] -- ^ Field labels for the constructor, if it is a record, - -- otherwise empty - -> [TyVar] -- ^ Universally quantified type variables - -> [TyVar] -- ^ Existentially quantified type variables - -> [(TyVar,Type)] -- ^ GADT equalities - -> ThetaType -- ^ Theta-type occuring before the arguments proper - -> [Type] -- ^ Original argument types - -> Type -- ^ Original result type - -> TyCon -- ^ Representation type constructor - -> ThetaType -- ^ The "stupid theta", context of the data declaration - -- e.g. @data Eq a => T a ...@ +mkDataCon :: Name + -> Bool -- ^ Is the constructor declared infix? + -> [HsBang] -- ^ Strictness annotations written in the source file + -> [FieldLabel] -- ^ Field labels for the constructor, if it is a record, + -- otherwise empty + -> [TyVar] -- ^ Universally quantified type variables + -> [TyVar] -- ^ Existentially quantified type variables + -> [(TyVar,Type)] -- ^ GADT equalities + -> ThetaType -- ^ Theta-type occuring before the arguments proper + -> [Type] -- ^ Original argument types + -> Type -- ^ Original result type + -> TyCon -- ^ Representation type constructor + -> ThetaType -- ^ The "stupid theta", context of the data declaration + -- e.g. @data Eq a => T a ...@ -> Id -- ^ Worker Id - -> DataConRep -- ^ Representation - -> DataCon + -> DataConRep -- ^ Representation + -> DataCon -- Can get the tag from the TyCon mkDataCon name declared_infix - arg_stricts -- Must match orig_arg_tys 1-1 - fields - univ_tvs ex_tvs - eq_spec theta - orig_arg_tys orig_res_ty rep_tycon - stupid_theta work_id rep --- Warning: mkDataCon is not a good place to check invariants. + arg_stricts -- Must match orig_arg_tys 1-1 + fields + univ_tvs ex_tvs + eq_spec theta + orig_arg_tys orig_res_ty rep_tycon + stupid_theta work_id rep +-- Warning: mkDataCon is not a good place to check invariants. -- If the programmer writes the wrong result type in the decl, thus: --- data T a where { MkT :: S } +-- data T a where { MkT :: S } -- then it's possible that the univ_tvs may hit an assertion failure -- if you pull on univ_tvs. This case is checked by checkValidDataCon, -- so the error is detected properly... it's just that asaertions here @@ -626,39 +620,39 @@ mkDataCon name declared_infix = con where is_vanilla = null ex_tvs && null eq_spec && null theta - con = MkData {dcName = name, dcUnique = nameUnique name, - dcVanilla = is_vanilla, dcInfix = declared_infix, - dcUnivTyVars = univ_tvs, dcExTyVars = ex_tvs, - dcEqSpec = eq_spec, - dcOtherTheta = theta, - dcStupidTheta = stupid_theta, - dcOrigArgTys = orig_arg_tys, dcOrigResTy = orig_res_ty, - dcRepTyCon = rep_tycon, - dcArgBangs = arg_stricts, - dcFields = fields, dcTag = tag, dcRepType = rep_ty, - dcWorkId = work_id, - dcRep = rep, + con = MkData {dcName = name, dcUnique = nameUnique name, + dcVanilla = is_vanilla, dcInfix = declared_infix, + dcUnivTyVars = univ_tvs, dcExTyVars = ex_tvs, + dcEqSpec = eq_spec, + dcOtherTheta = theta, + dcStupidTheta = stupid_theta, + dcOrigArgTys = orig_arg_tys, dcOrigResTy = orig_res_ty, + dcRepTyCon = rep_tycon, + dcArgBangs = arg_stricts, + dcFields = fields, dcTag = tag, dcRepType = rep_ty, + dcWorkId = work_id, + dcRep = rep, dcSourceArity = length orig_arg_tys, dcRepArity = length rep_arg_tys, dcPromoted = mb_promoted } - -- The 'arg_stricts' passed to mkDataCon are simply those for the - -- source-language arguments. We add extra ones for the - -- dictionary arguments right here. + -- The 'arg_stricts' passed to mkDataCon are simply those for the + -- source-language arguments. We add extra ones for the + -- dictionary arguments right here. tag = assoc "mkDataCon" (tyConDataCons rep_tycon `zip` [fIRST_TAG..]) con rep_arg_tys = dataConRepArgTys con - rep_ty = mkForAllTys univ_tvs $ mkForAllTys ex_tvs $ - mkFunTys rep_arg_tys $ - mkTyConApp rep_tycon (mkTyVarTys univ_tvs) + rep_ty = mkForAllTys univ_tvs $ mkForAllTys ex_tvs $ + mkFunTys rep_arg_tys $ + mkTyConApp rep_tycon (mkTyVarTys univ_tvs) mb_promoted -- See Note [Promoted data constructors] in TyCon | isJust (promotableTyCon_maybe rep_tycon) -- The TyCon is promotable only if all its datacons -- are, so the promoteType for prom_kind should succeed = Just (mkPromotedDataCon con name (getUnique name) prom_kind roles) - | otherwise - = Nothing + | otherwise + = Nothing prom_kind = promoteType (dataConUserType con) roles = map (const Nominal) (univ_tvs ++ ex_tvs) ++ map (const Representational) orig_arg_tys @@ -693,7 +687,7 @@ dataConTyCon = dcRepTyCon -- constructor. In case of a data family instance, that will be the family -- type constructor. dataConOrigTyCon :: DataCon -> TyCon -dataConOrigTyCon dc +dataConOrigTyCon dc | Just (tc, _) <- tyConFamInst_maybe (dcRepTyCon dc) = tc | otherwise = dcRepTyCon dc @@ -726,7 +720,7 @@ dataConEqSpec = dcEqSpec -- | The *full* constraints on the constructor type dataConTheta :: DataCon -> ThetaType -dataConTheta (MkData { dcEqSpec = eq_spec, dcOtherTheta = theta }) +dataConTheta (MkData { dcEqSpec = eq_spec, dcOtherTheta = theta }) = eqSpecPreds eq_spec ++ theta -- | Get the Id of the 'DataCon' worker: a function that is the "actual" @@ -738,7 +732,7 @@ dataConWorkId dc = dcWorkId dc -- | Get the Id of the 'DataCon' wrapper: a function that wraps the "actual" -- constructor so it has the type visible in the source program: c.f. 'dataConWorkId'. --- Returns Nothing if there is no wrapper, which occurs for an algebraic data constructor +-- Returns Nothing if there is no wrapper, which occurs for an algebraic data constructor -- and also for a newtype (whose constructor is inlined compulsorily) dataConWrapId_maybe :: DataCon -> Maybe Id dataConWrapId_maybe dc = case dcRep dc of @@ -781,7 +775,7 @@ dataConStrictMarks = dcArgBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the +-- | Gives the number of actual fields in the /representation/ of the -- data constructor. This may be more than appear in the source code; -- the extra ones are the existentially quantified dictionaries dataConRepArity :: DataCon -> Arity @@ -815,7 +809,7 @@ dataConRepBangs dc = case dcRep dc of dataConBoxer :: DataCon -> Maybe DataConBoxer dataConBoxer (MkData { dcRep = DCR { dcr_boxer = boxer } }) = Just boxer -dataConBoxer _ = Nothing +dataConBoxer _ = Nothing -- | The \"signature\" of the 'DataCon' returns, in order: -- @@ -828,9 +822,9 @@ dataConBoxer _ = Nothing -- -- 4) The /original/ result type of the 'DataCon' dataConSig :: DataCon -> ([TyVar], ThetaType, [Type], Type) -dataConSig (MkData {dcUnivTyVars = univ_tvs, dcExTyVars = ex_tvs, - dcEqSpec = eq_spec, dcOtherTheta = theta, - dcOrigArgTys = arg_tys, dcOrigResTy = res_ty}) +dataConSig (MkData {dcUnivTyVars = univ_tvs, dcExTyVars = ex_tvs, + dcEqSpec = eq_spec, dcOtherTheta = theta, + dcOrigArgTys = arg_tys, dcOrigResTy = res_ty}) = (univ_tvs ++ ex_tvs, eqSpecPreds eq_spec ++ theta, arg_tys, res_ty) -- | The \"full signature\" of the 'DataCon' returns, in order: @@ -843,15 +837,15 @@ dataConSig (MkData {dcUnivTyVars = univ_tvs, dcExTyVars = ex_tvs, -- -- 4) The result of 'dataConDictTheta' -- --- 5) The original argument types to the 'DataCon' (i.e. before +-- 5) The original argument types to the 'DataCon' (i.e. before -- any change of the representation of the type) -- -- 6) The original result type of the 'DataCon' -dataConFullSig :: DataCon - -> ([TyVar], [TyVar], [(TyVar,Type)], ThetaType, [Type], Type) -dataConFullSig (MkData {dcUnivTyVars = univ_tvs, dcExTyVars = ex_tvs, - dcEqSpec = eq_spec, dcOtherTheta = theta, - dcOrigArgTys = arg_tys, dcOrigResTy = res_ty}) +dataConFullSig :: DataCon + -> ([TyVar], [TyVar], [(TyVar,Type)], ThetaType, [Type], Type) +dataConFullSig (MkData {dcUnivTyVars = univ_tvs, dcExTyVars = ex_tvs, + dcEqSpec = eq_spec, dcOtherTheta = theta, + dcOrigArgTys = arg_tys, dcOrigResTy = res_ty}) = (univ_tvs, ex_tvs, eq_spec, theta, arg_tys, res_ty) dataConOrigResTy :: DataCon -> Type @@ -875,10 +869,10 @@ dataConUserType :: DataCon -> Type -- -- NB: If the constructor is part of a data instance, the result type -- mentions the family tycon, not the internal one. -dataConUserType (MkData { dcUnivTyVars = univ_tvs, - dcExTyVars = ex_tvs, dcEqSpec = eq_spec, - dcOtherTheta = theta, dcOrigArgTys = arg_tys, - dcOrigResTy = res_ty }) +dataConUserType (MkData { dcUnivTyVars = univ_tvs, + dcExTyVars = ex_tvs, dcEqSpec = eq_spec, + dcOtherTheta = theta, dcOrigArgTys = arg_tys, + dcOrigResTy = res_ty }) = mkForAllTys ((univ_tvs `minusList` map fst eq_spec) ++ ex_tvs) $ mkFunTys theta $ mkFunTys arg_tys $ @@ -888,13 +882,13 @@ dataConUserType (MkData { dcUnivTyVars = univ_tvs, -- NB: these INCLUDE any dictionary args -- but EXCLUDE the data-declaration context, which is discarded -- It's all post-flattening etc; this is a representation type -dataConInstArgTys :: DataCon -- ^ A datacon with no existentials or equality constraints - -- However, it can have a dcTheta (notably it can be a - -- class dictionary, with superclasses) - -> [Type] -- ^ Instantiated at these types - -> [Type] +dataConInstArgTys :: DataCon -- ^ A datacon with no existentials or equality constraints + -- However, it can have a dcTheta (notably it can be a + -- class dictionary, with superclasses) + -> [Type] -- ^ Instantiated at these types + -> [Type] dataConInstArgTys dc@(MkData {dcUnivTyVars = univ_tvs, dcEqSpec = eq_spec, - dcExTyVars = ex_tvs}) inst_tys + dcExTyVars = ex_tvs}) inst_tys = ASSERT2( length univ_tvs == length inst_tys , ptext (sLit "dataConInstArgTys") <+> ppr dc $$ ppr univ_tvs $$ ppr inst_tys) ASSERT2( null ex_tvs && null eq_spec, ppr dc ) @@ -902,16 +896,16 @@ dataConInstArgTys dc@(MkData {dcUnivTyVars = univ_tvs, dcEqSpec = eq_spec, -- | Returns just the instantiated /value/ argument types of a 'DataCon', -- (excluding dictionary args) -dataConInstOrigArgTys - :: DataCon -- Works for any DataCon - -> [Type] -- Includes existential tyvar args, but NOT - -- equality constraints or dicts - -> [Type] +dataConInstOrigArgTys + :: DataCon -- Works for any DataCon + -> [Type] -- Includes existential tyvar args, but NOT + -- equality constraints or dicts + -> [Type] -- For vanilla datacons, it's all quite straightforward -- But for the call in MatchCon, we really do want just the value args dataConInstOrigArgTys dc@(MkData {dcOrigArgTys = arg_tys, - dcUnivTyVars = univ_tvs, - dcExTyVars = ex_tvs}) inst_tys + dcUnivTyVars = univ_tvs, + dcExTyVars = ex_tvs}) inst_tys = ASSERT2( length tyvars == length inst_tys , ptext (sLit "dataConInstOrigArgTys") <+> ppr dc $$ ppr tyvars $$ ppr inst_tys ) map (substTyWith tyvars inst_tys) arg_tys @@ -925,13 +919,13 @@ dataConInstOrigArgTys dc@(MkData {dcOrigArgTys = arg_tys, dataConOrigArgTys :: DataCon -> [Type] dataConOrigArgTys dc = dcOrigArgTys dc --- | Returns the arg types of the worker, including *all* evidence, after any +-- | Returns the arg types of the worker, including *all* evidence, after any -- flattening has been done and without substituting for any type variables dataConRepArgTys :: DataCon -> [Type] -dataConRepArgTys (MkData { dcRep = rep +dataConRepArgTys (MkData { dcRep = rep , dcEqSpec = eq_spec , dcOtherTheta = theta - , dcOrigArgTys = orig_arg_tys }) + , dcOrigArgTys = orig_arg_tys }) = case rep of NoDataConRep -> ASSERT( null eq_spec ) theta ++ orig_arg_tys DCR { dcr_arg_tys = arg_tys } -> arg_tys @@ -952,7 +946,7 @@ dataConIdentity dc = bytesFS (packageKeyFS (modulePackageKey mod)) ++ \begin{code} isTupleDataCon :: DataCon -> Bool isTupleDataCon (MkData {dcRepTyCon = tc}) = isTupleTyCon tc - + isUnboxedTupleCon :: DataCon -> Bool isUnboxedTupleCon (MkData {dcRepTyCon = tc}) = isUnboxedTupleTyCon tc @@ -964,27 +958,27 @@ isVanillaDataCon dc = dcVanilla dc \begin{code} classDataCon :: Class -> DataCon classDataCon clas = case tyConDataCons (classTyCon clas) of - (dict_constr:no_more) -> ASSERT( null no_more ) dict_constr - [] -> panic "classDataCon" + (dict_constr:no_more) -> ASSERT( null no_more ) dict_constr + [] -> panic "classDataCon" \end{code} \begin{code} dataConCannotMatch :: [Type] -> DataCon -> Bool --- Returns True iff the data con *definitely cannot* match a --- scrutinee of type (T tys) --- where T is the dcRepTyCon for the data con +-- Returns True iff the data con *definitely cannot* match a +-- scrutinee of type (T tys) +-- where T is the dcRepTyCon for the data con -- NB: look at *all* equality constraints, not only those -- in dataConEqSpec; see Trac #5168 dataConCannotMatch tys con - | null theta = False -- Common - | all isTyVarTy tys = False -- Also common + | null theta = False -- Common + | all isTyVarTy tys = False -- Also common | otherwise = typesCantMatch [(Type.substTy subst ty1, Type.substTy subst ty2) | (ty1, ty2) <- concatMap predEqs theta ] where dc_tvs = dataConUnivTyVars con theta = dataConTheta con - subst = ASSERT2( length dc_tvs == length tys, ppr con $$ ppr dc_tvs $$ ppr tys ) + subst = ASSERT2( length dc_tvs == length tys, ppr con $$ ppr dc_tvs $$ ppr tys ) zipTopTvSubst dc_tvs tys -- TODO: could gather equalities from superclasses too @@ -995,36 +989,36 @@ dataConCannotMatch tys con \end{code} %************************************************************************ -%* * +%* * Building an algebraic data type -%* * +%* * %************************************************************************ buildAlgTyCon is here because it is called from TysWiredIn, which in turn depends on DataCon, but not on BuildTyCl. \begin{code} -buildAlgTyCon :: Name +buildAlgTyCon :: Name -> [TyVar] -- ^ Kind variables and type variables -> [Role] - -> Maybe CType - -> ThetaType -- ^ Stupid theta - -> AlgTyConRhs - -> RecFlag - -> Bool -- ^ True <=> this TyCon is promotable - -> Bool -- ^ True <=> was declared in GADT syntax + -> Maybe CType + -> ThetaType -- ^ Stupid theta + -> AlgTyConRhs + -> RecFlag + -> Bool -- ^ True <=> this TyCon is promotable + -> Bool -- ^ True <=> was declared in GADT syntax -> TyConParent - -> TyCon + -> TyCon -buildAlgTyCon tc_name ktvs roles cType stupid_theta rhs +buildAlgTyCon tc_name ktvs roles cType stupid_theta rhs is_rec is_promotable gadt_syn parent = tc - where + where kind = mkPiKinds ktvs liftedTypeKind -- tc and mb_promoted_tc are mutually recursive - tc = mkAlgTyCon tc_name kind ktvs roles cType stupid_theta - rhs parent is_rec gadt_syn + tc = mkAlgTyCon tc_name kind ktvs roles cType stupid_theta + rhs parent is_rec gadt_syn mb_promoted_tc mb_promoted_tc @@ -1066,11 +1060,11 @@ The transformation from type to kind is done by promoteType * Ensure all foralls are at the top (no higher rank stuff) * Ensure that all type constructors mentioned (Maybe and T - in the example) are promotable; that is, they have kind + in the example) are promotable; that is, they have kind * -> ... -> * -> * \begin{code} --- | Promotes a type to a kind. +-- | Promotes a type to a kind. -- Assumes the argument satisfies 'isPromotableType' promoteType :: Type -> Kind promoteType ty @@ -1083,23 +1077,23 @@ promoteType ty go (TyConApp tc tys) | Just prom_tc <- promotableTyCon_maybe tc = mkTyConApp prom_tc (map go tys) go (FunTy arg res) = mkArrowKind (go arg) (go res) - go (TyVarTy tv) | Just kv <- lookupVarEnv env tv + go (TyVarTy tv) | Just kv <- lookupVarEnv env tv = TyVarTy kv go _ = panic "promoteType" -- Argument did not satisfy isPromotableType promoteKind :: Kind -> SuperKind -- Promote the kind of a type constructor --- from (* -> * -> *) to (BOX -> BOX -> BOX) -promoteKind (TyConApp tc []) +-- from (* -> * -> *) to (BOX -> BOX -> BOX) +promoteKind (TyConApp tc []) | tc `hasKey` liftedTypeKindTyConKey = superKind promoteKind (FunTy arg res) = FunTy (promoteKind arg) (promoteKind res) promoteKind k = pprPanic "promoteKind" (ppr k) \end{code} %************************************************************************ -%* * +%* * \subsection{Splitting products} -%* * +%* * %************************************************************************ \begin{code} @@ -1116,15 +1110,15 @@ promoteKind k = pprPanic "promoteKind" (ppr k) -- -- Whether the type is a @data@ type or a @newtype@ splitDataProductType_maybe - :: Type -- ^ A product type, perhaps - -> Maybe (TyCon, -- The type constructor - [Type], -- Type args of the tycon - DataCon, -- The data constructor - [Type]) -- Its /representation/ arg types - - -- Rejecing existentials is conservative. Maybe some things - -- could be made to work with them, but I'm not going to sweat - -- it through till someone finds it's important. + :: Type -- ^ A product type, perhaps + -> Maybe (TyCon, -- The type constructor + [Type], -- Type args of the tycon + DataCon, -- The data constructor + [Type]) -- Its /representation/ arg types + + -- Rejecting existentials is conservative. Maybe some things + -- could be made to work with them, but I'm not going to sweat + -- it through till someone finds it's important. splitDataProductType_maybe ty | Just (tycon, ty_args) <- splitTyConApp_maybe ty |