@@ -86,11 +86,16 @@ elabClauses info' fc opts n_in cs =
8686 cs_elab <- mapM (elabClause info opts)
8787 (zip [0..] cs)
8888 ctxt <- getContext
89− -- pats_raw is the version we'll work with at compile time:
90− -- no simplification or PE
89+ -- pats_raw is the basic type checked version, no PE or forcing
90+ let optinfo = idris_optimisation ist
9191 let (pats_in, cs_full) = unzip cs_elab
9292 let pats_raw = map (simple_lhs ctxt) pats_in
93+ -- We'll apply forcing to the left hand side here, so that we don't
94+ -- do any unnecessary case splits
95+ let pats_forced = map (force_lhs optinfo) pats_raw
96+
9397 logElab 3 $ "Elaborated patterns:\n" ++ show pats_raw
98+ logElab 5 $ "Forced patterns:\n" ++ show pats_forced
9499
95100 solveDeferred fc n
96101
@@ -109,9 +114,10 @@ elabClauses info' fc opts n_in cs =
109114 -- If the definition is specialisable, this reduces the
110115 -- RHS
111116 pe_tm <- doPartialEval ist tpats
117+
112118 let pats_pe = if petrans
113− then map (simple_lhs ctxt) pe_tm
114− else pats_raw
119+ then map (force_lhs optinfo . simple_lhs ctxt) pe_tm
120+ else pats_forced
115121
116122 let tcase = opt_typecase (idris_options ist)
117123
@@ -138,11 +144,19 @@ elabClauses info' fc opts n_in cs =
138144
139145 -- addCaseDef builds case trees from <pdef> and <pdef'>
140146
141− -- pdef is the compile-time pattern definition.
142− -- This will get further inlined to help with totality checking.
143− let pdef = map (\(ns, lhs, rhs) -> (map fst ns, lhs, rhs)) $ map debind pats_raw
147+ -- pdef is the compile-time pattern definition, after forcing
148+ -- optimisation applied to LHS
149+ let pdef = map (\(ns, lhs, rhs) -> (map fst ns, lhs, rhs)) $
150+ map debind pats_forced
151+ -- pdef_cov is the pattern definition without forcing, which
152+ -- we feed to the coverage checker (we need to know what the
153+ -- programmer wrote before forcing erasure)
154+ let pdef_cov
155+ = map (\(ns, lhs, rhs) -> (map fst ns, lhs, rhs)) $
156+ map debind pats_raw
144157 -- pdef_pe is the one which will get further optimised
145− -- for run-time, and, partially evaluated
158+ -- for run-time, with no forcing optimisation of the LHS because
159+ -- the affects erasure. Also, it's partially evaluated
146160 let pdef_pe = map debind pats_transformed
147161
148162 logElab 5 $ "Initial typechecked patterns:\n" ++ show pats_raw
@@ -171,12 +185,12 @@ elabClauses info' fc opts n_in cs =
171185 pmissing <-
172186 if cov && not (hasDefault pats_raw)
173187 then do -- Generate clauses from the given possible cases
174− missing <- genClauses fc n (map getLHS pdef) cs_full
188+ missing <- genClauses fc n (map getLHS pdef_cov) cs_full
175189 -- missing <- genMissing n scargs sc
176190 missing' <- filterM (checkPossible info fc True n) missing
177191 -- Filter out the ones which match one of the
178192 -- given cases (including impossible ones)
179− let clhs = map getLHS pdef
193+ let clhs = map getLHS pdef_cov
180194 logElab 2 $ "Must be unreachable:\n" ++
181195 showSep "\n" (map showTmImpls missing') ++
182196 "\nAgainst: " ++
@@ -228,6 +242,7 @@ elabClauses info' fc opts n_in cs =
228242 putIState (ist { idris_patdefs = addDef n (force pdef_pe, force pmissing)
229243 (idris_patdefs ist) })
230244 let caseInfo = CaseInfo (inlinable opts) (inlinable opts) (dictionary opts)
245+
231246 case lookupTyExact n ctxt of
232247 Just ty ->
233248 do ctxt' <- do ctxt <- getContext
@@ -238,7 +253,7 @@ elabClauses info' fc opts n_in cs =
238253 (AssertTotal `elem` opts)
239254 atys
240255 inacc
241− pats_pe
256+ pats_forced
242257 pdef
243258 pdef' ty
244259 ctxt
@@ -329,9 +344,13 @@ elabClauses info' fc opts n_in cs =
329344
330345 -- Simplify the left hand side of a definition, to remove any lets
331346 -- that may have arisen during elaboration
332− simple_lhs ctxt (Right (x, y)) = Right (Idris.Core.Evaluate.simplify ctxt [] x, y)
347+ simple_lhs ctxt (Right (x, y))
348+ = Right (Idris.Core.Evaluate.simplify ctxt [] x, y)
333349 simple_lhs ctxt t = t
334350
351+ force_lhs opts (Right (x, y)) = Right (forceWith opts x, y)
352+ force_lhs opts t = t
353+
335354 simple_rt ctxt (p, x, y) = (p, x, force (uniqueBinders p
336355 (rt_simplify ctxt [] y)))
337356
@@ -354,6 +373,28 @@ elabClauses info' fc opts n_in cs =
354373 Just t -> return t
355374 Nothing -> ierror (At fc (Msg "No specialisation achieved"))
356375
376+forceWith :: Ctxt OptInfo -> Term -> Term
377+forceWith opts lhs = -- trace (show lhs ++ "\n==>\n" ++ show (force lhs) ++ "\n----") $
378+ force lhs
379+ where
380+ -- If there's forced arguments, erase them
381+ force ap@(App _ _ _)
382+ | (fn@(P _ c _), args) <- unApply ap,
383+ Just copt <- lookupCtxtExact c opts
384+ = let args' = eraseArg 0 (forceable copt) args in
385+ mkApp fn (map force args')
386+ force (App t f a)
387+ = App t (force f) (force a)
388+ -- We might have pat bindings, so go under them
389+ force (Bind n b sc) = Bind n b (force sc)
390+ -- Everything else, leave it alone
391+ force t = t
392+
393+ eraseArg i fs (n : ns) | i `elem` fs = Erased : eraseArg (i + 1) fs ns
394+ | otherwise = n : eraseArg (i + 1) fs ns
395+ eraseArg i _ [] = []
396+
397+
357398-- | Find 'static' applications in a term and partially evaluate them.
358399-- Return any new transformation rules
359400elabPE :: ElabInfo -> FC -> Name -> Term -> Idris [(Term, Term)]
@@ -667,7 +708,7 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
667708 then recheckC_borrowing False (PEGenerated `notElem` opts)
668709 [] (constraintNS info) fc id [] lhs_tm
669710 else return (lhs_tm, lhs_ty)
670− let clhs = Idris.Core.Evaluate.simplify ctxt [] clhs_c
711+ let clhs = normalise ctxt [] clhs_c
671712 let borrowed = borrowedNames [] clhs
672713
673714 -- These are the names we're not allowed to use on the RHS, because
@@ -925,7 +966,9 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
925966 let ret_ty = getRetTy (explicitNames (normalise ctxt [] lhs_ty))
926967 let static_names = getStaticNames i lhs_tm
927968 logElab 5 (show lhs_tm ++ "\n" ++ show static_names)
928− (clhs, clhsty) <- recheckC (constraintNS info) fc id [] lhs_tm
969+ (clhs_c, clhsty) <- recheckC (constraintNS info) fc id [] lhs_tm
970+ let clhs = normalise ctxt [] clhs_c
971+
929972 logElab 5 ("Checked " ++ show clhs)
930973 let bargs = getPBtys (explicitNames (normalise ctxt [] lhs_tm))
931974 let wval = rhs_trans info $ addImplBound i (map fst bargs) wval_in