josefs / Gradualizer

A Gradual type system for Erlang
MIT License
613 stars 35 forks source link

Don't discard annotations in instantiate/2 #517

Closed erszcz closed 1 year ago

erszcz commented 1 year ago

Prior to this commit we could run into the following error:

===> Uncaught error: {badkey,text}
===> Stack trace to the error location:
[{erlang,map_get,[text,#{}],[{error_info,#{module => erl_erts_errors}}]},
 {typechecker,get_record_fields,3,
              [{file,"/Users/erszcz/work/erszcz/tapl-erlang/apps/fullequirec/_checkouts/gradualizer/src/typechecker.erl"},
               {line,553}]},
 {typechecker,compat_ty,4,
              [{file,"/Users/erszcz/work/erszcz/tapl-erlang/apps/fullequirec/_checkouts/gradualizer/src/typechecker.erl"},
               {line,356}]},
 {typechecker,any_type,4,
              [{file,"/Users/erszcz/work/erszcz/tapl-erlang/apps/fullequirec/_checkouts/gradualizer/src/typechecker.erl"},
               {line,504}]},
 {typechecker,subtype,3,
              [{file,"/Users/erszcz/work/erszcz/tapl-erlang/apps/fullequirec/_checkouts/gradualizer/src/typechecker.erl"},
               {line,190}]},
 {typechecker,type_check_call,6,
              [{file,"/Users/erszcz/work/erszcz/tapl-erlang/apps/fullequirec/_checkouts/gradualizer/src/typechecker.erl"},
               {line,3450}]},
 {typechecker,do_type_check_expr_in,3,
              [{file,"/Users/erszcz/work/erszcz/tapl-erlang/apps/fullequirec/_checkouts/gradualizer/src/typechecker.erl"},
               {line,2690}]},
 {typechecker,type_check_expr_in,3,
              [{file,"/Users/erszcz/work/erszcz/tapl-erlang/apps/fullequirec/_checkouts/gradualizer/src/typechecker.erl"},
               {line,2449}]}]

It's caused by a record being mentioned in a spec, like:

1> h(prettypr,text,1).

  text(S::string()) -> #text{s=deep_string()}

but then instantiate/2, when called on the spec, dropping the annotation from some types, including records. Later on, in get_record_fields/3, a record without an annotation is taken as a locally defined one, which is not always the case, and a crash happens due to a lookup to the local REnv which doesn't have a given record name.

erszcz commented 1 year ago

Josef didn't add one, so there's no comment ;p It's instantiating type variables, so later on constraints can be added on them. Anyways, it's not that important - the important thing for this fix is that we drop an annotation that might contain a file reference.