Crash with Uncaught error: {badkey, ...}
ilya-klyuchnikov opened this issue · 1 comments
ilya-klyuchnikov commented
A minimal repro:
-module(box).
-export_type([box/0]).
-record(box, {value = <<>> :: binary()}).
-type box() :: #box{}.
-module(gradualizer_repro3).
-compile([export_all, nowarn_export_all]).
-spec get_box([tuple()]) -> box:box() | undefined.
get_box([H | _T]) when is_record(H, box, 1) -> H;
get_box([_ | Tail]) -> get_box(Tail);
get_box(_) -> undefined.
===> Uncaught error in rebar_core. Run with DIAGNOSTIC=1 to see stacktrace or consult rebar3.crashdump
===> Uncaught error: {badkey,box}
===> Stack trace to the error location:
[{erlang,map_get,[box,#{}],[{error_info,#{module => erl_erts_errors}}]},
{typechecker,get_record_fields,3,
[{file,"/Users/ilyaklyuchnikov/code/gr-rebar3/_build/default/plugins/gradualizer/src/typechecker.erl"},
{line,590}]},
{typechecker,compat_ty,4,
[{file,"/Users/ilyaklyuchnikov/code/gr-rebar3/_build/default/plugins/gradualizer/src/typechecker.erl"},
{line,375}]},
{typechecker,any_type,4,
[{file,"/Users/ilyaklyuchnikov/code/gr-rebar3/_build/default/plugins/gradualizer/src/typechecker.erl"},
{line,541}]},
{typechecker,subtype,3,
[{file,"/Users/ilyaklyuchnikov/code/gr-rebar3/_build/default/plugins/gradualizer/src/typechecker.erl"},
{line,190}]},
{typechecker,do_type_check_expr_in,3,
[{file,"/Users/ilyaklyuchnikov/code/gr-rebar3/_build/default/plugins/gradualizer/src/typechecker.erl"},
{line,2500}]},
{typechecker,type_check_expr_in,3,
[{file,"/Users/ilyaklyuchnikov/code/gr-rebar3/_build/default/plugins/gradualizer/src/typechecker.erl"},
{line,2487}]},
{typechecker,check_clause,5,
[{file,"/Users/ilyaklyuchnikov/code/gr-rebar3/_build/default/plugins/gradualizer/src/typechecker.erl"},
{line,4000}]}]
zuiderkwast commented
Interesting. The record definition is not available in the module, but it shouldn't have to be. is_record/3
shouldn't look up the record. It should just check if it's a tuple with the right size and the first element is the record name.
Josef tried to distinguish between tuples and records, but it's not really possible in situations like this.