Mode error in semidet list pattern matching without intermediate variable
jrfondren opened this issue · 1 comments
jrfondren commented
This is observed on rotd-2019-09-05 and on a Mercury build from Jul 14.
This module:
:- module split2.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module list, string.
main(!IO) :-
Line = "example.com: exa==root==addon==example.example.com==/home/exa==127.0.0.1:80==127.0.0.1:443====0==",
( if
[_Domain, Rest] = split_at_string(": ", Line),
[User, _Owner, _, _, _Docroot | _] = split_at_string("==", Rest)
%L = split_at_string("==", Rest),
%L = [User, _Owner, _, _, _Docroot | _]
then
io.print_line(User, !IO)
else
io.set_exit_status(1, !IO)
).
Fails to compile with these errors:
split2.m:013: In clause for `'__Unify__'(in, (unique(list.'[|]'(free,
split2.m:013: unique(list.'[|]'(free, unique(list.'[|]'(free,
split2.m:013: unique(list.'[|]'(free, free)))))))) >>
split2.m:013: bound(list.'[|]'(ground, bound(list.'[|]'(ground,
split2.m:013: bound(list.'[|]'(ground, bound(list.'[|]'(ground,
split2.m:013: ground))))))))), (ground >> bound(list.'[|]'(ground,
split2.m:013: bound(list.'[|]'(ground, bound(list.'[|]'(ground,
split2.m:013: bound(list.'[|]'(ground, ground))))))))))':
split2.m:013: mode error in unification of `HeadVar__1' and `list.[ArgX1 |
split2.m:013: V_15]'.
split2.m:013: Variable `HeadVar__1' has instantiatedness
split2.m:013: unique(
split2.m:013: '[|]'(
split2.m:013: free,
split2.m:013: unique(
split2.m:013: '[|]'(
split2.m:013: free,
split2.m:013: unique(
split2.m:013: '[|]'(
split2.m:013: free,
split2.m:013: unique(
split2.m:013: '[|]'(free, free)
split2.m:013: )
split2.m:013: )
split2.m:013: )
split2.m:013: )
split2.m:013: )
split2.m:013: )
split2.m:013: ),
split2.m:013: term `list.[ArgX1 | V_15]' has instantiatedness
split2.m:013: `named inst list.'[|]'(ground, free)'.
If the offending line is commented out and the next two lines are uncommented, it works just fine. I encountered this bug when adapting code that did some very simple parsing of cPanel's 'userdatadomains' file to only retrieve the User field.
AlaskanEmily commented
You can work around this by changing the line to:
split_at_string("==", Rest) = [User, _Owner, _, _, _Docroot | _]