ex_type icon indicating copy to clipboard operation
ex_type copied to clipboard

Local parametrised types are broken

Open turion opened this issue 4 years ago • 2 comments

defmodule Foo do
  @type t(elem) :: [elem]

  @spec mylength(t(term())) :: integer()

  def mylength(_) do
    23
  end
end
$ mix type
** (FunctionClauseError) no function clause matching in ExType.Typespec.eval_type/2    
    
    The following arguments were given to ExType.Typespec.eval_type/2:
    
        # 1
        %ExType.Type.Any{}
    
        # 2
        {Foo, %{elem: %ExType.Type.Any{}}}
    
    Attempted function clauses (showing 10 out of 57):
    
        def eval_type({:any, _, []}, _)
        def eval_type({:none, _, []}, _)
        def eval_type({:atom, _, []}, _)
        def eval_type({:map, _, []}, _)
        def eval_type({:pid, _, []}, _)
        def eval_type({:port, _, []}, _)
        def eval_type({:reference, _, []}, _)
        def eval_type({:struct, _, []}, _)
        def eval_type({:tuple, _, []}, _)
        def eval_type({:float, _, []}, _)
        ...
        (47 clauses not shown)
    
    lib/ex_type/typespec.ex:249: ExType.Typespec.eval_type/2
    lib/ex_type/typespec.ex:342: ExType.Typespec.eval_type/2
    (elixir 1.10.4) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
    lib/ex_type/typespec.ex:666: anonymous fn/4 in ExType.Typespec.fetch_specs/3
    (elixir 1.10.4) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
    lib/ex_type/typespec.ex:648: ExType.Typespec.fetch_specs/3
    lib/ex_type/custom_env.ex:154: ExType.CustomEnv.process_defs/5
    (elixir 1.10.4) lib/enum.ex:1400: anonymous fn/3 in Enum.map/2

turion avatar Dec 10 '20 09:12 turion

When I inline t, it works:

defmodule Foo do
  @spec mylength([term()]) :: integer()

  def mylength(_) do
    23
  end
end
$ mix type
✅  Foo.mylength/1

turion avatar Dec 10 '20 09:12 turion

The issue is probably in the handling of local types:

https://github.com/gyson/ex_type/blob/b23a0d9e7d70760e3eb46c73695554e99470d08e/lib/ex_type/typespec.ex#L614

There, the type variable is evaluated to %Any{}, but it should really be a %SpecVariable{} "applied" to %Any{}! In fact, it seems %SpecVariable{} doesn't even have a context, maybe they should be closures? Or they should be evaluated correctly at least.

turion avatar Dec 10 '20 09:12 turion