Warning emitted by integer combinator
lukaszsamson opened this issue · 3 comments
This code
defmodule ParserRepro do
import NimbleParsec
defparsec(:foo_parsec, integer(min: 1))
end
emits a warning
warning: this clause cannot match because of different types/sizes
debug:
defp foo_parsec__0(rest, acc, stack, context, line, offset) do
foo_parsec__1(rest, [], [acc | stack], context, line, offset)
end
defp foo_parsec__1(<<x0, rest::binary>>, acc, stack, context, comb__line, comb__offset) when x0 >= 48 and x0 <= 57 do
foo_parsec__2(rest, [x0 - 48] ++ acc, stack, context, comb__line, comb__offset + 1)
end
defp foo_parsec__1(rest, _acc, _stack, context, line, offset) do
{:error, "expected ASCII character in the range '0' to '9'", rest, context, line, offset}
end
defp foo_parsec__2(rest, acc, stack, context, line, offset) do
case {:cont, context} do
{:cont, context} -> foo_parsec__4(rest, acc, stack, context, line, offset)
{:halt, context} -> foo_parsec__3(rest, acc, stack, context, line, offset)
end
end
defp foo_parsec__4(<<x0, rest::binary>>, acc, stack, context, comb__line, comb__offset) when x0 >= 48 and x0 <= 57 do
foo_parsec__5(rest, [x0] ++ acc, stack, context, comb__line, comb__offset + 1)
end
defp foo_parsec__4(rest, acc, stack, context, line, offset) do
foo_parsec__3(rest, acc, stack, context, line, offset)
end
defp foo_parsec__5(rest, acc, stack, context, line, offset) do
foo_parsec__2(rest, acc, stack, context, line, offset)
end
defp foo_parsec__3(rest, user_acc, [acc | stack], context, line, offset) do
_ = user_acc
foo_parsec__6(
rest,
(
[head | tail] = :lists.reverse(user_acc)
[:lists.foldl(fn x, acc -> x - 48 + acc * 10 end, head, tail)]
) ++ acc,
stack,
context,
line,
offset
)
end
defp foo_parsec__6(rest, acc, _stack, context, line, offset) do
{:ok, acc, rest, context, line, offset}
end
the warning comes from foo_parsec__2
.
Interestingly, the warning is not emitted when compiling the project with mix. It is only emitted in elixir-ls.
You can mark the relevant bit as generated: true
in the compiler. Does that work?
I tried setting generated: true
on the quote
using output of NimbleParsec.Compiler.compile
but it didn't help.
I have the same problem. With the example, I found that there is a difference between the generated code when elixir ls compiles it and when mix compiles it:
(left is elixir ls and right is mix)
Not sure why elixir ls is compiling the version with the strange pattern match, which is the reason for the compiler warning (case {:cont, context}
with a pattern {:halt, context}
).