aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2019-05-28 11:36:15 +0200
committerJohn Högberg <[email protected]>2019-05-28 11:36:15 +0200
commit0e72e780498e47614de5730c8d4453948c9ad1da (patch)
tree027e7a07441b5e0c0a237e713a579f738f0a99ec /lib/compiler/src
parentc3993aa68647b0337892ad0a8bb5ad6d28ddcd74 (diff)
parent00dc96a9a0086e829e574b651b4a28155aa826df (diff)
downloadotp-0e72e780498e47614de5730c8d4453948c9ad1da.tar.gz
otp-0e72e780498e47614de5730c8d4453948c9ad1da.tar.bz2
otp-0e72e780498e47614de5730c8d4453948c9ad1da.zip
Merge branch 'john/compiler/list_append_type/OTP-15841' into maint
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/beam_ssa_type.erl14
-rw-r--r--lib/compiler/src/beam_validator.erl12
2 files changed, 17 insertions, 9 deletions
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl
index 417addf921..57fd7fec60 100644
--- a/lib/compiler/src/beam_ssa_type.erl
+++ b/lib/compiler/src/beam_ssa_type.erl
@@ -896,11 +896,15 @@ type(call, [#b_remote{mod=#b_literal{val=Mod},
{_,_} ->
#t_tuple{}
end;
- {erlang,'++',[List1,List2]} ->
- case get_type(List1, Ts) =:= cons orelse
- get_type(List2, Ts) =:= cons of
- true -> cons;
- false -> list
+ {erlang,'++',[LHS,RHS]} ->
+ LType = get_type(LHS, Ts),
+ RType = get_type(RHS, Ts),
+ case LType =:= cons orelse RType =:= cons of
+ true ->
+ cons;
+ false ->
+ %% `[] ++ RHS` yields RHS, even if RHS is not a list.
+ join(list, RType)
end;
{erlang,'--',[_,_]} ->
list;
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 09a5a6c104..ebe9631e09 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -2844,10 +2844,14 @@ call_return_type_1(erlang, setelement, 3, Vst) ->
setelement(3, TupleType, #{})
end;
call_return_type_1(erlang, '++', 2, Vst) ->
- case get_term_type({x,0}, Vst) =:= cons orelse
- get_term_type({x,1}, Vst) =:= cons of
- true -> cons;
- false -> list
+ LType = get_term_type({x,0}, Vst),
+ RType = get_term_type({x,1}, Vst),
+ case LType =:= cons orelse RType =:= cons of
+ true ->
+ cons;
+ false ->
+ %% `[] ++ RHS` yields RHS, even if RHS is not a list
+ join(list, RType)
end;
call_return_type_1(erlang, '--', 2, _Vst) ->
list;