Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix bind_* NIF typespecs #318

Merged
merged 1 commit into from
Feb 10, 2025
Merged

Conversation

ademenev
Copy link
Contributor

No description provided.

@ademenev
Copy link
Contributor Author

    now = :erlang.monotonic_time(:millisecond)
    {:ok, stmt} = Exqlite.Sqlite3.prepare(conn, "DELETE FROM queue WHERE expiration <= ?")
    :ok = Exqlite.Sqlite3.bind(stmt, [now])

dialyzer complains about the last line:

The function call will not succeed.
   
Exqlite.Sqlite3.bind(_stmt :: reference(), [integer(), ...])
   
will never return since the 2nd arguments differ  from the success typing arguments:
(reference(), nil | [])

and in exqlite source there is this:

  @spec bind_integer(statement, non_neg_integer, integer) :: :ok
  def bind_integer(stmt, index, integer) do
    case Sqlite3NIF.bind_integer(stmt, index, integer) do
      @sqlite_ok -> :ok
      rc -> raise Exqlite.Error, message: errmsg(stmt) || errstr(rc)
    end
  end

and this

  @spec bind_integer(statement, non_neg_integer, integer) :: :ok
  def bind_integer(_stmt, _index, _integer), do: :erlang.nif_error(:not_loaded)

The return value of Sqlite3NIF.bind_integer which is typed as :ok is matched against @sqlite_ok which is 0. That should always fail, so

The pattern can never match the type.
   
 Pattern:
 0
   
 Type:
 :ok

@warmwaffles
Copy link
Member

😮‍💨 I could not figure out the dialyzer errors for the life of me. It didn't occur to me to actually check the return from the nif.

Can you go ahead and add the dialyzer to the CI as well now 😄

- run: mix credo --all

@warmwaffles
Copy link
Member

I'm almost tempted to turn these integers into atoms in a separate PR. Much easier to decipher WTF.

@warmwaffles warmwaffles merged commit 4e9f389 into elixir-sqlite:main Feb 10, 2025
9 checks passed
@warmwaffles
Copy link
Member

I'll chuck the ci check in later. Thanks a ton @ademenev.

@ademenev
Copy link
Contributor Author

😮‍💨 I could not figure out the dialyzer errors for the life of me. It didn't occur to me to actually check the return from the nif.

Can you go ahead and add the dialyzer to the CI as well now 😄

- run: mix credo --all

It actually fails for me, so I guess adding it would just break CI

lib/mix/tasks/download_sqlite.ex:1:callback_info_missing
Callback info about the Mix.Task behaviour is not available.
________________________________________________________________________________
Please file a bug in https://github.com/jeremyjh/dialyxir/issues with this message.

Unknown error occurred: %Protocol.UndefinedError{protocol: String.Chars, value: {8, 34}, description: ""}


Legacy warning:
lib/mix/tasks/download_sqlite.ex:8:34: Unknown function 'Elixir.Exqlite.MixProject':sqlite_version/0
________________________________________________________________________________
lib/mix/tasks/test_sqlite_version.ex:1:callback_info_missing
Callback info about the Mix.Task behaviour is not available.
________________________________________________________________________________
lib/mix/tasks/test_sqlite_version.ex:17:unknown_function
Function Mix.raise/1 does not exist.
________________________________________________________________________________
Please file a bug in https://github.com/jeremyjh/dialyxir/issues with this message.

Unknown error occurred: %Protocol.UndefinedError{protocol: String.Chars, value: {9, 38}, description: ""}


Legacy warning:
lib/mix/tasks/test_sqlite_version.ex:9:38: Unknown function 'Elixir.Exqlite.MixProject':sqlite_version/0
________________________________________________________________________________
done (warnings were emitted)
Halting VM with exit status 2

Integestingly, ElixirLS does not report those for me, only mix dialyzer does

But al least for projects using the library dialyzer does is not complaining

@warmwaffles
Copy link
Member

I stopped using ElixirLS for the time being. It is slow, eats memory, and causes so much pain. 😭

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants