@@ -86,11 +86,16 @@ elabClauses info' fc opts n_in cs =
86 cs_elab <- mapM (elabClause info opts)
86 cs_elab <- mapM (elabClause info opts)
87 (zip [0..] cs)
87 (zip [0..] cs)
88 ctxt <- getContext
88 ctxt <- getContext
89− -- pats_raw is the version we'll work with at compile time:
89+ -- pats_raw is the basic type checked version, no PE or forcing
90− -- no simplification or PE
90+ let optinfo = idris_optimisation ist
91 let (pats_in, cs_full) = unzip cs_elab
91 let (pats_in, cs_full) = unzip cs_elab
92 let pats_raw = map (simple_lhs ctxt) pats_in
92 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
93 logElab 3 $ "Elaborated patterns:\n" ++ show pats_raw
97 logElab 3 $ "Elaborated patterns:\n" ++ show pats_raw
98+ logElab 5 $ "Forced patterns:\n" ++ show pats_forced
95 solveDeferred fc n
100 solveDeferred fc n
@@ -109,9 +114,10 @@ elabClauses info' fc opts n_in cs =
109 -- If the definition is specialisable, this reduces the
114 -- If the definition is specialisable, this reduces the
111 pe_tm <- doPartialEval ist tpats
116 pe_tm <- doPartialEval ist tpats
112 let pats_pe = if petrans
118 let pats_pe = if petrans
113− then map (simple_lhs ctxt) pe_tm
119+ then map (force_lhs optinfo . simple_lhs ctxt) pe_tm
114− else pats_raw
120+ else pats_forced
116 let tcase = opt_typecase (idris_options ist)
122 let tcase = opt_typecase (idris_options ist)
@@ -138,11 +144,19 @@ elabClauses info' fc opts n_in cs =
139 -- addCaseDef builds case trees from <pdef> and <pdef'>
145 -- addCaseDef builds case trees from <pdef> and <pdef'>
141− -- pdef is the compile-time pattern definition.
147+ -- pdef is the compile-time pattern definition, after forcing
142− -- This will get further inlined to help with totality checking.
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)
143− let pdef = map (\(ns, lhs, rhs) -> (map fst ns, lhs, rhs)) $ map debind pats_raw
155+ = map (\(ns, lhs, rhs) -> (map fst ns, lhs, rhs)) $
144 -- pdef_pe is the one which will get further optimised
157 -- pdef_pe is the one which will get further optimised
158+ -- for run-time, with no forcing optimisation of the LHS because
145− -- for run-time, and, partially evaluated
159+ -- the affects erasure. Also, it's partially evaluated
146 let pdef_pe = map debind pats_transformed
160 let pdef_pe = map debind pats_transformed
148 logElab 5 $ "Initial typechecked patterns:\n" ++ show pats_raw
162 logElab 5 $ "Initial typechecked patterns:\n" ++ show pats_raw
@@ -171,12 +185,12 @@ elabClauses info' fc opts n_in cs =
171 pmissing <-
185 pmissing <-
172 if cov && not (hasDefault pats_raw)
186 if cov && not (hasDefault pats_raw)
173 then do -- Generate clauses from the given possible cases
187 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
175 -- missing <- genMissing n scargs sc
189 -- missing <- genMissing n scargs sc
176 missing' <- filterM (checkPossible info fc True n) missing
190 missing' <- filterM (checkPossible info fc True n) missing
177 -- Filter out the ones which match one of the
191 -- Filter out the ones which match one of the
178 -- given cases (including impossible ones)
192 -- given cases (including impossible ones)
179− let clhs = map getLHS pdef
193+ let clhs = map getLHS pdef_cov
180 logElab 2 $ "Must be unreachable:\n" ++
194 logElab 2 $ "Must be unreachable:\n" ++
181 showSep "\n" (map showTmImpls missing') ++
195 showSep "\n" (map showTmImpls missing') ++
182 "\nAgainst: " ++
196 "\nAgainst: " ++
@@ -228,6 +242,7 @@ elabClauses info' fc opts n_in cs =
228 putIState (ist { idris_patdefs = addDef n (force pdef_pe, force pmissing)
242 putIState (ist { idris_patdefs = addDef n (force pdef_pe, force pmissing)
229 (idris_patdefs ist) })
243 (idris_patdefs ist) })
230 let caseInfo = CaseInfo (inlinable opts) (inlinable opts) (dictionary opts)
244 let caseInfo = CaseInfo (inlinable opts) (inlinable opts) (dictionary opts)
231 case lookupTyExact n ctxt of
246 case lookupTyExact n ctxt of
232 Just ty ->
247 Just ty ->
233 do ctxt' <- do ctxt <- getContext
248 do ctxt' <- do ctxt <- getContext
@@ -238,7 +253,7 @@ elabClauses info' fc opts n_in cs =
238 (AssertTotal `elem` opts)
253 (AssertTotal `elem` opts)
241− pats_pe
256+ pats_forced
@@ -329,9 +344,13 @@ elabClauses info' fc opts n_in cs =
330 -- Simplify the left hand side of a definition, to remove any lets
345 -- Simplify the left hand side of a definition, to remove any lets
331 -- that may have arisen during elaboration
346 -- that may have arisen during elaboration
347+ simple_lhs ctxt (Right (x, y))
332− simple_lhs ctxt (Right (x, y)) = Right (Idris.Core.Evaluate.simplify ctxt [] x, y)
348+ = Right (Idris.Core.Evaluate.simplify ctxt [] x, y)
333 simple_lhs ctxt t = t
349 simple_lhs ctxt t = t
351+ force_lhs opts (Right (x, y)) = Right (forceWith opts x, y)
352+ force_lhs opts t = t
335 simple_rt ctxt (p, x, y) = (p, x, force (uniqueBinders p
354 simple_rt ctxt (p, x, y) = (p, x, force (uniqueBinders p
336 (rt_simplify ctxt [] y)))
355 (rt_simplify ctxt [] y)))
@@ -354,6 +373,28 @@ elabClauses info' fc opts n_in cs =
354 Just t -> return t
373 Just t -> return t
355 Nothing -> ierror (At fc (Msg "No specialisation achieved"))
374 Nothing -> ierror (At fc (Msg "No specialisation achieved"))
376+forceWith :: Ctxt OptInfo -> Term -> Term
377+forceWith opts lhs = -- trace (show lhs ++ "\n==>\n" ++ show (force lhs) ++ "\n----") $
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')
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
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 _ [] = []
357-- | Find 'static' applications in a term and partially evaluate them.
398-- | Find 'static' applications in a term and partially evaluate them.
358-- Return any new transformation rules
399-- Return any new transformation rules
359elabPE :: ElabInfo -> FC -> Name -> Term -> Idris [(Term, Term)]
400elabPE :: 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
667 then recheckC_borrowing False (PEGenerated `notElem` opts)
708 then recheckC_borrowing False (PEGenerated `notElem` opts)
668 [] (constraintNS info) fc id [] lhs_tm
709 [] (constraintNS info) fc id [] lhs_tm
669 else return (lhs_tm, lhs_ty)
710 else return (lhs_tm, lhs_ty)
670− let clhs = Idris.Core.Evaluate.simplify ctxt [] clhs_c
711+ let clhs = normalise ctxt [] clhs_c
671 let borrowed = borrowedNames [] clhs
712 let borrowed = borrowedNames [] clhs
673 -- These are the names we're not allowed to use on the RHS, because
714 -- 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)
925 let ret_ty = getRetTy (explicitNames (normalise ctxt [] lhs_ty))
966 let ret_ty = getRetTy (explicitNames (normalise ctxt [] lhs_ty))
926 let static_names = getStaticNames i lhs_tm
967 let static_names = getStaticNames i lhs_tm
927 logElab 5 (show lhs_tm ++ "\n" ++ show static_names)
968 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
929 logElab 5 ("Checked " ++ show clhs)
972 logElab 5 ("Checked " ++ show clhs)
930 let bargs = getPBtys (explicitNames (normalise ctxt [] lhs_tm))
973 let bargs = getPBtys (explicitNames (normalise ctxt [] lhs_tm))
931 let wval = rhs_trans info $ addImplBound i (map fst bargs) wval_in
974 let wval = rhs_trans info $ addImplBound i (map fst bargs) wval_in