From 393470c0d82380a8b5bed89623693018490e9ece Mon Sep 17 00:00:00 2001 From: lucioleKi Date: Wed, 4 Dec 2024 10:58:38 +0100 Subject: [PATCH] dialyzer: fix issues related to opaques Fix https://github.com/erlang/otp/issues/9140. --- lib/dialyzer/src/dialyzer.hrl | 2 ++ lib/dialyzer/src/dialyzer_contracts.erl | 2 +- lib/dialyzer/src/dialyzer_dataflow.erl | 4 +-- lib/dialyzer/src/dialyzer_options.erl | 12 +++++--- .../test/opaque_SUITE_data/src/para/para6.erl | 29 +++++++++++++++++++ .../test/opaque_SUITE_data/src/para/para7.erl | 29 +++++++++++++++++++ 6 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 lib/dialyzer/test/opaque_SUITE_data/src/para/para6.erl create mode 100644 lib/dialyzer/test/opaque_SUITE_data/src/para/para7.erl diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl index 2a9eea0fd63d..55ff369ffd81 100644 --- a/lib/dialyzer/src/dialyzer.hrl +++ b/lib/dialyzer/src/dialyzer.hrl @@ -39,6 +39,7 @@ -define(WARN_CONTRACT_EXTRA_RETURN, warn_contract_extra_return). -define(WARN_CONTRACT_MISSING_RETURN, warn_contract_missing_return). -define(WARN_CONTRACT_NOT_EQUAL, warn_contract_not_equal). +-define(WARN_CONTRACT_OPAQUE, warn_contract_opaque). -define(WARN_CONTRACT_RANGE, warn_contract_range). -define(WARN_CONTRACT_SUBTYPE, warn_contract_subtype). -define(WARN_CONTRACT_SUPERTYPE, warn_contract_supertype). @@ -67,6 +68,7 @@ -type dial_warn_tag() :: ?WARN_BEHAVIOUR | ?WARN_BIN_CONSTRUCTION | ?WARN_CALLGRAPH | ?WARN_CONTRACT_EXTRA_RETURN | ?WARN_CONTRACT_MISSING_RETURN | ?WARN_CONTRACT_NOT_EQUAL + | ?WARN_CONTRACT_OPAQUE | ?WARN_CONTRACT_RANGE | ?WARN_CONTRACT_SUBTYPE | ?WARN_CONTRACT_SUPERTYPE | ?WARN_CONTRACT_SYNTAX | ?WARN_CONTRACT_TYPES | ?WARN_FAILING_CALL diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl index 1efb6af56681..7682996e5a4c 100644 --- a/lib/dialyzer/src/dialyzer_contracts.erl +++ b/lib/dialyzer/src/dialyzer_contracts.erl @@ -905,7 +905,7 @@ invalid_contract_warning({M, F, A}, WarningInfo, ProblemDetails, Contract, SuccT contract_opaque_warning({M, F, A}, WarningInfo, OpType, SuccType, RecDict) -> OpaqueStr = erl_types:t_to_string(OpType), SuccTypeStr = dialyzer_utils:format_sig(SuccType, RecDict), - {?WARN_CONTRACT_TYPES, WarningInfo, + {?WARN_CONTRACT_OPAQUE, WarningInfo, {contract_with_opaque, [M, F, A, OpaqueStr, SuccTypeStr]}}. overlapping_contract_warning({M, F, A}, WarningInfo) -> diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index 59494fa052b4..bc7d7cb93c6b 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -1760,13 +1760,13 @@ bind_guard(Guard, Map, Env, Eval, State0) -> values -> Es = cerl:values_es(Guard), {Types, State1} = lists:mapfoldl(fun(V, StateAcc0) -> - {_, Type, StateAcc0} = + {_, Type, StateAcc} = bind_guard(V, Map, Env, dont_know, StateAcc0), - {Type, StateAcc0} + {Type, StateAcc} end, State0, Es), {Map, t_product(Types), State1}; var -> diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl index 0e68559785be..518af66f22a0 100644 --- a/lib/dialyzer/src/dialyzer_options.erl +++ b/lib/dialyzer/src/dialyzer_options.erl @@ -43,6 +43,7 @@ build(Opts) -> ?WARN_FAILING_CALL, ?WARN_BIN_CONSTRUCTION, ?WARN_MAP_CONSTRUCTION, + ?WARN_CONTRACT_OPAQUE, ?WARN_CONTRACT_RANGE, ?WARN_CONTRACT_TYPES, ?WARN_CONTRACT_SYNTAX, @@ -502,15 +503,18 @@ build_warnings([Opt|Opts], Warnings) -> no_match -> ordsets:del_element(?WARN_MATCHING, Warnings); no_opaque -> - S = ordsets:from_list([?WARN_OPAQUE, + S = ordsets:from_list([?WARN_CONTRACT_OPAQUE, + ?WARN_OPAQUE, ?WARN_OPAQUE_UNION]), ordsets:subtract(Warnings, S); no_fail_call -> ordsets:del_element(?WARN_FAILING_CALL, Warnings); no_contracts -> - Warnings1 = ordsets:del_element(?WARN_CONTRACT_SYNTAX, Warnings), - Warnings2 = ordsets:del_element(?WARN_OVERLAPPING_CONTRACT, Warnings1), - ordsets:del_element(?WARN_CONTRACT_TYPES, Warnings2); + S = ordsets:from_list([?WARN_CONTRACT_OPAQUE, + ?WARN_CONTRACT_SYNTAX, + ?WARN_CONTRACT_TYPES, + ?WARN_OVERLAPPING_CONTRACT]), + ordsets:subtract(Warnings, S); no_behaviours -> ordsets:del_element(?WARN_BEHAVIOUR, Warnings); no_undefined_callbacks -> diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para6.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para6.erl new file mode 100644 index 000000000000..a77d800537ce --- /dev/null +++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para6.erl @@ -0,0 +1,29 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2024. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(para6). +-dialyzer({no_opaque,[exp_adt/0]}). + +-type exp() :: para3_adt:exp1(para3_adt:exp2()). + +-spec exp_adt() -> exp(). % invalid type spec + +exp_adt() -> + 3. diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para7.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para7.erl new file mode 100644 index 000000000000..566489fcf7c0 --- /dev/null +++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para7.erl @@ -0,0 +1,29 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2024. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(para6). +-dialyzer({no_contracts, exp_adt/0}). + +-type exp() :: para3_adt:exp1(para3_adt:exp2()). + +-spec exp_adt() -> exp(). % invalid type spec + +exp_adt() -> + 3.