From 7afd92015a0d1c32d5fb9f8a58d1fd4326aaa522 Mon Sep 17 00:00:00 2001 From: Stavros Aronis Date: Mon, 21 Mar 2011 18:37:13 +0200 Subject: Add small/refine_failing --- .../test/small_SUITE_data/results/refine_failing | 2 ++ .../test/small_SUITE_data/src/refine_failing.erl | 26 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 lib/dialyzer/test/small_SUITE_data/results/refine_failing create mode 100644 lib/dialyzer/test/small_SUITE_data/src/refine_failing.erl diff --git a/lib/dialyzer/test/small_SUITE_data/results/refine_failing b/lib/dialyzer/test/small_SUITE_data/results/refine_failing new file mode 100644 index 0000000000..2bf67c9d81 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/results/refine_failing @@ -0,0 +1,2 @@ + +refine_failing.erl:25: The call refine_failing:update_one(F::any(),Ds::{_,non_neg_integer()},[{_,non_neg_integer()},...]) will never return since it differs in the 2nd argument from the success typing arguments: (any(),[{_,non_neg_integer()}],[{_,non_neg_integer()}]) 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 + +-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]). -- cgit v1.2.3