aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2019-06-18 10:34:33 +0200
committerJohn Högberg <[email protected]>2019-06-18 10:34:33 +0200
commit48c6ae50648009218b91ae9cbc87890bbe0addb2 (patch)
treeea1dc463cd176417e6a636e84960fc8b1773006c /lib
parent63dec44359b45e735a8328a84ecc1d3826ee82f1 (diff)
parentd7b6e2ef74c28bc60058b110bdefe5c54d1da058 (diff)
downloadotp-48c6ae50648009218b91ae9cbc87890bbe0addb2.tar.gz
otp-48c6ae50648009218b91ae9cbc87890bbe0addb2.tar.bz2
otp-48c6ae50648009218b91ae9cbc87890bbe0addb2.zip
Merge branch 'john/compiler/cuddle-type-representation'
* john/compiler/cuddle-type-representation: compiler: Add common method for literal -> type conversion
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_ssa_type.erl31
-rw-r--r--lib/compiler/src/beam_types.erl29
-rw-r--r--lib/compiler/src/beam_validator.erl38
3 files changed, 42 insertions, 56 deletions
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl
index 79ed0d7885..c348dc68d3 100644
--- a/lib/compiler/src/beam_ssa_type.erl
+++ b/lib/compiler/src/beam_ssa_type.erl
@@ -1210,36 +1210,7 @@ get_type(#b_var{}=V, Ts) ->
#{V:=T} = Ts,
T;
get_type(#b_literal{val=Val}, _Ts) ->
- if
- is_atom(Val) ->
- beam_types:make_atom(Val);
- is_float(Val) ->
- float;
- is_function(Val) ->
- {arity,Arity} = erlang:fun_info(Val, arity),
- #t_fun{arity=Arity};
- is_integer(Val) ->
- beam_types:make_integer(Val);
- is_list(Val), Val =/= [] ->
- cons;
- is_map(Val) ->
- #t_map{};
- Val =:= {} ->
- beam_types:make_tuple(0, true);
- is_tuple(Val) ->
- {Es, _} = foldl(fun(E, {Es0, Index}) ->
- Type = get_type(#b_literal{val=E}, #{}),
- Es = beam_types:set_element_type(Index,
- Type,
- Es0),
- {Es, Index + 1}
- end, {#{}, 1}, tuple_to_list(Val)),
- beam_types:make_tuple(tuple_size(Val), true, Es);
- Val =:= [] ->
- nil;
- true ->
- any
- end.
+ beam_types:make_type_from_value(Val).
%% infer_types(Var, Types, #d{}) -> {SuccTypes,FailTypes}
%% Looking at the expression that defines the variable Var, infer
diff --git a/lib/compiler/src/beam_types.erl b/lib/compiler/src/beam_types.erl
index c3ad594304..07d3c3d3f2 100644
--- a/lib/compiler/src/beam_types.erl
+++ b/lib/compiler/src/beam_types.erl
@@ -22,6 +22,8 @@
-include("beam_types.hrl").
+-import(lists, [foldl/3]).
+
-export([meet/1, meet/2, join/1, join/2, subtract/2]).
-export([get_singleton_value/1,
@@ -31,6 +33,8 @@
-export([get_element_type/2, set_element_type/3]).
+-export([make_type_from_value/1]).
+
-export([make_atom/1,
make_boolean/0,
make_integer/1,
@@ -348,6 +352,31 @@ get_element_type(Index, Es) ->
%%% Type constructors
%%%
+-spec make_type_from_value(term()) -> type().
+make_type_from_value(Value) ->
+ mtfv_1(Value).
+
+mtfv_1([]) -> nil;
+mtfv_1([_|_]) -> cons;
+mtfv_1(A) when is_atom(A) -> #t_atom{elements=[A]};
+mtfv_1(B) when is_binary(B) -> #t_bitstring{unit=8};
+mtfv_1(B) when is_bitstring(B) -> #t_bitstring{};
+mtfv_1(F) when is_float(F) -> float;
+mtfv_1(F) when is_function(F) ->
+ {arity, Arity} = erlang:fun_info(F, arity),
+ #t_fun{arity=Arity};
+mtfv_1(I) when is_integer(I) -> make_integer(I);
+mtfv_1(M) when is_map(M) -> #t_map{};
+mtfv_1(T) when is_tuple(T) ->
+ {Es,_} = foldl(fun(Val, {Es0, Index}) ->
+ Type = mtfv_1(Val),
+ Es = set_element_type(Index, Type, Es0),
+ {Es, Index + 1}
+ end, {#{}, 1}, tuple_to_list(T)),
+ #t_tuple{exact=true,size=tuple_size(T),elements=Es};
+mtfv_1(_Term) ->
+ any.
+
-spec make_atom(atom()) -> type().
make_atom(Atom) when is_atom(Atom) ->
#t_atom{elements=[Atom]}.
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 8fe7ed8b69..90049b3a25 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -2014,32 +2014,18 @@ is_value_alive(#value_ref{}=Ref, #vst{current=#st{vs=Vs}}) ->
is_value_alive(_, _) ->
false.
-get_literal_type(nil) -> glt_1([]);
-get_literal_type({atom,A}) when is_atom(A) -> glt_1(A);
-get_literal_type({float,F}) when is_float(F) -> glt_1(F);
-get_literal_type({integer,I}) when is_integer(I) -> glt_1(I);
-get_literal_type({literal,L}) -> glt_1(L);
-get_literal_type(T) -> error({not_literal,T}).
-
-glt_1([]) -> nil;
-glt_1([_|_]) -> cons;
-glt_1(A) when is_atom(A) -> #t_atom{elements=[A]};
-glt_1(B) when is_bitstring(B) -> #t_bitstring{};
-glt_1(F) when is_float(F) -> float;
-glt_1(F) when is_function(F) ->
- {arity, Arity} = erlang:fun_info(F, arity),
- #t_fun{arity=Arity};
-glt_1(I) when is_integer(I) -> beam_types:make_integer(I);
-glt_1(M) when is_map(M) -> #t_map{};
-glt_1(T) when is_tuple(T) ->
- {Es,_} = foldl(fun(Val, {Es0, Index}) ->
- Type = glt_1(Val),
- Es = beam_types:set_element_type(Index, Type, Es0),
- {Es, Index + 1}
- end, {#{}, 1}, tuple_to_list(T)),
- #t_tuple{exact=true,size=tuple_size(T),elements=Es};
-glt_1(_Term) ->
- any.
+get_literal_type(nil) ->
+ beam_types:make_type_from_value([]);
+get_literal_type({atom,A}) when is_atom(A) ->
+ beam_types:make_type_from_value(A);
+get_literal_type({float,F}) when is_float(F) ->
+ beam_types:make_type_from_value(F);
+get_literal_type({integer,I}) when is_integer(I) ->
+ beam_types:make_type_from_value(I);
+get_literal_type({literal,L}) ->
+ beam_types:make_type_from_value(L);
+get_literal_type(T) ->
+ error({not_literal,T}).
%%%
%%% Branch tracking