From be40c431fed79d1184609ad638a86c9e9f60e7db Mon Sep 17 00:00:00 2001 From: Steve Dunham Date: Mon, 6 Oct 2025 15:20:44 -0700 Subject: [PATCH] Add error when a constructor is used for a primitive argument. Add testing for errors. --- scripts/test | 12 ++++++++- src/Lib/Elab.newt | 17 +++++++------ tests/LitConCase.newt | 8 ++++++ tests/LitConCase.newt.fail | 9 +++++++ tests/TestMap.newt.golden | 50 +++++++++++++++++++------------------- 5 files changed, 62 insertions(+), 34 deletions(-) create mode 100644 tests/LitConCase.newt create mode 100644 tests/LitConCase.newt.fail diff --git a/scripts/test b/scripts/test index b7063d5..b6e1475 100755 --- a/scripts/test +++ b/scripts/test @@ -14,9 +14,18 @@ for fn in tests/*.newt ; do # we've dropped support for compiling things without main for now. $NCC $fn > tmp/${bn}.compile fi - if [ $? != "0" ]; then + cerr=$? + if [ -f ${fn}.fail ]; then + if ! diff -q tmp/${bn}.compile ${fn}.fail; then + echo "Compile failure mismatch for $fn" + diff tmp/${bn}.comp ${fn}.fail + failed=$((failed + 1)) + continue + fi + elif [ $cerr != "0" ]; then echo Compile failed for $fn failed=$((failed + 1)) + cat tmp/${bn}.compile continue fi # if there is a golden file, run the code and compare output @@ -29,6 +38,7 @@ for fn in tests/*.newt ; do fi if ! diff -q tmp/${bn}.out ${fn}.golden; then echo "Output mismatch for $fn" + diff -q tmp/${bn}.out ${fn}.golden failed=$((failed + 1)) fi fi diff --git a/src/Lib/Elab.newt b/src/Lib/Elab.newt index 9217cdd..6bc07b0 100644 --- a/src/Lib/Elab.newt +++ b/src/Lib/Elab.newt @@ -966,7 +966,7 @@ buildCase ctx prob scnm scty (dcName, arity, ty) = do case lookup nm top of (Just (MkEntry _ name type (DCon _ _ k tcname) _)) => if (tcname /= sctynm) - then error fc "Constructor is \{show tcname} expected \{show sctynm}" + then error fc "Constructor is a \{show tcname} expected a \{show sctynm}" else pure Nothing Just _ => error fc "Internal Error: \{show nm} is not a DCon" Nothing => error fc "Internal Error: DCon \{show nm} not found" @@ -1096,11 +1096,12 @@ checkDone ctx ((x, pat) :: xs) body ty = error (getFC pat) "stray constraint \{x -- need to run constructors, then run default -- wild/var can come before 'x' so we need a list first -getLits : String -> List Clause -> List Literal -getLits nm Nil = Nil -getLits nm ((MkClause fc cons pats expr) :: cs) = case find ((_==_ nm) ∘ fst) cons of - Just (_, (PatLit _ lit)) => lit :: getLits nm cs - _ => getLits nm cs +getLits : Val -> String -> List Clause -> M (List Literal) +getLits ty nm Nil = pure Nil +getLits ty nm ((MkClause fc cons pats expr) :: cs) = case find ((_==_ nm) ∘ fst) cons of + Just (_, (PatLit _ lit)) => _::_ lit <$> getLits ty nm cs + Just (_, (PatCon fc _ _ _ _)) => error fc "expected \{show ty}" + _ => getLits ty nm cs -- collect constructors that are matched on matchedConstructors : String → List Clause → List QName @@ -1160,7 +1161,7 @@ buildDefault ctx prob fc scnm missing = do buildLitCases : Context -> Problem -> FC -> String -> Val -> M (List CaseAlt) buildLitCases ctx prob fc scnm scty = do - let lits = nub $ getLits scnm prob.clauses + lits <- nub <$> getLits scty scnm prob.clauses alts <- traverse (buildLitCase ctx prob fc scnm scty) lits let defclauses = filter isDefault prob.clauses @@ -1173,7 +1174,7 @@ buildLitCases ctx prob fc scnm scty = do isDefault cl = case find ((_==_ scnm) ∘ fst) cl.cons of Just (_, (PatVar _ _ _)) => True Just (_, (PatWild _ _)) => True - Nothing => True + Nothing => True -- can this happen? _ => False -- TODO - figure out if these need to be in Prelude or have a special namespace diff --git a/tests/LitConCase.newt b/tests/LitConCase.newt new file mode 100644 index 0000000..b2e05c1 --- /dev/null +++ b/tests/LitConCase.newt @@ -0,0 +1,8 @@ +module LitConCase + +data Unit = MkUnit + +foo : Int → Unit +foo 0 = MkUnit +foo MkUnit = MkUnit +foo _ = MkUnit diff --git a/tests/LitConCase.newt.fail b/tests/LitConCase.newt.fail new file mode 100644 index 0000000..fb1dc6c --- /dev/null +++ b/tests/LitConCase.newt.fail @@ -0,0 +1,9 @@ +*** Process tests/LitConCase.newt +module LitConCase +ERROR at tests/LitConCase.newt:(7, 5): expected Prim.Int + foo : Int → Unit + foo 0 = MkUnit + foo MkUnit = MkUnit + ^ + +Compile failed diff --git a/tests/TestMap.newt.golden b/tests/TestMap.newt.golden index 7183cff..d1018b3 100644 --- a/tests/TestMap.newt.golden +++ b/tests/TestMap.newt.golden @@ -1,44 +1,44 @@ -[(2, 0)] -[] -[(2, 3)] -[(1, 3), (2, 0)] -[(0, "MkUnit"), (1, "MkUnit"), (2, "MkUnit"), (3, "MkUnit"), (4, "MkUnit"), (5, "MkUnit"), (6, "MkUnit"), (7, "MkUnit"), (8, "MkUnit"), (9, "MkUnit"), (10, "MkUnit"), (11, "MkUnit"), (12, "MkUnit"), (13, "MkUnit"), (14, "MkUnit"), (16, "MkUnit"), (17, "MkUnit"), (20, "MkUnit")] -(Just _ (0, "MkUnit")) -(Just _ (20, "MkUnit")) +(1 _ {"tag":0,"h0":null,"h1":null,"h2":2,"h3":0} {"tag":0,"h0":null}) +{"tag":0,"h0":null} +(1 _ {"tag":0,"h0":null,"h1":null,"h2":2,"h3":3} {"tag":0,"h0":null}) +(1 _ {"tag":0,"h0":null,"h1":null,"h2":1,"h3":3} (1 _ {"tag":0,"h0":null,"h1":null,"h2":2,"h3":0} {"tag":0,"h0":null})) +(1 _ {"tag":0,"h0":null,"h1":null,"h2":0,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":1,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":2,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":3,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":4,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":5,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":6,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":7,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":8,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":9,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":10,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":11,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":12,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":13,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":14,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":16,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":17,"h3":0} (1 _ {"tag":0,"h0":null,"h1":null,"h2":20,"h3":0} {"tag":0,"h0":null})))))))))))))))))) +{"tag":0,"h0":null,"h1":{"tag":0,"h0":null,"h1":null,"h2":0,"h3":0}} +{"tag":0,"h0":null,"h1":{"tag":0,"h0":null,"h1":null,"h2":20,"h3":0}} ohne 4 -[0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 1 -[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 5 -[0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 7 -[0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 2 -[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 9 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 3 -[0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 10 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 6 -[0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 0 -[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 11 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 12 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 13 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 20 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 {"tag":0,"h0":null}))))))))))))))))) ohne 14 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 16 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 17 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 17 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 8 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 20 {"tag":0,"h0":null}))))))))))))))))) ohne 8 -[0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 17, 20] +(1 _ 0 (1 _ 1 (1 _ 2 (1 _ 3 (1 _ 4 (1 _ 5 (1 _ 6 (1 _ 7 (1 _ 9 (1 _ 10 (1 _ 11 (1 _ 12 (1 _ 13 (1 _ 14 (1 _ 16 (1 _ 17 (1 _ 20 {"tag":0,"h0":null})))))))))))))))))