aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dialyzer')
-rw-r--r--lib/dialyzer/doc/src/notes.xml32
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/fun_arity35
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl127
3 files changed, 180 insertions, 14 deletions
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 9b3a7244f1..aa29684697 100644
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -447,22 +447,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -776,19 +782,17 @@
Own Id: OTP-9731</p>
</item>
<item>
- <p>
<list> <item><p>No warnings for underspecs with remote
types</p></item> <item><p> Fix crash in Typer</p></item>
<item><p>Fix Dialyzer's warning for its own
code</p></item> <item><p>Fix Dialyzer's warnings in
HiPE</p></item> <item><p>Add file/line info in a
particular Dialyzer crash</p></item> <item><p>Update
- inets test results</p></item> </list></p>
+ inets test results</p></item> </list>
<p>
Own Id: OTP-9758</p>
</item>
<item>
- <p>
<list> <item><p>Correct callback spec in application
module</p></item> <item><p>Refine warning about callback
specs with extra ranges</p></item> <item><p>Cleanup
@@ -799,7 +803,7 @@
analysis</p></item> <item><p>Fix crash in
Dialyzer</p></item> <item><p>Variable substitution was
not generalizing any unknown variables.</p></item>
- </list></p>
+ </list>
<p>
Own Id: OTP-9776</p>
</item>
diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_arity b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
new file mode 100644
index 0000000000..280f5490d0
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
@@ -0,0 +1,35 @@
+
+fun_arity.erl:100: Fun application will fail since _cor1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:100: Function 'Mfa_0_ko'/1 has no local return
+fun_arity.erl:104: Fun application will fail since _cor1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:104: Function 'Mfa_1_ko'/1 has no local return
+fun_arity.erl:111: Fun application will fail since _cor1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:111: Function mFa_0_ko/1 has no local return
+fun_arity.erl:115: Fun application will fail since _cor1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:115: Function mFa_1_ko/1 has no local return
+fun_arity.erl:122: Fun application will fail since _cor2 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:122: Function 'MFa_0_ko'/2 has no local return
+fun_arity.erl:126: Fun application will fail since _cor2 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:126: Function 'MFa_1_ko'/2 has no local return
+fun_arity.erl:35: Fun application will fail since _cor0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:35: Function f_0_ko/0 has no local return
+fun_arity.erl:39: Fun application will fail since _cor0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:39: Function f_1_ko/0 has no local return
+fun_arity.erl:48: Fun application will fail since _cor0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:48: Function fa_0_ko/0 has no local return
+fun_arity.erl:53: Fun application will fail since _cor0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:53: Function fa_1_ko/0 has no local return
+fun_arity.erl:63: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:63: Function mfa_0_ko/0 has no local return
+fun_arity.erl:68: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:68: Function mfa_1_ko/0 has no local return
+fun_arity.erl:76: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:76: Function mfa_ne_0_ko/0 has no local return
+fun_arity.erl:78: Function mf_ne/0 will never be called
+fun_arity.erl:81: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:81: Function mfa_ne_1_ko/0 has no local return
+fun_arity.erl:83: Function mf_ne/1 will never be called
+fun_arity.erl:89: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:89: Function mfa_nd_0_ko/0 has no local return
+fun_arity.erl:93: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:93: Function mfa_nd_1_ko/0 has no local return
diff --git a/lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl b/lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl
new file mode 100644
index 0000000000..850d2fd331
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl
@@ -0,0 +1,127 @@
+%%--------------------------------------------------------------------------
+%% Module which contains calls to funs of different arity.
+%%--------------------------------------------------------------------------
+-module(fun_arity).
+
+-export([f_0_ok/0, f_0_ko/0]).
+-export([f_1_ok/0, f_1_ko/0]).
+
+-export([fa_0_ok/0, fa_0_ko/0]).
+-export([fa_1_ok/0, fa_1_ko/0]).
+
+-export([mfa_0_ok/0, mfa_0_ko/0, mf/0]).
+-export([mfa_1_ok/0, mfa_1_ko/0, mf/1]).
+
+-export([mfa_ne_0_ok/0, mfa_ne_0_ko/0]).
+-export([mfa_ne_1_ok/0, mfa_ne_1_ko/0]).
+
+-export([mfa_nd_0_ok/0, mfa_nd_0_ko/0]).
+-export([mfa_nd_1_ok/0, mfa_nd_1_ko/0]).
+
+-export(['Mfa_0_ok'/1, 'Mfa_0_ko'/1]).
+-export(['Mfa_1_ok'/1, 'Mfa_1_ko'/1]).
+
+-export(['mFa_0_ok'/1, 'mFa_0_ko'/1]).
+-export(['mFa_1_ok'/1, 'mFa_1_ko'/1]).
+
+-export(['MFa_0_ok'/2, 'MFa_0_ko'/2]).
+-export(['MFa_1_ok'/2, 'MFa_1_ko'/2]).
+
+%%--------------------------------------------------------------------------
+
+%% Funs like "fun(...) -> ... end".
+
+f_0_ok() -> (fun_f_0())().
+f_0_ko() -> (fun_f_0())(1).
+fun_f_0() -> fun() -> ok end.
+
+f_1_ok() -> (fun_f_1())(1).
+f_1_ko() -> (fun_f_1())().
+fun_f_1() -> fun(_) -> ok end .
+
+%%--------------------------------------------------------------------------
+
+%% Funs like "fun F/A" when F is literal atom and A is literal
+%% non-negative integer.
+
+fa_0_ok() -> (fun_fa_0())().
+fa_0_ko() -> (fun_fa_0())(1).
+fun_fa_0() -> fun f/0.
+f() -> ok.
+
+fa_1_ok() -> (fun_fa_1())(1).
+fa_1_ko() -> (fun_fa_1())().
+fun_fa_1() -> fun f/1.
+f(_) -> ok.
+
+%%--------------------------------------------------------------------------
+
+%% Funs like "fun M:F/A" when M and F are literal atoms, A is literal
+%% non-negative integer and function is (defined and) exported.
+
+mfa_0_ok() -> (fun_mfa_0())().
+mfa_0_ko() -> (fun_mfa_0())(1).
+fun_mfa_0() -> fun ?MODULE:mf/0.
+mf() -> ok.
+
+mfa_1_ok() -> (fun_mfa_1())(1).
+mfa_1_ko() -> (fun_mfa_1())().
+fun_mfa_1() -> fun ?MODULE:mf/1.
+mf(_) -> ok.
+
+%% Funs like "fun M:F/A" when M and F are literal atoms, A is literal
+%% non-negative integer and function is defined but not exported.
+
+mfa_ne_0_ok() -> (fun_mfa_ne_0())().
+mfa_ne_0_ko() -> (fun_mfa_ne_0())(1).
+fun_mfa_ne_0() -> fun ?MODULE:mf_ne/0.
+mf_ne() -> ok.
+
+mfa_ne_1_ok() -> (fun_mfa_ne_1())(1).
+mfa_ne_1_ko() -> (fun_mfa_ne_1())().
+fun_mfa_ne_1() -> fun ?MODULE:mf_ne/1.
+mf_ne(_) -> ok.
+
+%% Funs like "fun M:F/A" when M and F are literal atoms, A is literal
+%% non-negative integer and function is not defined.
+
+mfa_nd_0_ok() -> (fun_mfa_nd_0())().
+mfa_nd_0_ko() -> (fun_mfa_nd_0())(1).
+fun_mfa_nd_0() -> fun ?MODULE:mf_nd/0.
+
+mfa_nd_1_ok() -> (fun_mfa_nd_1())(1).
+mfa_nd_1_ko() -> (fun_mfa_nd_1())().
+fun_mfa_nd_1() -> fun ?MODULE:mf_nd/1.
+
+%% Funs like "fun M:F/A" when M is variable, F is literal atoms and A
+%% is literal non-negative integer.
+
+'Mfa_0_ok'(M) -> ('fun_Mfa_0'(M))().
+'Mfa_0_ko'(M) -> ('fun_Mfa_0'(M))(1).
+'fun_Mfa_0'(M) -> fun M:f/0.
+
+'Mfa_1_ok'(M) -> ('fun_Mfa_1'(M))(1).
+'Mfa_1_ko'(M) -> ('fun_Mfa_1'(M))().
+'fun_Mfa_1'(M) -> fun M:f/1.
+
+%% Funs like "fun M:F/A" when M is literal atom, F is variable and A
+%% is literal non-negative integer.
+
+'mFa_0_ok'(F) -> ('fun_mFa_0'(F))().
+'mFa_0_ko'(F) -> ('fun_mFa_0'(F))(1).
+'fun_mFa_0'(F) -> fun ?MODULE:F/0.
+
+'mFa_1_ok'(F) -> ('fun_mFa_1'(F))(1).
+'mFa_1_ko'(F) -> ('fun_mFa_1'(F))().
+'fun_mFa_1'(F) -> fun ?MODULE:F/1.
+
+%% Funs like "fun M:F/A" when M and F are variables and A is literal
+%% non-negative integer.
+
+'MFa_0_ok'(M, F) -> ('fun_MFa_0'(M, F))().
+'MFa_0_ko'(M, F) -> ('fun_MFa_0'(M, F))(1).
+'fun_MFa_0'(M, F) -> fun M:F/0.
+
+'MFa_1_ok'(M, F) -> ('fun_MFa_1'(M, F))(1).
+'MFa_1_ko'(M, F) -> ('fun_MFa_1'(M, F))().
+'fun_MFa_1'(M, F) -> fun M:F/1.