I apologize first if this is correct behavior.
NOTE: The example of reproduce code founded in elixir-lsp/elixir-ls.
Consider this code:
defmodule IgnorePattern do
def ignore_var() do
_otp_release = String.to_integer(System.otp_release())
{_compiled_with, _} = System.build_info() |> Map.fetch!(:otp_release) |> Integer.parse()
end
def ignore_var_not_warning() do
_otp_release = String.to_integer(System.otp_release())
end
end
When try compile with mix clean --all && mix compile. The result is:
Compiling 1 file (.ex)
warning: the result of the expression is ignored (suppress the warning by assigning the expression to the _ variable)
lib/ignore_pattern.ex:3
Generated ignore_pattern app
The _otp_release inside a function ignore_var_not_warning/0 should has a warning message as same as _otp_release in ignore_var/0 has. The current of compiler hasn't.
The behavior is as expected. In the function ignore_var the result of String.to_integer(System.otp_release()) will never be used and in ignore_var_not_warning the value will be used as the return value of the function.
Closing per the reasons explained by @NickNeck. The result of expression is being used on the second case (as return value).
@josevalim @NickNeck Thanks for your clarify. And may I asks you a few questions:
_otp_release in ignore_var, so why the compiler doesn't complain the primitive value? For example: def ignore_var_2() do
_otp_release = 1
{_compiled_with, _} = System.build_info() |> Map.fetch!(:otp_release) |> Integer.parse()
end
AFAIK It's a heuristic in the Erlang compiler where it assumes such constants might be a result of some configuration and warning on those would be too annoying.