diff options
author | Hans Bolinder <[email protected]> | 2015-07-02 15:12:54 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2015-08-25 09:24:55 +0200 |
commit | 9a5788654c0e6a08b404ac3e68bf3894cf7e8252 (patch) | |
tree | d040ba4495075a00da9715aa3ea41c1d2e54f9b5 /lib/hipe | |
parent | 85f6fe3b1343c726a380b6efa4b108ab98eff00d (diff) | |
download | otp-9a5788654c0e6a08b404ac3e68bf3894cf7e8252.tar.gz otp-9a5788654c0e6a08b404ac3e68bf3894cf7e8252.tar.bz2 otp-9a5788654c0e6a08b404ac3e68bf3894cf7e8252.zip |
dialyzer: Optimize the expansion of parameterized types somewhat
Expand parameters when needed only.
The opaqueness is removed from types expanded to any().
Diffstat (limited to 'lib/hipe')
-rw-r--r-- | lib/hipe/cerl/erl_types.erl | 94 |
1 files changed, 51 insertions, 43 deletions
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index ad92324911..f00663444a 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -4242,7 +4242,6 @@ builtin_type(Name, Type, TypeNames, ET, Site, MR, V, D, L) -> type_from_form(Name, Args, TypeNames, ET, Site0, MR, V, D, L) -> ArgsLen = length(Args), - {ArgTypes, L1} = list_from_form(Args, TypeNames, ET, Site0, MR, V, D, L), Module = site_module(Site0), {ok, R} = dict:find(Module, MR), TypeName = {type, {Module, Name, ArgsLen}}, @@ -4250,48 +4249,52 @@ type_from_form(Name, Args, TypeNames, ET, Site0, MR, V, D, L) -> {type, {{Module, _FileName, Form, ArgNames}, _Type}} -> case can_unfold_more(TypeName, TypeNames) of true -> + {ArgTypes, L1} = + list_from_form(Args, TypeNames, ET, Site0, MR, V, D, L), List = lists:zip(ArgNames, ArgTypes), TmpV = dict:from_list(List), Site = TypeName, t_from_form(Form, [TypeName|TypeNames], ET, Site, MR, TmpV, D, L1); false -> - {t_any(), L1} + {t_any(), L} end; {opaque, {{Module, _FileName, Form, ArgNames}, Type}} -> - {Rep, L2} = - case can_unfold_more(TypeName, TypeNames) of - true -> - List = lists:zip(ArgNames, ArgTypes), - TmpV = dict:from_list(List), - Site = TypeName, - t_from_form(Form, [TypeName|TypeNames], ET, Site, MR, TmpV, D, L1); - false -> {t_any(), L1} - end, - Rep1 = choose_opaque_type(Rep, Type), - Rep2 = case cannot_have_opaque(Rep1, TypeName, TypeNames) of - true -> Rep1; - false -> - ArgTypes2 = subst_all_vars_to_any_list(ArgTypes), - t_opaque(Module, Name, ArgTypes2, Rep1) - end, - {Rep2, L2}; + case can_unfold_more(TypeName, TypeNames) of + true -> + {ArgTypes, L1} = + list_from_form(Args, TypeNames, ET, Site0, MR, V, D, L), + List = lists:zip(ArgNames, ArgTypes), + TmpV = dict:from_list(List), + Site = TypeName, + {Rep, L2} = + t_from_form(Form, [TypeName|TypeNames], ET, Site, MR, + TmpV, D, L1), + Rep1 = choose_opaque_type(Rep, Type), + Rep2 = case cannot_have_opaque(Rep1, TypeName, TypeNames) of + true -> Rep1; + false -> + ArgTypes2 = subst_all_vars_to_any_list(ArgTypes), + t_opaque(Module, Name, ArgTypes2, Rep1) + end, + {Rep2, L2}; + false -> {t_any(), L} + end; error -> Msg = io_lib:format("Unable to find type ~w/~w\n", [Name, ArgsLen]), throw({error, Msg}) end. remote_from_form(RemMod, Name, Args, TypeNames, ET, S, MR, V, D, L) -> - {ArgTypes, L1} = list_from_form(Args, TypeNames, ET, S, MR, V, D, L), if ET =:= replace_by_none -> - {t_none(), L1}; + {t_none(), L}; true -> ArgsLen = length(Args), MFA = {RemMod, Name, ArgsLen}, case dict:find(RemMod, MR) of error -> self() ! {self(), ext_types, MFA}, - {t_any(), L1}; + {t_any(), L}; {ok, RemDict} -> RemType = {type, MFA}, case sets:is_element(MFA, ET) of @@ -4300,6 +4303,8 @@ remote_from_form(RemMod, Name, Args, TypeNames, ET, S, MR, V, D, L) -> {type, {{_Mod, _FileLine, Form, ArgNames}, _Type}} -> case can_unfold_more(RemType, TypeNames) of true -> + {ArgTypes, L1} = + list_from_form(Args, TypeNames, ET, S, MR, V, D, L), List = lists:zip(ArgNames, ArgTypes), TmpVarDict = dict:from_list(List), NewTypeNames = [RemType|TypeNames], @@ -4307,29 +4312,32 @@ remote_from_form(RemMod, Name, Args, TypeNames, ET, S, MR, V, D, L) -> t_from_form(Form, NewTypeNames, ET, Site, MR, TmpVarDict, D, L1); false -> - {t_any(), L1} + {t_any(), L} end; {opaque, {{Mod, _FileLine, Form, ArgNames}, Type}} -> - List = lists:zip(ArgNames, ArgTypes), - TmpVarDict = dict:from_list(List), - {NewRep, L2} = - case can_unfold_more(RemType, TypeNames) of - true -> - NewTypeNames = [RemType|TypeNames], - Site = RemType, + case can_unfold_more(RemType, TypeNames) of + true -> + NewTypeNames = [RemType|TypeNames], + {ArgTypes, L1} = + list_from_form(Args, TypeNames, ET, S, MR, V, D, L), + List = lists:zip(ArgNames, ArgTypes), + TmpVarDict = dict:from_list(List), + Site = RemType, + {NewRep, L2} = t_from_form(Form, NewTypeNames, ET, Site, MR, - TmpVarDict, D, L1); - false -> {t_any(), L1} - end, - NewRep1 = choose_opaque_type(NewRep, Type), - NewRep2 = - case cannot_have_opaque(NewRep1, RemType, TypeNames) of - true -> NewRep1; - false -> - ArgTypes2 = subst_all_vars_to_any_list(ArgTypes), - t_opaque(Mod, Name, ArgTypes2, NewRep1) - end, - {NewRep2, L2}; + TmpVarDict, D, L1), + NewRep1 = choose_opaque_type(NewRep, Type), + NewRep2 = + case cannot_have_opaque(NewRep1, RemType, TypeNames) of + true -> NewRep1; + false -> + ArgTypes2 = subst_all_vars_to_any_list(ArgTypes), + t_opaque(Mod, Name, ArgTypes2, NewRep1) + end, + {NewRep2, L2}; + false -> + {t_any(), L} + end; error -> Msg = io_lib:format("Unable to find remote type ~w:~w()\n", [RemMod, Name]), @@ -4337,7 +4345,7 @@ remote_from_form(RemMod, Name, Args, TypeNames, ET, S, MR, V, D, L) -> end; false -> self() ! {self(), ext_types, {RemMod, Name, ArgsLen}}, - {t_any(), L1} + {t_any(), L} end end end. |