Ticket #4359: multi-way-if.patch
| File multi-way-if.patch, 23.5 KB (added by mikhail.vorozhtsov, 10 months ago) |
|---|
-
compiler/deSugar/Coverage.lhs
From a319af507c27c67167fca95010b1aa7399ec30dc Mon Sep 17 00:00:00 2001 From: Mikhail Vorozhtsov <mikhail.vorozhtsov@gmail.com> Date: Sun, 15 Jul 2012 00:53:52 +0700 Subject: [PATCH] Implemented MultiWayIf extension. --- compiler/deSugar/Coverage.lhs | 5 +++ compiler/deSugar/DsExpr.lhs | 13 +++++++ compiler/deSugar/DsGRHSs.lhs | 10 +++--- compiler/deSugar/DsMeta.hs | 73 ++++++++++++++++++++++----------------- compiler/deSugar/Match.lhs | 1 + compiler/hsSyn/Convert.lhs | 4 +++ compiler/hsSyn/HsExpr.lhs | 12 +++++++ compiler/main/DynFlags.hs | 2 ++ compiler/parser/Lexer.x | 5 +++ compiler/parser/Parser.y.pp | 11 +++++- compiler/rename/RnBinds.lhs | 2 +- compiler/rename/RnExpr.lhs | 6 +++- compiler/typecheck/TcExpr.lhs | 5 +++ compiler/typecheck/TcHsSyn.lhs | 9 +++++ compiler/typecheck/TcMatches.lhs | 8 ++--- docs/users_guide/flags.xml | 6 ++++ docs/users_guide/glasgow_exts.xml | 21 +++++++++++ 17 files changed, 149 insertions(+), 44 deletions(-) diff --git a/compiler/deSugar/Coverage.lhs b/compiler/deSugar/Coverage.lhs index 28d83c9..ff3cfc5 100644
a b 423 423 isGoodBreakExpr (OpApp {}) = True 424 424 isGoodBreakExpr (NegApp {}) = True 425 425 isGoodBreakExpr (HsIf {}) = True 426 isGoodBreakExpr (HsMultiIf {}) = True 426 427 isGoodBreakExpr (HsCase {}) = True 427 428 isGoodBreakExpr (RecordCon {}) = True 428 429 isGoodBreakExpr (RecordUpd {}) = True … … 496 497 (addBinTickLHsExpr (BinBox CondBinBox) e1) 497 498 (addTickLHsExprOptAlt True e2) 498 499 (addTickLHsExprOptAlt True e3) 500 addTickHsExpr (HsMultiIf ty alts) 501 = do { let isOneOfMany = case alts of [_] -> False; _ -> True 502 ; alts' <- mapM (liftL $ addTickGRHS isOneOfMany False) alts 503 ; return $ HsMultiIf ty alts' } 499 504 addTickHsExpr (HsLet binds e) = 500 505 bindLocals (collectLocalBinders binds) $ 501 506 liftM2 HsLet -
compiler/deSugar/DsExpr.lhs
diff --git a/compiler/deSugar/DsExpr.lhs b/compiler/deSugar/DsExpr.lhs index 4795b5f..f8bd213 100644
a b 337 337 Just fun -> do { core_fun <- dsExpr fun 338 338 ; return (mkCoreApps core_fun [pred,b1,b2]) } 339 339 Nothing -> return $ mkIfThenElse pred b1 b2 } 340 341 dsExpr (HsMultiIf res_ty alts) 342 | null alts 343 = mkErrorExpr 344 345 | otherwise 346 = do { match_result <- liftM (foldr1 combineMatchResults) 347 (mapM (dsGRHS IfAlt res_ty) alts) 348 ; error_expr <- mkErrorExpr 349 ; extractMatchResult match_result error_expr } 350 where 351 mkErrorExpr = mkErrorAppDs nON_EXHAUSTIVE_GUARDS_ERROR_ID res_ty 352 (ptext (sLit "multi-way if")) 340 353 \end{code} 341 354 342 355 -
compiler/deSugar/DsGRHSs.lhs
diff --git a/compiler/deSugar/DsGRHSs.lhs b/compiler/deSugar/DsGRHSs.lhs index ed87d18..9e84e46 100644
a b 6 6 Matching guarded right-hand-sides (GRHSs) 7 7 8 8 \begin{code} 9 module DsGRHSs ( dsGuarded, dsGRHSs ) where9 module DsGRHSs ( dsGuarded, dsGRHSs, dsGRHS ) where 10 10 11 11 #include "HsVersions.h" 12 12 … … 55 55 -> GRHSs Id -- Guarded RHSs 56 56 -> Type -- Type of RHS 57 57 -> DsM MatchResult 58 dsGRHSs hs_ctx pats(GRHSs grhss binds) rhs_ty = do59 match_results <- mapM (dsGRHS hs_ctx patsrhs_ty) grhss58 dsGRHSs hs_ctx _ (GRHSs grhss binds) rhs_ty = do 59 match_results <- mapM (dsGRHS hs_ctx rhs_ty) grhss 60 60 let 61 61 match_result1 = foldr1 combineMatchResults match_results 62 62 match_result2 = adjustMatchResultDs … … 66 66 -- 67 67 return match_result2 68 68 69 dsGRHS :: HsMatchContext Name -> [Pat Id] ->Type -> LGRHS Id -> DsM MatchResult70 dsGRHS hs_ctx _rhs_ty (L _ (GRHS guards rhs))69 dsGRHS :: HsMatchContext Name -> Type -> LGRHS Id -> DsM MatchResult 70 dsGRHS hs_ctx rhs_ty (L _ (GRHS guards rhs)) 71 71 = matchGuards (map unLoc guards) (PatGuard hs_ctx) rhs rhs_ty 72 72 \end{code} 73 73 -
compiler/deSugar/DsMeta.hs
diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs index 7a60ae4..4d07c8c 100644
a b 890 890 b <- repLE y 891 891 c <- repLE z 892 892 repCond a b c 893 repE (HsMultiIf _ alts) 894 = do { (binds, alts') <- liftM unzip $ mapM repLGRHS alts 895 ; expr' <- repMultiIf (nonEmptyCoreList alts') 896 ; wrapGenSyms (concat binds) expr' } 893 897 repE (HsLet bs e) = do { (ss,ds) <- repBinds bs 894 898 ; e2 <- addBinds ss (repLE e) 895 899 ; z <- repLetE ds e2 … … 980 984 981 985 repGuards :: [LGRHS Name] -> DsM (Core TH.BodyQ) 982 986 repGuards [L _ (GRHS [] e)] 983 = do { a <- repLE e; repNormal a }984 repGuards other 985 = do { zs <- mapM process other; 986 let {(xs, ys) = unzip zs};987 gd <- repGuarded (nonEmptyCoreList ys); 988 wrapGenSyms (concat xs) gd}989 where 990 process:: LGRHS Name -> DsM ([GenSymBind], (Core (TH.Q (TH.Guard, TH.Exp))))991 process (L _ (GRHS [L _ (ExprStmt e1 _ _ _)] e2))992 = do { x <- repLNormalGE e1 e2;993 return ([], x) }994 process (L _ (GRHS ss rhs))995 = do (gs, ss') <- repLSts ss996 rhs'<- addBinds gs $ repLE rhs997 g <- repPatGE (nonEmptyCoreList ss') rhs'998 return (gs, g)987 = do { a <- repLE e 988 ; repNormal a } 989 repGuards alts 990 = do { (binds, alts') <- liftM unzip $ mapM repLGRHS alts 991 ; body <- repGuarded (nonEmptyCoreList alts') 992 ; wrapGenSyms (concat binds) body } 993 994 repLGRHS :: LGRHS Name -> DsM ([GenSymBind], (Core (TH.Q (TH.Guard, TH.Exp)))) 995 repLGRHS (L _ (GRHS [L _ (ExprStmt guard _ _ _)] rhs)) 996 = do { guarded <- repLNormalGE guard rhs 997 ; return ([], guarded) } 998 repLGRHS (L _ (GRHS stmts rhs)) 999 = do { (gs, stmts') <- repLSts stmts 1000 ; rhs' <- addBinds gs $ repLE rhs 1001 ; guarded <- repPatGE (nonEmptyCoreList stmts') rhs' 1002 ; return (gs, guarded) } 999 1003 1000 1004 repFields :: HsRecordBinds Name -> DsM (Core [TH.Q TH.FieldExp]) 1001 1005 repFields (HsRecFields { rec_flds = flds }) … … 1471 1475 repCond :: Core TH.ExpQ -> Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ) 1472 1476 repCond (MkC x) (MkC y) (MkC z) = rep2 condEName [x,y,z] 1473 1477 1478 repMultiIf :: Core [TH.Q (TH.Guard, TH.Exp)] -> DsM (Core TH.ExpQ) 1479 repMultiIf (MkC alts) = rep2 multiIfEName [alts] 1480 1474 1481 repLetE :: Core [TH.DecQ] -> Core TH.ExpQ -> DsM (Core TH.ExpQ) 1475 1482 repLetE (MkC ds) (MkC e) = rep2 letEName [ds, e] 1476 1483 … … 1902 1909 varEName, conEName, litEName, appEName, infixEName, 1903 1910 infixAppName, sectionLName, sectionRName, lamEName, lamCaseEName, 1904 1911 tupEName, unboxedTupEName, 1905 condEName, letEName, caseEName, doEName, compEName,1912 condEName, multiIfEName, letEName, caseEName, doEName, compEName, 1906 1913 fromEName, fromThenEName, fromToEName, fromThenToEName, 1907 1914 listEName, sigEName, recConEName, recUpdEName, 1908 1915 -- FieldExp … … 2066 2073 -- data Exp = ... 2067 2074 varEName, conEName, litEName, appEName, infixEName, infixAppName, 2068 2075 sectionLName, sectionRName, lamEName, lamCaseEName, tupEName, 2069 unboxedTupEName, condEName, letEName, caseEName, doEName,2070 compEName :: Name2076 unboxedTupEName, condEName, multiIfEName, letEName, caseEName, 2077 doEName, compEName :: Name 2071 2078 varEName = libFun (fsLit "varE") varEIdKey 2072 2079 conEName = libFun (fsLit "conE") conEIdKey 2073 2080 litEName = libFun (fsLit "litE") litEIdKey … … 2081 2088 tupEName = libFun (fsLit "tupE") tupEIdKey 2082 2089 unboxedTupEName = libFun (fsLit "unboxedTupE") unboxedTupEIdKey 2083 2090 condEName = libFun (fsLit "condE") condEIdKey 2091 multiIfEName = libFun (fsLit "multiIfE") multiIfEIdKey 2084 2092 letEName = libFun (fsLit "letE") letEIdKey 2085 2093 caseEName = libFun (fsLit "caseE") caseEIdKey 2086 2094 doEName = libFun (fsLit "doE") doEIdKey … … 2380 2388 -- data Exp = ... 2381 2389 varEIdKey, conEIdKey, litEIdKey, appEIdKey, infixEIdKey, infixAppIdKey, 2382 2390 sectionLIdKey, sectionRIdKey, lamEIdKey, lamCaseEIdKey, tupEIdKey, 2383 unboxedTupEIdKey, condEIdKey, 2391 unboxedTupEIdKey, condEIdKey, multiIfEIdKey, 2384 2392 letEIdKey, caseEIdKey, doEIdKey, compEIdKey, 2385 2393 fromEIdKey, fromThenEIdKey, fromToEIdKey, fromThenToEIdKey, 2386 2394 listEIdKey, sigEIdKey, recConEIdKey, recUpdEIdKey :: Unique … … 2397 2405 tupEIdKey = mkPreludeMiscIdUnique 280 2398 2406 unboxedTupEIdKey = mkPreludeMiscIdUnique 281 2399 2407 condEIdKey = mkPreludeMiscIdUnique 282 2400 letEIdKey = mkPreludeMiscIdUnique 283 2401 caseEIdKey = mkPreludeMiscIdUnique 284 2402 doEIdKey = mkPreludeMiscIdUnique 285 2403 compEIdKey = mkPreludeMiscIdUnique 286 2404 fromEIdKey = mkPreludeMiscIdUnique 287 2405 fromThenEIdKey = mkPreludeMiscIdUnique 288 2406 fromToEIdKey = mkPreludeMiscIdUnique 289 2407 fromThenToEIdKey = mkPreludeMiscIdUnique 290 2408 listEIdKey = mkPreludeMiscIdUnique 291 2409 sigEIdKey = mkPreludeMiscIdUnique 292 2410 recConEIdKey = mkPreludeMiscIdUnique 293 2411 recUpdEIdKey = mkPreludeMiscIdUnique 294 2408 multiIfEIdKey = mkPreludeMiscIdUnique 283 2409 letEIdKey = mkPreludeMiscIdUnique 284 2410 caseEIdKey = mkPreludeMiscIdUnique 285 2411 doEIdKey = mkPreludeMiscIdUnique 286 2412 compEIdKey = mkPreludeMiscIdUnique 287 2413 fromEIdKey = mkPreludeMiscIdUnique 288 2414 fromThenEIdKey = mkPreludeMiscIdUnique 289 2415 fromToEIdKey = mkPreludeMiscIdUnique 290 2416 fromThenToEIdKey = mkPreludeMiscIdUnique 291 2417 listEIdKey = mkPreludeMiscIdUnique 292 2418 sigEIdKey = mkPreludeMiscIdUnique 293 2419 recConEIdKey = mkPreludeMiscIdUnique 294 2420 recUpdEIdKey = mkPreludeMiscIdUnique 295 2412 2421 2413 2422 -- type FieldExp = ... 2414 2423 fieldExpIdKey :: Unique -
compiler/deSugar/Match.lhs
diff --git a/compiler/deSugar/Match.lhs b/compiler/deSugar/Match.lhs index c80446a..8fd3a20 100644
a b 88 88 incomplete_flag :: HsMatchContext id -> Bool 89 89 incomplete_flag (FunRhs {}) = wopt Opt_WarnIncompletePatterns dflags 90 90 incomplete_flag CaseAlt = wopt Opt_WarnIncompletePatterns dflags 91 incomplete_flag IfAlt = False 91 92 92 93 incomplete_flag LambdaExpr = wopt Opt_WarnIncompleteUniPatterns dflags 93 94 incomplete_flag PatBindRhs = wopt Opt_WarnIncompleteUniPatterns dflags -
compiler/hsSyn/Convert.lhs
diff --git a/compiler/hsSyn/Convert.lhs b/compiler/hsSyn/Convert.lhs index bf0f956..376ff23 100644
a b 495 495 cvt (UnboxedTupE es) = do { es' <- mapM cvtl es; return $ ExplicitTuple (map Present es') Unboxed } 496 496 cvt (CondE x y z) = do { x' <- cvtl x; y' <- cvtl y; z' <- cvtl z; 497 497 ; return $ HsIf (Just noSyntaxExpr) x' y' z' } 498 cvt (MultiIfE alts) 499 | null alts = failWith (ptext (sLit "Multi-way if-expression with no alternatives")) 500 | otherwise = do { alts' <- mapM cvtpair alts 501 ; return $ HsMultiIf placeHolderType alts' } 498 502 cvt (LetE ds e) = do { ds' <- cvtLocalDecs (ptext (sLit "a let expression")) ds 499 503 ; e' <- cvtl e; return $ HsLet ds' e' } 500 504 cvt (CaseE e ms) -
compiler/hsSyn/HsExpr.lhs
diff --git a/compiler/hsSyn/HsExpr.lhs b/compiler/hsSyn/HsExpr.lhs index 4db827a..a9cad67 100644
a b 152 152 (LHsExpr id) -- then part 153 153 (LHsExpr id) -- else part 154 154 155 | HsMultiIf PostTcType [LGRHS id] -- Multi-way if 156 155 157 | HsLet (HsLocalBinds id) -- let(rec) 156 158 (LHsExpr id) 157 159 … … 464 466 ptext (sLit "else"), 465 467 nest 4 (ppr e3)] 466 468 469 ppr_expr (HsMultiIf _ alts) 470 = sep $ ptext (sLit "if") : map ppr_alt alts 471 where ppr_alt (L _ (GRHS guards expr)) = 472 sep [ char '|' <+> interpp'SP guards 473 , ptext (sLit "->") <+> pprDeeper (ppr expr) ] 474 467 475 -- special case: let ... in let ... 468 476 ppr_expr (HsLet binds expr@(L _ (HsLet _ _))) 469 477 = sep [hang (ptext (sLit "let")) 2 (hsep [pprBinds binds, ptext (sLit "in")]), … … 1263 1271 = FunRhs id Bool -- Function binding for f; True <=> written infix 1264 1272 | LambdaExpr -- Patterns of a lambda 1265 1273 | CaseAlt -- Patterns and guards on a case alternative 1274 | IfAlt -- Guards of a multi-way if alternative 1266 1275 | ProcExpr -- Patterns of a proc 1267 1276 | PatBindRhs -- A pattern binding eg [y] <- e = e 1268 1277 … … 1313 1322 matchSeparator :: HsMatchContext id -> SDoc 1314 1323 matchSeparator (FunRhs {}) = ptext (sLit "=") 1315 1324 matchSeparator CaseAlt = ptext (sLit "->") 1325 matchSeparator IfAlt = ptext (sLit "->") 1316 1326 matchSeparator LambdaExpr = ptext (sLit "->") 1317 1327 matchSeparator ProcExpr = ptext (sLit "->") 1318 1328 matchSeparator PatBindRhs = ptext (sLit "=") … … 1335 1345 pprMatchContextNoun (FunRhs fun _) = ptext (sLit "equation for") 1336 1346 <+> quotes (ppr fun) 1337 1347 pprMatchContextNoun CaseAlt = ptext (sLit "case alternative") 1348 pprMatchContextNoun IfAlt = ptext (sLit "multi-way if alternative") 1338 1349 pprMatchContextNoun RecUpd = ptext (sLit "record-update construct") 1339 1350 pprMatchContextNoun ThPatQuote = ptext (sLit "Template Haskell pattern quotation") 1340 1351 pprMatchContextNoun PatBindRhs = ptext (sLit "pattern binding") … … 1383 1394 matchContextErrString :: Outputable id => HsMatchContext id -> SDoc 1384 1395 matchContextErrString (FunRhs fun _) = ptext (sLit "function") <+> ppr fun 1385 1396 matchContextErrString CaseAlt = ptext (sLit "case") 1397 matchContextErrString IfAlt = ptext (sLit "multi-way if") 1386 1398 matchContextErrString PatBindRhs = ptext (sLit "pattern binding") 1387 1399 matchContextErrString RecUpd = ptext (sLit "record update") 1388 1400 matchContextErrString LambdaExpr = ptext (sLit "lambda") -
compiler/main/DynFlags.hs
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs index 02d2004..b5ad8d1 100644
a b 486 486 | Opt_RelaxedLayout 487 487 | Opt_TraditionalRecordSyntax 488 488 | Opt_LambdaCase 489 | Opt_MultiWayIf 489 490 deriving (Eq, Enum, Show) 490 491 491 492 -- | Contains not only a collection of 'DynFlag's but also a plethora of … … 2164 2165 ( "RelaxedLayout", Opt_RelaxedLayout, nop ), 2165 2166 ( "TraditionalRecordSyntax", Opt_TraditionalRecordSyntax, nop ), 2166 2167 ( "LambdaCase", Opt_LambdaCase, nop ), 2168 ( "MultiWayIf", Opt_MultiWayIf, nop ), 2167 2169 ( "MonoLocalBinds", Opt_MonoLocalBinds, nop ), 2168 2170 ( "RelaxedPolyRec", Opt_RelaxedPolyRec, 2169 2171 \ turn_on -> if not turn_on -
compiler/parser/Lexer.x
diff --git a/compiler/parser/Lexer.x b/compiler/parser/Lexer.x index 03e8958..ac417ac 100644
a b 1867 1867 explicitNamespacesBit = 29 1868 1868 lambdaCaseBit :: Int 1869 1869 lambdaCaseBit = 30 1870 multiWayIfBit :: Int 1871 multiWayIfBit = 31 1870 1872 1871 1873 1872 1874 always :: Int -> Bool … … 1918 1920 explicitNamespacesEnabled flags = testBit flags explicitNamespacesBit 1919 1921 lambdaCaseEnabled :: Int -> Bool 1920 1922 lambdaCaseEnabled flags = testBit flags lambdaCaseBit 1923 multiWayIfEnabled :: Int -> Bool 1924 multiWayIfEnabled flags = testBit flags multiWayIfBit 1921 1925 1922 1926 -- PState for parsing options pragmas 1923 1927 -- … … 1979 1983 .|. typeLiteralsBit `setBitIf` xopt Opt_DataKinds flags 1980 1984 .|. explicitNamespacesBit `setBitIf` xopt Opt_ExplicitNamespaces flags 1981 1985 .|. lambdaCaseBit `setBitIf` xopt Opt_LambdaCase flags 1986 .|. multiWayIfBit `setBitIf` xopt Opt_MultiWayIf flags 1982 1987 -- 1983 1988 setBitIf :: Int -> Bool -> Int 1984 1989 b `setBitIf` cond | cond = bit b -
compiler/parser/Parser.y.pp
diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp index 67baa88..6213227 100644
a b 55 55 import Maybes ( orElse ) 56 56 import Outputable 57 57 58 import Control.Monad ( unless )58 import Control.Monad ( unless, liftM ) 59 59 import GHC.Exts 60 60 import Data.Char 61 61 import Control.Monad ( mplus ) … … 1394 1394 | 'if' exp optSemi 'then' exp optSemi 'else' exp 1395 1395 {% checkDoAndIfThenElse $2 $3 $5 $6 $8 >> 1396 1396 return (LL $ mkHsIf $2 $5 $8) } 1397 | 'if' gdpats {% hintMultiWayIf (getLoc $1) >> 1398 return (LL $ HsMultiIf placeHolderType (reverse $ unLoc $2)) } 1397 1399 | 'case' exp 'of' altslist { LL $ HsCase $2 (mkMatchGroup (unLoc $4)) } 1398 1400 | '-' fexp { LL $ NegApp $2 noSyntaxExpr } 1399 1401 … … 2141 2143 l <- getSrcLoc; 2142 2144 let loc = mkSrcLoc (srcLocFile l) 1 1; 2143 2145 return (mkSrcSpan loc loc) 2146 2147 -- Hint about the MultiWayIf extension 2148 hintMultiWayIf :: SrcSpan -> P () 2149 hintMultiWayIf span = do 2150 mwiEnabled <- liftM ((Opt_MultiWayIf `xopt`) . dflags) getPState 2151 unless mwiEnabled $ parseErrorSDoc span $ 2152 text "Multi-way if-expressions need -XMultiWayIf turned on" 2144 2153 } -
compiler/rename/RnBinds.lhs
diff --git a/compiler/rename/RnBinds.lhs b/compiler/rename/RnBinds.lhs index d3d1603..2c70698 100644
a b 25 25 26 26 -- Other bindings 27 27 rnMethodBinds, renameSigs, mkSigTvFn, 28 rnMatchGroup, rnGRHSs, 28 rnMatchGroup, rnGRHSs, rnGRHS, 29 29 makeMiniFixityEnv, MiniFixityEnv, 30 30 HsSigCtxt(..) 31 31 ) where -
compiler/rename/RnExpr.lhs
diff --git a/compiler/rename/RnExpr.lhs b/compiler/rename/RnExpr.lhs index 372daa9..e7dbe53 100644
a b 29 29 30 30 import RnSource ( rnSrcDecls, findSplice ) 31 31 import RnBinds ( rnLocalBindsAndThen, rnLocalValBindsLHS, rnLocalValBindsRHS, 32 rnMatchGroup, makeMiniFixityEnv)32 rnMatchGroup, rnGRHS, makeMiniFixityEnv) 33 33 import HsSyn 34 34 import TcRnMonad 35 35 import TcEnv ( thRnBrack ) … … 284 284 ; (mb_ite, fvITE) <- lookupIfThenElse 285 285 ; return (HsIf mb_ite p' b1' b2', plusFVs [fvITE, fvP, fvB1, fvB2]) } 286 286 287 rnExpr (HsMultiIf ty alts) 288 = do { (alts', fvs) <- mapFvRn (rnGRHS IfAlt) alts 289 ; return (HsMultiIf ty alts', fvs) } 290 287 291 rnExpr (HsType a) 288 292 = rnLHsType HsTypeCtx a `thenM` \ (t, fvT) -> 289 293 return (HsType t, fvT) -
compiler/typecheck/TcExpr.lhs
diff --git a/compiler/typecheck/TcExpr.lhs b/compiler/typecheck/TcExpr.lhs index ba2ca74..51b5eb3 100644
a b 445 445 -- and it maintains uniformity with other rebindable syntax 446 446 ; return (HsIf (Just fun') pred' b1' b2') } 447 447 448 tcExpr (HsMultiIf _ alts) res_ty 449 = do { alts' <- mapM (wrapLocM $ tcGRHS match_ctxt res_ty) alts 450 ; return $ HsMultiIf res_ty alts' } 451 where match_ctxt = MC { mc_what = IfAlt, mc_body = tcBody } 452 448 453 tcExpr (HsDo do_or_lc stmts _) res_ty 449 454 = tcDoStmts do_or_lc stmts res_ty 450 455 -
compiler/typecheck/TcHsSyn.lhs
diff --git a/compiler/typecheck/TcHsSyn.lhs b/compiler/typecheck/TcHsSyn.lhs index 51d6c12..922b2cd 100644
a b 621 621 ; new_e3 <- zonkLExpr env e3 622 622 ; returnM (HsIf new_e0 new_e1 new_e2 new_e3) } 623 623 624 zonkExpr env (HsMultiIf ty alts) 625 = do { alts' <- mapM (wrapLocM zonk_alt) alts 626 ; ty' <- zonkTcTypeToType env ty 627 ; returnM $ HsMultiIf ty' alts' } 628 where zonk_alt (GRHS guard expr) 629 = do { (env', guard') <- zonkStmts env guard 630 ; expr' <- zonkLExpr env' expr 631 ; returnM $ GRHS guard' expr' } 632 624 633 zonkExpr env (HsLet binds expr) 625 634 = zonkLocalBinds env binds `thenM` \ (new_env, new_binds) -> 626 635 zonkLExpr new_env expr `thenM` \ new_expr -> -
compiler/typecheck/TcMatches.lhs
diff --git a/compiler/typecheck/TcMatches.lhs b/compiler/typecheck/TcMatches.lhs index 2941a17..acc2064 100644
a b 13 13 -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces 14 14 -- for details 15 15 16 module TcMatches ( tcMatchesFun, tcGRHSsPat, tc MatchesCase, tcMatchLambda,17 TcMatchCtxt(..), TcStmtChecker,18 tcStmts, tcStmtsAndThen, tcDoStmts, tcBody,19 tcDoStmt, tcGuardStmt16 module TcMatches ( tcMatchesFun, tcGRHSsPat, tcGRHS, tcMatchesCase, 17 tcMatchLambda, TcMatchCtxt(..), TcStmtChecker, 18 tcStmts, tcStmtsAndThen, tcDoStmts, tcBody, 19 tcDoStmt, tcGuardStmt 20 20 ) where 21 21 22 22 import {-# SOURCE #-} TcExpr( tcSyntaxOp, tcInferRhoNC, tcInferRho, tcCheckId, -
docs/users_guide/flags.xml
diff --git a/docs/users_guide/flags.xml b/docs/users_guide/flags.xml index 544acd8..24c52f2 100644
a b 1128 1128 <entry><option>-XNoLambdaCase</option></entry> 1129 1129 </row> 1130 1130 <row> 1131 <entry><option>-XMultiWayIf</option></entry> 1132 <entry>Enable <link linkend="multi-way-if">multi-way if-expressions</link>.</entry> 1133 <entry>dynamic</entry> 1134 <entry><option>-XNoMultiWayIf</option></entry> 1135 </row> 1136 <row> 1131 1137 <entry><option>-XSafe</option></entry> 1132 1138 <entry>Enable the <link linkend="safe-haskell">Safe Haskell</link> Safe mode.</entry> 1133 1139 <entry>dynamic</entry> -
docs/users_guide/glasgow_exts.xml
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 805f53a..dde235e 100644
a b 1690 1690 </para> 1691 1691 </sect2> 1692 1692 1693 <sect2 id="multi-way-if"> 1694 <title>Multi-way if-expressions</title> 1695 <para> 1696 With <option>-XMultiWayIf</option> flag GHC accepts conditional expressions 1697 with multiple branches: 1698 <programlisting> 1699 if | guard1 -> expr1 1700 | ... 1701 | guardN -> exprN 1702 </programlisting> 1703 which is roughly equivalent to 1704 <programlisting> 1705 case () of 1706 _ | guard1 -> expr1 1707 ... 1708 _ | guardN -> exprN 1709 </programlisting> 1710 except that multi-way if-expressions do not alter the layout. 1711 </para> 1712 </sect2> 1713 1693 1714 <sect2 id="disambiguate-fields"> 1694 1715 <title>Record field disambiguation</title> 1695 1716 <para>
