diff options
Diffstat (limited to 'compiler/GHC/HsToCore')
-rw-r--r-- | compiler/GHC/HsToCore/Arrows.hs | 202 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Binds.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Coverage.hs | 30 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Expr.hs | 14 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Match.hs | 37 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Match.hs-boot | 2 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Pmc.hs | 29 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Pmc/Utils.hs | 30 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Quote.hs | 9 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Utils.hs | 1 |
10 files changed, 230 insertions, 128 deletions
diff --git a/compiler/GHC/HsToCore/Arrows.hs b/compiler/GHC/HsToCore/Arrows.hs index 3d93e0b7a5..fffa3347b0 100644 --- a/compiler/GHC/HsToCore/Arrows.hs +++ b/compiler/GHC/HsToCore/Arrows.hs @@ -1,5 +1,5 @@ - {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE BlockArguments #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -466,6 +466,8 @@ dsCmd ids local_vars stack_ty res_ty (HsCmdIf _ mb_fun cond then_cmd else_cmd) fvs_cond `unionDVarSet` fvs_then `unionDVarSet` fvs_else) {- +Note [Desugaring HsCmdCase] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ Case commands are treated in much the same way as if commands (see above) except that there are more alternatives. For example @@ -492,74 +494,87 @@ case bodies, containing the following fields: bodies with |||. -} -dsCmd ids local_vars stack_ty res_ty - (HsCmdCase _ exp (MG { mg_alts = L l matches - , mg_ext = MatchGroupTc arg_tys _ - , mg_origin = origin })) - env_ids = do +dsCmd ids local_vars stack_ty res_ty (HsCmdCase _ exp match) env_ids = do stack_id <- newSysLocalDs Many stack_ty - - -- Extract and desugar the leaf commands in the case, building tuple - -- expressions that will (after tagging) replace these leaves - - let - leaves = concatMap leavesMatch matches - make_branch (leaf, bound_vars) = do - (core_leaf, _fvs, leaf_ids) - <- dsfixCmd ids (bound_vars `unionVarSet` local_vars) stack_ty - res_ty leaf - return ([mkHsEnvStackExpr leaf_ids stack_id], - envStackType leaf_ids stack_ty, - core_leaf) - - branches <- mapM make_branch leaves - either_con <- dsLookupTyCon eitherTyConName - left_con <- dsLookupDataCon leftDataConName - right_con <- dsLookupDataCon rightDataConName - let - left_id = mkConLikeTc (RealDataCon left_con) - right_id = mkConLikeTc (RealDataCon right_con) - left_expr ty1 ty2 e = noLocA $ HsApp noComments - (noLocA $ mkHsWrap (mkWpTyApps [ty1, ty2]) left_id ) e - right_expr ty1 ty2 e = noLocA $ HsApp noComments - (noLocA $ mkHsWrap (mkWpTyApps [ty1, ty2]) right_id) e - - -- Prefix each tuple with a distinct series of Left's and Right's, - -- in a balanced way, keeping track of the types. - - merge_branches :: ([LHsExpr GhcTc], Type, CoreExpr) - -> ([LHsExpr GhcTc], Type, CoreExpr) - -> ([LHsExpr GhcTc], Type, CoreExpr) -- AZ - merge_branches (builds1, in_ty1, core_exp1) - (builds2, in_ty2, core_exp2) - = (map (left_expr in_ty1 in_ty2) builds1 ++ - map (right_expr in_ty1 in_ty2) builds2, - mkTyConApp either_con [in_ty1, in_ty2], - do_choice ids in_ty1 in_ty2 res_ty core_exp1 core_exp2) - (leaves', sum_ty, core_choices) = foldb merge_branches branches - - -- Replace the commands in the case with these tagged tuples, - -- yielding a HsExpr Id we can feed to dsExpr. - - (_, matches') = mapAccumL (replaceLeavesMatch res_ty) leaves' matches + (match', core_choices) + <- dsCases ids local_vars stack_id stack_ty res_ty match + let MG{ mg_ext = MatchGroupTc _ sum_ty } = match' in_ty = envStackType env_ids stack_ty - core_body <- dsExpr (HsCase noExtField exp - (MG { mg_alts = L l matches' - , mg_ext = MatchGroupTc arg_tys sum_ty - , mg_origin = origin })) - -- Note that we replace the HsCase result type by sum_ty, - -- which is the type of matches' + core_body <- dsExpr (HsCase noExtField exp match') core_matches <- matchEnvStack env_ids stack_id core_body return (do_premap ids in_ty sum_ty res_ty core_matches core_choices, exprFreeIdsDSet core_body `uniqDSetIntersectUniqSet` local_vars) +{- +\cases and \case are desugared analogously to a case command (see above). +For example + + \cases {p1 q1 -> c1; p2 q2 -> c2; p3 q3 -> c3 } + +is translated to + + premap (\ ((xs), (e1, (e2,stk))) -> cases e1 e2 of + p1 q1 -> (Left (Left (xs1), stk)) + p2 q2 -> Left ((Right (xs2), stk)) + p3 q3 -> Right ((xs3), stk)) + ((c1 ||| c2) ||| c3) + +(cases...of is hypothetical notation that works like case...of but with +multiple scrutinees) + +-} dsCmd ids local_vars stack_ty res_ty - (HsCmdLamCase _ mg@MG { mg_ext = MatchGroupTc [Scaled arg_mult arg_ty] _ }) env_ids = do - arg_id <- newSysLocalDs arg_mult arg_ty - let case_cmd = noLocA $Â HsCmdCase noExtField (nlHsVar arg_id) mg - dsCmdLam ids local_vars stack_ty res_ty [nlVarPat arg_id] case_cmd env_ids + (HsCmdLamCase _ lc_variant match@MG { mg_ext = MatchGroupTc {mg_arg_tys = arg_tys} } ) + env_ids = do + arg_ids <- newSysLocalsDs arg_tys + + let match_ctxt = ArrowLamCaseAlt lc_variant + pat_vars = mkVarSet arg_ids + local_vars' = pat_vars `unionVarSet` local_vars + (pat_tys, stack_ty') = splitTypeAt (length arg_tys) stack_ty + + -- construct and desugar a case expression with multiple scrutinees + (core_body, free_vars, env_ids') <- trimInput \env_ids -> do + stack_id <- newSysLocalDs Many stack_ty' + (match', core_choices) + <- dsCases ids local_vars' stack_id stack_ty' res_ty match + + let MG{ mg_ext = MatchGroupTc _ sum_ty } = match' + in_ty = envStackType env_ids stack_ty' + discrims = map nlHsVar arg_ids + (discrim_vars, matching_code) + <- matchWrapper (ArrowMatchCtxt match_ctxt) (Just discrims) match' + core_body <- flip (bind_vars discrim_vars) matching_code <$> + traverse dsLExpr discrims + + core_matches <- matchEnvStack env_ids stack_id core_body + return (do_premap ids in_ty sum_ty res_ty core_matches core_choices, + exprFreeIdsDSet core_body `uniqDSetIntersectUniqSet` local_vars') + + param_ids <- mapM (newSysLocalDs Many) pat_tys + stack_id' <- newSysLocalDs Many stack_ty' + + -- the expression is built from the inside out, so the actions + -- are presented in reverse order + + let -- build a new environment, plus what's left of the stack + core_expr = buildEnvStack env_ids' stack_id' + in_ty = envStackType env_ids stack_ty + in_ty' = envStackType env_ids' stack_ty' + + -- bind the scrutinees to the parameters + let match_code = bind_vars arg_ids (map Var param_ids) core_expr + + -- match the parameters against the top of the old stack + (stack_id, param_code) <- matchVarStack param_ids stack_id' match_code + -- match the old environment and stack against the input + select_code <- matchEnvStack env_ids stack_id param_code + return (do_premap ids in_ty in_ty' res_ty select_code core_body, + free_vars `uniqDSetMinusUniqSet` pat_vars) + where + bind_vars vars exprs expr = foldr (uncurry bindNonRec) expr $ zip vars exprs -- D; ys |-a cmd : stk --> t -- ---------------------------------- @@ -680,7 +695,7 @@ trimInput build_arrow (core_cmd, free_vars) <- build_arrow env_ids return (core_cmd, free_vars, dVarSetElems free_vars)) --- Desugaring for both HsCmdLam and HsCmdLamCase. +-- Desugaring for both HsCmdLam -- -- D; ys |-a cmd : stk t' -- ----------------------------------------------- @@ -726,6 +741,71 @@ dsCmdLam ids local_vars stack_ty res_ty pats body env_ids = do return (do_premap ids in_ty in_ty' res_ty select_code core_body, free_vars `uniqDSetMinusUniqSet` pat_vars) +-- Used for case and \case(s) +-- See Note [Desugaring HsCmdCase] +dsCases :: DsCmdEnv -- arrow combinators + -> IdSet -- set of local vars available to this command + -> Id -- stack id + -> Type -- type of the stack (right-nested tuple) + -> Type -- return type of the command + -> MatchGroup GhcTc (LHsCmd GhcTc) -- match group to desugar + -> DsM (MatchGroup GhcTc (LHsExpr GhcTc), -- match group with choice tree + CoreExpr) -- desugared choices +dsCases ids local_vars stack_id stack_ty res_ty + (MG { mg_alts = L l matches + , mg_ext = MatchGroupTc arg_tys _ + , mg_origin = origin }) = do + + -- Extract and desugar the leaf commands in the case, building tuple + -- expressions that will (after tagging) replace these leaves + + let leaves = concatMap leavesMatch matches + make_branch (leaf, bound_vars) = do + (core_leaf, _fvs, leaf_ids) + <- dsfixCmd ids (bound_vars `unionVarSet` local_vars) stack_ty + res_ty leaf + return ([mkHsEnvStackExpr leaf_ids stack_id], + envStackType leaf_ids stack_ty, + core_leaf) + + branches <- mapM make_branch leaves + either_con <- dsLookupTyCon eitherTyConName + left_con <- dsLookupDataCon leftDataConName + right_con <- dsLookupDataCon rightDataConName + let + left_id = mkConLikeTc (RealDataCon left_con) + right_id = mkConLikeTc (RealDataCon right_con) + left_expr ty1 ty2 e = noLocA $ HsApp noComments + (noLocA $ mkHsWrap (mkWpTyApps [ty1, ty2]) left_id ) e + right_expr ty1 ty2 e = noLocA $ HsApp noComments + (noLocA $ mkHsWrap (mkWpTyApps [ty1, ty2]) right_id) e + + -- Prefix each tuple with a distinct series of Left's and Right's, + -- in a balanced way, keeping track of the types. + + merge_branches :: ([LHsExpr GhcTc], Type, CoreExpr) + -> ([LHsExpr GhcTc], Type, CoreExpr) + -> ([LHsExpr GhcTc], Type, CoreExpr) -- AZ + merge_branches (builds1, in_ty1, core_exp1) + (builds2, in_ty2, core_exp2) + = (map (left_expr in_ty1 in_ty2) builds1 ++ + map (right_expr in_ty1 in_ty2) builds2, + mkTyConApp either_con [in_ty1, in_ty2], + do_choice ids in_ty1 in_ty2 res_ty core_exp1 core_exp2) + (leaves', sum_ty, core_choices) = foldb merge_branches branches + + -- Replace the commands in the case with these tagged tuples, + -- yielding a HsExpr Id we can feed to dsExpr. + + (_, matches') = mapAccumL (replaceLeavesMatch res_ty) leaves' matches + + -- Note that we replace the MatchGroup result type by sum_ty, + -- which is the type of matches' + return (MG { mg_alts = L l matches' + , mg_ext = MatchGroupTc arg_tys sum_ty + , mg_origin = origin }, + core_choices) + {- Translation of command judgements of the form diff --git a/compiler/GHC/HsToCore/Binds.hs b/compiler/GHC/HsToCore/Binds.hs index 793f8c9ffb..9da2ecbc02 100644 --- a/compiler/GHC/HsToCore/Binds.hs +++ b/compiler/GHC/HsToCore/Binds.hs @@ -164,9 +164,7 @@ dsHsBind dflags b@(FunBind { fun_id = L loc fun -- addTyCs: Add type evidence to the refinement type -- predicate of the coverage checker -- See Note [Long-distance information] in "GHC.HsToCore.Pmc" - matchWrapper - (mkPrefixFunRhs (L loc (idName fun))) - Nothing matches + matchWrapper (mkPrefixFunRhs (L loc (idName fun))) Nothing matches ; core_wrap <- dsHsWrapper co_fn ; let body' = mkOptTickBox tick body diff --git a/compiler/GHC/HsToCore/Coverage.hs b/compiler/GHC/HsToCore/Coverage.hs index e1e8489fe1..8fececdcea 100644 --- a/compiler/GHC/HsToCore/Coverage.hs +++ b/compiler/GHC/HsToCore/Coverage.hs @@ -536,19 +536,19 @@ addTickHsExpr e@(HsVar _ (L _ id)) = do freeVar id; return e addTickHsExpr e@(HsUnboundVar {}) = return e addTickHsExpr e@(HsRecSel _ (FieldOcc id _)) = do freeVar id; return e -addTickHsExpr e@(HsIPVar {}) = return e -addTickHsExpr e@(HsOverLit {}) = return e -addTickHsExpr e@(HsOverLabel{}) = return e -addTickHsExpr e@(HsLit {}) = return e -addTickHsExpr (HsLam x mg) = liftM (HsLam x) - (addTickMatchGroup True mg) -addTickHsExpr (HsLamCase x mgs) = liftM (HsLamCase x) - (addTickMatchGroup True mgs) -addTickHsExpr (HsApp x e1 e2) = liftM2 (HsApp x) (addTickLHsExprNever e1) - (addTickLHsExpr e2) -addTickHsExpr (HsAppType x e ty) = liftM3 HsAppType (return x) - (addTickLHsExprNever e) - (return ty) +addTickHsExpr e@(HsIPVar {}) = return e +addTickHsExpr e@(HsOverLit {}) = return e +addTickHsExpr e@(HsOverLabel{}) = return e +addTickHsExpr e@(HsLit {}) = return e +addTickHsExpr (HsLam x mg) = liftM (HsLam x) + (addTickMatchGroup True mg) +addTickHsExpr (HsLamCase x lc_variant mgs) = liftM (HsLamCase x lc_variant) + (addTickMatchGroup True mgs) +addTickHsExpr (HsApp x e1 e2) = liftM2 (HsApp x) (addTickLHsExprNever e1) + (addTickLHsExpr e2) +addTickHsExpr (HsAppType x e ty) = liftM3 HsAppType (return x) + (addTickLHsExprNever e) + (return ty) addTickHsExpr (OpApp fix e1 e2 e3) = liftM4 OpApp (return fix) @@ -891,8 +891,8 @@ addTickHsCmd (HsCmdCase x e mgs) = liftM2 (HsCmdCase x) (addTickLHsExpr e) (addTickCmdMatchGroup mgs) -addTickHsCmd (HsCmdLamCase x mgs) = - liftM (HsCmdLamCase x) (addTickCmdMatchGroup mgs) +addTickHsCmd (HsCmdLamCase x lc_variant mgs) = + liftM (HsCmdLamCase x lc_variant) (addTickCmdMatchGroup mgs) addTickHsCmd (HsCmdIf x cnd e1 c2 c3) = liftM3 (HsCmdIf x cnd) (addBinTickLHsExpr (BinBox CondBinBox) e1) diff --git a/compiler/GHC/HsToCore/Expr.hs b/compiler/GHC/HsToCore/Expr.hs index 8820d68a86..18e7cfbb8a 100644 --- a/compiler/GHC/HsToCore/Expr.hs +++ b/compiler/GHC/HsToCore/Expr.hs @@ -195,8 +195,7 @@ dsUnliftedBind (FunBind { fun_id = L l fun , fun_tick = tick }) body -- Can't be a bang pattern (that looks like a PatBind) -- so must be simply unboxed - = do { (args, rhs) <- matchWrapper (mkPrefixFunRhs (L l $ idName fun)) - Nothing matches + = do { (args, rhs) <- matchWrapper (mkPrefixFunRhs (L l $ idName fun)) Nothing matches ; massert (null args) -- Functions aren't lifted ; massert (isIdHsWrapper co_fn) ; let rhs' = mkOptTickBox tick rhs @@ -300,11 +299,10 @@ dsExpr (NegApp _ expr neg_expr) ; dsSyntaxExpr neg_expr [expr'] } dsExpr (HsLam _ a_Match) - = uncurry mkLams <$> matchWrapper LambdaExpr Nothing a_Match + = uncurry mkCoreLams <$> matchWrapper LambdaExpr Nothing a_Match -dsExpr (HsLamCase _ matches) - = do { ([discrim_var], matching_code) <- matchWrapper CaseAlt Nothing matches - ; return $ Lam discrim_var matching_code } +dsExpr (HsLamCase _ lc_variant matches) + = uncurry mkCoreLams <$> matchWrapper (LamCaseAlt lc_variant) Nothing matches dsExpr e@(HsApp _ fun arg) = do { fun' <- dsLExpr fun @@ -356,7 +354,7 @@ dsExpr (HsPragE _ prag expr) = dsExpr (HsCase _ discrim matches) = do { core_discrim <- dsLExpr discrim - ; ([discrim_var], matching_code) <- matchWrapper CaseAlt (Just discrim) matches + ; ([discrim_var], matching_code) <- matchWrapper CaseAlt (Just [discrim]) matches ; return (bindNonRec discrim_var core_discrim matching_code) } -- Pepe: The binds are in scope in the body but NOT in the binding group @@ -606,7 +604,7 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = Left fields -- constructor arguments. ; alts <- mapM (mk_alt upd_fld_env) cons_to_upd ; ([discrim_var], matching_code) - <- matchWrapper RecUpd (Just record_expr) -- See Note [Scrutinee in Record updates] + <- matchWrapper RecUpd (Just [record_expr]) -- See Note [Scrutinee in Record updates] (MG { mg_alts = noLocA alts , mg_ext = MatchGroupTc [unrestricted in_ty] out_ty , mg_origin = FromSource diff --git a/compiler/GHC/HsToCore/Match.hs b/compiler/GHC/HsToCore/Match.hs index 8fcb150329..5c45d9b705 100644 --- a/compiler/GHC/HsToCore/Match.hs +++ b/compiler/GHC/HsToCore/Match.hs @@ -708,15 +708,32 @@ Call @match@ with all of this information! \end{enumerate} -} +-- Note [matchWrapper scrutinees] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- There are three possible cases for matchWrapper's scrutinees argument: +-- +-- 1. Nothing Used for FunBind, HsLam, HsLamcase, where there is no explicit scrutinee +-- The MatchGroup may have matchGroupArity of 0 or more. Examples: +-- f p1 q1 = ... -- matchGroupArity 2 +-- f p2 q2 = ... +-- +-- \cases | g1 -> ... -- matchGroupArity 0 +-- | g2 -> ... +-- +-- 2. Just [e] Used for HsCase, RecordUpd; exactly one scrutinee +-- The MatchGroup has matchGroupArity of exactly 1. Example: +-- case e of p1 -> e1 -- matchGroupArity 1 +-- p2 -> e2 +-- +-- 3. Just es Used for HsCmdLamCase; zero or more scrutinees +-- The MatchGroup has matchGroupArity of (length es). Example: +-- \cases p1 q1 -> returnA -< ... -- matchGroupArity 2 +-- p2 q2 -> ... + matchWrapper :: HsMatchContext GhcRn -- ^ For shadowing warning messages - -> Maybe (LHsExpr GhcTc) -- ^ Scrutinee. (Just scrut) for a case expr - -- case scrut of { p1 -> e1 ... } - -- (and in this case the MatchGroup will - -- have all singleton patterns) - -- Nothing for a function definition - -- f p1 q1 = ... -- No "scrutinee" - -- f p2 q2 = ... -- in this case + -> Maybe [LHsExpr GhcTc] -- ^ Scrutinee(s) + -- see Note [matchWrapper scrutinees] -> MatchGroup GhcTc (LHsExpr GhcTc) -- ^ Matches being desugared -> DsM ([Id], CoreExpr) -- ^ Results (usually passed to 'match') @@ -744,7 +761,7 @@ one pattern, and match simply only accepts one pattern. JJQC 30-Nov-1997 -} -matchWrapper ctxt mb_scr (MG { mg_alts = L _ matches +matchWrapper ctxt scrs (MG { mg_alts = L _ matches , mg_ext = MatchGroupTc arg_tys rhs_ty , mg_origin = origin }) = do { dflags <- getDynFlags @@ -762,7 +779,7 @@ matchWrapper ctxt mb_scr (MG { mg_alts = L _ matches -- @rhss_nablas@ is a flat list of covered Nablas for each RHS. -- Each Match will split off one Nablas for its RHSs from this. ; matches_nablas <- if isMatchContextPmChecked dflags origin ctxt - then addHsScrutTmCs mb_scr new_vars $ + then addHsScrutTmCs (concat scrs) new_vars $ -- See Note [Long-distance information] pmcMatches (DsMatchContext ctxt locn) new_vars matches else pure (initNablasMatches matches) @@ -872,7 +889,7 @@ matchSinglePatVar var mb_scrut ctx pat ty match_result ; locn <- getSrcSpanDs -- Pattern match check warnings ; when (isMatchContextPmChecked dflags FromSource ctx) $ - addCoreScrutTmCs mb_scrut [var] $ + addCoreScrutTmCs (maybeToList mb_scrut) [var] $ pmcPatBind (DsMatchContext ctx locn) var (unLoc pat) ; let eqn_info = EqnInfo { eqn_pats = [unLoc (decideBangHood dflags pat)] diff --git a/compiler/GHC/HsToCore/Match.hs-boot b/compiler/GHC/HsToCore/Match.hs-boot index e163a0bde2..3e969e922d 100644 --- a/compiler/GHC/HsToCore/Match.hs-boot +++ b/compiler/GHC/HsToCore/Match.hs-boot @@ -15,7 +15,7 @@ match :: [Id] matchWrapper :: HsMatchContext GhcRn - -> Maybe (LHsExpr GhcTc) + -> Maybe [LHsExpr GhcTc] -> MatchGroup GhcTc (LHsExpr GhcTc) -> DsM ([Id], CoreExpr) diff --git a/compiler/GHC/HsToCore/Pmc.hs b/compiler/GHC/HsToCore/Pmc.hs index 0de7ab0a15..c810834c64 100644 --- a/compiler/GHC/HsToCore/Pmc.hs +++ b/compiler/GHC/HsToCore/Pmc.hs @@ -419,24 +419,25 @@ addTyCs origin ev_vars m = do addPhiCtsNablas nablas (PhiTyCt . evVarPred <$> ev_vars)) m --- | Add equalities for the 'CoreExpr' scrutinee to the local 'DsM' environment --- when checking a case expression: +-- | Add equalities for the 'CoreExpr' scrutinees to the local 'DsM' environment, +-- e.g. when checking a case expression: -- case e of x { matches } -- When checking matches we record that (x ~ e) where x is the initial -- uncovered. All matches will have to satisfy this equality. -addCoreScrutTmCs :: Maybe CoreExpr -> [Id] -> DsM a -> DsM a -addCoreScrutTmCs Nothing _ k = k -addCoreScrutTmCs (Just scr) [x] k = - flip locallyExtendPmNablas k $ \nablas -> +-- This is also used for the Arrows \cases command, where these equalities have +-- to be added for multiple scrutinees rather than just one. +addCoreScrutTmCs :: [CoreExpr] -> [Id] -> DsM a -> DsM a +addCoreScrutTmCs [] _ k = k +addCoreScrutTmCs (scr:scrs) (x:xs) k = + flip locallyExtendPmNablas (addCoreScrutTmCs scrs xs k) $ \nablas -> addPhiCtsNablas nablas (unitBag (PhiCoreCt x scr)) -addCoreScrutTmCs _ _ _ = panic "addCoreScrutTmCs: scrutinee, but more than one match id" - --- | 'addCoreScrutTmCs', but desugars the 'LHsExpr' first. -addHsScrutTmCs :: Maybe (LHsExpr GhcTc) -> [Id] -> DsM a -> DsM a -addHsScrutTmCs Nothing _ k = k -addHsScrutTmCs (Just scr) vars k = do - scr_e <- dsLExpr scr - addCoreScrutTmCs (Just scr_e) vars k +addCoreScrutTmCs _ _ _ = panic "addCoreScrutTmCs: numbers of scrutinees and match ids differ" + +-- | 'addCoreScrutTmCs', but desugars the 'LHsExpr's first. +addHsScrutTmCs :: [LHsExpr GhcTc] -> [Id] -> DsM a -> DsM a +addHsScrutTmCs scrs vars k = do + scr_es <- traverse dsLExpr scrs + addCoreScrutTmCs scr_es vars k {- Note [Long-distance information] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/compiler/GHC/HsToCore/Pmc/Utils.hs b/compiler/GHC/HsToCore/Pmc/Utils.hs index c79c1025d6..b7279e24b2 100644 --- a/compiler/GHC/HsToCore/Pmc/Utils.hs +++ b/compiler/GHC/HsToCore/Pmc/Utils.hs @@ -82,26 +82,28 @@ redundantBang dflags = wopt Opt_WarnRedundantBangPatterns dflags -- via which 'WarningFlag' it's controlled. -- Returns 'Nothing' if check is not supported. exhaustiveWarningFlag :: HsMatchContext id -> Maybe WarningFlag -exhaustiveWarningFlag (FunRhs {}) = Just Opt_WarnIncompletePatterns -exhaustiveWarningFlag CaseAlt = Just Opt_WarnIncompletePatterns -exhaustiveWarningFlag IfAlt = Just Opt_WarnIncompletePatterns -exhaustiveWarningFlag LambdaExpr = Just Opt_WarnIncompleteUniPatterns -exhaustiveWarningFlag PatBindRhs = Just Opt_WarnIncompleteUniPatterns -exhaustiveWarningFlag PatBindGuards = Just Opt_WarnIncompletePatterns +exhaustiveWarningFlag FunRhs{} = Just Opt_WarnIncompletePatterns +exhaustiveWarningFlag CaseAlt = Just Opt_WarnIncompletePatterns +exhaustiveWarningFlag LamCaseAlt{} = Just Opt_WarnIncompletePatterns +exhaustiveWarningFlag IfAlt = Just Opt_WarnIncompletePatterns +exhaustiveWarningFlag LambdaExpr = Just Opt_WarnIncompleteUniPatterns +exhaustiveWarningFlag PatBindRhs = Just Opt_WarnIncompleteUniPatterns +exhaustiveWarningFlag PatBindGuards = Just Opt_WarnIncompletePatterns exhaustiveWarningFlag (ArrowMatchCtxt c) = arrowMatchContextExhaustiveWarningFlag c -exhaustiveWarningFlag RecUpd = Just Opt_WarnIncompletePatternsRecUpd -exhaustiveWarningFlag ThPatSplice = Nothing -exhaustiveWarningFlag PatSyn = Nothing -exhaustiveWarningFlag ThPatQuote = Nothing +exhaustiveWarningFlag RecUpd = Just Opt_WarnIncompletePatternsRecUpd +exhaustiveWarningFlag ThPatSplice = Nothing +exhaustiveWarningFlag PatSyn = Nothing +exhaustiveWarningFlag ThPatQuote = Nothing -- Don't warn about incomplete patterns in list comprehensions, pattern guards -- etc. They are often *supposed* to be incomplete -exhaustiveWarningFlag (StmtCtxt {}) = Nothing +exhaustiveWarningFlag StmtCtxt{} = Nothing arrowMatchContextExhaustiveWarningFlag :: HsArrowMatchContext -> Maybe WarningFlag arrowMatchContextExhaustiveWarningFlag = \ case - ProcExpr -> Just Opt_WarnIncompleteUniPatterns - ArrowCaseAlt -> Just Opt_WarnIncompletePatterns - KappaExpr -> Just Opt_WarnIncompleteUniPatterns + ProcExpr -> Just Opt_WarnIncompleteUniPatterns + ArrowCaseAlt -> Just Opt_WarnIncompletePatterns + ArrowLamCaseAlt _ -> Just Opt_WarnIncompletePatterns + KappaExpr -> Just Opt_WarnIncompleteUniPatterns -- | Check whether any part of pattern match checking is enabled for this -- 'HsMatchContext' (does not matter whether it is the redundancy check or the diff --git a/compiler/GHC/HsToCore/Quote.hs b/compiler/GHC/HsToCore/Quote.hs index 22fc242e87..109df1a103 100644 --- a/compiler/GHC/HsToCore/Quote.hs +++ b/compiler/GHC/HsToCore/Quote.hs @@ -1499,10 +1499,14 @@ repE (HsOverLit _ l) = do { a <- repOverloadedLiteral l; repLit a } repE (HsLit _ l) = do { a <- repLiteral l; repLit a } repE (HsLam _ (MG { mg_alts = (L _ [m]) })) = repLambda m repE e@(HsLam _ (MG { mg_alts = (L _ _) })) = pprPanic "repE: HsLam with multiple alternatives" (ppr e) -repE (HsLamCase _ (MG { mg_alts = (L _ ms) })) +repE (HsLamCase _ LamCase (MG { mg_alts = (L _ ms) })) = do { ms' <- mapM repMatchTup ms ; core_ms <- coreListM matchTyConName ms' ; repLamCase core_ms } +repE (HsLamCase _ LamCases (MG { mg_alts = (L _ ms) })) + = do { ms' <- mapM repClauseTup ms + ; core_ms <- coreListM matchTyConName ms' + ; repLamCases core_ms } repE (HsApp _ x y) = do {a <- repLE x; b <- repLE y; repApp a b} repE (HsAppType _ e t) = do { a <- repLE e ; s <- repLTy (hswc_body t) @@ -2359,6 +2363,9 @@ repLam (MkC ps) (MkC e) = rep2 lamEName [ps, e] repLamCase :: Core [(M TH.Match)] -> MetaM (Core (M TH.Exp)) repLamCase (MkC ms) = rep2 lamCaseEName [ms] +repLamCases :: Core [(M TH.Clause)] -> MetaM (Core (M TH.Exp)) +repLamCases (MkC ms) = rep2 lamCasesEName [ms] + repTup :: Core [Maybe (M TH.Exp)] -> MetaM (Core (M TH.Exp)) repTup (MkC es) = rep2 tupEName [es] diff --git a/compiler/GHC/HsToCore/Utils.hs b/compiler/GHC/HsToCore/Utils.hs index 17b2b42917..effc1c9688 100644 --- a/compiler/GHC/HsToCore/Utils.hs +++ b/compiler/GHC/HsToCore/Utils.hs @@ -1,4 +1,3 @@ - {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeFamilies #-} |