aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2015-06-15 14:48:21 +0200
committerHans Bolinder <[email protected]>2015-06-18 10:33:49 +0200
commitba41f0b16cc434eb85285b3ecfb68fea873d8e30 (patch)
tree52ec553103df5e4e583413ad8b01ced80f6aaa08
parentea1b6f0c39b577860e01bf088bbb97b8d814fa43 (diff)
downloadotp-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.
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl42
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 =