aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib')
-rw-r--r--lib/stdlib/doc/src/array.xml16
-rw-r--r--lib/stdlib/doc/src/dict.xml10
-rw-r--r--lib/stdlib/doc/src/digraph.xml4
-rw-r--r--lib/stdlib/doc/src/ets.xml6
-rw-r--r--lib/stdlib/doc/src/gb_sets.xml90
-rw-r--r--lib/stdlib/doc/src/gb_trees.xml46
-rw-r--r--lib/stdlib/doc/src/queue.xml10
-rw-r--r--lib/stdlib/doc/src/sets.xml10
-rw-r--r--lib/stdlib/src/array.erl102
-rw-r--r--lib/stdlib/src/dict.erl124
-rw-r--r--lib/stdlib/src/digraph.erl98
-rw-r--r--lib/stdlib/src/digraph_utils.erl44
-rw-r--r--lib/stdlib/src/edlin_expand.erl14
-rw-r--r--lib/stdlib/src/epp.erl8
-rw-r--r--lib/stdlib/src/erl_eval.erl12
-rw-r--r--lib/stdlib/src/erl_expand_records.erl14
-rw-r--r--lib/stdlib/src/erl_lint.erl83
-rw-r--r--lib/stdlib/src/ets.erl4
-rw-r--r--lib/stdlib/src/gb_sets.erl167
-rw-r--r--lib/stdlib/src/gb_trees.erl139
-rw-r--r--lib/stdlib/src/otp_internal.erl18
-rw-r--r--lib/stdlib/src/queue.erl75
-rw-r--r--lib/stdlib/src/sets.erl114
-rw-r--r--lib/stdlib/src/sofs.erl10
-rw-r--r--lib/stdlib/src/stdlib.appup.src12
-rw-r--r--lib/stdlib/src/supervisor.erl52
-rw-r--r--lib/stdlib/src/supervisor_bridge.erl11
-rw-r--r--lib/stdlib/test/edlin_expand_SUITE.erl168
-rw-r--r--lib/stdlib/test/epp_SUITE.erl32
-rw-r--r--lib/stdlib/test/erl_eval_SUITE.erl18
-rw-r--r--lib/stdlib/test/erl_expand_records_SUITE.erl21
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl30
-rw-r--r--lib/stdlib/test/erl_lint_SUITE_data/predef.erl67
-rw-r--r--lib/stdlib/test/erl_lint_SUITE_data/predef2.erl56
-rw-r--r--lib/stdlib/test/ets_SUITE.erl18
-rw-r--r--lib/stdlib/test/stdlib_SUITE.erl73
36 files changed, 1029 insertions, 747 deletions
diff --git a/lib/stdlib/doc/src/array.xml b/lib/stdlib/doc/src/array.xml
index b0b3aa6dc1..b03a2fa0cc 100644
--- a/lib/stdlib/doc/src/array.xml
+++ b/lib/stdlib/doc/src/array.xml
@@ -3,7 +3,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2013</year>
+ <year>2007</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -84,7 +84,7 @@ the default value cannot be confused with the values of set entries.</p>
{'EXIT',{badarg,_}} = (catch array:get(18, A3)).</pre></description>
<datatypes>
<datatype>
- <name><marker id="type-array">array()</marker></name>
+ <name name="array" n_vars="1"/>
<desc>
<p>A functional, extendible array. The representation is
not documented and is subject to change without notice. Note that
@@ -92,6 +92,12 @@ the default value cannot be confused with the values of set entries.</p>
</desc>
</datatype>
<datatype>
+ <name name="array" n_vars="0"/>
+ <desc>
+ <p><c>array()</c> is equivalent to <c>array(term())</c>.</p>
+ </desc>
+ </datatype>
+ <datatype>
<name name="array_indx"/>
</datatype>
<datatype>
@@ -189,7 +195,7 @@ the default value cannot be confused with the values of set entries.</p>
<desc><marker id="from_orddict-2"/>
-<p>Convert an ordered list of pairs <c>{Index, Value}</c> to a
+<p>Convert an ordered list of pairs <c>{Index, <anno>Value</anno>}</c> to a
corresponding extendible array. <c><anno>Default</anno></c> is used as the value for
uninitialized entries of the array. If <c><anno>Orddict</anno></c> is not a proper,
ordered list of pairs whose first elements are nonnegative
@@ -455,7 +461,7 @@ cannot be changed once the array has been created.</p>
<desc><marker id="sparse_to_orddict-1"/>
-<p>Convert the array to an ordered list of pairs <c>{Index, Value}</c>,
+<p>Convert the array to an ordered list of pairs <c>{Index, <anno>Value</anno>}</c>,
skipping default-valued entries.
</p>
<p><em>See also:</em> <seealso marker="#to_orddict-1">to_orddict/1</seealso>.</p>
@@ -476,7 +482,7 @@ cannot be changed once the array has been created.</p>
<desc><marker id="to_orddict-1"/>
-<p>Convert the array to an ordered list of pairs <c>{Index, Value}</c>.
+<p>Convert the array to an ordered list of pairs <c>{Index, <anno>Value</anno>}</c>.
</p>
<p><em>See also:</em> <seealso marker="#from_orddict-2">from_orddict/2</seealso>, <seealso marker="#sparse_to_orddict-1">sparse_to_orddict/1</seealso>.</p>
</desc></func></funcs>
diff --git a/lib/stdlib/doc/src/dict.xml b/lib/stdlib/doc/src/dict.xml
index 6ff81b56ee..942fd1f45e 100644
--- a/lib/stdlib/doc/src/dict.xml
+++ b/lib/stdlib/doc/src/dict.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -41,9 +41,15 @@
<datatypes>
<datatype>
- <name><marker id="type-dict">dict()</marker></name>
+ <name name="dict" n_vars="2"/>
<desc><p>Dictionary as returned by <c>new/0</c>.</p></desc>
</datatype>
+ <datatype>
+ <name name="dict" n_vars="0"/>
+ <desc>
+ <p><c>dict()</c> is equivalent to <c>dict(term(), term())</c>.</p>
+ </desc>
+ </datatype>
</datatypes>
<funcs>
<func>
diff --git a/lib/stdlib/doc/src/digraph.xml b/lib/stdlib/doc/src/digraph.xml
index c5d5707f4f..9b9b48584b 100644
--- a/lib/stdlib/doc/src/digraph.xml
+++ b/lib/stdlib/doc/src/digraph.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -98,7 +98,7 @@
<name name="d_protection"/>
</datatype>
<datatype>
- <name><marker id="type-digraph">digraph()</marker></name>
+ <name name="graph"/>
<desc><p>A digraph as returned by <c>new/0,1</c>.</p></desc>
</datatype>
<datatype>
diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml
index 21cf8e4149..3df24bf688 100644
--- a/lib/stdlib/doc/src/ets.xml
+++ b/lib/stdlib/doc/src/ets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -171,6 +171,10 @@
<p>Returns a list of all tables at the node. Named tables are
given by their names, unnamed tables are given by their
table identifiers.</p>
+ <p>There is no guarantee of consistency in the returned list. Tables created
+ or deleted by other processes "during" the ets:all() call may or may
+ not be included in the list. Only tables created/deleted <em>before</em>
+ ets:all() is called are guaranteed to be included/excluded.</p>
</desc>
</func>
<func>
diff --git a/lib/stdlib/doc/src/gb_sets.xml b/lib/stdlib/doc/src/gb_sets.xml
index 8ca95df8fc..ea96c14472 100644
--- a/lib/stdlib/doc/src/gb_sets.xml
+++ b/lib/stdlib/doc/src/gb_sets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -115,28 +115,40 @@
<datatypes>
<datatype>
- <name><marker id="type-gb_set">gb_set()</marker></name>
+ <name name="set" n_vars="1"/>
<desc><p>A GB set.</p></desc>
</datatype>
<datatype>
- <name name="iter"/>
+ <name name="set" n_vars="0"/>
+ <desc>
+ <p><c>set()</c> is equivalent to <c>set(term())</c>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="iter" n_vars="1"/>
<desc><p>A GB set iterator.</p></desc>
</datatype>
+ <datatype>
+ <name name="iter" n_vars="0"/>
+ <desc>
+ <p><c>iter()</c> is equivalent to <c>iter(term())</c>.</p>
+ </desc>
+ </datatype>
</datatypes>
<funcs>
<func>
<name name="add" arity="2"/>
<name name="add_element" arity="2"/>
- <fsummary>Add a (possibly existing) element to a gb_set</fsummary>
+ <fsummary>Add a (possibly existing) element to a set</fsummary>
<desc>
- <p>Returns a new gb_set formed from <c><anno>Set1</anno></c> with
+ <p>Returns a new set formed from <c><anno>Set1</anno></c> with
<c><anno>Element</anno></c> inserted. If <c><anno>Element</anno></c> is already an
element in <c><anno>Set1</anno></c>, nothing is changed.</p>
</desc>
</func>
<func>
<name name="balance" arity="1"/>
- <fsummary>Rebalance tree representation of a gb_set</fsummary>
+ <fsummary>Rebalance tree representation of a set</fsummary>
<desc>
<p>Rebalances the tree representation of <c><anno>Set1</anno></c>. Note that
this is rarely necessary, but may be motivated when a large
@@ -148,9 +160,9 @@
</func>
<func>
<name name="delete" arity="2"/>
- <fsummary>Remove an element from a gb_set</fsummary>
+ <fsummary>Remove an element from a set</fsummary>
<desc>
- <p>Returns a new gb_set formed from <c><anno>Set1</anno></c> with
+ <p>Returns a new set formed from <c><anno>Set1</anno></c> with
<c><anno>Element</anno></c> removed. Assumes that <c><anno>Element</anno></c> is present
in <c><anno>Set1</anno></c>.</p>
</desc>
@@ -158,9 +170,9 @@
<func>
<name name="delete_any" arity="2"/>
<name name="del_element" arity="2"/>
- <fsummary>Remove a (possibly non-existing) element from a gb_set</fsummary>
+ <fsummary>Remove a (possibly non-existing) element from a set</fsummary>
<desc>
- <p>Returns a new gb_set formed from <c><anno>Set1</anno></c> with
+ <p>Returns a new set formed from <c><anno>Set1</anno></c> with
<c><anno>Element</anno></c> removed. If <c><anno>Element</anno></c> is not an element
in <c><anno>Set1</anno></c>, nothing is changed.</p>
</desc>
@@ -168,7 +180,7 @@
<func>
<name name="difference" arity="2"/>
<name name="subtract" arity="2"/>
- <fsummary>Return the difference of two gb_sets</fsummary>
+ <fsummary>Return the difference of two sets</fsummary>
<desc>
<p>Returns only the elements of <c><anno>Set1</anno></c> which are not also
elements of <c><anno>Set2</anno></c>.</p>
@@ -177,14 +189,14 @@
<func>
<name name="empty" arity="0"/>
<name name="new" arity="0"/>
- <fsummary>Return an empty gb_set</fsummary>
+ <fsummary>Return an empty set</fsummary>
<desc>
- <p>Returns a new empty gb_set.</p>
+ <p>Returns a new empty set.</p>
</desc>
</func>
<func>
<name name="filter" arity="2"/>
- <fsummary>Filter gb_set elements</fsummary>
+ <fsummary>Filter set elements</fsummary>
<desc>
<p>Filters elements in <c><anno>Set1</anno></c> using predicate function
<c><anno>Pred</anno></c>.</p>
@@ -192,7 +204,7 @@
</func>
<func>
<name name="fold" arity="3"/>
- <fsummary>Fold over gb_set elements</fsummary>
+ <fsummary>Fold over set elements</fsummary>
<desc>
<p>Folds <c><anno>Function</anno></c> over every element in <c><anno>Set</anno></c>
returning the final value of the accumulator.</p>
@@ -200,46 +212,46 @@
</func>
<func>
<name name="from_list" arity="1"/>
- <fsummary>Convert a list into a gb_set</fsummary>
+ <fsummary>Convert a list into a set</fsummary>
<desc>
- <p>Returns a gb_set of the elements in <c><anno>List</anno></c>, where
+ <p>Returns a set of the elements in <c><anno>List</anno></c>, where
<c><anno>List</anno></c> may be unordered and contain duplicates.</p>
</desc>
</func>
<func>
<name name="from_ordset" arity="1"/>
- <fsummary>Make a gb_set from an ordset list</fsummary>
+ <fsummary>Make a set from an ordset list</fsummary>
<desc>
- <p>Turns an ordered-set list <c><anno>List</anno></c> into a gb_set. The list
+ <p>Turns an ordered-set list <c><anno>List</anno></c> into a set. The list
must not contain duplicates.</p>
</desc>
</func>
<func>
<name name="insert" arity="2"/>
- <fsummary>Add a new element to a gb_set</fsummary>
+ <fsummary>Add a new element to a set</fsummary>
<desc>
- <p>Returns a new gb_set formed from <c><anno>Set1</anno></c> with
+ <p>Returns a new set formed from <c><anno>Set1</anno></c> with
<c><anno>Element</anno></c> inserted. Assumes that <c><anno>Element</anno></c> is not
present in <c><anno>Set1</anno></c>.</p>
</desc>
</func>
<func>
<name name="intersection" arity="2"/>
- <fsummary>Return the intersection of two gb_sets</fsummary>
+ <fsummary>Return the intersection of two sets</fsummary>
<desc>
<p>Returns the intersection of <c><anno>Set1</anno></c> and <c><anno>Set2</anno></c>.</p>
</desc>
</func>
<func>
<name name="intersection" arity="1"/>
- <fsummary>Return the intersection of a list of gb_sets</fsummary>
+ <fsummary>Return the intersection of a list of sets</fsummary>
<desc>
- <p>Returns the intersection of the non-empty list of gb_sets.</p>
+ <p>Returns the intersection of the non-empty list of sets.</p>
</desc>
</func>
<func>
<name name="is_disjoint" arity="2"/>
- <fsummary>Check whether two gb_sets are disjoint</fsummary>
+ <fsummary>Check whether two sets are disjoint</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Set1</anno></c> and
<c><anno>Set2</anno></c> are disjoint (have no elements in common),
@@ -248,7 +260,7 @@
</func>
<func>
<name name="is_empty" arity="1"/>
- <fsummary>Test for empty gb_set</fsummary>
+ <fsummary>Test for empty set</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Set</anno></c> is an empty set, and
<c>false</c> otherwise.</p>
@@ -257,7 +269,7 @@
<func>
<name name="is_member" arity="2"/>
<name name="is_element" arity="2"/>
- <fsummary>Test for membership of a gb_set</fsummary>
+ <fsummary>Test for membership of a set</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Element</anno></c> is an element of
<c><anno>Set</anno></c>, otherwise <c>false</c>.</p>
@@ -265,9 +277,9 @@
</func>
<func>
<name name="is_set" arity="1"/>
- <fsummary>Test for a gb_set</fsummary>
+ <fsummary>Test for a set</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> appears to be a gb_set,
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> appears to be a set,
otherwise <c>false</c>.</p>
</desc>
</func>
@@ -281,7 +293,7 @@
</func>
<func>
<name name="iterator" arity="1"/>
- <fsummary>Return an iterator for a gb_set</fsummary>
+ <fsummary>Return an iterator for a set</fsummary>
<desc>
<p>Returns an iterator that can be used for traversing the
entries of <c><anno>Set</anno></c>; see <c>next/1</c>. The implementation
@@ -303,7 +315,7 @@
</func>
<func>
<name name="next" arity="1"/>
- <fsummary>Traverse a gb_set with an iterator</fsummary>
+ <fsummary>Traverse a set with an iterator</fsummary>
<desc>
<p>Returns <c>{<anno>Element</anno>, <anno>Iter2</anno>}</c> where <c><anno>Element</anno></c> is the
smallest element referred to by the iterator <c><anno>Iter1</anno></c>,
@@ -314,14 +326,14 @@
</func>
<func>
<name name="singleton" arity="1"/>
- <fsummary>Return a gb_set with one element</fsummary>
+ <fsummary>Return a set with one element</fsummary>
<desc>
- <p>Returns a gb_set containing only the element <c><anno>Element</anno></c>.</p>
+ <p>Returns a set containing only the element <c><anno>Element</anno></c>.</p>
</desc>
</func>
<func>
<name name="size" arity="1"/>
- <fsummary>Return the number of elements in a gb_set</fsummary>
+ <fsummary>Return the number of elements in a set</fsummary>
<desc>
<p>Returns the number of elements in <c><anno>Set</anno></c>.</p>
</desc>
@@ -356,24 +368,24 @@
</func>
<func>
<name name="to_list" arity="1"/>
- <fsummary>Convert a gb_set into a list</fsummary>
+ <fsummary>Convert a set into a list</fsummary>
<desc>
<p>Returns the elements of <c><anno>Set</anno></c> as a list.</p>
</desc>
</func>
<func>
<name name="union" arity="2"/>
- <fsummary>Return the union of two gb_sets</fsummary>
+ <fsummary>Return the union of two sets</fsummary>
<desc>
- <p>Returns the merged (union) gb_set of <c><anno>Set1</anno></c> and
+ <p>Returns the merged (union) set of <c><anno>Set1</anno></c> and
<c><anno>Set2</anno></c>.</p>
</desc>
</func>
<func>
<name name="union" arity="1"/>
- <fsummary>Return the union of a list of gb_sets</fsummary>
+ <fsummary>Return the union of a list of sets</fsummary>
<desc>
- <p>Returns the merged (union) gb_set of the list of gb_sets.</p>
+ <p>Returns the merged (union) set of the list of sets.</p>
</desc>
</func>
</funcs>
diff --git a/lib/stdlib/doc/src/gb_trees.xml b/lib/stdlib/doc/src/gb_trees.xml
index 57e60eacb7..b2f237e1d7 100644
--- a/lib/stdlib/doc/src/gb_trees.xml
+++ b/lib/stdlib/doc/src/gb_trees.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -59,13 +59,25 @@
<datatypes>
<datatype>
- <name><marker id="type-gb_tree">gb_tree()</marker></name>
+ <name name="tree" n_vars="2"/>
<desc><p>A GB tree.</p></desc>
</datatype>
<datatype>
- <name name="iter"/>
+ <name name="tree" n_vars="0"/>
+ <desc>
+ <p><c>tree()</c> is equivalent to <c>tree(term(), term())</c>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="iter" n_vars="2"/>
<desc><p>A GB tree iterator.</p></desc>
</datatype>
+ <datatype>
+ <name name="iter" n_vars="0"/>
+ <desc>
+ <p><c>iter()</c> is equivalent to <c>iter(term(), term())</c>.</p>
+ </desc>
+ </datatype>
</datatypes>
<funcs>
<func>
@@ -108,9 +120,9 @@
<name name="enter" arity="3"/>
<fsummary>Insert or update key with value in a tree</fsummary>
<desc>
- <p>Inserts <c><anno>Key</anno></c> with value <c><anno>Val</anno></c> into <c><anno>Tree1</anno></c> if
+ <p>Inserts <c><anno>Key</anno></c> with value <c><anno>Value</anno></c> into <c><anno>Tree1</anno></c> if
the key is not present in the tree, otherwise updates
- <c><anno>Key</anno></c> to value <c><anno>Val</anno></c> in <c><anno>Tree1</anno></c>. Returns the
+ <c><anno>Key</anno></c> to value <c><anno>Value</anno></c> in <c><anno>Tree1</anno></c>. Returns the
new tree.</p>
</desc>
</func>
@@ -135,7 +147,7 @@
<name name="insert" arity="3"/>
<fsummary>Insert a new key and value in a tree</fsummary>
<desc>
- <p>Inserts <c><anno>Key</anno></c> with value <c><anno>Val</anno></c> into <c><anno>Tree1</anno></c>;
+ <p>Inserts <c><anno>Key</anno></c> with value <c><anno>Value</anno></c> into <c><anno>Tree1</anno></c>;
returns the new tree. Assumes that the key is not present in
the tree, crashes otherwise.</p>
</desc>
@@ -181,8 +193,8 @@
<name name="largest" arity="1"/>
<fsummary>Return largest key and value</fsummary>
<desc>
- <p>Returns <c>{<anno>Key</anno>, <anno>Val</anno>}</c>, where <c><anno>Key</anno></c> is the largest
- key in <c><anno>Tree</anno></c>, and <c><anno>Val</anno></c> is the value associated
+ <p>Returns <c>{<anno>Key</anno>, <anno>Value</anno>}</c>, where <c><anno>Key</anno></c> is the largest
+ key in <c><anno>Tree</anno></c>, and <c><anno>Value</anno></c> is the value associated
with this key. Assumes that the tree is nonempty.</p>
</desc>
</func>
@@ -191,7 +203,7 @@
<fsummary>Look up a key in a tree</fsummary>
<desc>
<p>Looks up <c><anno>Key</anno></c> in <c><anno>Tree</anno></c>; returns
- <c>{value, <anno>Val</anno>}</c>, or <c>none</c> if <c><anno>Key</anno></c> is not
+ <c>{value, <anno>Value</anno>}</c>, or <c>none</c> if <c><anno>Key</anno></c> is not
present.</p>
</desc>
</func>
@@ -207,7 +219,7 @@
<name name="next" arity="1"/>
<fsummary>Traverse a tree with an iterator</fsummary>
<desc>
- <p>Returns <c>{<anno>Key</anno>, <anno>Val</anno>, <anno>Iter2</anno>}</c> where <c><anno>Key</anno></c> is the
+ <p>Returns <c>{<anno>Key</anno>, <anno>Value</anno>, <anno>Iter2</anno>}</c> where <c><anno>Key</anno></c> is the
smallest key referred to by the iterator <c><anno>Iter1</anno></c>, and
<c><anno>Iter2</anno></c> is the new iterator to be used for
traversing the remaining nodes, or the atom <c>none</c> if no
@@ -225,8 +237,8 @@
<name name="smallest" arity="1"/>
<fsummary>Return smallest key and value</fsummary>
<desc>
- <p>Returns <c>{<anno>Key</anno>, <anno>Val</anno>}</c>, where <c><anno>Key</anno></c> is the smallest
- key in <c><anno>Tree</anno></c>, and <c><anno>Val</anno></c> is the value associated
+ <p>Returns <c>{<anno>Key</anno>, <anno>Value</anno>}</c>, where <c><anno>Key</anno></c> is the smallest
+ key in <c><anno>Tree</anno></c>, and <c><anno>Value</anno></c> is the value associated
with this key. Assumes that the tree is nonempty.</p>
</desc>
</func>
@@ -234,8 +246,8 @@
<name name="take_largest" arity="1"/>
<fsummary>Extract largest key and value</fsummary>
<desc>
- <p>Returns <c>{<anno>Key</anno>, <anno>Val</anno>, <anno>Tree2</anno>}</c>, where <c><anno>Key</anno></c> is the
- largest key in <c><anno>Tree1</anno></c>, <c><anno>Val</anno></c> is the value
+ <p>Returns <c>{<anno>Key</anno>, <anno>Value</anno>, <anno>Tree2</anno>}</c>, where <c><anno>Key</anno></c> is the
+ largest key in <c><anno>Tree1</anno></c>, <c><anno>Value</anno></c> is the value
associated with this key, and <c><anno>Tree2</anno></c> is this tree with
the corresponding node deleted. Assumes that the tree is
nonempty.</p>
@@ -245,8 +257,8 @@
<name name="take_smallest" arity="1"/>
<fsummary>Extract smallest key and value</fsummary>
<desc>
- <p>Returns <c>{<anno>Key</anno>, <anno>Val</anno>, <anno>Tree2</anno>}</c>, where <c><anno>Key</anno></c> is the
- smallest key in <c><anno>Tree1</anno></c>, <c><anno>Val</anno></c> is the value
+ <p>Returns <c>{<anno>Key</anno>, <anno>Value</anno>, <anno>Tree2</anno>}</c>, where <c><anno>Key</anno></c> is the
+ smallest key in <c><anno>Tree1</anno></c>, <c><anno>Value</anno></c> is the value
associated with this key, and <c><anno>Tree2</anno></c> is this tree with
the corresponding node deleted. Assumes that the tree is
nonempty.</p>
@@ -263,7 +275,7 @@
<name name="update" arity="3"/>
<fsummary>Update a key to new value in a tree</fsummary>
<desc>
- <p>Updates <c><anno>Key</anno></c> to value <c><anno>Val</anno></c> in <c><anno>Tree1</anno></c>;
+ <p>Updates <c><anno>Key</anno></c> to value <c><anno>Value</anno></c> in <c><anno>Tree1</anno></c>;
returns the new tree. Assumes that the key is present in the
tree.</p>
</desc>
diff --git a/lib/stdlib/doc/src/queue.xml b/lib/stdlib/doc/src/queue.xml
index bcf063bf0f..9c994154d4 100644
--- a/lib/stdlib/doc/src/queue.xml
+++ b/lib/stdlib/doc/src/queue.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -90,9 +90,15 @@
<datatypes>
<datatype>
- <name><marker id="type-queue">queue()</marker></name>
+ <name name="queue" n_vars="1"/>
<desc><p>As returned by <c>new/0</c>.</p></desc>
</datatype>
+ <datatype>
+ <name name="queue" n_vars="0"/>
+ <desc>
+ <p><c>queue()</c> is equivalent to <c>queue(term())</c>.</p>
+ </desc>
+ </datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/sets.xml b/lib/stdlib/doc/src/sets.xml
index 4b220bdd85..c5b8dce4b7 100644
--- a/lib/stdlib/doc/src/sets.xml
+++ b/lib/stdlib/doc/src/sets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -45,9 +45,15 @@
<datatypes>
<datatype>
- <name><marker id="type-dict">set()</marker></name>
+ <name name="set" n_vars="1"/>
<desc><p>As returned by <c>new/0</c>.</p></desc>
</datatype>
+ <datatype>
+ <name name="set" n_vars="0"/>
+ <desc>
+ <p><c>set()</c> is equivalent to <c>set(term())</c>.</p>
+ </desc>
+ </datatype>
</datatypes>
<funcs>
<func>
diff --git a/lib/stdlib/src/array.erl b/lib/stdlib/src/array.erl
index 2f69e2b0a4..10d2ccea45 100644
--- a/lib/stdlib/src/array.erl
+++ b/lib/stdlib/src/array.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -86,6 +86,8 @@
foldr/3, sparse_foldl/3, sparse_foldr/3, fix/1, relax/1, is_fix/1,
resize/1, resize/2]).
+-export_type([array/0, array/1]).
+
%%-define(TEST,1).
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
@@ -144,18 +146,28 @@
%%--------------------------------------------------------------------------
+-type element_tuple(T) ::
+ {T, T, T, T, T, T, T, T, T, T}
+ | {element_tuple(T), element_tuple(T), element_tuple(T),
+ element_tuple(T), element_tuple(T), element_tuple(T),
+ element_tuple(T), element_tuple(T), element_tuple(T),
+ element_tuple(T), non_neg_integer()}.
+
+-type elements(T) :: non_neg_integer()
+ | element_tuple(T)
+ | nil(). % kill reference, for GC
+
-record(array, {size :: non_neg_integer(), %% number of defined entries
max :: non_neg_integer(), %% maximum number of entries
%% in current tree
default, %% the default value (usually 'undefined')
- elements %% the tuple tree
+ elements :: elements(_) %% the tuple tree
}).
-%% A declaration equivalent to the following one is hard-coded in erl_types.
-%% That declaration contains hard-coded information about the #array{}
-%% structure and the types of its fields. So, please make sure that any
-%% changes to its structure are also propagated to erl_types.erl.
-%%
-%% -opaque array() :: #array{}.
+
+-opaque array() :: array(term()).
+
+-opaque array(Type) ::
+ #array{default :: Type, elements :: elements(Type)}.
%%
%% Types
@@ -164,13 +176,13 @@
-type array_indx() :: non_neg_integer().
-type array_opt() :: {'fixed', boolean()} | 'fixed'
- | {'default', Value :: term()}
+ | {'default', Type :: term()}
| {'size', N :: non_neg_integer()}
| (N :: non_neg_integer()).
-type array_opts() :: array_opt() | [array_opt()].
--type indx_pair() :: {Index :: array_indx(), Value :: term()}.
--type indx_pairs() :: [indx_pair()].
+-type indx_pair(Type) :: {Index :: array_indx(), Type}.
+-type indx_pairs(Type) :: [indx_pair(Type)].
%%--------------------------------------------------------------------------
@@ -321,7 +333,7 @@ size(_) -> erlang:error(badarg).
%%
%% @see new/2
--spec default(Array :: array()) -> term().
+-spec default(Array :: array(Type)) -> Value :: Type.
default(#array{default = D}) -> D;
default(_) -> erlang:error(badarg).
@@ -404,7 +416,7 @@ new_test_() ->
%% automatically upon insertion; see also {@link set/3}.
%% @see relax/1
--spec fix(Array :: array()) -> array().
+-spec fix(Array :: array(Type)) -> array(Type).
fix(#array{}=A) ->
A#array{max = 0}.
@@ -452,7 +464,7 @@ fix_test_() ->
%% fix/1}.)
%% @see fix/1
--spec relax(Array :: array()) -> array().
+-spec relax(Array :: array(Type)) -> array(Type).
relax(#array{size = N}=A) ->
A#array{max = find_max(N-1, ?LEAFSIZE)}.
@@ -477,7 +489,8 @@ relax_test_() ->
%% integer, the call fails with reason `badarg'. If the given array has
%% fixed size, the resulting array will also have fixed size.
--spec resize(Size :: non_neg_integer(), Array :: array()) -> array().
+-spec resize(Size :: non_neg_integer(), Array :: array(Type)) ->
+ array(Type).
resize(Size, #array{size = N, max = M, elements = E}=A)
when is_integer(Size), Size >= 0 ->
@@ -508,7 +521,7 @@ resize(_Size, _) ->
%% @see resize/2
%% @see sparse_size/1
--spec resize(Array :: array()) -> array().
+-spec resize(Array :: array(Type)) -> array(Type).
resize(Array) ->
resize(sparse_size(Array), Array).
@@ -558,7 +571,7 @@ resize_test_() ->
%% @see get/2
%% @see reset/2
--spec set(I :: array_indx(), Value :: term(), Array :: array()) -> array().
+-spec set(I :: array_indx(), Value :: Type, Array :: array(Type)) -> array(Type).
set(I, Value, #array{size = N, max = M, default = D, elements = E}=A)
when is_integer(I), I >= 0 ->
@@ -621,7 +634,7 @@ expand(I, _S, X, D) ->
%% @see set/3
--spec get(I :: array_indx(), Array :: array()) -> term().
+-spec get(I :: array_indx(), Array :: array(Type)) -> Value :: Type.
get(I, #array{size = N, max = M, elements = E, default = D})
when is_integer(I), I >= 0 ->
@@ -661,7 +674,7 @@ get_1(I, E, _D) ->
%% TODO: a reset_range function
--spec reset(I :: array_indx(), Array :: array()) -> array().
+-spec reset(I :: array_indx(), Array :: array(Type)) -> array(Type).
reset(I, #array{size = N, max = M, default = D, elements = E}=A)
when is_integer(I), I >= 0 ->
@@ -747,7 +760,7 @@ set_get_test_() ->
%% @see from_list/2
%% @see sparse_to_list/1
--spec to_list(Array :: array()) -> list().
+-spec to_list(Array :: array(Type)) -> list(Value :: Type).
to_list(#array{size = 0}) ->
[];
@@ -820,7 +833,7 @@ to_list_test_() ->
%%
%% @see to_list/1
--spec sparse_to_list(Array :: array()) -> list().
+-spec sparse_to_list(Array :: array(Type)) -> list(Value :: Type).
sparse_to_list(#array{size = 0}) ->
[];
@@ -887,7 +900,7 @@ sparse_to_list_test_() ->
%% @equiv from_list(List, undefined)
--spec from_list(List :: list()) -> array().
+-spec from_list(List :: list(Value :: Type)) -> array(Type).
from_list(List) ->
from_list(List, undefined).
@@ -899,7 +912,7 @@ from_list(List) ->
%% @see new/2
%% @see to_list/1
--spec from_list(List :: list(), Default :: term()) -> array().
+-spec from_list(List :: list(Value :: Type), Default :: term()) -> array(Type).
from_list([], Default) ->
new({default,Default});
@@ -998,7 +1011,7 @@ from_list_test_() ->
%% @see from_orddict/2
%% @see sparse_to_orddict/1
--spec to_orddict(Array :: array()) -> indx_pairs().
+-spec to_orddict(Array :: array(Type)) -> indx_pairs(Value :: Type).
to_orddict(#array{size = 0}) ->
[];
@@ -1035,16 +1048,16 @@ to_orddict_3(N, R, D, L, E, S) ->
to_orddict_2(element(N, E), R, D, L),
E, S).
--spec push_pairs(non_neg_integer(), array_indx(), term(), indx_pairs()) ->
- indx_pairs().
+-spec push_pairs(non_neg_integer(), array_indx(), term(), indx_pairs(Type)) ->
+ indx_pairs(Type).
push_pairs(0, _I, _E, L) ->
L;
push_pairs(N, I, E, L) ->
push_pairs(N-1, I-1, E, [{I, E} | L]).
--spec push_tuple_pairs(non_neg_integer(), array_indx(), term(), indx_pairs()) ->
- indx_pairs().
+-spec push_tuple_pairs(non_neg_integer(), array_indx(), term(), indx_pairs(Type)) ->
+ indx_pairs(Type).
push_tuple_pairs(0, _I, _T, L) ->
L;
@@ -1090,7 +1103,7 @@ to_orddict_test_() ->
%%
%% @see to_orddict/1
--spec sparse_to_orddict(Array :: array()) -> indx_pairs().
+-spec sparse_to_orddict(Array :: array(Type)) -> indx_pairs(Value :: Type).
sparse_to_orddict(#array{size = 0}) ->
[];
@@ -1128,7 +1141,7 @@ sparse_to_orddict_3(N, R, D, L, E, S) ->
E, S).
-spec sparse_push_tuple_pairs(non_neg_integer(), array_indx(),
- _, _, indx_pairs()) -> indx_pairs().
+ _, _, indx_pairs(Type)) -> indx_pairs(Type).
sparse_push_tuple_pairs(0, _I, _D, _T, L) ->
L;
@@ -1170,7 +1183,7 @@ sparse_to_orddict_test_() ->
%% @equiv from_orddict(Orddict, undefined)
--spec from_orddict(Orddict :: indx_pairs()) -> array().
+-spec from_orddict(Orddict :: indx_pairs(Value :: Type)) -> array(Type).
from_orddict(Orddict) ->
from_orddict(Orddict, undefined).
@@ -1184,7 +1197,8 @@ from_orddict(Orddict) ->
%% @see new/2
%% @see to_orddict/1
--spec from_orddict(Orddict :: indx_pairs(), Default :: term()) -> array().
+-spec from_orddict(Orddict :: indx_pairs(Value :: Type), Default :: Type) ->
+ array(Type).
from_orddict([], Default) ->
new({default,Default});
@@ -1379,8 +1393,8 @@ from_orddict_test_() ->
%% @see foldr/3
%% @see sparse_map/2
--spec map(Function, Array :: array()) -> array() when
- Function :: fun((Index :: array_indx(), Value :: _) -> _).
+-spec map(Function, Array :: array(Type1)) -> array(Type2) when
+ Function :: fun((Index :: array_indx(), Type1) -> Type2).
map(Function, Array=#array{size = N, elements = E, default = D})
when is_function(Function, 2) ->
@@ -1471,8 +1485,8 @@ map_test_() ->
%%
%% @see map/2
--spec sparse_map(Function, Array :: array()) -> array() when
- Function :: fun((Index :: array_indx(), Value :: _) -> _).
+-spec sparse_map(Function, Array :: array(Type1)) -> array(Type2) when
+ Function :: fun((Index :: array_indx(), Type1) -> Type2).
sparse_map(Function, Array=#array{size = N, elements = E, default = D})
when is_function(Function, 2) ->
@@ -1567,8 +1581,8 @@ sparse_map_test_() ->
%% @see map/2
%% @see sparse_foldl/3
--spec foldl(Function, InitialAcc :: A, Array :: array()) -> B when
- Function :: fun((Index :: array_indx(), Value :: _, Acc :: A) -> B).
+-spec foldl(Function, InitialAcc :: A, Array :: array(Type)) -> B when
+ Function :: fun((Index :: array_indx(), Value :: Type, Acc :: A) -> B).
foldl(Function, A, #array{size = N, elements = E, default = D})
when is_function(Function, 3) ->
@@ -1640,8 +1654,8 @@ foldl_test_() ->
%% @see foldl/3
%% @see sparse_foldr/3
--spec sparse_foldl(Function, InitialAcc :: A, Array :: array()) -> B when
- Function :: fun((Index :: array_indx(), Value :: _, Acc :: A) -> B).
+-spec sparse_foldl(Function, InitialAcc :: A, Array :: array(Type)) -> B when
+ Function :: fun((Index :: array_indx(), Value :: Type, Acc :: A) -> B).
sparse_foldl(Function, A, #array{size = N, elements = E, default = D})
when is_function(Function, 3) ->
@@ -1717,8 +1731,8 @@ sparse_foldl_test_() ->
%% @see foldl/3
%% @see map/2
--spec foldr(Function, InitialAcc :: A, Array :: array()) -> B when
- Function :: fun((Index :: array_indx(), Value :: _, Acc :: A) -> B).
+-spec foldr(Function, InitialAcc :: A, Array :: array(Type)) -> B when
+ Function :: fun((Index :: array_indx(), Value :: Type, Acc :: A) -> B).
foldr(Function, A, #array{size = N, elements = E, default = D})
when is_function(Function, 3) ->
@@ -1796,8 +1810,8 @@ foldr_test_() ->
%% @see foldr/3
%% @see sparse_foldl/3
--spec sparse_foldr(Function, InitialAcc :: A, Array :: array()) -> B when
- Function :: fun((Index :: array_indx(), Value :: _, Acc :: A) -> B).
+-spec sparse_foldr(Function, InitialAcc :: A, Array :: array(Type)) -> B when
+ Function :: fun((Index :: array_indx(), Value :: Type, Acc :: A) -> B).
sparse_foldr(Function, A, #array{size = N, elements = E, default = D})
when is_function(Function, 3) ->
diff --git a/lib/stdlib/src/dict.erl b/lib/stdlib/src/dict.erl
index 7e198a2469..6088e1a2dd 100644
--- a/lib/stdlib/src/dict.erl
+++ b/lib/stdlib/src/dict.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -41,6 +41,8 @@
-export([store/3,append/3,append_list/3,update/3,update/4,update_counter/3]).
-export([fold/3,map/2,filter/2,merge/3]).
+-export_type([dict/0, dict/2]).
+
%% Low-level interface.
%%-export([get_slot/2,get_bucket/2,on_bucket/3,fold_dict/3,
%% maybe_expand/2,maybe_contract/2]).
@@ -53,6 +55,9 @@
-define(exp_size, (?seg_size * ?expand_load)).
-define(con_size, (?seg_size * ?contract_load)).
+-type segs(K, V) :: tuple()
+ | {K, V}. % dummy
+
%% Define a hashtable. The default values are the standard ones.
-record(dict,
{size=0 :: non_neg_integer(), % Number of elements
@@ -62,14 +67,13 @@
exp_size=?exp_size :: non_neg_integer(), % Size to expand at
con_size=?con_size :: non_neg_integer(), % Size to contract at
empty :: tuple(), % Empty segment
- segs :: tuple() % Segments
+ segs :: segs(_, _) % Segments
}).
-%% A declaration equivalent to the following one is hard-coded in erl_types.
-%% That declaration contains hard-coded information about the #dict{}
-%% structure and the types of its fields. So, please make sure that any
-%% changes to its structure are also propagated to erl_types.erl.
-%%
-%% -opaque dict() :: #dict{}.
+
+
+-opaque dict() :: dict(_, _).
+
+-opaque dict(Key, Value) :: #dict{segs :: segs(Key, Value)}.
-define(kv(K,V), [K|V]). % Key-Value pair format
%%-define(kv(K,V), {K,V}). % Key-Value pair format
@@ -81,8 +85,7 @@ new() ->
#dict{empty=Empty,segs={Empty}}.
-spec is_key(Key, Dict) -> boolean() when
- Key :: term(),
- Dict :: dict().
+ Dict :: dict(Key, Value :: term()).
is_key(Key, D) ->
Slot = get_slot(D, Key),
@@ -94,15 +97,15 @@ find_key(K, [_|Bkt]) -> find_key(K, Bkt);
find_key(_, []) -> false.
-spec to_list(Dict) -> List when
- Dict :: dict(),
- List :: [{Key :: term(), Value :: term()}].
+ Dict :: dict(Key, Value),
+ List :: [{Key, Value}].
to_list(D) ->
fold(fun (Key, Val, List) -> [{Key,Val}|List] end, [], D).
-spec from_list(List) -> Dict when
- List :: [{Key :: term(), Value :: term()}],
- Dict :: dict().
+ Dict :: dict(Key, Value),
+ List :: [{Key, Value}].
from_list(L) ->
lists:foldl(fun ({K,V}, D) -> store(K, V, D) end, new(), L).
@@ -118,9 +121,7 @@ size(#dict{size=N}) when is_integer(N), N >= 0 -> N.
is_empty(#dict{size=N}) -> N =:= 0.
-spec fetch(Key, Dict) -> Value when
- Key :: term(),
- Dict :: dict(),
- Value :: term().
+ Dict :: dict(Key, Value).
fetch(Key, D) ->
Slot = get_slot(D, Key),
@@ -135,9 +136,7 @@ fetch_val(K, [_|Bkt]) -> fetch_val(K, Bkt);
fetch_val(_, []) -> throw(badarg).
-spec find(Key, Dict) -> {'ok', Value} | 'error' when
- Key :: term(),
- Dict :: dict(),
- Value :: term().
+ Dict :: dict(Key, Value).
find(Key, D) ->
Slot = get_slot(D, Key),
@@ -149,16 +148,16 @@ find_val(K, [_|Bkt]) -> find_val(K, Bkt);
find_val(_, []) -> error.
-spec fetch_keys(Dict) -> Keys when
- Dict :: dict(),
- Keys :: [term()].
+ Dict :: dict(Key, Value :: term()),
+ Keys :: [Key].
fetch_keys(D) ->
fold(fun (Key, _Val, Keys) -> [Key|Keys] end, [], D).
-spec erase(Key, Dict1) -> Dict2 when
- Key :: term(),
- Dict1 :: dict(),
- Dict2 :: dict().
+ Dict1 :: dict(Key, Value),
+ Dict2 :: dict(Key, Value).
+
%% Erase all elements with key Key.
erase(Key, D0) ->
@@ -174,10 +173,8 @@ erase_key(Key, [E|Bkt0]) ->
erase_key(_, []) -> {[],0}.
-spec store(Key, Value, Dict1) -> Dict2 when
- Key :: term(),
- Value :: term(),
- Dict1 :: dict(),
- Dict2 :: dict().
+ Dict1 :: dict(Key, Value),
+ Dict2 :: dict(Key, Value).
store(Key, Val, D0) ->
Slot = get_slot(D0, Key),
@@ -194,10 +191,8 @@ store_bkt_val(Key, New, [Other|Bkt0]) ->
store_bkt_val(Key, New, []) -> {[?kv(Key,New)],1}.
-spec append(Key, Value, Dict1) -> Dict2 when
- Key :: term(),
- Value :: term(),
- Dict1 :: dict(),
- Dict2 :: dict().
+ Dict1 :: dict(Key, Value),
+ Dict2 :: dict(Key, Value).
append(Key, Val, D0) ->
Slot = get_slot(D0, Key),
@@ -214,10 +209,9 @@ append_bkt(Key, Val, [Other|Bkt0]) ->
append_bkt(Key, Val, []) -> {[?kv(Key,[Val])],1}.
-spec append_list(Key, ValList, Dict1) -> Dict2 when
- Key :: term(),
- ValList :: [Value :: term()],
- Dict1 :: dict(),
- Dict2 :: dict().
+ Dict1 :: dict(Key, Value),
+ Dict2 :: dict(Key, Value),
+ ValList :: [Value].
append_list(Key, L, D0) ->
Slot = get_slot(D0, Key),
@@ -288,10 +282,9 @@ app_list_bkt(Key, L, []) -> {[?kv(Key,L)],1}.
%% {[Other|Bkt1],Dc}.
-spec update(Key, Fun, Dict1) -> Dict2 when
- Key :: term(),
- Fun :: fun((Value1 :: term()) -> Value2 :: term()),
- Dict1 :: dict(),
- Dict2 :: dict().
+ Dict1 :: dict(Key, Value),
+ Dict2 :: dict(Key, Value),
+ Fun :: fun((Value1 :: Value) -> Value2 :: Value).
update(Key, F, D0) ->
Slot = get_slot(D0, Key),
@@ -311,11 +304,10 @@ update_bkt(_Key, _F, []) ->
throw(badarg).
-spec update(Key, Fun, Initial, Dict1) -> Dict2 when
- Key :: term(),
- Initial :: term(),
- Fun :: fun((Value1 :: term()) -> Value2 :: term()),
- Dict1 :: dict(),
- Dict2 :: dict().
+ Dict1 :: dict(Key, Value),
+ Dict2 :: dict(Key, Value),
+ Fun :: fun((Value1 :: Value) -> Value2 :: Value),
+ Initial :: Value.
update(Key, F, Init, D0) ->
Slot = get_slot(D0, Key),
@@ -331,10 +323,9 @@ update_bkt(Key, F, I, [Other|Bkt0]) ->
update_bkt(Key, F, I, []) when is_function(F, 1) -> {[?kv(Key,I)],1}.
-spec update_counter(Key, Increment, Dict1) -> Dict2 when
- Key :: term(),
- Increment :: number(),
- Dict1 :: dict(),
- Dict2 :: dict().
+ Dict1 :: dict(Key, Value),
+ Dict2 :: dict(Key, Value),
+ Increment :: number().
update_counter(Key, Incr, D0) when is_number(Incr) ->
Slot = get_slot(D0, Key),
@@ -351,36 +342,35 @@ counter_bkt(Key, I, []) -> {[?kv(Key,I)],1}.
-spec fold(Fun, Acc0, Dict) -> Acc1 when
Fun :: fun((Key, Value, AccIn) -> AccOut),
- Key :: term(),
- Value :: term(),
- Acc0 :: term(),
- Acc1 :: term(),
- AccIn :: term(),
- AccOut :: term(),
- Dict :: dict().
+ Dict :: dict(Key, Value),
+ Acc0 :: Acc,
+ Acc1 :: Acc,
+ AccIn :: Acc,
+ AccOut :: Acc.
+
%% Fold function Fun over all "bags" in Table and return Accumulator.
fold(F, Acc, D) -> fold_dict(F, Acc, D).
-spec map(Fun, Dict1) -> Dict2 when
- Fun :: fun((Key :: term(), Value1 :: term()) -> Value2 :: term()),
- Dict1 :: dict(),
- Dict2 :: dict().
+ Fun :: fun((Key, Value1) -> Value2),
+ Dict1 :: dict(Key, Value1),
+ Dict2 :: dict(Key, Value2).
map(F, D) -> map_dict(F, D).
-spec filter(Pred, Dict1) -> Dict2 when
- Pred :: fun((Key :: term(), Value :: term()) -> boolean()),
- Dict1 :: dict(),
- Dict2 :: dict().
+ Pred :: fun((Key , Value) -> boolean()),
+ Dict1 :: dict(Key, Value),
+ Dict2 :: dict(Key, Value).
filter(F, D) -> filter_dict(F, D).
-spec merge(Fun, Dict1, Dict2) -> Dict3 when
- Fun :: fun((Key :: term(), Value1 :: term(), Value2 :: term()) -> Value :: term()),
- Dict1 :: dict(),
- Dict2 :: dict(),
- Dict3 :: dict().
+ Fun :: fun((Key, Value1, Value2) -> Value),
+ Dict1 :: dict(Key, Value1),
+ Dict2 :: dict(Key, Value2),
+ Dict3 :: dict(Key, Value).
merge(F, D1, D2) when D1#dict.size < D2#dict.size ->
fold_dict(fun (K, V1, D) ->
diff --git a/lib/stdlib/src/digraph.erl b/lib/stdlib/src/digraph.erl
index 78f74631dc..0c21271529 100644
--- a/lib/stdlib/src/digraph.erl
+++ b/lib/stdlib/src/digraph.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -36,18 +36,14 @@
-export([get_short_path/3, get_short_cycle/2]).
--export_type([digraph/0, d_type/0, vertex/0, edge/0]).
+-export_type([graph/0, d_type/0, vertex/0, edge/0]).
-record(digraph, {vtab = notable :: ets:tab(),
etab = notable :: ets:tab(),
ntab = notable :: ets:tab(),
cyclic = true :: boolean()}).
-%% A declaration equivalent to the following one is hard-coded in erl_types.
-%% That declaration contains hard-coded information about the #digraph{}
-%% record and the types of its fields. So, please make sure that any
-%% changes to its structure are also propagated to erl_types.erl.
-%%
-%% -opaque digraph() :: #digraph{}.
+
+-opaque graph() :: #digraph{}.
-type edge() :: term().
-type label() :: term().
@@ -67,11 +63,11 @@
-type d_cyclicity() :: 'acyclic' | 'cyclic'.
-type d_type() :: d_cyclicity() | d_protection().
--spec new() -> digraph().
+-spec new() -> graph().
new() -> new([]).
--spec new(Type) -> digraph() when
+-spec new(Type) -> graph() when
Type :: [d_type()].
new(Type) ->
@@ -106,7 +102,7 @@ check_type(_, _, _) -> error.
%%
%% Set graph type
%%
--spec set_type([{'cyclic', boolean()}], digraph()) -> digraph().
+-spec set_type([{'cyclic', boolean()}], graph()) -> graph().
set_type([{cyclic,V} | Ks], G) ->
set_type(Ks, G#digraph{cyclic = V});
@@ -116,7 +112,7 @@ set_type([], G) -> G.
%% Data access functions
-spec delete(G) -> 'true' when
- G :: digraph().
+ G :: graph().
delete(G) ->
ets:delete(G#digraph.vtab),
@@ -124,7 +120,7 @@ delete(G) ->
ets:delete(G#digraph.ntab).
-spec info(G) -> InfoList when
- G :: digraph(),
+ G :: graph(),
InfoList :: [{'cyclicity', Cyclicity :: d_cyclicity()} |
{'memory', NoWords :: non_neg_integer()} |
{'protection', Protection :: d_protection()}].
@@ -142,20 +138,20 @@ info(G) ->
[{cyclicity, Cyclicity}, {memory, Memory}, {protection, Protection}].
-spec add_vertex(G) -> vertex() when
- G :: digraph().
+ G :: graph().
add_vertex(G) ->
do_add_vertex({new_vertex_id(G), []}, G).
-spec add_vertex(G, V) -> vertex() when
- G :: digraph(),
+ G :: graph(),
V :: vertex().
add_vertex(G, V) ->
do_add_vertex({V, []}, G).
-spec add_vertex(G, V, Label) -> vertex() when
- G :: digraph(),
+ G :: graph(),
V :: vertex(),
Label :: label().
@@ -163,21 +159,21 @@ add_vertex(G, V, D) ->
do_add_vertex({V, D}, G).
-spec del_vertex(G, V) -> 'true' when
- G :: digraph(),
+ G :: graph(),
V :: vertex().
del_vertex(G, V) ->
do_del_vertex(V, G).
-spec del_vertices(G, Vertices) -> 'true' when
- G :: digraph(),
+ G :: graph(),
Vertices :: [vertex()].
del_vertices(G, Vs) ->
do_del_vertices(Vs, G).
-spec vertex(G, V) -> {V, Label} | 'false' when
- G :: digraph(),
+ G :: graph(),
V :: vertex(),
Label :: label().
@@ -188,37 +184,37 @@ vertex(G, V) ->
end.
-spec no_vertices(G) -> non_neg_integer() when
- G :: digraph().
+ G :: graph().
no_vertices(G) ->
ets:info(G#digraph.vtab, size).
-spec vertices(G) -> Vertices when
- G :: digraph(),
+ G :: graph(),
Vertices :: [vertex()].
vertices(G) ->
ets:select(G#digraph.vtab, [{{'$1', '_'}, [], ['$1']}]).
--spec source_vertices(digraph()) -> [vertex()].
+-spec source_vertices(graph()) -> [vertex()].
source_vertices(G) ->
collect_vertices(G, in).
--spec sink_vertices(digraph()) -> [vertex()].
+-spec sink_vertices(graph()) -> [vertex()].
sink_vertices(G) ->
collect_vertices(G, out).
-spec in_degree(G, V) -> non_neg_integer() when
- G :: digraph(),
+ G :: graph(),
V :: vertex().
in_degree(G, V) ->
length(ets:lookup(G#digraph.ntab, {in, V})).
-spec in_neighbours(G, V) -> Vertex when
- G :: digraph(),
+ G :: graph(),
V :: vertex(),
Vertex :: [vertex()].
@@ -228,7 +224,7 @@ in_neighbours(G, V) ->
collect_elems(ets:lookup(NT, {in, V}), ET, 2).
-spec in_edges(G, V) -> Edges when
- G :: digraph(),
+ G :: graph(),
V :: vertex(),
Edges :: [edge()].
@@ -236,14 +232,14 @@ in_edges(G, V) ->
ets:select(G#digraph.ntab, [{{{in, V}, '$1'}, [], ['$1']}]).
-spec out_degree(G, V) -> non_neg_integer() when
- G :: digraph(),
+ G :: graph(),
V :: vertex().
out_degree(G, V) ->
length(ets:lookup(G#digraph.ntab, {out, V})).
-spec out_neighbours(G, V) -> Vertices when
- G :: digraph(),
+ G :: graph(),
V :: vertex(),
Vertices :: [vertex()].
@@ -253,7 +249,7 @@ out_neighbours(G, V) ->
collect_elems(ets:lookup(NT, {out, V}), ET, 3).
-spec out_edges(G, V) -> Edges when
- G :: digraph(),
+ G :: graph(),
V :: vertex(),
Edges :: [edge()].
@@ -261,7 +257,7 @@ out_edges(G, V) ->
ets:select(G#digraph.ntab, [{{{out, V}, '$1'}, [], ['$1']}]).
-spec add_edge(G, V1, V2) -> edge() | {'error', add_edge_err_rsn()} when
- G :: digraph(),
+ G :: graph(),
V1 :: vertex(),
V2 :: vertex().
@@ -269,7 +265,7 @@ add_edge(G, V1, V2) ->
do_add_edge({new_edge_id(G), V1, V2, []}, G).
-spec add_edge(G, V1, V2, Label) -> edge() | {'error', add_edge_err_rsn()} when
- G :: digraph(),
+ G :: graph(),
V1 :: vertex(),
V2 :: vertex(),
Label :: label().
@@ -278,7 +274,7 @@ add_edge(G, V1, V2, D) ->
do_add_edge({new_edge_id(G), V1, V2, D}, G).
-spec add_edge(G, E, V1, V2, Label) -> edge() | {'error', add_edge_err_rsn()} when
- G :: digraph(),
+ G :: graph(),
E :: edge(),
V1 :: vertex(),
V2 :: vertex(),
@@ -288,34 +284,34 @@ add_edge(G, E, V1, V2, D) ->
do_add_edge({E, V1, V2, D}, G).
-spec del_edge(G, E) -> 'true' when
- G :: digraph(),
+ G :: graph(),
E :: edge().
del_edge(G, E) ->
do_del_edges([E], G).
-spec del_edges(G, Edges) -> 'true' when
- G :: digraph(),
+ G :: graph(),
Edges :: [edge()].
del_edges(G, Es) ->
do_del_edges(Es, G).
-spec no_edges(G) -> non_neg_integer() when
- G :: digraph().
+ G :: graph().
no_edges(G) ->
ets:info(G#digraph.etab, size).
-spec edges(G) -> Edges when
- G :: digraph(),
+ G :: graph(),
Edges :: [edge()].
edges(G) ->
ets:select(G#digraph.etab, [{{'$1', '_', '_', '_'}, [], ['$1']}]).
-spec edges(G, V) -> Edges when
- G :: digraph(),
+ G :: graph(),
V :: vertex(),
Edges :: [edge()].
@@ -324,7 +320,7 @@ edges(G, V) ->
{{{in, V}, '$1'}, [], ['$1']}]).
-spec edge(G, E) -> {E, V1, V2, Label} | 'false' when
- G :: digraph(),
+ G :: graph(),
E :: edge(),
V1 :: vertex(),
V2 :: vertex(),
@@ -339,7 +335,7 @@ edge(G, E) ->
%%
%% Generate a "unique" edge identifier (relative to this graph)
%%
--spec new_edge_id(digraph()) -> edge().
+-spec new_edge_id(graph()) -> edge().
new_edge_id(G) ->
NT = G#digraph.ntab,
@@ -351,7 +347,7 @@ new_edge_id(G) ->
%%
%% Generate a "unique" vertex identifier (relative to this graph)
%%
--spec new_vertex_id(digraph()) -> vertex().
+-spec new_vertex_id(graph()) -> vertex().
new_vertex_id(G) ->
NT = G#digraph.ntab,
@@ -371,7 +367,7 @@ collect_elems([{_,Key}|Keys], Table, Index, Acc) ->
[ets:lookup_element(Table, Key, Index)|Acc]);
collect_elems([], _, _, Acc) -> Acc.
--spec do_add_vertex({vertex(), label()}, digraph()) -> vertex().
+-spec do_add_vertex({vertex(), label()}, graph()) -> vertex().
do_add_vertex({V, _Label} = VL, G) ->
ets:insert(G#digraph.vtab, VL),
@@ -430,14 +426,14 @@ do_del_edge(E, V1, V2, G) ->
{{{out,V1}, E}, [], [true]}]),
ets:delete(G#digraph.etab, E).
--spec rm_edges([vertex(),...], digraph()) -> 'true'.
+-spec rm_edges([vertex(),...], graph()) -> 'true'.
rm_edges([V1, V2|Vs], G) ->
rm_edge(V1, V2, G),
rm_edges([V2|Vs], G);
rm_edges(_, _) -> true.
--spec rm_edge(vertex(), vertex(), digraph()) -> 'ok'.
+-spec rm_edge(vertex(), vertex(), graph()) -> 'ok'.
rm_edge(V1, V2, G) ->
Es = out_edges(G, V1),
@@ -456,7 +452,7 @@ rm_edge_0([], _, _, #digraph{}) -> ok.
%%
%% Check that endpoints exist
%%
--spec do_add_edge({edge(), vertex(), vertex(), label()}, digraph()) ->
+-spec do_add_edge({edge(), vertex(), vertex(), label()}, graph()) ->
edge() | {'error', add_edge_err_rsn()}.
do_add_edge({E, V1, V2, Label}, G) ->
@@ -484,14 +480,14 @@ other_edge_exists(#digraph{etab = ET}, E, V1, V2) ->
false
end.
--spec do_insert_edge(edge(), vertex(), vertex(), label(), digraph()) -> edge().
+-spec do_insert_edge(edge(), vertex(), vertex(), label(), graph()) -> edge().
do_insert_edge(E, V1, V2, Label, #digraph{ntab=NT, etab=ET}) ->
ets:insert(NT, [{{out, V1}, E}, {{in, V2}, E}]),
ets:insert(ET, {E, V1, V2, Label}),
E.
--spec acyclic_add_edge(edge(), vertex(), vertex(), label(), digraph()) ->
+-spec acyclic_add_edge(edge(), vertex(), vertex(), label(), graph()) ->
edge() | {'error', {'bad_edge', [vertex()]}}.
acyclic_add_edge(_E, V1, V2, _L, _G) when V1 =:= V2 ->
@@ -507,7 +503,7 @@ acyclic_add_edge(E, V1, V2, Label, G) ->
%%
-spec del_path(G, V1, V2) -> 'true' when
- G :: digraph(),
+ G :: graph(),
V1 :: vertex(),
V2 :: vertex().
@@ -529,7 +525,7 @@ del_path(G, V1, V2) ->
%%
-spec get_cycle(G, V) -> Vertices | 'false' when
- G :: digraph(),
+ G :: graph(),
V :: vertex(),
Vertices :: [vertex(),...].
@@ -550,7 +546,7 @@ get_cycle(G, V) ->
%%
-spec get_path(G, V1, V2) -> Vertices | 'false' when
- G :: digraph(),
+ G :: graph(),
V1 :: vertex(),
V2 :: vertex(),
Vertices :: [vertex(),...].
@@ -589,7 +585,7 @@ one_path([], _, [], _, _, _, _, _Counter) -> false.
%%
-spec get_short_cycle(G, V) -> Vertices | 'false' when
- G :: digraph(),
+ G :: graph(),
V :: vertex(),
Vertices :: [vertex(),...].
@@ -602,7 +598,7 @@ get_short_cycle(G, V) ->
%%
-spec get_short_path(G, V1, V2) -> Vertices | 'false' when
- G :: digraph(),
+ G :: graph(),
V1 :: vertex(),
V2 :: vertex(),
Vertices :: [vertex(),...].
diff --git a/lib/stdlib/src/digraph_utils.erl b/lib/stdlib/src/digraph_utils.erl
index 0e248df453..011bcd0260 100644
--- a/lib/stdlib/src/digraph_utils.erl
+++ b/lib/stdlib/src/digraph_utils.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -43,28 +43,28 @@
%%
-spec components(Digraph) -> [Component] when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Component :: [digraph:vertex()].
components(G) ->
forest(G, fun inout/3).
-spec strong_components(Digraph) -> [StrongComponent] when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
StrongComponent :: [digraph:vertex()].
strong_components(G) ->
forest(G, fun in/3, revpostorder(G)).
-spec cyclic_strong_components(Digraph) -> [StrongComponent] when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
StrongComponent :: [digraph:vertex()].
cyclic_strong_components(G) ->
remove_singletons(strong_components(G), G, []).
-spec reachable(Vertices, Digraph) -> Reachable when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Vertices :: [digraph:vertex()],
Reachable :: [digraph:vertex()].
@@ -72,7 +72,7 @@ reachable(Vs, G) when is_list(Vs) ->
lists:append(forest(G, fun out/3, Vs, first)).
-spec reachable_neighbours(Vertices, Digraph) -> Reachable when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Vertices :: [digraph:vertex()],
Reachable :: [digraph:vertex()].
@@ -80,7 +80,7 @@ reachable_neighbours(Vs, G) when is_list(Vs) ->
lists:append(forest(G, fun out/3, Vs, not_first)).
-spec reaching(Vertices, Digraph) -> Reaching when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Vertices :: [digraph:vertex()],
Reaching :: [digraph:vertex()].
@@ -88,7 +88,7 @@ reaching(Vs, G) when is_list(Vs) ->
lists:append(forest(G, fun in/3, Vs, first)).
-spec reaching_neighbours(Vertices, Digraph) -> Reaching when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Vertices :: [digraph:vertex()],
Reaching :: [digraph:vertex()].
@@ -96,7 +96,7 @@ reaching_neighbours(Vs, G) when is_list(Vs) ->
lists:append(forest(G, fun in/3, Vs, not_first)).
-spec topsort(Digraph) -> Vertices | 'false' when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Vertices :: [digraph:vertex()].
topsort(G) ->
@@ -107,13 +107,13 @@ topsort(G) ->
end.
-spec is_acyclic(Digraph) -> boolean() when
- Digraph :: digraph().
+ Digraph :: digraph:graph().
is_acyclic(G) ->
loop_vertices(G) =:= [] andalso topsort(G) =/= false.
-spec arborescence_root(Digraph) -> 'no' | {'yes', Root} when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Root :: digraph:vertex().
arborescence_root(G) ->
@@ -136,29 +136,29 @@ arborescence_root(G) ->
end.
-spec is_arborescence(Digraph) -> boolean() when
- Digraph :: digraph().
+ Digraph :: digraph:graph().
is_arborescence(G) ->
arborescence_root(G) =/= no.
-spec is_tree(Digraph) -> boolean() when
- Digraph :: digraph().
+ Digraph :: digraph:graph().
is_tree(G) ->
(digraph:no_edges(G) =:= digraph:no_vertices(G) - 1)
andalso (length(components(G)) =:= 1).
-spec loop_vertices(Digraph) -> Vertices when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Vertices :: [digraph:vertex()].
loop_vertices(G) ->
[V || V <- digraph:vertices(G), is_reflexive_vertex(V, G)].
-spec subgraph(Digraph, Vertices) -> SubGraph when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Vertices :: [digraph:vertex()],
- SubGraph :: digraph().
+ SubGraph :: digraph:graph().
subgraph(G, Vs) ->
try
@@ -169,8 +169,8 @@ subgraph(G, Vs) ->
end.
-spec subgraph(Digraph, Vertices, Options) -> SubGraph when
- Digraph :: digraph(),
- SubGraph :: digraph(),
+ Digraph :: digraph:graph(),
+ SubGraph :: digraph:graph(),
Vertices :: [digraph:vertex()],
Options :: [{'type', SubgraphType} | {'keep_labels', boolean()}],
SubgraphType :: 'inherit' | [digraph:d_type()].
@@ -184,8 +184,8 @@ subgraph(G, Vs, Opts) ->
end.
-spec condensation(Digraph) -> CondensedDigraph when
- Digraph :: digraph(),
- CondensedDigraph :: digraph().
+ Digraph :: digraph:graph(),
+ CondensedDigraph :: digraph:graph().
condensation(G) ->
SCs = strong_components(G),
@@ -209,14 +209,14 @@ condensation(G) ->
SCG.
-spec preorder(Digraph) -> Vertices when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Vertices :: [digraph:vertex()].
preorder(G) ->
lists:reverse(revpreorder(G)).
-spec postorder(Digraph) -> Vertices when
- Digraph :: digraph(),
+ Digraph :: digraph:graph(),
Vertices :: [digraph:vertex()].
postorder(G) ->
diff --git a/lib/stdlib/src/edlin_expand.erl b/lib/stdlib/src/edlin_expand.erl
index 0033010dce..a2b4663219 100644
--- a/lib/stdlib/src/edlin_expand.erl
+++ b/lib/stdlib/src/edlin_expand.erl
@@ -73,7 +73,7 @@ to_atom(Str) ->
error
end.
-match(Prefix, Alts, Extra) ->
+match(Prefix, Alts, Extra0) ->
Len = length(Prefix),
Matches = lists:sort(
[{S, A} || {H, A} <- Alts,
@@ -89,13 +89,11 @@ match(Prefix, Alts, Extra) ->
{yes, Remain, []}
end;
{complete, Str} ->
- {_, Arity} = lists:keyfind(Str, 1, Matches),
- case {Arity, Extra} of
- {0, "("} ->
- {yes, nthtail(Len, Str) ++ "()", []};
- _ ->
- {yes, nthtail(Len, Str) ++ Extra, []}
- end;
+ Extra = case {Extra0,Matches} of
+ {"(",[{Str,0}]} -> "()";
+ {_,_} -> Extra0
+ end,
+ {yes, nthtail(Len, Str) ++ Extra, []};
no ->
{no, [], []}
end.
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index 4fd302e612..68e079b7e5 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -46,8 +46,8 @@
istk=[], %Ifdef stack
sstk=[], %State stack
path=[], %Include-path
- macs = dict:new() :: dict(), %Macros (don't care locations)
- uses = dict:new() :: dict(), %Macro use structure
+ macs = dict:new() :: dict:dict(),%Macros (don't care locations)
+ uses = dict:new() :: dict:dict(),%Macro use structure
pre_opened = false :: boolean()
}).
@@ -640,7 +640,7 @@ leave_file(From, St) ->
Ms = dict:store({atom,'FILE'},
{none,[{string,CurrLoc,OldName2}]},
St#epp.macs),
- NextSt = OldSt#epp{sstk=Sts,macs=Ms},
+ NextSt = OldSt#epp{sstk=Sts,macs=Ms,uses=St#epp.uses},
enter_file_reply(From, OldName, CurrLoc, CurrLoc),
case OldName2 =:= OldName of
true ->
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index 63e7be4b74..3a4108e297 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -1006,12 +1006,16 @@ guard0([], _Bs, _Lf, _Ef) -> true.
guard_test({call,L,{atom,Ln,F},As0}, Bs0, Lf, Ef) ->
TT = type_test(F),
G = {call,L,{atom,Ln,TT},As0},
- try {value,true,_} = expr(G, Bs0, Lf, Ef, none)
- catch error:_ -> {value,false,Bs0} end;
-guard_test({call,L,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,_F}=T},As0},
+ expr_guard_test(G, Bs0, Lf, Ef);
+guard_test({call,L,{remote,Lr,{atom,Lm,erlang},{atom,Lf,F}},As0},
Bs0, Lf, Ef) ->
- guard_test({call,L,T,As0}, Bs0, Lf, Ef);
+ TT = type_test(F),
+ G = {call,L,{remote,Lr,{atom,Lm,erlang},{atom,Lf,TT}},As0},
+ expr_guard_test(G, Bs0, Lf, Ef);
guard_test(G, Bs0, Lf, Ef) ->
+ expr_guard_test(G, Bs0, Lf, Ef).
+
+expr_guard_test(G, Bs0, Lf, Ef) ->
try {value,true,_} = expr(G, Bs0, Lf, Ef, none)
catch error:_ -> {value,false,Bs0} end.
diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl
index 4741bef6b9..f53c6e1278 100644
--- a/lib/stdlib/src/erl_expand_records.erl
+++ b/lib/stdlib/src/erl_expand_records.erl
@@ -135,9 +135,10 @@ pattern({tuple,Line,Ps}, St0) ->
pattern({map,Line,Ps}, St0) ->
{TPs,St1} = pattern_list(Ps, St0),
{{map,Line,TPs},St1};
-pattern({map_field_exact,Line,Key,V0}, St0) ->
- {V,St1} = pattern(V0, St0),
- {{map_field_exact,Line,Key,V},St1};
+pattern({map_field_exact,Line,Key0,V0}, St0) ->
+ {Key,St1} = pattern(Key0, St0),
+ {V,St2} = pattern(V0, St1),
+ {{map_field_exact,Line,Key,V},St2};
%%pattern({struct,Line,Tag,Ps}, St0) ->
%% {TPs,TPsvs,St1} = pattern_list(Ps, St0),
%% {{struct,Line,Tag,TPs},TPsvs,St1};
@@ -310,9 +311,10 @@ expr({tuple,Line,Es0}, St0) ->
expr({map,Line,Es0}, St0) ->
{Es1,St1} = expr_list(Es0, St0),
{{map,Line,Es1},St1};
-expr({map,Line,Var,Es0}, St0) ->
- {Es1,St1} = expr_list(Es0, St0),
- {{map,Line,Var,Es1},St1};
+expr({map,Line,Arg0,Es0}, St0) ->
+ {Arg1,St1} = expr(Arg0, St0),
+ {Es1,St2} = expr_list(Es0, St1),
+ {{map,Line,Arg1,Es1},St2};
expr({map_field_assoc,Line,K0,V0}, St0) ->
{K,St1} = expr(K0, St0),
{V,St2} = expr(V0, St1),
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 0c6f41f594..9f5be2da37 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -85,8 +85,8 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
-record(usage, {
calls = dict:new(), %Who calls who
imported = [], %Actually imported functions
- used_records=sets:new() :: set(), %Used record definitions
- used_types = dict:new() :: dict() %Used type definitions
+ used_records=sets:new() :: sets:set(),%Used record definitions
+ used_types = dict:new() :: dict:dict()%Used type definitions
}).
%% Define the lint state record.
@@ -95,13 +95,13 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
-record(lint, {state=start :: 'start' | 'attribute' | 'function',
module=[], %Module
behaviour=[], %Behaviour
- exports=gb_sets:empty() :: gb_set(), %Exports
+ exports=gb_sets:empty() :: gb_sets:set(),%Exports
imports=[], %Imports
compile=[], %Compile flags
- records=dict:new() :: dict(), %Record definitions
- locals=gb_sets:empty() :: gb_set(), %All defined functions (prescanned)
- no_auto=gb_sets:empty() :: gb_set() | 'all', %Functions explicitly not autoimported
- defined=gb_sets:empty() :: gb_set(), %Defined fuctions
+ records=dict:new() :: dict:dict(), %Record definitions
+ locals=gb_sets:empty() :: gb_sets:set(),%All defined functions (prescanned)
+ no_auto=gb_sets:empty() :: gb_sets:set() | 'all',%Functions explicitly not autoimported
+ defined=gb_sets:empty() :: gb_sets:set(),%Defined fuctions
on_load=[] :: [fa()], %On-load function
on_load_line=0 :: line(), %Line for on_load
clashes=[], %Exported functions named as BIFs
@@ -118,10 +118,10 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
new = false :: boolean(), %Has user-defined 'new/N'
called= [] :: [{fa(),line()}], %Called functions
usage = #usage{} :: #usage{},
- specs = dict:new() :: dict(), %Type specifications
- callbacks = dict:new() :: dict(), %Callback types
- types = dict:new() :: dict(), %Type definitions
- exp_types=gb_sets:empty():: gb_set() %Exported types
+ specs = dict:new() :: dict:dict(), %Type specifications
+ callbacks = dict:new() :: dict:dict(), %Callback types
+ types = dict:new() :: dict:dict(), %Type definitions
+ exp_types=gb_sets:empty():: gb_sets:set()%Exported types
}).
-type lint_state() :: #lint{}.
@@ -344,9 +344,10 @@ format_error(spec_wrong_arity) ->
"spec has the wrong arity";
format_error(callback_wrong_arity) ->
"callback has the wrong arity";
-format_error({imported_predefined_type, Name}) ->
- io_lib:format("referring to built-in type ~w as a remote type; "
- "please take out the module name", [Name]);
+format_error({deprecated_type, {Name, Arity}, {Mod, NewName}, Rel}) ->
+ io_lib:format("type ~w/~w is deprecated and will be "
+ "removed in ~s; use ~w:~w/~w",
+ [Name, Arity, Rel, Mod, NewName, Arity]);
format_error({not_exported_opaque, {TypeName, Arity}}) ->
io_lib:format("opaque type ~w~s is not exported",
[TypeName, gen_type_paren(Arity)]);
@@ -1155,7 +1156,7 @@ export_type(Line, ETs, #lint{usage = Usage, exp_types = ETs0} = St0) ->
add_error(Line, {bad_export_type, ETs}, St0)
end.
--spec exports(lint_state()) -> gb_set().
+-spec exports(lint_state()) -> gb_sets:set().
exports(#lint{compile = Opts, defined = Defs, exports = Es}) ->
case lists:member(export_all, Opts) of
@@ -1888,7 +1889,7 @@ is_guard_test(Expression, Forms) ->
end, start(), RecordAttributes),
is_guard_test2(zip_file_and_line(Expression, "nofile"), St0#lint.records).
-%% is_guard_test2(Expression, RecordDefs :: dict()) -> boolean().
+%% is_guard_test2(Expression, RecordDefs :: dict:dict()) -> boolean().
is_guard_test2({call,Line,{atom,Lr,record},[E,A]}, RDs) ->
is_gexpr({call,Line,{atom,Lr,is_record},[E,A]}, RDs);
is_guard_test2({call,_Line,{atom,_La,Test},As}=Call, RDs) ->
@@ -2566,18 +2567,12 @@ check_type({paren_type, _L, [Type]}, SeenVars, St) ->
check_type(Type, SeenVars, St);
check_type({remote_type, L, [{atom, _, Mod}, {atom, _, Name}, Args]},
SeenVars, #lint{module=CurrentMod} = St) ->
- St1 =
- case is_default_type({Name, length(Args)})
- orelse is_var_arity_type(Name) of
- true -> add_error(L, {imported_predefined_type, Name}, St);
- false -> St
- end,
case Mod =:= CurrentMod of
- true -> check_type({type, L, Name, Args}, SeenVars, St1);
+ true -> check_type({type, L, Name, Args}, SeenVars, St);
false ->
lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
check_type(T, AccSeenVars, AccSt)
- end, {SeenVars, St1}, Args)
+ end, {SeenVars, St}, Args)
end;
check_type({integer, _L, _}, SeenVars, St) -> {SeenVars, St};
check_type({atom, _L, _}, SeenVars, St) -> {SeenVars, St};
@@ -2635,14 +2630,33 @@ check_type({type, _L, product, Args}, SeenVars, St) ->
lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
check_type(T, AccSeenVars, AccSt)
end, {SeenVars, St}, Args);
-check_type({type, La, TypeName, Args}, SeenVars, #lint{usage=Usage} = St) ->
+check_type({type, La, TypeName, Args}, SeenVars, St) ->
+ #lint{usage=Usage, module = Module, types=Types} = St,
Arity = length(Args),
+ TypePair = {TypeName, Arity},
St1 = case is_var_arity_type(TypeName) of
true -> St;
false ->
- OldUsed = Usage#usage.used_types,
- UsedTypes = dict:store({TypeName, Arity}, La, OldUsed),
- St#lint{usage=Usage#usage{used_types=UsedTypes}}
+ Obsolete = obsolete_type(TypePair),
+ IsObsolete =
+ case Obsolete of
+ {deprecated, {M, _}, _} when M =/= Module ->
+ case dict:find(TypePair, Types) of
+ {ok, _} -> false;
+ error -> true
+ end;
+ _ -> false
+ end,
+ case IsObsolete of
+ true ->
+ {deprecated, Replacement, Rel} = Obsolete,
+ W = {deprecated_type, TypePair, Replacement, Rel},
+ add_warning(La, W, St);
+ false ->
+ OldUsed = Usage#usage.used_types,
+ UsedTypes = dict:store(TypePair, La, OldUsed),
+ St#lint{usage=Usage#usage{used_types=UsedTypes}}
+ end
end,
check_type({type, -1, product, Args}, SeenVars, St1);
check_type(I, SeenVars, St) ->
@@ -2765,6 +2779,17 @@ is_newly_introduced_builtin_type({set, 0}) -> true; % opaque
is_newly_introduced_builtin_type({boolean, 0}) -> true;
is_newly_introduced_builtin_type({Name, _}) when is_atom(Name) -> false.
+%% Obsolete in OTP 17.0.
+obsolete_type({array, 0}) -> {deprecated, {array, array}, "OTP 18.0"};
+obsolete_type({dict, 0}) -> {deprecated, {dict, dict}, "OTP 18.0"};
+obsolete_type({digraph, 0}) -> {deprecated, {digraph, graph}, "OTP 18.0"};
+obsolete_type({gb_set, 0}) -> {deprecated, {gb_sets, set}, "OTP 18.0"};
+obsolete_type({gb_tree, 0}) -> {deprecated, {gb_trees, tree}, "OTP 18.0"};
+obsolete_type({queue, 0}) -> {deprecated, {queue, queue}, "OTP 18.0"};
+obsolete_type({set, 0}) -> {deprecated, {sets, set}, "OTP 18.0"};
+obsolete_type({tid, 0}) -> {deprecated, {ets, tid}, "OTP 18.0"};
+obsolete_type({Name, _}) when is_atom(Name) -> no.
+
%% spec_decl(Line, Fun, Types, State) -> State.
spec_decl(Line, MFA0, TypeSpecs, St0 = #lint{specs = Specs, module = Mod}) ->
diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index cc5e69f574..42b11a97e2 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -53,10 +53,8 @@
| {tab(),integer(),integer(),binary(),list(),integer()}
| {tab(),_,_,integer(),binary(),list(),integer(),integer()}.
-%% a similar definition is also in erl_types
-opaque tid() :: integer().
-%% these ones are also defined in erl_bif_types
-type match_pattern() :: atom() | tuple().
-type match_spec() :: [{match_pattern(), [_], [_]}].
diff --git a/lib/stdlib/src/gb_sets.erl b/lib/stdlib/src/gb_sets.erl
index 237317ac94..0a26d0182d 100644
--- a/lib/stdlib/src/gb_sets.erl
+++ b/lib/stdlib/src/gb_sets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -196,31 +196,32 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Some types.
--export_type([iter/0]).
+-export_type([set/0, set/1, iter/0, iter/1]).
--type gb_set_node() :: 'nil' | {term(), _, _}.
+-type gb_set_node(Element) :: 'nil' | {Element, _, _}.
+-type gb_set_node() :: gb_set_node(_).
+-opaque set(Element) :: {non_neg_integer(), gb_set_node(Element)}.
+-opaque set() :: set(_).
+-opaque iter(Element) :: [gb_set_node(Element)].
-opaque iter() :: [gb_set_node()].
-%% A declaration equivalent to the following is currently hard-coded
-%% in erl_types.erl
-%%
-%% -opaque gb_set() :: {non_neg_integer(), gb_set_node()}.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% gb_sets:set() in OTP 17 only.
+
-spec empty() -> Set when
- Set :: gb_set().
+ Set :: gb_sets:set().
empty() ->
{0, nil}.
-spec new() -> Set when
- Set :: gb_set().
+ Set :: gb_sets:set().
new() -> empty().
-spec is_empty(Set) -> boolean() when
- Set :: gb_set().
+ Set :: gb_sets:set().
is_empty({0, nil}) ->
true;
@@ -228,27 +229,24 @@ is_empty(_) ->
false.
-spec size(Set) -> non_neg_integer() when
- Set :: gb_set().
+ Set :: gb_sets:set().
size({Size, _}) ->
Size.
--spec singleton(Element) -> gb_set() when
- Element :: term().
+-spec singleton(Element) -> set(Element).
singleton(Key) ->
{1, {Key, nil, nil}}.
-spec is_element(Element, Set) -> boolean() when
- Element :: term(),
- Set :: gb_set().
+ Set :: set(Element).
is_element(Key, S) ->
is_member(Key, S).
-spec is_member(Element, Set) -> boolean() when
- Element :: term(),
- Set :: gb_set().
+ Set :: set(Element).
is_member(Key, {_, T}) ->
is_member_1(Key, T).
@@ -263,9 +261,8 @@ is_member_1(_, nil) ->
false.
-spec insert(Element, Set1) -> Set2 when
- Element :: term(),
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
insert(Key, {S, T}) ->
S1 = S + 1,
@@ -322,8 +319,8 @@ count(nil) ->
{1, 0}.
-spec balance(Set1) -> Set2 when
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
balance({S, T}) ->
{S, balance(T, S)}.
@@ -349,17 +346,15 @@ balance_list_1(L, 0) ->
{nil, L}.
-spec add_element(Element, Set1) -> Set2 when
- Element :: term(),
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
add_element(X, S) ->
add(X, S).
-spec add(Element, Set1) -> Set2 when
- Element :: term(),
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
add(X, S) ->
case is_member(X, S) of
@@ -370,32 +365,30 @@ add(X, S) ->
end.
-spec from_list(List) -> Set when
- List :: [term()],
- Set :: gb_set().
+ List :: [Element],
+ Set :: set(Element).
from_list(L) ->
from_ordset(ordsets:from_list(L)).
-spec from_ordset(List) -> Set when
- List :: [term()],
- Set :: gb_set().
+ List :: [Element],
+ Set :: set(Element).
from_ordset(L) ->
S = length(L),
{S, balance_list(L, S)}.
-spec del_element(Element, Set1) -> Set2 when
- Element :: term(),
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
del_element(Key, S) ->
delete_any(Key, S).
-spec delete_any(Element, Set1) -> Set2 when
- Element :: term(),
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
delete_any(Key, S) ->
case is_member(Key, S) of
@@ -406,9 +399,8 @@ delete_any(Key, S) ->
end.
-spec delete(Element, Set1) -> Set2 when
- Element :: term(),
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
delete(Key, {S, T}) ->
{S - 1, delete_1(Key, T)}.
@@ -431,9 +423,8 @@ merge(Smaller, Larger) ->
{Key, Smaller, Larger1}.
-spec take_smallest(Set1) -> {Element, Set2} when
- Set1 :: gb_set(),
- Set2 :: gb_set(),
- Element :: term().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
take_smallest({S, T}) ->
{Key, Larger} = take_smallest1(T),
@@ -445,8 +436,8 @@ take_smallest1({Key, Smaller, Larger}) ->
{Key1, Smaller1} = take_smallest1(Smaller),
{Key1, {Key, Smaller1, Larger}}.
--spec smallest(Set) -> term() when
- Set :: gb_set().
+-spec smallest(Set) -> Element when
+ Set :: set(Element).
smallest({_, T}) ->
smallest_1(T).
@@ -457,9 +448,8 @@ smallest_1({_Key, Smaller, _Larger}) ->
smallest_1(Smaller).
-spec take_largest(Set1) -> {Element, Set2} when
- Set1 :: gb_set(),
- Set2 :: gb_set(),
- Element :: term().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
take_largest({S, T}) ->
{Key, Smaller} = take_largest1(T),
@@ -471,8 +461,8 @@ take_largest1({Key, Smaller, Larger}) ->
{Key1, Larger1} = take_largest1(Larger),
{Key1, {Key, Smaller, Larger1}}.
--spec largest(Set) -> term() when
- Set :: gb_set().
+-spec largest(Set) -> Element when
+ Set :: set(Element).
largest({_, T}) ->
largest_1(T).
@@ -483,8 +473,8 @@ largest_1({_Key, _Smaller, Larger}) ->
largest_1(Larger).
-spec to_list(Set) -> List when
- Set :: gb_set(),
- List :: [term()].
+ Set :: set(Element),
+ List :: [Element].
to_list({_, T}) ->
to_list(T, []).
@@ -496,8 +486,8 @@ to_list({Key, Small, Big}, L) ->
to_list(nil, L) -> L.
-spec iterator(Set) -> Iter when
- Set :: gb_set(),
- Iter :: iter().
+ Set :: set(Element),
+ Iter :: iter(Element).
iterator({_, T}) ->
iterator(T, []).
@@ -513,9 +503,8 @@ iterator(nil, As) ->
As.
-spec next(Iter1) -> {Element, Iter2} | 'none' when
- Iter1 :: iter(),
- Iter2 :: iter(),
- Element :: term().
+ Iter1 :: iter(Element),
+ Iter2 :: iter(Element).
next([{X, _, T} | As]) ->
{X, iterator(T, As)};
@@ -546,9 +535,9 @@ next([]) ->
%% overhead.
-spec union(Set1, Set2) -> Set3 when
- Set1 :: gb_set(),
- Set2 :: gb_set(),
- Set3 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
union({N1, T1}, {N2, T2}) when N2 < N1 ->
union(to_list_1(T2), N2, T1, N1);
@@ -570,7 +559,7 @@ union(L, N1, T2, N2) ->
union_1(L, mk_set(N2, T2))
end.
--spec mk_set(non_neg_integer(), gb_set_node()) -> gb_set().
+-spec mk_set(non_neg_integer(), gb_set_node(T)) -> set(T).
mk_set(N, T) ->
{N, T}.
@@ -651,8 +640,8 @@ balance_revlist_1(L, 0) ->
{nil, L}.
-spec union(SetList) -> Set when
- SetList :: [gb_set(),...],
- Set :: gb_set().
+ SetList :: [set(Element),...],
+ Set :: set(Element).
union([S | Ss]) ->
union_list(S, Ss);
@@ -666,9 +655,9 @@ union_list(S, []) -> S.
%% The rest is modelled on the above.
-spec intersection(Set1, Set2) -> Set3 when
- Set1 :: gb_set(),
- Set2 :: gb_set(),
- Set3 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
intersection({N1, T1}, {N2, T2}) when N2 < N1 ->
intersection(to_list_1(T2), N2, T1, N1);
@@ -717,8 +706,8 @@ intersection_2(_, [], As, S) ->
{S, balance_revlist(As, S)}.
-spec intersection(SetList) -> Set when
- SetList :: [gb_set(),...],
- Set :: gb_set().
+ SetList :: [set(Element),...],
+ Set :: set(Element).
intersection([S | Ss]) ->
intersection_list(S, Ss).
@@ -728,8 +717,8 @@ intersection_list(S, [S1 | Ss]) ->
intersection_list(S, []) -> S.
-spec is_disjoint(Set1, Set2) -> boolean() when
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
is_disjoint({N1, T1}, {N2, T2}) when N1 < N2 ->
is_disjoint_1(T1, T2);
@@ -758,17 +747,17 @@ is_disjoint_1(_, nil) ->
%% traverse the whole element list of the left operand.
-spec subtract(Set1, Set2) -> Set3 when
- Set1 :: gb_set(),
- Set2 :: gb_set(),
- Set3 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
subtract(S1, S2) ->
difference(S1, S2).
-spec difference(Set1, Set2) -> Set3 when
- Set1 :: gb_set(),
- Set2 :: gb_set(),
- Set3 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
difference({N1, T1}, {N2, T2}) ->
difference(to_list_1(T1), N1, T2, N2).
@@ -817,8 +806,8 @@ difference_2(Xs, [], As, S) ->
%% without the construction of a new set.
-spec is_subset(Set1, Set2) -> boolean() when
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
is_subset({N1, T1}, {N2, T2}) ->
is_subset(to_list_1(T1), N1, T2, N2).
@@ -867,20 +856,20 @@ is_set({N, {_, _, _}}) when is_integer(N), N >= 0 -> true;
is_set(_) -> false.
-spec filter(Pred, Set1) -> Set2 when
- Pred :: fun((E :: term()) -> boolean()),
- Set1 :: gb_set(),
- Set2 :: gb_set().
+ Pred :: fun((Element) -> boolean()),
+ Set1 :: set(Element),
+ Set2 :: set(Element).
filter(F, S) ->
from_ordset([X || X <- to_list(S), F(X)]).
-spec fold(Function, Acc0, Set) -> Acc1 when
- Function :: fun((E :: term(), AccIn) -> AccOut),
- Acc0 :: term(),
- Acc1 :: term(),
- AccIn :: term(),
- AccOut :: term(),
- Set :: gb_set().
+ Function :: fun((Element, AccIn) -> AccOut),
+ Acc0 :: Acc,
+ Acc1 :: Acc,
+ AccIn :: Acc,
+ AccOut :: Acc,
+ Set :: set(Element).
fold(F, A, {_, T}) when is_function(F, 2) ->
fold_1(F, A, T).
diff --git a/lib/stdlib/src/gb_trees.erl b/lib/stdlib/src/gb_trees.erl
index 7a4dfe1a0b..7069b61873 100644
--- a/lib/stdlib/src/gb_trees.erl
+++ b/lib/stdlib/src/gb_trees.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -152,25 +152,25 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Some types.
--export_type([iter/0]).
+-export_type([tree/0, tree/2, iter/0, iter/2]).
--type gb_tree_node() :: 'nil' | {_, _, _, _}.
+-type gb_tree_node(K, V) :: 'nil'
+ | {K, V, gb_tree_node(K, V), gb_tree_node(K, V)}.
+-type gb_tree_node() :: gb_tree_node(_, _).
+-opaque tree(Key, Value) :: {non_neg_integer(), gb_tree_node(Key, Value)}.
+-opaque tree() :: tree(_, _).
+-opaque iter(Key, Value) :: [gb_tree_node(Key, Value)].
-opaque iter() :: [gb_tree_node()].
-%% A declaration equivalent to the following is currently hard-coded
-%% in erl_types.erl
-%%
-%% -opaque gb_tree() :: {non_neg_integer(), gb_tree_node()}.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec empty() -> gb_tree().
+-spec empty() -> tree().
empty() ->
{0, nil}.
-spec is_empty(Tree) -> boolean() when
- Tree :: gb_tree().
+ Tree :: tree().
is_empty({0, nil}) ->
true;
@@ -178,17 +178,15 @@ is_empty(_) ->
false.
-spec size(Tree) -> non_neg_integer() when
- Tree :: gb_tree().
+ Tree :: tree().
size({Size, _}) when is_integer(Size), Size >= 0 ->
Size.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec lookup(Key, Tree) -> 'none' | {'value', Val} when
- Key :: term(),
- Val :: term(),
- Tree :: gb_tree().
+-spec lookup(Key, Tree) -> 'none' | {'value', Value} when
+ Tree :: tree(Key, Value).
lookup(Key, {_, T}) ->
lookup_1(Key, T).
@@ -214,8 +212,7 @@ lookup_1(_, nil) ->
%% This is a specialized version of `lookup'.
-spec is_defined(Key, Tree) -> boolean() when
- Key :: term(),
- Tree :: gb_tree().
+ Tree :: tree(Key, Value :: term()).
is_defined(Key, {_, T}) ->
is_defined_1(Key, T).
@@ -233,10 +230,8 @@ is_defined_1(_, nil) ->
%% This is a specialized version of `lookup'.
--spec get(Key, Tree) -> Val when
- Key :: term(),
- Tree :: gb_tree(),
- Val :: term().
+-spec get(Key, Tree) -> Value when
+ Tree :: tree(Key, Value).
get(Key, {_, T}) ->
get_1(Key, T).
@@ -250,11 +245,9 @@ get_1(_, {_, Value, _, _}) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec update(Key, Val, Tree1) -> Tree2 when
- Key :: term(),
- Val :: term(),
- Tree1 :: gb_tree(),
- Tree2 :: gb_tree().
+-spec update(Key, Value, Tree1) -> Tree2 when
+ Tree1 :: tree(Key, Value),
+ Tree2 :: tree(Key, Value).
update(Key, Val, {S, T}) ->
T1 = update_1(Key, Val, T),
@@ -271,11 +264,9 @@ update_1(Key, Value, {_, _, Smaller, Bigger}) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec insert(Key, Val, Tree1) -> Tree2 when
- Key :: term(),
- Val :: term(),
- Tree1 :: gb_tree(),
- Tree2 :: gb_tree().
+-spec insert(Key, Value, Tree1) -> Tree2 when
+ Tree1 :: tree(Key, Value),
+ Tree2 :: tree(Key, Value).
insert(Key, Val, {S, T}) when is_integer(S) ->
S1 = S+1,
@@ -324,11 +315,9 @@ insert_1(Key, _, _, _) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec enter(Key, Val, Tree1) -> Tree2 when
- Key :: term(),
- Val :: term(),
- Tree1 :: gb_tree(),
- Tree2 :: gb_tree().
+-spec enter(Key, Value, Tree1) -> Tree2 when
+ Tree1 :: tree(Key, Value),
+ Tree2 :: tree(Key, Value).
enter(Key, Val, T) ->
case is_defined(Key, T) of
@@ -352,8 +341,8 @@ count(nil) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec balance(Tree1) -> Tree2 when
- Tree1 :: gb_tree(),
- Tree2 :: gb_tree().
+ Tree1 :: tree(Key, Value),
+ Tree2 :: tree(Key, Value).
balance({S, T}) ->
{S, balance(T, S)}.
@@ -379,8 +368,8 @@ balance_list_1(L, 0) ->
{nil, L}.
-spec from_orddict(List) -> Tree when
- List :: [{Key :: term(), Val :: term()}],
- Tree :: gb_tree().
+ List :: [{Key, Value}],
+ Tree :: tree(Key, Value).
from_orddict(L) ->
S = length(L),
@@ -389,9 +378,8 @@ from_orddict(L) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec delete_any(Key, Tree1) -> Tree2 when
- Key :: term(),
- Tree1 :: gb_tree(),
- Tree2 :: gb_tree().
+ Tree1 :: tree(Key, Value),
+ Tree2 :: tree(Key, Value).
delete_any(Key, T) ->
case is_defined(Key, T) of
@@ -404,9 +392,8 @@ delete_any(Key, T) ->
%%% delete. Assumes that key is present.
-spec delete(Key, Tree1) -> Tree2 when
- Key :: term(),
- Tree1 :: gb_tree(),
- Tree2 :: gb_tree().
+ Tree1 :: tree(Key, Value),
+ Tree2 :: tree(Key, Value).
delete(Key, {S, T}) when is_integer(S), S >= 0 ->
{S - 1, delete_1(Key, T)}.
@@ -432,11 +419,9 @@ merge(Smaller, Larger) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec take_smallest(Tree1) -> {Key, Val, Tree2} when
- Tree1 :: gb_tree(),
- Tree2 :: gb_tree(),
- Key :: term(),
- Val :: term().
+-spec take_smallest(Tree1) -> {Key, Value, Tree2} when
+ Tree1 :: tree(Key, Value),
+ Tree2 :: tree(Key, Value).
take_smallest({Size, Tree}) when is_integer(Size), Size >= 0 ->
{Key, Value, Larger} = take_smallest1(Tree),
@@ -448,10 +433,8 @@ take_smallest1({Key, Value, Smaller, Larger}) ->
{Key1, Value1, Smaller1} = take_smallest1(Smaller),
{Key1, Value1, {Key, Value, Smaller1, Larger}}.
--spec smallest(Tree) -> {Key, Val} when
- Tree :: gb_tree(),
- Key :: term(),
- Val :: term().
+-spec smallest(Tree) -> {Key, Value} when
+ Tree :: tree(Key, Value).
smallest({_, Tree}) ->
smallest_1(Tree).
@@ -461,11 +444,9 @@ smallest_1({Key, Value, nil, _Larger}) ->
smallest_1({_Key, _Value, Smaller, _Larger}) ->
smallest_1(Smaller).
--spec take_largest(Tree1) -> {Key, Val, Tree2} when
- Tree1 :: gb_tree(),
- Tree2 :: gb_tree(),
- Key :: term(),
- Val :: term().
+-spec take_largest(Tree1) -> {Key, Value, Tree2} when
+ Tree1 :: tree(Key, Value),
+ Tree2 :: tree(Key, Value).
take_largest({Size, Tree}) when is_integer(Size), Size >= 0 ->
{Key, Value, Smaller} = take_largest1(Tree),
@@ -477,10 +458,8 @@ take_largest1({Key, Value, Smaller, Larger}) ->
{Key1, Value1, Larger1} = take_largest1(Larger),
{Key1, Value1, {Key, Value, Smaller, Larger1}}.
--spec largest(Tree) -> {Key, Val} when
- Tree :: gb_tree(),
- Key :: term(),
- Val :: term().
+-spec largest(Tree) -> {Key, Value} when
+ Tree :: tree(Key, Value).
largest({_, Tree}) ->
largest_1(Tree).
@@ -492,10 +471,8 @@ largest_1({_Key, _Value, _Smaller, Larger}) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec to_list(Tree) -> [{Key, Val}] when
- Tree :: gb_tree(),
- Key :: term(),
- Val :: term().
+-spec to_list(Tree) -> [{Key, Value}] when
+ Tree :: tree(Key, Value).
to_list({_, T}) ->
to_list(T, []).
@@ -509,8 +486,7 @@ to_list(nil, L) -> L.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec keys(Tree) -> [Key] when
- Tree :: gb_tree(),
- Key :: term().
+ Tree :: tree(Key, Value :: term()).
keys({_, T}) ->
keys(T, []).
@@ -521,9 +497,8 @@ keys(nil, L) -> L.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec values(Tree) -> [Val] when
- Tree :: gb_tree(),
- Val :: term().
+-spec values(Tree) -> [Value] when
+ Tree :: tree(Key :: term(), Value).
values({_, T}) ->
values(T, []).
@@ -535,8 +510,8 @@ values(nil, L) -> L.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec iterator(Tree) -> Iter when
- Tree :: gb_tree(),
- Iter :: iter().
+ Tree :: tree(Key, Value),
+ Iter :: iter(Key, Value).
iterator({_, T}) ->
iterator_1(T).
@@ -554,11 +529,9 @@ iterator({_, _, L, _} = T, As) ->
iterator(nil, As) ->
As.
--spec next(Iter1) -> 'none' | {Key, Val, Iter2} when
- Iter1 :: iter(),
- Iter2 :: iter(),
- Key :: term(),
- Val :: term().
+-spec next(Iter1) -> 'none' | {Key, Value, Iter2} when
+ Iter1 :: iter(Key, Value),
+ Iter2 :: iter(Key, Value).
next([{X, V, _, T} | As]) ->
{X, V, iterator(T, As)};
@@ -568,9 +541,9 @@ next([]) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec map(Function, Tree1) -> Tree2 when
- Function :: fun((K :: term(), V1 :: term()) -> V2 :: term()),
- Tree1 :: gb_tree(),
- Tree2 :: gb_tree().
+ Function :: fun((K :: Key, V1 :: Value1) -> V2 :: Value2),
+ Tree1 :: tree(Key, Value1),
+ Tree2 :: tree(Key, Value2).
map(F, {Size, Tree}) when is_function(F, 2) ->
{Size, map_1(F, Tree)}.
diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl
index cebc9c91bd..380bc3eccc 100644
--- a/lib/stdlib/src/otp_internal.erl
+++ b/lib/stdlib/src/otp_internal.erl
@@ -577,6 +577,24 @@ obsolete_1(wxCursor, new, 3) ->
obsolete_1(wxCursor, new, 4) ->
{deprecated,"deprecated function not available in wxWidgets-2.9 and later"};
+%% Added in OTP 17.
+obsolete_1(asn1ct, decode,3) ->
+ {deprecated,"deprecated; use Mod:decode/2 instead"};
+obsolete_1(asn1ct, encode, 3) ->
+ {deprecated,"deprecated; use Mod:encode/2 instead"};
+obsolete_1(asn1rt, decode,3) ->
+ {deprecated,"deprecated; use Mod:decode/2 instead"};
+obsolete_1(asn1rt, encode, 2) ->
+ {deprecated,"deprecated; use Mod:encode/2 instead"};
+obsolete_1(asn1rt, encode, 3) ->
+ {deprecated,"deprecated; use Mod:encode/2 instead"};
+obsolete_1(asn1rt, info, 1) ->
+ {deprecated,"deprecated; use Mod:info/0 instead"};
+obsolete_1(asn1rt, utf8_binary_to_list, 1) ->
+ {deprecated,{unicode,characters_to_list,1}};
+obsolete_1(asn1rt, utf8_list_to_binary, 1) ->
+ {deprecated,{unicode,characters_to_binary,1}};
+
obsolete_1(_, _, _) ->
no.
diff --git a/lib/stdlib/src/queue.erl b/lib/stdlib/src/queue.erl
index 4bbf5de8a5..472d503b99 100644
--- a/lib/stdlib/src/queue.erl
+++ b/lib/stdlib/src/queue.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -32,6 +32,8 @@
-export([cons/2,head/1,tail/1,
snoc/2,last/1,daeh/1,init/1,liat/1,lait/1]).
+-export_type([queue/0, queue/1]).
+
%%--------------------------------------------------------------------------
%% Efficient implementation of double ended fifo queues
%%
@@ -44,10 +46,9 @@
%% that is; the RearList is reversed.
%%
-%% A declaration equivalent to the following is currently hard-coded
-%% in erl_types.erl
-%%
-%% -opaque queue() :: {list(), list()}.
+-opaque queue(Item) :: {list(Item), list(Item)}.
+
+-opaque queue() :: queue(_).
%% Creation, inspection and conversion
@@ -79,7 +80,7 @@ len(Q) ->
erlang:error(badarg, [Q]).
%% O(len(Q))
--spec to_list(Q :: queue()) -> list().
+-spec to_list(Q :: queue(Item)) -> list(Item).
to_list({In,Out}) when is_list(In), is_list(Out) ->
Out++lists:reverse(In, []);
to_list(Q) ->
@@ -88,7 +89,7 @@ to_list(Q) ->
%% Create queue from list
%%
%% O(length(L))
--spec from_list(L :: list()) -> queue().
+-spec from_list(L :: list(Item)) -> queue(Item).
from_list(L) when is_list(L) ->
f2r(L);
from_list(L) ->
@@ -97,7 +98,7 @@ from_list(L) ->
%% Return true or false depending on if element is in queue
%%
%% O(length(Q)) worst case
--spec member(Item :: term(), Q :: queue()) -> boolean().
+-spec member(Item, Q :: queue(Item)) -> boolean().
member(X, {R,F}) when is_list(R), is_list(F) ->
lists:member(X, R) orelse lists:member(X, F);
member(X, Q) ->
@@ -110,7 +111,7 @@ member(X, Q) ->
%% Put at least one element in each list, if it is cheap
%%
%% O(1)
--spec in(Item :: term(), Q1 :: queue()) -> Q2 :: queue().
+-spec in(Item, Q1 :: queue(Item)) -> Q2 :: queue(Item).
in(X, {[_]=In,[]}) ->
{[X], In};
in(X, {In,Out}) when is_list(In), is_list(Out) ->
@@ -122,7 +123,7 @@ in(X, Q) ->
%% Put at least one element in each list, if it is cheap
%%
%% O(1)
--spec in_r(Item :: term(), Q1 :: queue()) -> Q2 :: queue().
+-spec in_r(Item, Q1 :: queue(Item)) -> Q2 :: queue(Item).
in_r(X, {[],[_]=F}) ->
{F,[X]};
in_r(X, {R,F}) when is_list(R), is_list(F) ->
@@ -133,9 +134,9 @@ in_r(X, Q) ->
%% Take from head/front
%%
%% O(1) amortized, O(len(Q)) worst case
--spec out(Q1 :: queue()) ->
- {{value, Item :: term()}, Q2 :: queue()} |
- {empty, Q1 :: queue()}.
+-spec out(Q1 :: queue(Item)) ->
+ {{value, Item}, Q2 :: queue(Item)} |
+ {empty, Q1 :: queue(Item)}.
out({[],[]}=Q) ->
{empty,Q};
out({[V],[]}) ->
@@ -153,9 +154,9 @@ out(Q) ->
%% Take from tail/rear
%%
%% O(1) amortized, O(len(Q)) worst case
--spec out_r(Q1 :: queue()) ->
- {{value, Item :: term()}, Q2 :: queue()} |
- {empty, Q1 :: queue()}.
+-spec out_r(Q1 :: queue(Item)) ->
+ {{value, Item}, Q2 :: queue(Item)} |
+ {empty, Q1 :: queue(Item)}.
out_r({[],[]}=Q) ->
{empty,Q};
out_r({[],[V]}) ->
@@ -176,7 +177,7 @@ out_r(Q) ->
%% Return the first element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec get(Q :: queue()) -> Item :: term().
+-spec get(Q :: queue(Item)) -> Item.
get({[],[]}=Q) ->
erlang:error(empty, [Q]);
get({R,F}) when is_list(R), is_list(F) ->
@@ -195,7 +196,7 @@ get([_|R], []) -> % malformed queue -> O(len(Q))
%% Return the last element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec get_r(Q :: queue()) -> Item :: term().
+-spec get_r(Q :: queue(Item)) -> Item.
get_r({[],[]}=Q) ->
erlang:error(empty, [Q]);
get_r({[H|_],F}) when is_list(F) ->
@@ -210,7 +211,7 @@ get_r(Q) ->
%% Return the first element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec peek(Q :: queue()) -> empty | {value,Item :: term()}.
+-spec peek(Q :: queue(Item)) -> empty | {value, Item}.
peek({[],[]}) ->
empty;
peek({R,[H|_]}) when is_list(R) ->
@@ -225,7 +226,7 @@ peek(Q) ->
%% Return the last element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec peek_r(Q :: queue()) -> empty | {value,Item :: term()}.
+-spec peek_r(Q :: queue(Item)) -> empty | {value, Item}.
peek_r({[],[]}) ->
empty;
peek_r({[H|_],F}) when is_list(F) ->
@@ -240,7 +241,7 @@ peek_r(Q) ->
%% Remove the first element and return resulting queue
%%
%% O(1) amortized
--spec drop(Q1 :: queue()) -> Q2 :: queue().
+-spec drop(Q1 :: queue(Item)) -> Q2 :: queue(Item).
drop({[],[]}=Q) ->
erlang:error(empty, [Q]);
drop({[_],[]}) ->
@@ -258,7 +259,7 @@ drop(Q) ->
%% Remove the last element and return resulting queue
%%
%% O(1) amortized
--spec drop_r(Q1 :: queue()) -> Q2 :: queue().
+-spec drop_r(Q1 :: queue(Item)) -> Q2 :: queue(Item).
drop_r({[],[]}=Q) ->
erlang:error(empty, [Q]);
drop_r({[],[_]}) ->
@@ -279,7 +280,7 @@ drop_r(Q) ->
%% Return reversed queue
%%
%% O(1)
--spec reverse(Q1 :: queue()) -> Q2 :: queue().
+-spec reverse(Q1 :: queue(Item)) -> Q2 :: queue(Item).
reverse({R,F}) when is_list(R), is_list(F) ->
{F,R};
reverse(Q) ->
@@ -289,7 +290,7 @@ reverse(Q) ->
%%
%% Q2 empty: O(1)
%% else: O(len(Q1))
--spec join(Q1 :: queue(), Q2 :: queue()) -> Q3 :: queue().
+-spec join(Q1 :: queue(Item), Q2 :: queue(Item)) -> Q3 :: queue(Item).
join({R,F}=Q, {[],[]}) when is_list(R), is_list(F) ->
Q;
join({[],[]}, {R,F}=Q) when is_list(R), is_list(F) ->
@@ -303,8 +304,8 @@ join(Q1, Q2) ->
%%
%% N = 0..len(Q)
%% O(max(N, len(Q)))
--spec split(N :: non_neg_integer(), Q1 :: queue()) ->
- {Q2 :: queue(),Q3 :: queue()}.
+-spec split(N :: non_neg_integer(), Q1 :: queue(Item)) ->
+ {Q2 :: queue(Item),Q3 :: queue(Item)}.
split(0, {R,F}=Q) when is_list(R), is_list(F) ->
{{[],[]},Q};
split(N, {R,F}=Q) when is_integer(N), N >= 1, is_list(R), is_list(F) ->
@@ -345,8 +346,8 @@ split_r1_to_f2(N, [X|R1], F1, R2, F2) ->
%%
%% Fun(_) -> List: O(length(List) * len(Q))
%% else: O(len(Q)
--spec filter(Fun, Q1 :: queue()) -> Q2 :: queue() when
- Fun :: fun((Item :: term()) -> boolean() | list()).
+-spec filter(Fun, Q1 :: queue(Item)) -> Q2 :: queue(Item) when
+ Fun :: fun((Item) -> boolean() | list(Item)).
filter(Fun, {R0,F0}) when is_function(Fun, 1), is_list(R0), is_list(F0) ->
F = filter_f(Fun, F0),
R = filter_r(Fun, R0),
@@ -422,7 +423,7 @@ filter_r(Fun, [X|R0]) ->
%% Cons to head
%%
--spec cons(Item :: term(), Q1 :: queue()) -> Q2 :: queue().
+-spec cons(Item, Q1 :: queue(Item)) -> Q2 :: queue(Item).
cons(X, Q) ->
in_r(X, Q).
@@ -431,7 +432,7 @@ cons(X, Q) ->
%% Return the first element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec head(Q :: queue()) -> Item :: term().
+-spec head(Q :: queue(Item)) -> Item.
head({[],[]}=Q) ->
erlang:error(empty, [Q]);
head({R,F}) when is_list(R), is_list(F) ->
@@ -441,7 +442,7 @@ head(Q) ->
%% Remove head element and return resulting queue
%%
--spec tail(Q1 :: queue()) -> Q2 :: queue().
+-spec tail(Q1 :: queue(Item)) -> Q2 :: queue(Item).
tail(Q) ->
drop(Q).
@@ -449,22 +450,22 @@ tail(Q) ->
%% Cons to tail
%%
--spec snoc(Q1 :: queue(), Item :: term()) -> Q2 :: queue().
+-spec snoc(Q1 :: queue(Item), Item) -> Q2 :: queue(Item).
snoc(Q, X) ->
in(X, Q).
%% Return last element
--spec daeh(Q :: queue()) -> Item :: term().
+-spec daeh(Q :: queue(Item)) -> Item.
daeh(Q) -> get_r(Q).
--spec last(Q :: queue()) -> Item :: term().
+-spec last(Q :: queue(Item)) -> Item.
last(Q) -> get_r(Q).
%% Remove last element and return resulting queue
--spec liat(Q1 :: queue()) -> Q2 :: queue().
+-spec liat(Q1 :: queue(Item)) -> Q2 :: queue(Item).
liat(Q) -> drop_r(Q).
--spec lait(Q1 :: queue()) -> Q2 :: queue().
+-spec lait(Q1 :: queue(Item)) -> Q2 :: queue(Item).
lait(Q) -> drop_r(Q). %% Oops, mis-spelled 'tail' reversed. Forget this one.
--spec init(Q1 :: queue()) -> Q2 :: queue().
+-spec init(Q1 :: queue(Item)) -> Q2 :: queue(Item).
init(Q) -> drop_r(Q).
%%--------------------------------------------------------------------------
diff --git a/lib/stdlib/src/sets.erl b/lib/stdlib/src/sets.erl
index ebf011a7d9..be4b600f25 100644
--- a/lib/stdlib/src/sets.erl
+++ b/lib/stdlib/src/sets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -43,6 +43,8 @@
-export([subtract/2,is_subset/2]).
-export([fold/3,filter/2]).
+-export_type([set/0, set/1]).
+
%% Note: mk_seg/1 must be changed too if seg_size is changed.
-define(seg_size, 16).
-define(max_seg, 32).
@@ -54,7 +56,8 @@
%%------------------------------------------------------------------------------
-type seg() :: tuple().
--type segs() :: tuple().
+-type segs(E) :: tuple()
+ | E. % dummy
%% Define a hash set. The default values are the standard ones.
-record(set,
@@ -65,14 +68,12 @@
exp_size=?exp_size :: non_neg_integer(), % Size to expand at
con_size=?con_size :: non_neg_integer(), % Size to contract at
empty :: seg(), % Empty segment
- segs :: segs() % Segments
+ segs :: segs(_) % Segments
}).
-%% A declaration equivalent to the following one is hard-coded in erl_types.
-%% That declaration contains hard-coded information about the #set{}
-%% record and the types of its fields. So, please make sure that any
-%% changes to its structure are also propagated to erl_types.erl.
-%%
-%% -opaque set() :: #set{}.
+
+-opaque set() :: set(_).
+
+-opaque set(Element) :: #set{segs :: segs(Element)}.
%%------------------------------------------------------------------------------
@@ -98,24 +99,23 @@ size(S) -> S#set.size.
%% to_list(Set) -> [Elem].
%% Return the elements in Set as a list.
-spec to_list(Set) -> List when
- Set :: set(),
- List :: [term()].
+ Set :: set(Element),
+ List :: [Element].
to_list(S) ->
fold(fun (Elem, List) -> [Elem|List] end, [], S).
%% from_list([Elem]) -> Set.
%% Build a set from the elements in List.
-spec from_list(List) -> Set when
- List :: [term()],
- Set :: set().
+ List :: [Element],
+ Set :: set(Element).
from_list(L) ->
lists:foldl(fun (E, S) -> add_element(E, S) end, new(), L).
%% is_element(Element, Set) -> boolean().
%% Return 'true' if Element is an element of Set, else 'false'.
-spec is_element(Element, Set) -> boolean() when
- Element :: term(),
- Set :: set().
+ Set :: set(Element).
is_element(E, S) ->
Slot = get_slot(S, E),
Bkt = get_bucket(S, Slot),
@@ -124,9 +124,8 @@ is_element(E, S) ->
%% add_element(Element, Set) -> Set.
%% Return Set with Element inserted in it.
-spec add_element(Element, Set1) -> Set2 when
- Element :: term(),
- Set1 :: set(),
- Set2 :: set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
add_element(E, S0) ->
Slot = get_slot(S0, E),
{S1,Ic} = on_bucket(fun (B0) -> add_bkt_el(E, B0, B0) end, S0, Slot),
@@ -141,9 +140,8 @@ add_bkt_el(E, [], Bkt) -> {[E|Bkt],1}.
%% del_element(Element, Set) -> Set.
%% Return Set but with Element removed.
-spec del_element(Element, Set1) -> Set2 when
- Element :: term(),
- Set1 :: set(),
- Set2 :: set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
del_element(E, S0) ->
Slot = get_slot(S0, E),
{S1,Dc} = on_bucket(fun (B0) -> del_bkt_el(E, B0) end, S0, Slot),
@@ -159,9 +157,9 @@ del_bkt_el(_, []) -> {[],0}.
%% union(Set1, Set2) -> Set
%% Return the union of Set1 and Set2.
-spec union(Set1, Set2) -> Set3 when
- Set1 :: set(),
- Set2 :: set(),
- Set3 :: set().
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
union(S1, S2) when S1#set.size < S2#set.size ->
fold(fun (E, S) -> add_element(E, S) end, S2, S1);
union(S1, S2) ->
@@ -170,14 +168,14 @@ union(S1, S2) ->
%% union([Set]) -> Set
%% Return the union of the list of sets.
-spec union(SetList) -> Set when
- SetList :: [set()],
- Set :: set().
+ SetList :: [set(Element)],
+ Set :: set(Element).
union([S1,S2|Ss]) ->
union1(union(S1, S2), Ss);
union([S]) -> S;
union([]) -> new().
--spec union1(set(), [set()]) -> set().
+-spec union1(set(E), [set(E)]) -> set(E).
union1(S1, [S2|Ss]) ->
union1(union(S1, S2), Ss);
union1(S1, []) -> S1.
@@ -185,9 +183,9 @@ union1(S1, []) -> S1.
%% intersection(Set1, Set2) -> Set.
%% Return the intersection of Set1 and Set2.
-spec intersection(Set1, Set2) -> Set3 when
- Set1 :: set(),
- Set2 :: set(),
- Set3 :: set().
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
intersection(S1, S2) when S1#set.size < S2#set.size ->
filter(fun (E) -> is_element(E, S2) end, S1);
intersection(S1, S2) ->
@@ -196,13 +194,13 @@ intersection(S1, S2) ->
%% intersection([Set]) -> Set.
%% Return the intersection of the list of sets.
-spec intersection(SetList) -> Set when
- SetList :: [set(),...],
- Set :: set().
+ SetList :: [set(Element),...],
+ Set :: set(Element).
intersection([S1,S2|Ss]) ->
intersection1(intersection(S1, S2), Ss);
intersection([S]) -> S.
--spec intersection1(set(), [set()]) -> set().
+-spec intersection1(set(E), [set(E)]) -> set(E).
intersection1(S1, [S2|Ss]) ->
intersection1(intersection(S1, S2), Ss);
intersection1(S1, []) -> S1.
@@ -210,8 +208,8 @@ intersection1(S1, []) -> S1.
%% is_disjoint(Set1, Set2) -> boolean().
%% Check whether Set1 and Set2 are disjoint.
-spec is_disjoint(Set1, Set2) -> boolean() when
- Set1 :: set(),
- Set2 :: set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
is_disjoint(S1, S2) when S1#set.size < S2#set.size ->
fold(fun (_, false) -> false;
(E, true) -> not is_element(E, S2)
@@ -225,9 +223,9 @@ is_disjoint(S1, S2) ->
%% Return all and only the elements of Set1 which are not also in
%% Set2.
-spec subtract(Set1, Set2) -> Set3 when
- Set1 :: set(),
- Set2 :: set(),
- Set3 :: set().
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Set3 :: set(Element).
subtract(S1, S2) ->
filter(fun (E) -> not is_element(E, S2) end, S1).
@@ -235,34 +233,34 @@ subtract(S1, S2) ->
%% Return 'true' when every element of Set1 is also a member of
%% Set2, else 'false'.
-spec is_subset(Set1, Set2) -> boolean() when
- Set1 :: set(),
- Set2 :: set().
+ Set1 :: set(Element),
+ Set2 :: set(Element).
is_subset(S1, S2) ->
fold(fun (E, Sub) -> Sub andalso is_element(E, S2) end, true, S1).
%% fold(Fun, Accumulator, Set) -> Accumulator.
%% Fold function Fun over all elements in Set and return Accumulator.
-spec fold(Function, Acc0, Set) -> Acc1 when
- Function :: fun((E :: term(),AccIn) -> AccOut),
- Set :: set(),
- Acc0 :: T,
- Acc1 :: T,
- AccIn :: T,
- AccOut :: T.
+ Function :: fun((Element, AccIn) -> AccOut),
+ Set :: set(Element),
+ Acc0 :: Acc,
+ Acc1 :: Acc,
+ AccIn :: Acc,
+ AccOut :: Acc.
fold(F, Acc, D) -> fold_set(F, Acc, D).
%% filter(Fun, Set) -> Set.
%% Filter Set with Fun.
-spec filter(Pred, Set1) -> Set2 when
- Pred :: fun((E :: term()) -> boolean()),
- Set1 :: set(),
- Set2 :: set().
+ Pred :: fun((Element) -> boolean()),
+ Set1 :: set(Element),
+ Set2 :: set(Element).
filter(F, D) -> filter_set(F, D).
%% get_slot(Hashdb, Key) -> Slot.
%% Get the slot. First hash on the new range, if we hit a bucket
%% which has not been split use the unsplit buddy bucket.
--spec get_slot(set(), term()) -> non_neg_integer().
+-spec get_slot(set(E), E) -> non_neg_integer().
get_slot(T, Key) ->
H = erlang:phash(Key, T#set.maxn),
if
@@ -276,8 +274,8 @@ get_bucket(T, Slot) -> get_bucket_s(T#set.segs, Slot).
%% on_bucket(Fun, Hashdb, Slot) -> {NewHashDb,Result}.
%% Apply Fun to the bucket in Slot and replace the returned bucket.
--spec on_bucket(fun((_) -> {[_], 0 | 1}), set(), non_neg_integer()) ->
- {set(), 0 | 1}.
+-spec on_bucket(fun((_) -> {[_], 0 | 1}), set(E), non_neg_integer()) ->
+ {set(E), 0 | 1}.
on_bucket(F, T, Slot) ->
SegI = ((Slot-1) div ?seg_size) + 1,
BktI = ((Slot-1) rem ?seg_size) + 1,
@@ -351,7 +349,7 @@ put_bucket_s(Segs, Slot, Bkt) ->
Seg = setelement(BktI, element(SegI, Segs), Bkt),
setelement(SegI, Segs, Seg).
--spec maybe_expand(set(), 0 | 1) -> set().
+-spec maybe_expand(set(E), 0 | 1) -> set(E).
maybe_expand(T0, Ic) when T0#set.size + Ic > T0#set.exp_size ->
T = maybe_expand_segs(T0), %Do we need more segments.
N = T#set.n + 1, %Next slot to expand into
@@ -369,14 +367,14 @@ maybe_expand(T0, Ic) when T0#set.size + Ic > T0#set.exp_size ->
segs = Segs2};
maybe_expand(T, Ic) -> T#set{size = T#set.size + Ic}.
--spec maybe_expand_segs(set()) -> set().
+-spec maybe_expand_segs(set(E)) -> set(E).
maybe_expand_segs(T) when T#set.n =:= T#set.maxn ->
T#set{maxn = 2 * T#set.maxn,
bso = 2 * T#set.bso,
segs = expand_segs(T#set.segs, T#set.empty)};
maybe_expand_segs(T) -> T.
--spec maybe_contract(set(), non_neg_integer()) -> set().
+-spec maybe_contract(set(E), non_neg_integer()) -> set(E).
maybe_contract(T, Dc) when T#set.size - Dc < T#set.con_size,
T#set.n > ?seg_size ->
N = T#set.n,
@@ -395,7 +393,7 @@ maybe_contract(T, Dc) when T#set.size - Dc < T#set.con_size,
segs = Segs2});
maybe_contract(T, Dc) -> T#set{size = T#set.size - Dc}.
--spec maybe_contract_segs(set()) -> set().
+-spec maybe_contract_segs(set(E)) -> set(E).
maybe_contract_segs(T) when T#set.n =:= T#set.bso ->
T#set{maxn = T#set.maxn div 2,
bso = T#set.bso div 2,
@@ -422,7 +420,7 @@ mk_seg(16) -> {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}.
%% of segments. We special case the powers of 2 upto 32, this should
%% catch most case. N.B. the last element in the segments tuple is
%% an extra element containing a default empty segment.
--spec expand_segs(segs(), seg()) -> segs().
+-spec expand_segs(segs(E), seg()) -> segs(E).
expand_segs({B1}, Empty) ->
{B1,Empty};
expand_segs({B1,B2}, Empty) ->
@@ -440,7 +438,7 @@ expand_segs(Segs, Empty) ->
list_to_tuple(tuple_to_list(Segs)
++ lists:duplicate(tuple_size(Segs), Empty)).
--spec contract_segs(segs()) -> segs().
+-spec contract_segs(segs(E)) -> segs(E).
contract_segs({B1,_}) ->
{B1};
contract_segs({B1,B2,_,_}) ->
diff --git a/lib/stdlib/src/sofs.erl b/lib/stdlib/src/sofs.erl
index 34eb224647..0bd67db100 100644
--- a/lib/stdlib/src/sofs.erl
+++ b/lib/stdlib/src/sofs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1509,7 +1509,7 @@ family_projection(SetFun, F) when ?IS_SET(F) ->
%%%
-spec(family_to_digraph(Family) -> Graph when
- Graph :: digraph(),
+ Graph :: digraph:graph(),
Family :: family()).
family_to_digraph(F) when ?IS_SET(F) ->
case ?TYPE(F) of
@@ -1519,7 +1519,7 @@ family_to_digraph(F) when ?IS_SET(F) ->
end.
-spec(family_to_digraph(Family, GraphType) -> Graph when
- Graph :: digraph(),
+ Graph :: digraph:graph(),
Family :: family(),
GraphType :: [digraph:d_type()]).
family_to_digraph(F, Type) when ?IS_SET(F) ->
@@ -1541,7 +1541,7 @@ family_to_digraph(F, Type) when ?IS_SET(F) ->
end.
-spec(digraph_to_family(Graph) -> Family when
- Graph :: digraph(),
+ Graph :: digraph:graph(),
Family :: family()).
digraph_to_family(G) ->
case catch digraph_family(G) of
@@ -1550,7 +1550,7 @@ digraph_to_family(G) ->
end.
-spec(digraph_to_family(Graph, Type) -> Family when
- Graph :: digraph(),
+ Graph :: digraph:graph(),
Family :: family(),
Type :: type()).
digraph_to_family(G, T) ->
diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src
index 749a9a4201..22eefb2514 100644
--- a/lib/stdlib/src/stdlib.appup.src
+++ b/lib/stdlib/src/stdlib.appup.src
@@ -1,7 +1,7 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -16,12 +16,10 @@
%%
%% %CopyrightEnd%
{"%VSN%",
- %% Up from - max two major revisions back
+ %% Up from - max one major revision back
[{<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R16
- {<<"1\\.18(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R15
- %% Down to - max two major revisions back
+ {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16
+ %% Down to - max one major revision back
[{<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R16
- {<<"1\\.18(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R15
+ {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16
}.
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index d18387568d..ede2742875 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -45,10 +45,13 @@
-type restart() :: 'permanent' | 'transient' | 'temporary'.
-type shutdown() :: 'brutal_kill' | timeout().
-type worker() :: 'worker' | 'supervisor'.
--type sup_name() :: {'local', Name :: atom()} | {'global', Name :: atom()}.
+-type sup_name() :: {'local', Name :: atom()}
+ | {'global', Name :: atom()}
+ | {'via', Module :: module(), Name :: any()}.
-type sup_ref() :: (Name :: atom())
| {Name :: atom(), Node :: node()}
| {'global', Name :: atom()}
+ | {'via', Module :: module(), Name :: any()}
| pid().
-type child_spec() :: {Id :: child_id(),
StartFunc :: mfargs(),
@@ -74,14 +77,15 @@
modules = [] :: modules()}).
-type child_rec() :: #child{}.
--define(DICT, dict).
+-define(DICTS, dict).
+-define(DICT, dict:dict).
-define(SETS, sets).
--define(SET, set).
+-define(SET, sets:set).
-record(state, {name,
strategy :: strategy(),
children = [] :: [child_rec()],
- dynamics :: ?DICT() | ?SET(),
+ dynamics :: ?DICT(pid(), list()) | ?SET(pid()),
intensity :: non_neg_integer(),
period :: pos_integer(),
restarts = [],
@@ -441,7 +445,7 @@ handle_call(which_children, _From, #state{children = [#child{restart_type = RTyp
State) when ?is_simple(State) ->
Reply = lists:map(fun({?restarting(_),_}) -> {undefined,restarting,CT,Mods};
({Pid, _}) -> {undefined, Pid, CT, Mods} end,
- ?DICT:to_list(dynamics_db(RType, State#state.dynamics))),
+ ?DICTS:to_list(dynamics_db(RType, State#state.dynamics))),
{reply, Reply, State};
handle_call(which_children, _From, State) ->
@@ -480,7 +484,7 @@ handle_call(count_children, _From, #state{children = [#child{restart_type = RTy
child_type = CT}]} = State)
when ?is_simple(State) ->
{Active, Count} =
- ?DICT:fold(fun(Pid, _Val, {Alive, Tot}) ->
+ ?DICTS:fold(fun(Pid, _Val, {Alive, Tot}) ->
case is_pid(Pid) andalso is_process_alive(Pid) of
true ->
{Alive+1, Tot +1};
@@ -774,17 +778,17 @@ restart(Child, State) ->
restart(simple_one_for_one, Child, State) ->
#child{pid = OldPid, mfargs = {M, F, A}} = Child,
- Dynamics = ?DICT:erase(OldPid, dynamics_db(Child#child.restart_type,
+ Dynamics = ?DICTS:erase(OldPid, dynamics_db(Child#child.restart_type,
State#state.dynamics)),
case do_start_child_i(M, F, A) of
{ok, Pid} ->
- NState = State#state{dynamics = ?DICT:store(Pid, A, Dynamics)},
+ NState = State#state{dynamics = ?DICTS:store(Pid, A, Dynamics)},
{ok, NState};
{ok, Pid, _Extra} ->
- NState = State#state{dynamics = ?DICT:store(Pid, A, Dynamics)},
+ NState = State#state{dynamics = ?DICTS:store(Pid, A, Dynamics)},
{ok, NState};
{error, Error} ->
- NState = State#state{dynamics = ?DICT:store(restarting(OldPid), A,
+ NState = State#state{dynamics = ?DICTS:store(restarting(OldPid), A,
Dynamics)},
report_error(start_error, Error, Child, State#state.name),
{try_again, NState}
@@ -977,7 +981,7 @@ terminate_dynamic_children(Child, Dynamics, SupName) ->
wait_dynamic_children(Child, Pids, Sz, TRef, EStack0)
end,
%% Unroll stacked errors and report them
- ?DICT:fold(fun(Reason, Ls, _) ->
+ ?DICTS:fold(fun(Reason, Ls, _) ->
report_error(shutdown_error, Reason,
Child#child{pid=Ls}, SupName)
end, ok, EStack).
@@ -991,22 +995,22 @@ monitor_dynamic_children(#child{restart_type=temporary}, Dynamics) ->
{error, normal} ->
{Pids, EStack};
{error, Reason} ->
- {Pids, ?DICT:append(Reason, P, EStack)}
+ {Pids, ?DICTS:append(Reason, P, EStack)}
end
- end, {?SETS:new(), ?DICT:new()}, Dynamics);
+ end, {?SETS:new(), ?DICTS:new()}, Dynamics);
monitor_dynamic_children(#child{restart_type=RType}, Dynamics) ->
- ?DICT:fold(fun(P, _, {Pids, EStack}) when is_pid(P) ->
+ ?DICTS:fold(fun(P, _, {Pids, EStack}) when is_pid(P) ->
case monitor_child(P) of
ok ->
{?SETS:add_element(P, Pids), EStack};
{error, normal} when RType =/= permanent ->
{Pids, EStack};
{error, Reason} ->
- {Pids, ?DICT:append(Reason, P, EStack)}
+ {Pids, ?DICTS:append(Reason, P, EStack)}
end;
(?restarting(_), _, {Pids, EStack}) ->
{Pids, EStack}
- end, {?SETS:new(), ?DICT:new()}, Dynamics).
+ end, {?SETS:new(), ?DICTS:new()}, Dynamics).
wait_dynamic_children(_Child, _Pids, 0, undefined, EStack) ->
@@ -1030,7 +1034,7 @@ wait_dynamic_children(#child{shutdown=brutal_kill} = Child, Pids, Sz,
{'DOWN', _MRef, process, Pid, Reason} ->
wait_dynamic_children(Child, ?SETS:del_element(Pid, Pids), Sz-1,
- TRef, ?DICT:append(Reason, Pid, EStack))
+ TRef, ?DICTS:append(Reason, Pid, EStack))
end;
wait_dynamic_children(#child{restart_type=RType} = Child, Pids, Sz,
TRef, EStack) ->
@@ -1045,7 +1049,7 @@ wait_dynamic_children(#child{restart_type=RType} = Child, Pids, Sz,
{'DOWN', _MRef, process, Pid, Reason} ->
wait_dynamic_children(Child, ?SETS:del_element(Pid, Pids), Sz-1,
- TRef, ?DICT:append(Reason, Pid, EStack));
+ TRef, ?DICTS:append(Reason, Pid, EStack));
{timeout, TRef, kill} ->
?SETS:fold(fun(P, _) -> exit(P, kill) end, ok, Pids),
@@ -1070,12 +1074,12 @@ save_child(Child, #state{children = Children} = State) ->
save_dynamic_child(temporary, Pid, _, #state{dynamics = Dynamics} = State) ->
State#state{dynamics = ?SETS:add_element(Pid, dynamics_db(temporary, Dynamics))};
save_dynamic_child(RestartType, Pid, Args, #state{dynamics = Dynamics} = State) ->
- State#state{dynamics = ?DICT:store(Pid, Args, dynamics_db(RestartType, Dynamics))}.
+ State#state{dynamics = ?DICTS:store(Pid, Args, dynamics_db(RestartType, Dynamics))}.
dynamics_db(temporary, undefined) ->
?SETS:new();
dynamics_db(_, undefined) ->
- ?DICT:new();
+ ?DICTS:new();
dynamics_db(_,Dynamics) ->
Dynamics.
@@ -1084,14 +1088,14 @@ dynamic_child_args(Pid, Dynamics) ->
true ->
{ok, undefined};
false ->
- ?DICT:find(Pid, Dynamics)
+ ?DICTS:find(Pid, Dynamics)
end.
state_del_child(#child{pid = Pid, restart_type = temporary}, State) when ?is_simple(State) ->
NDynamics = ?SETS:del_element(Pid, dynamics_db(temporary, State#state.dynamics)),
State#state{dynamics = NDynamics};
state_del_child(#child{pid = Pid, restart_type = RType}, State) when ?is_simple(State) ->
- NDynamics = ?DICT:erase(Pid, dynamics_db(RType, State#state.dynamics)),
+ NDynamics = ?DICTS:erase(Pid, dynamics_db(RType, State#state.dynamics)),
State#state{dynamics = NDynamics};
state_del_child(Child, State) ->
NChildren = del_child(Child#child.name, State#state.children),
@@ -1154,7 +1158,7 @@ is_dynamic_pid(Pid, Dynamics) ->
true ->
?SETS:is_element(Pid, Dynamics);
false ->
- ?DICT:is_key(Pid, Dynamics)
+ ?DICTS:is_key(Pid, Dynamics)
end.
replace_child(Child, State) ->
diff --git a/lib/stdlib/src/supervisor_bridge.erl b/lib/stdlib/src/supervisor_bridge.erl
index e8405ab9a4..ff4502f0b9 100644
--- a/lib/stdlib/src/supervisor_bridge.erl
+++ b/lib/stdlib/src/supervisor_bridge.erl
@@ -101,7 +101,16 @@ handle_cast(_, State) ->
{noreply, State}.
handle_info({'EXIT', Pid, Reason}, State) when State#state.pid =:= Pid ->
- report_error(child_terminated, Reason, State),
+ case Reason of
+ normal ->
+ ok;
+ shutdown ->
+ ok;
+ {shutdown, _Term} ->
+ ok;
+ _ ->
+ report_error(child_terminated, Reason, State)
+ end,
{stop, Reason, State#state{pid = undefined}};
handle_info(_, State) ->
{noreply, State}.
diff --git a/lib/stdlib/test/edlin_expand_SUITE.erl b/lib/stdlib/test/edlin_expand_SUITE.erl
index 2c1c5acf5a..43c980e994 100644
--- a/lib/stdlib/test/edlin_expand_SUITE.erl
+++ b/lib/stdlib/test/edlin_expand_SUITE.erl
@@ -26,11 +26,11 @@
-include_lib("test_server/include/test_server.hrl").
-% Default timetrap timeout (set in init_per_testcase).
+%% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
init_per_testcase(_Case, Config) ->
- ?line Dog = ?t:timetrap(?default_timeout),
+ Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
@@ -67,23 +67,21 @@ normal(doc) ->
normal(suite) ->
[];
normal(Config) when is_list(Config) ->
- ?line {module,expand_test} = c:l(expand_test),
- % These tests might fail if another module with the prefix "expand_" happens
- % to also be loaded.
- ?line {yes, "test:", []} = edlin_expand:expand(lists:reverse("expand_")),
- ?line {no, [], []} = edlin_expand:expand(lists:reverse("expandXX_")),
- ?line {no,[],
- [{"a_fun_name",1},
- {"a_less_fun_name",1},
- {"b_comes_after_a",1},
- {"expand0arity_entirely",0},
- {"module_info",0},
- {"module_info",1}]} = edlin_expand:expand(lists:reverse("expand_test:")),
- ?line {yes,[],[{"a_fun_name",1},
- {"a_less_fun_name",1}]} = edlin_expand:expand(
- lists:reverse("expand_test:a_")),
- ?line {yes,"arity_entirely()",[]} = edlin_expand:expand(
- lists:reverse("expand_test:expand0")),
+ {module,expand_test} = c:l(expand_test),
+ %% These tests might fail if another module with the prefix
+ %% "expand_" happens to also be loaded.
+ {yes, "test:", []} = do_expand("expand_"),
+ {no, [], []} = do_expand("expandXX_"),
+ {no,[],
+ [{"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"expand0arity_entirely",0},
+ {"module_info",0},
+ {"module_info",1}]} = do_expand("expand_test:"),
+ {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = do_expand("expand_test:a_"),
+ {yes,"arity_entirely()",[]} = do_expand("expand_test:expand0"),
ok.
quoted_fun(doc) ->
@@ -91,38 +89,35 @@ quoted_fun(doc) ->
quoted_fun(suite) ->
[];
quoted_fun(Config) when is_list(Config) ->
- ?line {module,expand_test} = c:l(expand_test),
- ?line {module,expand_test1} = c:l(expand_test1),
+ {module,expand_test} = c:l(expand_test),
+ {module,expand_test1} = c:l(expand_test1),
%% should be no colon after test this time
- ?line {yes, "test", []} = edlin_expand:expand(lists:reverse("expand_")),
- ?line {no, [], []} = edlin_expand:expand(lists:reverse("expandXX_")),
- ?line {no,[],[{"'#weird-fun-name'",1},
- {"'Quoted_fun_name'",0},
- {"'Quoted_fun_too'",0},
- {"a_fun_name",1},
- {"a_less_fun_name",1},
- {"b_comes_after_a",1},
- {"module_info",0},
- {"module_info",1}]} = edlin_expand:expand(
- lists:reverse("expand_test1:")),
- ?line {yes,"_",[]} = edlin_expand:expand(
- lists:reverse("expand_test1:a")),
- ?line {yes,[],[{"a_fun_name",1},
- {"a_less_fun_name",1}]} = edlin_expand:expand(
- lists:reverse("expand_test1:a_")),
- ?line {yes,[],
- [{"'#weird-fun-name'",1},
+ {yes, "test", []} = do_expand("expand_"),
+ {no, [], []} = do_expand("expandXX_"),
+ {no,[],[{"'#weird-fun-name'",1},
{"'Quoted_fun_name'",0},
- {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
- lists:reverse("expand_test1:'")),
- ?line {yes,"uoted_fun_",[]} = edlin_expand:expand(
- lists:reverse("expand_test1:'Q")),
- ?line {yes,[],
- [{"'Quoted_fun_name'",0},
- {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
- lists:reverse("expand_test1:'Quoted_fun_")),
- ?line {yes,"weird-fun-name'(",[]} = edlin_expand:expand(
- lists:reverse("expand_test1:'#")),
+ {"'Quoted_fun_too'",0},
+ {"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = do_expand("expand_test1:"),
+ {yes,"_",[]} = do_expand("expand_test1:a"),
+ {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = do_expand("expand_test1:a_"),
+ {yes,[],
+ [{"'#weird-fun-name'",1},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = do_expand("expand_test1:'"),
+ {yes,"uoted_fun_",[]} = do_expand("expand_test1:'Q"),
+ {yes,[],
+ [{"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = do_expand("expand_test1:'Quoted_fun_"),
+ {yes,"weird-fun-name'(",[]} = do_expand("expand_test1:'#"),
+
+ %% Since there is a module_info/1 as well as a module_info/0
+ %% there should not be a closing parenthesis added.
+ {yes,"(",[]} = do_expand("expand_test:module_info"),
ok.
quoted_module(doc) ->
@@ -130,51 +125,46 @@ quoted_module(doc) ->
quoted_module(suite) ->
[];
quoted_module(Config) when is_list(Config) ->
- ?line {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'),
- ?line {yes, "Caps':", []} = edlin_expand:expand(lists:reverse("'ExpandTest")),
- ?line {no,[],
- [{"a_fun_name",1},
- {"a_less_fun_name",1},
- {"b_comes_after_a",1},
- {"module_info",0},
- {"module_info",1}]} = edlin_expand:expand(lists:reverse("'ExpandTestCaps':")),
- ?line {yes,[],[{"a_fun_name",1},
- {"a_less_fun_name",1}]} = edlin_expand:expand(
- lists:reverse("'ExpandTestCaps':a_")),
+ {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'),
+ {yes, "Caps':", []} = do_expand("'ExpandTest"),
+ {no,[],
+ [{"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = do_expand("'ExpandTestCaps':"),
+ {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = do_expand("'ExpandTestCaps':a_"),
ok.
quoted_both(suite) ->
[];
quoted_both(Config) when is_list(Config) ->
- ?line {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'),
- ?line {module,'ExpandTestCaps1'} = c:l('ExpandTestCaps1'),
+ {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'),
+ {module,'ExpandTestCaps1'} = c:l('ExpandTestCaps1'),
%% should be no colon (or quote) after test this time
- ?line {yes, "Caps", []} = edlin_expand:expand(lists:reverse("'ExpandTest")),
- ?line {no,[],[{"'#weird-fun-name'",0},
- {"'Quoted_fun_name'",0},
- {"'Quoted_fun_too'",0},
- {"a_fun_name",1},
- {"a_less_fun_name",1},
- {"b_comes_after_a",1},
- {"module_info",0},
- {"module_info",1}]} = edlin_expand:expand(
- lists:reverse("'ExpandTestCaps1':")),
- ?line {yes,"_",[]} = edlin_expand:expand(
- lists:reverse("'ExpandTestCaps1':a")),
- ?line {yes,[],[{"a_fun_name",1},
- {"a_less_fun_name",1}]} = edlin_expand:expand(
- lists:reverse("'ExpandTestCaps1':a_")),
- ?line {yes,[],
- [{"'#weird-fun-name'",0},
+ {yes, "Caps", []} = do_expand("'ExpandTest"),
+ {no,[],[{"'#weird-fun-name'",0},
{"'Quoted_fun_name'",0},
- {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
- lists:reverse("'ExpandTestCaps1':'")),
- ?line {yes,"uoted_fun_",[]} = edlin_expand:expand(
- lists:reverse("'ExpandTestCaps1':'Q")),
- ?line {yes,[],
- [{"'Quoted_fun_name'",0},
- {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
- lists:reverse("'ExpandTestCaps1':'Quoted_fun_")),
- ?line {yes,"weird-fun-name'()",[]} = edlin_expand:expand(
- lists:reverse("'ExpandTestCaps1':'#")),
+ {"'Quoted_fun_too'",0},
+ {"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = do_expand("'ExpandTestCaps1':"),
+ {yes,"_",[]} = do_expand("'ExpandTestCaps1':a"),
+ {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = do_expand("'ExpandTestCaps1':a_"),
+ {yes,[],
+ [{"'#weird-fun-name'",0},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = do_expand("'ExpandTestCaps1':'"),
+ {yes,"uoted_fun_",[]} = do_expand("'ExpandTestCaps1':'Q"),
+ {yes,[],
+ [{"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = do_expand("'ExpandTestCaps1':'Quoted_fun_"),
+ {yes,"weird-fun-name'()",[]} = do_expand("'ExpandTestCaps1':'#"),
ok.
+
+do_expand(String) ->
+ edlin_expand:expand(lists:reverse(String)).
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index 0cbdf76270..0b4726c07a 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,8 @@
variable_1/1, otp_4870/1, otp_4871/1, otp_5362/1,
pmod/1, not_circular/1, skip_header/1, otp_6277/1, otp_7702/1,
otp_8130/1, overload_mac/1, otp_8388/1, otp_8470/1, otp_8503/1,
- otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1]).
+ otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1,
+ otp_11728/1]).
-export([epp_parse_erl_form/2]).
@@ -67,7 +68,7 @@ all() ->
{group, variable}, otp_4870, otp_4871, otp_5362, pmod,
not_circular, skip_header, otp_6277, otp_7702, otp_8130,
overload_mac, otp_8388, otp_8470, otp_8503, otp_8562,
- otp_8665, otp_8911, otp_10302, otp_10820].
+ otp_8665, otp_8911, otp_10302, otp_10820, otp_11728].
groups() ->
[{upcase_mac, [], [upcase_mac_1, upcase_mac_2]},
@@ -1387,6 +1388,31 @@ do_otp_10820(File, C, PC) ->
true = test_server:stop_node(Node),
ok.
+otp_11728(doc) ->
+ ["OTP-11728. Bugfix circular macro."];
+otp_11728(suite) ->
+ [];
+otp_11728(Config) when is_list(Config) ->
+ Dir = ?config(priv_dir, Config),
+ H = <<"-define(MACRO,[[]++?MACRO]).">>,
+ HrlFile = filename:join(Dir, "otp_11728.hrl"),
+ ok = file:write_file(HrlFile, H),
+ C = <<"-module(otp_11728).
+ -compile(export_all).
+
+ -include(\"otp_11728.hrl\").
+
+ function_name()->
+ A=?MACRO, % line 7
+ ok">>,
+ ErlFile = filename:join(Dir, "otp_11728.erl"),
+ ok = file:write_file(ErlFile, C),
+ {ok, L} = epp:parse_file(ErlFile, [Dir], []),
+ true = lists:member({error,{7,epp,{circular,'MACRO',none}}}, L),
+ _ = file:delete(HrlFile),
+ _ = file:delete(ErlFile),
+ ok.
+
check(Config, Tests) ->
eval_tests(Config, fun check_test/2, Tests).
diff --git a/lib/stdlib/test/erl_eval_SUITE.erl b/lib/stdlib/test/erl_eval_SUITE.erl
index b194c7cb41..e6512b7d71 100644
--- a/lib/stdlib/test/erl_eval_SUITE.erl
+++ b/lib/stdlib/test/erl_eval_SUITE.erl
@@ -25,7 +25,7 @@
match_bin/1,
string_plusplus/1,
pattern_expr/1,
- guard_3/1, guard_4/1,
+ guard_3/1, guard_4/1, guard_5/1,
lc/1,
simple_cases/1,
unary_plus/1,
@@ -79,7 +79,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[guard_1, guard_2, match_pattern, string_plusplus,
- pattern_expr, match_bin, guard_3, guard_4, lc,
+ pattern_expr, match_bin, guard_3, guard_4, guard_5, lc,
simple_cases, unary_plus, apply_atom, otp_5269,
otp_6539, otp_6543, otp_6787, otp_6977, otp_7550,
otp_8133, otp_10622, funs, try_catch, eval_expr_5, zero_width,
@@ -248,6 +248,20 @@ guard_4(Config) when is_list(Config) ->
false),
ok.
+guard_5(doc) ->
+ ["Guards with erlang:'=='/2"];
+guard_5(suite) ->
+ [];
+guard_5(Config) when is_list(Config) ->
+ {ok,Tokens ,_} =
+ erl_scan:string("case 1 of A when erlang:'=='(A, 1) -> true end."),
+ {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
+ true = guard_5_compiled(),
+ {value, true, [{'A',1}]} = erl_eval:expr(Expr, []),
+ ok.
+
+guard_5_compiled() ->
+ case 1 of A when erlang:'=='(A, 1) -> true end.
lc(doc) ->
["OTP-4518."];
diff --git a/lib/stdlib/test/erl_expand_records_SUITE.erl b/lib/stdlib/test/erl_expand_records_SUITE.erl
index 94b4397a9c..43e679f7ed 100644
--- a/lib/stdlib/test/erl_expand_records_SUITE.erl
+++ b/lib/stdlib/test/erl_expand_records_SUITE.erl
@@ -38,7 +38,7 @@
-export([attributes/1, expr/1, guard/1,
init/1, pattern/1, strict/1, update/1,
otp_5915/1, otp_7931/1, otp_5990/1,
- otp_7078/1, otp_7101/1]).
+ otp_7078/1, otp_7101/1, maps/1]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -56,7 +56,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[attributes, expr, guard, init,
- pattern, strict, update, {group, tickets}].
+ pattern, strict, update, maps, {group, tickets}].
groups() ->
[{tickets, [],
@@ -402,7 +402,22 @@ update(Config) when is_list(Config) ->
],
?line run(Config, Ts),
ok.
-
+
+maps(Config) when is_list(Config) ->
+ Ts = [<<"-record(rr, {a,b,c}).
+ t() ->
+ R0 = id(#rr{a=1,b=2,c=3}),
+ R1 = id(#rr{a=4,b=5,c=6}),
+ [{R0,R1}] =
+ maps:to_list(#{#rr{a=1,b=2,c=3} => #rr{a=4,b=5,c=6}}),
+ #{#rr{a=1,b=2,c=3} := #rr{a=1,b=2,c=3}} =
+ #{#rr{a=1,b=2,c=3} => R1}#{#rr{a=1,b=2,c=3} := R0},
+ ok.
+
+ id(X) -> X.
+ ">>],
+ run(Config, Ts, [strict_record_tests]),
+ ok.
otp_5915(doc) ->
"Strict record tests in guards.";
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 48f50d5f43..1614a2722f 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -60,7 +60,8 @@
format_warn/1,
on_load_successful/1, on_load_failing/1,
too_many_arguments/1,
- basic_errors/1,bin_syntax_errors/1
+ basic_errors/1,bin_syntax_errors/1,
+ predef/1
]).
% Default timetrap timeout (set in init_per_testcase).
@@ -87,7 +88,7 @@ all() ->
otp_5878, otp_5917, otp_6585, otp_6885, otp_10436, otp_11254,export_all,
bif_clash, behaviour_basic, behaviour_multiple,
otp_7550, otp_8051, format_warn, {group, on_load},
- too_many_arguments, basic_errors, bin_syntax_errors].
+ too_many_arguments, basic_errors, bin_syntax_errors, predef].
groups() ->
[{unused_vars_warn, [],
@@ -3241,6 +3242,23 @@ bin_syntax_errors(Config) ->
[] = run(Config, Ts),
ok.
+predef(doc) ->
+ "Predefined types: array(), digraph(), and so on";
+predef(suite) -> [];
+predef(Config) when is_list(Config) ->
+ W = get_compilation_warnings(Config, "predef", []),
+ [] = W,
+ W2 = get_compilation_warnings(Config, "predef2", []),
+ [{7,erl_lint,{deprecated_type,{array,0},{array,array},"OTP 18.0"}},
+ {12,erl_lint,{deprecated_type,{dict,0},{dict,dict},"OTP 18.0"}},
+ {17,erl_lint,{deprecated_type,{digraph,0},{digraph,graph},"OTP 18.0"}},
+ {27,erl_lint,{deprecated_type,{gb_set,0},{gb_sets,set},"OTP 18.0"}},
+ {32,erl_lint,{deprecated_type,{gb_tree,0},{gb_trees,tree},"OTP 18.0"}},
+ {37,erl_lint,{deprecated_type,{queue,0},{queue,queue},"OTP 18.0"}},
+ {42,erl_lint,{deprecated_type,{set,0},{sets,set},"OTP 18.0"}},
+ {47,erl_lint,{deprecated_type,{tid,0},{ets,tid},"OTP 18.0"}}] = W2,
+ ok.
+
run(Config, Tests) ->
F = fun({N,P,Ws,E}, BadL) ->
case catch run_test(Config, P, Ws) of
@@ -3263,8 +3281,10 @@ get_compilation_warnings(Conf, Filename, Warnings) ->
FileS = binary_to_list(Bin),
{match,[{Start,Length}|_]} = re:run(FileS, "-module.*\\n"),
Test = lists:nthtail(Start+Length, FileS),
- {warnings, Ws} = run_test(Conf, Test, Warnings),
- Ws.
+ case run_test(Conf, Test, Warnings) of
+ {warnings, Ws} -> Ws;
+ [] -> []
+ end.
%% Compiles a test module and returns the list of errors and warnings.
diff --git a/lib/stdlib/test/erl_lint_SUITE_data/predef.erl b/lib/stdlib/test/erl_lint_SUITE_data/predef.erl
new file mode 100644
index 0000000000..c2364fd1c2
--- /dev/null
+++ b/lib/stdlib/test/erl_lint_SUITE_data/predef.erl
@@ -0,0 +1,67 @@
+-module(predef).
+
+-export([array/1, dict/1, digraph/1, digraph2/1, gb_set/1, gb_tree/1,
+ queue/1, set/1, tid/0, tid2/0]).
+
+-export_type([array/0, digraph/0, gb_set/0]).
+
+%% Before R17B local re-definitions of pre-defined opaque types were
+%% ignored but did not generate any warning.
+-opaque array() :: atom().
+-opaque digraph() :: atom().
+-opaque gb_set() :: atom().
+-type dict() :: atom().
+-type gb_tree() :: atom().
+-type queue() :: atom().
+-type set() :: atom().
+-type tid() :: atom().
+
+-spec array(array()) -> array:array().
+
+array(A) ->
+ array:relax(A).
+
+-spec dict(dict()) -> dict:dict().
+
+dict(D) ->
+ dict:store(1, a, D).
+
+-spec digraph(digraph()) -> [digraph:edge()].
+
+digraph(G) ->
+ digraph:edges(G).
+
+-spec digraph2(digraph:graph()) -> [digraph:edge()].
+
+digraph2(G) ->
+ digraph:edges(G).
+
+-spec gb_set(gb_set()) -> gb_sets:set().
+
+gb_set(S) ->
+ gb_sets:balance(S).
+
+-spec gb_tree(gb_tree()) -> gb_trees:tree().
+
+gb_tree(S) ->
+ gb_trees:balance(S).
+
+-spec queue(queue()) -> queue:queue().
+
+queue(Q) ->
+ queue:reverse(Q).
+
+-spec set(set()) -> sets:set().
+
+set(S) ->
+ sets:union([S]).
+
+-spec tid() -> tid().
+
+tid() ->
+ ets:new(tid, []).
+
+-spec tid2() -> ets:tid().
+
+tid2() ->
+ ets:new(tid, []).
diff --git a/lib/stdlib/test/erl_lint_SUITE_data/predef2.erl b/lib/stdlib/test/erl_lint_SUITE_data/predef2.erl
new file mode 100644
index 0000000000..b1d941a49a
--- /dev/null
+++ b/lib/stdlib/test/erl_lint_SUITE_data/predef2.erl
@@ -0,0 +1,56 @@
+-module(predef2).
+
+-export([array/1, dict/1, digraph/1, digraph2/1, gb_set/1, gb_tree/1,
+ queue/1, set/1, tid/0, tid2/0]).
+
+-export_type([array/0, digraph/0, gb_set/0]).
+
+-spec array(array()) -> array:array().
+
+array(A) ->
+ array:relax(A).
+
+-spec dict(dict()) -> dict:dict().
+
+dict(D) ->
+ dict:store(1, a, D).
+
+-spec digraph(digraph()) -> [digraph:edge()].
+
+digraph(G) ->
+ digraph:edges(G).
+
+-spec digraph2(digraph:graph()) -> [digraph:edge()].
+
+digraph2(G) ->
+ digraph:edges(G).
+
+-spec gb_set(gb_set()) -> gb_sets:set().
+
+gb_set(S) ->
+ gb_sets:balance(S).
+
+-spec gb_tree(gb_tree()) -> gb_trees:tree().
+
+gb_tree(S) ->
+ gb_trees:balance(S).
+
+-spec queue(queue()) -> queue:queue().
+
+queue(Q) ->
+ queue:reverse(Q).
+
+-spec set(set()) -> sets:set().
+
+set(S) ->
+ sets:union([S]).
+
+-spec tid() -> tid().
+
+tid() ->
+ ets:new(tid, []).
+
+-spec tid2() -> ets:tid().
+
+tid2() ->
+ ets:new(tid, []).
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 82c3e7ecaf..8dc8b2c291 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -75,6 +75,7 @@
-export([otp_9932/1]).
-export([otp_9423/1]).
-export([otp_10182/1]).
+-export([ets_all/1]).
-export([memory_check_summary/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -151,6 +152,7 @@ all() ->
otp_10182,
otp_9932,
otp_9423,
+ ets_all,
memory_check_summary]. % MUST BE LAST
@@ -5565,7 +5567,19 @@ otp_10182(Config) when is_list(Config) ->
ets:delete(Db),
In = Out.
-
+%% Test that ets:all include/exclude tables that we know are created/deleted
+ets_all(Config) when is_list(Config) ->
+ Pids = [spawn_link(fun() -> ets_all_run() end) || _ <- [1,2]],
+ receive after 3*1000 -> ok end,
+ [begin unlink(P), exit(P,kill) end || P <- Pids],
+ ok.
+
+ets_all_run() ->
+ Table = ets:new(undefined, []),
+ true = lists:member(Table, ets:all()),
+ ets:delete(Table),
+ false = lists:member(Table, ets:all()),
+ ets_all_run().
%
diff --git a/lib/stdlib/test/stdlib_SUITE.erl b/lib/stdlib/test/stdlib_SUITE.erl
index 8fff5e2e05..53a34511d9 100644
--- a/lib/stdlib/test/stdlib_SUITE.erl
+++ b/lib/stdlib/test/stdlib_SUITE.erl
@@ -23,10 +23,6 @@
-include_lib("test_server/include/test_server.hrl").
-% Default timetrap timeout (set in init_per_testcase).
--define(default_timeout, ?t:minutes(1)).
--define(application, stdlib).
-
% Test server specific exports
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
@@ -60,11 +56,8 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(_Case, Config) ->
- ?line Dog=test_server:timetrap(?default_timeout),
- [{watchdog, Dog}|Config].
-end_per_testcase(_Case, Config) ->
- Dog=?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
+ Config.
+end_per_testcase(_Case, _Config) ->
ok.
%
@@ -78,17 +71,18 @@ app_test(Config) when is_list(Config) ->
?t:app_test(stdlib),
ok.
-%% Test that appup allows upgrade from/downgrade to a maximum of two
-%% major releases back.
+%% Test that appup allows upgrade from/downgrade to a maximum of one
+%% major release back.
appup_test(_Config) ->
- do_appup_tests(create_test_vsns()).
+ appup_tests(stdlib,create_test_vsns(stdlib)).
-do_appup_tests({[],[]}) ->
+appup_tests(_App,{[],[]}) ->
{skip,"no previous releases available"};
-do_appup_tests({OkVsns,NokVsns}) ->
- application:load(stdlib),
- {_,_,Vsn} = lists:keyfind(stdlib,1,application:loaded_applications()),
- AppupFile = filename:join([code:lib_dir(stdlib),ebin,"stdlib.appup"]),
+appup_tests(App,{OkVsns,NokVsns}) ->
+ application:load(App),
+ {_,_,Vsn} = lists:keyfind(App,1,application:loaded_applications()),
+ AppupFileName = atom_to_list(App) ++ ".appup",
+ AppupFile = filename:join([code:lib_dir(App),ebin,AppupFileName]),
{ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile),
ct:log("~p~n",[AppupScript]),
ct:log("Testing ok versions: ~p~n",[OkVsns]),
@@ -99,13 +93,12 @@ do_appup_tests({OkVsns,NokVsns}) ->
check_appup(NokVsns,DownTo,error),
ok.
-create_test_vsns() ->
+create_test_vsns(App) ->
This = erlang:system_info(otp_release),
FirstMajor = previous_major(This),
SecondMajor = previous_major(FirstMajor),
- ThirdMajor = previous_major(SecondMajor),
- Ok = stdlib_vsn([FirstMajor,SecondMajor]),
- Nok0 = stdlib_vsn([ThirdMajor]),
+ Ok = app_vsn(App,[FirstMajor]),
+ Nok0 = app_vsn(App,[SecondMajor]),
Nok = case Ok of
[Ok1|_] ->
[Ok1 ++ ",1" | Nok0]; % illegal
@@ -121,18 +114,36 @@ previous_major("r"++Rel) ->
previous_major(Rel) ->
integer_to_list(list_to_integer(Rel)-1).
-stdlib_vsn([R|Rs]) ->
- case test_server:is_release_available(R) of
- true ->
- {ok,N} = test_server:start_node(prevrel,peer,[{erl,[{release,R}]}]),
- As = rpc:call(N,application,which_applications,[]),
- {_,_,KV} = lists:keyfind(stdlib,1,As),
- test_server:stop_node(N),
- [KV|stdlib_vsn(Rs)];
+app_vsn(App,[R|Rs]) ->
+ OldRel =
+ case test_server:is_release_available(R) of
+ true ->
+ {release,R};
+ false ->
+ case ct:get_config({otp_releases,list_to_atom(R)}) of
+ undefined ->
+ false;
+ Prog0 ->
+ case os:find_executable(Prog0) of
+ false ->
+ false;
+ Prog ->
+ {prog,Prog}
+ end
+ end
+ end,
+ case OldRel of
false ->
- stdlib_vsn(Rs)
+ app_vsn(App,Rs);
+ _ ->
+ {ok,N} = test_server:start_node(prevrel,peer,[{erl,[OldRel]}]),
+ _ = rpc:call(N,application,load,[App]),
+ As = rpc:call(N,application,loaded_applications,[]),
+ {_,_,V} = lists:keyfind(App,1,As),
+ test_server:stop_node(N),
+ [V|app_vsn(App,Rs)]
end;
-stdlib_vsn([]) ->
+app_vsn(_App,[]) ->
[].
check_appup([Vsn|Vsns],Instrs,Expected) ->