xadhoom

xadhoom

Well,

while migrating to elixir 1.11.3 (from 1.10.4) I’ve a new warning about a somewhat complex guard expression that has incompatible types.

An example code triggering that is something like:

  @allowed_types [
    :any,
    :atom,
    :boolean,
    false,
    :float,
    :integer,
    :keyword,
    :list,
    :map,
    nil,
    :number,
    :string,
    :struct,
    true,
    :tuple
  ]

  defguardp is_complex(param)
            when (is_tuple(param) and
                    elem(param, 0) in @allowed_types) or
                   param in @allowed_types

  def hello(param) when is_atom(param) and is_complex(param) do
    "1st guard: #{inspect(param)}"
  end

  def hello(param) when is_complex(param) do
    "2nd guard: #{inspect(param)}"
  end

The warning is pretty long, only on the first hello/1

warning: incompatible types:

    atom() !~ tuple()

in expression:

    # lib/foo.ex:38
    is_atom(param) and (is_tuple(param) and (elem(param, 0) === :any or elem(param, 0) === :atom or elem(param, 0) === :boolean or elem(param, 0) === false or elem(param, 0) === :float or elem(param, 0) === :integer or elem(param, 0) === :keyword or elem(param, 0) === :list or elem(param, 0) === :map or elem(param, 0) === nil or elem(param, 0) === :number or elem(param, 0) === :string or elem(param, 0) === :struct or elem(param, 0) === true or elem(param, 0) === :tuple) or (param === :any or param === :atom or param === :boolean or param === false or param === :float or param === :integer or param === :keyword or param === :list or param === :map or param === nil or param === :number or param === :string or param === :struct or param === true or param === :tuple))

where "param" was given the type atom() in:

    # lib/foo.ex:38
    is_atom(param)

where "param" was given the type tuple() in:

    # lib/foo.ex:38
    is_tuple(param) and (elem(param, 0) === :any or elem(param, 0) === :atom or elem(param, 0) === :boolean or elem(param, 0) === false or elem(param, 0) === :float or elem(param, 0) === :integer or elem(param, 0) === :keyword or elem(param, 0) === :list or elem(param, 0) === :map or elem(param, 0) === nil or elem(param, 0) === :number or elem(param, 0) === :string or elem(param, 0) === :struct or elem(param, 0) === true or elem(param, 0) === :tuple) or (param === :any or param === :atom or param === :boolean or param === false or param === :float or param === :integer or param === :keyword or param === :list or param === :map or param === nil or param === :number or param === :string or param === :struct or param === true or param === :tuple)

Conflict found at
  lib/foo.ex:38: Foo.hello/1

The expression works perfectly as expected and while it can be simplified to avoid the compiler warning, I’m really curious on what’s wrong here, if is something related to elixir 1.11 or the author.

In the example code the custom guard does not make a lot of sense, but in the original one is used to avoid creating different guards and reusing the same one everywhere.

Any suggestion ?

Showing Posts 1 to 4

josevalim

josevalim

Creator of Elixir

It is related to Elixir. We already have something in the issues tracker to handle this case. :slight_smile:

xadhoom

xadhoom OP

Great! I did a quick search in the issues and the most similar is this one "Incompatible types in guard" warning · Issue #10611 · elixir-lang/elixir · GitHub which is closed but does not apply here ( tested also with latest master of today and still happens ), so must be some different issue which I did not noticed.

Thanks, I’ll take a look on the issues so.

eksperimental

eksperimental

Here’s a reduced test case.

defmodule Warning do
  defguardp is_tuple_or_nil(param) when is_nil(param) or is_tuple(param)
                   
  def hello(param) when is_atom(param) and is_tuple_or_nil(param) do
    :is_atom_or_nil
  end
end
— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
psy-q
I’m trying to set up Emacs with elixir-ls via lsp-mode and credo via Flycheck. This should mostly be preconfigured as Flycheck picks up c...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews