%---------------------------------------------------------------------------% % vim: ts=4 sw=4 et ft=mercury %---------------------------------------------------------------------------% % % We used to get this compiler abort on this file: % % Uncaught Mercury exception: % Software Error: check_hlds.det_analysis: % predicate `check_hlds.det_analysis.det_infer_unify'/13: % Unexpected: complicated_unify but no var % % The ultimate cause was the three-fold duplication of the X = Y test in p/4 % due to the two-level switch on X and Y. In two of the copies, X and Y are % known to be non-unifiable (X = a/1 and Y = b/1 or vice versa). Both of those % copies of X = Y use a mode of the unification procedure of t that cannot % succeed, and which contain var/functor unifications that cannot succeed. % The compiler abort was due to determinism analysis not being able to compute % a failure context from a var/functor unification that cannot succeed. :- module complicated_unify_bug. :- interface. :- import_module io. :- pred main(io::di, io::uo) is det. :- implementation. :- import_module bool. :- import_module int. :- import_module string. :- type t ---> a(int) ; b(string). main(!IO) :- do_test(a(1), a(1), !IO), do_test(a(2), a(3), !IO), do_test(a(4), b("four"), !IO), do_test(b("five"), a(5), !IO), do_test(b("six"), b("six"), !IO), do_test(b("seven"), b("eight"), !IO). :- pred do_test(t::in, t::in, io::di, io::uo) is det. do_test(X, Y, !IO) :- p(X, Y, Z, S), io.write(Z, !IO), io.write_string(" ", !IO), io.write_string(S, !IO), io.nl(!IO). :- pred p(t::in, t::in, t::out, string::out) is det. :- pragma no_inline(p/4). p(X, Y, Z, S) :- ( X = a(XN), Y = a(YN), Z = a(XN + YN), S = "aa" ; ( X = a(XN), Y = b(YS), Z = b(string.int_to_string(XN) ++ " " ++ YS) ; X = b(XS), Y = a(YN), Z = b(XS ++ " " ++ string.int_to_string(YN)) ; X = b(XS), Y = b(YS), Z = b(XS ++ " " ++ YS) ), ( if X = Y then S = "same" else S = "diff" ) ).