Skip to content

Commit

Permalink
Merge pull request #457 from erszcz/fix-map-type-inference
Browse files Browse the repository at this point in the history
Fix map type inference
  • Loading branch information
erszcz authored Sep 19, 2022
2 parents 494358b + 8fe9691 commit e874016
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 11 deletions.
8 changes: 4 additions & 4 deletions src/typechecker.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1544,15 +1544,15 @@ subst_ty(_, Ty) -> Ty.
%% and the expression to type check.
%% Returns the type of the expression, a collection of variables bound in
%% the expression together with their type and constraints.
-spec type_check_expr(env(), expr()) -> {any(), env(), constraints:constraints()}.
-spec type_check_expr(env(), expr()) -> {type(), env(), constraints:constraints()}.
type_check_expr(Env, Expr) ->
Res = {Ty, _VarBinds, _Cs} = do_type_check_expr(Env, Expr),
?verbose(Env, "~sPropagated type of ~ts :: ~ts~n",
[gradualizer_fmt:format_location(Expr, brief), erl_prettypr:format(Expr), typelib:pp_type(Ty)]),
Res.

%% TODO: move tenv to back
-spec do_type_check_expr(env(), expr()) -> {any(), env(), constraints:constraints()}.
-spec do_type_check_expr(env(), expr()) -> {type(), env(), constraints:constraints()}.
do_type_check_expr(Env, {var, _P, Var}) ->
case Env#env.venv of
#{Var := Ty} ->
Expand Down Expand Up @@ -1714,10 +1714,10 @@ do_type_check_expr(#env{infer = true} = Env, {float, _, _F}) ->
%% Maps
do_type_check_expr(Env, {map, _, Assocs}) ->
{AssocTys, VB, Cs} = type_check_assocs(Env, Assocs),
% TODO: When the --infer flag is set we should return the type of the map
case Env#env.infer of
true ->
{type(map, AssocTys), VB, Cs};
MapTy = update_map_type(type(map, []), AssocTys),
{MapTy, VB, Cs};
false ->
{type(any), VB, Cs}
end;
Expand Down
8 changes: 2 additions & 6 deletions test/should_fail/covariant_map_keys_fail.erl
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
-module(covariant_map_keys_fail).

-compile([nowarn_unused_function]).
-export([not_good/1]).

-spec good(#{ good := A }) -> A.
good(#{ good := X }) -> X.
-spec good(#{good := A}) -> A.
good(#{good := X}) -> X.

-spec not_good(#{good | bad := A}) -> A.
not_good(M) -> good(M). %% This call should fail

-spec kaboom() -> integer().
kaboom() -> not_good(#{ bad => 0 }).
5 changes: 4 additions & 1 deletion test/should_pass/map_creation.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-module(map_creation).
-export([f/0, g/0]).
-export([f/0, g/0, h/0]).

-spec f() -> #{apa := bepa}.
f() -> #{apa => bepa}.
Expand All @@ -9,3 +9,6 @@ f() -> #{apa => bepa}.
-spec g() -> typed_map().
g() ->
#{field_a => <<"ala ma kota">>}.

-spec h() -> #{inner := #{a := 5}}.
h() -> #{inner => #{a => 5}}.
19 changes: 19 additions & 0 deletions test/should_pass/map_infer_pass.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-module(map_infer_pass).

-export([not_good/1,
kaboom1/0,
kaboom2/0]).

-gradualizer([infer]).

-spec not_good(#{good | bad := integer()}) -> integer().
not_good(#{good := _}) -> 0.

-spec kaboom1() -> integer().
kaboom1() ->
M = #{bad => 0},
not_good(M).

-spec kaboom2() -> integer().
kaboom2() ->
not_good(#{bad => 0}).

0 comments on commit e874016

Please sign in to comment.