sztosz

sztosz

Is Dialyzer fetching incorrect specs, or are they incorrect in Meeseeks?

defmodule A do
  def x() do
    Meeseeks.parse("<div id=main><p>Hello, Meeseeks!</p></div>")
  end
end

This gives me this error:

The call:
Meeseeks.parse(<<_::336>>)

will never return since it differs in arguments with
positions 1 from the success typing arguments:

(
  [
    binary()
    | {:comment, binary()}
    | {:pi, binary()}
    | {:pi | binary(), binary() | [{_, _}], binary() | [any()]}
    | {:doctype, binary(), binary(), binary()}
  ]
  | {:comment, binary()}
  | {:pi, binary()}
  | {:pi | binary(), binary() | [{binary(), binary()}], binary() | [any()]}
  | {:doctype, binary(), binary(), binary()}
)

When the specs for Meeseeks.parse is @spec parse(Parser.source()) :: Document.t() | {:error, Error.t()} with Parser.source() being @type source :: String.t() | TupleTree.t() and then TupleTree.t() being

  @type comment :: {:comment, String.t()}
  @type doctype :: {:doctype, String.t(), String.t(), String.t()}
  @type element :: {String.t(), [{String.t(), String.t()}], [node_t]}
  @type processing_instruction ::
          {:pi, String.t()}
          | {:pi, String.t(), [{String.t(), String.t()}]}
          | {:pi, String.t(), String.t()}
  @type text :: String.t()
  @type node_t :: comment | doctype | element | processing_instruction | text
  @type t :: node_t | [node_t]

Dialyxir and Dialyzer helped ma lot, but I don’t understand what’s wrong with those specs, or is it bug with tools rather.

If source :: String.t() | TupleTree.t() or source :: binary() | TupleTree.t() then call Meeseeks.parse(<<_::336>>) where <<_::336>> is binary should satisfy those specs. Right?

Beside, even when dialyxir/dialyzer says [...] will never return since [...] actually when run always returns and simply works OK.

Most Liked

NobbZ

NobbZ

I code dived a bit. And on a first glance everything looks like passing in a string should work (and actually does).

But, this string gets passed (deep in the stack of function calls) to MeeseeksHtml5ever.Native.parse_html/1. As you can guess from its name, its a NIF.

NIFs always have two implemantations. A native one (eg.: C or Rust) and a “naive” one (BEAM-compatible). Often the naive one is simply throwing.

This throw does happen as well for this function (check https://github.com/mischov/meeseeks_html5ever/blob/master/lib/meeseeks_html5ever/native.ex).

This is the only implementation dialyzer sees. So from dialyzers view, passing a string to Meeseex.parse/1 will always resuilt in a throw, so dialyzer removes String.t silently from the spec.

This has to be fixed upstream (meeseex_html5ever).

mischov

mischov

Using :erlang.nif_error appears to resolve the error.

Thanks for bringing it to my attention- I’ll see if I can’t get releases out with the fix before too long.

jeremyjh

jeremyjh

What I’m suggesting is just change above spec to what appears to be the success typing:

@spec parse(list(Parser.source()) | Parser.source()) :: Document.t() | {:error, Error.t()}
mischov

mischov

Hmm. Would using :erlang.nif_error in the naive function where I previously raised be the standard solution? From the description of nif_error:

Works exactly like error/1, but Dialyzer thinks that this BIF will return an arbitrary term. When used in a stub function for a NIF to generate an exception when the NIF library is not loaded, Dialyzer does not generate false warnings.

mischov

mischov

Well Meeseeks 0.9.3 was available on Github already, I just hadn’t gotten it up on Hex yet. It’s up now.

Where Next?

Popular in Questions Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New

Other popular topics Top

SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement