aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2019-04-26 08:53:06 +0200
committerHans Bolinder <[email protected]>2019-04-26 08:53:06 +0200
commita90da2351b7088547b93413a3adf779d936bd056 (patch)
tree1a2eed3f836f64d4218d3e8826b2b1aac9f5f5e7 /lib
parent8f6d45ddc8b2b12376c252a30b267a822cad171a (diff)
parent6d9d4af8725f26972481b2e997c54ee5b3eafb29 (diff)
downloadotp-a90da2351b7088547b93413a3adf779d936bd056.tar.gz
otp-a90da2351b7088547b93413a3adf779d936bd056.tar.bz2
otp-a90da2351b7088547b93413a3adf779d936bd056.zip
Merge branch 'hasse/dialyzer/fun_app_args/OTP-15779'
* hasse/dialyzer/fun_app_args/OTP-15779: dialyzer: Improve the warning tagged 'fun_app_args'
Diffstat (limited to 'lib')
-rw-r--r--lib/dialyzer/src/dialyzer.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_dataflow.erl7
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/fun_app_args3
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/fun_app_args.erl12
4 files changed, 26 insertions, 3 deletions
diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl
index 185c8c9ae6..a168b3c8c5 100644
--- a/lib/dialyzer/src/dialyzer.erl
+++ b/lib/dialyzer/src/dialyzer.erl
@@ -320,9 +320,12 @@ message_to_string({call_to_missing, [M, F, A]}) ->
message_to_string({exact_eq, [Type1, Op, Type2]}) ->
io_lib:format("The test ~ts ~s ~ts can never evaluate to 'true'\n",
[Type1, Op, Type2]);
-message_to_string({fun_app_args, [Args, Type]}) ->
+message_to_string({fun_app_args, [ArgNs, Args, Type]}) ->
+ PositionString = form_position_string(ArgNs),
io_lib:format("Fun application with arguments ~ts will fail"
- " since the function has type ~ts\n", [Args, Type]);
+ " since the function has type ~ts,"
+ " which differs in the ~s argument\n",
+ [Args, Type, PositionString]);
message_to_string({fun_app_no_fun, [Op, Type, Arity]}) ->
io_lib:format("Fun application will fail since ~ts :: ~ts"
" is not a function of arity ~w\n", [Op, Type, Arity]);
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl
index 45b4abb253..f7aa167f5c 100644
--- a/lib/dialyzer/src/dialyzer_dataflow.erl
+++ b/lib/dialyzer/src/dialyzer_dataflow.erl
@@ -405,8 +405,13 @@ handle_apply(Tree, Map, State) ->
t_fun_args(OpType1, 'universe')),
case any_none(NewArgs) of
true ->
+ EnumNewArgs = lists:zip(lists:seq(1, length(NewArgs)),
+ NewArgs),
+ ArgNs = [Arg ||
+ {Arg, Type} <- EnumNewArgs, t_is_none(Type)],
Msg = {fun_app_args,
- [format_args(Args, ArgTypes, State),
+ [ArgNs,
+ format_args(Args, ArgTypes, State),
format_type(OpType, State)]},
State3 = state__add_warning(State2, ?WARN_FAILING_CALL,
Tree, Msg),
diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_app_args b/lib/dialyzer/test/small_SUITE_data/results/fun_app_args
new file mode 100644
index 0000000000..ac153a6fb2
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/fun_app_args
@@ -0,0 +1,3 @@
+
+fun_app_args.erl:12: Fun application with arguments ('b',[]) will fail since the function has type 'c' | fun(('a',[]) -> any()), which differs in the 1st argument
+fun_app_args.erl:12: The created fun has no local return
diff --git a/lib/dialyzer/test/small_SUITE_data/src/fun_app_args.erl b/lib/dialyzer/test/small_SUITE_data/src/fun_app_args.erl
new file mode 100644
index 0000000000..b4409bc550
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/fun_app_args.erl
@@ -0,0 +1,12 @@
+-module(fun_app_args).
+
+-export([t/1]).
+
+-type ft() :: fun((a, []) -> any()).
+
+-record(r, {
+ h = c :: c | ft()
+}).
+
+t(#r{h = H}) ->
+ fun(_) -> (H)(b, []) end.