gradient icon indicating copy to clipboard operation
gradient copied to clipboard

Fails to recognize that pos_integer() * pos_integer() will always return pos_integer()

Open skwerlman opened this issue 10 months ago • 0 comments

I have the following code:

{dx, dy} = Matrex.size(matrix)
elems = dx * dy

Matrex.size/1 has a spec of size(matrex()) :: {index(), index()} where index() is an alias for pos_integer().

When I use elems later on in code that expects an index(), gradient incorrectly complains that it has type integer():

lib/noise/printer.ex: Matrex.reshape()/3 call arguments on line 11 don't match the function type:
(list(matrex()), index(), index() -> matrex())
(list(element()), index(), index() -> matrex())
(matrex(), index(), index() -> matrex())
(Range.t(), index(), index() -> matrex())
(Enumerable.t(), index(), index() -> matrex())
Inferred argument types:
%{required(:__struct__) => Matrex, required(:data) => binary()}, 1, integer()

for now im working around this with this function:

@compile {:inline,
          hack_to_make_gradient_realize_that_pos_int_times_pos_int_is_always_pos_int: 2}
@spec hack_to_make_gradient_realize_that_pos_int_times_pos_int_is_always_pos_int(
        pos_integer(),
        pos_integer()
      ) :: pos_integer()
defp hack_to_make_gradient_realize_that_pos_int_times_pos_int_is_always_pos_int(a, b), do: a * b

skwerlman avatar Apr 20 '24 21:04 skwerlman