Created
July 28, 2020 13:41
-
-
Save seriyps/d4daa42185ba2ce2e319184199cd4039 to your computer and use it in GitHub Desktop.
Parameterized record types dialyzer oddity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ rebar3 dialyzer [15:33:30] | |
===> Verifying dependencies... | |
===> Compiling mylib | |
===> Dialyzer starting, this may take a while... | |
===> Updating plt... | |
===> Resolving files... | |
===> Checking 202 files in "sandbox/mylib/_build/default/rebar3_23.0_plt"... | |
===> Doing success typing analysis... | |
===> Resolving files... | |
===> Analyzing 2 files with "sandbox/mylib/_build/default/rebar3_23.0_plt"... | |
src/parameterized_record.erl | |
38: Function test2/0 has no local return | |
40: The call parameterized_record:take_type1_rec(Rec2::#my_record{id::2,type::2}) breaks the contract (#my_record{id::integer(),type::1}) -> 'ok' | |
42: Invalid type specification for function parameterized_record:take_type1_rec/1. The success typing is (#my_record{id::2,type::2}) -> any() | |
58: Invalid type specification for function parameterized_record:should_make_type2_rec/0. The success typing is () -> #my_record{id::1,type::1} | |
src/parameterized_tuple.erl | |
29: Function test1/0 has no local return | |
31: The call parameterized_tuple:take_type1(Rec2::{'my_tag',pos_integer(),2}) breaks the contract (my_record(1)) -> 'ok' | |
33: Invalid type specification for function parameterized_tuple:take_type1/1. The success typing is ({'my_tag',pos_integer(),2}) -> any() | |
38: Function test2/0 has no local return | |
40: The call parameterized_tuple:take_type1_rec(Rec2::{'my_tag',pos_integer(),2}) breaks the contract ({'my_tag',integer(),1}) -> 'ok' | |
42: Invalid type specification for function parameterized_tuple:take_type1_rec/1. The success typing is ({'my_tag',pos_integer(),2}) -> any() | |
50: Invalid type specification for function parameterized_tuple:should_make_type2/0. The success typing is () -> {'my_tag',pos_integer(),1} | |
58: Invalid type specification for function parameterized_tuple:should_make_type2_rec/0. The success typing is () -> {'my_tag',pos_integer(),1} | |
===> Warnings written to sandbox/mylib/_build/default/23.0.dialyzer_warnings | |
===> Warnings occurred running dialyzer: 12 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(parameterized_record). | |
-export([mk_type1/0, mk_type2/0]). | |
-export([test1/0, test2/0, test3/0, test4/0]). | |
-export_type([my_record/1, my_record/0, my_rec_type/0]). | |
-define(TYPE1, 1). | |
-define(TYPE2, 2). | |
-record(my_record, | |
{id = [] :: [] | integer(), | |
type = []}). | |
-type my_record(Type) :: #my_record{id :: integer(), type :: Type}. | |
-type my_record() :: my_record(my_rec_type()). | |
-type my_rec_type() :: ?TYPE1..?TYPE2. | |
-spec mk_type1() -> my_record(?TYPE1). | |
mk_type1() -> | |
#my_record{id = 1, type = ?TYPE1}. | |
-spec mk_type2() -> my_record(?TYPE2). | |
mk_type2() -> | |
#my_record{id = 2, type = ?TYPE2}. | |
test1() -> | |
Rec2 = mk_type2(), | |
take_type1(Rec2). %expects ?TYPE1, gets ?TYPE2. NOT reported!!! | |
-spec take_type1(my_record(?TYPE1)) -> ok. | |
take_type1(Rec) -> | |
gen_server:call(somewhere, Rec). | |
test2() -> | |
Rec2 = mk_type2(), | |
take_type1_rec(Rec2). %expects ?TYPE1, gets ?TYPE2. Reported. | |
-spec take_type1_rec(#my_record{id :: integer(), type :: ?TYPE1}) -> ok. | |
take_type1_rec(Rec) -> | |
gen_server:call(somewhere, Rec). | |
test3() -> | |
should_make_type2(). %spec says returns ?TYPE2, returns ?TYPE1. NOT Reported!! | |
-spec should_make_type2() -> my_record(?TYPE2). | |
should_make_type2() -> | |
mk_type1(). | |
test4() -> | |
should_make_type2_rec(). %spec says returns ?TYPE2, returns ?TYPE1. Reported. | |
-spec should_make_type2_rec() -> #my_record{id :: integer(), type :: ?TYPE2}. | |
should_make_type2_rec() -> | |
mk_type1(). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(parameterized_tuple). | |
-export([mk_type1/0, mk_type2/0]). | |
-export([test1/0, test2/0, test3/0, test4/0]). | |
-export_type([my_record/1, my_record/0, my_rec_type/0]). | |
-define(TYPE1, 1). | |
-define(TYPE2, 2). | |
-type my_record(Type) :: {my_tag, | |
Id :: integer(), | |
Type}. | |
-type my_record() :: my_record(my_rec_type()). | |
-type my_rec_type() :: ?TYPE1..?TYPE2. | |
-spec mk_type1() -> my_record(?TYPE1). | |
mk_type1() -> | |
{my_tag, rand:uniform(10), ?TYPE1}. | |
-spec mk_type2() -> my_record(?TYPE2). | |
mk_type2() -> | |
{my_tag, rand:uniform(10), ?TYPE2}. | |
test1() -> | |
Rec2 = mk_type2(), | |
take_type1(Rec2). %expects ?TYPE1, gets ?TYPE2. Reported! | |
-spec take_type1(my_record(?TYPE1)) -> ok. | |
take_type1(Rec) -> | |
gen_server:call(somewhere, Rec). | |
test2() -> | |
Rec2 = mk_type2(), | |
take_type1_rec(Rec2). %expects ?TYPE1, gets ?TYPE2. Reported! | |
-spec take_type1_rec({my_tag, integer(), ?TYPE1}) -> ok. | |
take_type1_rec(Rec) -> | |
gen_server:call(somewhere, Rec). | |
test3() -> | |
should_make_type2(). %spec says returns ?TYPE2, returns ?TYPE1. Reported! | |
-spec should_make_type2() -> my_record(?TYPE2). | |
should_make_type2() -> | |
mk_type1(). | |
test4() -> | |
should_make_type2_rec(). %spec says returns ?TYPE2, returns ?TYPE1. Reported! | |
-spec should_make_type2_rec() -> {my_tag, integer(), ?TYPE2}. | |
should_make_type2_rec() -> | |
mk_type1(). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment