summaryrefslogtreecommitdiff
path: root/lib/compiler/test/beam_type_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler/test/beam_type_SUITE.erl')
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl41
1 files changed, 39 insertions, 2 deletions
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 5189afde58..65e4e59be9 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -25,7 +25,7 @@
cons/1,tuple/1,record_float/1,binary_float/1,float_compare/1,
arity_checks/1,elixir_binaries/1,find_best/1,
test_size/1,cover_lists_functions/1,list_append/1,bad_binary_unit/1,
- none_argument/1,success_type_oscillation/1]).
+ none_argument/1,success_type_oscillation/1,type_subtraction/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -52,7 +52,8 @@ groups() ->
list_append,
bad_binary_unit,
none_argument,
- success_type_oscillation
+ success_type_oscillation,
+ type_subtraction
]}].
init_per_suite(Config) ->
@@ -596,5 +597,41 @@ sto_1(case_4_1) -> {b, [sto_1(case_3_1)]};
sto_1(case_4_2) -> {b, [sto_1(case_3_2)]};
sto_1(step_4_3) -> {b, [sto_1(case_3_3)]}.
+%% ERL-1440: On inequality, we subtracted the type *common to* both variables
+%% rather than the left-hand type from the right-hand variable and vice versa,
+%% giving an erroneously narrow type.
+%%
+%% In the test below, we have functions returning integers ranged 1..2 and
+%% 2..3 and test for their equality. We know that it can only succeed when both
+%% return 2, but they can fail when the former returns 1 or the latter returns
+%% 3, so we must not subtract 2 on the failure path.
+type_subtraction(Config) when is_list(Config) ->
+ true = type_subtraction_1(id(<<"A">>)),
+ ok.
+
+type_subtraction_1(_x@1) ->
+ _a@1 = ts_12(_x@1),
+ _b@1 = ts_23(_x@1),
+ case _a@1 /= _b@1 of
+ false -> error;
+ true -> _a@1 =:= 3 andalso _b@1 =:= 2
+ end.
+
+ts_12(_x@1) ->
+ case _x@1 == <<"A">> of
+ false ->
+ 2;
+ true ->
+ 3
+ end.
+
+ts_23(_x@1) ->
+ case _x@1 == <<"A">> of
+ false ->
+ 1;
+ true ->
+ 2
+ end.
+
id(I) ->
I.