This module contains definitions for the IdInfo for things that
have a standard form, namely:
This module contains definitions for the IdInfo for things that
have a standard form, namely:
-- The above warning supression flag is a temporary kludge.
-- While working on this module you are encouraged to remove it and fix
-- any warnings in the module. See
-- The above warning supression flag is a temporary kludge.
-- While working on this module you are encouraged to remove it and fix
-- any warnings in the module. See
- mkDataConIds,
- mkRecordSelId,
- mkPrimOpId, mkFCallId, mkTickBoxOpId, mkBreakPointOpId,
+ mkDataConIds,
+ mkRecordSelId,
+ mkPrimOpId, mkFCallId, mkTickBoxOpId, mkBreakPointOpId,
- mkReboxingAlt, wrapNewTypeBody, unwrapNewTypeBody,
+ mkReboxingAlt, wrapNewTypeBody, unwrapNewTypeBody,
wrapFamInstBody, unwrapFamInstScrut,
mkUnpackCase, mkProductBox,
wrapFamInstBody, unwrapFamInstScrut,
mkUnpackCase, mkProductBox,
- -- And some particular Ids; see below for why they are wired in
- wiredInIds, ghcPrimIds,
- unsafeCoerceId, realWorldPrimId, voidArgId, nullAddrId, seqId,
- lazyId, lazyIdUnfolding, lazyIdKey,
+ -- And some particular Ids; see below for why they are wired in
+ wiredInIds, ghcPrimIds,
+ unsafeCoerceId, realWorldPrimId, voidArgId, nullAddrId, seqId,
+ lazyId, lazyIdUnfolding, lazyIdKey,
- mkRuntimeErrorApp,
- rEC_CON_ERROR_ID, iRREFUT_PAT_ERROR_ID, rUNTIME_ERROR_ID,
- nON_EXHAUSTIVE_GUARDS_ERROR_ID, nO_METHOD_BINDING_ERROR_ID,
- pAT_ERROR_ID, eRROR_ID,
+ mkRuntimeErrorApp,
+ rEC_CON_ERROR_ID, iRREFUT_PAT_ERROR_ID, rUNTIME_ERROR_ID,
+ nON_EXHAUSTIVE_GUARDS_ERROR_ID, nO_METHOD_BINDING_ERROR_ID,
+ pAT_ERROR_ID, eRROR_ID,
- = [ -- These error-y things are wired in because we don't yet have
- -- a way to express in an interface file that the result type variable
- -- is 'open'; that is can be unified with an unboxed type
- --
- -- [The interface file format now carry such information, but there's
- -- no way yet of expressing at the definition site for these
- -- error-reporting functions that they have an 'open'
- -- result type. -- sof 1/99]
-
- eRROR_ID, -- This one isn't used anywhere else in the compiler
- -- But we still need it in wiredInIds so that when GHC
- -- compiles a program that mentions 'error' we don't
- -- import its type from the interface file; we just get
- -- the Id defined here. Which has an 'open-tyvar' type.
+ = [ -- These error-y things are wired in because we don't yet have
+ -- a way to express in an interface file that the result type variable
+ -- is 'open'; that is can be unified with an unboxed type
+ --
+ -- [The interface file format now carry such information, but there's
+ -- no way yet of expressing at the definition site for these
+ -- error-reporting functions that they have an 'open'
+ -- result type. -- sof 1/99]
+
+ eRROR_ID, -- This one isn't used anywhere else in the compiler
+ -- But we still need it in wiredInIds so that when GHC
+ -- compiles a program that mentions 'error' we don't
+ -- import its type from the interface file; we just get
+ -- the Id defined here. Which has an 'open-tyvar' type.
- = [ -- These can't be defined in Haskell, but they have
- -- perfectly reasonable unfoldings in Core
+ = [ -- These can't be defined in Haskell, but they have
+ -- perfectly reasonable unfoldings in Core
%************************************************************************
The wrapper for a constructor is an ordinary top-level binding that evaluates
%************************************************************************
The wrapper for a constructor is an ordinary top-level binding that evaluates
- T1 = /\ a b ->
- \d1::Data a, d2::C b ->
- \p q r -> case p of { p ->
- case q of { q ->
- Con T1 [a,b] [p,q,r]}}
+ T1 = /\ a b ->
+ \d1::Data a, d2::C b ->
+ \p q r -> case p of { p ->
+ case q of { q ->
+ Con T1 [a,b] [p,q,r]}}
$WMapPair :: forall a b v. Map a (Map a b v) -> Map (a, b) v
$WMapPair a b v = MapPair a b v `cast` sym (Co123Map a b v)
$WMapPair :: forall a b v. Map a (Map a b v) -> Map (a, b) v
$WMapPair a b v = MapPair a b v `cast` sym (Co123Map a b v)
MapPair :: forall a b v. Map a (Map a b v) -> :R123Map a b v
This coercion is conditionally applied by wrapFamInstBody.
MapPair :: forall a b v. Map a (Map a b v) -> :R123Map a b v
This coercion is conditionally applied by wrapFamInstBody.
T1 :: forall c b. (c ~ Maybe b) => b -> :R7T c
\begin{code}
mkDataConIds :: Name -> Name -> DataCon -> DataConIds
mkDataConIds wrap_name wkr_name data_con
T1 :: forall c b. (c ~ Maybe b) => b -> :R7T c
\begin{code}
mkDataConIds :: Name -> Name -> DataCon -> DataConIds
mkDataConIds wrap_name wkr_name data_con
- | any isMarkedStrict all_strict_marks -- Algebraic, needs wrapper
- || not (null eq_spec) -- NB: LoadIface.ifaceDeclSubBndrs
- || isFamInstTyCon tycon -- depends on this test
+ | any isMarkedStrict all_strict_marks -- Algebraic, needs wrapper
+ || not (null eq_spec) -- NB: LoadIface.ifaceDeclSubBndrs
+ || isFamInstTyCon tycon -- depends on this test
= DCIds Nothing wrk_id
where
(univ_tvs, ex_tvs, eq_spec,
eq_theta, dict_theta, orig_arg_tys, res_ty) = dataConFullSig data_con
= DCIds Nothing wrk_id
where
(univ_tvs, ex_tvs, eq_spec,
eq_theta, dict_theta, orig_arg_tys, res_ty) = dataConFullSig data_con
- ----------- Worker (algebraic data types only) --------------
- -- The *worker* for the data constructor is the function that
- -- takes the representation arguments and builds the constructor.
+ ----------- Worker (algebraic data types only) --------------
+ -- The *worker* for the data constructor is the function that
+ -- takes the representation arguments and builds the constructor.
- `setArityInfo` wkr_arity
- `setAllStrictnessInfo` Just wkr_sig
- `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated,
- -- even if arity = 0
+ `setArityInfo` wkr_arity
+ `setAllStrictnessInfo` Just wkr_sig
+ `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated,
+ -- even if arity = 0
- -- Note [Data-con worker strictness]
- -- Notice that we do *not* say the worker is strict
- -- even if the data constructor is declared strict
- -- e.g. data T = MkT !(Int,Int)
- -- Why? Because the *wrapper* is strict (and its unfolding has case
- -- expresssions that do the evals) but the *worker* itself is not.
- -- If we pretend it is strict then when we see
- -- case x of y -> $wMkT y
- -- the simplifier thinks that y is "sure to be evaluated" (because
- -- $wMkT is strict) and drops the case. No, $wMkT is not strict.
- --
- -- When the simplifer sees a pattern
- -- case e of MkT x -> ...
- -- it uses the dataConRepStrictness of MkT to mark x as evaluated;
- -- but that's fine... dataConRepStrictness comes from the data con
- -- not from the worker Id.
+ -- Note [Data-con worker strictness]
+ -- Notice that we do *not* say the worker is strict
+ -- even if the data constructor is declared strict
+ -- e.g. data T = MkT !(Int,Int)
+ -- Why? Because the *wrapper* is strict (and its unfolding has case
+ -- expresssions that do the evals) but the *worker* itself is not.
+ -- If we pretend it is strict then when we see
+ -- case x of y -> $wMkT y
+ -- the simplifier thinks that y is "sure to be evaluated" (because
+ -- $wMkT is strict) and drops the case. No, $wMkT is not strict.
+ --
+ -- When the simplifer sees a pattern
+ -- case e of MkT x -> ...
+ -- it uses the dataConRepStrictness of MkT to mark x as evaluated;
+ -- but that's fine... dataConRepStrictness comes from the data con
+ -- not from the worker Id.
- isDataTyCon tycon &&
- wkr_arity > 0 &&
- wkr_arity <= mAX_CPR_SIZE = retCPR
- | otherwise = TopRes
- -- RetCPR is only true for products that are real data types;
- -- that is, not unboxed tuples or [non-recursive] newtypes
-
- ----------- Workers for newtypes --------------
+ isDataTyCon tycon &&
+ wkr_arity > 0 &&
+ wkr_arity <= mAX_CPR_SIZE = retCPR
+ | otherwise = TopRes
+ -- RetCPR is only true for products that are real data types;
+ -- that is, not unboxed tuples or [non-recursive] newtypes
+
+ ----------- Workers for newtypes --------------
- nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo
- `setArityInfo` 1 -- Arity 1
- `setUnfoldingInfo` newtype_unf
+ nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo
+ `setArityInfo` 1 -- Arity 1
+ `setUnfoldingInfo` newtype_unf
- -- there may be a dict theta rather than a singleton orig_arg_ty
- -- ASSERT( isVanillaDataCon data_con &&
- -- isSingleton orig_arg_tys )
- --
- -- No existentials on a newtype, but it can have a context
- -- e.g. newtype Eq a => T a = MkT (...)
- mkCompulsoryUnfolding $
- mkLams wrap_tvs $ Lam id_arg1 $
- wrapNewTypeBody tycon res_ty_args
+ -- there may be a dict theta rather than a singleton orig_arg_ty
+ -- ASSERT( isVanillaDataCon data_con &&
+ -- isSingleton orig_arg_tys )
+ --
+ -- No existentials on a newtype, but it can have a context
+ -- e.g. newtype Eq a => T a = MkT (...)
+ mkCompulsoryUnfolding $
+ mkLams wrap_tvs $ Lam id_arg1 $
+ wrapNewTypeBody tycon res_ty_args
- (if null orig_arg_tys
- then ASSERT(not (null $ dataConDictTheta data_con)) mkPredTy $ head (dataConDictTheta data_con)
- else head orig_arg_tys
- )
-
- ----------- Wrapper --------------
- -- We used to include the stupid theta in the wrapper's args
- -- but now we don't. Instead the type checker just injects these
- -- extra constraints where necessary.
+ (if null orig_arg_tys
+ then ASSERT(not (null $ dataConDictTheta data_con)) mkPredTy $ head (dataConDictTheta data_con)
+ else head orig_arg_tys
+ )
+
+ ----------- Wrapper --------------
+ -- We used to include the stupid theta in the wrapper's args
+ -- but now we don't. Instead the type checker just injects these
+ -- extra constraints where necessary.
eq_tys = mkPredTys eq_theta
dict_tys = mkPredTys dict_theta
wrap_ty = mkForAllTys wrap_tvs $ mkFunTys eq_tys $ mkFunTys dict_tys $
eq_tys = mkPredTys eq_theta
dict_tys = mkPredTys dict_theta
wrap_ty = mkForAllTys wrap_tvs $ mkFunTys eq_tys $ mkFunTys dict_tys $
- mkFunTys orig_arg_tys $ res_ty
- -- NB: watch out here if you allow user-written equality
- -- constraints in data constructor signatures
+ mkFunTys orig_arg_tys $ res_ty
+ -- NB: watch out here if you allow user-written equality
+ -- constraints in data constructor signatures
- alg_wrap_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo
- `setArityInfo` wrap_arity
- -- It's important to specify the arity, so that partial
- -- applications are treated as values
- `setUnfoldingInfo` wrap_unf
- `setAllStrictnessInfo` Just wrap_sig
+ alg_wrap_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo
+ `setArityInfo` wrap_arity
+ -- It's important to specify the arity, so that partial
+ -- applications are treated as values
+ `setUnfoldingInfo` wrap_unf
+ `setAllStrictnessInfo` Just wrap_sig
all_strict_marks = dataConExStricts data_con ++ dataConStrictMarks data_con
wrap_sig = mkStrictSig (mkTopDmdType arg_dmds cpr_info)
arg_dmds = map mk_dmd all_strict_marks
mk_dmd str | isMarkedStrict str = evalDmd
all_strict_marks = dataConExStricts data_con ++ dataConStrictMarks data_con
wrap_sig = mkStrictSig (mkTopDmdType arg_dmds cpr_info)
arg_dmds = map mk_dmd all_strict_marks
mk_dmd str | isMarkedStrict str = evalDmd
- | otherwise = lazyDmd
- -- The Cpr info can be important inside INLINE rhss, where the
- -- wrapper constructor isn't inlined.
- -- And the argument strictness can be important too; we
- -- may not inline a contructor when it is partially applied.
- -- For example:
- -- data W = C !Int !Int !Int
- -- ...(let w = C x in ...(w p q)...)...
- -- we want to see that w is strict in its two arguments
+ | otherwise = lazyDmd
+ -- The Cpr info can be important inside INLINE rhss, where the
+ -- wrapper constructor isn't inlined.
+ -- And the argument strictness can be important too; we
+ -- may not inline a contructor when it is partially applied.
+ -- For example:
+ -- data W = C !Int !Int !Int
+ -- ...(let w = C x in ...(w p q)...)...
+ -- we want to see that w is strict in its two arguments
- Var wrk_id `mkTyApps` res_ty_args
- `mkVarApps` ex_tvs
- `mkTyApps` map snd eq_spec -- Equality evidence
- `mkVarApps` eq_args
- `mkVarApps` reverse rep_ids
+ Var wrk_id `mkTyApps` res_ty_args
+ `mkVarApps` ex_tvs
+ -- Equality evidence:
+ `mkTyApps` map snd eq_spec
+ `mkVarApps` eq_args
+ `mkVarApps` reverse rep_ids
(dict_args,i2) = mkLocals 1 dict_tys
(id_args,i3) = mkLocals i2 orig_arg_tys
(dict_args,i2) = mkLocals 1 dict_tys
(id_args,i3) = mkLocals i2 orig_arg_tys
(eq_args,_) = mkCoVarLocals i3 eq_tys
mkCoVarLocals i [] = ([],i)
(eq_args,_) = mkCoVarLocals i3 eq_tys
mkCoVarLocals i [] = ([],i)
- :: (Id, StrictnessMark) -- Arg, strictness
- -> (Int -> [Id] -> CoreExpr) -- Body
- -> Int -- Next rep arg id
- -> [Id] -- Rep args so far, reversed
- -> CoreExpr
+ :: (Id, StrictnessMark) -- Arg, strictness
+ -> (Int -> [Id] -> CoreExpr) -- Body
+ -> Int -- Next rep arg id
+ -> [Id] -- Rep args so far, reversed
+ -> CoreExpr
- = case strict of
- NotMarkedStrict -> body i (arg:rep_args)
- MarkedStrict
- | isUnLiftedType (idType arg) -> body i (arg:rep_args)
- | otherwise ->
- Case (Var arg) arg res_ty [(DEFAULT,[], body i (arg:rep_args))]
-
- MarkedUnboxed
- -> unboxProduct i (Var arg) (idType arg) the_body
+ = case strict of
+ NotMarkedStrict -> body i (arg:rep_args)
+ MarkedStrict
+ | isUnLiftedType (idType arg) -> body i (arg:rep_args)
+ | otherwise ->
+ Case (Var arg) arg res_ty [(DEFAULT,[], body i (arg:rep_args))]
+
+ MarkedUnboxed
+ -> unboxProduct i (Var arg) (idType arg) the_body
where
the_body i con_args = body i (reverse con_args ++ rep_args)
mAX_CPR_SIZE :: Arity
mAX_CPR_SIZE = 10
-- We do not treat very big tuples as CPR-ish:
where
the_body i con_args = body i (reverse con_args ++ rep_args)
mAX_CPR_SIZE :: Arity
mAX_CPR_SIZE = 10
-- We do not treat very big tuples as CPR-ish:
--- a) for a start we get into trouble because there aren't
--- "enough" unboxed tuple types (a tiresome restriction,
--- but hard to fix),
--- b) more importantly, big unboxed tuples get returned mainly
--- on the stack, and are often then allocated in the heap
--- by the caller. So doing CPR for them may in fact make
--- things worse.
+-- a) for a start we get into trouble because there aren't
+-- "enough" unboxed tuple types (a tiresome restriction,
+-- but hard to fix),
+-- b) more importantly, big unboxed tuples get returned mainly
+-- on the stack, and are often then allocated in the heap
+-- by the caller. So doing CPR for them may in fact make
+-- things worse.
%************************************************************************
We're going to build a record selector unfolding that looks like this:
%************************************************************************
We're going to build a record selector unfolding that looks like this:
- data T a b c = T1 { ..., op :: a, ...}
- | T2 { ..., op :: a, ...}
- | T3
+ data T a b c = T1 { ..., op :: a, ...}
+ | T2 { ..., op :: a, ...}
+ | T3
(not f :: R -> forall a. a->a, which gives the type inference mechanism
problems at call sites)
Similarly for (recursive) newtypes
(not f :: R -> forall a. a->a, which gives the type inference mechanism
problems at call sites)
Similarly for (recursive) newtypes
Note [Naughty record selectors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A "naughty" field is one for which we can't define a record
selector, because an existential type variable would escape. For example:
Note [Naughty record selectors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A "naughty" field is one for which we can't define a record
selector, because an existential type variable would escape. For example:
- data T = forall a. MkT { x,y::a }
-We obviously can't define
- x (MkT v _) = v
+ data T = forall a. MkT { x,y::a }
+We obviously can't define
+ x (MkT v _) = v
Nevertheless we *do* put a RecordSelId into the type environment
so that if the user tries to use 'x' as a selector we can bleat
helpfully, rather than saying unhelpfully that 'x' is not in scope.
Nevertheless we *do* put a RecordSelId into the type environment
so that if the user tries to use 'x' as a selector we can bleat
helpfully, rather than saying unhelpfully that 'x' is not in scope.
For GADTs, we require that all constructors with a common field 'f' have the same
result type (modulo alpha conversion). [Checked in TcTyClsDecls.checkValidTyCon]
E.g.
For GADTs, we require that all constructors with a common field 'f' have the same
result type (modulo alpha conversion). [Checked in TcTyClsDecls.checkValidTyCon]
E.g.
Note the forall'd tyvars of the selector are just the free tyvars
of the result type; there may be other tyvars in the constructor's
type (e.g. 'b' in T2).
Note the forall'd tyvars of the selector are just the free tyvars
of the result type; there may be other tyvars in the constructor's
type (e.g. 'b' in T2).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It's OK to combine GADTs and type families. Here's a running example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It's OK to combine GADTs and type families. Here's a running example:
- fld :: forall b. T [Maybe b] -> b
- fld = /\b. \(d::T [Maybe b]).
- case d `cast` :CoR7T (Maybe b) of
- T1 (x::b) -> x
+ fld :: forall b. T [Maybe b] -> b
+ fld = /\b. \(d::T [Maybe b]).
+ case d `cast` :CoR7T (Maybe b) of
+ T1 (x::b) -> x
The scrutinee of the case has type :R7T (Maybe b), which can be
gotten by appying the eq_spec to the univ_tvs of the data con.
The scrutinee of the case has type :R7T (Maybe b), which can be
gotten by appying the eq_spec to the univ_tvs of the data con.
-- check whether the type is naughty: this thunk does not get forced
-- until the type is actually needed
-- check whether the type is naughty: this thunk does not get forced
-- until the type is actually needed
is_naughty = not (tyVarsOfType field_ty `subVarSet` data_tv_set)
-- it's important that this doesn't force the if
(theType, theInfo) = if is_naughty
-- Escapist case here for naughty constructors
is_naughty = not (tyVarsOfType field_ty `subVarSet` data_tv_set)
-- it's important that this doesn't force the if
(theType, theInfo) = if is_naughty
-- Escapist case here for naughty constructors
then (forall_a_a, noCafIdInfo)
-- otherwise do the real case
else (selector_ty, info)
then (forall_a_a, noCafIdInfo)
-- otherwise do the real case
else (selector_ty, info)
- sel_id_details = RecordSelId { sel_tycon = tycon, sel_label = field_label, sel_naughty = is_naughty }
+ sel_id_details = RecordSelId { sel_tycon = tycon,
+ sel_label = field_label,
+ sel_naughty = is_naughty }
-- For a data type family, the tycon is the *instance* TyCon
-- for naughty case
forall_a_a = mkForAllTy alphaTyVar (mkTyVarTy alphaTyVar)
-- real case starts here:
-- For a data type family, the tycon is the *instance* TyCon
-- for naughty case
forall_a_a = mkForAllTy alphaTyVar (mkTyVarTy alphaTyVar)
-- real case starts here:
- data_cons = tyConDataCons tycon
- data_cons_w_field = filter has_field data_cons -- Can't be empty!
+ data_cons = tyConDataCons tycon
+ data_cons_w_field = filter has_field data_cons -- Can't be empty!
(univ_tvs, _, eq_spec, _, _, _, data_ty) = dataConFullSig con1
(univ_tvs, _, eq_spec, _, _, _, data_ty) = dataConFullSig con1
- -- For a data type family, the data_ty (and hence selector_ty) mentions
- -- only the family TyCon, not the instance TyCon
- data_tv_set = tyVarsOfType data_ty
- data_tvs = varSetElems data_tv_set
+ -- For a data type family, the data_ty (and hence selector_ty) mentions
+ -- only the family TyCon, not the instance TyCon
+ data_tv_set = tyVarsOfType data_ty
+ data_tvs = varSetElems data_tv_set
- -- *Very* tiresomely, the selectors are (unnecessarily!) overloaded over
- -- just the dictionaries in the types of the constructors that contain
- -- the relevant field. [The Report says that pattern matching on a
- -- constructor gives the same constraints as applying it.] Urgh.
- --
- -- However, not all data cons have all constraints (because of
- -- BuildTyCl.mkDataConStupidTheta). So we need to find all the data cons
- -- involved in the pattern match and take the union of their constraints.
+ -- *Very* tiresomely, the selectors are (unnecessarily!) overloaded over
+ -- just the dictionaries in the types of the constructors that contain
+ -- the relevant field. [The Report says that pattern matching on a
+ -- constructor gives the same constraints as applying it.] Urgh.
+ --
+ -- However, not all data cons have all constraints (because of
+ -- BuildTyCl.mkDataConStupidTheta). So we need to find all the data cons
+ -- involved in the pattern match and take the union of their constraints.
stupid_dict_tys = mkPredTys (dataConsStupidTheta data_cons_w_field)
n_stupid_dicts = length stupid_dict_tys
stupid_dict_tys = mkPredTys (dataConsStupidTheta data_cons_w_field)
n_stupid_dicts = length stupid_dict_tys
field_theta = filter (not . isEqPred) pre_field_theta
field_dict_tys = mkPredTys field_theta
n_field_dict_tys = length field_dict_tys
field_theta = filter (not . isEqPred) pre_field_theta
field_dict_tys = mkPredTys field_theta
n_field_dict_tys = length field_dict_tys
- -- If the field has a universally quantified type we have to
- -- be a bit careful. Suppose we have
- -- data R = R { op :: forall a. Foo a => a -> a }
- -- Then we can't give op the type
- -- op :: R -> forall a. Foo a => a -> a
- -- because the typechecker doesn't understand foralls to the
- -- right of an arrow. The "right" type to give it is
- -- op :: forall a. Foo a => R -> a -> a
- -- But then we must generate the right unfolding too:
- -- op = /\a -> \dfoo -> \ r ->
- -- case r of
- -- R op -> op a dfoo
- -- Note that this is exactly the type we'd infer from a user defn
- -- op (R op) = op
+ -- If the field has a universally quantified type we have to
+ -- be a bit careful. Suppose we have
+ -- data R = R { op :: forall a. Foo a => a -> a }
+ -- Then we can't give op the type
+ -- op :: R -> forall a. Foo a => a -> a
+ -- because the typechecker doesn't understand foralls to the
+ -- right of an arrow. The "right" type to give it is
+ -- op :: forall a. Foo a => R -> a -> a
+ -- But then we must generate the right unfolding too:
+ -- op = /\a -> \dfoo -> \ r ->
+ -- case r of
+ -- R op -> op a dfoo
+ -- Note that this is exactly the type we'd infer from a user defn
+ -- op (R op) = op
arity = 1 + n_stupid_dicts + n_field_dict_tys
(strict_sig, rhs_w_str) = dmdAnalTopRhs sel_rhs
arity = 1 + n_stupid_dicts + n_field_dict_tys
(strict_sig, rhs_w_str) = dmdAnalTopRhs sel_rhs
- `setCafInfo` caf_info
- `setArityInfo` arity
- `setUnfoldingInfo` mkTopUnfolding rhs_w_str
- `setAllStrictnessInfo` Just strict_sig
-
- -- Allocate Ids. We do it a funny way round because field_dict_tys is
- -- almost always empty. Also note that we use max_dict_tys
- -- rather than n_dict_tys, because the latter gives an infinite loop:
- -- n_dict tys depends on the_alts, which depens on arg_ids, which depends
- -- on arity, which depends on n_dict tys. Sigh! Mega sigh!
+ `setCafInfo` caf_info
+ `setArityInfo` arity
+ `setUnfoldingInfo` mkTopUnfolding rhs_w_str
+ `setAllStrictnessInfo` Just strict_sig
+
+ -- Allocate Ids. We do it a funny way round because field_dict_tys is
+ -- almost always empty. Also note that we use max_dict_tys
+ -- rather than n_dict_tys, because the latter gives an infinite loop:
+ -- n_dict tys depends on the_alts, which depens on arg_ids, which depends
+ -- on arity, which depends on n_dict tys. Sigh! Mega sigh!
stupid_dict_ids = mkTemplateLocalsNum 1 stupid_dict_tys
max_stupid_dicts = length (tyConStupidTheta tycon)
field_dict_base = max_stupid_dicts + 1
field_dict_ids = mkTemplateLocalsNum field_dict_base field_dict_tys
dict_id_base = field_dict_base + n_field_dict_tys
stupid_dict_ids = mkTemplateLocalsNum 1 stupid_dict_tys
max_stupid_dicts = length (tyConStupidTheta tycon)
field_dict_base = max_stupid_dicts + 1
field_dict_ids = mkTemplateLocalsNum field_dict_base field_dict_tys
dict_id_base = field_dict_base + n_field_dict_tys
- data_id = mkTemplateLocal dict_id_base data_ty
- scrut_id = mkTemplateLocal (dict_id_base+1) scrut_ty
- arg_base = dict_id_base + 2
+ data_id = mkTemplateLocal dict_id_base data_ty
+ scrut_id = mkTemplateLocal (dict_id_base+1) scrut_ty
+ arg_base = dict_id_base + 2
- the_alts = map mk_alt data_cons_w_field -- Already sorted by data-con
- no_default = length data_cons == length data_cons_w_field -- No default needed
+ the_alts = map mk_alt data_cons_w_field -- Already sorted by data-con
+ no_default = length data_cons == length data_cons_w_field -- No default needed
- -- NB: A newtype always has a vanilla DataCon; no existentials etc
- -- data_tys will simply be the dataConUnivTyVars
+ -- NB: A newtype always has a vanilla DataCon; no existentials etc
+ -- data_tys will simply be the dataConUnivTyVars
- -- We pull the field lambdas to the top, so we need to
- -- apply them in the body. For example:
- -- data T = MkT { foo :: forall a. a->a }
- --
- -- foo :: forall a. T -> a -> a
- -- foo = /\a. \t:T. case t of { MkT f -> f a }
+ -- We pull the field lambdas to the top, so we need to
+ -- apply them in the body. For example:
+ -- data T = MkT { foo :: forall a. a->a }
+ --
+ -- foo :: forall a. T -> a -> a
+ -- foo = /\a. \t:T. case t of { MkT f -> f a }
- rebox_base = arg_base + length ex_tvs + length co_tvs + length arg_vs
- rebox_uniqs = map mkBuiltinUnique [rebox_base..]
+ rebox_base = arg_base + length ex_tvs + length co_tvs + length arg_vs
+ rebox_uniqs = map mkBuiltinUnique [rebox_base..]
- -- data T :: *->* where T1 { fld :: Maybe b } -> T [b]
- -- Hence T1 :: forall a b. (a=[b]) => b -> T a
- -- fld :: forall b. T [b] -> Maybe b
- -- fld = /\b.\(t:T[b]). case t of
- -- T1 b' (c : [b]=[b']) (x:Maybe b')
- -- -> x `cast` Maybe (sym (right c))
+ -- data T :: *->* where T1 { fld :: Maybe b } -> T [b]
+ -- Hence T1 :: forall a b. (a=[b]) => b -> T a
+ -- fld :: forall b. T [b] -> Maybe b
+ -- fld = /\b.\(t:T[b]). case t of
+ -- T1 b' (c : [b]=[b']) (x:Maybe b')
+ -- -> x `cast` Maybe (sym (right c))
-
- -- Generate the refinement for b'=b,
- -- and apply to (Maybe b'), to get (Maybe b)
+ -- Generate the refinement for b'=b,
+ -- and apply to (Maybe b'), to get (Maybe b)
- Just (co, data_ty) -> (Cast (Var the_arg_id) co, data_ty)
- Nothing -> (Var the_arg_id, the_arg_id_ty)
+ Just (co, data_ty) -> (Cast (Var the_arg_id) co, data_ty)
+ Nothing -> (Var the_arg_id, the_arg_id_ty)
- field_vs = filter (not . isPredTy . idType) arg_vs
- the_arg_id = assoc "mkRecordSelId:mk_alt" (field_lbls `zip` field_vs) field_label
- field_lbls = dataConFieldLabels data_con
+ field_vs = filter (not . isPredTy . idType) arg_vs
+ the_arg_id = assoc "mkRecordSelId:mk_alt" (field_lbls `zip` field_vs) field_label
+ field_lbls = dataConFieldLabels data_con
error_expr = mkRuntimeErrorApp rEC_SEL_ERROR_ID field_ty full_msg
full_msg = showSDoc (sep [text "No match in record selector", ppr sel_id])
error_expr = mkRuntimeErrorApp rEC_SEL_ERROR_ID field_ty full_msg
full_msg = showSDoc (sep [text "No match in record selector", ppr sel_id])
mkUnpackCase :: Id -> CoreExpr -> [Id] -> DataCon -> CoreExpr -> CoreExpr
-- (mkUnpackCase x e args Con body)
mkUnpackCase :: Id -> CoreExpr -> [Id] -> DataCon -> CoreExpr -> CoreExpr
-- (mkUnpackCase x e args Con body)
- (_tycon, _tycon_args, _pack_con, con_arg_tys) = deepSplitProductType "reboxProduct" ty
+ (_tycon, _tycon_args, _pack_con, con_arg_tys) = deepSplitProductType "reboxProduct" ty
-- but it does the reboxing necessary to construct the *source*
-- arguments, xs, from the representation arguments ys.
-- For example:
-- but it does the reboxing necessary to construct the *source*
-- arguments, xs, from the representation arguments ys.
-- For example:
--- = (DataAlt MkT, [y::Int,z::Int,b], let x = (y,z) in r)
+-- = (DataAlt MkT, [y::Int,z::Int,b], let x = (y,z) in r)
--
-- mkDataAlt should really be in DataCon, but it can't because
-- it manipulates CoreSyn.
mkReboxingAlt
--
-- mkDataAlt should really be in DataCon, but it can't because
-- it manipulates CoreSyn.
mkReboxingAlt
%************************************************************************
Selecting a field for a dictionary. If there is just one field, then
%************************************************************************
Selecting a field for a dictionary. If there is just one field, then
This is unlike ordinary record selectors, which have all the for-alls
at the outside. When dealing with classes it's very convenient to
recover the original type signature from the class op selector.
\begin{code}
This is unlike ordinary record selectors, which have all the for-alls
at the outside. When dealing with classes it's very convenient to
recover the original type signature from the class op selector.
\begin{code}
-mkDictSelId :: Name -> Class -> Id
-mkDictSelId name clas
+mkDictSelId :: Bool -- True <=> don't include the unfolding
+ -- Little point on imports without -O, because the
+ -- dictionary itself won't be visible
+ -> Name -> Class -> Id
+mkDictSelId no_unf name clas
= mkGlobalId (ClassOpId clas) name sel_ty info
where
sel_ty = mkForAllTys tyvars (mkFunTy (idType dict_id) (idType the_arg_id))
= mkGlobalId (ClassOpId clas) name sel_ty info
where
sel_ty = mkForAllTys tyvars (mkFunTy (idType dict_id) (idType the_arg_id))
- -- We can't just say (exprType rhs), because that would give a type
- -- C a -> C a
- -- for a single-op class (after all, the selector is the identity)
- -- But it's type must expose the representation of the dictionary
- -- to get (say) C a -> (a -> a)
+ -- We can't just say (exprType rhs), because that would give a type
+ -- C a -> C a
+ -- for a single-op class (after all, the selector is the identity)
+ -- But it's type must expose the representation of the dictionary
+ -- to get (say) C a -> (a -> a)
- `setArityInfo` 1
- `setUnfoldingInfo` mkTopUnfolding rhs
- `setAllStrictnessInfo` Just strict_sig
-
- -- We no longer use 'must-inline' on record selectors. They'll
- -- inline like crazy if they scrutinise a constructor
-
- -- The strictness signature is of the form U(AAAVAAAA) -> T
- -- where the V depends on which item we are selecting
- -- It's worth giving one, so that absence info etc is generated
- -- even if the selector isn't inlined
+ `setArityInfo` 1
+ `setAllStrictnessInfo` Just strict_sig
+ `setUnfoldingInfo` (if no_unf then noUnfolding
+ else mkTopUnfolding rhs)
+
+ -- We no longer use 'must-inline' on record selectors. They'll
+ -- inline like crazy if they scrutinise a constructor
+
+ -- The strictness signature is of the form U(AAAVAAAA) -> T
+ -- where the V depends on which item we are selecting
+ -- It's worth giving one, so that absence info etc is generated
+ -- even if the selector isn't inlined
tycon = classTyCon clas
[data_con] = tyConDataCons tycon
tyvars = dataConUnivTyVars data_con
arg_tys = {- ASSERT( isVanillaDataCon data_con ) -} dataConRepArgTys data_con
tycon = classTyCon clas
[data_con] = tyConDataCons tycon
tyvars = dataConUnivTyVars data_con
arg_tys = {- ASSERT( isVanillaDataCon data_con ) -} dataConRepArgTys data_con
the_arg_id = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` arg_ids) name
pred = mkClassPred clas (mkTyVarTys tyvars)
the_arg_id = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` arg_ids) name
pred = mkClassPred clas (mkTyVarTys tyvars)
rhs = mkLams tyvars (Lam dict_id rhs_body)
rhs_body | isNewTyCon tycon = unwrapNewTypeBody tycon (map mkTyVarTy tyvars) (Var dict_id)
rhs = mkLams tyvars (Lam dict_id rhs_body)
rhs_body | isNewTyCon tycon = unwrapNewTypeBody tycon (map mkTyVarTy tyvars) (Var dict_id)
- | otherwise = Case (Var dict_id) dict_id (idType the_arg_id)
- [(DataAlt data_con, eq_ids ++ arg_ids, Var the_arg_id)]
+ | otherwise = Case (Var dict_id) dict_id (idType the_arg_id)
+ [(DataAlt data_con, eq_ids ++ arg_ids, Var the_arg_id)]
%************************************************************************
\begin{code}
wrapNewTypeBody :: TyCon -> [Type] -> CoreExpr -> CoreExpr
-- The wrapper for the data constructor for a newtype looks like this:
%************************************************************************
\begin{code}
wrapNewTypeBody :: TyCon -> [Type] -> CoreExpr -> CoreExpr
-- The wrapper for the data constructor for a newtype looks like this:
--- newtype T a = MkT (a,Int)
--- MkT :: forall a. (a,Int) -> T a
--- MkT = /\a. \(x:(a,Int)). x `cast` sym (CoT a)
+-- newtype T a = MkT (a,Int)
+-- MkT :: forall a. (a,Int) -> T a
+-- MkT = /\a. \(x:(a,Int)). x `cast` sym (CoT a)
-- where CoT is the coercion TyCon assoicated with the newtype
--
-- The call (wrapNewTypeBody T [a] e) returns the
-- body of the wrapper, namely
-- where CoT is the coercion TyCon assoicated with the newtype
--
-- The call (wrapNewTypeBody T [a] e) returns the
-- body of the wrapper, namely
--
-- If a coercion constructor is provided in the newtype, then we use
-- it, otherwise the wrap/unwrap are both no-ops
--
-- If a coercion constructor is provided in the newtype, then we use
-- it, otherwise the wrap/unwrap are both no-ops
(tyvars,arg_tys,res_ty, arity, strict_sig) = primOpSig prim_op
ty = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
name = mkWiredInName gHC_PRIM (primOpOcc prim_op)
(tyvars,arg_tys,res_ty, arity, strict_sig) = primOpSig prim_op
ty = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
name = mkWiredInName gHC_PRIM (primOpOcc prim_op)
-- For each ccall we manufacture a separate CCallOpId, giving it
-- a fresh unique, a type that is correct for this particular ccall,
-- For each ccall we manufacture a separate CCallOpId, giving it
-- a fresh unique, a type that is correct for this particular ccall,
- -- A CCallOpId should have no free type variables;
- -- when doing substitutions won't substitute over it
+ -- A CCallOpId should have no free type variables;
+ -- when doing substitutions won't substitute over it
- -- The "occurrence name" of a ccall is the full info about the
- -- ccall; it is encoded, but may have embedded spaces etc!
+ -- The "occurrence name" of a ccall is the full info about the
+ -- ccall; it is encoded, but may have embedded spaces etc!
strict_sig = mkStrictSig (mkTopDmdType (replicate arity evalDmd) TopRes)
-- Tick boxes and breakpoints are both represented as TickBoxOpIds,
strict_sig = mkStrictSig (mkTopDmdType (replicate arity evalDmd) TopRes)
-- Tick boxes and breakpoints are both represented as TickBoxOpIds,
%************************************************************************
Important notes about dict funs and default methods
%************************************************************************
Important notes about dict funs and default methods
not_const (clas, tys) = not (isEmptyVarSet (tyVarsOfTypes tys))
sc_theta' = substClasses (zipTopTvSubst class_tyvars inst_tys) sc_theta
dfun_theta = case inst_decl_theta of
not_const (clas, tys) = not (isEmptyVarSet (tyVarsOfTypes tys))
sc_theta' = substClasses (zipTopTvSubst class_tyvars inst_tys) sc_theta
dfun_theta = case inst_decl_theta of
- [] -> [] -- If inst_decl_theta is empty, then we don't
- -- want to have any dict arguments, so that we can
- -- expose the constant methods.
-
- other -> nub (inst_decl_theta ++ filter not_const sc_theta')
- -- Otherwise we pass the superclass dictionaries to
- -- the dictionary function; the Mark Jones optimisation.
- --
- -- NOTE the "nub". I got caught by this one:
- -- class Monad m => MonadT t m where ...
- -- instance Monad m => MonadT (EnvT env) m where ...
- -- Here, the inst_decl_theta has (Monad m); but so
- -- does the sc_theta'!
- --
- -- NOTE the "not_const". I got caught by this one too:
- -- class Foo a => Baz a b where ...
- -- instance Wob b => Baz T b where..
- -- Now sc_theta' has Foo T
+ [] -> [] -- If inst_decl_theta is empty, then we don't
+ -- want to have any dict arguments, so that we can
+ -- expose the constant methods.
+
+ other -> nub (inst_decl_theta ++ filter not_const sc_theta')
+ -- Otherwise we pass the superclass dictionaries to
+ -- the dictionary function; the Mark Jones optimisation.
+ --
+ -- NOTE the "nub". I got caught by this one:
+ -- class Monad m => MonadT t m where ...
+ -- instance Monad m => MonadT (EnvT env) m where ...
+ -- Here, the inst_decl_theta has (Monad m); but so
+ -- does the sc_theta'!
+ --
+ -- NOTE the "not_const". I got caught by this one too:
+ -- class Foo a => Baz a b where ...
+ -- instance Wob b => Baz T b where..
+ -- Now sc_theta' has Foo T
%************************************************************************
These Ids can't be defined in Haskell. They could be defined in
%************************************************************************
These Ids can't be defined in Haskell. They could be defined in
= mkWiredInName mod (mkOccNameFS varName fs) uniq (AnId id) UserSyntax
unsafeCoerceName = mkWiredInIdName gHC_PRIM FSLIT("unsafeCoerce#") unsafeCoerceIdKey unsafeCoerceId
= mkWiredInName mod (mkOccNameFS varName fs) uniq (AnId id) UserSyntax
unsafeCoerceName = mkWiredInIdName gHC_PRIM FSLIT("unsafeCoerce#") unsafeCoerceIdKey unsafeCoerceId
-nullAddrName = mkWiredInIdName gHC_PRIM FSLIT("nullAddr#") nullAddrIdKey nullAddrId
-seqName = mkWiredInIdName gHC_PRIM FSLIT("seq") seqIdKey seqId
-realWorldName = mkWiredInIdName gHC_PRIM FSLIT("realWorld#") realWorldPrimIdKey realWorldPrimId
-lazyIdName = mkWiredInIdName gHC_BASE FSLIT("lazy") lazyIdKey lazyId
-
-errorName = mkWiredInIdName gHC_ERR FSLIT("error") errorIdKey eRROR_ID
-recSelErrorName = mkWiredInIdName gHC_ERR FSLIT("recSelError") recSelErrorIdKey rEC_SEL_ERROR_ID
-runtimeErrorName = mkWiredInIdName gHC_ERR FSLIT("runtimeError") runtimeErrorIdKey rUNTIME_ERROR_ID
-irrefutPatErrorName = mkWiredInIdName gHC_ERR FSLIT("irrefutPatError") irrefutPatErrorIdKey iRREFUT_PAT_ERROR_ID
-recConErrorName = mkWiredInIdName gHC_ERR FSLIT("recConError") recConErrorIdKey rEC_CON_ERROR_ID
-patErrorName = mkWiredInIdName gHC_ERR FSLIT("patError") patErrorIdKey pAT_ERROR_ID
+nullAddrName = mkWiredInIdName gHC_PRIM FSLIT("nullAddr#") nullAddrIdKey nullAddrId
+seqName = mkWiredInIdName gHC_PRIM FSLIT("seq") seqIdKey seqId
+realWorldName = mkWiredInIdName gHC_PRIM FSLIT("realWorld#") realWorldPrimIdKey realWorldPrimId
+lazyIdName = mkWiredInIdName gHC_BASE FSLIT("lazy") lazyIdKey lazyId
+
+errorName = mkWiredInIdName gHC_ERR FSLIT("error") errorIdKey eRROR_ID
+recSelErrorName = mkWiredInIdName gHC_ERR FSLIT("recSelError") recSelErrorIdKey rEC_SEL_ERROR_ID
+runtimeErrorName = mkWiredInIdName gHC_ERR FSLIT("runtimeError") runtimeErrorIdKey rUNTIME_ERROR_ID
+irrefutPatErrorName = mkWiredInIdName gHC_ERR FSLIT("irrefutPatError") irrefutPatErrorIdKey iRREFUT_PAT_ERROR_ID
+recConErrorName = mkWiredInIdName gHC_ERR FSLIT("recConError") recConErrorIdKey rEC_CON_ERROR_ID
+patErrorName = mkWiredInIdName gHC_ERR FSLIT("patError") patErrorIdKey pAT_ERROR_ID
= pcMiscPrelId unsafeCoerceName ty info
where
info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
= pcMiscPrelId unsafeCoerceName ty info
where
info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
[x] = mkTemplateLocals [openAlphaTy]
rhs = mkLams [openAlphaTyVar,openBetaTyVar,x] $
Cast (Var x) (mkUnsafeCoercion openAlphaTy openBetaTy)
[x] = mkTemplateLocals [openAlphaTy]
rhs = mkLams [openAlphaTyVar,openBetaTyVar,x] $
Cast (Var x) (mkUnsafeCoercion openAlphaTy openBetaTy)
[x,y] = mkTemplateLocals [alphaTy, openBetaTy]
rhs = mkLams [alphaTyVar,openBetaTyVar,x,y] (Case (Var x) x openBetaTy [(DEFAULT, [], Var y)])
[x,y] = mkTemplateLocals [alphaTy, openBetaTy]
rhs = mkLams [alphaTyVar,openBetaTyVar,x,y] (Case (Var x) x openBetaTy [(DEFAULT, [], Var y)])
--- lazy :: forall a?. a? -> a? (i.e. works for unboxed types too)
--- Used to lazify pseq: pseq a b = a `seq` lazy b
+-- lazy :: forall a?. a? -> a? (i.e. works for unboxed types too)
+-- Used to lazify pseq: pseq a b = a `seq` lazy b
--
-- Also, no strictness: by being a built-in Id, all the info about lazyId comes from here,
-- not from GHC.Base.hi. This is important, because the strictness
-- analyser will spot it as strict!
--
-- Also no unfolding in lazyId: it gets "inlined" by a HACK in the worker/wrapperpass
--
-- Also, no strictness: by being a built-in Id, all the info about lazyId comes from here,
-- not from GHC.Base.hi. This is important, because the strictness
-- analyser will spot it as strict!
--
-- Also no unfolding in lazyId: it gets "inlined" by a HACK in the worker/wrapperpass
-- We could use inline phases to do this, but that would be vulnerable to changes in
-- phase numbering....we must inline precisely after strictness analysis.
lazyId
-- We could use inline phases to do this, but that would be vulnerable to changes in
-- phase numbering....we must inline precisely after strictness analysis.
lazyId
voidArgId is a Local Id used simply as an argument in functions
where we just want an arg to avoid having a thunk of unlifted type.
E.g.
voidArgId is a Local Id used simply as an argument in functions
where we just want an arg to avoid having a thunk of unlifted type.
E.g.
- (noCafIdInfo `setUnfoldingInfo` evaldUnfolding)
- -- The evaldUnfolding makes it look that realWorld# is evaluated
- -- which in turn makes Simplify.interestingArg return True,
- -- which in turn makes INLINE things applied to realWorld# likely
- -- to be inlined
-
-voidArgId -- :: State# RealWorld
+ (noCafIdInfo `setUnfoldingInfo` evaldUnfolding)
+ -- The evaldUnfolding makes it look that realWorld# is evaluated
+ -- which in turn makes Simplify.interestingArg return True,
+ -- which in turn makes INLINE things applied to realWorld# likely
+ -- to be inlined
+
+voidArgId :: Id
+voidArgId -- :: State# RealWorld
= mkSysLocal FSLIT("void") voidArgIdKey realWorldStatePrimTy
\end{code}
%************************************************************************
= mkSysLocal FSLIT("void") voidArgIdKey realWorldStatePrimTy
\end{code}
%************************************************************************
%************************************************************************
GHC randomly injects these into the code.
%************************************************************************
GHC randomly injects these into the code.
- :: Id -- Should be of type (forall a. Addr# -> a)
- -- where Addr# points to a UTF8 encoded string
- -> Type -- The type to instantiate 'a'
- -> String -- The string to print
- -> CoreExpr
+ :: Id -- Should be of type (forall a. Addr# -> a)
+ -- where Addr# points to a UTF8 encoded string
+ -> Type -- The type to instantiate 'a'
+ -> String -- The string to print
+ -> CoreExpr
mkRuntimeErrorApp err_id res_ty err_msg
= mkApps (Var err_id) [Type res_ty, err_string]
where
err_string = Lit (mkStringLit err_msg)
mkRuntimeErrorApp err_id res_ty err_msg
= mkApps (Var err_id) [Type res_ty, err_string]
where
err_string = Lit (mkStringLit err_msg)
-rEC_SEL_ERROR_ID = mkRuntimeErrorId recSelErrorName
-rUNTIME_ERROR_ID = mkRuntimeErrorId runtimeErrorName
-iRREFUT_PAT_ERROR_ID = mkRuntimeErrorId irrefutPatErrorName
-rEC_CON_ERROR_ID = mkRuntimeErrorId recConErrorName
-pAT_ERROR_ID = mkRuntimeErrorId patErrorName
+rEC_SEL_ERROR_ID = mkRuntimeErrorId recSelErrorName
+rUNTIME_ERROR_ID = mkRuntimeErrorId runtimeErrorName
+iRREFUT_PAT_ERROR_ID = mkRuntimeErrorId irrefutPatErrorName
+rEC_CON_ERROR_ID = mkRuntimeErrorId recConErrorName
+pAT_ERROR_ID = mkRuntimeErrorId patErrorName
-- being compiled, then it's just a matter of luck if the definition
-- will be in "the right place" to be in scope.
-- being compiled, then it's just a matter of luck if the definition
-- will be in "the right place" to be in scope.
pc_bottoming_Id name ty
= pcMiscPrelId name ty bottoming_info
where
bottoming_info = vanillaIdInfo `setAllStrictnessInfo` Just strict_sig
pc_bottoming_Id name ty
= pcMiscPrelId name ty bottoming_info
where
bottoming_info = vanillaIdInfo `setAllStrictnessInfo` Just strict_sig
- -- Do *not* mark them as NoCafRefs, because they can indeed have
- -- CAF refs. For example, pAT_ERROR_ID calls GHC.Err.untangle,
- -- which has some CAFs
- -- In due course we may arrange that these error-y things are
- -- regarded by the GC as permanently live, in which case we
- -- can give them NoCaf info. As it is, any function that calls
- -- any pc_bottoming_Id will itself have CafRefs, which bloats
- -- SRTs.
-
- strict_sig = mkStrictSig (mkTopDmdType [evalDmd] BotRes)
- -- These "bottom" out, no matter what their arguments
+ -- Do *not* mark them as NoCafRefs, because they can indeed have
+ -- CAF refs. For example, pAT_ERROR_ID calls GHC.Err.untangle,
+ -- which has some CAFs
+ -- In due course we may arrange that these error-y things are
+ -- regarded by the GC as permanently live, in which case we
+ -- can give them NoCaf info. As it is, any function that calls
+ -- any pc_bottoming_Id will itself have CafRefs, which bloats
+ -- SRTs.
+
+ strict_sig = mkStrictSig (mkTopDmdType [evalDmd] BotRes)
+ -- These "bottom" out, no matter what their arguments