X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FdeSugar%2FMatchLit.lhs;h=be112e09a782cdb6dc49eaa6c66b3c4f5306977d;hb=bf902b277afa1feff586f7d96178b59be2cfcfe2;hp=5e30f327781d33b0a9b5e45ed542ae90d7748530;hpb=393f26621b762225b204b3dc78b05a3ecf08871e;p=ghc-hetmet.git diff --git a/compiler/deSugar/MatchLit.lhs b/compiler/deSugar/MatchLit.lhs index 5e30f32..be112e0 100644 --- a/compiler/deSugar/MatchLit.lhs +++ b/compiler/deSugar/MatchLit.lhs @@ -27,13 +27,11 @@ import TyCon import DataCon import TcHsSyn ( shortCutLit ) import TcType -import Type import PrelNames import TysWiredIn -import Unique import Literal import SrcLoc -import Ratio +import Data.Ratio import Outputable import Util import FastString @@ -154,43 +152,54 @@ tidyLitPat (HsString s) tidyLitPat lit = LitPat lit ---------------- -tidyNPat :: HsOverLit Id -> Maybe (SyntaxExpr Id) -> SyntaxExpr Id -> Pat Id -tidyNPat (OverLit val False _ ty) mb_neg _ - -- Take short cuts only if the literal is not using rebindable syntax - | isIntTy ty = mk_con_pat intDataCon (HsIntPrim int_val) - | isWordTy ty = mk_con_pat wordDataCon (HsWordPrim int_val) - | isFloatTy ty = mk_con_pat floatDataCon (HsFloatPrim rat_val) - | isDoubleTy ty = mk_con_pat doubleDataCon (HsDoublePrim rat_val) --- | isStringTy lit_ty = mk_con_pat stringDataCon (HsStringPrim str_val) +tidyNPat :: (HsLit -> Pat Id) -- How to tidy a LitPat + -- We need this argument because tidyNPat is called + -- both by Match and by Check, but they tidy LitPats + -- slightly differently; and we must desugar + -- literals consistently (see Trac #5117) + -> HsOverLit Id -> Maybe (SyntaxExpr Id) -> SyntaxExpr Id + -> Pat Id +tidyNPat tidy_lit_pat (OverLit val False _ ty) mb_neg _ + -- False: Take short cuts only if the literal is not using rebindable syntax + -- + -- Once that is settled, look for cases where the type of the + -- entire overloaded literal matches the type of the underlying literal, + -- and in that case take the short cut + -- NB: Watch out for wierd cases like Trac #3382 + -- f :: Int -> Int + -- f "blah" = 4 + -- which might be ok if we hvae 'instance IsString Int' + -- + + | isIntTy ty, Just int_lit <- mb_int_lit = mk_con_pat intDataCon (HsIntPrim int_lit) + | isWordTy ty, Just int_lit <- mb_int_lit = mk_con_pat wordDataCon (HsWordPrim int_lit) + | isFloatTy ty, Just rat_lit <- mb_rat_lit = mk_con_pat floatDataCon (HsFloatPrim rat_lit) + | isDoubleTy ty, Just rat_lit <- mb_rat_lit = mk_con_pat doubleDataCon (HsDoublePrim rat_lit) + | isStringTy ty, Just str_lit <- mb_str_lit = tidy_lit_pat (HsString str_lit) where mk_con_pat :: DataCon -> HsLit -> Pat Id mk_con_pat con lit = unLoc (mkPrefixConPat con [noLoc $ LitPat lit] ty) - neg_val = case (mb_neg, val) of - (Nothing, _) -> val - (Just _, HsIntegral i) -> HsIntegral (-i) - (Just _, HsFractional f) -> HsFractional (-f) - (Just _, HsIsString _) -> panic "tidyNPat" - - int_val :: Integer - int_val = case neg_val of - HsIntegral i -> i - _ -> panic "tidyNPat" + mb_int_lit :: Maybe Integer + mb_int_lit = case (mb_neg, val) of + (Nothing, HsIntegral i) -> Just i + (Just _, HsIntegral i) -> Just (-i) + _ -> Nothing - rat_val :: Rational - rat_val = case neg_val of - HsIntegral i -> fromInteger i - HsFractional f -> f - _ -> panic "tidyNPat" + mb_rat_lit :: Maybe Rational + mb_rat_lit = case (mb_neg, val) of + (Nothing, HsIntegral i) -> Just (fromInteger i) + (Just _, HsIntegral i) -> Just (fromInteger (-i)) + (Nothing, HsFractional f) -> Just f + (Just _, HsFractional f) -> Just (-f) + _ -> Nothing -{- - str_val :: FastString - str_val = case val of - HsIsString s -> s - _ -> panic "tidyNPat" --} - -tidyNPat over_lit mb_neg eq + mb_str_lit :: Maybe FastString + mb_str_lit = case (mb_neg, val) of + (Nothing, HsIsString s) -> Just s + _ -> Nothing + +tidyNPat _ over_lit mb_neg eq = NPat over_lit mb_neg eq \end{code} @@ -248,14 +257,8 @@ matchLiterals [] _ _ = panic "matchLiterals []" %************************************************************************ \begin{code} -matchNPats :: [Id] -> Type -> [[EquationInfo]] -> DsM MatchResult - -- All NPats, but perhaps for different literals -matchNPats vars ty groups - = do { match_results <- mapM (matchOneNPat vars ty) groups - ; return (foldr1 combineMatchResults match_results) } - -matchOneNPat :: [Id] -> Type -> [EquationInfo] -> DsM MatchResult -matchOneNPat (var:vars) ty (eqn1:eqns) -- All for the same literal +matchNPats :: [Id] -> Type -> [EquationInfo] -> DsM MatchResult +matchNPats (var:vars) ty (eqn1:eqns) -- All for the same literal = do { let NPat lit mb_neg eq_chk = firstPat eqn1 ; lit_expr <- dsOverLit lit ; neg_lit <- case mb_neg of @@ -266,7 +269,7 @@ matchOneNPat (var:vars) ty (eqn1:eqns) -- All for the same literal ; let pred_expr = mkApps eq_expr [Var var, neg_lit] ; match_result <- match vars ty (shiftEqns (eqn1:eqns)) ; return (mkGuardedMatchResult pred_expr match_result) } -matchOneNPat vars _ eqns = pprPanic "matchOneNPat" (ppr (vars, eqns)) +matchNPats vars _ eqns = pprPanic "matchOneNPat" (ppr (vars, eqns)) \end{code}