diff options
author | José Valim <[email protected]> | 2013-11-08 23:50:43 +0100 |
---|---|---|
committer | Anthony Ramine <[email protected]> | 2013-12-12 10:46:07 +0100 |
commit | 6c5c39827cc06a9e9b3e3fa4fa856f4610eb40b6 (patch) | |
tree | 7946344140b7ada4ca214d07de644b9c7119bb5c /lib/dialyzer/src/dialyzer_dataflow.erl | |
parent | 458e302f61e2de36ebd49c5a5a5b984224bdce94 (diff) | |
download | otp-6c5c39827cc06a9e9b3e3fa4fa856f4610eb40b6.tar.gz otp-6c5c39827cc06a9e9b3e3fa4fa856f4610eb40b6.tar.bz2 otp-6c5c39827cc06a9e9b3e3fa4fa856f4610eb40b6.zip |
Support non top level letrecs in dialyzer
Dialyzer so far only supported letrecs at the top-level
and comprehension-like letrecs (i.e. that were directly applied)
in their body.
This commit address this issue by storing in the callgraph
bound letrec labels pointing to their functions. This information
is then used by the dataflow to properly lookup recursive
definitions.
Diffstat (limited to 'lib/dialyzer/src/dialyzer_dataflow.erl')
-rw-r--r-- | lib/dialyzer/src/dialyzer_dataflow.erl | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index 6956850f1a..922ccad599 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -308,7 +308,7 @@ traverse(Tree, Map, State) -> {State1, Map1, Type}; var -> ?debug("Looking up unknown variable: ~p\n", [Tree]), - case state__lookup_type_for_rec_var(Tree, State) of + case state__lookup_type_for_letrec(Tree, State) of error -> LType = lookup_type(Tree, Map), Opaques = State#state.opaques, @@ -1468,7 +1468,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) -> var -> Opaques = State#state.opaques, VarType1 = - case state__lookup_type_for_rec_var(Pat, State) of + case state__lookup_type_for_letrec(Pat, State) of error -> LType = lookup_type(Pat, Map), case t_opaque_match_record(LType, Opaques) of @@ -2829,12 +2829,11 @@ state__get_warnings(#state{tree_map = TreeMap, fun_tab = FunTab, state__is_escaping(Fun, #state{callgraph = Callgraph}) -> dialyzer_callgraph:is_escaping(Fun, Callgraph). -state__lookup_type_for_rec_var(Var, #state{callgraph = Callgraph} = State) -> +state__lookup_type_for_letrec(Var, #state{callgraph = Callgraph} = State) -> Label = get_label(Var), - case dialyzer_callgraph:lookup_rec_var(Label, Callgraph) of + case dialyzer_callgraph:lookup_letrec(Label, Callgraph) of error -> error; - {ok, MFA} -> - {ok, FunLabel} = dialyzer_callgraph:lookup_label(MFA, Callgraph), + {ok, FunLabel} -> {ok, state__fun_type(FunLabel, State)} end. |