diff options
author | Fredrik Gustafsson <[email protected]> | 2013-01-22 14:57:42 +0100 |
---|---|---|
committer | Fredrik Gustafsson <[email protected]> | 2013-01-22 14:57:42 +0100 |
commit | 0ab216f3dc96890b50f7430895ad5d7f6251f129 (patch) | |
tree | 594d82b3b2cb00a7c09eb493ea4e70804a8e558c /lib/dialyzer/src | |
parent | ffedd0feb21de368cfede09b3ba5c1026e1633f7 (diff) | |
parent | 0e37e993c477dfab0e7218b8246bf94b7a9b97a1 (diff) | |
download | otp-0ab216f3dc96890b50f7430895ad5d7f6251f129.tar.gz otp-0ab216f3dc96890b50f7430895ad5d7f6251f129.tar.bz2 otp-0ab216f3dc96890b50f7430895ad5d7f6251f129.zip |
Merge branch 'sa/dialyzer-list-spec/OTP-10740'
* sa/dialyzer-list-spec/OTP-10740:
Report spec discrepancy on mismatching lists
Diffstat (limited to 'lib/dialyzer/src')
-rw-r--r-- | lib/dialyzer/src/dialyzer_contracts.erl | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl index 0b932d5a1f..157c951f77 100644 --- a/lib/dialyzer/src/dialyzer_contracts.erl +++ b/lib/dialyzer/src/dialyzer_contracts.erl @@ -254,14 +254,35 @@ check_extraneous([C|Cs], SuccType) -> end. check_extraneous_1(Contract, SuccType) -> - CRngs = erl_types:t_elements(erl_types:t_fun_range(Contract)), + CRng = erl_types:t_fun_range(Contract), + CRngs = erl_types:t_elements(CRng), STRng = erl_types:t_fun_range(SuccType), ?debug("CR = ~p\nSR = ~p\n", [CRngs, STRng]), - case [CR || CR <- CRngs, erl_types:t_is_none(erl_types:t_inf(CR, STRng, opaque))] of - [] -> ok; + case [CR || CR <- CRngs, + erl_types:t_is_none(erl_types:t_inf(CR, STRng, opaque))] of + [] -> + CRngList = list_part(CRng), + STRngList = list_part(STRng), + case is_not_nil_list(CRngList) andalso is_not_nil_list(STRngList) of + false -> ok; + true -> + CRngElements = erl_types:t_list_elements(CRngList), + STRngElements = erl_types:t_list_elements(STRngList), + Inf = erl_types:t_inf(CRngElements, STRngElements, opaque), + case erl_types:t_is_none(Inf) of + true -> {error, invalid_contract}; + false -> ok + end + end; CRs -> {error, {extra_range, erl_types:t_sup(CRs), STRng}} end. +list_part(Type) -> + erl_types:t_inf(erl_types:t_list(), Type, opaque). + +is_not_nil_list(Type) -> + erl_types:t_is_list(Type) andalso not erl_types:t_is_nil(Type). + %% This is the heart of the "range function" -spec process_contracts([contract_pair()], [erl_types:erl_type()]) -> erl_types:erl_type(). |