X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FdeSugar%2FDsUtils.lhs;h=579062820dbd739c9d773867414881ed2b3e429d;hb=dabfa71f33eabc5a2d10959728f772aa016f1c84;hp=07cbe0b249279e78b7049369e09e04a2da175679;hpb=0596517a9b4b2b32e5d375a986351102ac4540fc;p=ghc-hetmet.git diff --git a/ghc/compiler/deSugar/DsUtils.lhs b/ghc/compiler/deSugar/DsUtils.lhs index 07cbe0b..5790628 100644 --- a/ghc/compiler/deSugar/DsUtils.lhs +++ b/ghc/compiler/deSugar/DsUtils.lhs @@ -15,7 +15,7 @@ module DsUtils ( combineMatchResults, dsExprToAtom, mkCoAlgCaseMatchResult, - mkAppDs, mkConDs, mkPrimDs, + mkAppDs, mkConDs, mkPrimDs, mkErrorAppDs, mkCoLetsMatchResult, mkCoPrimCaseMatchResult, mkFailurePair, @@ -23,7 +23,8 @@ module DsUtils ( mkSelectorBinds, mkTupleBind, mkTupleExpr, - selectMatchVars + selectMatchVars, + showForErr ) where import Ubiq @@ -37,20 +38,26 @@ import CoreSyn import DsMonad -import CoreUtils ( coreExprType, escErrorMsg, mkCoreIfThenElse, mkErrorApp ) -import PrelInfo ( stringTy ) -import Id ( idType, getInstantiatedDataConSig, mkTupleCon, +import CoreUtils ( coreExprType, mkCoreIfThenElse ) +import PprStyle ( PprStyle(..) ) +import PrelVals ( iRREFUT_PAT_ERROR_ID ) +import Pretty ( ppShow ) +import Id ( idType, dataConArgTys, mkTupleCon, + pprId{-ToDo:rm-}, DataCon(..), DictVar(..), Id(..), GenId ) -import TyCon ( mkTupleTyCon ) -import Type ( mkTyVarTys, mkRhoTy, mkFunTys, - applyTyCon, getAppDataTyCon ) +import Literal ( Literal(..) ) +import TyCon ( mkTupleTyCon, isNewTyCon, tyConDataCons ) +import Type ( mkTyVarTys, mkRhoTy, mkForAllTys, mkFunTys, + mkTheta, isUnboxedType, applyTyCon, getAppTyCon + ) import UniqSet ( mkUniqSet, minusUniqSet, uniqSetToList, UniqSet(..) ) -import Util ( panic, assertPanic ) - -isUnboxedDataType = panic "DsUtils.isUnboxedDataType" -quantifyTy = panic "DsUtils.quantifyTy" -splitDictType = panic "DsUtils.splitDictType" -mkCoTyApps = panic "DsUtils.mkCoTyApps" +import Util ( panic, assertPanic, pprTrace{-ToDo:rm-} ) +import PprCore{-ToDo:rm-} +--import PprType--ToDo:rm +import Pretty--ToDo:rm +import TyVar--ToDo:rm +import Unique--ToDo:rm +import Usage--ToDo:rm \end{code} %************************************************************************ @@ -127,7 +134,13 @@ mkCoPrimCaseMatchResult var alts mkCoAlgCaseMatchResult :: Id -- Scrutinee -> [(DataCon, [Id], MatchResult)] -- Alternatives -> DsM MatchResult + mkCoAlgCaseMatchResult var alts + | isNewTyCon tycon -- newtype case; use a let + = ASSERT( newtype_sanity ) + returnDs (mkCoLetsMatchResult [coercion_bind] match_result) + + | otherwise -- datatype case = -- Find all the constructors in the type which aren't -- explicitly mentioned in the alternatives: case un_mentioned_constructors of @@ -141,7 +154,7 @@ mkCoAlgCaseMatchResult var alts -- We need to build new locals for the args of the constructor, -- and figuring out their types is somewhat tiresome. let - (_,arg_tys,_) = getInstantiatedDataConSig con tycon_arg_tys + arg_tys = dataConArgTys con tycon_arg_tys in newSysLocalsDs arg_tys `thenDs` \ arg_ids -> @@ -161,8 +174,21 @@ mkCoAlgCaseMatchResult var alts (mk_case alts (\fail_expr -> BindDefault wild fail_expr)) cxt1) where + -- Common stuff scrut_ty = idType var - (tycon, tycon_arg_tys, data_cons) = getAppDataTyCon scrut_ty + (tycon, tycon_arg_tys) = --pprTrace "CoAlgCase:" (pprType PprDebug scrut_ty) $ + getAppTyCon scrut_ty + + -- Stuff for newtype + (con_id, arg_ids, match_result) = head alts + arg_id = head arg_ids + coercion_bind = NonRec arg_id (Coerce (CoerceOut con_id) + (idType arg_id) + (Var var)) + newtype_sanity = null (tail alts) && null (tail arg_ids) + + -- Stuff for data types + data_cons = tyConDataCons tycon un_mentioned_constructors = uniqSetToList (mkUniqSet data_cons `minusUniqSet` mkUniqSet [ con | (con, _, _) <- alts] ) @@ -228,7 +254,7 @@ dsExprToAtom arg_expr continue_with newSysLocalDs ty `thenDs` \ arg_id -> continue_with (VarArg arg_id) `thenDs` \ body -> returnDs ( - if isUnboxedDataType ty + if isUnboxedType ty then Case arg_expr (PrimAlts [] (BindDefault arg_id body)) else Let (NonRec arg_id arg_expr) body ) @@ -252,8 +278,6 @@ dsExprsToAtoms (arg:args) continue_with %* * %************************************************************************ -Plumb the desugarer's @UniqueSupply@ in/out of the @UniqSupply@ monad -world. \begin{code} mkAppDs :: CoreExpr -> [Type] -> [CoreExpr] -> DsM CoreExpr mkConDs :: Id -> [Type] -> [CoreExpr] -> DsM CoreExpr @@ -272,6 +296,24 @@ mkPrimDs op tys arg_exprs returnDs (mkPrim op [] tys vals) \end{code} +\begin{code} +showForErr :: Outputable a => a -> String -- Boring but useful +showForErr thing = ppShow 80 (ppr PprForUser thing) + +mkErrorAppDs :: Id -- The error function + -> Type -- Type to which it should be applied + -> String -- The error message string to pass + -> DsM CoreExpr + +mkErrorAppDs err_id ty msg + = getSrcLocDs `thenDs` \ (file, line) -> + let + full_msg = file ++ "|" ++ line ++ "|" ++msg + msg_lit = NoRepStr (_PK_ full_msg) + in + returnDs (mkApp (Var err_id) [] [ty] [LitArg msg_lit]) +\end{code} + %************************************************************************ %* * \subsection[mkSelectorBind]{Make a selector bind} @@ -303,17 +345,10 @@ mkSelectorBinds :: [TyVar] -- Variables wrt which the pattern is polymorphic -> DsM [(Id,CoreExpr)] mkSelectorBinds tyvars pat locals_and_globals val_expr - = getSrcLocDs `thenDs` \ (src_file, src_line) -> - - if is_simple_tuple_pat pat then + = if is_simple_tuple_pat pat then mkTupleBind tyvars [] locals_and_globals val_expr else - newSysLocalDs stringTy `thenDs` \ str_var -> -- to hold the string - let - src_loc_str = escErrorMsg ('"' : src_file) ++ "%l" ++ src_line - error_string = src_loc_str ++ "%~" --> ": pattern-match failed on an irrefutable pattern" - error_msg = mkErrorApp res_ty str_var error_string - in + mkErrorAppDs iRREFUT_PAT_ERROR_ID res_ty "" `thenDs` \ error_msg -> matchSimply val_expr pat res_ty local_tuple error_msg `thenDs` \ tuple_expr -> mkTupleBind tyvars [] locals_and_globals tuple_expr where @@ -384,7 +419,9 @@ The general case: \begin{code} mkTupleBind tyvars dicts local_global_prs tuple_expr - = newSysLocalDs tuple_var_ty `thenDs` \ tuple_var -> + = --pprTrace "mkTupleBind:\n" (ppAboves [ppCat (map (pprId PprShowAll) locals), ppCat (map (pprId PprShowAll) globals), {-ppr PprDebug local_tuple, pprType PprDebug res_ty,-} ppr PprDebug tuple_expr]) $ + + newSysLocalDs tuple_var_ty `thenDs` \ tuple_var -> zipWithDs (mk_selector (Var tuple_var)) local_global_prs @@ -404,12 +441,12 @@ mkTupleBind tyvars dicts local_global_prs tuple_expr tuple_var_ty :: Type tuple_var_ty - = case (quantifyTy tyvars (mkRhoTy theta - (applyTyCon (mkTupleTyCon no_of_binders) - (map idType locals)))) of - (_{-tossed templates-}, ty) -> ty + = mkForAllTys tyvars $ + mkRhoTy theta $ + applyTyCon (mkTupleTyCon no_of_binders) + (map idType locals) where - theta = map (splitDictType . idType) dicts + theta = mkTheta (map idType dicts) mk_selector :: CoreExpr -> (Id, Id) -> Int -> DsM (Id, CoreExpr) @@ -421,17 +458,14 @@ mkTupleBind tyvars dicts local_global_prs tuple_expr returnDs ( global, mkLam tyvars dicts ( - mkTupleSelector (mkApp_XX (mkCoTyApps tuple_var_expr tyvar_tys) dicts) - binders selected) + mkTupleSelector + (mkValApp (mkTyApp tuple_var_expr tyvar_tys) + (map VarArg dicts)) + binders + selected) ) - -mkApp_XX :: CoreExpr -> [Id] -> CoreExpr -mkApp_XX expr [] = expr -mkApp_XX expr (id:ids) = mkApp_XX (App expr (VarArg id)) ids \end{code} - - @mkTupleExpr@ builds a tuple; the inverse to @mkTupleSelector@. If it has only one element, it is the identity function. \begin{code} @@ -537,7 +571,7 @@ mkFailurePair :: Type -- Result type of the whole case expression CoreExpr) -- Either the fail variable, or fail variable -- applied to unit tuple mkFailurePair ty - | isUnboxedDataType ty + | isUnboxedType ty = newFailLocalDs (mkFunTys [unit_ty] ty) `thenDs` \ fail_fun_var -> newSysLocalDs unit_ty `thenDs` \ fail_fun_arg -> returnDs (\ body ->