X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FdeSugar%2FDsGRHSs.lhs;h=33f86edcf90b3c69bcd101f408f35d08b133865a;hb=63539f9d057f2143ea395da99584bc898b321c9b;hp=b14e264d4005231425a57a4204085ef9a0fa54f6;hpb=861e836ed0cc1aa45932ecb3470967964440a0ef;p=ghc-hetmet.git diff --git a/ghc/compiler/deSugar/DsGRHSs.lhs b/ghc/compiler/deSugar/DsGRHSs.lhs index b14e264..33f86ed 100644 --- a/ghc/compiler/deSugar/DsGRHSs.lhs +++ b/ghc/compiler/deSugar/DsGRHSs.lhs @@ -8,18 +8,23 @@ module DsGRHSs ( dsGuarded, dsGRHSs ) where #include "HsVersions.h" -import {-# SOURCE #-} DsExpr ( dsExpr, dsLet ) +import {-# SOURCE #-} DsExpr ( dsLExpr, dsLocalBinds ) import {-# SOURCE #-} Match ( matchSinglePat ) -import HsSyn ( Stmt(..), HsExpr(..), GRHSs(..), GRHS(..) ) -import TcHsSyn ( TypecheckedGRHSs, TypecheckedPat, TypecheckedStmt ) +import HsSyn ( Stmt(..), HsExpr(..), GRHSs(..), GRHS(..), + LHsExpr, HsMatchContext(..), Pat(..) ) import CoreSyn ( CoreExpr ) +import Var ( Id ) import Type ( Type ) import DsMonad import DsUtils +import Unique ( Uniquable(..) ) import PrelInfo ( nON_EXHAUSTIVE_GUARDS_ERROR_ID ) -import PrelNames ( otherwiseIdKey, trueDataConKey, hasKey ) +import TysWiredIn ( trueDataConId ) +import PrelNames ( otherwiseIdKey, hasKey ) +import Name ( Name ) +import SrcLoc ( unLoc, Located(..) ) \end{code} @dsGuarded@ is used for both @case@ expressions and pattern bindings. @@ -34,32 +39,33 @@ producing an expression with a runtime error in the corner if necessary. The type argument gives the type of the @ei@. \begin{code} -dsGuarded :: TypecheckedGRHSs -> DsM CoreExpr +dsGuarded :: GRHSs Id -> Type -> DsM CoreExpr -dsGuarded grhss - = dsGRHSs PatBindMatch [] grhss `thenDs` \ (err_ty, match_result) -> - mkErrorAppDs nON_EXHAUSTIVE_GUARDS_ERROR_ID err_ty "" `thenDs` \ error_expr -> +dsGuarded grhss rhs_ty + = dsGRHSs PatBindRhs [] grhss rhs_ty `thenDs` \ match_result -> + mkErrorAppDs nON_EXHAUSTIVE_GUARDS_ERROR_ID rhs_ty "" `thenDs` \ error_expr -> extractMatchResult match_result error_expr \end{code} In contrast, @dsGRHSs@ produces a @MatchResult@. \begin{code} -dsGRHSs :: DsMatchKind -> [TypecheckedPat] -- These are to build a MatchContext from - -> TypecheckedGRHSs -- Guarded RHSs - -> DsM (Type, MatchResult) +dsGRHSs :: HsMatchContext Name -> [Pat Id] -- These are to build a MatchContext from + -> GRHSs Id -- Guarded RHSs + -> Type -- Type of RHS + -> DsM MatchResult -dsGRHSs kind pats (GRHSs grhss binds (Just ty)) - = mapDs (dsGRHS kind pats) grhss `thenDs` \ match_results -> +dsGRHSs hs_ctx pats (GRHSs grhss binds) rhs_ty + = mappM (dsGRHS hs_ctx pats rhs_ty) grhss `thenDs` \ match_results -> let match_result1 = foldr1 combineMatchResults match_results - match_result2 = adjustMatchResultDs (dsLet binds) match_result1 + match_result2 = adjustMatchResultDs (dsLocalBinds binds) match_result1 -- NB: nested dsLet inside matchResult in - returnDs (ty, match_result2) + returnDs match_result2 -dsGRHS kind pats (GRHS guard locn) - = matchGuard guard (DsMatchContext kind pats locn) +dsGRHS hs_ctx pats rhs_ty (L loc (GRHS guards rhs)) + = matchGuards (map unLoc guards) hs_ctx rhs rhs_ty \end{code} @@ -70,34 +76,45 @@ dsGRHS kind pats (GRHS guard locn) %************************************************************************ \begin{code} -matchGuard :: [TypecheckedStmt] -- Guard - -> DsMatchContext -- Context - -> DsM MatchResult +matchGuards :: [Stmt Id] -- Guard + -> HsMatchContext Name -- Context + -> LHsExpr Id -- RHS + -> Type -- Type of RHS of guard + -> DsM MatchResult -matchGuard (ExprStmt expr locn : should_be_null) ctx - = putSrcLocDs locn (dsExpr expr) `thenDs` \ core_expr -> - returnDs (cantFailMatchResult core_expr) +-- See comments with HsExpr.Stmt re what an ExprStmt means +-- Here we must be in a guard context (not do-expression, nor list-comp) +matchGuards [] ctx rhs rhs_ty + = do { core_rhs <- dsLExpr rhs + ; return (cantFailMatchResult core_rhs) } + + -- ExprStmts must be guards -- Turn an "otherwise" guard is a no-op -matchGuard (GuardStmt (HsVar v) _ : stmts) ctx +matchGuards (ExprStmt (L _ (HsVar v)) _ _ : stmts) ctx rhs rhs_ty | v `hasKey` otherwiseIdKey - || v `hasKey` trueDataConKey - = matchGuard stmts ctx - -matchGuard (GuardStmt expr locn : stmts) ctx - = matchGuard stmts ctx `thenDs` \ match_result -> - putSrcLocDs locn (dsExpr expr) `thenDs` \ pred_expr -> + || v `hasKey` getUnique trueDataConId + -- trueDataConId doesn't have the same + -- unique as trueDataCon + = matchGuards stmts ctx rhs rhs_ty + +matchGuards (ExprStmt expr _ _ : stmts) ctx rhs rhs_ty + = matchGuards stmts ctx rhs rhs_ty `thenDs` \ match_result -> + dsLExpr expr `thenDs` \ pred_expr -> returnDs (mkGuardedMatchResult pred_expr match_result) -matchGuard (LetStmt binds : stmts) ctx - = matchGuard stmts ctx `thenDs` \ match_result -> - returnDs (adjustMatchResultDs (dsLet binds) match_result) +matchGuards (LetStmt binds : stmts) ctx rhs rhs_ty + = matchGuards stmts ctx rhs rhs_ty `thenDs` \ match_result -> + returnDs (adjustMatchResultDs (dsLocalBinds binds) match_result) -- NB the dsLet occurs inside the match_result - -matchGuard (BindStmt pat rhs locn : stmts) ctx - = matchGuard stmts ctx `thenDs` \ match_result -> - putSrcLocDs locn (dsExpr rhs) `thenDs` \ core_rhs -> - matchSinglePat core_rhs ctx pat match_result + -- Reason: dsLet takes the body expression as its argument + -- so we can't desugar the bindings without the + -- body expression in hand + +matchGuards (BindStmt pat bind_rhs _ _ : stmts) ctx rhs rhs_ty + = matchGuards stmts ctx rhs rhs_ty `thenDs` \ match_result -> + dsLExpr bind_rhs `thenDs` \ core_rhs -> + matchSinglePat core_rhs ctx pat rhs_ty match_result \end{code} Should {\em fail} if @e@ returns @D@