File 0285-dialyzer-Optimize-infimum-on-bit-strings.patch of Package erlang
From 923ecb37fa2f24593d4f12585ffe00a7ac4a4676 Mon Sep 17 00:00:00 2001
From: Hans Bolinder <hasse@erlang.org>
Date: Wed, 28 Jul 2021 10:19:02 +0200
Subject: [PATCH 5/7] dialyzer: Optimize infimum on bit strings
t_inf/2 finds the common base of two bit string types faster in some
cases. It is a little bit slower on many cases, though.
---
lib/dialyzer/src/erl_types.erl | 10 ++++++----
lib/dialyzer/test/erl_types_SUITE.erl | 15 +++++++++++++--
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/lib/dialyzer/src/erl_types.erl b/lib/dialyzer/src/erl_types.erl
index 7b88ebd59c..e381bfb64e 100644
--- a/lib/dialyzer/src/erl_types.erl
+++ b/lib/dialyzer/src/erl_types.erl
@@ -2933,7 +2933,7 @@ t_inf(?map(_, ADefK, ADefV) = A, ?map(_, BDefK, BDefV) = B, _Opaques) ->
%% result in a none result.
Pairs =
map_pairwise_merge(
- %% For optional keys in both maps, when the infinimum is none, we have
+ %% For optional keys in both maps, when the infimum is none, we have
%% essentially concluded that K must not be a key in the map.
fun(K, ?opt, V1, ?opt, V2) -> {K, ?opt, t_inf(V1, V2)};
%% When a key is optional in one map, but mandatory in another, it
@@ -3404,9 +3404,11 @@ findfirst(N1, N2, U1, B1, U2, B2) ->
if Val1 =:= Val2 ->
Val1;
Val1 > Val2 ->
- findfirst(N1, N2+1, U1, B1, U2, B2);
+ N2_1 = N2 + max((Val1 - Val2) div U2, 1),
+ findfirst(N1, N2_1, U1, B1, U2, B2);
Val1 < Val2 ->
- findfirst(N1+1, N2, U1, B1, U2, B2)
+ N1_1 = N1 + max((Val2 - Val1) div U1, 1),
+ findfirst(N1_1, N2, U1, B1, U2, B2)
end.
%% Optimization. Before Erlang/OTP 25, subst_all_vars_to_any() was
@@ -4046,7 +4048,7 @@ t_subtract(?map(APairs, ADefK, ADefV) = A, ?map(_, BDefK, BDefV) = B) ->
%% * The arguments constrain A at least as much as B, i.e. that A so far
%% is a subtype of B. In that case they return false
%% * That for the particular arguments, A being a subtype of B does not
- %% hold, but the infinimum of A and B is nonempty, and by narrowing a
+ %% hold, but the infimum of A and B is nonempty, and by narrowing a
%% pair in A, we can create a type that excludes some elements in the
%% infinumum. In that case, they will return that pair.
%% * That for the particular arguments, A being a subtype of B does not
diff --git a/lib/dialyzer/test/erl_types_SUITE.erl b/lib/dialyzer/test/erl_types_SUITE.erl
index 7d7c144b69..72a705ee26 100644
--- a/lib/dialyzer/test/erl_types_SUITE.erl
+++ b/lib/dialyzer/test/erl_types_SUITE.erl
@@ -15,7 +15,9 @@
-module(erl_types_SUITE).
-export([all/0,
- consistency_and_to_string/1, map_multiple_representations/1]).
+ consistency_and_to_string/1,
+ misc/1,
+ map_multiple_representations/1]).
%% Simplify calls into erl_types and avoid importing the entire module.
-define(M, erl_types).
@@ -23,7 +25,7 @@
-include_lib("common_test/include/ct.hrl").
all() ->
- [consistency_and_to_string, map_multiple_representations].
+ [consistency_and_to_string, misc, map_multiple_representations].
consistency_and_to_string(_Config) ->
%% Check consistency of types
@@ -196,6 +198,16 @@ consistency_and_to_string(_Config) ->
"{'false',_} | {'true',_}" = ?M:t_to_string(Union10),
"{'true',integer()}" = ?M:t_to_string(?M:t_inf(Union10, ?M:t_tuple([?M:t_atom(true), ?M:t_integer()]))).
+misc(_Config) ->
+ %% Miscellaneous cases which have been fixed.
+
+ %% Used to take "forever".
+ B1_1 = ?M:t_bitstr(6442450944, 1456),
+ B1_2 = ?M:t_bitstr(85, 7),
+ R1_R = ?M:t_bitstr(547608330240, 347892352432),
+ R1_R = ?M:t_inf(B1_1, B1_2),
+ ok.
+
%% OTP-17537.
map_multiple_representations(_Config) ->
DefV = erl_types:t_atom(),
--
2.31.1