Mercury-Language/mercury

Mode error in semidet list pattern matching without intermediate variable

jrfondren opened this issue · 1 comments

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.

You can work around this by changing the line to:

split_at_string("==", Rest) = [User, _Owner, _, _, _Docroot | _]