From 43f1a1b64f394042b5ddf2ca1ae89e8bc3c2ff0a Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Sun, 23 Aug 2026 11:05:17 +0200 Subject: [PATCH 01/16] [src] add 5.4 compatibility This relies on cppo. Compilation issues are naively fixed. No error is introduced in the tests. The project-configuration files (dune, opam, ci) have been updated. --- .github/workflows/workflow.yml | 5 ++++- README.md | 3 ++- dead_code_analyzer.opam | 3 ++- dune-project | 3 ++- src/deadArg.ml | 20 +++++++++++++++++++- src/deadArg.mli | 11 +++++++++++ src/deadCode.ml | 16 +++++++++++++--- src/deadLexiFi.ml | 8 +++++++- src/deadObj.ml | 7 ++++++- src/deadSign.ml | 16 +++++++++++++++- src/dune | 4 +++- 11 files changed, 84 insertions(+), 12 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 190eb0aa..790981f8 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -15,6 +15,9 @@ jobs: - ubuntu-latest - macos-latest - windows-latest + ocaml: + - "5.3" + - "5.4" runs-on: ${{ matrix.os }} @@ -25,7 +28,7 @@ jobs: - name: Set-up OCaml uses: ocaml/setup-ocaml@v3 with: - ocaml-compiler: "5.3" + ocaml-compiler: ${{ matrix.ocaml }} - run: opam install . --deps-only --with-test diff --git a/README.md b/README.md index a91ee50a..72398cc1 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,9 @@ For more information, see the [User documentation](docs/USER_DOC.md) ## Requirements -- Currently tested and working on **OCaml 5.3** +- Currently tested and working on **OCaml 5.3 & 5.4** - **dune >= 3.20** +- **cppo** ## Install diff --git a/dead_code_analyzer.opam b/dead_code_analyzer.opam index 845ff95e..ae82d587 100644 --- a/dead_code_analyzer.opam +++ b/dead_code_analyzer.opam @@ -15,7 +15,8 @@ homepage: "https://github.com/LexiFi/dead_code_analyzer" bug-reports: "https://github.com/LexiFi/dead_code_analyzer/issues" depends: [ "dune" {>= "3.20"} - "ocaml" {>= "5.3" & < "5.4"} + "ocaml" {>= "5.3" & < "5.5"} + "cppo" "odoc" {with-doc} ] build: [ diff --git a/dune-project b/dune-project index 16e58f49..8a44de20 100644 --- a/dune-project +++ b/dune-project @@ -22,6 +22,7 @@ (synopsis "Dead code analyzer for OCaml") (license MIT) (depends - (ocaml (and (>= 5.3) (< 5.4))) + (ocaml (and (>= 5.3) (< 5.5))) + cppo ) ) diff --git a/src/deadArg.ml b/src/deadArg.ml index 566dbaed..4a68a819 100644 --- a/src/deadArg.ml +++ b/src/deadArg.ml @@ -70,6 +70,22 @@ let deferrable_register_use label expr builddir loc last_loc count_tbl = else register_use () else register_use () +let options_of_args args = + #if OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + (* Texp_apply's args changed in OCaml 5.4, from expression option + to arg_or_omitted. This does the reverse conversion *) + let args = + List.map + (fun (lab, arg) -> + match arg with + | Arg expr -> lab, Some expr + | Omitted _ -> lab, None + ) + args + in + #endif + args + let rec register_uses builddir loc args = List.iter (fun (_, e) -> Option.iter (register_higher_order_uses builddir) e) @@ -140,7 +156,9 @@ and register_higher_order_uses builddir e = | (Tpat_var _, Texp_apply (_, args)) -> if c_lhs.pat_loc.loc_ghost && c_rhs.exp_loc.loc_ghost && expr.exp_loc.loc_ghost - then register_uses builddir ident_loc args + then + let args = options_of_args args in + register_uses builddir ident_loc args | _ -> () ) | _ -> () diff --git a/src/deadArg.mli b/src/deadArg.mli index c5b19aac..a1a08763 100644 --- a/src/deadArg.mli +++ b/src/deadArg.mli @@ -27,6 +27,17 @@ val eocb : unit -> unit locations, their respective files. [eocb] = end of code base. *) +val options_of_args : + #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) + (Asttypes.arg_label * expression option) list + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + (Asttypes.arg_label * (expression, unit) arg_or_omitted) list + #endif + -> (Asttypes.arg_label * expression option) list +(** Convert Texp_apply's args representation to its OCaml 5.3 representation. + In particular, the type of a single arg changed in OCaml 5.4, from + expression option to arg_or_omitted. This does the reverse conversion. +*) val register_uses : Lexing.position -> (Asttypes.arg_label * expression option) list -> unit diff --git a/src/deadCode.ml b/src/deadCode.ml index 63893c0e..70abc780 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -34,7 +34,9 @@ let main_files = Hashtbl.create 256 (* names -> paths *) let rec treat_exp exp args = match exp.exp_desc with - | Texp_apply (exp, in_args) -> treat_exp exp (in_args @ args) + | Texp_apply (exp, in_args) -> + let in_args = DeadArg.options_of_args in_args in + treat_exp exp (in_args @ args) | Texp_ident (_, _, {Types.val_loc = {Location.loc_start = loc; _}; _}) | Texp_field (_, _, {lbl_loc = {Location.loc_start = loc; _}; _}) -> @@ -152,8 +154,15 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - begin match p.pat_desc with | Tpat_record (l, _) -> List.iter - (fun (_, {Types.lbl_loc = {Location.loc_start = lab_loc; _}; _}, _) -> - if exported ~is_type:true sections.types lab_loc then + (fun (_, lab, _) -> + #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) + let lab : Types.label_description = lab in + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + (* The type of lab moved in OCaml 5.4 *) + let lab : Data_types.label_description = lab in + #endif + let lab_loc = lab.lbl_loc.Location.loc_start in + if exported ~is_type:true sections.types lab_loc then DeadType.collect_references lab_loc pat_loc ) l @@ -194,6 +203,7 @@ let expr super self e = | Texp_apply (exp, args) -> + let args = DeadArg.options_of_args args in if Config.must_report_opt_args state.config then treat_exp exp args; begin match exp.exp_desc with diff --git a/src/deadLexiFi.ml b/src/deadLexiFi.ml index 6f1446ea..a926d08e 100644 --- a/src/deadLexiFi.ml +++ b/src/deadLexiFi.ml @@ -129,7 +129,13 @@ module Extension = struct let rec process (p, typ, call_site) = match get_deep_desc typ with | Tarrow (_, t, _, _) -> process (p, t, call_site) - | Ttuple ts -> List.iter (fun t -> process (p, t, call_site)) ts + | Ttuple ts -> + #if OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + (* Ttuple's ts' content changed in OCaml 5.4, from type_expr to + (string option * type_expr). This does the reverse conversion *) + let ts = List.map snd ts in + #endif + List.iter (fun t -> process (p, t, call_site)) ts | Tconstr (path, ts, _) -> let name = Path.name path in let name = diff --git a/src/deadObj.ml b/src/deadObj.ml index dff43646..29c7d87f 100644 --- a/src/deadObj.ml +++ b/src/deadObj.ml @@ -317,7 +317,12 @@ let class_structure cl_struct = add_equal pat.pat_loc.Location.loc_start !last_class | _ -> () end; match pat.pat_desc with - | Tpat_alias (pat, _, _, _) -> add_aliases pat + #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) + | Tpat_alias (pat, _, _, _) -> + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + | Tpat_alias (pat, _, _, _, _) -> + #endif + add_aliases pat | _ -> () in add_aliases cl_struct.cstr_self diff --git a/src/deadSign.ml b/src/deadSign.ml index 3209518a..ccc5df69 100644 --- a/src/deadSign.ml +++ b/src/deadSign.ml @@ -173,7 +173,11 @@ let collect_export_from_structure ~path ~comp_unit structure = let id = Ident.name id in let value = value_of pat loc uid in export export_value ~path id value + #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_alias (sub_pat, id, {loc; _}, uid) -> + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + | Tpat_alias (sub_pat, id, {loc; _}, uid, _) -> + #endif let id = Ident.name id in let value = value_of pat loc uid in export export_value ~path id value; @@ -185,9 +189,19 @@ let collect_export_from_structure ~path ~comp_unit structure = | Tpat_variant (_, Some pat, _) | Tpat_lazy pat -> collect_value ~path pat - | Tpat_tuple pats + | Tpat_tuple pats -> + #if OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + (* Tpat_tuple's pats changed in OCaml 5.4, from pat list to + (string option * pat) list. This does the reverse conversion *) + let pats = List.map snd pats in + #endif + List.iter (collect_value ~path) pats | Tpat_construct (_, _, pats, _) + #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_array pats -> + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + | Tpat_array (_, pats) -> + #endif List.iter (collect_value ~path) pats | Tpat_record (fields, _) -> List.iter (fun (_, _, pat) -> collect_value ~path pat) fields diff --git a/src/dune b/src/dune index 20d1c70f..81af7f69 100644 --- a/src/dune +++ b/src/dune @@ -1,6 +1,8 @@ (executable (public_name dead_code_analyzer) (name deadCode) - (libraries compiler-libs.common)) + (libraries compiler-libs.common) + (preprocess (action (run %{bin:cppo} -V OCAML:%{ocaml_version} %{input-file}))) +) (include_subdirs unqualified) From 3db83bf38cbef445d8a2973df89e774bbaf5cfed Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Sun, 23 Aug 2026 12:12:48 +0200 Subject: [PATCH 02/16] [src] add 5.5 compatibility This relies on cppo. Compilation issues are naively fixed. FP (and corresponding FN) are introduced in the tests. The project-configuration files (dune, opam, ci) have been updated. --- .github/workflows/workflow.yml | 1 + check/classic/classic.ref | 19 ++++++-- check/internal/internal.ref | 19 ++++++-- check/threshold-1/threshold-1.ref | 53 +++++++++++++--------- check/threshold-3-0.5/threshold-3-0.5.ref | 55 +++++++++++++---------- dead_code_analyzer.opam | 2 +- dune-project | 2 +- src/deadArg.ml | 2 +- src/deadArg.mli | 2 +- src/deadCode.ml | 2 +- src/deadLexiFi.ml | 2 +- src/deadObj.ml | 2 +- src/deadSign.ml | 6 +-- src/state/location_dependencies.ml | 3 ++ 14 files changed, 109 insertions(+), 61 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 790981f8..f02f70f5 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -18,6 +18,7 @@ jobs: ocaml: - "5.3" - "5.4" + - "5.5" runs-on: ${{ matrix.os }} diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 7a356929..6f3280c8 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -179,24 +179,29 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/alias/alias_lib.mli:2: original#unused ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method +./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#unused ./examples/docs/methods/code_constructs/constructor/constructor_bin.ml:2: unused_class#unused_method +./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/factory_fun/factory_fun_bin.ml:2: unused_factory#unused_method +./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Should not be detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#reset ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#unused ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#unused ./examples/docs/methods/code_constructs/immediate_object/immediate_object_bin.ml:2: unused_obj#unused_method +./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#unused +./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Should not be detected ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#reset ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#unused @@ -234,22 +239,30 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_int +./examples/using_make/obj/class.mli:1: c#f: Should not be detected ./examples/using_make/obj/class.mli:1: c#h ./examples/using_make/obj/class_type.mli:9: c#h ./examples/using_make/obj/coerce.mli:6: p#f ./examples/using_make/obj/coerce.mli:6: p#h +./examples/using_make/obj/coerce.mli:8: c#h: Should not be detected ./examples/using_make/obj/constraint.ml:1: p#g +./examples/using_make/obj/fooCl.mli:1: p1#f: Should not be detected ./examples/using_make/obj/fooCl.mli:1: p1#g ./examples/using_make/obj/fooCl.mli:1: p1#h ./examples/using_make/obj/fooCl.mli:7: p2#h +./examples/using_make/obj/fun_class.ml:1: c#m1: Should not be detected ./examples/using_make/obj/fun_class.ml:1: c#m3 +./examples/using_make/obj/fun_obj_param.ml:1: f#m: Should not be detected ./examples/using_make/obj/fun_obj_param.ml:1: f#n +./examples/using_make/obj/inher.mli:1: p#f: Should not be detected ./examples/using_make/obj/inher.mli:1: p#h ./examples/using_make/obj/named.mli:10: c#g ./examples/using_make/obj/obj_inher.ml:1: c#g ./examples/using_make/obj/obj_inher.ml:1: c#h ./examples/using_make/obj/obj_inher.ml:19: o3#k +./examples/using_make/obj/object.ml:1: o#f: Should not be detected ./examples/using_make/obj/object.ml:1: o#h +./examples/using_make/obj/overr.mli:1: p1#f: Should not be detected ./examples/using_make/obj/overr.mli:1: p1#g ./examples/using_make/obj/overr.mli:1: p1#h ./examples/using_make/obj/overr.mli:7: p2#g @@ -732,7 +745,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 603 +Total: 616 Success: 603 -Failed: 0 -Ratio: 100.% +Failed: 13 +Ratio: 97.8896103896% diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 4a7eedfb..b2ab484b 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -131,24 +131,29 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/alias/alias_lib.mli:2: original#unused ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method +./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#unused ./examples/docs/methods/code_constructs/constructor/constructor_bin.ml:2: unused_class#unused_method +./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/factory_fun/factory_fun_bin.ml:2: unused_factory#unused_method +./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Should not be detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#reset ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#unused ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#unused ./examples/docs/methods/code_constructs/immediate_object/immediate_object_bin.ml:2: unused_obj#unused_method +./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#unused +./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Should not be detected ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#reset ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#unused @@ -186,22 +191,30 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_int +./examples/using_make/obj/class.mli:1: c#f: Should not be detected ./examples/using_make/obj/class.mli:1: c#h ./examples/using_make/obj/class_type.mli:9: c#h ./examples/using_make/obj/coerce.mli:6: p#f ./examples/using_make/obj/coerce.mli:6: p#h +./examples/using_make/obj/coerce.mli:8: c#h: Should not be detected ./examples/using_make/obj/constraint.ml:1: p#g +./examples/using_make/obj/fooCl.mli:1: p1#f: Should not be detected ./examples/using_make/obj/fooCl.mli:1: p1#g ./examples/using_make/obj/fooCl.mli:1: p1#h ./examples/using_make/obj/fooCl.mli:7: p2#h +./examples/using_make/obj/fun_class.ml:1: c#m1: Should not be detected ./examples/using_make/obj/fun_class.ml:1: c#m3 +./examples/using_make/obj/fun_obj_param.ml:1: f#m: Should not be detected ./examples/using_make/obj/fun_obj_param.ml:1: f#n +./examples/using_make/obj/inher.mli:1: p#f: Should not be detected ./examples/using_make/obj/inher.mli:1: p#h ./examples/using_make/obj/named.mli:10: c#g ./examples/using_make/obj/obj_inher.ml:1: c#g ./examples/using_make/obj/obj_inher.ml:1: c#h ./examples/using_make/obj/obj_inher.ml:19: o3#k +./examples/using_make/obj/object.ml:1: o#f: Should not be detected ./examples/using_make/obj/object.ml:1: o#h +./examples/using_make/obj/overr.mli:1: p1#f: Should not be detected ./examples/using_make/obj/overr.mli:1: p1#g ./examples/using_make/obj/overr.mli:1: p1#h ./examples/using_make/obj/overr.mli:7: p2#g @@ -684,7 +697,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 559 +Total: 572 Success: 559 -Failed: 0 -Ratio: 100.% +Failed: 13 +Ratio: 97.7272727273% diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index c82df69c..48aae011 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -425,24 +425,29 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/alias/alias_lib.mli:2: original#unused ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method +./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#unused ./examples/docs/methods/code_constructs/constructor/constructor_bin.ml:2: unused_class#unused_method +./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/factory_fun/factory_fun_bin.ml:2: unused_factory#unused_method +./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Should not be detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#reset ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#unused ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#unused ./examples/docs/methods/code_constructs/immediate_object/immediate_object_bin.ml:2: unused_obj#unused_method +./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#unused +./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Should not be detected ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#reset ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#unused @@ -480,22 +485,30 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_int +./examples/using_make/obj/class.mli:1: c#f: Should not be detected ./examples/using_make/obj/class.mli:1: c#h ./examples/using_make/obj/class_type.mli:9: c#h ./examples/using_make/obj/coerce.mli:6: p#f ./examples/using_make/obj/coerce.mli:6: p#h +./examples/using_make/obj/coerce.mli:8: c#h: Should not be detected ./examples/using_make/obj/constraint.ml:1: p#g +./examples/using_make/obj/fooCl.mli:1: p1#f: Should not be detected ./examples/using_make/obj/fooCl.mli:1: p1#g ./examples/using_make/obj/fooCl.mli:1: p1#h ./examples/using_make/obj/fooCl.mli:7: p2#h +./examples/using_make/obj/fun_class.ml:1: c#m1: Should not be detected ./examples/using_make/obj/fun_class.ml:1: c#m3 +./examples/using_make/obj/fun_obj_param.ml:1: f#m: Should not be detected ./examples/using_make/obj/fun_obj_param.ml:1: f#n +./examples/using_make/obj/inher.mli:1: p#f: Should not be detected ./examples/using_make/obj/inher.mli:1: p#h ./examples/using_make/obj/named.mli:10: c#g ./examples/using_make/obj/obj_inher.ml:1: c#g ./examples/using_make/obj/obj_inher.ml:1: c#h ./examples/using_make/obj/obj_inher.ml:19: o3#k +./examples/using_make/obj/object.ml:1: o#f: Should not be detected ./examples/using_make/obj/object.ml:1: o#h +./examples/using_make/obj/overr.mli:1: p1#f: Should not be detected ./examples/using_make/obj/overr.mli:1: p1#g ./examples/using_make/obj/overr.mli:1: p1#h ./examples/using_make/obj/overr.mli:7: p2#g @@ -510,33 +523,28 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push - +./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Not detected ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#used_by_requirement ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push - +./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Not detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#peek ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#pop -./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push - +./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Not detected ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#used ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#used_locally ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#used ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push - +./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Not detected ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#used ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#used_by_child ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#peek ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#pop -./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push - +./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Not detected ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#externally_used ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#internally_used ./examples/using_dune/preprocessed_lib/preprocessed_no_intf.ml:12: immediate#externally_used @@ -574,28 +582,29 @@ Nothing else to report in this section ./examples/using_make/advanced/mod.mli:4: p#f -./examples/using_make/obj/class.mli:1: c#f +./examples/using_make/obj/class.mli:1: c#f: Not detected ./examples/using_make/obj/class.mli:1: c#g ./examples/using_make/obj/class_type.mli:7: p#f ./examples/using_make/obj/class_type.mli:7: p#h -./examples/using_make/obj/coerce.mli:8: c#h +./examples/using_make/obj/coerce.mli:8: c#f: Should not be detected +./examples/using_make/obj/coerce.mli:8: c#h: Not detected ./examples/using_make/obj/constraint.ml:1: p#f ./examples/using_make/obj/depend.ml:8: M.c#f -./examples/using_make/obj/fooCl.mli:1: p1#f +./examples/using_make/obj/fooCl.mli:1: p1#f: Not detected ./examples/using_make/obj/fooCl.mli:7: p2#g -./examples/using_make/obj/fun_class.ml:1: c#m1 +./examples/using_make/obj/fun_class.ml:1: c#m1: Not detected ./examples/using_make/obj/fun_class.ml:1: c#m2 ./examples/using_make/obj/fun_class.ml:1: c#m4 -./examples/using_make/obj/fun_obj_param.ml:1: f#m +./examples/using_make/obj/fun_obj_param.ml:1: f#m: Not detected ./examples/using_make/obj/fun_obj_param.ml:1: f#x -./examples/using_make/obj/inher.mli:1: p#f +./examples/using_make/obj/inher.mli:1: p#f: Not detected ./examples/using_make/obj/inher.mli:1: p#g ./examples/using_make/obj/named.mli:1: p1#g ./examples/using_make/obj/named.mli:6: p2#f ./examples/using_make/obj/named.mli:10: c#f -./examples/using_make/obj/object.ml:1: o#f +./examples/using_make/obj/object.ml:1: o#f: Not detected ./examples/using_make/obj/object.ml:1: o#g -./examples/using_make/obj/overr.mli:1: p1#f +./examples/using_make/obj/overr.mli:1: p1#f: Not detected ./examples/using_make/obj/overr.mli:12: c#g Nothing else to report in this section @@ -1212,7 +1221,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1001 -Success: 1001 -Failed: 0 -Ratio: 100.% +Total: 1015 +Success: 988 +Failed: 27 +Ratio: 97.3399014778% diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 3919783a..4649ebf1 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -568,24 +568,29 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/alias/alias_lib.mli:2: original#unused ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method +./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#unused ./examples/docs/methods/code_constructs/constructor/constructor_bin.ml:2: unused_class#unused_method +./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/factory_fun/factory_fun_bin.ml:2: unused_factory#unused_method +./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Should not be detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#reset ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#unused ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#unused ./examples/docs/methods/code_constructs/immediate_object/immediate_object_bin.ml:2: unused_obj#unused_method +./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#unused +./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Should not be detected ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#reset ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#unused @@ -623,22 +628,30 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_int +./examples/using_make/obj/class.mli:1: c#f: Should not be detected ./examples/using_make/obj/class.mli:1: c#h ./examples/using_make/obj/class_type.mli:9: c#h ./examples/using_make/obj/coerce.mli:6: p#f ./examples/using_make/obj/coerce.mli:6: p#h +./examples/using_make/obj/coerce.mli:8: c#h: Should not be detected ./examples/using_make/obj/constraint.ml:1: p#g +./examples/using_make/obj/fooCl.mli:1: p1#f: Should not be detected ./examples/using_make/obj/fooCl.mli:1: p1#g ./examples/using_make/obj/fooCl.mli:1: p1#h ./examples/using_make/obj/fooCl.mli:7: p2#h +./examples/using_make/obj/fun_class.ml:1: c#m1: Should not be detected ./examples/using_make/obj/fun_class.ml:1: c#m3 +./examples/using_make/obj/fun_obj_param.ml:1: f#m: Should not be detected ./examples/using_make/obj/fun_obj_param.ml:1: f#n +./examples/using_make/obj/inher.mli:1: p#f: Should not be detected ./examples/using_make/obj/inher.mli:1: p#h ./examples/using_make/obj/named.mli:10: c#g ./examples/using_make/obj/obj_inher.ml:1: c#g ./examples/using_make/obj/obj_inher.ml:1: c#h ./examples/using_make/obj/obj_inher.ml:19: o3#k +./examples/using_make/obj/object.ml:1: o#f: Should not be detected ./examples/using_make/obj/object.ml:1: o#h +./examples/using_make/obj/overr.mli:1: p1#f: Should not be detected ./examples/using_make/obj/overr.mli:1: p1#g ./examples/using_make/obj/overr.mli:1: p1#h ./examples/using_make/obj/overr.mli:7: p2#g @@ -653,33 +666,28 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push - +./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Not detected ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#used_by_requirement ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push - +./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Not detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#peek ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#pop -./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push - +./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Not detected ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#used ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#used_locally ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#used ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push - +./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Not detected ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#used ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#used_by_child ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#peek ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#pop -./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push - +./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Not detected ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#externally_used ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#internally_used ./examples/using_dune/preprocessed_lib/preprocessed_no_intf.ml:12: immediate#externally_used @@ -717,28 +725,29 @@ Nothing else to report in this section ./examples/using_make/advanced/mod.mli:4: p#f -./examples/using_make/obj/class.mli:1: c#f +./examples/using_make/obj/class.mli:1: c#f: Not detected ./examples/using_make/obj/class.mli:1: c#g ./examples/using_make/obj/class_type.mli:7: p#f ./examples/using_make/obj/class_type.mli:7: p#h -./examples/using_make/obj/coerce.mli:8: c#h +./examples/using_make/obj/coerce.mli:8: c#f: Should not be detected +./examples/using_make/obj/coerce.mli:8: c#h: Not detected ./examples/using_make/obj/constraint.ml:1: p#f ./examples/using_make/obj/depend.ml:8: M.c#f -./examples/using_make/obj/fooCl.mli:1: p1#f +./examples/using_make/obj/fooCl.mli:1: p1#f: Not detected ./examples/using_make/obj/fooCl.mli:7: p2#g -./examples/using_make/obj/fun_class.ml:1: c#m1 +./examples/using_make/obj/fun_class.ml:1: c#m1: Not detected ./examples/using_make/obj/fun_class.ml:1: c#m2 ./examples/using_make/obj/fun_class.ml:1: c#m4 -./examples/using_make/obj/fun_obj_param.ml:1: f#m +./examples/using_make/obj/fun_obj_param.ml:1: f#m: Not detected ./examples/using_make/obj/fun_obj_param.ml:1: f#x -./examples/using_make/obj/inher.mli:1: p#f +./examples/using_make/obj/inher.mli:1: p#f: Not detected ./examples/using_make/obj/inher.mli:1: p#g ./examples/using_make/obj/named.mli:1: p1#g ./examples/using_make/obj/named.mli:6: p2#f ./examples/using_make/obj/named.mli:10: c#f -./examples/using_make/obj/object.ml:1: o#f +./examples/using_make/obj/object.ml:1: o#f: Not detected ./examples/using_make/obj/object.ml:1: o#g -./examples/using_make/obj/overr.mli:1: p1#f +./examples/using_make/obj/overr.mli:1: p1#f: Not detected ./examples/using_make/obj/overr.mli:12: c#g -------- @@ -773,7 +782,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:11: factory#used_int ./examples/using_make/obj/class_type.mli:7: p#g -./examples/using_make/obj/coerce.mli:8: c#f +./examples/using_make/obj/coerce.mli:8: c#f: Not detected ./examples/using_make/obj/named.mli:1: p1#f ./examples/using_make/obj/obj_inher.ml:1: c#f -------- @@ -1613,7 +1622,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1323 -Success: 1323 -Failed: 0 -Ratio: 100.% +Total: 1337 +Success: 1309 +Failed: 28 +Ratio: 97.9057591623% diff --git a/dead_code_analyzer.opam b/dead_code_analyzer.opam index ae82d587..c7c82d99 100644 --- a/dead_code_analyzer.opam +++ b/dead_code_analyzer.opam @@ -15,7 +15,7 @@ homepage: "https://github.com/LexiFi/dead_code_analyzer" bug-reports: "https://github.com/LexiFi/dead_code_analyzer/issues" depends: [ "dune" {>= "3.20"} - "ocaml" {>= "5.3" & < "5.5"} + "ocaml" {>= "5.3" & < "5.6"} "cppo" "odoc" {with-doc} ] diff --git a/dune-project b/dune-project index 8a44de20..1853b014 100644 --- a/dune-project +++ b/dune-project @@ -22,7 +22,7 @@ (synopsis "Dead code analyzer for OCaml") (license MIT) (depends - (ocaml (and (>= 5.3) (< 5.5))) + (ocaml (and (>= 5.3) (< 5.6))) cppo ) ) diff --git a/src/deadArg.ml b/src/deadArg.ml index 4a68a819..7148c142 100644 --- a/src/deadArg.ml +++ b/src/deadArg.ml @@ -71,7 +71,7 @@ let deferrable_register_use label expr builddir loc last_loc count_tbl = else register_use () let options_of_args args = - #if OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + #if OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (* Texp_apply's args changed in OCaml 5.4, from expression option to arg_or_omitted. This does the reverse conversion *) let args = diff --git a/src/deadArg.mli b/src/deadArg.mli index a1a08763..7b1ef419 100644 --- a/src/deadArg.mli +++ b/src/deadArg.mli @@ -30,7 +30,7 @@ val eocb : unit -> unit val options_of_args : #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) (Asttypes.arg_label * expression option) list - #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (Asttypes.arg_label * (expression, unit) arg_or_omitted) list #endif -> (Asttypes.arg_label * expression option) list diff --git a/src/deadCode.ml b/src/deadCode.ml index 70abc780..3a5d58eb 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -157,7 +157,7 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - (fun (_, lab, _) -> #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) let lab : Types.label_description = lab in - #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (* The type of lab moved in OCaml 5.4 *) let lab : Data_types.label_description = lab in #endif diff --git a/src/deadLexiFi.ml b/src/deadLexiFi.ml index a926d08e..d3c49df6 100644 --- a/src/deadLexiFi.ml +++ b/src/deadLexiFi.ml @@ -130,7 +130,7 @@ module Extension = struct match get_deep_desc typ with | Tarrow (_, t, _, _) -> process (p, t, call_site) | Ttuple ts -> - #if OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + #if OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (* Ttuple's ts' content changed in OCaml 5.4, from type_expr to (string option * type_expr). This does the reverse conversion *) let ts = List.map snd ts in diff --git a/src/deadObj.ml b/src/deadObj.ml index 29c7d87f..c6bcd27d 100644 --- a/src/deadObj.ml +++ b/src/deadObj.ml @@ -319,7 +319,7 @@ let class_structure cl_struct = match pat.pat_desc with #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_alias (pat, _, _, _) -> - #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_alias (pat, _, _, _, _) -> #endif add_aliases pat diff --git a/src/deadSign.ml b/src/deadSign.ml index ccc5df69..98960d12 100644 --- a/src/deadSign.ml +++ b/src/deadSign.ml @@ -175,7 +175,7 @@ let collect_export_from_structure ~path ~comp_unit structure = export export_value ~path id value #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_alias (sub_pat, id, {loc; _}, uid) -> - #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_alias (sub_pat, id, {loc; _}, uid, _) -> #endif let id = Ident.name id in @@ -190,7 +190,7 @@ let collect_export_from_structure ~path ~comp_unit structure = | Tpat_lazy pat -> collect_value ~path pat | Tpat_tuple pats -> - #if OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + #if OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (* Tpat_tuple's pats changed in OCaml 5.4, from pat list to (string option * pat) list. This does the reverse conversion *) let pats = List.map snd pats in @@ -199,7 +199,7 @@ let collect_export_from_structure ~path ~comp_unit structure = | Tpat_construct (_, _, pats, _) #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_array pats -> - #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 5, 0) + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_array (_, pats) -> #endif List.iter (collect_value ~path) pats diff --git a/src/state/location_dependencies.ml b/src/state/location_dependencies.ml index d951af2a..77ebdacd 100644 --- a/src/state/location_dependencies.ml +++ b/src/state/location_dependencies.ml @@ -22,6 +22,9 @@ let fill_from_cmt_tbl uid_to_decl res_uid_to_loc = let find_opt_external_uid_loc ~comp_unit_to_path = function | Shape.Uid.(Compilation_unit _ | Internal | Predef _) -> None + #if OCAML_VERSION >= (5, 5, 0) && OCAML_VERSION < (5, 6, 0) + | Local_opaque_item _ -> None + #endif | Item {comp_unit; from; _} as uid -> let ( let* ) x f = Option.bind x f in let cached = From 63780b81a86db99dc7c5ed0bc1a014155babe0c4 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Sun, 23 Aug 2026 12:38:34 +0200 Subject: [PATCH 03/16] [src][deadCommon] `get_deep_desc` traverses monomorphic type disguised as `Tpoly` Since OCaml 5.5 function arguments types must be `Tpoly` nodes. Monoporphic arguments are therefore represented as a `Tpoly` with an empty list of names. When looking for the type description, we always want to this pattern as the underlying monoporhic type. This fixes the FP/FN introduced in the previous commit (adaptation to OCaml 5.5). --- README.md | 2 +- check/classic/classic.ref | 19 ++------ check/internal/internal.ref | 19 ++------ check/threshold-1/threshold-1.ref | 53 +++++++++------------- check/threshold-3-0.5/threshold-3-0.5.ref | 55 ++++++++++------------- src/deadCommon.ml | 4 +- 6 files changed, 55 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index 72398cc1..dc60dcfc 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ For more information, see the [User documentation](docs/USER_DOC.md) ## Requirements -- Currently tested and working on **OCaml 5.3 & 5.4** +- Currently tested and working on **OCaml 5.3 - 5.5** - **dune >= 3.20** - **cppo** diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 6f3280c8..7a356929 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -179,29 +179,24 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/alias/alias_lib.mli:2: original#unused ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method -./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#unused ./examples/docs/methods/code_constructs/constructor/constructor_bin.ml:2: unused_class#unused_method -./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/factory_fun/factory_fun_bin.ml:2: unused_factory#unused_method -./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Should not be detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#reset ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#unused ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#unused ./examples/docs/methods/code_constructs/immediate_object/immediate_object_bin.ml:2: unused_obj#unused_method -./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#unused -./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Should not be detected ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#reset ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#unused @@ -239,30 +234,22 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_int -./examples/using_make/obj/class.mli:1: c#f: Should not be detected ./examples/using_make/obj/class.mli:1: c#h ./examples/using_make/obj/class_type.mli:9: c#h ./examples/using_make/obj/coerce.mli:6: p#f ./examples/using_make/obj/coerce.mli:6: p#h -./examples/using_make/obj/coerce.mli:8: c#h: Should not be detected ./examples/using_make/obj/constraint.ml:1: p#g -./examples/using_make/obj/fooCl.mli:1: p1#f: Should not be detected ./examples/using_make/obj/fooCl.mli:1: p1#g ./examples/using_make/obj/fooCl.mli:1: p1#h ./examples/using_make/obj/fooCl.mli:7: p2#h -./examples/using_make/obj/fun_class.ml:1: c#m1: Should not be detected ./examples/using_make/obj/fun_class.ml:1: c#m3 -./examples/using_make/obj/fun_obj_param.ml:1: f#m: Should not be detected ./examples/using_make/obj/fun_obj_param.ml:1: f#n -./examples/using_make/obj/inher.mli:1: p#f: Should not be detected ./examples/using_make/obj/inher.mli:1: p#h ./examples/using_make/obj/named.mli:10: c#g ./examples/using_make/obj/obj_inher.ml:1: c#g ./examples/using_make/obj/obj_inher.ml:1: c#h ./examples/using_make/obj/obj_inher.ml:19: o3#k -./examples/using_make/obj/object.ml:1: o#f: Should not be detected ./examples/using_make/obj/object.ml:1: o#h -./examples/using_make/obj/overr.mli:1: p1#f: Should not be detected ./examples/using_make/obj/overr.mli:1: p1#g ./examples/using_make/obj/overr.mli:1: p1#h ./examples/using_make/obj/overr.mli:7: p2#g @@ -745,7 +732,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 616 +Total: 603 Success: 603 -Failed: 13 -Ratio: 97.8896103896% +Failed: 0 +Ratio: 100.% diff --git a/check/internal/internal.ref b/check/internal/internal.ref index b2ab484b..4a7eedfb 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -131,29 +131,24 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/alias/alias_lib.mli:2: original#unused ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method -./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#unused ./examples/docs/methods/code_constructs/constructor/constructor_bin.ml:2: unused_class#unused_method -./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/factory_fun/factory_fun_bin.ml:2: unused_factory#unused_method -./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Should not be detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#reset ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#unused ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#unused ./examples/docs/methods/code_constructs/immediate_object/immediate_object_bin.ml:2: unused_obj#unused_method -./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#unused -./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Should not be detected ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#reset ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#unused @@ -191,30 +186,22 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_int -./examples/using_make/obj/class.mli:1: c#f: Should not be detected ./examples/using_make/obj/class.mli:1: c#h ./examples/using_make/obj/class_type.mli:9: c#h ./examples/using_make/obj/coerce.mli:6: p#f ./examples/using_make/obj/coerce.mli:6: p#h -./examples/using_make/obj/coerce.mli:8: c#h: Should not be detected ./examples/using_make/obj/constraint.ml:1: p#g -./examples/using_make/obj/fooCl.mli:1: p1#f: Should not be detected ./examples/using_make/obj/fooCl.mli:1: p1#g ./examples/using_make/obj/fooCl.mli:1: p1#h ./examples/using_make/obj/fooCl.mli:7: p2#h -./examples/using_make/obj/fun_class.ml:1: c#m1: Should not be detected ./examples/using_make/obj/fun_class.ml:1: c#m3 -./examples/using_make/obj/fun_obj_param.ml:1: f#m: Should not be detected ./examples/using_make/obj/fun_obj_param.ml:1: f#n -./examples/using_make/obj/inher.mli:1: p#f: Should not be detected ./examples/using_make/obj/inher.mli:1: p#h ./examples/using_make/obj/named.mli:10: c#g ./examples/using_make/obj/obj_inher.ml:1: c#g ./examples/using_make/obj/obj_inher.ml:1: c#h ./examples/using_make/obj/obj_inher.ml:19: o3#k -./examples/using_make/obj/object.ml:1: o#f: Should not be detected ./examples/using_make/obj/object.ml:1: o#h -./examples/using_make/obj/overr.mli:1: p1#f: Should not be detected ./examples/using_make/obj/overr.mli:1: p1#g ./examples/using_make/obj/overr.mli:1: p1#h ./examples/using_make/obj/overr.mli:7: p2#g @@ -697,7 +684,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 572 +Total: 559 Success: 559 -Failed: 13 -Ratio: 97.7272727273% +Failed: 0 +Ratio: 100.% diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 48aae011..c82df69c 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -425,29 +425,24 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/alias/alias_lib.mli:2: original#unused ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method -./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#unused ./examples/docs/methods/code_constructs/constructor/constructor_bin.ml:2: unused_class#unused_method -./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/factory_fun/factory_fun_bin.ml:2: unused_factory#unused_method -./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Should not be detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#reset ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#unused ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#unused ./examples/docs/methods/code_constructs/immediate_object/immediate_object_bin.ml:2: unused_obj#unused_method -./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#unused -./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Should not be detected ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#reset ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#unused @@ -485,30 +480,22 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_int -./examples/using_make/obj/class.mli:1: c#f: Should not be detected ./examples/using_make/obj/class.mli:1: c#h ./examples/using_make/obj/class_type.mli:9: c#h ./examples/using_make/obj/coerce.mli:6: p#f ./examples/using_make/obj/coerce.mli:6: p#h -./examples/using_make/obj/coerce.mli:8: c#h: Should not be detected ./examples/using_make/obj/constraint.ml:1: p#g -./examples/using_make/obj/fooCl.mli:1: p1#f: Should not be detected ./examples/using_make/obj/fooCl.mli:1: p1#g ./examples/using_make/obj/fooCl.mli:1: p1#h ./examples/using_make/obj/fooCl.mli:7: p2#h -./examples/using_make/obj/fun_class.ml:1: c#m1: Should not be detected ./examples/using_make/obj/fun_class.ml:1: c#m3 -./examples/using_make/obj/fun_obj_param.ml:1: f#m: Should not be detected ./examples/using_make/obj/fun_obj_param.ml:1: f#n -./examples/using_make/obj/inher.mli:1: p#f: Should not be detected ./examples/using_make/obj/inher.mli:1: p#h ./examples/using_make/obj/named.mli:10: c#g ./examples/using_make/obj/obj_inher.ml:1: c#g ./examples/using_make/obj/obj_inher.ml:1: c#h ./examples/using_make/obj/obj_inher.ml:19: o3#k -./examples/using_make/obj/object.ml:1: o#f: Should not be detected ./examples/using_make/obj/object.ml:1: o#h -./examples/using_make/obj/overr.mli:1: p1#f: Should not be detected ./examples/using_make/obj/overr.mli:1: p1#g ./examples/using_make/obj/overr.mli:1: p1#h ./examples/using_make/obj/overr.mli:7: p2#g @@ -523,28 +510,33 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Not detected +./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push + ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#used_by_requirement ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Not detected +./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push + ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#peek ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#pop -./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Not detected +./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push + ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#used ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#used_locally ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#used ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Not detected +./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push + ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#used ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#used_by_child ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#peek ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#pop -./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Not detected +./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push + ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#externally_used ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#internally_used ./examples/using_dune/preprocessed_lib/preprocessed_no_intf.ml:12: immediate#externally_used @@ -582,29 +574,28 @@ Nothing else to report in this section ./examples/using_make/advanced/mod.mli:4: p#f -./examples/using_make/obj/class.mli:1: c#f: Not detected +./examples/using_make/obj/class.mli:1: c#f ./examples/using_make/obj/class.mli:1: c#g ./examples/using_make/obj/class_type.mli:7: p#f ./examples/using_make/obj/class_type.mli:7: p#h -./examples/using_make/obj/coerce.mli:8: c#f: Should not be detected -./examples/using_make/obj/coerce.mli:8: c#h: Not detected +./examples/using_make/obj/coerce.mli:8: c#h ./examples/using_make/obj/constraint.ml:1: p#f ./examples/using_make/obj/depend.ml:8: M.c#f -./examples/using_make/obj/fooCl.mli:1: p1#f: Not detected +./examples/using_make/obj/fooCl.mli:1: p1#f ./examples/using_make/obj/fooCl.mli:7: p2#g -./examples/using_make/obj/fun_class.ml:1: c#m1: Not detected +./examples/using_make/obj/fun_class.ml:1: c#m1 ./examples/using_make/obj/fun_class.ml:1: c#m2 ./examples/using_make/obj/fun_class.ml:1: c#m4 -./examples/using_make/obj/fun_obj_param.ml:1: f#m: Not detected +./examples/using_make/obj/fun_obj_param.ml:1: f#m ./examples/using_make/obj/fun_obj_param.ml:1: f#x -./examples/using_make/obj/inher.mli:1: p#f: Not detected +./examples/using_make/obj/inher.mli:1: p#f ./examples/using_make/obj/inher.mli:1: p#g ./examples/using_make/obj/named.mli:1: p1#g ./examples/using_make/obj/named.mli:6: p2#f ./examples/using_make/obj/named.mli:10: c#f -./examples/using_make/obj/object.ml:1: o#f: Not detected +./examples/using_make/obj/object.ml:1: o#f ./examples/using_make/obj/object.ml:1: o#g -./examples/using_make/obj/overr.mli:1: p1#f: Not detected +./examples/using_make/obj/overr.mli:1: p1#f ./examples/using_make/obj/overr.mli:12: c#g Nothing else to report in this section @@ -1221,7 +1212,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1015 -Success: 988 -Failed: 27 -Ratio: 97.3399014778% +Total: 1001 +Success: 1001 +Failed: 0 +Ratio: 100.% diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 4649ebf1..3919783a 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -568,29 +568,24 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/alias/alias_lib.mli:2: original#unused ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method -./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#unused ./examples/docs/methods/code_constructs/constructor/constructor_bin.ml:2: unused_class#unused_method -./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/factory_fun/factory_fun_bin.ml:2: unused_factory#unused_method -./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Should not be detected ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#reset ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#unused ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#unused ./examples/docs/methods/code_constructs/immediate_object/immediate_object_bin.ml:2: unused_obj#unused_method -./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Should not be detected ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#reset ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#unused -./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Should not be detected ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#reset ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#unused @@ -628,30 +623,22 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#unused_int -./examples/using_make/obj/class.mli:1: c#f: Should not be detected ./examples/using_make/obj/class.mli:1: c#h ./examples/using_make/obj/class_type.mli:9: c#h ./examples/using_make/obj/coerce.mli:6: p#f ./examples/using_make/obj/coerce.mli:6: p#h -./examples/using_make/obj/coerce.mli:8: c#h: Should not be detected ./examples/using_make/obj/constraint.ml:1: p#g -./examples/using_make/obj/fooCl.mli:1: p1#f: Should not be detected ./examples/using_make/obj/fooCl.mli:1: p1#g ./examples/using_make/obj/fooCl.mli:1: p1#h ./examples/using_make/obj/fooCl.mli:7: p2#h -./examples/using_make/obj/fun_class.ml:1: c#m1: Should not be detected ./examples/using_make/obj/fun_class.ml:1: c#m3 -./examples/using_make/obj/fun_obj_param.ml:1: f#m: Should not be detected ./examples/using_make/obj/fun_obj_param.ml:1: f#n -./examples/using_make/obj/inher.mli:1: p#f: Should not be detected ./examples/using_make/obj/inher.mli:1: p#h ./examples/using_make/obj/named.mli:10: c#g ./examples/using_make/obj/obj_inher.ml:1: c#g ./examples/using_make/obj/obj_inher.ml:1: c#h ./examples/using_make/obj/obj_inher.ml:19: o3#k -./examples/using_make/obj/object.ml:1: o#f: Should not be detected ./examples/using_make/obj/object.ml:1: o#h -./examples/using_make/obj/overr.mli:1: p1#f: Should not be detected ./examples/using_make/obj/overr.mli:1: p1#g ./examples/using_make/obj/overr.mli:1: p1#h ./examples/using_make/obj/overr.mli:7: p2#g @@ -666,28 +653,33 @@ Nothing else to report in this section ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push: Not detected +./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#push + ./examples/docs/methods/code_constructs/coercion/coercion_lib.mli:2: obj#used_by_requirement ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push: Not detected +./examples/docs/methods/code_constructs/constructor/constructor_lib.mli:2: int_stack#push + ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#peek ./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#pop -./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push: Not detected +./examples/docs/methods/code_constructs/factory_fun/factory_fun_lib.mli:2: get_stack#push + ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#used ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:2: factory_with_intermediate_binding#used_locally ./examples/docs/methods/code_constructs/factory_fun_indir/factory_fun_indir.ml:13: random_factory#used ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#peek ./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#pop -./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push: Not detected +./examples/docs/methods/code_constructs/immediate_object/immediate_object_lib.mli:2: int_stack#push + ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#used ./examples/docs/methods/code_constructs/inheritance/inheritance_lib.mli:2: parent#used_by_child ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#peek ./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#pop -./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push: Not detected +./examples/docs/methods/code_constructs/polymorphic_class/polymorphic_class_lib.mli:2: stack#push + ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#externally_used ./examples/using_dune/preprocessed_lib/preprocessed.mli:6: immediate#internally_used ./examples/using_dune/preprocessed_lib/preprocessed_no_intf.ml:12: immediate#externally_used @@ -725,29 +717,28 @@ Nothing else to report in this section ./examples/using_make/advanced/mod.mli:4: p#f -./examples/using_make/obj/class.mli:1: c#f: Not detected +./examples/using_make/obj/class.mli:1: c#f ./examples/using_make/obj/class.mli:1: c#g ./examples/using_make/obj/class_type.mli:7: p#f ./examples/using_make/obj/class_type.mli:7: p#h -./examples/using_make/obj/coerce.mli:8: c#f: Should not be detected -./examples/using_make/obj/coerce.mli:8: c#h: Not detected +./examples/using_make/obj/coerce.mli:8: c#h ./examples/using_make/obj/constraint.ml:1: p#f ./examples/using_make/obj/depend.ml:8: M.c#f -./examples/using_make/obj/fooCl.mli:1: p1#f: Not detected +./examples/using_make/obj/fooCl.mli:1: p1#f ./examples/using_make/obj/fooCl.mli:7: p2#g -./examples/using_make/obj/fun_class.ml:1: c#m1: Not detected +./examples/using_make/obj/fun_class.ml:1: c#m1 ./examples/using_make/obj/fun_class.ml:1: c#m2 ./examples/using_make/obj/fun_class.ml:1: c#m4 -./examples/using_make/obj/fun_obj_param.ml:1: f#m: Not detected +./examples/using_make/obj/fun_obj_param.ml:1: f#m ./examples/using_make/obj/fun_obj_param.ml:1: f#x -./examples/using_make/obj/inher.mli:1: p#f: Not detected +./examples/using_make/obj/inher.mli:1: p#f ./examples/using_make/obj/inher.mli:1: p#g ./examples/using_make/obj/named.mli:1: p1#g ./examples/using_make/obj/named.mli:6: p2#f ./examples/using_make/obj/named.mli:10: c#f -./examples/using_make/obj/object.ml:1: o#f: Not detected +./examples/using_make/obj/object.ml:1: o#f ./examples/using_make/obj/object.ml:1: o#g -./examples/using_make/obj/overr.mli:1: p1#f: Not detected +./examples/using_make/obj/overr.mli:1: p1#f ./examples/using_make/obj/overr.mli:12: c#g -------- @@ -782,7 +773,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:11: factory#used_int ./examples/using_make/obj/class_type.mli:7: p#g -./examples/using_make/obj/coerce.mli:8: c#f: Not detected +./examples/using_make/obj/coerce.mli:8: c#f ./examples/using_make/obj/named.mli:1: p1#f ./examples/using_make/obj/obj_inher.ml:1: c#f -------- @@ -1622,7 +1613,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1337 -Success: 1309 -Failed: 28 -Ratio: 97.9057591623% +Total: 1323 +Success: 1323 +Failed: 0 +Ratio: 100.% diff --git a/src/deadCommon.ml b/src/deadCommon.ml index 01b16d46..bbcd3e7c 100644 --- a/src/deadCommon.ml +++ b/src/deadCommon.ml @@ -138,7 +138,9 @@ let file_exists fn = (* We often simply traverse a Tlink to process the linked type *) let rec get_deep_desc typ = match Types.get_desc typ with - | Tlink t -> get_deep_desc t + | Tlink t + | Tpoly (t, []) -> + get_deep_desc t | t -> t From bb97975c6bebe2be4bff5e8e0c9be1459ba3be7f Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Sun, 23 Aug 2026 16:08:47 +0200 Subject: [PATCH 04/16] [src] add 5.2 compatibility This relies on cppo. Compilation issues are naively fixed. No error is introduced in the tests. The project-configuration files (dune, opam, ci) have been updated. --- .github/workflows/workflow.yml | 1 + README.md | 2 +- dead_code_analyzer.opam | 2 +- dune-project | 2 +- src/deadArg.mli | 2 +- src/deadCode.ml | 11 ++++++++++- src/deadLexiFi.ml | 5 +++++ src/deadObj.ml | 9 ++++++++- src/deadSign.ml | 4 ++-- src/state/location_dependencies.ml | 20 ++++++++++++++++++++ src/state/location_dependencies.mli | 21 +++++++++++++++------ src/utils.ml | 10 ++++++++++ 12 files changed, 75 insertions(+), 14 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index f02f70f5..4e225c01 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -16,6 +16,7 @@ jobs: - macos-latest - windows-latest ocaml: + - "5.2" - "5.3" - "5.4" - "5.5" diff --git a/README.md b/README.md index dc60dcfc..24adbc05 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ For more information, see the [User documentation](docs/USER_DOC.md) ## Requirements -- Currently tested and working on **OCaml 5.3 - 5.5** +- Currently tested and working on **OCaml 5.2 - 5.5** - **dune >= 3.20** - **cppo** diff --git a/dead_code_analyzer.opam b/dead_code_analyzer.opam index c7c82d99..b5c063c1 100644 --- a/dead_code_analyzer.opam +++ b/dead_code_analyzer.opam @@ -15,7 +15,7 @@ homepage: "https://github.com/LexiFi/dead_code_analyzer" bug-reports: "https://github.com/LexiFi/dead_code_analyzer/issues" depends: [ "dune" {>= "3.20"} - "ocaml" {>= "5.3" & < "5.6"} + "ocaml" {>= "5.2" & < "5.6"} "cppo" "odoc" {with-doc} ] diff --git a/dune-project b/dune-project index 1853b014..804702fb 100644 --- a/dune-project +++ b/dune-project @@ -22,7 +22,7 @@ (synopsis "Dead code analyzer for OCaml") (license MIT) (depends - (ocaml (and (>= 5.3) (< 5.6))) + (ocaml (and (>= 5.2) (< 5.6))) cppo ) ) diff --git a/src/deadArg.mli b/src/deadArg.mli index 7b1ef419..78816bed 100644 --- a/src/deadArg.mli +++ b/src/deadArg.mli @@ -28,7 +28,7 @@ val eocb : unit -> unit [eocb] = end of code base. *) val options_of_args : - #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) (Asttypes.arg_label * expression option) list #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (Asttypes.arg_label * (expression, unit) arg_or_omitted) list diff --git a/src/deadCode.ml b/src/deadCode.ml index 3a5d58eb..74994405 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -42,7 +42,12 @@ let rec treat_exp exp args = | Texp_field (_, _, {lbl_loc = {Location.loc_start = loc; _}; _}) -> DeadArg.register_uses loc args + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + | Texp_match (_, comp_l, _) -> + let val_l = [] in (* effect cases appear in OCaml 5.3 *) + #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) | Texp_match (_, comp_l, val_l, _) -> + #endif let process_cases l = List.iter (fun {c_rhs = exp; _} -> treat_exp exp args) l in @@ -155,7 +160,7 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - | Tpat_record (l, _) -> List.iter (fun (_, lab, _) -> - #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) let lab : Types.label_description = lab in #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (* The type of lab moved in OCaml 5.4 *) @@ -228,7 +233,11 @@ let expr super self e = "let () = ... in ... (=> use sequence)" end + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + | Texp_match (_, [{c_lhs; _}], _) + #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) | Texp_match (_, [{c_lhs; _}], [], _) + #endif when DeadType.is_unit c_lhs.pat_type && sections.style.seq -> begin match c_lhs.pat_desc with | Tpat_value tpat_arg -> diff --git a/src/deadLexiFi.ml b/src/deadLexiFi.ml index d3c49df6..c5737aff 100644 --- a/src/deadLexiFi.ml +++ b/src/deadLexiFi.ml @@ -47,8 +47,13 @@ module Extension = struct let sig_value (value : Types.value_description) = let add strct = match strct.pstr_desc with + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + | Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string (s, _, _)); + _}, _) -> + #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) | Pstr_eval ({pexp_desc = Pexp_constant {pconst_desc= (Pconst_string (s, _, _)); _}; _}, _) -> + #endif hashtbl_add_unique_to_list str s value.val_loc.loc_start | _ -> () in diff --git a/src/deadObj.ml b/src/deadObj.ml index c6bcd27d..0d5ecd7f 100644 --- a/src/deadObj.ml +++ b/src/deadObj.ml @@ -288,10 +288,17 @@ let add_var loc expr = | Texp_ident (_, _, {Types.val_loc; _}) -> `Ident val_loc.Location.loc_start (* Cases not traversed by repr_exp *) + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + | Texp_match (_, cases, _) -> + find_first_case_kind cases + | Texp_try (_, cases) -> + find_first_case_kind cases + #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) | Texp_match (_, cases, _, _) -> find_first_case_kind cases | Texp_try (_, cases, _) -> find_first_case_kind cases + #endif | Texp_ifthenelse (_, then_, Some else_) -> find_first_kind [then_; else_] (* Default *) @@ -317,7 +324,7 @@ let class_structure cl_struct = add_equal pat.pat_loc.Location.loc_start !last_class | _ -> () end; match pat.pat_desc with - #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_alias (pat, _, _, _) -> #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_alias (pat, _, _, _, _) -> diff --git a/src/deadSign.ml b/src/deadSign.ml index 98960d12..64b3ea7c 100644 --- a/src/deadSign.ml +++ b/src/deadSign.ml @@ -173,7 +173,7 @@ let collect_export_from_structure ~path ~comp_unit structure = let id = Ident.name id in let value = value_of pat loc uid in export export_value ~path id value - #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_alias (sub_pat, id, {loc; _}, uid) -> #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_alias (sub_pat, id, {loc; _}, uid, _) -> @@ -197,7 +197,7 @@ let collect_export_from_structure ~path ~comp_unit structure = #endif List.iter (collect_value ~path) pats | Tpat_construct (_, _, pats, _) - #if OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_array pats -> #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_array (_, pats) -> diff --git a/src/state/location_dependencies.ml b/src/state/location_dependencies.ml index 77ebdacd..fa91739f 100644 --- a/src/state/location_dependencies.ml +++ b/src/state/location_dependencies.ml @@ -6,6 +6,24 @@ module UidTbl = Shape.Uid.Tbl type uid_to_decl = Typedtree.item_declaration UidTbl.t +#if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + +let init ~comp_unit_to_path:_ cmt_infos _cmti_uid_to_decl = + match cmt_infos with + | Cmt_format.{cmt_annots = Implementation _; cmt_value_dependencies; _} -> + let loc_of_vd vd = vd.Types.val_loc.loc_start in + cmt_value_dependencies + |> List.map (fun (vd1, vd2) -> loc_of_vd vd1, loc_of_vd vd2) + |> Result.ok + | _ -> Result.error "No implementation found in cmt_infos" + +#elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) +(* Since OCaml 5.3, cmt_infos.cmt_value_dependencies is not available. + We try to reproduce it using the cmti_uid_to_decl and comp_unit_to_path + information, respectively found in a .cmti's cmt_infos and built using + the config.paths_to_analyze. +*) + let loc_opt_of_item_decl = function | Typedtree.Value {val_loc = loc; _} | Typedtree.Value_binding {vb_pat = {pat_loc = loc; _}; _} -> @@ -85,3 +103,5 @@ let init ~comp_unit_to_path cmt_infos cmti_uid_to_decl = |> cmt_decl_dep_to_loc_dep ~comp_unit_to_path cmt_infos.cmt_declaration_dependencies |> Result.ok | _ -> Result.error "No implementation found in cmt_infos" + +#endif diff --git a/src/state/location_dependencies.mli b/src/state/location_dependencies.mli index f7a124b0..5d106172 100644 --- a/src/state/location_dependencies.mli +++ b/src/state/location_dependencies.mli @@ -10,11 +10,20 @@ val init : -> Cmt_format.cmt_infos -> uid_to_decl option -> (t, string) result -(** [init ~comp_unit_to_path cmt_infos cmti_infos cmti_uid_to_decl] expects +(** [init ~comp_unit_to_path cmt_infos cmti_uid_to_decl] expects [cmt_infos.cmt_annots = Implementation _]. - It reads the [cmt_infos] and the [cmti_uid_to_decl] to retrieve their - and converts [cmt_infos.cmt_declaration_dependencies] into a single [t]. It returns an [Ok t] with [t] on success. - In case the [cmt_infos] does not contain an implementation, it returns an - [Err msg] with msg a string describing the issue. - [comp_unit_to_path] is used to load external cm files if necessary. *) + In case the [cmt_infos] does not contain an implementation, it returns + an [Err msg] with msg a string describing the issue. + + In OCaml <= 5.2, it simply maps [cmt_infos.cmt_value_dependencies] to + the correpsonding locations. [comp_unit_to_path] and [cmti_uid_to_decl] + are unused. + + In OCaml >= 5.3, it reads [cmt_infos.cmt_uid_to_decl] and + [cmti_uid_to_decl] to convert [cmt_infos.cmt_declaration_dependencies] + into a single [t] (equivalent to the result provided in OCaml <= 5.2 + using [cmt_infos.cmt_value_dependencies]). + [comp_unit_to_path] is used to load external .cmt and .cmti files if + necessary. +*) diff --git a/src/utils.ml b/src/utils.ml index 8c9b037d..f1210116 100644 --- a/src/utils.ml +++ b/src/utils.ml @@ -10,7 +10,17 @@ module Filepath = struct | _ -> filepath let unit filepath = + #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + (* reproduce https://github.com/ocaml/ocaml/blob/5.3/parsing/unit_info.ml#L60 *) + let remove_all_ext basename = + match String.index basename '.' with + | dot_pos -> String.sub basename 0 dot_pos + | exception Not_found -> basename + in + filepath |> Filename.basename |> remove_all_ext |> String.capitalize_ascii + #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) Unit_info.lax_modname_from_source filepath + #endif type kind = | Cmti From f1a6a2cd80ce324c05cbdd10c8e319c8db8ae9d4 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Sun, 23 Aug 2026 17:37:26 +0200 Subject: [PATCH 05/16] [src] add 5.1 compatibility This relies on cppo. Compilation issues are naively fixed. No error is introduced in the tests. The project-configuration files (dune, opam, ci) have been updated. --- .github/workflows/workflow.yml | 1 + README.md | 2 +- dead_code_analyzer.opam | 2 +- dune-project | 2 +- src/deadArg.ml | 79 +++++++++++++++-------- src/deadArg.mli | 2 +- src/deadCode.ml | 97 +++++++++++++++++------------ src/deadLexiFi.ml | 2 +- src/deadObj.ml | 10 ++- src/deadSign.ml | 14 ++++- src/state/file_infos.ml | 4 ++ src/state/location_dependencies.ml | 6 +- src/state/location_dependencies.mli | 9 +++ src/utils.ml | 24 +++++-- src/utils.mli | 9 ++- 15 files changed, 180 insertions(+), 83 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 4e225c01..bf4f578c 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -16,6 +16,7 @@ jobs: - macos-latest - windows-latest ocaml: + - "5.1" - "5.2" - "5.3" - "5.4" diff --git a/README.md b/README.md index 24adbc05..7c38eb72 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ For more information, see the [User documentation](docs/USER_DOC.md) ## Requirements -- Currently tested and working on **OCaml 5.2 - 5.5** +- Currently tested and working on **OCaml 5.1 - 5.5** - **dune >= 3.20** - **cppo** diff --git a/dead_code_analyzer.opam b/dead_code_analyzer.opam index b5c063c1..d0f8fbf9 100644 --- a/dead_code_analyzer.opam +++ b/dead_code_analyzer.opam @@ -15,7 +15,7 @@ homepage: "https://github.com/LexiFi/dead_code_analyzer" bug-reports: "https://github.com/LexiFi/dead_code_analyzer/issues" depends: [ "dune" {>= "3.20"} - "ocaml" {>= "5.2" & < "5.6"} + "ocaml" {>= "5.1" & < "5.6"} "cppo" "odoc" {with-doc} ] diff --git a/dune-project b/dune-project index 804702fb..2938500b 100644 --- a/dune-project +++ b/dune-project @@ -22,7 +22,7 @@ (synopsis "Dead code analyzer for OCaml") (license MIT) (depends - (ocaml (and (>= 5.2) (< 5.6))) + (ocaml (and (>= 5.1) (< 5.6))) cppo ) ) diff --git a/src/deadArg.ml b/src/deadArg.ml index 7148c142..7eda5123 100644 --- a/src/deadArg.ml +++ b/src/deadArg.ml @@ -148,7 +148,11 @@ and register_higher_order_uses builddir e = in let$ (c_lhs, c_rhs) = match expr.exp_desc with + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Texp_function {cases = [case]; _} -> + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Texp_function (_, Tfunction_cases {cases = [case]; _}) -> + #endif Some (case.c_lhs, case.c_rhs) | _ -> None in @@ -174,32 +178,13 @@ let register_uses val_loc args = let rec bind loc expr = let state = State.get_current () in match expr.exp_desc with - | Texp_function (params, body) -> ( - let check_param_style = function - | Tparam_pat {pat_type; _} - | Tparam_optional_default ({pat_type; _}, _) -> - DeadType.check_style pat_type expr.exp_loc.Location.loc_start - in - let register_optional_param = function - | Asttypes.Optional s - when Config.must_report_opt_args state.config -> - let (opts, next) = VdNode.get loc in - VdNode.update loc (s :: opts, next) - | _ -> () - in - List.iter - (fun {fp_kind; fp_arg_label; _} -> - check_param_style fp_kind; - register_optional_param fp_arg_label - ) - params; - match body with - | Tfunction_body exp -> bind loc exp - | Tfunction_cases {cases = [{c_lhs = {pat_type; _}; c_rhs = exp; _}]; _} -> - DeadType.check_style pat_type expr.exp_loc.Location.loc_start; - bind loc exp - | _ -> () - ) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Texp_function {arg_label; cases; _} -> + bind_function loc expr arg_label cases + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + | Texp_function (params, body) -> + bind_function loc expr params body + #endif | exp_desc when Config.must_report_opt_args state.config && DeadType.nb_args ~keep:`Opt expr.exp_type > 0 -> @@ -215,6 +200,48 @@ let rec bind loc expr = VdNode.merge_locs loc loc2 | _ -> () +and bind_function loc expr = + let state = State.get_current () in + let register_optional_param = function + | Asttypes.Optional s + when Config.must_report_opt_args state.config -> + let (opts, next) = VdNode.get loc in + VdNode.update loc (s :: opts, next) + | _ -> () + in + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + fun arg_label -> function + | {c_lhs = {pat_type; _}; c_rhs; _}::[] -> + DeadType.check_style pat_type expr.exp_loc.Location.loc_start; + register_optional_param arg_label; + bind loc c_rhs + | _ -> () + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + let process_params params = + let check_param_style = function + | Tparam_pat {pat_type; _} + | Tparam_optional_default ({pat_type; _}, _) -> + DeadType.check_style pat_type expr.exp_loc.Location.loc_start + in + List.iter + (fun {fp_kind; fp_arg_label; _} -> + check_param_style fp_kind; + register_optional_param fp_arg_label + ) + params + in + let process_body = function + | Tfunction_body exp -> bind loc exp + | Tfunction_cases {cases = [{c_lhs = {pat_type; _}; c_rhs = exp; _}]; _} -> + DeadType.check_style pat_type expr.exp_loc.Location.loc_start; + bind loc exp + | _ -> () + in + fun params body -> + process_params params; + process_body body + #endif + (******** WRAPPING ********) let wrap f x y = diff --git a/src/deadArg.mli b/src/deadArg.mli index 78816bed..5db563df 100644 --- a/src/deadArg.mli +++ b/src/deadArg.mli @@ -28,7 +28,7 @@ val eocb : unit -> unit [eocb] = end of code base. *) val options_of_args : - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 4, 0) (Asttypes.arg_label * expression option) list #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (Asttypes.arg_label * (expression, unit) arg_or_omitted) list diff --git a/src/deadCode.ml b/src/deadCode.ml index 74994405..3bc04055 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -42,7 +42,7 @@ let rec treat_exp exp args = | Texp_field (_, _, {lbl_loc = {Location.loc_start = loc; _}; _}) -> DeadArg.register_uses loc args - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) | Texp_match (_, comp_l, _) -> let val_l = [] in (* effect cases appear in OCaml 5.3 *) #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) @@ -69,32 +69,24 @@ let value_binding super self x = DeadArg.at_eof := []; incr depth; let open Asttypes in - begin match x with - | { vb_pat = - { pat_desc = Tpat_var ( - _, - {loc = {Location.loc_start = loc1; loc_ghost = false; _}; _}, _); - _}; - vb_expr = - { exp_desc = Texp_ident ( - _, - _, - {val_loc = {Location.loc_start = loc2; loc_ghost = false; _}; _}); - _}; - _ - } -> - VdNode.merge_locs loc1 loc2; - DeadObj.add_equal loc1 loc2 - | { vb_pat = - { pat_desc = Tpat_var ( - _, - {loc = {Location.loc_start = loc; loc_ghost = false; _}; _}, _); - _}; - vb_expr = exp; - _ - } -> - DeadArg.bind loc exp; - DeadObj.add_var loc exp + begin match x.vb_pat.pat_desc with + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_var (_, {loc; _}) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_var (_, {loc; _}, _) + #endif + when not loc.Location.loc_ghost -> + let loc = loc.Location.loc_start in + begin match x.vb_expr.exp_desc with + | Texp_ident (_, _, {val_loc; _}) when not val_loc.Location.loc_ghost -> + let val_loc = val_loc.Location.loc_start in + VdNode.merge_locs loc val_loc; + DeadObj.add_equal loc val_loc + | _ -> + let exp = x.vb_expr in + DeadArg.bind loc exp; + DeadObj.add_var loc exp + end | _ -> () end; @@ -145,9 +137,18 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - if DeadType.is_unit p.pat_type && sections.style.unit_pat then begin match p.pat_desc with | Tpat_construct _ -> () - | Tpat_var (_, {txt = "eta"; loc = _}, _) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_var (_, {txt = "eta"; _}) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_var (_, {txt = "eta"; _}, _) + #endif when p.pat_loc = Location.none -> () - | Tpat_var (_, {txt; _}, _) -> if check_underscore txt then u txt + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_var (_, {txt; _}) -> + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_var (_, {txt; _}, _) -> + #endif + if check_underscore txt then u txt | Tpat_any -> if state.config.underscore then u "_" | Tpat_value tpat_arg -> begin match (tpat_arg :> value general_pattern) with @@ -160,7 +161,7 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - | Tpat_record (l, _) -> List.iter (fun (_, lab, _) -> - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 4, 0) let lab : Types.label_description = lab in #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (* The type of lab moved in OCaml 5.4 *) @@ -226,14 +227,20 @@ let expr super self e = | Texp_let (_, [{vb_pat; _}], _) when DeadType.is_unit vb_pat.pat_type && sections.style.seq -> begin match vb_pat.pat_desc with - | Tpat_var (id, _, _) when not (check_underscore (Ident.name id)) -> () + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_var (id, _) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_var (id, _, _) + #endif + when not (check_underscore (Ident.name id)) -> + () | _ -> register_style vb_pat.pat_loc.Location.loc_start "let () = ... in ... (=> use sequence)" end - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) | Texp_match (_, [{c_lhs; _}], _) #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) | Texp_match (_, [{c_lhs; _}], [], _) @@ -251,14 +258,24 @@ let expr super self e = | _ -> () end - | Texp_let ( - Asttypes.Nonrecursive, - [{vb_pat = {pat_desc = Tpat_var (id1, _, _); pat_loc = {loc_start = loc; _}; _}; _}], - {exp_desc = Texp_ident (Path.Pident id2, _, _); exp_extra = []; _}) - when id1 = id2 - && sections.style.binding - && check_underscore (Ident.name id1) -> - register_style loc "let x = ... in x (=> useless binding)" + | Texp_let (Asttypes.Nonrecursive, + [{vb_pat; _}], + {exp_desc; exp_extra = []; _}) + -> + begin match vb_pat.pat_desc, exp_desc with + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_var (id1, _), Texp_ident (Path.Pident id2, _, _) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_var (id1, _, _), Texp_ident (Path.Pident id2, _, _) + #endif + when id1 = id2 + && sections.style.binding + && check_underscore (Ident.name id1) + -> + let loc = vb_pat.pat_loc.loc_start in + register_style loc "let x = ... in x (=> useless binding)" + | _ -> () + end | _ -> () end; diff --git a/src/deadLexiFi.ml b/src/deadLexiFi.ml index c5737aff..94666dd2 100644 --- a/src/deadLexiFi.ml +++ b/src/deadLexiFi.ml @@ -47,7 +47,7 @@ module Extension = struct let sig_value (value : Types.value_description) = let add strct = match strct.pstr_desc with - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) | Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string (s, _, _)); _}, _) -> #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) diff --git a/src/deadObj.ml b/src/deadObj.ml index 0d5ecd7f..19dc0adc 100644 --- a/src/deadObj.ml +++ b/src/deadObj.ml @@ -145,8 +145,12 @@ let rec treat_fields action typ = match get_deep_desc typ with let rec repr_exp expr f = match expr.exp_desc with | Texp_sequence (_, expr) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Texp_function {cases = {c_rhs=expr; _}::_ ; _} + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Texp_function (_, Tfunction_cases { cases = {c_rhs=expr; _}::_ ; _ }) | Texp_function (_, Tfunction_body expr) + #endif | Texp_let (_, _, expr) | Texp_apply (expr, _) -> repr_exp expr f | _ -> f expr @@ -288,7 +292,7 @@ let add_var loc expr = | Texp_ident (_, _, {Types.val_loc; _}) -> `Ident val_loc.Location.loc_start (* Cases not traversed by repr_exp *) - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) | Texp_match (_, cases, _) -> find_first_case_kind cases | Texp_try (_, cases) -> @@ -324,7 +328,9 @@ let class_structure cl_struct = add_equal pat.pat_loc.Location.loc_start !last_class | _ -> () end; match pat.pat_desc with - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_alias (pat, _, _) -> + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_alias (pat, _, _, _) -> #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_alias (pat, _, _, _, _) -> diff --git a/src/deadSign.ml b/src/deadSign.ml index 64b3ea7c..1c600318 100644 --- a/src/deadSign.ml +++ b/src/deadSign.ml @@ -169,11 +169,21 @@ let collect_export_from_structure ~path ~comp_unit structure = | Tpat_constant _ | Tpat_variant (_, None, _) -> () + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_var (id, {loc; _}) -> + let uid = Shape.Uid.internal_not_actually_unique in + (* uid appear in OCaml 5.2. Dummy value because we do not rely on it *) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (id, {loc; _}, uid) -> + #endif let id = Ident.name id in let value = value_of pat loc uid in export export_value ~path id value - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_alias (sub_pat, id, {loc; _}) -> + let uid = Shape.Uid.internal_not_actually_unique in + (* uid appear in OCaml 5.2. Dummy value because we do not rely on it *) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_alias (sub_pat, id, {loc; _}, uid) -> #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_alias (sub_pat, id, {loc; _}, uid, _) -> @@ -197,7 +207,7 @@ let collect_export_from_structure ~path ~comp_unit structure = #endif List.iter (collect_value ~path) pats | Tpat_construct (_, _, pats, _) - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_array pats -> #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_array (_, pats) -> diff --git a/src/state/file_infos.ml b/src/state/file_infos.ml index f8ea0bc7..4bff292e 100644 --- a/src/state/file_infos.ml +++ b/src/state/file_infos.ml @@ -44,7 +44,11 @@ let init_from_all_cm_infos ~cm_file cmt_infos = let cm_infos = match cmt_infos.cmt_annots with | Interface sign -> + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) + let cmti_uid_to_decl = Location_dependencies.NA in + #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) let cmti_uid_to_decl = cmt_infos.cmt_uid_to_decl in + #endif Cmti {sign; cmti_uid_to_decl} | Implementation strc -> let location_dependencies = Location_dependencies.empty in diff --git a/src/state/location_dependencies.ml b/src/state/location_dependencies.ml index fa91739f..fc90e449 100644 --- a/src/state/location_dependencies.ml +++ b/src/state/location_dependencies.ml @@ -4,9 +4,9 @@ let empty = [] module UidTbl = Shape.Uid.Tbl -type uid_to_decl = Typedtree.item_declaration UidTbl.t +#if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) -#if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) +type uid_to_decl = NA let init ~comp_unit_to_path:_ cmt_infos _cmti_uid_to_decl = match cmt_infos with @@ -24,6 +24,8 @@ let init ~comp_unit_to_path:_ cmt_infos _cmti_uid_to_decl = the config.paths_to_analyze. *) +type uid_to_decl = Typedtree.item_declaration UidTbl.t + let loc_opt_of_item_decl = function | Typedtree.Value {val_loc = loc; _} | Typedtree.Value_binding {vb_pat = {pat_loc = loc; _}; _} -> diff --git a/src/state/location_dependencies.mli b/src/state/location_dependencies.mli index 5d106172..b477d139 100644 --- a/src/state/location_dependencies.mli +++ b/src/state/location_dependencies.mli @@ -3,7 +3,16 @@ type t = (Lexing.position * Lexing.position) list val empty : t (** No signature read *) +#if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) +(* The corresponding [cmt_infos.cmt_uid_to_decl] is introduced in + OCaml 5.2 but not used until OCaml 5.3 (see {!init} below). + We still provide a constructor to keep the state representation as + uniform as possible. +*) +type uid_to_decl = NA +#elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) type uid_to_decl = Typedtree.item_declaration Shape.Uid.Tbl.t +#endif val init : comp_unit_to_path: (string, string) Hashtbl.t diff --git a/src/utils.ml b/src/utils.ml index f1210116..e35f9479 100644 --- a/src/utils.ml +++ b/src/utils.ml @@ -10,7 +10,7 @@ module Filepath = struct | _ -> filepath let unit filepath = - #if OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) (* reproduce https://github.com/ocaml/ocaml/blob/5.3/parsing/unit_info.ml#L60 *) let remove_all_ext basename = match String.index basename '.' with @@ -71,12 +71,26 @@ module Envaux = struct let setup = ref (Lazy.from_val ()) let force_setup () = Lazy.force !setup - let set_loadpaths (paths : Load_path.paths) = + type paths = + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + string list + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + Load_path.paths + #endif + + let set_loadpaths paths = + let init_load_path ~auto_include paths = + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + Load_path.init ~auto_include paths; + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + let visible = paths.Load_path.visible in + let hidden = paths.Load_path.hidden in + Load_path.init ~auto_include ~visible ~hidden; + #endif + in let reset () = let auto_include = Load_path.no_auto_include in - let visible = paths.visible in - let hidden = paths.hidden in - Load_path.init ~auto_include ~visible ~hidden; + init_load_path ~auto_include paths; Envaux.reset_cache () in setup := Lazy.from_fun reset diff --git a/src/utils.mli b/src/utils.mli index 12994a43..b234cce2 100644 --- a/src/utils.mli +++ b/src/utils.mli @@ -42,7 +42,14 @@ val typedtree_signature_of_modtype : module StringSet : Set.S with type elt = String.t module Envaux : sig - val set_loadpaths : Load_path.paths -> unit + type paths = + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + string list + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + Load_path.paths + #endif + + val set_loadpaths : paths -> unit (** Reset the load_path to the [paths]. Also calls Envaux.reset_cache. To call when loading a new .cmt *) From ebf6a85b63a5fed7e3db96ea6a2a70373037496e Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Tue, 25 Aug 2026 18:52:25 +0200 Subject: [PATCH 06/16] [src] add 5.0 compatibility This relies on cppo. Compilation issues are naively fixed. No error is introduced in the tests. The project-configuration files (dune, opam, ci) have been updated. --- .github/workflows/workflow.yml | 1 + .gitignore | 1 + README.md | 2 +- check/src/Makefile | 14 ++++++++++++-- check/src/aggregate.ml | 2 +- check/src/check.ml | 2 +- check/src/io.cppo.ml | 20 ++++++++++++++++++++ check/src/io.mli | 3 +++ check/src/pretty_print.ml | 2 +- check/src/scores.ml | 2 +- dead_code_analyzer.opam | 2 +- dune-project | 2 +- src/deadArg.ml | 6 +++--- src/deadArg.mli | 2 +- src/deadCode.ml | 16 ++++++++-------- src/deadLexiFi.ml | 2 +- src/deadObj.ml | 6 +++--- src/deadSign.ml | 20 +++++++++++++------- src/state/file_infos.ml | 2 +- src/state/location_dependencies.ml | 2 +- src/state/location_dependencies.mli | 2 +- src/utils.ml | 6 +++--- src/utils.mli | 2 +- 23 files changed, 80 insertions(+), 39 deletions(-) create mode 100644 check/src/io.cppo.ml create mode 100644 check/src/io.mli diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index bf4f578c..78b0a37f 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -16,6 +16,7 @@ jobs: - macos-latest - windows-latest ocaml: + - "5.0" - "5.1" - "5.2" - "5.3" diff --git a/.gitignore b/.gitignore index 79fc7d32..27fbd80f 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ *.install _build _opam +check/src/io.ml # tests output *.out *.err diff --git a/README.md b/README.md index 7c38eb72..1c8db2af 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ For more information, see the [User documentation](docs/USER_DOC.md) ## Requirements -- Currently tested and working on **OCaml 5.1 - 5.5** +- Currently tested and working on **OCaml 5.0 - 5.5** - **dune >= 3.20** - **cppo** diff --git a/check/src/Makefile b/check/src/Makefile index dc9543de..f2f13cd3 100644 --- a/check/src/Makefile +++ b/check/src/Makefile @@ -1,8 +1,15 @@ COMPFLAGS=-g -w +A-4-9-40-42 -bin-annot -keep-locs OCAMLC=ocamlc $(COMPFLAGS) OCAMLOPT=ocamlopt $(COMPFLAGS) +OCAML_VERSION=$(shell ocamlc -version) -API_SRC=pretty_print.ml section.ml scores.ml path.ml reports.ml +ADD_UNIX=$(shell [ $(OCAML_VERSION) \< 5.1 ] && echo "YES") +ifeq ($(ADD_UNIX), YES) +OCAMLC:=$(OCAMLC) -I +unix unix.cma +OCAMLOPT:=$(OCAMLOPT) -I +unix unix.cmxa +endif + +API_SRC=io.ml pretty_print.ml section.ml scores.ml path.ml reports.ml CHECK_SRC=$(API_SRC:.ml=.mli) $(API_SRC) check.mli check.ml AGGR_SRC=$(API_SRC:.ml=.mli) $(API_SRC) aggregate.mli aggregate.ml @@ -18,5 +25,8 @@ aggregate.byt$(EXE): $(AGGR_SRC) aggregate.opt$(EXE): $(AGGR_SRC) $(OCAMLOPT) -o $@ $^ +io.ml: io.cppo.ml + cppo -V OCAML:$(OCAML_VERSION) -o $@ $^ + clean: - rm -f *~ *.cm* *.a *.lib *.o *.obj *.byt$(EXE) *.opt$(EXE) **.out + rm -f io.ml *~ *.cm* *.a *.lib *.o *.obj *.byt$(EXE) *.opt$(EXE) **.out diff --git a/check/src/aggregate.ml b/check/src/aggregate.ml index a5f704b2..c2e88f2c 100644 --- a/check/src/aggregate.ml +++ b/check/src/aggregate.ml @@ -92,7 +92,7 @@ let update state line = let process state filepath = let input_lines = - In_channel.with_open_text filepath In_channel.input_lines + In_channel.with_open_text filepath Io.input_lines in print_title (Filename.remove_extension filepath); let local_state = List.fold_left update State.init input_lines in diff --git a/check/src/check.ml b/check/src/check.ml index 8672faf6..18da9a5f 100644 --- a/check/src/check.ml +++ b/check/src/check.ml @@ -178,7 +178,7 @@ let normalized_lines_of ~is_res_file filename = else Path.normalize_to_unix line ) in - In_channel.with_open_text filename In_channel.input_lines + In_channel.with_open_text filename Io.input_lines |> List.map normalize let () = diff --git a/check/src/io.cppo.ml b/check/src/io.cppo.ml new file mode 100644 index 00000000..509e2e6d --- /dev/null +++ b/check/src/io.cppo.ml @@ -0,0 +1,20 @@ +let isatty fd = + #scope + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 1, 0) + #define Out_channel Unix + #endif + match fd with + | `Stdout -> Out_channel.isatty Out_channel.stdout + | `Stderr -> Out_channel.isatty Out_channel.stderr + #endscope + + +#if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 1, 0) +let [@tail_mod_cons] rec input_lines ic = + (* reproduce https://github.com/ocaml/ocaml/blob/5.3.0/stdlib/in_channel.ml#L195 *) + match In_channel.input_line ic with + | Some line -> line :: input_lines ic + | None -> [] +#elif OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 6, 0) +let input_lines = In_channel.input_lines +#endif diff --git a/check/src/io.mli b/check/src/io.mli new file mode 100644 index 00000000..d490e3d7 --- /dev/null +++ b/check/src/io.mli @@ -0,0 +1,3 @@ +val isatty : [`Stdout | `Stderr] -> bool + +val input_lines : In_channel.t -> string list diff --git a/check/src/pretty_print.ml b/check/src/pretty_print.ml index 55b72b09..b1f66492 100644 --- a/check/src/pretty_print.ml +++ b/check/src/pretty_print.ml @@ -8,6 +8,6 @@ let style_reset = "\x1b[0m" let bold = "\x1b[01m" let error ~err ~ctx = - if Out_channel.isatty Out_channel.stderr then + if Io.isatty `Stderr then Printf.eprintf "%s%s: %s%s%s%s\n%!" red ctx white bg_red err style_reset else Printf.eprintf "%s: %s\n%!" ctx err diff --git a/check/src/scores.ml b/check/src/scores.ml index a7577217..84f363bb 100644 --- a/check/src/scores.ml +++ b/check/src/scores.ml @@ -41,7 +41,7 @@ let extract_failed = extract_from (failed_fmt ~isatty:false ()) let pp t = let total = total t in - let isatty = Out_channel.isatty Out_channel.stdout in + let isatty = Io.isatty `Stdout in let print_line fmt value = Printf.printf (fmt ~isatty ()) value; Printf.printf "\n" diff --git a/dead_code_analyzer.opam b/dead_code_analyzer.opam index d0f8fbf9..45626138 100644 --- a/dead_code_analyzer.opam +++ b/dead_code_analyzer.opam @@ -15,7 +15,7 @@ homepage: "https://github.com/LexiFi/dead_code_analyzer" bug-reports: "https://github.com/LexiFi/dead_code_analyzer/issues" depends: [ "dune" {>= "3.20"} - "ocaml" {>= "5.1" & < "5.6"} + "ocaml" {>= "5.0" & < "5.6"} "cppo" "odoc" {with-doc} ] diff --git a/dune-project b/dune-project index 2938500b..d274cb48 100644 --- a/dune-project +++ b/dune-project @@ -22,7 +22,7 @@ (synopsis "Dead code analyzer for OCaml") (license MIT) (depends - (ocaml (and (>= 5.1) (< 5.6))) + (ocaml (and (>= 5.0) (< 5.6))) cppo ) ) diff --git a/src/deadArg.ml b/src/deadArg.ml index 7eda5123..8e244954 100644 --- a/src/deadArg.ml +++ b/src/deadArg.ml @@ -148,7 +148,7 @@ and register_higher_order_uses builddir e = in let$ (c_lhs, c_rhs) = match expr.exp_desc with - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Texp_function {cases = [case]; _} -> #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Texp_function (_, Tfunction_cases {cases = [case]; _}) -> @@ -178,7 +178,7 @@ let register_uses val_loc args = let rec bind loc expr = let state = State.get_current () in match expr.exp_desc with - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Texp_function {arg_label; cases; _} -> bind_function loc expr arg_label cases #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) @@ -209,7 +209,7 @@ and bind_function loc expr = VdNode.update loc (s :: opts, next) | _ -> () in - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) fun arg_label -> function | {c_lhs = {pat_type; _}; c_rhs; _}::[] -> DeadType.check_style pat_type expr.exp_loc.Location.loc_start; diff --git a/src/deadArg.mli b/src/deadArg.mli index 5db563df..0d827b55 100644 --- a/src/deadArg.mli +++ b/src/deadArg.mli @@ -28,7 +28,7 @@ val eocb : unit -> unit [eocb] = end of code base. *) val options_of_args : - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 4, 0) (Asttypes.arg_label * expression option) list #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (Asttypes.arg_label * (expression, unit) arg_or_omitted) list diff --git a/src/deadCode.ml b/src/deadCode.ml index 3bc04055..f0652cf9 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -42,7 +42,7 @@ let rec treat_exp exp args = | Texp_field (_, _, {lbl_loc = {Location.loc_start = loc; _}; _}) -> DeadArg.register_uses loc args - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) | Texp_match (_, comp_l, _) -> let val_l = [] in (* effect cases appear in OCaml 5.3 *) #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) @@ -70,7 +70,7 @@ let value_binding super self x = incr depth; let open Asttypes in begin match x.vb_pat.pat_desc with - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (_, {loc; _}) #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (_, {loc; _}, _) @@ -137,13 +137,13 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - if DeadType.is_unit p.pat_type && sections.style.unit_pat then begin match p.pat_desc with | Tpat_construct _ -> () - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (_, {txt = "eta"; _}) #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (_, {txt = "eta"; _}, _) #endif when p.pat_loc = Location.none -> () - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (_, {txt; _}) -> #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (_, {txt; _}, _) -> @@ -161,7 +161,7 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - | Tpat_record (l, _) -> List.iter (fun (_, lab, _) -> - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 4, 0) let lab : Types.label_description = lab in #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (* The type of lab moved in OCaml 5.4 *) @@ -227,7 +227,7 @@ let expr super self e = | Texp_let (_, [{vb_pat; _}], _) when DeadType.is_unit vb_pat.pat_type && sections.style.seq -> begin match vb_pat.pat_desc with - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (id, _) #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (id, _, _) @@ -240,7 +240,7 @@ let expr super self e = "let () = ... in ... (=> use sequence)" end - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) | Texp_match (_, [{c_lhs; _}], _) #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) | Texp_match (_, [{c_lhs; _}], [], _) @@ -263,7 +263,7 @@ let expr super self e = {exp_desc; exp_extra = []; _}) -> begin match vb_pat.pat_desc, exp_desc with - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (id1, _), Texp_ident (Path.Pident id2, _, _) #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (id1, _, _), Texp_ident (Path.Pident id2, _, _) diff --git a/src/deadLexiFi.ml b/src/deadLexiFi.ml index 94666dd2..e761770a 100644 --- a/src/deadLexiFi.ml +++ b/src/deadLexiFi.ml @@ -47,7 +47,7 @@ module Extension = struct let sig_value (value : Types.value_description) = let add strct = match strct.pstr_desc with - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) | Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string (s, _, _)); _}, _) -> #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) diff --git a/src/deadObj.ml b/src/deadObj.ml index 19dc0adc..6f235913 100644 --- a/src/deadObj.ml +++ b/src/deadObj.ml @@ -145,7 +145,7 @@ let rec treat_fields action typ = match get_deep_desc typ with let rec repr_exp expr f = match expr.exp_desc with | Texp_sequence (_, expr) - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Texp_function {cases = {c_rhs=expr; _}::_ ; _} #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Texp_function (_, Tfunction_cases { cases = {c_rhs=expr; _}::_ ; _ }) @@ -292,7 +292,7 @@ let add_var loc expr = | Texp_ident (_, _, {Types.val_loc; _}) -> `Ident val_loc.Location.loc_start (* Cases not traversed by repr_exp *) - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) | Texp_match (_, cases, _) -> find_first_case_kind cases | Texp_try (_, cases) -> @@ -328,7 +328,7 @@ let class_structure cl_struct = add_equal pat.pat_loc.Location.loc_start !last_class | _ -> () end; match pat.pat_desc with - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_alias (pat, _, _) -> #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_alias (pat, _, _, _) -> diff --git a/src/deadSign.ml b/src/deadSign.ml index 1c600318..a0e8f084 100644 --- a/src/deadSign.ml +++ b/src/deadSign.ml @@ -169,7 +169,7 @@ let collect_export_from_structure ~path ~comp_unit structure = | Tpat_constant _ | Tpat_variant (_, None, _) -> () - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (id, {loc; _}) -> let uid = Shape.Uid.internal_not_actually_unique in (* uid appear in OCaml 5.2. Dummy value because we do not rely on it *) @@ -179,7 +179,7 @@ let collect_export_from_structure ~path ~comp_unit structure = let id = Ident.name id in let value = value_of pat loc uid in export export_value ~path id value - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_alias (sub_pat, id, {loc; _}) -> let uid = Shape.Uid.internal_not_actually_unique in (* uid appear in OCaml 5.2. Dummy value because we do not rely on it *) @@ -207,7 +207,7 @@ let collect_export_from_structure ~path ~comp_unit structure = #endif List.iter (collect_value ~path) pats | Tpat_construct (_, _, pats, _) - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_array pats -> #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_array (_, pats) -> @@ -226,7 +226,9 @@ let collect_export_from_structure ~path ~comp_unit structure = collect_structure ~path structure | Tmod_functor (_, m) | Tmod_apply (m, _, _) - | Tmod_apply_unit m + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 6, 0) + | Tmod_apply_unit m (* Constructor introduced in OCaml 5.1 *) + #endif | Tmod_constraint (m, _, Tmodtype_implicit, _) -> collect_module ~path m | Tmod_constraint (_, _, Tmodtype_explicit mt, _) -> @@ -314,7 +316,9 @@ let collect_from_include incl_decl = (None, signature) | Tmod_functor (_, mod_expr) | Tmod_apply (mod_expr, _, _) - | Tmod_apply_unit mod_expr + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 6, 0) + | Tmod_apply_unit mod_expr (* Constructor introduced in OCaml 5.1 *) + #endif | Tmod_constraint (mod_expr, _, _, _) -> get_mod_path_and_signature mod_expr in @@ -422,8 +426,10 @@ let collect_eq_from_module_alias ~path module_binding = mt | Tmod_constraint (mod_expr, _, _, _) | Tmod_functor (_, mod_expr) - | Tmod_apply (mod_expr, _, _) - | Tmod_apply_unit mod_expr -> + #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 6, 0) + | Tmod_apply_unit mod_expr (* Constructor introduced in OCaml 5.1 *) + #endif + | Tmod_apply (mod_expr, _, _) -> collect_from_module_expr mod_expr | Tmod_structure _ | Tmod_unpack (_, _) -> () diff --git a/src/state/file_infos.ml b/src/state/file_infos.ml index 4bff292e..8c7fdf15 100644 --- a/src/state/file_infos.ml +++ b/src/state/file_infos.ml @@ -44,7 +44,7 @@ let init_from_all_cm_infos ~cm_file cmt_infos = let cm_infos = match cmt_infos.cmt_annots with | Interface sign -> - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) let cmti_uid_to_decl = Location_dependencies.NA in #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) let cmti_uid_to_decl = cmt_infos.cmt_uid_to_decl in diff --git a/src/state/location_dependencies.ml b/src/state/location_dependencies.ml index fc90e449..d2b7ea67 100644 --- a/src/state/location_dependencies.ml +++ b/src/state/location_dependencies.ml @@ -4,7 +4,7 @@ let empty = [] module UidTbl = Shape.Uid.Tbl -#if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) +#if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) type uid_to_decl = NA diff --git a/src/state/location_dependencies.mli b/src/state/location_dependencies.mli index b477d139..87546422 100644 --- a/src/state/location_dependencies.mli +++ b/src/state/location_dependencies.mli @@ -3,7 +3,7 @@ type t = (Lexing.position * Lexing.position) list val empty : t (** No signature read *) -#if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) +#if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) (* The corresponding [cmt_infos.cmt_uid_to_decl] is introduced in OCaml 5.2 but not used until OCaml 5.3 (see {!init} below). We still provide a constructor to keep the state representation as diff --git a/src/utils.ml b/src/utils.ml index e35f9479..bc2985b5 100644 --- a/src/utils.ml +++ b/src/utils.ml @@ -10,7 +10,7 @@ module Filepath = struct | _ -> filepath let unit filepath = - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) (* reproduce https://github.com/ocaml/ocaml/blob/5.3/parsing/unit_info.ml#L60 *) let remove_all_ext basename = match String.index basename '.' with @@ -72,7 +72,7 @@ module Envaux = struct let force_setup () = Lazy.force !setup type paths = - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) string list #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) Load_path.paths @@ -80,7 +80,7 @@ module Envaux = struct let set_loadpaths paths = let init_load_path ~auto_include paths = - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) Load_path.init ~auto_include paths; #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) let visible = paths.Load_path.visible in diff --git a/src/utils.mli b/src/utils.mli index b234cce2..2a427f19 100644 --- a/src/utils.mli +++ b/src/utils.mli @@ -43,7 +43,7 @@ module StringSet : Set.S with type elt = String.t module Envaux : sig type paths = - #if OCAML_VERSION >= (5, 1, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) string list #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) Load_path.paths From f29145d9a93edfc03743b8778cda120bca29557b Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Tue, 25 Aug 2026 19:02:13 +0200 Subject: [PATCH 07/16] [src] add 4.14 compatibility This relies on cppo. Compilation issues are naively fixed. No error is introduced in the tests. The project-configuration files (dune, opam, ci) have been updated. --- .github/workflows/workflow.yml | 1 + README.md | 2 +- check/src/io.cppo.ml | 4 ++-- dead_code_analyzer.opam | 2 +- dune-project | 2 +- src/deadArg.ml | 6 +++--- src/deadArg.mli | 2 +- src/deadCode.ml | 16 ++++++++-------- src/deadLexiFi.ml | 2 +- src/deadObj.ml | 6 +++--- src/deadSign.ml | 6 +++--- src/state/file_infos.ml | 2 +- src/state/location_dependencies.ml | 2 +- src/state/location_dependencies.mli | 2 +- src/utils.ml | 29 ++++++++++++++++------------- src/utils.mli | 2 +- 16 files changed, 45 insertions(+), 41 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 78b0a37f..87fe6e70 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -16,6 +16,7 @@ jobs: - macos-latest - windows-latest ocaml: + - "4.14" - "5.0" - "5.1" - "5.2" diff --git a/README.md b/README.md index 1c8db2af..caaf2187 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ For more information, see the [User documentation](docs/USER_DOC.md) ## Requirements -- Currently tested and working on **OCaml 5.0 - 5.5** +- Currently tested and working on **OCaml 4.14 - 5.5** - **dune >= 3.20** - **cppo** diff --git a/check/src/io.cppo.ml b/check/src/io.cppo.ml index 509e2e6d..a78ee2c2 100644 --- a/check/src/io.cppo.ml +++ b/check/src/io.cppo.ml @@ -1,6 +1,6 @@ let isatty fd = #scope - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 1, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 1, 0) #define Out_channel Unix #endif match fd with @@ -9,7 +9,7 @@ let isatty fd = #endscope -#if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 1, 0) +#if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 1, 0) let [@tail_mod_cons] rec input_lines ic = (* reproduce https://github.com/ocaml/ocaml/blob/5.3.0/stdlib/in_channel.ml#L195 *) match In_channel.input_line ic with diff --git a/dead_code_analyzer.opam b/dead_code_analyzer.opam index 45626138..79ac2919 100644 --- a/dead_code_analyzer.opam +++ b/dead_code_analyzer.opam @@ -15,7 +15,7 @@ homepage: "https://github.com/LexiFi/dead_code_analyzer" bug-reports: "https://github.com/LexiFi/dead_code_analyzer/issues" depends: [ "dune" {>= "3.20"} - "ocaml" {>= "5.0" & < "5.6"} + "ocaml" {>= "4.14" & < "5.6"} "cppo" "odoc" {with-doc} ] diff --git a/dune-project b/dune-project index d274cb48..b0eab14a 100644 --- a/dune-project +++ b/dune-project @@ -22,7 +22,7 @@ (synopsis "Dead code analyzer for OCaml") (license MIT) (depends - (ocaml (and (>= 5.0) (< 5.6))) + (ocaml (and (>= 4.14) (< 5.6))) cppo ) ) diff --git a/src/deadArg.ml b/src/deadArg.ml index 8e244954..608bec02 100644 --- a/src/deadArg.ml +++ b/src/deadArg.ml @@ -148,7 +148,7 @@ and register_higher_order_uses builddir e = in let$ (c_lhs, c_rhs) = match expr.exp_desc with - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Texp_function {cases = [case]; _} -> #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Texp_function (_, Tfunction_cases {cases = [case]; _}) -> @@ -178,7 +178,7 @@ let register_uses val_loc args = let rec bind loc expr = let state = State.get_current () in match expr.exp_desc with - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Texp_function {arg_label; cases; _} -> bind_function loc expr arg_label cases #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) @@ -209,7 +209,7 @@ and bind_function loc expr = VdNode.update loc (s :: opts, next) | _ -> () in - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) fun arg_label -> function | {c_lhs = {pat_type; _}; c_rhs; _}::[] -> DeadType.check_style pat_type expr.exp_loc.Location.loc_start; diff --git a/src/deadArg.mli b/src/deadArg.mli index 0d827b55..23e75431 100644 --- a/src/deadArg.mli +++ b/src/deadArg.mli @@ -28,7 +28,7 @@ val eocb : unit -> unit [eocb] = end of code base. *) val options_of_args : - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 4, 0) (Asttypes.arg_label * expression option) list #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (Asttypes.arg_label * (expression, unit) arg_or_omitted) list diff --git a/src/deadCode.ml b/src/deadCode.ml index f0652cf9..f8dcdefc 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -42,7 +42,7 @@ let rec treat_exp exp args = | Texp_field (_, _, {lbl_loc = {Location.loc_start = loc; _}; _}) -> DeadArg.register_uses loc args - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 3, 0) | Texp_match (_, comp_l, _) -> let val_l = [] in (* effect cases appear in OCaml 5.3 *) #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) @@ -70,7 +70,7 @@ let value_binding super self x = incr depth; let open Asttypes in begin match x.vb_pat.pat_desc with - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (_, {loc; _}) #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (_, {loc; _}, _) @@ -137,13 +137,13 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - if DeadType.is_unit p.pat_type && sections.style.unit_pat then begin match p.pat_desc with | Tpat_construct _ -> () - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (_, {txt = "eta"; _}) #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (_, {txt = "eta"; _}, _) #endif when p.pat_loc = Location.none -> () - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (_, {txt; _}) -> #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (_, {txt; _}, _) -> @@ -161,7 +161,7 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - | Tpat_record (l, _) -> List.iter (fun (_, lab, _) -> - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 4, 0) let lab : Types.label_description = lab in #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) (* The type of lab moved in OCaml 5.4 *) @@ -227,7 +227,7 @@ let expr super self e = | Texp_let (_, [{vb_pat; _}], _) when DeadType.is_unit vb_pat.pat_type && sections.style.seq -> begin match vb_pat.pat_desc with - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (id, _) #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (id, _, _) @@ -240,7 +240,7 @@ let expr super self e = "let () = ... in ... (=> use sequence)" end - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 3, 0) | Texp_match (_, [{c_lhs; _}], _) #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) | Texp_match (_, [{c_lhs; _}], [], _) @@ -263,7 +263,7 @@ let expr super self e = {exp_desc; exp_extra = []; _}) -> begin match vb_pat.pat_desc, exp_desc with - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (id1, _), Texp_ident (Path.Pident id2, _, _) #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (id1, _, _), Texp_ident (Path.Pident id2, _, _) diff --git a/src/deadLexiFi.ml b/src/deadLexiFi.ml index e761770a..6f8ff48e 100644 --- a/src/deadLexiFi.ml +++ b/src/deadLexiFi.ml @@ -47,7 +47,7 @@ module Extension = struct let sig_value (value : Types.value_description) = let add strct = match strct.pstr_desc with - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 3, 0) | Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string (s, _, _)); _}, _) -> #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) diff --git a/src/deadObj.ml b/src/deadObj.ml index 6f235913..0e7e1993 100644 --- a/src/deadObj.ml +++ b/src/deadObj.ml @@ -145,7 +145,7 @@ let rec treat_fields action typ = match get_deep_desc typ with let rec repr_exp expr f = match expr.exp_desc with | Texp_sequence (_, expr) - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Texp_function {cases = {c_rhs=expr; _}::_ ; _} #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Texp_function (_, Tfunction_cases { cases = {c_rhs=expr; _}::_ ; _ }) @@ -292,7 +292,7 @@ let add_var loc expr = | Texp_ident (_, _, {Types.val_loc; _}) -> `Ident val_loc.Location.loc_start (* Cases not traversed by repr_exp *) - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 3, 0) | Texp_match (_, cases, _) -> find_first_case_kind cases | Texp_try (_, cases) -> @@ -328,7 +328,7 @@ let class_structure cl_struct = add_equal pat.pat_loc.Location.loc_start !last_class | _ -> () end; match pat.pat_desc with - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_alias (pat, _, _) -> #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_alias (pat, _, _, _) -> diff --git a/src/deadSign.ml b/src/deadSign.ml index a0e8f084..475cc5e3 100644 --- a/src/deadSign.ml +++ b/src/deadSign.ml @@ -169,7 +169,7 @@ let collect_export_from_structure ~path ~comp_unit structure = | Tpat_constant _ | Tpat_variant (_, None, _) -> () - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_var (id, {loc; _}) -> let uid = Shape.Uid.internal_not_actually_unique in (* uid appear in OCaml 5.2. Dummy value because we do not rely on it *) @@ -179,7 +179,7 @@ let collect_export_from_structure ~path ~comp_unit structure = let id = Ident.name id in let value = value_of pat loc uid in export export_value ~path id value - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Tpat_alias (sub_pat, id, {loc; _}) -> let uid = Shape.Uid.internal_not_actually_unique in (* uid appear in OCaml 5.2. Dummy value because we do not rely on it *) @@ -207,7 +207,7 @@ let collect_export_from_structure ~path ~comp_unit structure = #endif List.iter (collect_value ~path) pats | Tpat_construct (_, _, pats, _) - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 4, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 4, 0) | Tpat_array pats -> #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_array (_, pats) -> diff --git a/src/state/file_infos.ml b/src/state/file_infos.ml index 8c7fdf15..f45a6a41 100644 --- a/src/state/file_infos.ml +++ b/src/state/file_infos.ml @@ -44,7 +44,7 @@ let init_from_all_cm_infos ~cm_file cmt_infos = let cm_infos = match cmt_infos.cmt_annots with | Interface sign -> - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 3, 0) let cmti_uid_to_decl = Location_dependencies.NA in #elif OCAML_VERSION >= (5, 3, 0) && OCAML_VERSION < (5, 6, 0) let cmti_uid_to_decl = cmt_infos.cmt_uid_to_decl in diff --git a/src/state/location_dependencies.ml b/src/state/location_dependencies.ml index d2b7ea67..db268ac2 100644 --- a/src/state/location_dependencies.ml +++ b/src/state/location_dependencies.ml @@ -4,7 +4,7 @@ let empty = [] module UidTbl = Shape.Uid.Tbl -#if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) +#if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 3, 0) type uid_to_decl = NA diff --git a/src/state/location_dependencies.mli b/src/state/location_dependencies.mli index 87546422..bce18d2f 100644 --- a/src/state/location_dependencies.mli +++ b/src/state/location_dependencies.mli @@ -3,7 +3,7 @@ type t = (Lexing.position * Lexing.position) list val empty : t (** No signature read *) -#if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) +#if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 3, 0) (* The corresponding [cmt_infos.cmt_uid_to_decl] is introduced in OCaml 5.2 but not used until OCaml 5.3 (see {!init} below). We still provide a constructor to keep the state representation as diff --git a/src/utils.ml b/src/utils.ml index bc2985b5..6a4bd761 100644 --- a/src/utils.ml +++ b/src/utils.ml @@ -10,7 +10,7 @@ module Filepath = struct | _ -> filepath let unit filepath = - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 3, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 3, 0) (* reproduce https://github.com/ocaml/ocaml/blob/5.3/parsing/unit_info.ml#L60 *) let remove_all_ext basename = match String.index basename '.' with @@ -72,25 +72,28 @@ module Envaux = struct let force_setup () = Lazy.force !setup type paths = - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) string list #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) Load_path.paths #endif + let init_load_path paths = + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 0, 0) + Load_path.init paths + #elif OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + let auto_include = Load_path.no_auto_include in + Load_path.init ~auto_include paths + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + let auto_include = Load_path.no_auto_include in + let visible = paths.Load_path.visible in + let hidden = paths.Load_path.hidden in + Load_path.init ~auto_include ~visible ~hidden + #endif + let set_loadpaths paths = - let init_load_path ~auto_include paths = - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) - Load_path.init ~auto_include paths; - #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) - let visible = paths.Load_path.visible in - let hidden = paths.Load_path.hidden in - Load_path.init ~auto_include ~visible ~hidden; - #endif - in let reset () = - let auto_include = Load_path.no_auto_include in - init_load_path ~auto_include paths; + init_load_path paths; Envaux.reset_cache () in setup := Lazy.from_fun reset diff --git a/src/utils.mli b/src/utils.mli index 2a427f19..e5d20e4a 100644 --- a/src/utils.mli +++ b/src/utils.mli @@ -43,7 +43,7 @@ module StringSet : Set.S with type elt = String.t module Envaux : sig type paths = - #if OCAML_VERSION >= (5, 0, 0) && OCAML_VERSION < (5, 2, 0) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) string list #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) Load_path.paths From a45c60e596c806f2510d713c4c712d482ad3696c Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Thu, 3 Sep 2026 14:55:17 +0200 Subject: [PATCH 08/16] [examples][using_dune][style] add more useless binding The `let (x : t) = ...` case produces a different tree from `let x = ...`. The former is translated to `let ((_ : t) as x) = ...`. The particular case of `let x : t = ...` is either equivalent to the former (from OCaml 5.1 to 5.4) or the latter. The former is equivalent to the latter in OCaml 5.5. --- check/classic/classic.exp | 4 ++++ check/classic/classic.ref | 12 +++++++----- check/internal/internal.exp | 4 ++++ check/internal/internal.ref | 12 +++++++----- check/threshold-1/threshold-1.exp | 4 ++++ check/threshold-1/threshold-1.ref | 12 +++++++----- check/threshold-3-0.5/threshold-3-0.5.exp | 4 ++++ check/threshold-3-0.5/threshold-3-0.5.ref | 12 +++++++----- examples/using_dune/lib/style/style.ml | 15 +++++++++++++++ 9 files changed, 59 insertions(+), 20 deletions(-) diff --git a/check/classic/classic.exp b/check/classic/classic.exp index 395b0276..610ad6bb 100644 --- a/check/classic/classic.exp +++ b/check/classic/classic.exp @@ -706,6 +706,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -717,6 +719,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 7a356929..98d7d2be 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -706,7 +706,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) - +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -717,7 +718,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) - +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -732,7 +734,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 603 +Total: 607 Success: 603 -Failed: 0 -Ratio: 100.% +Failed: 4 +Ratio: 99.3410214168% diff --git a/check/internal/internal.exp b/check/internal/internal.exp index 9248e8c1..4585eafc 100644 --- a/check/internal/internal.exp +++ b/check/internal/internal.exp @@ -658,6 +658,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -669,6 +671,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 4a7eedfb..cfed2692 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -658,7 +658,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) - +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -669,7 +670,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) - +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -684,7 +686,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 559 +Total: 563 Success: 559 -Failed: 0 -Ratio: 100.% +Failed: 4 +Ratio: 99.2895204263% diff --git a/check/threshold-1/threshold-1.exp b/check/threshold-1/threshold-1.exp index c8277204..70973b71 100644 --- a/check/threshold-1/threshold-1.exp +++ b/check/threshold-1/threshold-1.exp @@ -1183,6 +1183,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1194,6 +1196,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index c82df69c..c75a941d 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -1186,7 +1186,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) - +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1197,7 +1198,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) - +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1212,7 +1214,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1001 +Total: 1005 Success: 1001 -Failed: 0 -Ratio: 100.% +Failed: 4 +Ratio: 99.6019900498% diff --git a/check/threshold-3-0.5/threshold-3-0.5.exp b/check/threshold-3-0.5/threshold-3-0.5.exp index e04ce12a..875d7e61 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.exp +++ b/check/threshold-3-0.5/threshold-3-0.5.exp @@ -1591,6 +1591,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1602,6 +1604,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 3919783a..65b6d049 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1587,7 +1587,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) - +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1598,7 +1599,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) - +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1613,7 +1615,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1323 +Total: 1327 Success: 1323 -Failed: 0 -Ratio: 100.% +Failed: 4 +Ratio: 99.6985681989% diff --git a/examples/using_dune/lib/style/style.ml b/examples/using_dune/lib/style/style.ml index 4a01b40f..e08acb02 100644 --- a/examples/using_dune/lib/style/style.ml +++ b/examples/using_dune/lib/style/style.ml @@ -5,3 +5,18 @@ let all = let useless_binding = 42 in useless_binding +(* more useless bindings *) + +let _ = + let constrained_useless_binding : int = 42 in + (* This is translated as + let ((_ : int) as constrained_useless_binding) = ... + from OCaml 5.1 to 5.4 *) + constrained_useless_binding + +let _ = + let (constrained_useless_binding : int) = 42 in + (* This is translated as + let ((_ : int) as constrained_useless_binding) = ... + OCaml <= 5.4 *) + constrained_useless_binding From 7aa91694a500f53d186bd5766e11bd0d7d459670 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Thu, 3 Sep 2026 15:14:59 +0200 Subject: [PATCH 09/16] [src][deadCode] detect constrained useless bindings Identify `let (_ as x) = ... in x` as a useless binding. This pattern is created by e.g. `let (x : t) = ... in x`. --- check/classic/classic.ref | 16 +++++++----- check/internal/internal.ref | 16 +++++++----- check/threshold-1/threshold-1.ref | 16 +++++++----- check/threshold-3-0.5/threshold-3-0.5.ref | 16 +++++++----- src/deadCode.ml | 32 +++++++++++++++++------ 5 files changed, 60 insertions(+), 36 deletions(-) diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 98d7d2be..80a22a68 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -706,8 +706,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) -./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -718,8 +719,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) -./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected -./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -735,6 +737,6 @@ Nothing else to report in this section Total: 607 -Success: 603 -Failed: 4 -Ratio: 99.3410214168% +Success: 607 +Failed: 0 +Ratio: 100.% diff --git a/check/internal/internal.ref b/check/internal/internal.ref index cfed2692..7642d999 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -658,8 +658,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) -./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -670,8 +671,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) -./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected -./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -687,6 +689,6 @@ Nothing else to report in this section Total: 563 -Success: 559 -Failed: 4 -Ratio: 99.2895204263% +Success: 563 +Failed: 0 +Ratio: 100.% diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index c75a941d..8e839791 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -1186,8 +1186,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) -./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1198,8 +1199,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) -./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected -./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1215,6 +1217,6 @@ Nothing else to report in this section Total: 1005 -Success: 1001 -Failed: 4 -Ratio: 99.6019900498% +Success: 1005 +Failed: 0 +Ratio: 100.% diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 65b6d049..f330f30f 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1587,8 +1587,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) -./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1599,8 +1600,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:4: let () = ... in ... (=> use sequence) ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) -./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding): Not detected -./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding): Not detected +./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1616,6 +1618,6 @@ Nothing else to report in this section Total: 1327 -Success: 1323 -Failed: 4 -Ratio: 99.6985681989% +Success: 1327 +Failed: 0 +Ratio: 100.% diff --git a/src/deadCode.ml b/src/deadCode.ml index f8dcdefc..e4e33034 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -262,15 +262,31 @@ let expr super self e = [{vb_pat; _}], {exp_desc; exp_extra = []; _}) -> - begin match vb_pat.pat_desc, exp_desc with - #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) - | Tpat_var (id1, _), Texp_ident (Path.Pident id2, _, _) - #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) - | Tpat_var (id1, _, _), Texp_ident (Path.Pident id2, _, _) - #endif - when id1 = id2 + let pat_id = + match vb_pat.pat_desc with + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_var (id, _) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_var (id, _, _) + #endif + (* let x = ... *) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, id, _) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _) + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _, _) + #endif + (* let (x: t) = ... *) + -> Some id + | _ -> None + in + begin match pat_id, exp_desc with + | Some pat_id, Texp_ident (Path.Pident exp_id, _, _) + (* let x = ... in y *) + when pat_id = exp_id (* x = y *) && sections.style.binding - && check_underscore (Ident.name id1) + && check_underscore (Ident.name pat_id) -> let loc = vb_pat.pat_loc.loc_start in register_style loc "let x = ... in x (=> useless binding)" From 427bb6da4a2c355e09f9c0eb18d5c0821ab80ebc Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Thu, 3 Sep 2026 15:56:05 +0200 Subject: [PATCH 10/16] [examples][using_dune][style] add more opt arg in arg Notable issues are: - Multiline lhs with multiple arguments lead to mismatch locations as demonstrated by `multiline_opt_arg_in_arg` and; `implicit_multiline_opt_arg_in_arg` - If the arg is itself an opt arg then we only detect the style issue in OCaml >= 5.2 and if a default value is provided (example `opt_arg_in_opt_arg_val`). There is also a non-stylistic opt arg issue related to implicit optional arguments (demonstrated by the `implicit_*` functions): although the optional arguments are never explicited, they are implied by the use of the function as argument. Those optional arguments exist because they are used by requirement, making the reports tautological. --- check/classic/classic.exp | 16 +++++++++++ check/classic/classic.ref | 34 +++++++++++++++++++---- check/internal/internal.exp | 16 +++++++++++ check/internal/internal.ref | 34 +++++++++++++++++++---- check/threshold-1/threshold-1.exp | 16 +++++++++++ check/threshold-1/threshold-1.ref | 34 +++++++++++++++++++---- check/threshold-3-0.5/threshold-3-0.5.exp | 16 +++++++++++ check/threshold-3-0.5/threshold-3-0.5.ref | 34 +++++++++++++++++++---- examples/using_dune/lib/style/style.ml | 24 ++++++++++++++++ 9 files changed, 200 insertions(+), 24 deletions(-) diff --git a/check/classic/classic.exp b/check/classic/classic.exp index 610ad6bb..5a506945 100644 --- a/check/classic/classic.exp +++ b/check/classic/classic.exp @@ -580,6 +580,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/unwrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:36: ?opt ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?never ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?never @@ -620,6 +623,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/wrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:36: ?opt ./examples/using_make/dir/alias_opt.ml:2: ?b ./examples/using_make/dir/alias_opt.ml:11: ?a @@ -708,6 +714,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -721,6 +732,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 80a22a68..75036f8f 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -423,6 +423,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:8: ?duplicate ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:17: ?type_used +./examples/using_dune/unwrapped_lib/style/style.ml:38: ?opt: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:43: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:15: ?always @@ -463,6 +465,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:8: ?duplicate ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:17: ?type_used +./examples/using_dune/wrapped_lib/style/style.ml:38: ?opt: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:43: ?opt: Should not be detected ./examples/using_make/baz.ml:1: ?d ./examples/using_make/baz.ml:5: ?d ./examples/using_make/cond_sel.ml:1: ?a @@ -580,6 +584,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/unwrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:36: ?opt ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?never ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?never @@ -620,6 +627,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/wrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:36: ?opt ./examples/using_make/dir/alias_opt.ml:2: ?b ./examples/using_make/dir/alias_opt.ml:11: ?a @@ -708,7 +718,13 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) - +./examples/using_dune/unwrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -721,7 +737,13 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) - +./examples/using_dune/wrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -736,7 +758,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 607 -Success: 607 -Failed: 0 -Ratio: 100.% +Total: 631 +Success: 615 +Failed: 16 +Ratio: 97.4643423138% diff --git a/check/internal/internal.exp b/check/internal/internal.exp index 4585eafc..b4a648ab 100644 --- a/check/internal/internal.exp +++ b/check/internal/internal.exp @@ -532,6 +532,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/unwrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:36: ?opt ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?never ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?never @@ -572,6 +575,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/wrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:36: ?opt ./examples/using_make/dir/alias_opt.ml:2: ?b ./examples/using_make/dir/alias_opt.ml:11: ?a @@ -660,6 +666,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -673,6 +684,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 7642d999..02d5e45a 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -375,6 +375,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:8: ?duplicate ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:17: ?type_used +./examples/using_dune/unwrapped_lib/style/style.ml:38: ?opt: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:43: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:15: ?always @@ -415,6 +417,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:8: ?duplicate ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:17: ?type_used +./examples/using_dune/wrapped_lib/style/style.ml:38: ?opt: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:43: ?opt: Should not be detected ./examples/using_make/baz.ml:1: ?d ./examples/using_make/baz.ml:5: ?d ./examples/using_make/cond_sel.ml:1: ?a @@ -532,6 +536,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/unwrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:36: ?opt ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?never ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?never @@ -572,6 +579,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/wrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:36: ?opt ./examples/using_make/dir/alias_opt.ml:2: ?b ./examples/using_make/dir/alias_opt.ml:11: ?a @@ -660,7 +670,13 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) - +./examples/using_dune/unwrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -673,7 +689,13 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) - +./examples/using_dune/wrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -688,7 +710,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 563 -Success: 563 -Failed: 0 -Ratio: 100.% +Total: 587 +Success: 571 +Failed: 16 +Ratio: 97.2742759796% diff --git a/check/threshold-1/threshold-1.exp b/check/threshold-1/threshold-1.exp index 70973b71..0d166cac 100644 --- a/check/threshold-1/threshold-1.exp +++ b/check/threshold-1/threshold-1.exp @@ -1057,6 +1057,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/unwrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:36: ?opt ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?never ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?never @@ -1097,6 +1100,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/wrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:36: ?opt ./examples/using_make/dir/alias_opt.ml:2: ?b ./examples/using_make/dir/alias_opt.ml:11: ?a @@ -1185,6 +1191,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1198,6 +1209,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 8e839791..89ec0d34 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -903,6 +903,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:8: ?duplicate ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:17: ?type_used +./examples/using_dune/unwrapped_lib/style/style.ml:38: ?opt: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:43: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:15: ?always @@ -943,6 +945,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:8: ?duplicate ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:17: ?type_used +./examples/using_dune/wrapped_lib/style/style.ml:38: ?opt: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:43: ?opt: Should not be detected ./examples/using_make/baz.ml:1: ?d ./examples/using_make/baz.ml:5: ?d ./examples/using_make/cond_sel.ml:1: ?a @@ -1060,6 +1064,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/unwrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:36: ?opt ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?never ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?never @@ -1100,6 +1107,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/wrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:36: ?opt ./examples/using_make/dir/alias_opt.ml:2: ?b ./examples/using_make/dir/alias_opt.ml:11: ?a @@ -1188,7 +1198,13 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) - +./examples/using_dune/unwrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1201,7 +1217,13 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) - +./examples/using_dune/wrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1216,7 +1238,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1005 -Success: 1005 -Failed: 0 -Ratio: 100.% +Total: 1029 +Success: 1013 +Failed: 16 +Ratio: 98.4450923226% diff --git a/check/threshold-3-0.5/threshold-3-0.5.exp b/check/threshold-3-0.5/threshold-3-0.5.exp index 875d7e61..46371716 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.exp +++ b/check/threshold-3-0.5/threshold-3-0.5.exp @@ -1382,6 +1382,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/unwrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:36: ?opt ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?never ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?never @@ -1422,6 +1425,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/wrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:36: ?opt ./examples/using_make/dir/alias_opt.ml:2: ?b ./examples/using_make/dir/alias_opt.ml:11: ?a @@ -1593,6 +1599,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1606,6 +1617,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index f330f30f..584ecd0b 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1125,6 +1125,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:8: ?duplicate ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:17: ?type_used +./examples/using_dune/unwrapped_lib/style/style.ml:38: ?opt: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:43: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:15: ?always @@ -1165,6 +1167,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:8: ?duplicate ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:17: ?type_used +./examples/using_dune/wrapped_lib/style/style.ml:38: ?opt: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:43: ?opt: Should not be detected ./examples/using_make/baz.ml:1: ?d ./examples/using_make/baz.ml:5: ?d ./examples/using_make/cond_sel.ml:1: ?a @@ -1379,6 +1383,9 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/unwrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/unwrapped_lib/style/style.ml:36: ?opt ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?never ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?never @@ -1419,6 +1426,9 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.mli:7: ?duplicate ./examples/using_dune/wrapped_lib/style/style.ml:3: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:28: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:33: ?opt +./examples/using_dune/wrapped_lib/style/style.ml:36: ?opt ./examples/using_make/dir/alias_opt.ml:2: ?b ./examples/using_make/dir/alias_opt.ml:11: ?a @@ -1589,7 +1599,13 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) - +./examples/using_dune/unwrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1602,7 +1618,13 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) - +./examples/using_dune/wrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1617,7 +1639,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1327 -Success: 1327 -Failed: 0 -Ratio: 100.% +Total: 1351 +Success: 1335 +Failed: 16 +Ratio: 98.8156920799% diff --git a/examples/using_dune/lib/style/style.ml b/examples/using_dune/lib/style/style.ml index e08acb02..165d9c92 100644 --- a/examples/using_dune/lib/style/style.ml +++ b/examples/using_dune/lib/style/style.ml @@ -20,3 +20,27 @@ let _ = let ((_ : int) as constrained_useless_binding) = ... OCaml <= 5.4 *) constrained_useless_binding + +(* more opt arg in arg *) + +let _ = + let multiline_opt_arg_in_arg a b (* unused params *) + (f : ?opt:'a -> unit -> unit) = + f () + in + let opt_arg_in_opt_arg_sig ?(f: (?opt:'a -> unit -> unit) option) () = + match f with + | Some f -> f () + | None -> () + in + let opt_arg_in_opt_arg_val ?(f=fun ?opt () -> ()) () = f () in + let multiline_implicit_opt_arg_in_arg a b + f = + multiline_opt_arg_in_arg a b f + in + let implicit_opt_arg_in_opt_arg ?f () = + match f with + | Some f -> multiline_opt_arg_in_arg () () f + | None -> () + in + () From d3720b0ceeadc49ae13b360085a77589990638d0 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Thu, 3 Sep 2026 17:46:11 +0200 Subject: [PATCH 11/16] [src][deadArg] fix style check of opt arg in arg This fixes the 2 style issues identified in the previous commit: - Because `Texp_function`'s representation changed in OCaml 5.2, rather than using its location, we need to use the params' locs (which were unavailable in prior versions); - The types of opt args are always wrapped in an `option` (even if a default valuei is provided), making them `Tconstr`. In order to properly check the "opt arg in arg" style on opt args, we need to extract the underlying type from the `Tconstr`. --- check/classic/classic.ref | 30 +++++++++---------- check/internal/internal.ref | 30 +++++++++---------- check/threshold-1/threshold-1.ref | 30 +++++++++---------- check/threshold-3-0.5/threshold-3-0.5.ref | 30 +++++++++---------- src/deadArg.ml | 36 +++++++++++++++-------- 5 files changed, 80 insertions(+), 76 deletions(-) diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 75036f8f..af23d010 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -718,13 +718,12 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) -./examples/using_dune/unwrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/unwrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -737,13 +736,12 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) -./examples/using_dune/wrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/wrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -758,7 +756,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 631 -Success: 615 -Failed: 16 -Ratio: 97.4643423138% +Total: 627 +Success: 623 +Failed: 4 +Ratio: 99.3620414673% diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 02d5e45a..af69954c 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -670,13 +670,12 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) -./examples/using_dune/unwrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/unwrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -689,13 +688,12 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) -./examples/using_dune/wrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/wrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -710,7 +708,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 587 -Success: 571 -Failed: 16 -Ratio: 97.2742759796% +Total: 583 +Success: 579 +Failed: 4 +Ratio: 99.3138936535% diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 89ec0d34..6fe41b27 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -1198,13 +1198,12 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) -./examples/using_dune/unwrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/unwrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1217,13 +1216,12 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) -./examples/using_dune/wrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/wrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1238,7 +1236,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1029 -Success: 1013 -Failed: 16 -Ratio: 98.4450923226% +Total: 1025 +Success: 1021 +Failed: 4 +Ratio: 99.6097560976% diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 584ecd0b..532b58d5 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1599,13 +1599,12 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/unwrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) -./examples/using_dune/unwrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/unwrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1618,13 +1617,12 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:5: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:11: let x = ... in x (=> useless binding) ./examples/using_dune/wrapped_lib/style/style.ml:18: let x = ... in x (=> useless binding) -./examples/using_dune/wrapped_lib/style/style.ml:27: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:28: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:31: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/wrapped_lib/style/style.ml:37: val f: ... -> (... -> ?_:_ -> ...) -> ...: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1639,7 +1637,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1351 -Success: 1335 -Failed: 16 -Ratio: 98.8156920799% +Total: 1347 +Success: 1343 +Failed: 4 +Ratio: 99.703043801% diff --git a/src/deadArg.ml b/src/deadArg.ml index 608bec02..20570a88 100644 --- a/src/deadArg.ml +++ b/src/deadArg.ml @@ -180,10 +180,11 @@ let rec bind loc expr = match expr.exp_desc with #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) | Texp_function {arg_label; cases; _} -> - bind_function loc expr arg_label cases + let expr_loc = expr.exp_loc.Location.loc_start in + bind_function loc expr_loc arg_label cases #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Texp_function (params, body) -> - bind_function loc expr params body + bind_function loc params body #endif | exp_desc when Config.must_report_opt_args state.config @@ -200,7 +201,7 @@ let rec bind loc expr = VdNode.merge_locs loc loc2 | _ -> () -and bind_function loc expr = +and bind_function loc = let state = State.get_current () in let register_optional_param = function | Asttypes.Optional s @@ -209,31 +210,42 @@ and bind_function loc expr = VdNode.update loc (s :: opts, next) | _ -> () in + let arg_type arg_label pat_type = + match arg_label with + | Asttypes.Optional _ -> + (* The type of optional arguments is wrapped in option *) + begin match get_deep_desc pat_type with + | Tconstr (_, [typ], _) -> typ + | _ -> pat_type + end + | _ -> pat_type + in #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) - fun arg_label -> function + fun expr_loc arg_label -> function | {c_lhs = {pat_type; _}; c_rhs; _}::[] -> - DeadType.check_style pat_type expr.exp_loc.Location.loc_start; + let arg_type = arg_type arg_label pat_type in + DeadType.check_style arg_type expr_loc; register_optional_param arg_label; bind loc c_rhs | _ -> () #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) let process_params params = - let check_param_style = function + let check_param_style arg_loc arg_label = function | Tparam_pat {pat_type; _} | Tparam_optional_default ({pat_type; _}, _) -> - DeadType.check_style pat_type expr.exp_loc.Location.loc_start + let arg_type = arg_type arg_label pat_type in + DeadType.check_style arg_type arg_loc.Location.loc_start in List.iter - (fun {fp_kind; fp_arg_label; _} -> - check_param_style fp_kind; + (fun {fp_kind; fp_arg_label; fp_loc; _} -> + check_param_style fp_loc fp_arg_label fp_kind; register_optional_param fp_arg_label ) params in let process_body = function - | Tfunction_body exp -> bind loc exp - | Tfunction_cases {cases = [{c_lhs = {pat_type; _}; c_rhs = exp; _}]; _} -> - DeadType.check_style pat_type expr.exp_loc.Location.loc_start; + | Tfunction_body exp + | Tfunction_cases {cases = [{c_rhs = exp; _}]; _} -> bind loc exp | _ -> () in From 46333588323c2b2f539c8af7f63bdd5178e44d44 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Fri, 4 Sep 2026 15:44:57 +0200 Subject: [PATCH 12/16] [examples][using_dune][style] add more opt arg in arg If there is an optional argument with default value before the faulty arg, then the style issue is not detected in OCaml < 5.2. --- check/classic/classic.exp | 2 ++ check/classic/classic.ref | 12 +++++++----- check/internal/internal.exp | 2 ++ check/internal/internal.ref | 12 +++++++----- check/threshold-1/threshold-1.exp | 2 ++ check/threshold-1/threshold-1.ref | 12 +++++++----- check/threshold-3-0.5/threshold-3-0.5.exp | 2 ++ check/threshold-3-0.5/threshold-3-0.5.ref | 12 +++++++----- examples/using_dune/lib/style/style.ml | 4 ++++ 9 files changed, 40 insertions(+), 20 deletions(-) diff --git a/check/classic/classic.exp b/check/classic/classic.exp index 5a506945..7f548664 100644 --- a/check/classic/classic.exp +++ b/check/classic/classic.exp @@ -719,6 +719,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -737,6 +738,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/classic/classic.ref b/check/classic/classic.ref index af23d010..7f6d2d61 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -425,6 +425,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: ?opt: Should not be detected ./examples/using_dune/unwrapped_lib/style/style.ml:43: ?opt: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:47: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:15: ?always @@ -467,6 +468,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/style/style.ml:43: ?opt: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:47: ?opt: Should not be detected ./examples/using_make/baz.ml:1: ?d ./examples/using_make/baz.ml:5: ?d ./examples/using_make/cond_sel.ml:1: ?a @@ -723,7 +725,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -741,7 +743,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -756,7 +758,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 627 +Total: 631 Success: 623 -Failed: 4 -Ratio: 99.3620414673% +Failed: 8 +Ratio: 98.7321711569% diff --git a/check/internal/internal.exp b/check/internal/internal.exp index b4a648ab..2164bd5a 100644 --- a/check/internal/internal.exp +++ b/check/internal/internal.exp @@ -671,6 +671,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -689,6 +690,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/internal/internal.ref b/check/internal/internal.ref index af69954c..105fd002 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -377,6 +377,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: ?opt: Should not be detected ./examples/using_dune/unwrapped_lib/style/style.ml:43: ?opt: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:47: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:15: ?always @@ -419,6 +420,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/style/style.ml:43: ?opt: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:47: ?opt: Should not be detected ./examples/using_make/baz.ml:1: ?d ./examples/using_make/baz.ml:5: ?d ./examples/using_make/cond_sel.ml:1: ?a @@ -675,7 +677,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -693,7 +695,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -708,7 +710,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 583 +Total: 587 Success: 579 -Failed: 4 -Ratio: 99.3138936535% +Failed: 8 +Ratio: 98.6371379898% diff --git a/check/threshold-1/threshold-1.exp b/check/threshold-1/threshold-1.exp index 0d166cac..a1aea207 100644 --- a/check/threshold-1/threshold-1.exp +++ b/check/threshold-1/threshold-1.exp @@ -1196,6 +1196,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1214,6 +1215,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 6fe41b27..42ddaba5 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -905,6 +905,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: ?opt: Should not be detected ./examples/using_dune/unwrapped_lib/style/style.ml:43: ?opt: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:47: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:15: ?always @@ -947,6 +948,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/style/style.ml:43: ?opt: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:47: ?opt: Should not be detected ./examples/using_make/baz.ml:1: ?d ./examples/using_make/baz.ml:5: ?d ./examples/using_make/cond_sel.ml:1: ?a @@ -1203,7 +1205,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1221,7 +1223,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1236,7 +1238,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1025 +Total: 1029 Success: 1021 -Failed: 4 -Ratio: 99.6097560976% +Failed: 8 +Ratio: 99.2225461613% diff --git a/check/threshold-3-0.5/threshold-3-0.5.exp b/check/threshold-3-0.5/threshold-3-0.5.exp index 46371716..59efca04 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.exp +++ b/check/threshold-3-0.5/threshold-3-0.5.exp @@ -1604,6 +1604,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1622,6 +1623,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 532b58d5..cd6bfc0e 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1127,6 +1127,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: ?opt: Should not be detected ./examples/using_dune/unwrapped_lib/style/style.ml:43: ?opt: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:47: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:1: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:8: ?always ./examples/using_dune/wrapped_lib/opt_args/mixed_args.ml:15: ?always @@ -1169,6 +1170,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: ?opt: Should not be detected ./examples/using_dune/wrapped_lib/style/style.ml:43: ?opt: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:47: ?opt: Should not be detected ./examples/using_make/baz.ml:1: ?d ./examples/using_make/baz.ml:5: ?d ./examples/using_make/cond_sel.ml:1: ?a @@ -1604,7 +1606,7 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1622,7 +1624,7 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1637,7 +1639,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1347 +Total: 1351 Success: 1343 -Failed: 4 -Ratio: 99.703043801% +Failed: 8 +Ratio: 99.40784604% diff --git a/examples/using_dune/lib/style/style.ml b/examples/using_dune/lib/style/style.ml index 165d9c92..e628dc3c 100644 --- a/examples/using_dune/lib/style/style.ml +++ b/examples/using_dune/lib/style/style.ml @@ -43,4 +43,8 @@ let _ = | Some f -> multiline_opt_arg_in_arg () () f | None -> () in + let multiline_implicit_opt_arg_in_arg a b ?(opt = None) + f = + multiline_opt_arg_in_arg a b f + in () From 5b63b9e469a1f5524e17e10a17d0d47cc29989be Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Fri, 4 Sep 2026 16:13:16 +0200 Subject: [PATCH 13/16] [src][deadArg] fix style check of opt arg in arg In the case where there is an opt arg with a default value before the faulty arg, in OCaml < 5.2, an internmediate `let ... in` is intoduced to set the value of the opt arg before the rest of the `function`. --- check/classic/classic.ref | 12 +++++++----- check/internal/internal.ref | 12 +++++++----- check/threshold-1/threshold-1.ref | 12 +++++++----- check/threshold-3-0.5/threshold-3-0.5.ref | 12 +++++++----- src/deadArg.ml | 21 +++++++++++++++++++++ 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 7f6d2d61..c62accaf 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -725,7 +725,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -743,7 +744,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -759,6 +761,6 @@ Nothing else to report in this section Total: 631 -Success: 623 -Failed: 8 -Ratio: 98.7321711569% +Success: 625 +Failed: 6 +Ratio: 99.0491283677% diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 105fd002..79f4846a 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -677,7 +677,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -695,7 +696,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -711,6 +713,6 @@ Nothing else to report in this section Total: 587 -Success: 579 -Failed: 8 -Ratio: 98.6371379898% +Success: 581 +Failed: 6 +Ratio: 98.9778534923% diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 42ddaba5..2d004c0a 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -1205,7 +1205,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1223,7 +1224,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1239,6 +1241,6 @@ Nothing else to report in this section Total: 1029 -Success: 1021 -Failed: 8 -Ratio: 99.2225461613% +Success: 1023 +Failed: 6 +Ratio: 99.416909621% diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index cd6bfc0e..5bad9339 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1606,7 +1606,8 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1624,7 +1625,8 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:36: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... -./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ...: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1640,6 +1642,6 @@ Nothing else to report in this section Total: 1351 -Success: 1343 -Failed: 8 -Ratio: 99.40784604% +Success: 1345 +Failed: 6 +Ratio: 99.55588453% diff --git a/src/deadArg.ml b/src/deadArg.ml index 20570a88..0219b2de 100644 --- a/src/deadArg.ml +++ b/src/deadArg.ml @@ -182,6 +182,27 @@ let rec bind loc expr = | Texp_function {arg_label; cases; _} -> let expr_loc = expr.exp_loc.Location.loc_start in bind_function loc expr_loc arg_label cases + | Texp_let (_, [_], in_expr) -> + (* optional arguments with default value + `fun ?(opt = default) x -> ...` + are translated into + ``` + fun ?opt -> + (let opt = match opt with + Some sth -> sth | None -> default + in + fun x -> ... + )[@@#default] + ``` + Checking if we have a `let ... in` with a "#default" attribute + is enough to identify those cases. + *) + let is_default expr = + List.exists + (fun Parsetree.{attr_name={txt; _}; _} -> String.equal txt "#default") + expr.exp_attributes + in + if is_default expr then bind loc in_expr #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Texp_function (params, body) -> bind_function loc params body From 6bd2a00e8e00d0550704a84a4b09e8ee52da55a7 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Fri, 4 Sep 2026 16:49:39 +0200 Subject: [PATCH 14/16] [examples][using_dune][style] add more unit bindings Constrained vars are misunderstood patterns in OCaml < 5.5, leading to `!!pattern!!` in the reports instead of a name, and even FP in case the name was prefixed by an underscore. --- check/classic/classic.exp | 10 +++++++ check/classic/classic.ref | 32 ++++++++++++++++++----- check/internal/internal.exp | 10 +++++++ check/internal/internal.ref | 32 ++++++++++++++++++----- check/threshold-1/threshold-1.exp | 10 +++++++ check/threshold-1/threshold-1.ref | 32 ++++++++++++++++++----- check/threshold-3-0.5/threshold-3-0.5.exp | 10 +++++++ check/threshold-3-0.5/threshold-3-0.5.ref | 32 ++++++++++++++++++----- examples/using_dune/lib/style/style.ml | 17 ++++++++++++ 9 files changed, 161 insertions(+), 24 deletions(-) diff --git a/check/classic/classic.exp b/check/classic/classic.exp index 7f548664..9326ee3c 100644 --- a/check/classic/classic.exp +++ b/check/classic/classic.exp @@ -720,6 +720,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -739,6 +744,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/classic/classic.ref b/check/classic/classic.ref index c62accaf..3c24b5c5 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -726,7 +726,17 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -745,7 +755,17 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -760,7 +780,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 631 -Success: 625 -Failed: 6 -Ratio: 99.0491283677% +Total: 653 +Success: 629 +Failed: 24 +Ratio: 96.3246554364% diff --git a/check/internal/internal.exp b/check/internal/internal.exp index 2164bd5a..5435b5b1 100644 --- a/check/internal/internal.exp +++ b/check/internal/internal.exp @@ -672,6 +672,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -691,6 +696,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 79f4846a..1b4c78f9 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -678,7 +678,17 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -697,7 +707,17 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -712,7 +732,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 587 -Success: 581 -Failed: 6 -Ratio: 98.9778534923% +Total: 609 +Success: 585 +Failed: 24 +Ratio: 96.0591133005% diff --git a/check/threshold-1/threshold-1.exp b/check/threshold-1/threshold-1.exp index a1aea207..5fd52d3d 100644 --- a/check/threshold-1/threshold-1.exp +++ b/check/threshold-1/threshold-1.exp @@ -1197,6 +1197,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1216,6 +1221,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 2d004c0a..bd981aab 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -1206,7 +1206,17 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1225,7 +1235,17 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1240,7 +1260,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1029 -Success: 1023 -Failed: 6 -Ratio: 99.416909621% +Total: 1051 +Success: 1027 +Failed: 24 +Ratio: 97.7164605138% diff --git a/check/threshold-3-0.5/threshold-3-0.5.exp b/check/threshold-3-0.5/threshold-3-0.5.exp index 59efca04..7cd2c3d0 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.exp +++ b/check/threshold-3-0.5/threshold-3-0.5.exp @@ -1605,6 +1605,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1624,6 +1629,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 5bad9339..214e9054 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1607,7 +1607,17 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1626,7 +1636,17 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:38: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... - +./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1641,7 +1661,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1351 -Success: 1345 -Failed: 6 -Ratio: 99.55588453% +Total: 1373 +Success: 1349 +Failed: 24 +Ratio: 98.2520029133% diff --git a/examples/using_dune/lib/style/style.ml b/examples/using_dune/lib/style/style.ml index e628dc3c..e4338332 100644 --- a/examples/using_dune/lib/style/style.ml +++ b/examples/using_dune/lib/style/style.ml @@ -48,3 +48,20 @@ let _ = multiline_opt_arg_in_arg a b f in () + +(* more unit bindings *) + +let _ = + let constrained_unit_binding : unit = () in + (* This is translated as + let ((_ : int) as constrained_unit_binding) = ... + from OCaml 5.1 to 5.4 *) + let (constrained_unit_binding : unit) = () in + (* This is translated as + let ((_ : int) as constrained_unit_binding) = ... + OCaml <= 5.4 *) + let f (param : unit) = () in + let _underscore_unit_binding = () in + let (_underscore_constrained_unit_binding : unit) = () in + let f (_underscore_param : unit) = () in + () From 9a00dcc041a9857c99276dea755edebd0858aa77 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Fri, 4 Sep 2026 17:04:34 +0200 Subject: [PATCH 15/16] [src][deadCode] detect constrained unit bindings Identify `((_ : unit) as x)` as a unit binding. This pattern is created by e.g. `(x : unit)` --- check/classic/classic.ref | 34 ++++++++--------------- check/internal/internal.ref | 34 ++++++++--------------- check/threshold-1/threshold-1.ref | 34 ++++++++--------------- check/threshold-3-0.5/threshold-3-0.5.ref | 34 ++++++++--------------- src/deadCode.ml | 23 +++++++++++++-- src/deadType.ml | 2 +- 6 files changed, 70 insertions(+), 91 deletions(-) diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 3c24b5c5..3b3d0c5b 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -727,16 +727,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) -./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding ./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) -./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -756,16 +751,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) -./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding ./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) -./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -780,7 +770,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 653 -Success: 629 -Failed: 24 -Ratio: 96.3246554364% +Total: 641 +Success: 635 +Failed: 6 +Ratio: 99.0639625585% diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 1b4c78f9..6219ff7c 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -679,16 +679,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) -./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding ./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) -./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -708,16 +703,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) -./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding ./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) -./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -732,7 +722,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 609 -Success: 585 -Failed: 24 -Ratio: 96.0591133005% +Total: 597 +Success: 591 +Failed: 6 +Ratio: 98.9949748744% diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index bd981aab..69746819 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -1207,16 +1207,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) -./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding ./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) -./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1236,16 +1231,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) -./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding ./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) -./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1260,7 +1250,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1051 -Success: 1027 -Failed: 24 -Ratio: 97.7164605138% +Total: 1039 +Success: 1033 +Failed: 6 +Ratio: 99.4225216554% diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 214e9054..b1bacdd1 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1608,16 +1608,11 @@ Nothing else to report in this section ./examples/using_dune/unwrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/unwrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) -./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/unwrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding ./examples/using_dune/unwrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) -./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param: Not detected -./examples/using_dune/unwrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/unwrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/unwrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/unwrapped_lib/style/style.ml:63: unit pattern param + ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:20: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:22: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/opt_args/opt_args_in_higher_order_fun.ml:25: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1637,16 +1632,11 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/style/style.ml:41: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:47: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_dune/wrapped_lib/style/style.ml:55: let () = ... in ... (=> use sequence) -./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding: Not detected +./examples/using_dune/wrapped_lib/style/style.ml:55: unit pattern constrained_unit_binding ./examples/using_dune/wrapped_lib/style/style.ml:59: let () = ... in ... (=> use sequence) -./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param: Not detected -./examples/using_dune/wrapped_lib/style/style.ml:65: let () = ... in ... (=> use sequence): Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:65: unit pattern !!pattern!!: Should not be detected -./examples/using_dune/wrapped_lib/style/style.ml:66: unit pattern !!pattern!!: Should not be detected +./examples/using_dune/wrapped_lib/style/style.ml:59: unit pattern constrained_unit_binding +./examples/using_dune/wrapped_lib/style/style.ml:63: unit pattern param + ./examples/using_make/dir/fn_arg.ml:3: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:9: val f: ... -> (... -> ?_:_ -> ...) -> ... ./examples/using_make/dir/fn_arg.ml:11: val f: ... -> (... -> ?_:_ -> ...) -> ... @@ -1661,7 +1651,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1373 -Success: 1349 -Failed: 24 -Ratio: 98.2520029133% +Total: 1361 +Success: 1355 +Failed: 6 +Ratio: 99.5591476855% diff --git a/src/deadCode.ml b/src/deadCode.ml index e4e33034..f9d68fd8 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -144,10 +144,20 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - #endif when p.pat_loc = Location.none -> () #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) - | Tpat_var (_, {txt; _}) -> + | Tpat_var (_, {txt; _}) #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) - | Tpat_var (_, {txt; _}, _) -> + | Tpat_var (_, {txt; _}, _) #endif + (* x *) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, _, {txt; _}) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, _, {txt; _}, _) + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, _, {txt; _}, _, _) + #endif + (* (x: t) *) + -> if check_underscore txt then u txt | Tpat_any -> if state.config.underscore then u "_" | Tpat_value tpat_arg -> @@ -232,6 +242,15 @@ let expr super self e = #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) | Tpat_var (id, _, _) #endif + (* x *) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, id, _) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _) + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _, _) + #endif + (* (x: t) *) when not (check_underscore (Ident.name id)) -> () | _ -> diff --git a/src/deadType.ml b/src/deadType.ml index 3a97e548..a7673b8f 100644 --- a/src/deadType.ml +++ b/src/deadType.ml @@ -27,7 +27,7 @@ let equivalences = ref [] (* t1 = t2 *) (******** HELPERS ********) -let is_unit t = match get_desc t with +let is_unit t = match get_deep_desc t with | Tconstr (p, [], _) -> Path.same p Predef.path_unit | _ -> false From 207d53969d01c5ec5428a8b66b1dfe750bccb687 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Mon, 7 Sep 2026 12:20:55 +0200 Subject: [PATCH 16/16] [src][deadCode] factorize id_of_var The same heavy pattern matching to extract the id of a `Tpat_var` (or `Tpat_alias (Tpat_any)`) was used in 3 different places. This is now done in `id_of_var` which returns an option. --- src/deadCode.ml | 83 ++++++++++++++++++------------------------------- 1 file changed, 30 insertions(+), 53 deletions(-) diff --git a/src/deadCode.ml b/src/deadCode.ml index f9d68fd8..73095ba4 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -125,6 +125,27 @@ let structure_item super self i = r +let id_of_var : type k . k pattern_desc -> Ident.t option = function + (* helper function to extract the var's id in tpat_var and + tpat_alias(tpat_any) patterns for all OCaml versions *) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_var (id, _) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_var (id, _, _) + #endif + (* x *) + #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, id, _) + #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _) + #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) + | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _, _) + #endif + (* (x: t) *) + -> Some id + | _ -> None + + let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern -> k general_pattern = fun super self p -> let state = State.get_current () in @@ -143,29 +164,18 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - | Tpat_var (_, {txt = "eta"; _}, _) #endif when p.pat_loc = Location.none -> () - #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) - | Tpat_var (_, {txt; _}) - #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) - | Tpat_var (_, {txt; _}, _) - #endif - (* x *) - #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) - | Tpat_alias ({pat_desc=Tpat_any; _}, _, {txt; _}) - #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) - | Tpat_alias ({pat_desc=Tpat_any; _}, _, {txt; _}, _) - #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) - | Tpat_alias ({pat_desc=Tpat_any; _}, _, {txt; _}, _, _) - #endif - (* (x: t) *) - -> - if check_underscore txt then u txt | Tpat_any -> if state.config.underscore then u "_" | Tpat_value tpat_arg -> begin match (tpat_arg :> value general_pattern) with | {pat_desc=(Tpat_construct _ | Tpat_var _ | Tpat_any); _} -> () | _ -> u "!!pattern!!" end - | _ -> u "!!pattern!!" + | var -> + match id_of_var var with + | Some id -> + let txt = Ident.name id in + if check_underscore txt then u txt + | None -> u "!!pattern!!" end; begin match p.pat_desc with | Tpat_record (l, _) -> @@ -236,23 +246,8 @@ let expr super self e = | Texp_let (_, [{vb_pat; _}], _) when DeadType.is_unit vb_pat.pat_type && sections.style.seq -> - begin match vb_pat.pat_desc with - #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) - | Tpat_var (id, _) - #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) - | Tpat_var (id, _, _) - #endif - (* x *) - #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) - | Tpat_alias ({pat_desc=Tpat_any; _}, id, _) - #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) - | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _) - #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) - | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _, _) - #endif - (* (x: t) *) - when not (check_underscore (Ident.name id)) -> - () + begin match id_of_var vb_pat.pat_desc with + | Some id when not (check_underscore (Ident.name id)) -> () | _ -> register_style vb_pat.pat_loc.Location.loc_start @@ -281,25 +276,7 @@ let expr super self e = [{vb_pat; _}], {exp_desc; exp_extra = []; _}) -> - let pat_id = - match vb_pat.pat_desc with - #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) - | Tpat_var (id, _) - #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 6, 0) - | Tpat_var (id, _, _) - #endif - (* let x = ... *) - #if OCAML_VERSION >= (4, 14, 0) && OCAML_VERSION < (5, 2, 0) - | Tpat_alias ({pat_desc=Tpat_any; _}, id, _) - #elif OCAML_VERSION >= (5, 2, 0) && OCAML_VERSION < (5, 4, 0) - | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _) - #elif OCAML_VERSION >= (5, 4, 0) && OCAML_VERSION < (5, 6, 0) - | Tpat_alias ({pat_desc=Tpat_any; _}, id, _, _, _) - #endif - (* let (x: t) = ... *) - -> Some id - | _ -> None - in + let pat_id = id_of_var vb_pat.pat_desc in begin match pat_id, exp_desc with | Some pat_id, Texp_ident (Path.Pident exp_id, _, _) (* let x = ... in y *)