mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-20 20:03:44 +00:00
Estimated hours taken: 6 Fix a bug where type errors were causing spurious mode errors, compiler/post_typecheck.m: Add new predicate post_typecheck__ill_typed_pred, which just module-qualifies the pred declaration for that pred. This is necessary to avoid spurious mode errors in predicates that call the ill-typed pred. compiler/typecheck.m: Call post_typecheck__ill_typed_pred on ill-typed predicates before calling module_info_remove_pred. We need to call it here because later passes won't process the pred once it has been removed. tests/invalid/Mmakefile: tests/invalid/spurious_mode_error.m: tests/invalid/spurious_mode_error.err_exp: Regression test for the above-mentioned bug.
127 lines
2.1 KiB
Mathematica
127 lines
2.1 KiB
Mathematica
:- module spurious_mode_error.
|
|
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io__state::di, io__state::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module char, float, int, list, string, std_util.
|
|
|
|
:- type opt(T)
|
|
---> a(pred(int, T, T))
|
|
; b(pred(string, T, T))
|
|
; c(pred(float, T, T))
|
|
.
|
|
|
|
:- inst opt = bound((
|
|
a(pred(in, in, out) is det)
|
|
; b(pred(in, in, out) is det)
|
|
; c(pred(in, in, out) is det)
|
|
)).
|
|
|
|
:- type f(T)
|
|
---> f(
|
|
maybe(pred(int, T, T)),
|
|
maybe(pred(string, T, T)),
|
|
maybe(pred(float, T, T))
|
|
).
|
|
|
|
:- inst m(I) = bound((no ; yes(I))).
|
|
|
|
:- inst f = bound(f(
|
|
m(pred(in, in, out) is det),
|
|
m(pred(in, in, out) is det),
|
|
m(pred(in, in, out) is det)
|
|
)).
|
|
|
|
main -->
|
|
{ makeit([a(foo), b(bar), c(baz)], f(no, no, no), Thing) },
|
|
{ foldit([i(23), s("42"), f(4.2)], Thing, 0, Stuff) },
|
|
write(Stuff).
|
|
|
|
:- pred foldit(list(string__poly_type), f(T), T, T).
|
|
:- mode foldit(in, in(f), in, out) is det.
|
|
|
|
foldit([], _F, T, T).
|
|
foldit([X|Xs], F, T0, T) :-
|
|
(
|
|
X = i(I),
|
|
(
|
|
F = f(no, _, _),
|
|
T1 = T0
|
|
;
|
|
F = f(yes(Z), _, _),
|
|
call(Z, I, T0, T1)
|
|
)
|
|
;
|
|
X = s(S),
|
|
(
|
|
F = f(_, no, _),
|
|
T1 = T0
|
|
;
|
|
F = f(_, yes(Z), _),
|
|
call(Z, S, T0, T1)
|
|
)
|
|
;
|
|
X = f(W),
|
|
(
|
|
F = f(_, _, no),
|
|
T1 = T0
|
|
;
|
|
F = f(_, _, yes(Z)),
|
|
call(Z, W, T0, T1)
|
|
)
|
|
;
|
|
X = c(J),
|
|
foobie(J, T0, T1)
|
|
),
|
|
foldit(Xs, F, T1, T).
|
|
|
|
:- pred makeit(list(opt(T)), f(T), f(T)).
|
|
:- mode makeit(in(list_skel(opt)), in(f), out(f)) is det.
|
|
|
|
makeit([], F, F).
|
|
makeit([Opt|Opts], F0, F) :-
|
|
add_opt(Opt, F0, F1),
|
|
makeit(Opts, F1, F).
|
|
|
|
:- pred add_opt(opt(T), f(T), f(T)).
|
|
:- mode add_opt(in(opt), in(f), out(f)) is det.
|
|
|
|
add_opt(a(Z), F0, F) :-
|
|
F0 = f(_, B, C),
|
|
F = f(yes(Z), B, C).
|
|
add_opt(b(Z), F0, F) :-
|
|
F0 = f(A, _, C),
|
|
F = f(A, yes(Z), C).
|
|
add_opt(c(Z), F0, F) :-
|
|
F0 = f(A, B, _),
|
|
F = f(A, B, yes(Z)).
|
|
|
|
:- pred foo(int, T, T).
|
|
:- mode foo(in, in, out) is det.
|
|
|
|
foo(_, T, T).
|
|
|
|
:- pred bar(string, T, T).
|
|
:- mode bar(in, in, out) is det.
|
|
|
|
bar(_, T, T).
|
|
|
|
:- pred baz(float, T, T).
|
|
:- mode baz(in, in, out) is det.
|
|
|
|
baz(_, T, T).
|
|
|
|
/* XXX to make the bug go away, uncomment this predicate!
|
|
:- pred foobie(char, T, T).
|
|
:- mode foobie(in, in, out) is det.
|
|
|
|
foobie(_, T, T).
|
|
*/
|
|
|
|
|