X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FbasicTypes%2FMkId.lhs;h=de8db07c6dac0d130407e7a79bc9f7a8f1bdb9fe;hb=8912a05e1bcc30c7e8e5e017d9cf10176076f141;hp=84b3546e622f1b1f4421b6bc544caaca89a89b4a;hpb=0065d5ab628975892cea1ec7303f968c3338cbe1;p=ghc-hetmet.git diff --git a/compiler/basicTypes/MkId.lhs b/compiler/basicTypes/MkId.lhs index 84b3546..de8db07 100644 --- a/compiler/basicTypes/MkId.lhs +++ b/compiler/basicTypes/MkId.lhs @@ -20,12 +20,13 @@ module MkId ( mkRecordSelId, mkPrimOpId, mkFCallId, - mkReboxingAlt, mkNewTypeBody, + mkReboxingAlt, wrapNewTypeBody, unwrapNewTypeBody, + mkUnpackCase, mkProductBox, -- And some particular Ids; see below for why they are wired in wiredInIds, ghcPrimIds, unsafeCoerceId, realWorldPrimId, voidArgId, nullAddrId, seqId, - lazyId, lazyIdUnfolding, lazyIdKey, + lazyId, lazyIdUnfolding, lazyIdKey, mkRuntimeErrorApp, rEC_CON_ERROR_ID, iRREFUT_PAT_ERROR_ID, rUNTIME_ERROR_ID, @@ -45,35 +46,43 @@ import TysPrim ( openAlphaTyVars, alphaTyVar, alphaTy, ) import TysWiredIn ( charTy, mkListTy ) import PrelRules ( primOpRules ) -import Type ( TyThing(..), mkForAllTy, tyVarsOfTypes ) +import Type ( TyThing(..), mkForAllTy, tyVarsOfTypes, newTyConInstRhs, coreEqType, + PredType(..), + mkTopTvSubst, substTyVar ) +import TcGadt ( gadtRefine, refineType, emptyRefinement ) +import HsBinds ( ExprCoFn(..), isIdCoercion ) +import Coercion ( mkSymCoercion, mkUnsafeCoercion, + splitNewTypeRepCo_maybe, isEqPred ) import TcType ( Type, ThetaType, mkDictTy, mkPredTys, mkPredTy, mkTyConApp, mkTyVarTys, mkClassPred, mkFunTys, mkFunTy, mkSigmaTy, tcSplitSigmaTy, isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType, tcSplitFunTys, tcSplitForAllTys, dataConsStupidTheta ) -import CoreUtils ( exprType ) +import CoreUtils ( exprType, dataConInstPat ) import CoreUnfold ( mkTopUnfolding, mkCompulsoryUnfolding ) import Literal ( nullAddrLit, mkStringLit ) import TyCon ( TyCon, isNewTyCon, tyConDataCons, FieldLabel, - tyConStupidTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon ) + tyConStupidTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon, + newTyConCo, tyConArity ) import Class ( Class, classTyCon, classSelIds ) -import Var ( Id, TyVar, Var ) +import Var ( Id, TyVar, Var, setIdType, mkCoVar, mkWildCoVar ) import VarSet ( isEmptyVarSet, subVarSet, varSetElems ) -import Name ( mkFCallName, mkWiredInName, Name, BuiltInSyntax(..) ) +import Name ( mkFCallName, mkWiredInName, Name, BuiltInSyntax(..), + mkSysTvName ) import OccName ( mkOccNameFS, varName ) import PrimOp ( PrimOp, primOpSig, primOpOcc, primOpTag ) import ForeignCall ( ForeignCall ) -import DataCon ( DataCon, DataConIds(..), dataConTyVars, +import DataCon ( DataCon, DataConIds(..), dataConTyCon, dataConUnivTyVars, dataConFieldLabels, dataConRepArity, dataConResTys, - dataConRepArgTys, dataConRepType, + dataConRepArgTys, dataConRepType, dataConFullSig, dataConSig, dataConStrictMarks, dataConExStricts, splitProductType, isVanillaDataCon, dataConFieldType, - dataConInstOrigArgTys + dataConInstOrigArgTys, deepSplitProductType ) import Id ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal, mkTemplateLocals, mkTemplateLocalsNum, mkExportedLocalId, - mkTemplateLocal, idName + mkTemplateLocal, idName, mkWildId ) import IdInfo ( IdInfo, noCafIdInfo, setUnfoldingInfo, setArityInfo, setSpecInfo, setCafInfo, @@ -91,7 +100,7 @@ import PrelNames import Util ( dropList, isSingleton ) import Outputable import FastString -import ListSetOps ( assoc ) +import ListSetOps ( assoc, minusList ) \end{code} %************************************************************************ @@ -184,30 +193,37 @@ Notice that \begin{code} mkDataConIds :: Name -> Name -> DataCon -> DataConIds - -- Makes the *worker* for the data constructor; that is, the function - -- that takes the reprsentation arguments and builds the constructor. mkDataConIds wrap_name wkr_name data_con | isNewTyCon tycon = NewDC nt_wrap_id | any isMarkedStrict all_strict_marks -- Algebraic, needs wrapper + || not (null eq_spec) = AlgDC (Just alg_wrap_id) wrk_id | otherwise -- Algebraic, no wrapper = AlgDC Nothing wrk_id where - (tyvars, theta, orig_arg_tys, tycon, res_tys) = dataConSig data_con + (univ_tvs, ex_tvs, eq_spec, theta, orig_arg_tys) = dataConFullSig data_con + tycon = dataConTyCon data_con - dict_tys = mkPredTys theta - all_arg_tys = dict_tys ++ orig_arg_tys - result_ty = mkTyConApp tycon res_tys - - wrap_ty = mkForAllTys tyvars (mkFunTys all_arg_tys result_ty) + ----------- 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. + wrap_tvs = (univ_tvs `minusList` map fst eq_spec) ++ ex_tvs + subst = mkTopTvSubst eq_spec + dict_tys = mkPredTys theta + result_ty_args = map (substTyVar subst) univ_tvs + result_ty = mkTyConApp tycon result_ty_args + wrap_ty = mkForAllTys wrap_tvs $ mkFunTys dict_tys $ + mkFunTys orig_arg_tys $ result_ty + -- NB: watch out here if you allow user-written equality + -- constraints in data constructor signatures ----------- Worker (algebraic data types only) -------------- + -- The *worker* for the data constructor is the function that + -- takes the representation arguments and builds the constructor. wrk_id = mkGlobalId (DataConWorkId data_con) wkr_name (dataConRepType data_con) wkr_info @@ -252,9 +268,10 @@ mkDataConIds wrap_name wkr_name 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 (...) - mkTopUnfolding $ Note InlineMe $ - mkLams tyvars $ Lam id_arg1 $ - mkNewTypeBody tycon result_ty (Var id_arg1) + mkCompulsoryUnfolding $ + mkLams wrap_tvs $ Lam id_arg1 $ + wrapNewTypeBody tycon result_ty_args + (Var id_arg1) id_arg1 = mkTemplateLocal 1 (head orig_arg_tys) @@ -282,14 +299,16 @@ mkDataConIds wrap_name wkr_name data_con -- we want to see that w is strict in its two arguments alg_unf = mkTopUnfolding $ Note InlineMe $ - mkLams tyvars $ + mkLams wrap_tvs $ mkLams dict_args $ mkLams id_args $ foldr mk_case con_app (zip (dict_args ++ id_args) all_strict_marks) i3 [] - con_app i rep_ids = mkApps (Var wrk_id) - (map varToCoreExpr (tyvars ++ reverse rep_ids)) + con_app i rep_ids = Var wrk_id `mkTyApps` result_ty_args + `mkVarApps` ex_tvs + `mkTyApps` map snd eq_spec + `mkVarApps` reverse rep_ids (dict_args,i2) = mkLocals 1 dict_tys (id_args,i3) = mkLocals i2 orig_arg_tys @@ -310,14 +329,9 @@ mkDataConIds wrap_name wkr_name data_con Case (Var arg) arg result_ty [(DEFAULT,[], body i (arg:rep_args))] MarkedUnboxed - -> case splitProductType "do_unbox" (idType arg) of - (tycon, tycon_args, con, tys) -> - Case (Var arg) arg result_ty - [(DataAlt con, - con_args, - body i' (reverse con_args ++ rep_args))] - where - (con_args, i') = mkLocals i tys + -> unboxProduct i (Var arg) (idType arg) the_body result_ty + where + the_body i con_args = body i (reverse con_args ++ rep_args) mAX_CPR_SIZE :: Arity mAX_CPR_SIZE = 10 @@ -391,11 +405,13 @@ We obviously can't define 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. -Hence the sel_naughty flag, to identify record selcectors that don't really exist. +Hence the sel_naughty flag, to identify record selectors that don't really exist. In general, a field is naughty if its type mentions a type variable that isn't in the result type of the constructor. +Note [GADT record selectors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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. @@ -413,10 +429,10 @@ type (e.g. 'b' in T2). \begin{code} --- XXX - autrijus - --- Plan: 1. Determine naughtiness by comparing field type vs result type --- 2. Install naughty ones with selector_ty of type _|_ and fill in mzero for info --- 3. If it's not naughty, do the normal plan. +-- Steps for handling "naughty" vs "non-naughty" selectors: +-- 1. Determine naughtiness by comparing field type vs result type +-- 2. Install naughty ones with selector_ty of type _|_ and fill in mzero for info +-- 3. If it's not naughty, do the normal plan. mkRecordSelId :: TyCon -> FieldLabel -> Id mkRecordSelId tycon field_label @@ -424,7 +440,7 @@ mkRecordSelId tycon field_label | is_naughty = naughty_id | otherwise = sel_id where - is_naughty = not (tyVarsOfType field_ty `subVarSet` tyvar_set) + is_naughty = not (tyVarsOfType field_ty `subVarSet` res_tv_set) sel_id_details = RecordSelId tycon field_label is_naughty -- Escapist case here for naughty construcotrs @@ -440,8 +456,8 @@ mkRecordSelId tycon field_label con1 = head data_cons_w_field res_tys = dataConResTys con1 - tyvar_set = tyVarsOfTypes res_tys - tyvars = varSetElems tyvar_set + res_tv_set = tyVarsOfTypes res_tys + res_tvs = varSetElems res_tv_set data_ty = mkTyConApp tycon res_tys field_ty = dataConFieldType con1 field_label @@ -456,7 +472,9 @@ mkRecordSelId tycon field_label stupid_dict_tys = mkPredTys (dataConsStupidTheta data_cons_w_field) n_stupid_dicts = length stupid_dict_tys - (field_tyvars,field_theta,field_tau) = tcSplitSigmaTy field_ty + (field_tyvars,pre_field_theta,field_tau) = tcSplitSigmaTy field_ty + + 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 @@ -475,7 +493,7 @@ mkRecordSelId tycon field_label -- op (R op) = op selector_ty :: Type - selector_ty = mkForAllTys tyvars $ mkForAllTys field_tyvars $ + selector_ty = mkForAllTys res_tvs $ mkForAllTys field_tyvars $ mkFunTys stupid_dict_tys $ mkFunTys field_dict_tys $ mkFunTy data_ty field_tau @@ -515,12 +533,14 @@ mkRecordSelId tycon field_label caf_info | no_default = NoCafRefs | otherwise = MayHaveCafRefs - sel_rhs = mkLams tyvars $ mkLams field_tyvars $ + sel_rhs = mkLams res_tvs $ mkLams field_tyvars $ mkLams stupid_dict_ids $ mkLams field_dict_ids $ - Lam data_id $ sel_body + Lam data_id $ mk_result sel_body - sel_body | isNewTyCon tycon = mk_result (mkNewTypeBody tycon field_ty (Var data_id)) - | otherwise = Case (Var data_id) data_id field_tau (default_alt ++ the_alts) + -- NB: A newtype always has a vanilla DataCon; no existentials etc + -- res_tys will simply be the dataConUnivTyVars + sel_body | isNewTyCon tycon = unwrapNewTypeBody tycon res_tys (Var data_id) + | otherwise = Case (Var data_id) data_id field_ty (default_alt ++ the_alts) mk_result poly_result = mkVarApps (mkVarApps poly_result field_tyvars) field_dict_ids -- We pull the field lambdas to the top, so we need to @@ -533,28 +553,122 @@ mkRecordSelId tycon field_label mk_alt data_con = -- In the non-vanilla case, the pattern must bind type variables and -- the context stuff; hence the arg_prefix binding below - mkReboxingAlt uniqs data_con (arg_prefix ++ arg_ids) - (mk_result (Var the_arg_id)) + mkReboxingAlt uniqs data_con (arg_prefix ++ arg_ids) rhs where (arg_prefix, arg_ids) | isVanillaDataCon data_con -- Instantiate from commmon base = ([], mkTemplateLocalsNum arg_base (dataConInstOrigArgTys data_con res_tys)) | otherwise -- The case pattern binds type variables, which are used -- in the types of the arguments of the pattern - = (dc_tyvars ++ mkTemplateLocalsNum arg_base (mkPredTys dc_theta), - mkTemplateLocalsNum arg_base' dc_arg_tys) + = (ex_tvs ++ co_tvs ++ dict_vs, field_vs) + + (ex_tvs, co_tvs, arg_vs) = dataConInstPat uniqs' data_con res_tys + (dict_vs, field_vs) = splitAt (length dc_theta) arg_vs + + (_, pre_dc_theta, dc_arg_tys) = dataConSig data_con + dc_theta = filter (not . isEqPred) pre_dc_theta - (dc_tyvars, dc_theta, dc_arg_tys, _, _) = dataConSig data_con arg_base' = arg_base + length dc_theta unpack_base = arg_base' + length dc_arg_tys - uniqs = map mkBuiltinUnique [unpack_base..] + + uniq_list = map mkBuiltinUnique [unpack_base..] + + Succeeded refinement = gadtRefine emptyRefinement ex_tvs co_tvs + (co_fn, out_ty) = refineType refinement (idType the_arg_id) + + rhs = ASSERT(out_ty `coreEqType` field_tau) perform_co co_fn (Var the_arg_id) + + perform_co (ExprCoFn co) expr = Cast expr co + perform_co id_co expr = ASSERT(isIdCoercion id_co) expr + + -- split the uniq_list into two + uniqs = takeHalf uniq_list + uniqs' = takeHalf (drop 1 uniq_list) + + takeHalf [] = [] + takeHalf (h:_:t) = h:(takeHalf t) + takeHalf (h:t) = [h] the_arg_id = assoc "mkRecordSelId:mk_alt" (field_lbls `zip` arg_ids) field_label field_lbls = dataConFieldLabels data_con error_expr = mkRuntimeErrorApp rEC_SEL_ERROR_ID field_tau full_msg - full_msg = showSDoc (sep [text "No match in record selector", ppr sel_id]) + full_msg = showSDoc (sep [text "No match in record selector", ppr sel_id]) + +-- unbox a product type... +-- we will recurse into newtypes, casting along the way, and unbox at the +-- first product data constructor we find. e.g. +-- +-- data PairInt = PairInt Int Int +-- newtype S = MkS PairInt +-- newtype T = MkT S +-- +-- If we have e = MkT (MkS (PairInt 0 1)) and some body expecting a list of +-- ids, we get (modulo int passing) +-- +-- case (e `cast` (sym CoT)) `cast` (sym CoS) of +-- PairInt a b -> body [a,b] +-- +-- The Ints passed around are just for creating fresh locals +unboxProduct :: Int -> CoreExpr -> Type -> (Int -> [Id] -> CoreExpr) -> Type -> CoreExpr +unboxProduct i arg arg_ty body res_ty + = result + where + result = mkUnpackCase the_id arg arg_ty con_args boxing_con rhs + (tycon, tycon_args, boxing_con, tys) = deepSplitProductType "unboxProduct" arg_ty + ([the_id], i') = mkLocals i [arg_ty] + (con_args, i'') = mkLocals i' tys + rhs = body i'' con_args + +mkUnpackCase :: Id -> CoreExpr -> Type -> [Id] -> DataCon -> CoreExpr -> CoreExpr +-- (mkUnpackCase x e args Con body) +-- returns +-- case (e `cast` ...) of bndr { Con args -> body } +-- +-- the type of the bndr passed in is irrelevent +mkUnpackCase bndr arg arg_ty unpk_args boxing_con body + = Case cast_arg (setIdType bndr bndr_ty) (exprType body) [(DataAlt boxing_con, unpk_args, body)] + where + (cast_arg, bndr_ty) = go (idType bndr) arg + go ty arg + | res@(tycon, tycon_args, _, _) <- splitProductType "mkUnpackCase" ty + , isNewTyCon tycon && not (isRecursiveTyCon tycon) + = go (newTyConInstRhs tycon tycon_args) + (unwrapNewTypeBody tycon tycon_args arg) + | otherwise = (arg, ty) + +-- ...and the dual +reboxProduct :: [Unique] -- uniques to create new local binders + -> Type -- type of product to box + -> ([Unique], -- remaining uniques + CoreExpr, -- boxed product + [Id]) -- Ids being boxed into product +reboxProduct us ty + = let + (tycon, tycon_args, pack_con, con_arg_tys) = deepSplitProductType "reboxProduct" ty + + us' = dropList con_arg_tys us + + arg_ids = zipWith (mkSysLocal FSLIT("rb")) us con_arg_tys + + bind_rhs = mkProductBox arg_ids ty + + in + (us', bind_rhs, arg_ids) + +mkProductBox :: [Id] -> Type -> CoreExpr +mkProductBox arg_ids ty + = result_expr + where + (tycon, tycon_args, pack_con, con_arg_tys) = splitProductType "mkProductBox" ty + + result_expr + | isNewTyCon tycon && not (isRecursiveTyCon tycon) + = wrap (mkProductBox arg_ids (newTyConInstRhs tycon tycon_args)) + | otherwise = mkConApp pack_con (map Type tycon_args ++ map Var arg_ids) + + wrap expr = wrapNewTypeBody tycon tycon_args expr -- (mkReboxingAlt us con xs rhs) basically constructs the case @@ -571,10 +685,10 @@ mkRecordSelId tycon field_label -- it manipulates CoreSyn. mkReboxingAlt - :: [Unique] -- Uniques for the new Ids + :: [Unique] -- Uniques for the new Ids -> DataCon - -> [Var] -- Source-level args, including existential dicts - -> CoreExpr -- RHS + -> [Var] -- Source-level args, including existential dicts + -> CoreExpr -- RHS -> CoreAlt mkReboxingAlt us con args rhs @@ -601,16 +715,11 @@ mkReboxingAlt us con args rhs -- Term variable case go (arg:args) (str:stricts) us | isMarkedUnboxed str - = let - (_, tycon_args, pack_con, con_arg_tys) - = splitProductType "mkReboxingAlt" (idType arg) - - unpacked_args = zipWith (mkSysLocal FSLIT("rb")) us con_arg_tys - (binds, args') = go args stricts (dropList con_arg_tys us) - con_app = mkConApp pack_con (map Type tycon_args ++ map Var unpacked_args) - in - (NonRec arg con_app : binds, unpacked_args ++ args') - + = + let (binds, unpacked_args') = go args stricts us' + (us', bind_rhs, unpacked_args) = reboxProduct us (idType arg) + in + (NonRec arg bind_rhs : binds, unpacked_args ++ unpacked_args') | otherwise = let (binds, args') = go args stricts us in (binds, arg:args') @@ -672,26 +781,46 @@ mkDictSelId name clas tycon = classTyCon clas [data_con] = tyConDataCons tycon - tyvars = dataConTyVars data_con - arg_tys = dataConRepArgTys data_con + 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) (dict_id:arg_ids) = mkTemplateLocals (mkPredTy pred : arg_tys) - rhs | isNewTyCon tycon = mkLams tyvars $ Lam dict_id $ - mkNewTypeBody tycon (head arg_tys) (Var dict_id) - | otherwise = mkLams tyvars $ Lam dict_id $ - Case (Var dict_id) dict_id (idType the_arg_id) - [(DataAlt data_con, arg_ids, Var the_arg_id)] - -mkNewTypeBody tycon result_ty result_expr - -- Adds a coerce where necessary - -- Used for both wrapping and unwrapping - | isRecursiveTyCon tycon -- Recursive case; use a coerce - = Note (Coerce result_ty (exprType result_expr)) result_expr - | otherwise -- Normal case + 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, arg_ids, Var the_arg_id)] + +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` 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 +-- e `cast` CoT [a] +-- +-- If a coercion constructor is prodivided in the newtype, then we use +-- it, otherwise the wrap/unwrap are both no-ops +-- +wrapNewTypeBody tycon args result_expr + | Just co_con <- newTyConCo tycon + = Cast result_expr (mkTyConApp co_con args) + | otherwise + = result_expr + +unwrapNewTypeBody :: TyCon -> [Type] -> CoreExpr -> CoreExpr +unwrapNewTypeBody tycon args result_expr + | Just co_con <- newTyConCo tycon + = Cast result_expr (mkSymCoercion (mkTyConApp co_con args)) + | otherwise = result_expr + + \end{code} @@ -855,18 +984,18 @@ unsafeCoerceName = mkWiredInIdName gHC_PRIM FSLIT("unsafeCoerce#") unsafeCoerceI 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 pREL_BASE FSLIT("lazy") lazyIdKey lazyId - -errorName = mkWiredInIdName pREL_ERR FSLIT("error") errorIdKey eRROR_ID -recSelErrorName = mkWiredInIdName pREL_ERR FSLIT("recSelError") recSelErrorIdKey rEC_SEL_ERROR_ID -runtimeErrorName = mkWiredInIdName pREL_ERR FSLIT("runtimeError") runtimeErrorIdKey rUNTIME_ERROR_ID -irrefutPatErrorName = mkWiredInIdName pREL_ERR FSLIT("irrefutPatError") irrefutPatErrorIdKey iRREFUT_PAT_ERROR_ID -recConErrorName = mkWiredInIdName pREL_ERR FSLIT("recConError") recConErrorIdKey rEC_CON_ERROR_ID -patErrorName = mkWiredInIdName pREL_ERR FSLIT("patError") patErrorIdKey pAT_ERROR_ID -noMethodBindingErrorName = mkWiredInIdName pREL_ERR FSLIT("noMethodBindingError") +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 +noMethodBindingErrorName = mkWiredInIdName gHC_ERR FSLIT("noMethodBindingError") noMethodBindingErrorIdKey nO_METHOD_BINDING_ERROR_ID nonExhaustiveGuardsErrorName - = mkWiredInIdName pREL_ERR FSLIT("nonExhaustiveGuardsError") + = mkWiredInIdName gHC_ERR FSLIT("nonExhaustiveGuardsError") nonExhaustiveGuardsErrorIdKey nON_EXHAUSTIVE_GUARDS_ERROR_ID \end{code} @@ -882,7 +1011,8 @@ unsafeCoerceId (mkFunTy openAlphaTy openBetaTy) [x] = mkTemplateLocals [openAlphaTy] rhs = mkLams [openAlphaTyVar,openBetaTyVar,x] $ - Note (Coerce openBetaTy openAlphaTy) (Var x) +-- Note (Coerce openBetaTy openAlphaTy) (Var x) + Cast (Var x) (mkUnsafeCoercion openAlphaTy openBetaTy) -- nullAddr# :: Addr# -- The reason is is here is because we don't provide @@ -902,22 +1032,26 @@ seqId ty = mkForAllTys [alphaTyVar,openBetaTyVar] (mkFunTy alphaTy (mkFunTy openBetaTy openBetaTy)) [x,y] = mkTemplateLocals [alphaTy, openBetaTy] --- gaw 2004 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 --- No unfolding: it gets "inlined" by the worker/wrapper pass --- Also, no strictness: by being a built-in Id, it overrides all --- the info in PrelBase.hi. This is important, because the strictness +-- +-- 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/wrapper pass +-- (see WorkWrap.wwExpr) +-- 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 = pcMiscPrelId lazyIdName ty info where info = noCafIdInfo ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy alphaTy) -lazyIdUnfolding :: CoreExpr -- Used to expand LazyOp after strictness anal +lazyIdUnfolding :: CoreExpr -- Used to expand 'lazyId' after strictness anal lazyIdUnfolding = mkLams [openAlphaTyVar,x] (Var x) where [x] = mkTemplateLocals [openAlphaTy]