import_type
Directive #
This EEP proposes a new -import_type(Module, [Types])
module directive
to import remote types. Imported types can be referenced the same way as local
types, eliminating the need for a module prefix.
The reasoning behind the proposal aligns with the existing
-import(Module, [Functions])
directive. The primary motivations for
introducing the directive are:
erl_lint
module defines
a local type anno()
to refer to the type erl_anno:anno()
.It makes exporting and importing types symmetrical to exporting and importing functions. Until now, there is an asymmetry: types can be exported but cannot be imported.
A new module directive is introduced:
-import_type(Module, [T1/A1, ..., Tk/Ak]).
Here the Module
is an atom (the name of the module from which types are
imported), the Ti
’s are atoms (the name of the type) and Ai
’s are integers
(the arities). Imported types can be referenced the same way as local types -
without any module prefix.
Example:
-module(m1).
-import_type(common_types, [user/0, id/0]).
-spec get_user_id(user()) -> id().
A reference to a type should be unambiguously resolved to a locally defined type, predefined built-in type or imported type. That imposes a few restrictions (similar to restrictions for importing functions):
Ti/Ai
can be imported only once.The restrictions are validated by the compiler (as part of the erl_lint
stage). It is up to tooling to check whether the imported remote type exists
and exported, the compiler doesn’t check it.
Examples of restrictions:
Overriding a built-in type:
-module(m2).
-import_type(m1, [binary/0]).
error: import directive overrides auto-imported builtin type binary/0
Importing twice:
-module(m).
-import_type(m1, [user/0]).
-import_type(m2, [user/0]).
error: type user/0 already imported from m1.
Importing twice from the same module:
-module(m).
-import_type(m1, [a/0, b/0]).
-import_type(m1, [b/0, c/0]).
error: type b/0 already imported from m1
Redefining imported type:
-module(m).
-import_type(m1, [user/0]).
-type user() :: {user, binary()}.
error: defining imported type user/0
https://github.com/erlang/otp/pull/7618
The implementation consists of three logical pieces:
erl_parse
) to support the new directive.erl_lint
to enforce restrictions (from the Details section)The change is backward compatible. Existing code cannot have the proposed
import_type
attributes, since they are not parseable by the current compiler.
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.