mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-30 16:54:41 +00:00
Estimated hours taken: 6
Branches: main
In the presence of large amounts of unresolved overloading, the compiler could
consume unbounded amounts of space and time. This diff fixes this problem.
I tried to avoid having this fix lead to a slowdown; in fact, the last three
changes to typecheck_info.m lead to a slight speedup.
compiler/options.m:
doc/user_guide.texi:
Add a new option, --typecheck-ambiguity-error-limit. This gives the
number of type assignments that cause the typechecker to stop
processing further goals. No such facility existed before.
Add a new option, --typecheck-ambiguity-warn-limit. This gives the
number of type assignments that cause the typechecker to emit a
warning. This generalizes the previous hard-coded value in typecheck.m.
Move the definitions of some existing options to the right set of
options.
compiler/typecheck_info.m:
Add the values of the two new options as fields to the typecheck_info,
since we will want to look them up often.
Separate out the error_specs concerned with overloading from the other
error specs, since we want to be able to have an error about excessive
overloading to overwrite a warning about excessive overloading
generated earlier.
Fix a performance bug: the pred_markers were being looked up in the
pred_info each time they were asked for, even though they were also
available directly in a field.
Move the least frequently accessed fields of the typecheck_info
into a separate substructure, to reduce amount of allocation required.
Delete the get and set predicates for the most frequently used fields,
to avoid the overhead of cross-module calls. These fields are now
accessed via field access functions.
compiler/typecheck.m:
Don't typecheck goals if the number of type assignments exceeds
the error limit.
Conform to the changes in typecheck_info.m.
compiler/typecheck_errors.m:
Add a function to generate the new error message.
Conform to the changes in typecheck_info.m.
tests/invalid/ambiguous_overloading_error.{m,err_exp}:
Add this new test case. It is a copy of the existing test case
warnings/ambiguous_overloading, but with more overloading. Old
compilers consume so much memory on it that they eventually run out
and crash, but the new compiler generates an error message
and finishes quickly.
tests/invalid/Mmakefile:
Enable the new test case.
tests/warnings/ambiguous_overloading.exp:
Update the output of this test case to account for the fact that
the context of the warning is now that of the goal *after* the point
at which the number of type assignments exceeds 50, not the goal
*before* this point.
118 lines
2.4 KiB
Mathematica
118 lines
2.4 KiB
Mathematica
% Test the error for ambiguous overloading.
|
|
:- module ambiguous_overloading_error.
|
|
|
|
:- interface.
|
|
|
|
:- import_module getopt.
|
|
:- import_module io.
|
|
:- import_module list.
|
|
|
|
:- type foo ---> f ; g.
|
|
:- type bar ---> f ; h.
|
|
|
|
:- pred ambig_overload1(list(foo)::out) is det.
|
|
|
|
:- type baz ---> a1 ; a2 ; a3.
|
|
:- type qux ---> a1 ; a2 ; a4.
|
|
|
|
:- pred ambig_overload2(list(baz)::out) is det.
|
|
|
|
:- pred test_lt(int::out) is det.
|
|
|
|
:- type set_param
|
|
---> set_print
|
|
; set_browse
|
|
; set_print_all
|
|
; set_flat
|
|
; set_raw_pretty
|
|
; set_verbose
|
|
; set_pretty.
|
|
|
|
:- pred set_browser_param_from_option_table(option_table(set_param)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module bool.
|
|
:- import_module int.
|
|
:- import_module float.
|
|
|
|
ambig_overload1(L) :-
|
|
A = f, B = f, C = f, D = f, E = f, F = f,
|
|
G = f, H = f, I = f, J = f, K = f, L = f,
|
|
L = [A, B, C, D, E, F, G, H, I, J, K, L].
|
|
|
|
ambig_overload2(L) :-
|
|
A = a1, B = a1, C = a2, D = a2, E = a1, F = a1, G = a2,
|
|
L = [A, B, C, D, E, F, G].
|
|
|
|
test_lt(X) :-
|
|
(
|
|
X1 < Y1,
|
|
X2 < Y2,
|
|
X3 < Y3,
|
|
X4 < Y4,
|
|
X5 < Y5,
|
|
X6 < Y6,
|
|
X7 < Y7,
|
|
X8 < Y8,
|
|
X9 < Y9,
|
|
XA < YA,
|
|
XB < YB,
|
|
XC < YC,
|
|
XD < YD,
|
|
XE < YE,
|
|
XF < YF,
|
|
XG < YG,
|
|
XH < YH,
|
|
XI < YI,
|
|
XJ < YJ,
|
|
XK < YK,
|
|
XL < YL,
|
|
XM < YM,
|
|
XN < YN,
|
|
X1 = 1, Y1 = 11,
|
|
X2 = 2, Y2 = 12,
|
|
X3 = 3, Y3 = 13,
|
|
X4 = 4.0, Y4 = 14.0,
|
|
X5 = 5.0, Y5 = 15.0,
|
|
X6 = 6.0, Y6 = 16.0,
|
|
X7 = 7.0, Y7 = 17.0,
|
|
X8 = 8.0, Y8 = 18.0,
|
|
X9 = 9.0, Y9 = 19.0,
|
|
XA = 10.0, YA = 20.0,
|
|
XB = 11.0, YB = 21.0,
|
|
XC = 12.0, YC = 22.0,
|
|
XD = 13.0, YD = 23.0,
|
|
XE = 14.0, YE = 24.0,
|
|
XF = 15.0, YF = 25.0,
|
|
XG = 16.0, YG = 26.0,
|
|
XH = 17.0, YH = 27.0,
|
|
XI = 18.0, YI = 28.0,
|
|
XJ = 19.0, YJ = 29.0,
|
|
XK = 20.0, YK = 30.0,
|
|
XL = 21.0, YL = 31.0,
|
|
XM = 22.0, YM = 32.0,
|
|
XN = 23.0, YN = 33.0
|
|
->
|
|
X = 0
|
|
;
|
|
X = 1
|
|
).
|
|
|
|
set_browser_param_from_option_table(OptionTable, !IO) :-
|
|
set_browser_param(
|
|
lookup_bool_option(OptionTable, set_print),
|
|
lookup_bool_option(OptionTable, set_browse),
|
|
lookup_bool_option(OptionTable, set_print_all),
|
|
lookup_bool_option(OptionTable, set_flat),
|
|
lookup_bool_option(OptionTable, set_raw_pretty),
|
|
lookup_bool_option(OptionTable, set_verbose),
|
|
lookup_bool_option(OptionTable, set_pretty),
|
|
!IO).
|
|
|
|
:- pred set_browser_param(bool::in, bool::in, bool::in, bool::in,
|
|
bool::in, bool::in, bool::in, io::di, io::uo) is det.
|
|
|
|
set_browser_param(_, _, _, _, _, _, _, !IO).
|