diff --git a/compiler/desugared/linting.mli b/compiler/desugared/linting.mli new file mode 100644 index 00000000..9d60f78c --- /dev/null +++ b/compiler/desugared/linting.mli @@ -0,0 +1,19 @@ +(* This file is part of the Catala compiler, a specification language for tax + and social benefits computation rules. Copyright (C) 2023 Inria, contributor: + Denis Merigoux + + Licensed under the Apache License, Version 2.0 (the "License"); you may not + use this file except in compliance with the License. You may obtain a copy of + the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations under + the License. *) + +val lint_program : Ast.program -> unit +(** Performs various lints on the program, displaying warnings to help the + developer improve the code. *) diff --git a/tests/test_enum/bad/missing_case.catala_en b/tests/test_enum/bad/missing_case.catala_en index 4f98ef14..f46837e0 100644 --- a/tests/test_enum/bad/missing_case.catala_en +++ b/tests/test_enum/bad/missing_case.catala_en @@ -18,6 +18,13 @@ scope A: ```catala-test-inline $ catala Interpret -s A +[WARNING] The constructor "Case3" of enumeration "E" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_enum/bad/missing_case.catala_en:7.5-10: +└─┐ +7 │ -- Case3 + │ ‾‾‾‾‾ + └─ Article [ERROR] The constructor Case3 of enum E is missing from this pattern matching ┌─⯈ tests/test_enum/bad/missing_case.catala_en:14.24-16.21: diff --git a/tests/test_proof/bad/enums-empty.catala_en b/tests/test_proof/bad/enums-empty.catala_en index 36b39796..e72a6134 100644 --- a/tests/test_proof/bad/enums-empty.catala_en +++ b/tests/test_proof/bad/enums-empty.catala_en @@ -23,6 +23,13 @@ scope A: ```catala-test-inline $ catala Proof --disable_counterexamples +[WARNING] The constructor "C" of enumeration "T" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_proof/bad/enums-empty.catala_en:7.6-7: +└─┐ +7 │ -- C content boolean + │ ‾ + └─ Test [ERROR] [A.x] This variable might return an empty error: ┌─⯈ tests/test_proof/bad/enums-empty.catala_en:15.10-11: └──┐ diff --git a/tests/test_proof/bad/enums-nonbool-empty.catala_en b/tests/test_proof/bad/enums-nonbool-empty.catala_en index 6b8fd5ad..6683a610 100644 --- a/tests/test_proof/bad/enums-nonbool-empty.catala_en +++ b/tests/test_proof/bad/enums-nonbool-empty.catala_en @@ -21,6 +21,13 @@ scope A: ```catala-test-inline $ catala Proof --disable_counterexamples +[WARNING] The constructor "C" of enumeration "T" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_proof/bad/enums-nonbool-empty.catala_en:5.6-7: +└─┐ +5 │ -- C content boolean + │ ‾ + └─ Test [ERROR] [A.x] This variable might return an empty error: ┌─⯈ tests/test_proof/bad/enums-nonbool-empty.catala_en:13.10-11: └──┐ diff --git a/tests/test_proof/bad/enums-nonbool-overlap.catala_en b/tests/test_proof/bad/enums-nonbool-overlap.catala_en index bb19c9b9..add115b9 100644 --- a/tests/test_proof/bad/enums-nonbool-overlap.catala_en +++ b/tests/test_proof/bad/enums-nonbool-overlap.catala_en @@ -21,6 +21,13 @@ scope A: ```catala-test-inline $ catala Proof --disable_counterexamples +[WARNING] The constructor "C" of enumeration "T" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_proof/bad/enums-nonbool-overlap.catala_en:5.6-7: +└─┐ +5 │ -- C content boolean + │ ‾ + └─ Test [ERROR] [A.x] At least two exceptions overlap for this variable: ┌─⯈ tests/test_proof/bad/enums-nonbool-overlap.catala_en:13.10-11: └──┐ diff --git a/tests/test_proof/bad/enums-overlap.catala_en b/tests/test_proof/bad/enums-overlap.catala_en index e241f823..7d8e6880 100644 --- a/tests/test_proof/bad/enums-overlap.catala_en +++ b/tests/test_proof/bad/enums-overlap.catala_en @@ -23,6 +23,13 @@ scope A: ```catala-test-inline $ catala Proof --disable_counterexamples +[WARNING] The constructor "C" of enumeration "T" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_proof/bad/enums-overlap.catala_en:7.6-7: +└─┐ +7 │ -- C content boolean + │ ‾ + └─ Test [ERROR] [A.x] At least two exceptions overlap for this variable: ┌─⯈ tests/test_proof/bad/enums-overlap.catala_en:15.10-11: └──┐ diff --git a/tests/test_proof/bad/enums_inj-empty.catala_en b/tests/test_proof/bad/enums_inj-empty.catala_en index 57382389..9125403f 100644 --- a/tests/test_proof/bad/enums_inj-empty.catala_en +++ b/tests/test_proof/bad/enums_inj-empty.catala_en @@ -16,6 +16,13 @@ scope A: ```catala-test-inline $ catala Proof --disable_counterexamples +[WARNING] The constructor "C2" of enumeration "E" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_proof/bad/enums_inj-empty.catala_en:6.5-7: +└─┐ +6 │ -- C2 + │ ‾‾ + └─ Article [ERROR] [A.y] This variable might return an empty error: ┌─⯈ tests/test_proof/bad/enums_inj-empty.catala_en:10.10-11: └──┐ diff --git a/tests/test_proof/good/enums-arith.catala_en b/tests/test_proof/good/enums-arith.catala_en index c69c2138..70194087 100644 --- a/tests/test_proof/good/enums-arith.catala_en +++ b/tests/test_proof/good/enums-arith.catala_en @@ -21,5 +21,12 @@ scope A: ```catala-test-inline $ catala Proof --disable_counterexamples +[WARNING] The constructor "C" of enumeration "T" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_proof/good/enums-arith.catala_en:5.6-7: +└─┐ +5 │ -- C content boolean + │ ‾ + └─ Test [RESULT] No errors found during the proof mode run. ``` diff --git a/tests/test_proof/good/enums-nonbool.catala_en b/tests/test_proof/good/enums-nonbool.catala_en index 2c89b7e4..da0af638 100644 --- a/tests/test_proof/good/enums-nonbool.catala_en +++ b/tests/test_proof/good/enums-nonbool.catala_en @@ -21,5 +21,12 @@ scope A: ```catala-test-inline $ catala Proof --disable_counterexamples +[WARNING] The constructor "C" of enumeration "T" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_proof/good/enums-nonbool.catala_en:5.6-7: +└─┐ +5 │ -- C content boolean + │ ‾ + └─ Test [RESULT] No errors found during the proof mode run. ``` diff --git a/tests/test_proof/good/enums.catala_en b/tests/test_proof/good/enums.catala_en index 64d53462..c727a91e 100644 --- a/tests/test_proof/good/enums.catala_en +++ b/tests/test_proof/good/enums.catala_en @@ -20,5 +20,12 @@ scope A: ``` ```catala-test-inline $ catala Proof --disable_counterexamples +[WARNING] The constructor "C" of enumeration "T" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_proof/good/enums.catala_en:5.6-7: +└─┐ +5 │ -- C content boolean + │ ‾ + └─ Test [RESULT] No errors found during the proof mode run. ``` diff --git a/tests/test_scope/good/nothing.catala_en b/tests/test_scope/good/nothing.catala_en index 05410a23..b7985dce 100644 --- a/tests/test_scope/good/nothing.catala_en +++ b/tests/test_scope/good/nothing.catala_en @@ -7,6 +7,13 @@ declaration scope Foo2: ```catala-test-inline $ catala Scalc -s Foo2 -O -t +[WARNING] The variable "bar" is declared but never defined in scope "Foo2"; did you forget something? + +┌─⯈ tests/test_scope/good/nothing.catala_en:5.9-12: +└─┐ +5 │ output bar content integer + │ ‾‾‾ + └─ Test let Foo2_3 (Foo2_in_2: Foo2_in {}) = decl temp_bar_4 : any; temp_bar_4 = dead_value_1; diff --git a/tests/test_scope/good/scope_call.catala_en b/tests/test_scope/good/scope_call.catala_en index 8fe9b35f..8773a990 100644 --- a/tests/test_scope/good/scope_call.catala_en +++ b/tests/test_scope/good/scope_call.catala_en @@ -26,6 +26,20 @@ scope Foo: ```catala-test-inline $ catala interpret -s Foo +[WARNING] The field "z2" of struct "Test" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_scope/good/scope_call.catala_en:3.9-11: +└─┐ +3 │ data z2 content integer + │ ‾‾ + +[WARNING] The field "z3" of struct "Test" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_scope/good/scope_call.catala_en:4.9-11: +└─┐ +4 │ data z3 content integer + │ ‾‾ + [RESULT] Computation successful! Results: [RESULT] example = -7 ``` diff --git a/tests/test_struct/bad/nested.catala_en b/tests/test_struct/bad/nested.catala_en index d354d270..395e15f6 100644 --- a/tests/test_struct/bad/nested.catala_en +++ b/tests/test_struct/bad/nested.catala_en @@ -14,6 +14,13 @@ scope A: ```catala-test-inline $ catala Interpret -s A +[WARNING] The constructor "Rec" of enumeration "E" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_struct/bad/nested.catala_en:6.5-8: +└─┐ +6 │ -- Rec content E + │ ‾‾‾ + └─ Article [ERROR] The type E is defined using itself, which is forbidden since Catala does not provide recursive types ┌─⯈ tests/test_struct/bad/nested.catala_en:6.17-18: diff --git a/tests/test_struct/bad/nested2.catala_en b/tests/test_struct/bad/nested2.catala_en index 21d07694..a6407332 100644 --- a/tests/test_struct/bad/nested2.catala_en +++ b/tests/test_struct/bad/nested2.catala_en @@ -15,6 +15,27 @@ declaration scope A: ```catala-test-inline $ catala Interpret -s A +[WARNING] The field "x" of struct "S" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_struct/bad/nested2.catala_en:5.7-8: +└─┐ +5 │ data x content E + │ ‾ + └─ Article +[WARNING] The field "y" of struct "S" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_struct/bad/nested2.catala_en:6.7-8: +└─┐ +6 │ data y content integer + │ ‾ + └─ Article +[WARNING] The enumeration "E" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_struct/bad/nested2.catala_en:8.24-25: +└─┐ +8 │ declaration enumeration E: + │ ‾ + └─ Article [ERROR] Cyclic dependency detected between types! Cycle type S, declared: diff --git a/tests/test_struct/bad/wrong_qualified_field.catala_en b/tests/test_struct/bad/wrong_qualified_field.catala_en index df65d2a6..4b9d592f 100644 --- a/tests/test_struct/bad/wrong_qualified_field.catala_en +++ b/tests/test_struct/bad/wrong_qualified_field.catala_en @@ -19,7 +19,7 @@ scope A: ```catala-test-inline $ catala Interpret -s A -[ERROR] Field g does not belong to structure Foo, but to Bar +[ERROR] Field "g" does not belong to structure "Foo", but to "Bar" ┌─⯈ tests/test_struct/bad/wrong_qualified_field.catala_en:17.22-29: └──┐ diff --git a/tests/test_struct/good/ambiguous_fields.catala_en b/tests/test_struct/good/ambiguous_fields.catala_en index ee8a81fe..45cc1e61 100644 --- a/tests/test_struct/good/ambiguous_fields.catala_en +++ b/tests/test_struct/good/ambiguous_fields.catala_en @@ -18,5 +18,12 @@ scope A: ```catala-test-inline $ catala Interpret -s A +[WARNING] The field "f" of struct "Bar" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_struct/good/ambiguous_fields.catala_en:8.7-8: +└─┐ +8 │ data f content integer + │ ‾ + └─ Article [RESULT] Computation successful! ``` diff --git a/tests/test_struct/good/same_name_fields.catala_en b/tests/test_struct/good/same_name_fields.catala_en index 4a23c955..66c65f0e 100644 --- a/tests/test_struct/good/same_name_fields.catala_en +++ b/tests/test_struct/good/same_name_fields.catala_en @@ -18,6 +18,13 @@ scope A: ```catala-test-inline $ catala Interpret -s A +[WARNING] The field "f" of struct "Bar" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_struct/good/same_name_fields.catala_en:8.7-8: +└─┐ +8 │ data f content integer + │ ‾ + └─ Article [RESULT] Computation successful! Results: [RESULT] x = Foo { "f"= 1 } [RESULT] y = 1 diff --git a/tests/test_typing/bad/err3.catala_en b/tests/test_typing/bad/err3.catala_en index 04cdd814..c152b64a 100644 --- a/tests/test_typing/bad/err3.catala_en +++ b/tests/test_typing/bad/err3.catala_en @@ -12,6 +12,13 @@ scope S: ```catala-test-inline $ catala Typecheck +[WARNING] The constructor "Dec" of enumeration "Enum" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_typing/bad/common.catala_en:4.5-8: +└─┐ +4 │ -- Dec content decimal + │ ‾‾‾ + [ERROR] Error during typechecking, incompatible types: --> integer --> decimal @@ -43,6 +50,13 @@ Re-putting the same check again, to ensure that the `Typecheck` and `ocaml` subc ```catala-test-inline $ catala ocaml +[WARNING] The constructor "Dec" of enumeration "Enum" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_typing/bad/common.catala_en:4.5-8: +└─┐ +4 │ -- Dec content decimal + │ ‾‾‾ + [ERROR] Error during typechecking, incompatible types: --> integer --> decimal diff --git a/tests/test_typing/bad/err4.catala_en b/tests/test_typing/bad/err4.catala_en index ec25f415..5bb392a5 100644 --- a/tests/test_typing/bad/err4.catala_en +++ b/tests/test_typing/bad/err4.catala_en @@ -10,6 +10,34 @@ Should be "catala Typecheck", see test err3 ```catala-test-inline $ catala ocaml +[WARNING] The field "i" of struct "Structure" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_typing/bad/common.catala_en:8.7-8: +└─┐ +8 │ data i content integer + │ ‾ + +[WARNING] The field "e" of struct "Structure" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_typing/bad/common.catala_en:9.7-8: +└─┐ +9 │ data e content Enum + │ ‾ + +[WARNING] The constructor "Dec" of enumeration "Enum" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_typing/bad/common.catala_en:4.5-8: +└─┐ +4 │ -- Dec content decimal + │ ‾‾‾ + +[WARNING] The constructor "Dat" of enumeration "Enum" is never used; maybe it's unnecessary? + +┌─⯈ tests/test_typing/bad/common.catala_en:5.5-8: +└─┐ +5 │ -- Dat content date + │ ‾‾‾ + [ERROR] Error during typechecking, incompatible types: --> Enum --> Structure