|
| 1 | +The reference files for this example are in the |
| 2 | +[inline\_record](../../../examples/docs/fields_and_constructors/code_constructs/inline_record) directory. |
| 3 | + |
| 4 | +The reference takes place in `/tmp/docs/fields_and_constructors/code_constructs`, which |
| 5 | +is a copy of the [code\_constructs](../../../examples/docs/fields_and_constructors/code_constructs) |
| 6 | +directory. Reported locations may differ depending on the location of the source |
| 7 | +files. |
| 8 | + |
| 9 | +The compilation command is : |
| 10 | +``` |
| 11 | +make -C inline_record build |
| 12 | +``` |
| 13 | + |
| 14 | +The analysis command is : |
| 15 | +``` |
| 16 | +make -C inline_record analyze |
| 17 | +``` |
| 18 | + |
| 19 | +The compile + analyze command is : |
| 20 | +``` |
| 21 | +make -C inline_record |
| 22 | +``` |
| 23 | + |
| 24 | +> [!IMPORTANT] |
| 25 | +> **LIMITATION** |
| 26 | +> |
| 27 | +> The analyzer ignores fields in inline records. |
| 28 | +
|
| 29 | +## First run |
| 30 | + |
| 31 | +Code : |
| 32 | +```OCaml |
| 33 | +(* inline_record_lib.mli *) |
| 34 | +type ('a, 'b) t = |
| 35 | + | Both of {left : 'a; right : 'b} |
| 36 | + | Left of 'a |
| 37 | + | Right of 'b |
| 38 | +
|
| 39 | +val get_left_opt : ('a, 'b) t -> 'a option |
| 40 | +``` |
| 41 | +```OCaml |
| 42 | +(* inline_record_lib.ml *) |
| 43 | +type ('a, 'b) t = |
| 44 | + | Both of {left : 'a; right : 'b} |
| 45 | + | Left of 'a |
| 46 | + | Right of 'b |
| 47 | +
|
| 48 | +let get_left_opt = function |
| 49 | + | Both {left; _} |
| 50 | + | Left left -> Some left |
| 51 | + | _ -> None |
| 52 | +``` |
| 53 | +```OCaml |
| 54 | +(* inline_record_bin.ml *) |
| 55 | +let () = |
| 56 | + let open Inline_record_lib in |
| 57 | + let both = Both {left = 1; right = "one"} in |
| 58 | + match get_left_opt both with |
| 59 | + | Some left -> assert (left = 1) |
| 60 | + | _ -> assert false |
| 61 | +``` |
| 62 | + |
| 63 | +Before looking at the analysis results, let's look at the code. |
| 64 | + |
| 65 | +The `Inline_record_lib` defines 1 variant type `t` with 3 constructors : `Both`, |
| 66 | +`Left`, and `Right`. Only the first one is used, the 2 others are only matched |
| 67 | +on in `get_left_opt`. Constructor `Both` has an inline record argument with 2 |
| 68 | +fields : `left`, and `right`. Only the first one is used, the other one is only |
| 69 | +written to. |
| 70 | +Following the report semantics on constructors and fields, `Left`, `Right`, and |
| 71 | +`right` should be reported unused. |
| 72 | + |
| 73 | +However, the analyzer does not report unused inline record fields. |
| 74 | +The compiler also does not warn on unused inline record fields. |
| 75 | + |
| 76 | +Compile and analyze : |
| 77 | +``` |
| 78 | +$ make -C inline_record |
| 79 | +make: Entering directory '/tmp/docs/fields_and_constructors/code_constructs/inline_record' |
| 80 | +ocamlopt -w +37+69 -bin-annot inline_record_lib.mli inline_record_lib.ml inline_record_bin.ml |
| 81 | +dead_code_analyzer --nothing -T all . |
| 82 | +Scanning files... |
| 83 | + [DONE] |
| 84 | +
|
| 85 | +.> UNUSED CONSTRUCTORS/RECORD FIELDS: |
| 86 | +==================================== |
| 87 | +/tmp/docs/fields_and_constructors/code_constructs/inline_record/inline_record_lib.mli:4: t.Left |
| 88 | +/tmp/docs/fields_and_constructors/code_constructs/inline_record/inline_record_lib.mli:5: t.Right |
| 89 | +
|
| 90 | +Nothing else to report in this section |
| 91 | +-------------------------------------------------------------------------------- |
| 92 | +
|
| 93 | +
|
| 94 | +make: Leaving directory '/tmp/docs/fields_and_constructors/code_constructs/inline_record' |
| 95 | +``` |
| 96 | + |
| 97 | +As expected, `t.Left`, and `t.Right` are reported unused by the analyzer. |
| 98 | +As explained, the analyzer does not report inline record fields so `right` is |
| 99 | +not reported. |
| 100 | +Fixing the unused constructors is the same as in the |
| 101 | +[Polymorphic type](./POLYMORPHIC_TYPE.md) example. Our work here is done. |
0 commit comments