- -- And becuase case-merging can cause many to show up
-
-------- Merge nested cases ----------
-prepareDefault dflags env outer_bndr bndr_ty imposs_cons (Just deflt_rhs)
- | dopt Opt_CaseMerge dflags
- , Case (Var inner_scrut_var) inner_bndr _ inner_alts <- deflt_rhs
- , DoneId inner_scrut_var' <- substId env inner_scrut_var
- -- Remember, inner_scrut_var is an InId, but outer_bndr is an OutId
- , inner_scrut_var' == outer_bndr
- -- NB: the substId means that if the outer scrutinee was a
- -- variable, and inner scrutinee is the same variable,
- -- then inner_scrut_var' will be outer_bndr
- -- via the magic of simplCaseBinder
- = do { tick (CaseMerge outer_bndr)
-
- ; let munge_rhs rhs = bindCaseBndr inner_bndr (Var outer_bndr) rhs
- ; return [(con, args, munge_rhs rhs) | (con, args, rhs) <- inner_alts,
- not (con `elem` imposs_cons) ]
- -- NB: filter out any imposs_cons. Example:
- -- case x of
- -- A -> e1
- -- DEFAULT -> case x of
- -- A -> e2
- -- B -> e3
- -- When we merge, we must ensure that e1 takes
- -- precedence over e2 as the value for A!
- }
- -- Warning: don't call prepareAlts recursively!
- -- Firstly, there's no point, because inner alts have already had
- -- mkCase applied to them, so they won't have a case in their default
- -- Secondly, if you do, you get an infinite loop, because the bindCaseBndr
- -- in munge_rhs may put a case into the DEFAULT branch!
-