Skip to content

Commit 7ca34d1

Browse files
authored
[ fix ] False positives checking for conflicts in coverage checking (#3478)
* [ fix ] expand functions when checking for impossibility * [ fix ] don't compare incompatible spines * [ fix ] Krivine was relying on false positive for impossible * improve code clarity
1 parent e33de48 commit 7ca34d1

File tree

6 files changed

+40
-17
lines changed

6 files changed

+40
-17
lines changed

libs/papers/Language/IntrinsicTyping/Krivine.idr

+2
Original file line numberDiff line numberDiff line change
@@ -522,13 +522,15 @@ namespace Machine
522522
public export
523523
vlam0 : (eq : ctx = []) -> (tr : Trace (Lam sc) env ctx) -> tr ~=~ Machine.Done {sc, env}
524524
vlam0 eq Done = Refl
525+
vlam0 eq (Beta {arg = Element _ _, ctx = Element _ _} _) impossible
525526

526527
public export
527528
vlamS : {0 env : ValidEnv g} -> {0 arg : ValidClosed a} ->
528529
{0 sc : Term (a :: g) b} -> {0 ctx' : ValidEvalContext b c} ->
529530
(eq : ctx = ValidEvalContext.(::) arg ctx') ->
530531
(tr : Trace (Lam sc) env ctx) ->
531532
(tr' : Trace sc (arg :: env) ctx' ** tr ~=~ Machine.Beta {sc, arg, env} tr')
533+
vlamS {arg = (Element _ _)} {ctx' = (Element _ _)} eq Done impossible
532534
vlamS eq (Beta tr) with 0 (fst (biinjective @{CONS} eq))
533535
_ | Refl with 0 (snd (biinjective @{CONS} eq))
534536
_ | Refl = (tr ** Refl)

src/Core/Coverage.idr

+19-16
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,21 @@ conflictMatch : {vars : _} -> List (Name, Term vars) -> Bool
2424
conflictMatch [] = False
2525
conflictMatch ((x, tm) :: ms) = conflictArgs x tm ms || conflictMatch ms
2626
where
27-
clash : Term vars -> Term vars -> Bool
27+
data ClashResult = Distinct | Same | Incomparable
28+
29+
clash : Term vars -> Term vars -> ClashResult
2830
clash (Ref _ (DataCon t _) _) (Ref _ (DataCon t' _) _)
29-
= t /= t'
31+
= if t /= t' then Distinct else Same
3032
clash (Ref _ (TyCon t _) _) (Ref _ (TyCon t' _) _)
31-
= t /= t'
32-
clash (PrimVal _ c) (PrimVal _ c')
33-
= c /= c'
34-
clash (Ref _ t _) (PrimVal _ _) = isJust (isCon t)
35-
clash (PrimVal _ _) (Ref _ t _) = isJust (isCon t)
36-
clash (Ref _ t _) (TType _ _) = isJust (isCon t)
37-
clash (TType _ _) (Ref _ t _) = isJust (isCon t)
38-
clash (TType _ _) (PrimVal _ _) = True
39-
clash (PrimVal _ _) (TType _ _) = True
40-
clash _ _ = False
33+
= if t /= t' then Distinct else Same
34+
clash (PrimVal _ c) (PrimVal _ c') = if c /= c' then Distinct else Same
35+
clash (Ref _ t _) (PrimVal _ _) = if isJust (isCon t) then Distinct else Incomparable
36+
clash (PrimVal _ _) (Ref _ t _) = if isJust (isCon t) then Distinct else Incomparable
37+
clash (Ref _ t _) (TType _ _) = if isJust (isCon t) then Distinct else Incomparable
38+
clash (TType _ _) (Ref _ t _) = if isJust (isCon t) then Distinct else Incomparable
39+
clash (TType _ _) (PrimVal _ _) = Distinct
40+
clash (PrimVal _ _) (TType _ _) = Distinct
41+
clash _ _ = Incomparable
4142

4243
findN : Nat -> Term vars -> Bool
4344
findN i (Local _ _ i' _) = i == i'
@@ -60,7 +61,10 @@ conflictMatch ((x, tm) :: ms) = conflictArgs x tm ms || conflictMatch ms
6061
conflictTm tm tm'
6162
= let (f, args) = getFnArgs tm
6263
(f', args') = getFnArgs tm' in
63-
clash f f' || any (uncurry conflictTm) (zip args args')
64+
case clash f f' of
65+
Distinct => True
66+
Incomparable => False
67+
Same => (any (uncurry conflictTm) (zip args args'))
6468

6569
conflictArgs : Name -> Term vars -> List (Name, Term vars) -> Bool
6670
conflictArgs n tm [] = False
@@ -107,13 +111,12 @@ conflict defs env nfty n
107111
conflictNF i t (NBind fc x b sc)
108112
-- invent a fresh name, in case a user has bound the same name
109113
-- twice somehow both references appear in the result it's unlikely
110-
-- put posslbe
114+
-- put possible
111115
= let x' = MN (show x) i in
112116
conflictNF (i + 1) t
113117
!(sc defs (toClosure defaultOpts [] (Ref fc Bound x')))
114118
conflictNF i nf (NApp _ (NRef Bound n) [])
115-
= do empty <- clearDefs defs
116-
pure (Just [(n, !(quote empty env nf))])
119+
= pure (Just [(n, !(quote defs env nf))])
117120
conflictNF i (NDCon _ n t a args) (NDCon _ n' t' a' args')
118121
= if t == t'
119122
then conflictArgs i (map snd args) (map snd args')

src/TTImp/ProcessDef.idr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,9 @@ processDef opts nest env fc n_in cs_in
11181118
pure (Just rtm))
11191119
(\err => do defs <- get Ctxt
11201120
if not !(recoverableErr defs err)
1121-
then pure Nothing
1121+
then do
1122+
log "declare.def.impossible" 5 "impossible because \{show err}"
1123+
pure Nothing
11221124
else pure (Just tm))
11231125
where
11241126
closeEnv : Defs -> NF [] -> Core ClosedTerm
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test : (xs : List Int) -> 2 = length xs -> (Int, Int)
2+
test (x1 :: x2 :: x3 :: []) pf = (x1, x2)
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
1/1: Building Issue3477 (Issue3477.idr)
2+
Error: test is not covering.
3+
4+
Issue3477:1:1--1:55
5+
1 | test : (xs : List Int) -> 2 = length xs -> (Int, Int)
6+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7+
8+
Missing cases:
9+
test [_, _] _
10+

tests/idris2/coverage/coverage022/run

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
. ../../../testutils.sh
2+
3+
# expect a coverage error
4+
check Issue3477.idr

0 commit comments

Comments
 (0)