aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2017-02-28 14:26:15 +0100
committerHans Bolinder <[email protected]>2017-02-28 14:37:16 +0100
commit79e0af92ffe050a484d0f00d0dd9c4b4f4e9eb02 (patch)
tree3f708fd96df4a165ffc1119f65f2ad0315266e77 /lib
parent0d12ca4bb9fc85e9db980f1f4f990a7c81c5a7a4 (diff)
downloadotp-79e0af92ffe050a484d0f00d0dd9c4b4f4e9eb02.tar.gz
otp-79e0af92ffe050a484d0f00d0dd9c4b4f4e9eb02.tar.bz2
otp-79e0af92ffe050a484d0f00d0dd9c4b4f4e9eb02.zip
dialyzer: Improve a warning
When a pattern a type do not match, opaque warnings were given precedence before structure mismatches. This is no longer always the case. Mentioned by Nick Marino on erlang-questions.
Diffstat (limited to 'lib')
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/weird4
-rw-r--r--lib/hipe/cerl/erl_types.erl18
2 files changed, 14 insertions, 8 deletions
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/weird b/lib/dialyzer/test/opaque_SUITE_data/results/weird
index df69c9b6f2..d7f57cd152 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/weird
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/weird
@@ -1,6 +1,6 @@
-weird_warning1.erl:15: The attempt to match a term of type #b{q::queue:queue(_)} against the pattern {'a', Dict} breaks the opacity of queue:queue(_)
-weird_warning2.erl:13: The attempt to match a term of type <#a{d::dict:dict(_,_)},'my_key','my_value'> against the pattern <{'b', Queue}, Key, Value> breaks the opacity of dict:dict(_,_)
+weird_warning1.erl:15: Matching of pattern {'a', Dict} tagged with a record name violates the declared type of #b{q::queue:queue(_)}
+weird_warning2.erl:13: Matching of pattern <{'b', Queue}, Key, Value> tagged with a record name violates the declared type of <#a{d::dict:dict(_,_)},'my_key','my_value'>
weird_warning3.erl:14: The call weird_warning3:add_element(#a{d::queue:queue(_)},'my_key','my_value') does not have a term of type #a{d::dict:dict(_,_)} | #b{q::queue:queue(_)} (with opaque subterms) as 1st argument
weird_warning3.erl:16: The attempt to match a term of type #a{d::queue:queue(_)} against the pattern {'a', Dict} breaks the opacity of queue:queue(_)
weird_warning3.erl:18: Matching of pattern {'b', Queue} tagged with a record name violates the declared type of #a{d::queue:queue(_)}
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 36652db176..a5a3e8c136 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -526,7 +526,8 @@ list_contains_opaque(List, Opaques) ->
lists:any(fun(E) -> t_contains_opaque(E, Opaques) end, List).
%% t_find_opaque_mismatch/2 of two types should only be used if their
-%% t_inf is t_none() due to some opaque type violation.
+%% t_inf is t_none() due to some opaque type violation. However,
+%% 'error' is returned if a structure mismatch is found.
%%
%% The first argument of the function is the pattern and its second
%% argument the type we are matching against the pattern.
@@ -535,10 +536,10 @@ list_contains_opaque(List, Opaques) ->
'error' | {'ok', erl_type(), erl_type()}.
t_find_opaque_mismatch(T1, T2, Opaques) ->
- t_find_opaque_mismatch(T1, T2, T2, Opaques).
+ catch t_find_opaque_mismatch(T1, T2, T2, Opaques).
t_find_opaque_mismatch(?any, _Type, _TopType, _Opaques) -> error;
-t_find_opaque_mismatch(?none, _Type, _TopType, _Opaques) -> error;
+t_find_opaque_mismatch(?none, _Type, _TopType, _Opaques) -> throw(error);
t_find_opaque_mismatch(?list(T1, Tl1, _), ?list(T2, Tl2, _), TopType, Opaques) ->
t_find_opaque_mismatch_ordlists([T1, Tl1], [T2, Tl2], TopType, Opaques);
t_find_opaque_mismatch(T1, ?opaque(_) = T2, TopType, Opaques) ->
@@ -574,7 +575,11 @@ t_find_opaque_mismatch(?tuple(_, _, _) = T1, ?tuple_set(_) = T2,
t_find_opaque_mismatch_lists(Tuples1, Tuples2, TopType, Opaques);
t_find_opaque_mismatch(T1, ?union(U2), TopType, Opaques) ->
t_find_opaque_mismatch_lists([T1], U2, TopType, Opaques);
-t_find_opaque_mismatch(_T1, _T2, _TopType, _Opaques) -> error.
+t_find_opaque_mismatch(T1, T2, _TopType, Opaques) ->
+ case t_is_none(t_inf(T1, T2, Opaques)) of
+ false -> error;
+ true -> throw(error)
+ end.
t_find_opaque_mismatch_ordlists(L1, L2, TopType, Opaques) ->
List = lists:zipwith(fun(T1, T2) ->
@@ -583,10 +588,11 @@ t_find_opaque_mismatch_ordlists(L1, L2, TopType, Opaques) ->
t_find_opaque_mismatch_list(List).
t_find_opaque_mismatch_lists(L1, L2, _TopType, Opaques) ->
- List = [t_find_opaque_mismatch(T1, T2, T2, Opaques) || T1 <- L1, T2 <- L2],
+ List = [catch t_find_opaque_mismatch(T1, T2, T2, Opaques) ||
+ T1 <- L1, T2 <- L2],
t_find_opaque_mismatch_list(List).
-t_find_opaque_mismatch_list([]) -> error;
+t_find_opaque_mismatch_list([]) -> throw(error);
t_find_opaque_mismatch_list([H|T]) ->
case H of
{ok, _T1, _T2} -> H;