diff options
author | Björn Gustavsson <[email protected]> | 2014-02-03 12:24:34 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2014-02-05 09:59:34 +0100 |
commit | 89bbe43c61320d6415d2f530df54dc4f6ccf03d4 (patch) | |
tree | aa285e1e88e63bfafa8c05898c31db2c61c95bdc /lib/dialyzer/src | |
parent | 8ad4c1c9b3a13d0236a03d4f47fb3b847d8e5cee (diff) | |
download | otp-89bbe43c61320d6415d2f530df54dc4f6ccf03d4.tar.gz otp-89bbe43c61320d6415d2f530df54dc4f6ccf03d4.tar.bz2 otp-89bbe43c61320d6415d2f530df54dc4f6ccf03d4.zip |
dialyzer: Silence useless warnings about list comprehensions
Dialyzer will warn if the value of list comprehension is
ignored by putting it in a sequence like this:
[SomeSideEffect(E) || E <- Es],
ok
To avoid a warning, you'll have to write:
_ = [SomeSideEffect(E) || E <- Es],
ok
Most of the time, this warning is merely annoying because it does
not point out any real errors.
Kostis Sagonas suggested that by suppressing the warning for
list comprehension that return a list of a simple type (e.g. ['ok']),
there would be no warning for code such as:
[io:format("~p\n", [E]) || E <- Es],
ok
but there would be still be a warning for:
[file:close(Fd) || Fd <- Fds],
ok
because an error condition is ignored.
Diffstat (limited to 'lib/dialyzer/src')
-rw-r--r-- | lib/dialyzer/src/dialyzer_dataflow.erl | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index 33fa107019..288d2dfbeb 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -58,10 +58,12 @@ t_fun_range/2, t_integer/0, t_integers/1, t_is_any/1, t_is_atom/1, t_is_atom/2, t_is_any_atom/3, t_is_boolean/2, - t_is_integer/2, t_is_nil/2, t_is_none/1, t_is_none_or_unit/1, + t_is_integer/2, t_is_list/1, + t_is_nil/2, t_is_none/1, t_is_none_or_unit/1, t_is_number/2, t_is_reference/2, t_is_pid/2, t_is_port/2, t_is_unit/1, - t_limit/2, t_list/0, t_maybe_improper_list/0, t_module/0, + t_limit/2, t_list/0, t_list_elements/2, + t_maybe_improper_list/0, t_module/0, t_none/0, t_non_neg_integer/0, t_number/0, t_number_vals/2, t_pid/0, t_port/0, t_product/1, t_reference/0, t_to_string/2, t_to_tlist/1, @@ -293,6 +295,7 @@ traverse(Tree, Map, State) -> t_is_any(ArgType) orelse t_is_simple(ArgType, State) orelse is_call_to_send(Arg) + orelse is_lc_simple_list(Arg, ArgType, State) of true -> % do not warn in these cases State1; @@ -2710,6 +2713,13 @@ is_call_to_send(Tree) -> andalso (Arity =:= 2) end. +is_lc_simple_list(Tree, TreeType, State) -> + Opaques = State#state.opaques, + Ann = cerl:get_ann(Tree), + lists:member(list_comprehension, Ann) + andalso t_is_list(TreeType) + andalso t_is_simple(t_list_elements(TreeType, Opaques), State). + filter_match_fail([Clause] = Cls) -> Body = cerl:clause_body(Clause), case cerl:type(Body) of |