diff options
Diffstat (limited to 'lib/dialyzer/test/small_SUITE_data/src')
-rw-r--r-- | lib/dialyzer/test/small_SUITE_data/src/refine_failing.erl | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/dialyzer/test/small_SUITE_data/src/refine_failing.erl b/lib/dialyzer/test/small_SUITE_data/src/refine_failing.erl new file mode 100644 index 0000000000..243f4806e6 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/refine_failing.erl @@ -0,0 +1,26 @@ +%% This testcase shows why it's a bad idea to block refinement (by forwarding +%% any() to all arguments) when a failing call is encountered. The initial +%% success typing for update_one allows anything to be an element of the list in +%% the second argument. This will be refined during dataflow by the result from +%% add_counters to just a list of tuples. This will cause the call in the second +%% clause of update_one to fail correctly and identify the discrepancy. It could +%% be a better idea to refuse to add the failing calls but this may lead to a +%% ton of unused functions, +%% +%% by Stavros Aronis<[email protected]> + +-module(refine_failing). + +-export([foo/2]). + +foo(A, B) -> update_all(add_counters(A, []), B). + +add_counters( [], Acc) -> Acc; +add_counters([H|T], Acc) -> add_counters(T, [{H, 0}|Acc]). + +update_all(Ds, []) -> Ds; +update_all(Ds, [F|Fs]) -> update_all(update_one(F, Ds, []), Fs). + +update_one(_F, [], Acc) -> Acc; +update_one( F, [{F, Cr},Ds], Acc) -> update_one(F, Ds, [{F,Cr+1}|Acc]); +update_one( F, [ D|Ds], Acc) -> update_one(F, Ds, [ D|Acc]). |