'unification cannot succeed' warning is very easily dropped
jrfondren opened this issue · 1 comments
jrfondren commented
This properly warns:
:- module recur.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module list.
main(!IO) :-
io.command_line_arguments(Args, !IO),
( if Args = [_ | Args] then
io.set_exit_status(1, !IO)
else
true
).
With output:
Making Mercury/int3s/recur.int3
Making Mercury/ints/recur.int
Making Mercury/cs/recur.c
recur.m:010: In clause for `main(di, uo)':
recur.m:010: warning: unification of `Args' and list.'[|]' cannot succeed,
recur.m:010: because `Args' cannot be equal to a term containing itself.
recur.m:010: Warning: the condition of this if-then-else cannot succeed.
Making Mercury/os/recur.o
Making recur
This (the same code with a second pre-|
binding) does not:
:- module recur.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module list.
main(!IO) :-
io.command_line_arguments(Args, !IO),
( if Args = [_, _ | Args] then
io.set_exit_status(1, !IO)
else
true
).
This came up in troubleshooting some unusual command line handling (for an app that can't just use getopt):
else if Args = [NStr, Command | Args] then
( if to_int(NStr, N) then
Res = ok(options(!.Opt^p_input, !.Opt^p_brief, N, Command, Args))
else
Res = error(count(NStr))
)
zsomogyi commented
The compiler can now generate warnings for code like this in many more situations.
The change that does this is in the latest ROTD.