aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/test/small_SUITE_data/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dialyzer/test/small_SUITE_data/src')
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/chars.erl18
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/extra_range.erl59
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/left_assoc.erl96
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/stacktrace.erl73
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/unused_funs.erl21
5 files changed, 262 insertions, 5 deletions
diff --git a/lib/dialyzer/test/small_SUITE_data/src/chars.erl b/lib/dialyzer/test/small_SUITE_data/src/chars.erl
index 1e9c8ab6b9..62b90cf54d 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/chars.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/chars.erl
@@ -12,17 +12,25 @@
-spec t() -> $0-$0..$9-$0| $?.
t() ->
- c(#r{f = $z - 3}),
+ r(#r{f = $z - 3}),
+ r(#r{f = 97}),
+ c($/),
c($z - 3),
c($B).
-spec c(cs()) -> $3-$0..$9-$0.
-
-c($A + 1) -> 2;
+c($A + 1) -> $9-$0;
c(C) ->
case C of
- $z - 3 -> 3;
- #r{f = $z - 3} -> 7
+ $z - 3 -> $3-$0;
+ _ -> $7-$0
+ end.
+
+-spec r(#r{f :: $a..$z}) -> ok | error.
+r(R) ->
+ case R of
+ #r{f = $z - 3} -> error;
+ _ -> ok
end.
%% Display contract with character in warning:
diff --git a/lib/dialyzer/test/small_SUITE_data/src/extra_range.erl b/lib/dialyzer/test/small_SUITE_data/src/extra_range.erl
new file mode 100644
index 0000000000..9d6ba89c95
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/extra_range.erl
@@ -0,0 +1,59 @@
+%% Test that a spec containing more items than actually returned
+%% (whether by accident or by benign overspeccing) does not prevent
+%% detection of impossible matches.
+
+-module(extra_range).
+
+-export([t1/2, t2/2, t3/2, t4/2]).
+
+-dialyzer([no_return]).
+
+%% this spec matches the behaviour of the code
+-spec normal(integer()) -> ok | error.
+normal(1) -> ok;
+normal(2) -> error.
+
+t1(X, Y) when is_integer(X), is_integer(Y) ->
+ ok = normal(X),
+ error = normal(Y),
+ ok.
+
+
+%% this spec has a typo, which should cause anyone trying to match on
+%% `ok = typo(X)' to get a warning, because `ok' is not in the spec
+-spec typo(integer()) -> ook | error.
+typo(1) -> ok;
+typo(2) -> error.
+
+t2(X, Y) when is_integer(X), is_integer(Y) ->
+ ok = typo(X), % warning expected - not allowed according to spec
+ error = typo(Y),
+ ok.
+
+
+%% this is overspecified, and should cause a warning for trying
+%% to match on `no = over(X)', because it cannot succeed and either
+%% the spec should be updated or the code should be extended
+-spec over(integer()) -> yes | no | maybe.
+over(1) -> yes;
+over(_) -> maybe.
+
+t3(X, Y) when is_integer(X), is_integer(Y) ->
+ yes = over(X),
+ no = over(Y), % warning expected - spec or code needs fixing
+ maybe = over(X + Y),
+ ok.
+
+
+%% this is underspecified, which should cause anyone trying to match on
+%% `maybe = under(X)' to get a warning, because `maybe' is not in the spec
+-spec under(integer()) -> yes | no.
+under(1) -> yes;
+under(2) -> no;
+under(_) -> maybe.
+
+t4(X, Y) when is_integer(X), is_integer(Y) ->
+ yes = under(X),
+ no = under(Y),
+ maybe = under(X + Y), % warning expected - not in spec
+ ok.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/left_assoc.erl b/lib/dialyzer/test/small_SUITE_data/src/left_assoc.erl
new file mode 100644
index 0000000000..0250e4ab49
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/left_assoc.erl
@@ -0,0 +1,96 @@
+-module(left_assoc).
+
+%% As pointed out in ERL-680, analyzing guards with short circuit
+%% operators becomes very slow as the number of left associations
+%% grows.
+
+-spec from_iso8601('Elixir.String':t(), 'Elixir.Calendar':calendar()) ->
+ {ok, t()} | {error, atom()}.
+
+-export_type([t/0]).
+
+-type t() ::
+ #{'__struct__' := 'Elixir.Date',
+ calendar := 'Elixir.Calendar':calendar(),
+ day := 'Elixir.Calendar':day(),
+ month := 'Elixir.Calendar':month(),
+ year := 'Elixir.Calendar':year()}.
+
+-export([from_iso8601/1,
+ from_iso8601/2]).
+
+from_iso8601(__@1) ->
+ from_iso8601(__@1, 'Elixir.Calendar.ISO').
+
+from_iso8601(<<45/integer,_rest@1/binary>>, _calendar@1) ->
+ case raw_from_iso8601(_rest@1, _calendar@1) of
+ {ok,#{year := _year@1} = _date@1} ->
+ {ok,_date@1#{year := - _year@1}};
+ __@1 ->
+ __@1
+ end;
+from_iso8601(<<_rest@1/binary>>, _calendar@1) ->
+ raw_from_iso8601(_rest@1, _calendar@1).
+
+raw_from_iso8601(_string@1, _calendar@1) ->
+ case _string@1 of
+ <<_y1@1/integer,
+ _y2@1/integer,
+ _y3@1/integer,
+ _y4@1/integer,
+ 45/integer,
+ _m1@1/integer,
+ _m2@1/integer,
+ 45/integer,
+ _d1@1/integer,
+ _d2@1/integer>>
+ when
+ ((((((((((((((_y1@1 >= 48
+ andalso
+ _y1@1 =< 57)
+ andalso
+ _y2@1 >= 48)
+ andalso
+ _y2@1 =< 57)
+ andalso
+ _y3@1 >= 48)
+ andalso
+ _y3@1 =< 57)
+ andalso
+ _y4@1 >= 48)
+ andalso
+ _y4@1 =< 57)
+ andalso
+ _m1@1 >= 48)
+ andalso
+ _m1@1 =< 57)
+ andalso
+ _m2@1 >= 48)
+ andalso
+ _m2@1 =< 57)
+ andalso
+ _d1@1 >= 48)
+ andalso
+ _d1@1 =< 57)
+ andalso
+ _d2@1 >= 48)
+ andalso
+ _d2@1 =< 57 ->
+ {ok,
+ #{year => (_y1@1 - 48) * 1000 + (_y2@1 - 48) * 100
+ +
+ (_y3@1 - 48) * 10
+ +
+ (_y4@1 - 48),
+ month => (_m1@1 - 48) * 10 + (_m2@1 - 48),
+ day => (_d1@1 - 48) * 10 + (_d2@1 - 48),
+ calendar => _calendar@1,
+ '__struct__' => 'Elixir.Date'}};
+ __@1 ->
+ case __@1 of
+ _ ->
+ {error,invalid_format};
+ __@2 ->
+ error({with_clause,__@2})
+ end
+ end.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/stacktrace.erl b/lib/dialyzer/test/small_SUITE_data/src/stacktrace.erl
new file mode 100644
index 0000000000..de79e710e9
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/stacktrace.erl
@@ -0,0 +1,73 @@
+-module(stacktrace).
+
+%% Check the stacktrace variable introduced in Erlang/OTP 21.0
+
+-export([t1/0, t2/0, t3/0, t4/0, s1/0, s2/0, s3/0, s4/0]).
+
+t1() ->
+ try foo:bar()
+ catch
+ E:P:S ->
+ {a,b} = S, % can never match
+ {E, P}
+ end.
+
+t2() ->
+ try foo:bar()
+ catch
+ E:P:S ->
+ [a,b] = S, % can never match
+ {E, P}
+ end.
+
+t3() ->
+ try foo:bar()
+ catch
+ E:P:S ->
+ [{m,f,[],[]}] = S,
+ {E, P}
+ end.
+
+t4() ->
+ try foo:bar()
+ catch
+ E:P:S ->
+ [{m,f,1,[{file,"tjo"},{line,95}]}] = S,
+ {E, P}
+ end.
+
+s1() ->
+ try foo:bar()
+ catch
+ E:P ->
+ S = erlang:get_stacktrace(),
+ {a,b} = S, % can never match
+ {E, P}
+ end.
+
+s2() ->
+ try foo:bar()
+ catch
+ E:P ->
+ S = erlang:get_stacktrace(),
+ [a,b] = S, % can never match
+ {E, P}
+ end.
+
+s3() ->
+ try foo:bar()
+ catch
+ E:P ->
+ S = erlang:get_stacktrace(),
+ [{m,f,[],[]}] = S,
+ {E, P}
+ end.
+
+s4() ->
+ try foo:bar()
+ catch
+ E:P ->
+ S = erlang:get_stacktrace(),
+ [{m,f,1,[{file,"tjo"},{line,95}]}] = S,
+ {E, P}
+ end.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/unused_funs.erl b/lib/dialyzer/test/small_SUITE_data/src/unused_funs.erl
new file mode 100644
index 0000000000..c24cf3ea81
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/unused_funs.erl
@@ -0,0 +1,21 @@
+%% See also ERL-593.
+
+-module(unused_funs).
+
+-export([test/0]).
+
+test() -> % "has no local return"
+ Var = outer_scope,
+ case other_error of
+ error -> % "can never match"
+ %% No warnings "no local return" and "_ = 1 can never match 0" (!)
+ foo(fun() -> {Var, 1 = 0} end)
+ end.
+
+not_used() -> % "will never be called"
+ %% No warnings "no local return" and "1 can never match 0".
+ foo(fun() -> 1 = 0 end).
+
+foo(Fun) -> % "will never be called"
+ 1 = 0, % No pattern match warning (foo/1 is not traversed at all).
+ Fun().