summaryrefslogtreecommitdiff
path: root/lib/compiler/src/beam_validator.erl
diff options
context:
space:
mode:
authorJohn Högberg <john@erlang.org>2021-05-26 11:22:15 +0200
committerJohn Högberg <john@erlang.org>2021-05-26 11:22:15 +0200
commitfa00d16e901f4a8f94041db46b5cd8ab3cc5e8d9 (patch)
tree11f4e593a0ea6fda4e3dcf7d56a3461746548b2c /lib/compiler/src/beam_validator.erl
parent6f0ef0fd2edb3c64d550c410c78c0ca1cc4d4b31 (diff)
parent609a77ba5dd99612983039aec98a65843940625f (diff)
downloaderlang-fa00d16e901f4a8f94041db46b5cd8ab3cc5e8d9.tar.gz
Merge branch 'john/compiler/validator-container-type-subtraction-pt2/GH-4774/OTP-17437' into maint
* john/compiler/validator-container-type-subtraction-pt2/GH-4774/OTP-17437: beam_validator: Update containers in infer_types/4
Diffstat (limited to 'lib/compiler/src/beam_validator.erl')
-rw-r--r--lib/compiler/src/beam_validator.erl25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 54a91d037c..171b3f0ddd 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1997,6 +1997,31 @@ infer_types_1(#value{op={bif,tuple_size}, args=[Tuple]},
eq_exact -> update_type(fun meet/2, Type, Tuple, Vst);
ne_exact -> update_type(fun subtract/2, Type, Tuple, Vst)
end;
+infer_types_1(#value{op={bif,element},args=[{integer,Index}, Tuple]},
+ Val, eq_exact, Vst) ->
+ ValType = get_term_type(Val, Vst),
+ Es = beam_types:set_tuple_element(Index, ValType, #{}),
+ TupleType = #t_tuple{size=Index,elements=Es},
+ update_type(fun meet/2, TupleType, Tuple, Vst);
+infer_types_1(#value{op={bif,element},args=[{integer,Index}, Tuple]},
+ Val, ne_exact, Vst) ->
+ %% Subtraction is only safe with singletons, see update_ne_types/3 for
+ %% details.
+ ValType = get_term_type(Val, Vst),
+ case beam_types:is_singleton_type(ValType) of
+ true ->
+ case beam_types:set_tuple_element(Index, ValType, #{}) of
+ #{ Index := _ }=Es ->
+ TupleType = #t_tuple{size=Index,elements=Es},
+ update_type(fun subtract/2, TupleType, Tuple, Vst);
+ #{} ->
+ %% Index was above the element limit; subtraction is not
+ %% safe.
+ Vst
+ end;
+ false ->
+ Vst
+ end;
infer_types_1(_, _, _, Vst) ->
Vst.