%---------------------------------------------------------------------------% % vim: ts=4 sw=4 et ft=mercury %---------------------------------------------------------------------------% % % Predicates generated by the untupling transformation were being given the % same forms of names, no matter if the original procedure being transformed % was a predicate or a function. If a module had a predicate and a function % with the same name and arity, and tracing was enabled, and a low enough % optimisation level was being used, this would result in an exception being % thrown. % % mmc -C -O0 --untuple --trace deep --trace-optimized untuple_bug.m % % Uncaught Mercury exception: % Software Error: map__det_insert: key already present % Key Type: ll_backend.llds.label % Key Value: internal(2, proc(unqualified("untuple_bug"), predicate, % unqualified("untuple_bug"), "untupling_0__pred__f__0__1", 1, 0)) % Value Type: ll_backend.llds.data_addr % % A similar nameclash happened when two procedures of the same name but % different arities were expanded into procedures of the same arity. :- module untuple_bug. :- interface. :- type t ---> t(int). :- type tt ---> tt(int, int). % A function and predicate of the same name and arity. :- func f = t. :- pred f(t::out) is det. % Two predicates that expand into the same name and arity. :- pred g(t::in, t::in) is semidet. :- pred g(tt::in) is semidet. :- pred h(t::in, t::in) is semidet. :- pred h(tt::in) is semidet. :- implementation. f = t(0). f(t(0)). g(t(T), t(T)). g(tt(T, T)). % These are on the same line to make sure that a counter is being used % properly when generating names. h(t(T), t(T)). h(tt(T, T)).