diff options
author | John Högberg <john@erlang.org> | 2021-05-26 11:22:15 +0200 |
---|---|---|
committer | John Högberg <john@erlang.org> | 2021-05-26 11:22:15 +0200 |
commit | fa00d16e901f4a8f94041db46b5cd8ab3cc5e8d9 (patch) | |
tree | 11f4e593a0ea6fda4e3dcf7d56a3461746548b2c /lib/compiler/src/beam_validator.erl | |
parent | 6f0ef0fd2edb3c64d550c410c78c0ca1cc4d4b31 (diff) | |
parent | 609a77ba5dd99612983039aec98a65843940625f (diff) | |
download | erlang-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.erl | 25 |
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. |