Inability to import shared types upgrading from 0.4 to 0.5
baldwindavid opened this issue · comments
In moving from 0.4 to 0.5 (and up) it seems that I can no longer import
shared types. Example:
defmodule Typetest.MyTypes do
use TypeCheck
@type! a_name :: binary()
end
defmodule Typetest do
use TypeCheck
import Typetest.MyTypes
@spec! hello(a_name()) :: binary()
def hello(name) do
"Hello, #{name}"
end
end
This works in 0.4, but the following error happens in 0.5 and up...
== Compilation error in file lib/typetest.ex ==
9 ** (CompileError) lib/typetest.ex:1: type a_name/0 undefined (no such type in Typetest)
8 (elixir 1.12.2) lib/kernel/typespec.ex:925: Kernel.Typespec.compile_error/2
7 (stdlib 3.15.2) lists.erl:1358: :lists.mapfoldl/3
6 (elixir 1.12.2) lib/kernel/typespec.ex:977: Kernel.Typespec.fn_args/5
5 (elixir 1.12.2) lib/kernel/typespec.ex:963: Kernel.Typespec.fn_args/6
4 (elixir 1.12.2) lib/kernel/typespec.ex:390: Kernel.Typespec.translate_spec/8
3 (stdlib 3.15.2) lists.erl:1358: :lists.mapfoldl/3
2 (elixir 1.12.2) lib/kernel/typespec.ex:236: Kernel.Typespec.translate_typespecs_for_module/2
If I add that same @type
directly within the file while still importing Types
, the resulting error is clear that the shared one is imported...
defmodule Typetest do
use TypeCheck
import Typetest.MyTypes
@type! a_name :: binary()
@spec! hello(a_name()) :: binary()
def hello(name) do
"Hello, #{name}"
end
end
6 == Compilation error in file lib/typetest.ex ==
5 ** (CompileError) lib/typetest.ex:7: function a_name/0 imported from both TypeCheck.Internals.UserTypes.Typetest and Typetest.MyTypes, call is ambiguous
4 (type_check 0.5.0) expanding macro: TypeCheck.Macros.__before_compile__/1
3 lib/typetest.ex:1: Typetest (module)
2 (elixir 1.12.2) lib/kernel/parallel_compiler.ex:319: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7
Is there a different method in order to share types via imports now? I'd rather not alias some very commonly used types.
Elixir does not support importing types between modules.
(This is the reason for the first error you received, the type a_name/0 undefined (no such type in Typetest)
)
That this worked in versions of TypeCheck older than 0.5.0 was caused by an oversight, where it did not correctly add a @spec
for all @spec!
s.
I see the following solutions:
- While importing types is not possible, aliasing a module is. So
alias Typetest.MyTypes, as: T
and then usingT.a_name()
might be a clean solution to your problem. - If you really want to use the types as if they were local, you will need to
- either redefine them without importing the other module. With some metaprogramming, this could become as concise as
use Typetest.MyTypes
. - Or add
@autogen_typespec false
to all types/specs which use the type-functions which have been added to the local scope by theimport Typetest.MyTypes
statement.
I'm pretty sure that (1) is the cleaner solution.
Yeah, I guess I felt like I needed this ability to import previously because of literals missing from https://hexdocs.pm/elixir/1.12/typespecs.html
For example, I had my own keyword()
type for awhile until it was added to the library. Now that most of that page (I think) is in the library that really shouldn't be necessary.
Any truly custom types that wouldn't be in regular typespecs should really be aliased anyway, so I guess this isn't a problem.