erlangspecificationsdialyzer

Dialyzer: Unknown Type re:mp()


In this contrived example, the parsing module offers a function called parse_equation/2, which accepts an equation to be parsed, and a regular expression pattern to be used for said parsing:

-module(parsing).
-export([parse_equation/2]).

parse_equation(Equation, Pattern) ->
    {match, [_, Left, Right]} = re:run(Equation, Pattern, [{capture, all, binary}]),
    {Left, Right}.

This works as intended:

$ erl
1> c(parsing).
{ok,parsing}
2> {ok, Pattern} = re:compile("^(.+) = (.+)$").
{ok, ...}
3> parsing:parse_equation("1 + 1 = 2", Pattern).
{<<"1 + 1">>,<<"2">>}

I'd like to add a type specification to parse_equation/2. According to the re manpage,Pattern is of type mp(), i.e. re:mp() from my module. So this is my spec:

-spec parse_equation(string(), re:mp()) -> {binary(), binary()}.

However, the dialyzer cannot make sense of that specification:

$ dialyzer parsing.erl 
  Checking whether the PLT /home/patrick/.cache/erlang/.dialyzer_plt is up-to-date... yes
  Proceeding with analysis...
Unknown types:
  re:mp/0 (/home/patrick/github.com/patrickbucher/learning-erlang/dialyzer-issue/parsing.erl:4:32)
 done in 0m0.14s
done (warnings were emitted)

How can I make the type re:mp() known to the dialyzer? I did run dialyzer --build_plt --apps erts kernel stdlib before.


Solution

  • re.erl does define the mp/0 type, but since there is no -export_type declaration (described in the docs here), it is not available to other modules. (See also this Github issue)

    To make the type re:mp() available, you'd need to add -export_type there.


    In fact, there is a pull request that does that. So most likely this will work correctly once Erlang/OTP 27 is released.