diff options
author | Hans Bolinder <[email protected]> | 2015-06-04 13:50:20 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2015-06-15 08:17:58 +0200 |
commit | e4691d14078de0419c6b644566e45aa696aa122e (patch) | |
tree | 499e3ab8fe147f47323ec1c12cef9f45da7697e7 /lib/dialyzer/src/dialyzer_contracts.erl | |
parent | 75e0da6a5c5c6b2ac21dfdffb1feb9ac96834e5d (diff) | |
download | otp-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.erl | 21 |
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). |