diff options
author | Hans Bolinder <[email protected]> | 2015-06-15 14:48:21 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2015-06-18 10:33:49 +0200 |
commit | ba41f0b16cc434eb85285b3ecfb68fea873d8e30 (patch) | |
tree | 52ec553103df5e4e583413ad8b01ced80f6aaa08 /lib/dialyzer/src | |
parent | ea1b6f0c39b577860e01bf088bbb97b8d814fa43 (diff) | |
download | otp-ba41f0b16cc434eb85285b3ecfb68fea873d8e30.tar.gz otp-ba41f0b16cc434eb85285b3ecfb68fea873d8e30.tar.bz2 otp-ba41f0b16cc434eb85285b3ecfb68fea873d8e30.zip |
dialyzer: Expand opaque types before other types
Opaque types need to be expanded before record field types, otherwise
any() could be used for opaque types.
Diffstat (limited to 'lib/dialyzer/src')
-rw-r--r-- | lib/dialyzer/src/dialyzer_utils.erl | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl index dbfd20014c..62ffa9413a 100644 --- a/lib/dialyzer/src/dialyzer_utils.erl +++ b/lib/dialyzer/src/dialyzer_utils.erl @@ -297,6 +297,7 @@ get_record_fields([], _RecDict, Acc) -> process_record_remote_types(CServer) -> TempRecords = dialyzer_codeserver:get_temp_records(CServer), TempExpTypes = dialyzer_codeserver:get_temp_exported_types(CServer), + TempRecords1 = process_opaque_types0(TempRecords, TempExpTypes), ModuleFun = fun(Module, Record) -> RecordFun = @@ -309,12 +310,39 @@ process_record_remote_types(CServer) -> erl_types:t_from_form(Field, TempExpTypes, Module, - TempRecords)} + TempRecords1)} || {Name, Field, _} <- Fields] end, {FileLine, Fields} = Value, {FileLine, orddict:map(FieldFun, Fields)}; - {opaque, _, _} -> + _Other -> Value + end + end, + dict:map(RecordFun, Record) + end, + NewRecords = dict:map(ModuleFun, TempRecords1), + ok = check_record_fields(NewRecords, TempExpTypes), + CServer1 = dialyzer_codeserver:finalize_records(NewRecords, CServer), + dialyzer_codeserver:finalize_exported_types(TempExpTypes, CServer1). + +process_opaque_types0(TempRecords0, TempExpTypes) -> + TempRecords = process_opaque_types(TempRecords0, TempExpTypes), + L0 = lists:keysort(1, dict:to_list(TempRecords0)), + L1 = lists:keysort(1, dict:to_list(TempRecords)), + if + L0 =:= L1 -> + TempRecords; + true -> + process_opaque_types0(TempRecords, TempExpTypes) + end. + +process_opaque_types(TempRecords, TempExpTypes) -> + ModuleFun = + fun(Module, Record) -> + RecordFun = + fun(Key, Value) -> + case Key of + {opaque, _Name, _NArgs} -> {{_Module, _FileLine, Form, _ArgNames}=F, _Type} = Value, Type = erl_types:t_from_form(Form, TempExpTypes, Module, TempRecords), @@ -324,15 +352,7 @@ process_record_remote_types(CServer) -> end, dict:map(RecordFun, Record) end, - try dict:map(ModuleFun, TempRecords) of - NewRecords -> - ok = check_record_fields(NewRecords, TempExpTypes), - CServer1 = dialyzer_codeserver:finalize_records(NewRecords, CServer), - dialyzer_codeserver:finalize_exported_types(TempExpTypes, CServer1) - catch - throw:{error, _RecName, _Error} = Error -> - Error - end. + dict:map(ModuleFun, TempRecords). check_record_fields(Records, TempExpTypes) -> CheckFun = |