File 4331-EEP-61-Built-in-dynamic-type.patch of Package erlang

From 048e62b9041d84958f1e089b4ae3d4666004269e Mon Sep 17 00:00:00 2001
From: Ilya Klyuchnikov <ilya.klyuchnikov@gmail.com>
Date: Mon, 6 Mar 2023 23:10:06 +0000
Subject: [PATCH] EEP 61: Built-in dynamic type

---
 erts/preloaded/src/erlang.erl            |  3 ++-
 lib/dialyzer/src/erl_types.erl           |  3 +++
 lib/stdlib/src/erl_internal.erl          |  1 +
 system/doc/reference_manual/typespec.xml | 17 ++++++++++++++++-
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 923b0ad806..ddb81dfc76 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -86,6 +86,7 @@
 -type boolean() :: true | false.
 -type byte() :: 0..255.
 -type char() :: 0..16#10FFFF.
+-type dynamic() :: dynamic().
 -type float() :: float().
 -type function() :: fun().
 -type identifier() :: pid() | port() | reference().
@@ -123,7 +124,7 @@
 -type timeout() :: 'infinity' | non_neg_integer().
 -type tuple() :: tuple().
 -export_type([any/0, arity/0, atom/0, binary/0, bitstring/0, bool/0, boolean/0, byte/0,
-              char/0, float/0, function/0, identifier/0, integer/0, iodata/0, iolist/0,
+              char/0, dynamic/0, float/0, function/0, identifier/0, integer/0, iodata/0, iolist/0,
               list/0, list/1, map/0, maybe_improper_list/0, maybe_improper_list/2, mfa/0,
               module/0, neg_integer/0, nil/0, no_return/0, node/0, non_neg_integer/0,
               none/0, nonempty_binary/0, nonempty_bitstring/0, nonempty_improper_list/2,
diff --git a/lib/dialyzer/src/erl_types.erl b/lib/dialyzer/src/erl_types.erl
index 9943996882..8068baf8e8 100644
--- a/lib/dialyzer/src/erl_types.erl
+++ b/lib/dialyzer/src/erl_types.erl
@@ -4394,6 +4394,8 @@ from_form({type, _Anno, byte, []}, _S, _D, L, C) ->
   {t_byte(), L, C};
 from_form({type, _Anno, char, []}, _S, _D, L, C) ->
   {t_char(), L, C};
+from_form({type, _Anno, dynamic, []}, _S, _D, L, C) ->
+  {t_any(), L, C};
 from_form({type, _Anno, float, []}, _S, _D, L, C) ->
   {t_float(), L, C};
 from_form({type, _Anno, function, []}, _S, _D, L, C) ->
@@ -5062,6 +5064,7 @@ t_form_to_string({type, _Anno, binary, [Base, Unit]} = Type) ->
     _ -> io_lib:format("Badly formed bitstr type ~w", [Type])
   end;
 t_form_to_string({type, _Anno, bitstring, []}) -> "bitstring()";
+t_form_to_string({type, _Anno, dynamic, []}) -> "dynamic()";
 t_form_to_string({type, _Anno, 'fun', []}) -> "fun()";
 t_form_to_string({type, _Anno, 'fun', [{type, _, any}, Range]}) ->
   "fun(...) -> " ++ t_form_to_string(Range);
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl
index 8453c1e7b7..1ac604a363 100644
--- a/lib/stdlib/src/erl_internal.erl
+++ b/lib/stdlib/src/erl_internal.erl
@@ -566,6 +566,7 @@ is_type(bool, 0) -> true;
 is_type(boolean, 0) -> true;
 is_type(byte, 0) -> true;
 is_type(char, 0) -> true;
+is_type(dynamic, 0) -> true;
 is_type(float, 0) -> true;
 is_type(function, 0) -> true;
 is_type(identifier, 0) -> true;
diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml
index e4b9c4f62c..fa751834f6 100644
--- a/system/doc/reference_manual/typespec.xml
+++ b/system/doc/reference_manual/typespec.xml
@@ -83,17 +83,32 @@
     </p>
     <pre>  atom() | integer()</pre>
     <p>
-      Because of subtype relations that exist between types, types
+      Because of subtype relations that exist between types, all types,
+      except <c>dynamic()</c>,
       form a lattice where the top-most element, <c>any()</c>, denotes
       the set of all Erlang terms and the bottom-most element, <c>none()</c>,
       denotes the empty set of terms.
     </p>
+    <p>
+      To facilitate <url href="https://en.wikipedia.org/wiki/Gradual_typing">
+      gradual typing</url> of Erlang, the type `dynamic()` is provided.
+      It is similar to
+      <url href="https://docs.python.org/3/library/typing.html#the-any-type">Any</url>
+      in Python,
+      <url href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any">any</url>
+      in TypeScript and
+      <url href="https://docs.hhvm.com/hack/built-in-types/dynamic">dynamic</url>
+      in Hack. `any()` and `dynamic()` interact with
+      <url href="https://learnyousomeerlang.com/dialyzer#success-typing">success typing</url>
+      the same way, so Dialyzer doesn't distinguish between them.
+    </p>
     <p>
       The set of predefined types and the syntax for types follows:
     </p>
     <pre><![CDATA[
   Type :: any()                 %% The top type, the set of all Erlang terms
         | none()                %% The bottom type, contains no terms
+        | dynamic()
         | pid()
         | port()
         | reference()
-- 
2.35.3

openSUSE Build Service is sponsored by