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

no function clause matching in Gradient.ElixirExpr.pp_guards/1 #171

Open
alanvardy opened this issue May 15, 2023 · 3 comments
Open

no function clause matching in Gradient.ElixirExpr.pp_guards/1 #171

alanvardy opened this issue May 15, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@alanvardy
Copy link
Contributor

Hello,

I've been really enjoying using gradient, thank you for the work! I've encountered this error today when running mix gradient

(FunctionClauseError) no function clause matching in Gradient.ElixirExpr.pp_guards/1

    The following arguments were given to Gradient.ElixirExpr.pp_guards/1:

        # 1
        [[{:call, [generated: true, location: 486], {:remote, [generated: true, location: 486], {:atom, [generated: true, location: 486], :erlang}, {:atom, [generated: true, location: 486], :is_atom}}, [{:var, [generated: true, location: 486], :_@2}]}, {:op, [generated: true, location: 486], :"=/=", {:var, [generated: true, location: 486], :_@2}, {:atom, [generated: true, location: 486], nil}}, {:op, [generated: true, location: 486], :"=/=", {:var, [generated: true, location: 486], :_@2}, {:atom, [generated: true, location: 486], true}}, {:op, [generated: true, location: 486], :"=/=", {:var, [generated: true, location: 486], :_@2}, {:atom, [generated: true, location: 486], false}}]]

    Attempted function clauses (showing 2 out of 2):

        def pp_guards([])
        def pp_guards([[guard]])

    Gradient.ElixirExpr.pp_guards/1
    lib/gradient/elixir_expr.ex:310: Gradient.ElixirExpr.pp_case_clause/1
    (elixir 1.14.2) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
    (elixir 1.14.2) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
    lib/gradient/elixir_expr.ex:248: Gradient.ElixirExpr.pp_clauses/2
    lib/gradient/elixir_expr.ex:207: Gradient.ElixirExpr.pp_expr/1
    lib/gradient/elixir_expr.ex:154: Gradient.ElixirExpr.pp_expr/1
    (elixir 1.14.2) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
[[Command exited with 1]]

The error occurs three times within the same module and nowhere else. I believe that the issue stems from my custom guard which is used in three different functions.

Here is the guard definition

  @max_integer 32_767

  defguard pos_int(integer) when integer < @max_integer and integer > 0

And here is an example of it in use

  @doc false
  @spec kills(Match.t(), puuid) :: res(non_neg_integer)
  def kills(match, puuid) do
    case Fetch.player(match, puuid) do
      {:ok, %Player{stats: %PlayerStats{kills: kills}}} when pos_int(kills) ->
        {:ok, kills}

      {:ok, %Player{}} ->
        {:ok, 0}

      {:error, error} ->
        {:error, error}
    end
  end
@erszcz erszcz added the bug Something isn't working label May 16, 2023
@erszcz
Copy link
Member

erszcz commented May 16, 2023

Thanks for the report!

From a quick look it seems we're missing a clause for used-defined guards. We'll take a look at this.

@erszcz
Copy link
Member

erszcz commented May 16, 2023

#145 (comment) seems to be related.

@mariari
Copy link

mariari commented Mar 27, 2024

I manage to get a small reproducible case that might be related to this

  @spec indirection(number(), number(), non_neg_integer()) ::
          list({atom(), list(), binary()})
  def indirection(storage, key, order) do
      [:hi, [<<2>>], <<4>>]
  end



  @spec crash() :: number()
  def crash() do
    order = 2
    key = 5
    with {:atomic, [{_, [^order, ^key | 0], value}]} <- indirection(order, key, order) do
      2 + 5
    end
  end

calling mix gradiant gives me

lib/project/storage.ex: The atom on line 289 is expected to have type {atom(), list(), binary()} but it has type :hi
287           list({atom(), list(), binary()})
288   def indirection(storage, key, order) do
289       [:hi, [<<2>>], <<4>>]
290   end
291 

lib/project/storage.ex: ** (FunctionClauseError) no function clause matching in Gradient.ElixirExpr.pp_cons/1    
    
    The following arguments were given to Gradient.ElixirExpr.pp_cons/1:
    
        # 1
        {:integer, 299, 0}
    
    Attempted function clauses (showing 3 out of 3):
    
        defp pp_cons({:cons, _, h, {nil, _}})
        defp pp_cons({:cons, _, h, {:var, _, _} = v})
        defp pp_cons({:cons, _, h, t})
    
    (gradient 0.1.0) Gradient.ElixirExpr.pp_cons/1
    (gradient 0.1.0) lib/gradient/elixir_expr.ex:491: Gradient.ElixirExpr.pp_cons/1
    (gradient 0.1.0) lib/gradient/elixir_expr.ex:68: Gradient.ElixirExpr.pp_expr/1
    (elixir 1.15.5) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2
    (elixir 1.15.5) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2
    (gradient 0.1.0) lib/gradient/elixir_expr.ex:158: Gradient.ElixirExpr.pp_expr/1
    (gradient 0.1.0) lib/gradient/elixir_expr.ex:68: Gradient.ElixirExpr.pp_expr/1
    (elixir 1.15.5) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2

I've noticed that I can fix the crash by changing the code to the following

  @spec crash() :: number()
  def crash() do
    order = 2
    key = 5
    zero = 0
    with {:atomic, [{_, [^order, ^key | ^zero], value}]} <- indirection(order, key, order) do
      2 + 5
    end
  end

the | 0 for some reason is causing issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants