aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/cerl
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2016-06-28 11:23:49 +0200
committerMagnus Lång <[email protected]>2016-06-28 13:36:11 +0200
commita296fc4d7f6f52c78da4596b9b08f39147089d44 (patch)
treeda8292afe0cbdb1a9f980c0a69e52d742a99df9c /lib/hipe/cerl
parent3b7a6ffddc819bf305353a593904cea9e932e7dc (diff)
downloadotp-a296fc4d7f6f52c78da4596b9b08f39147089d44.tar.gz
otp-a296fc4d7f6f52c78da4596b9b08f39147089d44.tar.bz2
otp-a296fc4d7f6f52c78da4596b9b08f39147089d44.zip
erl_types: Normalise X:=none() pairs in t_map/3
t_map/3 previously required callers to perform this normalisation, but as t_from_form/5 would sometimes fail to do so, this requirement is relaxed. Bug (ERL-177) reported and shrunk by Luke Imhoff.
Diffstat (limited to 'lib/hipe/cerl')
-rw-r--r--lib/hipe/cerl/erl_types.erl20
1 files changed, 10 insertions, 10 deletions
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 7826dada9d..243bb6e25d 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -1664,10 +1664,12 @@ t_map(Pairs0, DefK0, DefV0) ->
%% define(DEBUG, true).
try
validate_map_elements(Pairs)
- catch error:badarg -> error(badarg, [Pairs0,DefK0,DefV0]);
- error:{badarg, E} -> error({badarg, E}, [Pairs0,DefK0,DefV0])
+ catch error:badarg -> error(badarg, [Pairs0,DefK0,DefV0])
end,
- ?map(Pairs, DefK, DefV).
+ case map_pairs_are_none(Pairs) of
+ true -> ?none;
+ false -> ?map(Pairs, DefK, DefV)
+ end.
normalise_map_optionals([], _, _) -> [];
normalise_map_optionals([E={K,?opt,?none}|T], DefK, DefV) ->
@@ -1684,7 +1686,6 @@ normalise_map_optionals([E={K,?opt,V}|T], DefK, DefV) ->
normalise_map_optionals([E|T], DefK, DefV) ->
[E|normalise_map_optionals(T, DefK, DefV)].
-validate_map_elements([{_,?mand,?none}|_]) -> error({badarg, none_in_mand});
validate_map_elements([{K1,_,_}|Rest=[{K2,_,_}|_]]) ->
case is_singleton_type(K1) andalso K1 < K2 of
false -> error(badarg);
@@ -1697,6 +1698,10 @@ validate_map_elements([{K,_,_}]) ->
end;
validate_map_elements([]) -> true.
+map_pairs_are_none([]) -> false;
+map_pairs_are_none([{_,?mand,?none}|_]) -> true;
+map_pairs_are_none([_|Ps]) -> map_pairs_are_none(Ps).
+
-spec t_is_map(erl_type()) -> boolean().
t_is_map(Type) ->
@@ -2833,12 +2838,7 @@ t_inf(?map(_, ADefK, ADefV) = A, ?map(_, BDefK, BDefV) = B, _Opaques) ->
%% becomes mandatory in the infinumum
(K, _, V1, _, V2) -> {K, ?mand, t_inf(V1, V2)}
end, A, B),
- %% If the infinimum of any mandatory values is ?none, the entire map infinimum
- %% is ?none.
- case lists:any(fun({_,?mand,?none})->true; ({_,_,_}) -> false end, Pairs) of
- true -> t_none();
- false -> t_map(Pairs, t_inf(ADefK, BDefK), t_inf(ADefV, BDefV))
- end;
+ t_map(Pairs, t_inf(ADefK, BDefK), t_inf(ADefV, BDefV));
t_inf(?matchstate(Pres1, Slots1), ?matchstate(Pres2, Slots2), _Opaques) ->
?matchstate(t_inf(Pres1, Pres2), t_inf(Slots1, Slots2));
t_inf(?nil, ?nil, _Opaques) -> ?nil;