aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/src/dialyzer_contracts.erl
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2015-06-04 13:50:20 +0200
committerHans Bolinder <[email protected]>2015-06-15 08:17:58 +0200
commite4691d14078de0419c6b644566e45aa696aa122e (patch)
tree499e3ab8fe147f47323ec1c12cef9f45da7697e7 /lib/dialyzer/src/dialyzer_contracts.erl
parent75e0da6a5c5c6b2ac21dfdffb1feb9ac96834e5d (diff)
downloadotp-e4691d14078de0419c6b644566e45aa696aa122e.tar.gz
otp-e4691d14078de0419c6b644566e45aa696aa122e.tar.bz2
otp-e4691d14078de0419c6b644566e45aa696aa122e.zip
dialyzer: Fix a bug in the expansion of forms
The check that a modified type of a field is a subtype of the declared type has been moved outside of the expansion of forms to avoid loops.
Diffstat (limited to 'lib/dialyzer/src/dialyzer_contracts.erl')
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl21
1 files changed, 15 insertions, 6 deletions
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index 4a1ba9c539..914a4c6d8f 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -409,7 +409,7 @@ contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], Module, RecDict,
fun(ExpTypes, AllRecords) ->
NewType =
try
- erl_types:t_from_form(Form, ExpTypes, Module, AllRecords)
+ from_form_with_check(Form, ExpTypes, Module, AllRecords)
catch
throw:{error, Msg} ->
{File, Line} = FileLine,
@@ -430,8 +430,8 @@ contract_from_form([{type, _L1, bounded_fun,
fun(ExpTypes, AllRecords) ->
{Constr1, VarDict} =
process_constraints(Constr, Module, RecDict, ExpTypes, AllRecords),
- NewType = erl_types:t_from_form(Form, ExpTypes, Module, AllRecords,
- VarDict),
+ NewType = from_form_with_check(Form, ExpTypes, Module, AllRecords,
+ VarDict),
NewTypeNoVars = erl_types:subst_all_vars_to_any(NewType),
{NewTypeNoVars, Constr1}
end,
@@ -454,7 +454,7 @@ initialize_constraints([], _Module, _RecDict, _ExpTypes, _AllRecords, Acc) ->
initialize_constraints([Constr|Rest], Module, RecDict, ExpTypes, AllRecords, Acc) ->
case Constr of
{type, _, constraint, [{atom, _, is_subtype}, [Type1, Type2]]} ->
- T1 = final_form(Type1, Module, ExpTypes, AllRecords, dict:new()),
+ T1 = final_form(Type1, ExpTypes, Module, AllRecords, dict:new()),
Entry = {T1, Type2},
initialize_constraints(Rest, Module, RecDict, ExpTypes, AllRecords, [Entry|Acc]);
{type, _, constraint, [{atom,_,Name}, List]} ->
@@ -483,7 +483,16 @@ constraints_fixpoint(OldVarDict, Module, Constrs, RecDict, ExpTypes, AllRecords)
constraints_fixpoint(NewVarDict, Module, Constrs, RecDict, ExpTypes, AllRecords)
end.
-final_form(Form, Module, ExpTypes, AllRecords, VarDict) ->
+final_form(Form, ExpTypes, Module, AllRecords, VarDict) ->
+ from_form_with_check(Form, ExpTypes, Module, AllRecords, VarDict).
+
+from_form_with_check(Form, ExpTypes, Module, AllRecords) ->
+ erl_types:t_check_record_fields(Form, ExpTypes, Module, AllRecords),
+ erl_types:t_from_form(Form, ExpTypes, Module, AllRecords).
+
+from_form_with_check(Form, ExpTypes, Module, AllRecords, VarDict) ->
+ erl_types:t_check_record_fields(Form, ExpTypes, Module, AllRecords,
+ VarDict),
erl_types:t_from_form(Form, ExpTypes, Module, AllRecords, VarDict).
constraints_to_dict(Constrs, Module, RecDict, ExpTypes, AllRecords, VarDict) ->
@@ -495,7 +504,7 @@ constraints_to_subs([], _Module, _RecDict, _ExpTypes, _AllRecords, _VarDict, Acc
Acc;
constraints_to_subs([C|Rest], Module, RecDict, ExpTypes, AllRecords, VarDict, Acc) ->
{T1, Form2} = C,
- T2 = final_form(Form2, Module, ExpTypes, AllRecords, VarDict),
+ T2 = final_form(Form2, ExpTypes, Module, AllRecords, VarDict),
NewAcc = [{subtype, T1, T2}|Acc],
constraints_to_subs(Rest, Module, RecDict, ExpTypes, AllRecords, VarDict, NewAcc).