From b66e75c285cba469c5225f3394da149456d17d16 Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Mon, 3 Feb 2014 10:27:39 +0100 Subject: Deprecate pre-defined built-in types The types array(), dict(), digraph(), gb_set(), gb_tree(), queue(), set(), and tid() have been deprecated. They will be removed in OTP 18.0. Instead the types array:array(), dict:dict(), digraph:graph(), gb_set:set(), gb_tree:tree(), queue:queue(), sets:set(), and ets:tid() can be used. (Note: it has always been necessary to use ets:tid().) It is allowed in OTP 17.0 to locally re-define the types array(), dict(), and so on. New types array:array/1, dict:dict/2, gb_sets:set/1, gb_trees:tree/2, queue:queue/1, and sets:set/1 have been added. --- .../test/opaque_SUITE_data/src/dict/dict_use.erl | 2 +- .../test/opaque_SUITE_data/src/ets/ets_use.erl | 4 +- .../test/opaque_SUITE_data/src/ewgi/ewgi.hrl | 2 +- .../test/opaque_SUITE_data/src/ewgi2/ewgi.hrl | 2 +- .../opaque_SUITE_data/src/gb_sets/gb_sets_rec.erl | 4 +- .../test/opaque_SUITE_data/src/inf_loop1.erl | 4 +- .../test/opaque_SUITE_data/src/inf_loop2.erl | 4 +- .../src/multiple_wrong_opaques.erl | 2 +- .../test/opaque_SUITE_data/src/para/para1.erl | 93 ++++++++++++++++ .../test/opaque_SUITE_data/src/para/para1_adt.erl | 36 ++++++ .../test/opaque_SUITE_data/src/para/para2.erl | 123 +++++++++++++++++++++ .../test/opaque_SUITE_data/src/para/para2_adt.erl | 64 +++++++++++ .../test/opaque_SUITE_data/src/para/para3.erl | 77 +++++++++++++ .../test/opaque_SUITE_data/src/para/para3_adt.erl | 27 +++++ .../opaque_SUITE_data/src/simple/exact_api.erl | 4 +- .../opaque_SUITE_data/src/wings/wings_util.erl | 4 +- .../test/opaque_SUITE_data/src/zoltan_kis2.erl | 2 +- 17 files changed, 437 insertions(+), 17 deletions(-) create mode 100644 lib/dialyzer/test/opaque_SUITE_data/src/para/para1.erl create mode 100644 lib/dialyzer/test/opaque_SUITE_data/src/para/para1_adt.erl create mode 100644 lib/dialyzer/test/opaque_SUITE_data/src/para/para2.erl create mode 100644 lib/dialyzer/test/opaque_SUITE_data/src/para/para2_adt.erl create mode 100644 lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl create mode 100644 lib/dialyzer/test/opaque_SUITE_data/src/para/para3_adt.erl (limited to 'lib/dialyzer/test/opaque_SUITE_data/src') diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl b/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl index 8a2cd86f43..a4cec065ab 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl @@ -24,7 +24,7 @@ ok3() -> ok4() -> dict:fetch(foo, dict:new()). -ok5() -> % this is OK since some_mod:new/0 might be returning a dict() +ok5() -> % this is OK since some_mod:new/0 might be returning a dict:dict() dict:fetch(foo, some_mod:new()). ok6() -> diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/ets/ets_use.erl b/lib/dialyzer/test/opaque_SUITE_data/src/ets/ets_use.erl index 4eb202f16a..593d9a669d 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/ets/ets_use.erl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/ets/ets_use.erl @@ -17,6 +17,6 @@ t3() -> is_atom(n()). % no warning since atom() is possible t4() -> - is_integer(n()). % opaque warning since tid() is opaque + is_integer(n()). % opaque warning since ets:tid() is opaque -n() -> ets:new(n, [named_table]). % -> atom() | tid() +n() -> ets:new(n, [named_table]). % -> atom() | ets:tid() diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/ewgi/ewgi.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/ewgi/ewgi.hrl index 0b98f550f1..5cbc79f948 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/ewgi/ewgi.hrl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/ewgi/ewgi.hrl @@ -28,7 +28,7 @@ %% @type bag() = gb_tree() -ifdef(HAS_GB_TREE_SPEC). --type bag() :: gb_tree(). +-type bag() :: gb_trees:tree(). -else. -type bag() :: {non_neg_integer(), {any(), any(), any(), any()} | 'nil'}. -endif. diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/ewgi2/ewgi.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/ewgi2/ewgi.hrl index 5da8ff0ecf..d8e15cb081 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/ewgi2/ewgi.hrl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/ewgi2/ewgi.hrl @@ -29,7 +29,7 @@ %% @type bag() = gb_tree() -ifdef(HAS_GB_TREE_SPEC). --type bag() :: gb_tree(). +-type bag() :: gb_trees:tree(). -else. -type bag() :: {non_neg_integer(), {any(), any(), any(), any()} | 'nil'}. -endif. diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/gb_sets/gb_sets_rec.erl b/lib/dialyzer/test/opaque_SUITE_data/src/gb_sets/gb_sets_rec.erl index 008b0a486a..7c34b01c2d 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/gb_sets/gb_sets_rec.erl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/gb_sets/gb_sets_rec.erl @@ -12,12 +12,12 @@ -export([new/0, get_g/1]). --record(rec, {g :: gb_set()}). +-record(rec, {g :: gb_sets:set()}). -spec new() -> #rec{}. new() -> #rec{g = gb_sets:empty()}. --spec get_g(#rec{}) -> gb_set(). +-spec get_g(#rec{}) -> gb_sets:set(). get_g(R) -> R#rec.g. diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/inf_loop1.erl b/lib/dialyzer/test/opaque_SUITE_data/src/inf_loop1.erl index 0dff16cf14..3275736e75 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/inf_loop1.erl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/inf_loop1.erl @@ -1,7 +1,7 @@ %% -*- erlang-indent-level: 2 -*- %%---------------------------------------------------------------------------- %% Non-sensical (i.e., stripped-down) program that sends the analysis -%% into an infinite loop. The #we.es field was originally a gb_tree() +%% into an infinite loop. The #we.es field was originally a gb_trees:tree() %% but the programmer declared it as an array in order to change it to %% that data type instead. In the file, there are two calls to function %% gb_trees:get/2 which seem to be the ones responsible for sending the @@ -14,7 +14,7 @@ -export([command/1]). -record(we, {id, - es = array:new() :: array(), + es = array:new() :: array:array(), vp, mirror = none}). -record(edge, {vs,ve,a = none,b = none,lf,rf,ltpr,ltsu,rtpr,rtsu}). diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/inf_loop2.erl b/lib/dialyzer/test/opaque_SUITE_data/src/inf_loop2.erl index 659ccaf015..3787fc6750 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/inf_loop2.erl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/inf_loop2.erl @@ -4,7 +4,7 @@ %% restored. %% Non-sensical (i.e., stripped-down) program that sends the analysis -%% into an infinite loop. The #we.es field was originally a gb_tree() +%% into an infinite loop. The #we.es field was originally a gb_trees:tree() %% but the programmer declared it as an array in order to change it to %% that data type instead. In the file, there are two calls to function %% gb_trees:get/2 which seem to be the ones responsible for sending the @@ -17,7 +17,7 @@ -export([command/1]). -record(we, {id, - es = array:new() :: array(), + es = array:new() :: array:array(), vp, mirror = none}). -record(edge, {vs,ve,a = none,b = none,lf,rf,ltpr,ltsu,rtpr,rtsu}). diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/multiple_wrong_opaques.erl b/lib/dialyzer/test/opaque_SUITE_data/src/multiple_wrong_opaques.erl index 9e695cec1d..e9f7ad825b 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/multiple_wrong_opaques.erl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/multiple_wrong_opaques.erl @@ -2,7 +2,7 @@ -export([weird/1]). --spec weird(dict() | gb_tree()) -> 42. +-spec weird(dict:dict() | gb_trees:tree()) -> 42. weird(gazonk) -> 42. diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para1.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para1.erl new file mode 100644 index 0000000000..68e2c60368 --- /dev/null +++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para1.erl @@ -0,0 +1,93 @@ +-module(para1). + +-compile(export_all). + +%% Parameterized opaque types + +-export_type([t/0, t/1]). + +-opaque t() :: {integer(), integer()}. + +-opaque t(A) :: {A, A}. + +-type y(A) :: {A, A}. + +tt1() -> + I = t1(), + A = t2(), + A =:= I. % never 'true' + +tt2() -> + I = t0(), + A = t2(), + A =:= I. % never 'true' + +tt3() -> + I1 = t0(), + I2 = t1(), + I1 =:= I2. % never true + +tt4() -> + I1 = y1(), + I2 = y2(), + I1 =:= I2. % cannot evaluate to true + +adt_tt1() -> + I = adt_t1(), + A = adt_t2(), + A =:= I. % opaque attempt + +adt_tt2() -> + I = adt_t0(), + A = adt_t2(), + A =:= I. % opaque attempt + +adt_tt3() -> + I1 = adt_t0(), + I2 = adt_t1(), + I1 =:= I2. % opaque attempt + +adt_tt4() -> + I1 = adt_y1(), + I2 = adt_y2(), + I1 =:= I2. % cannot evaluate to true + +-spec t0() -> t(). + +t0() -> + {3, 2}. + +-spec t1() -> t(integer()). + +t1() -> + {3, 3}. + +-spec t2() -> t(atom()). + +t2() -> + {a, b}. + +-spec y1() -> y(integer()). + +y1() -> + {3, 2}. + +-spec y2() -> y(atom()). + +y2() -> + {a, b}. + +adt_t0() -> + para1_adt:t0(). + +adt_t1() -> + para1_adt:t1(). + +adt_t2() -> + para1_adt:t2(). + +adt_y1() -> + para1_adt:y1(). + +adt_y2() -> + para1_adt:y2(). diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para1_adt.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para1_adt.erl new file mode 100644 index 0000000000..95ac6b7982 --- /dev/null +++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para1_adt.erl @@ -0,0 +1,36 @@ +-module(para1_adt). + +-export([t0/0, t1/0, t2/0, y1/0, y2/0]). + +-export_type([t/0, t/1, y/1]). + +-opaque t() :: {integer(), integer()}. + +-opaque t(A) :: {A, A}. + +-type y(A) :: {A, A}. + +-spec t0() -> t(). + +t0() -> + {3, 2}. + +-spec t1() -> t(integer()). + +t1() -> + {3, 3}. + +-spec t2() -> t(atom()). + +t2() -> + {a, b}. + +-spec y1() -> y(integer()). + +y1() -> + {3, 2}. + +-spec y2() -> y(atom()). + +y2() -> + {a, b}. diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para2.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para2.erl new file mode 100644 index 0000000000..09b2235fa5 --- /dev/null +++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para2.erl @@ -0,0 +1,123 @@ +-module(para2). + +-compile(export_all). + +%% More parameterized opaque types + +-export_type([strange/1]). + +-export_type([c1/0, c2/0]). + +-export_type([circ/1, circ/2]). + +-opaque strange(A) :: {B, B, A}. + +-spec t(strange(integer())) -> strange(atom()). + +t({3, 4, 5}) -> + {a, b, c}. + +-opaque c1() :: c2(). +-opaque c2() :: c1(). + +c() -> + A = c1(), + B = c2(), + A =:= B. + +t() -> + A = ct1(), + B = ct2(), + A =:= B. % can never evaluate to 'true' + +-spec c1() -> c1(). + +c1() -> + a. + +-spec c2() -> c2(). + +c2() -> + a. + +-type ct1() :: ct2(). +-type ct2() :: ct1(). + +-spec ct1() -> ct1(). + +ct1() -> + a. + +-spec ct2() -> ct2(). + +ct2() -> + b. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +c_adt() -> + A = c1_adt(), + B = c2_adt(), + A =:= B. % opaque attempt + +t_adt() -> + A = ct1_adt(), + B = ct2_adt(), + A =:= B. % can never evaluate to true + +c1_adt() -> + para2_adt:c1(). + +c2_adt() -> + para2_adt:c2(). + +ct1_adt() -> + para2_adt:ct1(). + +ct2_adt() -> + para2_adt:ct2(). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-opaque circ(A) :: circ(A, A). +-opaque circ(A, B) :: circ({A, B}). + +tcirc() -> + A = circ1(), + B = circ2(), + A =:= B. % can never evaluate to 'true' (but the types are not OK, or?) + +-spec circ1() -> circ(integer()). + +circ1() -> + 3. + +-spec circ2() -> circ(integer(), integer()). + +circ2() -> + {3, 3}. + +tcirc_adt() -> + A = circ1_adt(), + B = circ2_adt(), + A =:= B. % opaque attempt (one would expect them to be the same...) + +circ1_adt() -> + para2_adt:circ1(). + +circ2_adt() -> + para2_adt:circ2(). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +u_adt() -> + A = u1_adt(), + B = u2_adt(), + %% The resulting types are equal, but not the parameters: + A =:= B. % opaque attempt + +u1_adt() -> + para2_adt:u1(). + +u2_adt() -> + para2_adt:u2(). diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para2_adt.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para2_adt.erl new file mode 100644 index 0000000000..96df437c67 --- /dev/null +++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para2_adt.erl @@ -0,0 +1,64 @@ +-module(para2_adt). + +%% More parameterized opaque types + +-export_type([c1/0, c2/0]). + +-export_type([ct1/0, ct2/0]). + +-export_type([circ/1, circ/2]). + +-export_type([un/2]). + +-export([c1/0, c2/0, ct1/0, ct2/0, circ1/0, circ2/0, u1/0, u2/0]). + +-opaque c1() :: c2(). +-opaque c2() :: c1(). + +-spec c1() -> c1(). + +c1() -> + a. + +-spec c2() -> c2(). + +c2() -> + a. + +-type ct1() :: ct2(). +-type ct2() :: ct1(). + +-spec ct1() -> ct1(). + +ct1() -> + a. + +-spec ct2() -> ct2(). + +ct2() -> + b. + +-opaque circ(A) :: circ(A, A). +-opaque circ(A, B) :: circ({A, B}). + +-spec circ1() -> circ(integer()). + +circ1() -> + 3. + +-spec circ2() -> circ(integer(), integer()). + +circ2() -> + {3, 3}. + +-opaque un(A, B) :: A | B. + +-spec u1() -> un(integer(), atom()). + +u1() -> + 3. + +-spec u2() -> un(atom(), integer()). + +u2() -> + 3. diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl new file mode 100644 index 0000000000..792ae40d39 --- /dev/null +++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl @@ -0,0 +1,77 @@ +-module(para3). + +-export([t/0, t1/1, t2/0, ot1/1, ot2/0, t1_adt/0, t2_adt/0]). + +-export([exp_adt/0]). + +%% More opaque tests. + +-export_type([ot1/0, ot1/1, ot1/2, ot1/3, ot1/4, ot1/5]). + +-opaque ot1() :: {ot1(_)}. + +-opaque ot1(A) :: {ot1(A, A)}. + +-opaque ot1(A, B) :: {ot1(A, B, A)}. + +-opaque ot1(A, B, C) :: {ot1(A, B, C, A)}. + +-opaque ot1(A, B, C, D) :: {ot1(A, B, C, D, A)}. + +-opaque ot1(A, B, C, D, E) :: {A, B, C, D, E}. + +-spec ot1(_) -> ot1(). + +ot1(A) -> + {{{{{A, A, A, A, A}}}}}. + +-spec ot2() -> ot1(). % invalid type spec + +ot2() -> + foo. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +t() -> + {{{17}}} = t1(3). %% pattern can never match + +-type t1() :: {t1(_)}. + +-type t1(A) :: {t1(A, A)}. + +-type t1(A, B) :: {t1(A, B, A)}. + +-type t1(A, B, C) :: {t1(A, B, C, A)}. + +-type t1(A, B, C, D) :: {t1(A, B, C, D, A)}. + +-type t1(A, B, C, D, E) :: {A, B, C, D, E}. + +-spec t1(_) -> t1(). + +t1(A) -> + {{{{{A, A, A, A, A}}}}}. + +-spec t2() -> t1(). % invalid type spec + +t2() -> + foo. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Shows that the list TypeNames in t_from_form must include ArgsLen. + +t1_adt() -> + {{{{{17}}}}} = para3_adt:t1(3). % breaks the opaqueness + +t2_adt() -> + {{{{17}}}} = para3_adt:t1(3). % can never match + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-type exp() :: para3_adt:exp1(para3_adt:exp2()). + +-spec exp_adt() -> exp(). + +exp_adt() -> + 3. diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para3_adt.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para3_adt.erl new file mode 100644 index 0000000000..3919b846e6 --- /dev/null +++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para3_adt.erl @@ -0,0 +1,27 @@ +-module(para3_adt). + +-export([t1/1]). + +-export_type([t1/0, t1/1, t1/2, t1/3, t1/4, ot1/5]). + +-export_type([exp1/1, exp2/0]). + +-type t1() :: {t1(_)}. + +-type t1(A) :: {t1(A, A)}. + +-type t1(A, B) :: {t1(A, B, A)}. + +-type t1(A, B, C) :: {t1(A, B, C, A)}. + +-type t1(A, B, C, D) :: {ot1(A, B, C, D, A)}. + +-opaque ot1(A, B, C, D, E) :: {A, B, C, D, E}. + +-spec t1(_) -> t1(). + +t1(A) -> + {{{{{A, A, A, A, A}}}}}. + +-opaque exp1(T) :: T. +-opaque exp2() :: integer(). diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl index 5f7ab4f3aa..c19330eb30 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl @@ -10,14 +10,14 @@ ntab = notable :: ets:tab(), cyclic = true :: boolean()}). --spec new() -> digraph(). +-spec new() -> digraph:graph(). new() -> A = #digraph{}, set_type(A), % does not have an opaque term as 1st argument A. --spec set_type(digraph()) -> true. +-spec set_type(digraph:graph()) -> true. set_type(G) -> digraph:delete(G). diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl b/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl index 8f0da1f5dc..ca6bc0ab4a 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl @@ -14,12 +14,12 @@ rel2fam(Rel) -> sofs:to_external(sofs:relation_to_family(sofs:relation(Rel))). -%% a definition that does not violate the opaqueness of gb_tree() +%% a definition that does not violate the opaqueness of gb_trees:tree() gb_trees_smallest_key(Tree) -> {Key, _V} = gb_trees:smallest(Tree), Key. -%% a definition that violates the opaqueness of gb_tree() +%% a definition that violates the opaqueness of gb_trees:tree() gb_trees_largest_key({_, Tree}) -> largest_key1(Tree). diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/zoltan_kis2.erl b/lib/dialyzer/test/opaque_SUITE_data/src/zoltan_kis2.erl index 38c6051c58..e094d1982b 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/src/zoltan_kis2.erl +++ b/lib/dialyzer/test/opaque_SUITE_data/src/zoltan_kis2.erl @@ -2,7 +2,7 @@ -export([get/2]). --opaque data() :: gb_tree(). +-opaque data() :: gb_trees:tree(). -spec get(term(), data()) -> term(). -- cgit v1.2.3