From a37d0a27979641d953ffa318e660e659bf9bbaf8 Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Wed, 23 Oct 2019 12:20:17 +0200 Subject: [PATCH 1/2] Normalize annotated types --- src/typechecker.erl | 7 +++++++ .../should_pass/annotated_types_problems.erl | 9 --------- .../should_pass/pattern_ann_type.erl | 13 ------------- test/should_pass/ann_types.erl | 17 ++++++++++++++++- test/should_pass/user_types.erl | 4 +++- 5 files changed, 26 insertions(+), 24 deletions(-) delete mode 100644 test/known_problems/should_pass/annotated_types_problems.erl delete mode 100644 test/known_problems/should_pass/pattern_ann_type.erl diff --git a/src/typechecker.erl b/src/typechecker.erl index 0d54efff..e00f4f66 100644 --- a/src/typechecker.erl +++ b/src/typechecker.erl @@ -587,6 +587,13 @@ normalize({type, _, union, Tys}, TEnv) -> [T] -> T; Ts -> type(union, Ts) end; +normalize({ann_type, _, _} = Type, TEnv) -> + Types = flatten_type(Type, TEnv), + case merge_union_types(Types, TEnv) of + [] -> type(none); + [T] -> T; + Ts -> type(union, Ts) + end; normalize({user_type, P, Name, Args} = Type, TEnv) -> case typelib:get_module_from_annotation(P) of {ok, Module} -> diff --git a/test/known_problems/should_pass/annotated_types_problems.erl b/test/known_problems/should_pass/annotated_types_problems.erl deleted file mode 100644 index 682511d6..00000000 --- a/test/known_problems/should_pass/annotated_types_problems.erl +++ /dev/null @@ -1,9 +0,0 @@ --module(annotated_types_problems). - --export([named_record_arg/1]). - --record(r, {}). --type r() :: #r{}. - --spec named_record_arg(R :: r()) -> {ok, R}. -named_record_arg(#r{} = R) -> {ok, R}. diff --git a/test/known_problems/should_pass/pattern_ann_type.erl b/test/known_problems/should_pass/pattern_ann_type.erl deleted file mode 100644 index c9888730..00000000 --- a/test/known_problems/should_pass/pattern_ann_type.erl +++ /dev/null @@ -1,13 +0,0 @@ --module(pattern_ann_type). - --export([f/1]). - --type mytuple() :: tuple(). - -%% The problem is that a user_type/remote_type is encapsulated in an -%% ann_type. The type is not normalized if annotated and -%% `expect_tuple_type/2` cannot handle user/remote types. -%% Type check passes if Pat annotation is removed. --spec f(Pat :: mytuple()) -> ok. -f({}) -> - ok. diff --git a/test/should_pass/ann_types.erl b/test/should_pass/ann_types.erl index fe0e8bfb..a71ca74b 100644 --- a/test/should_pass/ann_types.erl +++ b/test/should_pass/ann_types.erl @@ -1,7 +1,7 @@ %%% @doc Test module for annotated types -module(ann_types). --export([f/2]). +-export([f/2, g/2, h/1, annotated_named_record_arg/1, remote_named_record_arg/1]). -spec f(A :: atom(), integer()) -> {A :: term(), B :: number()}. f(A, B) -> @@ -10,3 +10,18 @@ f(A, B) -> -spec g(A :: atom(), Map :: map()) -> NewMap :: map(). g(A, Map) -> Map#{ A => any }. + +-type mytuple() :: tuple(). +-spec h(Pat :: mytuple()) -> ok. +h({}) -> + ok. + +-record(r, {}). +-type r() :: #r{}. +-spec annotated_named_record_arg(R :: r()) -> {ok, R :: r()}. +annotated_named_record_arg(#r{} = R) -> {ok, R}. + +-spec remote_named_record_arg(R :: user_types:my_empty_record()) -> + {ok, R :: user_types:my_empty_record()}. +remote_named_record_arg(#r{} = R) -> {ok, R}. + diff --git a/test/should_pass/user_types.erl b/test/should_pass/user_types.erl index 738a4f6c..579b66ad 100644 --- a/test/should_pass/user_types.erl +++ b/test/should_pass/user_types.erl @@ -3,8 +3,10 @@ -export([f/1]). %% these exported types are used in remote_types module --export_type([my_tuple/0, my_list/0, my_union/0, my_opaque/0]). +-export_type([my_tuple/0, my_list/0, my_union/0, my_opaque/0, my_empty_record/0]). +-record(r, {}). +-type my_empty_record() :: #r{}. -type my_atom() :: atom(). -type my_tuple() :: {my_atom(), integer()}. -type my_list() :: list(my_atom()). From bc5c68811c487df7871f78bcbd9ab676fcc4c3b3 Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Tue, 31 Dec 2019 18:04:40 +0000 Subject: [PATCH 2/2] Parse ann_type in place --- src/typechecker.erl | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/typechecker.erl b/src/typechecker.erl index e00f4f66..83c75c0f 100644 --- a/src/typechecker.erl +++ b/src/typechecker.erl @@ -587,13 +587,8 @@ normalize({type, _, union, Tys}, TEnv) -> [T] -> T; Ts -> type(union, Ts) end; -normalize({ann_type, _, _} = Type, TEnv) -> - Types = flatten_type(Type, TEnv), - case merge_union_types(Types, TEnv) of - [] -> type(none); - [T] -> T; - Ts -> type(union, Ts) - end; +normalize({ann_type, _Ann, [_Var, Type]}, TEnv) -> + normalize(Type, TEnv); normalize({user_type, P, Name, Args} = Type, TEnv) -> case typelib:get_module_from_annotation(P) of {ok, Module} ->