Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require all functions in src/typechecker.erl to have specs #499

Merged
merged 29 commits into from
Dec 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9fa6c02
Raise errors on missing API specs in src/typechecker.erl
erszcz Dec 16, 2022
855ab9d
Fix all warnings in src/typechecker.erl
erszcz Dec 16, 2022
17351a0
Raise errors on any missing specs in src/typechecker.erl
erszcz Dec 16, 2022
06a59da
Define constraints:t/0 type
erszcz Dec 16, 2022
d526375
Add missing specs in src/typechecker.erl
erszcz Dec 16, 2022
1fb0681
Drop constraints:constraints/0 type
erszcz Dec 17, 2022
a966310
Fix self-check error
erszcz Dec 27, 2022
2f3a525
Add test/known_problems/should_pass/recursive_call_with_remote_union_…
erszcz Dec 27, 2022
2803d29
Fix test/known_problems/recursive_call_with_remote_union_return_type_…
erszcz Dec 27, 2022
6f5553e
Fix get_rec_field_type/2 spec
erszcz Dec 27, 2022
2f34e70
Fix get_imported_bounded_fun_type_list/4 spec
erszcz Dec 27, 2022
9d85571
Fix free_vars/2 spec
erszcz Dec 27, 2022
7f17e2e
Fix expect_tuple_union/6 spec
erszcz Dec 27, 2022
2711035
Fix bounded_type_subst/2 spec
erszcz Dec 27, 2022
61dc67f
Fix subst_ty/2 spec
erszcz Dec 27, 2022
258295b
Fix self-check error by dropping an unused clause
erszcz Dec 27, 2022
4053044
Fix expect_record_union/6 spec
erszcz Dec 27, 2022
aacbb2a
Fix cover make rule
erszcz Dec 28, 2022
f1ea019
Add a more complex union type to test/should_pass/tuple_union_pass.erl
erszcz Dec 28, 2022
9a7a952
Add more complex union type tests to test/should_pass/record_union_pa…
erszcz Dec 28, 2022
86d186f
Remove dead record support code
erszcz Dec 28, 2022
96ba547
Remove more dead record code
erszcz Dec 28, 2022
4bd89c6
Fix free_vars/1,2 specs
erszcz Dec 28, 2022
877f6a3
Fix get_atom/2 spec
erszcz Dec 28, 2022
993a577
Add assertion in unary_op_arg_type/2
erszcz Dec 28, 2022
a1a7fcc
Fix call to type_error()
erszcz Dec 28, 2022
719ca58
Remove dead code to fix a self-check error
erszcz Dec 28, 2022
f0a7295
Fix check_reachable_clauses/7 spec
erszcz Dec 28, 2022
43e5295
Unify how annotations are passed to type_error/2
erszcz Dec 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -169,20 +169,22 @@ cli-tests: bin/gradualizer test/arg.beam
bin/gradualizer --no_prelude --specs_override_dir priv/prelude \
test/should_pass/cyclic_otp_specs.erl || (echo "CLI 10"; exit 1)

# Cover compile, run eunit, export and generate reports
define erl_cover_run
case cover:compile_beam_directory("ebin") of \
{error, _} -> halt(2); \
_List -> ok \
end, \
$(erl_run_eunit), \
cover:export("cover/eunit.coverdata"), \
cover:analyse_to_file([{outdir, "cover"}]), \
cover:analyse_to_file([{outdir, "cover"}, html])
endef

.PHONY: cover
cover: compile-tests
mkdir -p cover
erl -noinput -pa ebin -pa test -eval \
'%% Cover compile, run eunit, export and generate reports \
case cover:compile_beam_directory("ebin") of % \
{error, _} -> halt(2); % \
_List -> ok % \
end, % \
$(erl_run_eunit), % \
cover:export("cover/eunit.coverdata"), % \
cover:analyse_to_file([{outdir, "cover"}]), % plain text \
cover:analyse_to_file([{outdir, "cover"}, html]), % \
halt().'
erl $(ERL_OPTS) -noinput -pa ebin -pa test -eval '$(erl_cover_run), halt().'

cover/coverage.xml: cover test/covertool.beam
erl -noinput -pa test -eval \
Expand Down
3 changes: 3 additions & 0 deletions include/gradualizer.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
-compile({nowarn_unused_function, ['::'/2, ':::'/2]}).
-ignore_xref(['::'/2, ':::'/2]).

-spec '::'(any(), any()) -> any().
'::'(Expr, _Type) -> Expr.

-spec ':::'(any(), any()) -> any().
':::'(Expr, _Type) -> Expr.

%% Type annotation
Expand Down
16 changes: 8 additions & 8 deletions src/constraints.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

-export([empty/0, upper/2, lower/2, combine/1, combine/2, add_var/2]).

-export_type([constraints/0]).
-export_type([t/0]).

-type type() :: gradualizer_type:abstract_type().

Expand All @@ -13,30 +13,30 @@
exist_vars = #{} :: #{ var() => true }
}).

-type constraints() :: #constraints{}.
-type t() :: #constraints{}.
-type var() :: gradualizer_type:gr_type_var().

-spec empty() -> constraints().
-spec empty() -> t().
empty() ->
#constraints{}.

-spec add_var(var(), constraints()) -> constraints().
-spec add_var(var(), t()) -> t().
add_var(Var, Cs) ->
Cs#constraints{ exist_vars = maps:put(Var, true, Cs#constraints.exist_vars) }.

-spec upper(var(), type()) -> constraints().
-spec upper(var(), type()) -> t().
upper(Var, Ty) ->
#constraints{ upper_bounds = #{ Var => [Ty] } }.

-spec lower(var(), type()) -> constraints().
-spec lower(var(), type()) -> t().
lower(Var, Ty) ->
#constraints{ lower_bounds = #{ Var => [Ty] } }.

-spec combine(constraints(), constraints()) -> constraints().
-spec combine(t(), t()) -> t().
combine(C1, C2) ->
combine([C1, C2]).

-spec combine([constraints()]) -> constraints().
-spec combine([t()]) -> t().
combine([]) ->
empty();
combine([Cs]) ->
Expand Down
5 changes: 3 additions & 2 deletions src/gradualizer.erl
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ env(ErlSource, Opts) ->
%% @see type_of/2
-spec type_of(string()) -> typechecker:type().
type_of(Expr) ->
type_of(Expr, env([infer])).
type_of(Expr, env()).

%% @doc Infer type of an Erlang expression.
%%
Expand All @@ -413,5 +413,6 @@ type_of(Expr) ->
-spec type_of(string(), typechecker:env()) -> typechecker:type().
type_of(Expr, Env) ->
AlwaysInfer = Env#env{infer = true},
{Ty, _Env, _Cs} = typechecker:type_check_expr(AlwaysInfer, merl:quote(Expr)),
[Form] = gradualizer_lib:ensure_form_list(merl:quote(lists:flatten(Expr))),
{Ty, _Env, _Cs} = typechecker:type_check_expr(AlwaysInfer, Form),
Ty.
4 changes: 2 additions & 2 deletions src/gradualizer_cache.erl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ start_link(Opts) ->
%% GLB Cache
%%

-spec get_glb(module(), type(), type()) -> false | {type(), constraints:constraints()}.
-spec get_glb(module(), type(), type()) -> false | {type(), constraints:t()}.
get_glb(Module, T1, T2) ->
try ets:lookup(?GLB_CACHE, {Module, T1, T2}) of
[] ->
Expand All @@ -53,7 +53,7 @@ get_glb(Module, T1, T2) ->
false
end.

-spec store_glb(module(), type(), type(), {type(), constraints:constraints()}) -> ok.
-spec store_glb(module(), type(), type(), {type(), constraints:t()}) -> ok.
store_glb(Module, T1, T2, TyCs) ->
try
ets:insert(?GLB_CACHE, {{Module, T1, T2}, TyCs}),
Expand Down
7 changes: 3 additions & 4 deletions src/gradualizer_fmt.erl
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ format_type_error({illegal_map_type, Type}, Opts) ->
[format_location(Type, brief, Opts),
pp_type(Type, Opts),
format_location(Type, verbose, Opts)]);
format_type_error({type_error, list, _Anno, Ty1, Ty}, Opts) ->
format_type_error({type_error, list, Anno, Ty1, Ty}, Opts) ->
io_lib:format(
"~sThe type ~s cannot be an element of a list of type ~s~n",
[format_location(_Anno, brief, Opts),
[format_location(Anno, brief, Opts),
pp_type(Ty1, Opts),
pp_type(Ty, Opts)]);
format_type_error({type_error, list, Anno, Ty}, Opts) ->
Expand All @@ -150,8 +150,7 @@ format_type_error({argument_length_mismatch, Anno, LenTy, LenArgs}, Opts) ->
format_location(Anno, verbose, Opts),
LenTy,
LenArgs]);
format_type_error({type_error, unreachable_clauses, Clauses}, Opts) ->
Anno = element(2, hd(Clauses)),
format_type_error({type_error, unreachable_clauses, Anno}, Opts) ->
io_lib:format(
"~sThe clause~s cannot be reached~n",
[format_location(Anno, brief, Opts),
Expand Down
2 changes: 2 additions & 0 deletions src/gradualizer_type.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
%% Export the additional types that gradualizer uses
-export_type([abstract_pattern/0,
af_assoc_type/0,
af_atom/0,
af_binary_op/1,
af_constrained_function_type/0,
af_constraint/0,
af_field_name/0,
af_fun_type/0,
af_function_type_list/0,
af_record_field/1,
Expand Down
Loading