X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FdeSugar%2FDsExpr.lhs;h=164316cf99d07c8a85885dca8873cb4d2ee1a8ad;hb=04feba252e40d16101b92948cd1e13c7bc1f3062;hp=6dc8f22d224adc2cdf6bb960999c2d0744ebf1ba;hpb=4a5870490196e05c40a9362ac2fef0081567bffc;p=ghc-hetmet.git diff --git a/ghc/compiler/deSugar/DsExpr.lhs b/ghc/compiler/deSugar/DsExpr.lhs index 6dc8f22..164316c 100644 --- a/ghc/compiler/deSugar/DsExpr.lhs +++ b/ghc/compiler/deSugar/DsExpr.lhs @@ -4,14 +4,14 @@ \section[DsExpr]{Matching expressions (Exprs)} \begin{code} -module DsExpr ( dsExpr, dsLExpr, dsLet, dsLit ) where +module DsExpr ( dsExpr, dsLExpr, dsLocalBinds, dsValBinds, dsLit ) where #include "HsVersions.h" import Match ( matchWrapper, matchSimply, matchSinglePat ) import MatchLit ( dsLit, dsOverLit ) -import DsBinds ( dsHsNestedBinds ) +import DsBinds ( dsLHsBinds, dsCoercion ) import DsGRHSs ( dsGuarded ) import DsListComp ( dsListComp, dsPArrComp ) import DsUtils ( mkErrorAppDs, mkStringExpr, mkConsExpr, mkNilExpr, @@ -26,7 +26,7 @@ import DsMeta ( dsBracket ) #endif import HsSyn -import TcHsSyn ( hsPatType ) +import TcHsSyn ( hsPatType, mkVanillaTuplePat ) -- NB: The desugarer, which straddles the source and Core worlds, sometimes -- needs to see source types (newtypes etc), and sometimes not @@ -76,24 +76,34 @@ This must be transformed to a case expression and, if the type has more than one constructor, may fail. \begin{code} -dsLet :: [HsBindGroup Id] -> CoreExpr -> DsM CoreExpr -dsLet groups body = foldlDs dsBindGroup body (reverse groups) - -dsBindGroup :: CoreExpr -> HsBindGroup Id -> DsM CoreExpr -dsBindGroup body (HsIPBinds binds) - = foldlDs dsIPBind body binds +dsLocalBinds :: HsLocalBinds Id -> CoreExpr -> DsM CoreExpr +dsLocalBinds EmptyLocalBinds body = return body +dsLocalBinds (HsValBinds binds) body = dsValBinds binds body +dsLocalBinds (HsIPBinds binds) body = dsIPBinds binds body + +------------------------- +dsValBinds :: HsValBinds Id -> CoreExpr -> DsM CoreExpr +dsValBinds (ValBindsOut binds _) body = foldrDs ds_val_bind body binds + +------------------------- +dsIPBinds (IPBinds ip_binds dict_binds) body + = do { prs <- dsLHsBinds dict_binds + ; let inner = foldr (\(x,r) e -> Let (NonRec x r) e) body prs + ; foldrDs ds_ip_bind inner ip_binds } where - dsIPBind body (L _ (IPBind n e)) - = dsLExpr e `thenDs` \ e' -> - returnDs (Let (NonRec (ipNameName n) e') body) + ds_ip_bind (L _ (IPBind n e)) body + = dsLExpr e `thenDs` \ e' -> + returnDs (Let (NonRec (ipNameName n) e') body) +------------------------- +ds_val_bind :: (RecFlag, LHsBinds Id) -> CoreExpr -> DsM CoreExpr -- Special case for bindings which bind unlifted variables -- We need to do a case right away, rather than building -- a tuple and doing selections. --- Silently ignore INLINE pragmas... -dsBindGroup body bind@(HsBindGroup hsbinds sigs is_rec) - | [L _ (AbsBinds [] [] exports inlines binds)] <- bagToList hsbinds, - or [isUnLiftedType (idType g) | (_, g, l) <- exports] +-- Silently ignore INLINE and SPECIALISE pragmas... +ds_val_bind (is_rec, hsbinds) body + | [L _ (AbsBinds [] [] exports binds)] <- bagToList hsbinds, + or [isUnLiftedType (idType g) | (_, g, _, _) <- exports] = ASSERT (case is_rec of {NonRecursive -> True; other -> False}) -- Unlifted bindings are always non-recursive -- and are always a Fun or Pat monobind @@ -102,32 +112,33 @@ dsBindGroup body bind@(HsBindGroup hsbinds sigs is_rec) -- could be dict binds in the 'binds'. (See the notes -- below. Then pattern-match would fail. Urk.) let - body_w_exports = foldr bind_export body exports - bind_export (tvs, g, l) body = ASSERT( null tvs ) - bindNonRec g (Var l) body + body_w_exports = foldr bind_export body exports + bind_export (tvs, g, l, _) body = ASSERT( null tvs ) + bindNonRec g (Var l) body mk_error_app pat = mkErrorAppDs iRREFUT_PAT_ERROR_ID (exprType body) (showSDoc (ppr pat)) in case bagToList binds of - [L loc (FunBind (L _ fun) _ matches)] + [L loc (FunBind { fun_id = L _ fun, fun_matches = matches, fun_co_fn = co_fn })] -> putSrcSpanDs loc $ matchWrapper (FunRhs (idName fun)) matches `thenDs` \ (args, rhs) -> ASSERT( null args ) -- Functions aren't lifted + ASSERT( isIdCoercion co_fn ) returnDs (bindNonRec fun rhs body_w_exports) - [L loc (PatBind pat grhss ty)] + [L loc (PatBind {pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty })] -> putSrcSpanDs loc $ dsGuarded grhss ty `thenDs` \ rhs -> mk_error_app pat `thenDs` \ error_expr -> matchSimply rhs PatBindRhs pat body_w_exports error_expr - other -> pprPanic "dsLet: unlifted" (ppr bind $$ ppr body) + other -> pprPanic "dsLet: unlifted" (pprLHsBinds hsbinds $$ ppr body) -- Ordinary case for bindings -dsBindGroup body (HsBindGroup binds sigs is_rec) - = dsHsNestedBinds binds `thenDs` \ prs -> +ds_val_bind (is_rec, binds) body + = dsLHsBinds binds `thenDs` \ prs -> returnDs (Let (Rec prs) body) -- Use a Rec regardless of is_rec. -- Why? Because it allows the binds to be all @@ -247,14 +258,29 @@ dsExpr (HsCoreAnn fs expr) returnDs (Note (CoreNote $ unpackFS fs) core_expr) -- Special case to handle unboxed tuple patterns; they can't appear nested +-- The idea is that +-- case e of (# p1, p2 #) -> rhs +-- should desugar to +-- case e of (# x1, x2 #) -> ... match p1, p2 ... +-- NOT +-- let x = e in case x of .... +-- +-- But there may be a big +-- let fail = ... in case e of ... +-- wrapping the whole case, which complicates matters slightly +-- It all seems a bit fragile. Test is dsrun013. + dsExpr (HsCase discrim matches@(MatchGroup _ ty)) | isUnboxedTupleType (funArgTy ty) = dsLExpr discrim `thenDs` \ core_discrim -> matchWrapper CaseAlt matches `thenDs` \ ([discrim_var], matching_code) -> - case matching_code of - Case (Var x) bndr ty alts | x == discrim_var -> - returnDs (Case core_discrim bndr ty alts) - _ -> panic ("dsLExpr: tuple pattern:\n" ++ showSDoc (ppr matching_code)) + let + scrungle (Case (Var x) bndr ty alts) + | x == discrim_var = Case core_discrim bndr ty alts + scrungle (Let binds body) = Let binds (scrungle body) + scrungle other = panic ("dsLExpr: tuple pattern:\n" ++ showSDoc (ppr other)) + in + returnDs (scrungle matching_code) dsExpr (HsCase discrim matches) = dsLExpr discrim `thenDs` \ core_discrim -> @@ -263,7 +289,7 @@ dsExpr (HsCase discrim matches) dsExpr (HsLet binds body) = dsLExpr body `thenDs` \ body' -> - dsLet binds body' + dsLocalBinds binds body' -- We need the `ListComp' form to use `deListComp' (rather than the "do" form) -- because the interpretation of `stmts' depends on what sort of thing it is. @@ -474,7 +500,7 @@ dsExpr expr@(RecordUpd record_expr rbinds record_in_ty record_out_ty) mk_alt con = newSysLocalsDs (dataConInstOrigArgTys con in_inst_tys) `thenDs` \ arg_ids -> - -- This call to dataConArgTys won't work for existentials + -- This call to dataConInstOrigArgTys won't work for existentials -- but existentials don't have record types anyway let val_args = zipWithEqual "dsExpr:RecordUpd" mk_val_arg @@ -538,6 +564,8 @@ dsExpr (DictLam dictvars expr) dsExpr (DictApp expr dicts) -- becomes a curried application = dsLExpr expr `thenDs` \ core_expr -> returnDs (foldl (\f d -> f `App` (Var d)) core_expr dicts) + +dsExpr (HsCoerce co_fn e) = dsCoercion co_fn (dsExpr e) \end{code} Here is where we desugar the Template Haskell brackets and escapes @@ -589,7 +617,7 @@ dsDo stmts body result_ty go (LetStmt binds : stmts) = do { rest <- go stmts - ; dsLet binds rest } + ; dsLocalBinds binds rest } go (BindStmt pat rhs bind_op fail_op : stmts) = do { body <- go stmts @@ -644,7 +672,7 @@ dsMDo tbl stmts body result_ty go (LetStmt binds : stmts) = do { rest <- go stmts - ; dsLet binds rest } + ; dsLocalBinds binds rest } go (ExprStmt rhs _ rhs_ty : stmts) = do { rhs2 <- dsLExpr rhs @@ -670,7 +698,7 @@ dsMDo tbl stmts body result_ty go (new_bind_stmt : let_stmt : stmts) where new_bind_stmt = mkBindStmt (mk_tup_pat later_pats) mfix_app - let_stmt = LetStmt [HsBindGroup binds [] Recursive] + let_stmt = LetStmt (HsValBinds (ValBindsOut [(Recursive, binds)] [])) -- Remove the later_ids that appear (without fancy coercions) @@ -708,7 +736,7 @@ dsMDo tbl stmts body result_ty mk_tup_pat :: [LPat Id] -> LPat Id mk_tup_pat [p] = p - mk_tup_pat ps = noLoc $ TuplePat ps Boxed + mk_tup_pat ps = noLoc $ mkVanillaTuplePat ps Boxed mk_ret_tup :: [LHsExpr Id] -> LHsExpr Id mk_ret_tup [r] = r