Skip to content

Dialyzer fails with no_return when using Mix.raise/1 in Elixir 1.17.0 #13656

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

Closed
ypconstante opened this issue Jun 12, 2024 · 2 comments · Fixed by #13659
Closed

Dialyzer fails with no_return when using Mix.raise/1 in Elixir 1.17.0 #13656

ypconstante opened this issue Jun 12, 2024 · 2 comments · Fixed by #13659
Assignees

Comments

@ypconstante
Copy link
Contributor

Elixir and Erlang/OTP versions

Erlang/OTP 26 [erts-14.2.1] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]

Elixir 1.17.0 (compiled with Erlang/OTP 26)

Operating system

macOS 14.5

Current behavior

With Elixir 1.17 dialyzer is failing with no_return when a mix task uses Mix.raise as the return of with/else, using case or raise Mix.Error avoids this issue.

> mix dialyzer
...
lib/mix/tasks/example.ex:6:no_return
The created anonymous function has no local return.
defmodule Mix.Tasks.Example do
  use Mix.Task

  @impl Mix.Task
  def run(argv) do
    with [] <- argv do
      :ok
    else
      _ -> Mix.raise("message")
    end
  end
end

defmodule Mix.Tasks.Example2 do
  use Mix.Task

  @impl Mix.Task
  def run(argv) do
    case argv do
      [] -> :ok
      _ -> Mix.raise("message")
    end
  end
end

defmodule Mix.Tasks.Example3 do
  use Mix.Task

  @impl Mix.Task
  def run(argv) do
    with [] <- argv do
      :ok
    else
      _ -> raise Mix.Error, message: "message"
    end
  end
end

Expected behavior

Dialyzer behaves the same as in previous versions when using Mix.raise/1

@josevalim
Copy link
Member

We tag Mix.raise as a no_return, so everything should work. We don't really guarantee Dialyzer compatibility but we would be welcome to review and merge a PR that provides a fix.

@sabiwara
Copy link
Contributor

I think it's because with now defines an anonymous function internally, it would expand to:

Screenshot 2024-06-13 at 6 52 33

where dialyzer complains that The created anonymous function has no local return. fun.
This is only the case when fun isn't explicitly raising but calling a function with a no_return type.

I'm not sure if this could be fixed upstream, or maybe we could try to add more generated: true here to silence it since we're already doing this in a bunch of places for with anyway. Will try to give it a shot.

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

Successfully merging a pull request may close this issue.

3 participants