[m-rev.] for post-commit review: limiting number of type assignments

Zoltan Somogyi zs at csse.unimelb.edu.au
Mon May 14 18:19:38 AEST 2007


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.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.557
diff -u -b -r1.557 options.m
--- compiler/options.m	7 May 2007 05:21:34 -0000	1.557
+++ compiler/options.m	10 May 2007 14:49:28 -0000
@@ -792,12 +792,14 @@
     ;       options_search_directories
     ;       use_subdirs
     ;       use_grade_subdirs
-
-    % Miscellaneous Options
     ;       search_directories
     ;       intermod_directories
     ;       use_search_directories_for_intermod
+
+    % Miscellaneous Options
     ;       filenames_from_stdin
+    ;       typecheck_ambiguity_warn_limit
+    ;       typecheck_ambiguity_error_limit
     ;       help
     ;       version
     ;       fullarch
@@ -1565,6 +1567,8 @@
 option_defaults_2(miscellaneous_option, [
     % Miscellaneous Options
     filenames_from_stdin                -   bool(no),
+    typecheck_ambiguity_warn_limit      -   int(50),
+    typecheck_ambiguity_error_limit     -   int(3000),
     help                                -   bool(no),
     version                             -   bool(no),
     fullarch                            -   string(""),
@@ -2358,6 +2362,10 @@
                     use_search_directories_for_intermod).
 
 % misc options
+long_option("typecheck-ambiguity-warn-limit",
+                                    typecheck_ambiguity_warn_limit).
+long_option("typecheck-ambiguity-error-limit",
+                                    typecheck_ambiguity_error_limit).
 long_option("help",                 help).
 long_option("version",              version).
 long_option("filenames-from-stdin", filenames_from_stdin).
@@ -4837,6 +4845,14 @@
         "\tis reached. (This allows a program or user to interactively",
         "\tcompile several modules without the overhead of process",
         "\tcreation for each one.)",
+        "--typecheck-ambiguity-warn-limit <n>",
+        "\tSet the number of type assignments required to generate a warning",
+        "\tabout highly ambiguous overloading to <n>.",
+        "--typecheck-ambiguity-error-limit <n>",
+        "\tSet the number of type assignments required to generate an error",
+        "\tabout excessively ambiguous overloading to <n>. If this limit is",
+        "\treached, the typechecker will not process the predicate or",
+        "\tfunction any further.",
         "--version",
         "\tDisplay the compiler version.",
 
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.420
diff -u -b -r1.420 typecheck.m
--- compiler/typecheck.m	26 Apr 2007 09:10:42 -0000	1.420
+++ compiler/typecheck.m	14 May 2007 00:22:18 -0000
@@ -282,8 +282,8 @@
     ( pred_info_is_imported(PredInfo0) ->
         true
     ;
-        typecheck_pred_if_needed(Iteration, PredId, PredInfo0,
-            PredInfo1, !ModuleInfo, PredSpecs, PredChanged),
+        typecheck_pred_if_needed(Iteration, PredId, PredInfo0, PredInfo1,
+            !ModuleInfo, PredSpecs, PredChanged),
         module_info_get_globals(!.ModuleInfo, Globals),
         ContainsErrors = contains_errors(Globals, PredSpecs),
         (
@@ -292,7 +292,7 @@
             module_info_set_preds(Preds, !ModuleInfo)
         ;
             ContainsErrors = yes,
-%       /********************
+
 %       This code is not needed at the moment,
 %       since currently we don't run mode analysis if
 %       there are any type errors.
@@ -313,7 +313,7 @@
 %           post_finish_ill_typed_pred(ModuleInfo0,
 %               PredId, PredInfo1, PredInfo),
 %           map.det_update(Preds0, PredId, PredInfo, Preds),
-%       *******************/
+
             map.det_update(Preds0, PredId, PredInfo1, Preds),
             module_info_set_preds(Preds, !ModuleInfo),
             module_info_remove_predid(PredId, !ModuleInfo)
@@ -439,8 +439,8 @@
             )
         ;
             ClausesRep1IsEmpty = no,
-            pred_info_get_typevarset(!.PredInfo, TypeVarSet0),
             pred_info_get_import_status(!.PredInfo, Status),
+            pred_info_get_typevarset(!.PredInfo, TypeVarSet0),
             ( check_marker(Markers0, marker_infer_type) ->
                 % For a predicate whose type is inferred, the predicate is
                 % allowed to bind the type variables in the head of the
@@ -478,11 +478,11 @@
             ;
                 IsFieldAccessFunction = no
             ),
-            pred_info_get_markers(!.PredInfo, Markers),
+            pred_info_get_markers(!.PredInfo, PredMarkers),
             typecheck_info_init(!.ModuleInfo, PredId, IsFieldAccessFunction,
                 TypeVarSet0, VarSet, ExplicitVarTypes0, !.HeadTypeParams,
-                Constraints, Status, Markers, StartingSpecs, !:Info),
-            typecheck_info_get_type_assign_set(!.Info, OrigTypeAssignSet),
+                Constraints, Status, PredMarkers, StartingSpecs, !:Info),
+            OrigTypeAssignSet = !.Info ^ tc_info_type_assign_set,
             get_clause_list(ClausesRep1, Clauses1),
             typecheck_clause_list(HeadVars, ArgTypes0, Clauses1, Clauses,
                 !Info),
@@ -617,7 +617,7 @@
 
                 Changed = no
             ),
-            typecheck_info_get_errors(!.Info, Specs)
+            typecheck_info_get_all_errors(!.Info, Specs)
         )
     ).
 
@@ -1264,7 +1264,7 @@
 typecheck_clause(HeadVars, ArgTypes, !Clause, !Info) :-
     Body0 = !.Clause ^ clause_body,
     Context = !.Clause ^clause_context,
-    typecheck_info_set_context(Context, !Info),
+    !:Info = !.Info ^ tc_info_context := Context,
 
     % Typecheck the clause - first the head unification, and then the body.
     typecheck_var_has_type_list(HeadVars, ArgTypes, 1, !Info),
@@ -1273,7 +1273,7 @@
         type_checkpoint("end of clause", !.Info, !IO)
     ),
     !:Clause = !.Clause ^ clause_body := Body,
-    typecheck_info_set_context(Context, !Info),
+    !:Info = !.Info ^ tc_info_context := Context,
     typecheck_check_for_ambiguity(clause_only, HeadVars, !Info).
 
 %-----------------------------------------------------------------------------%
@@ -1299,7 +1299,7 @@
     typecheck_info::in, typecheck_info::out) is det.
 
 typecheck_check_for_ambiguity(StuffToCheck, HeadVars, !Info) :-
-    typecheck_info_get_type_assign_set(!.Info, TypeAssignSet),
+    TypeAssignSet = !.Info ^ tc_info_type_assign_set,
     (
         % There should always be a type assignment, because if there is
         % an error somewhere, instead of setting the current type assignment
@@ -1321,7 +1321,7 @@
         %     head variables (and hence can't be resolved by looking at
         %     later clauses).
 
-        typecheck_info_get_errors(!.Info, ErrorsSoFar),
+        typecheck_info_get_all_errors(!.Info, ErrorsSoFar),
         (
             ErrorsSoFar = [],
             (
@@ -1331,7 +1331,7 @@
 
                 % Only report an error if the headvar types are identical
                 % (which means that the ambiguity must have occurred
-                % in the body)
+                % in the body).
                 type_assign_get_var_types(TypeAssign1, VarTypes1),
                 type_assign_get_var_types(TypeAssign2, VarTypes2),
                 type_assign_get_type_bindings(TypeAssign1, TypeBindings1),
@@ -1358,25 +1358,62 @@
     typecheck_info::in, typecheck_info::out) is det.
 
     % Typecheck a goal.
-    % Note that we save the context of the goal in the typeinfo for
+    % Note that we save the context of the goal in the typecheck_info for
     % use in error messages.  Also, if the context of the goal is empty,
-    % we set the context of the goal from the surrounding
-    % context saved in the type-info.  (That should probably be done
-    % in make_hlds, but it was easier to do here.)
+    % we set the context of the goal to the surrounding context saved in
+    % the typecheck_info.  (That should probably be done in make_hlds,
+    % but it was easier to do here.)
     %
 typecheck_goal(hlds_goal(GoalExpr0, GoalInfo0), hlds_goal(GoalExpr, GoalInfo),
         !Info) :-
     goal_info_get_context(GoalInfo0, Context),
     term.context_init(EmptyContext),
     ( Context = EmptyContext ->
-        typecheck_info_get_context(!.Info, EnclosingContext),
+        EnclosingContext = !.Info ^ tc_info_context,
         goal_info_set_context(EnclosingContext, GoalInfo0, GoalInfo)
     ;
         GoalInfo = GoalInfo0,
-        typecheck_info_set_context(Context, !Info)
+        !:Info = !.Info ^ tc_info_context := Context
+    ),
+
+    TypeAssignSet = !.Info ^ tc_info_type_assign_set,
+    list.length(TypeAssignSet, Count),
+
+    % Our algorithm handles overloading quite inefficiently: for each symbol
+    % that matches N declarations, we make N copies of the existing set of type
+    % assignments. In the worst case, therefore, the complexity of our
+    % algorithm (space complexity as well as time complexity) is therefore
+    % exponential in the number of ambiguous symbols.
+    %
+    % We issue a warning whenever the number of type assignments exceeds
+    % the warn limit, and stop typechecking (after generating an error)
+    % whenever it exceeds the error limit.
+
+    WarnLimit = !.Info ^ tc_info_ambiguity_warn_limit,
+    ( Count > WarnLimit ->
+        typecheck_info_get_ambiguity_error_limit(!.Info, ErrorLimit),
+        ( Count > ErrorLimit ->
+            % Override any existing overload warning.
+            ErrorSpec = report_error_too_much_overloading(!.Info),
+            typecheck_info_set_overload_error(yes(ErrorSpec), !Info),
+
+            % Don't call typecheck_goal_2 to do the actual typechecking,
+            % since it will almost certainly take too much time and memory.
+            GoalExpr = GoalExpr0
+        ;
+            typecheck_info_get_overload_error(!.Info, MaybePrevSpec),
+            (
+                MaybePrevSpec = no,
+                WarnSpec = report_warning_too_much_overloading(!.Info),
+                typecheck_info_set_overload_error(yes(WarnSpec), !Info)
+            ;
+                MaybePrevSpec = yes(_)
     ),
-    typecheck_goal_2(GoalExpr0, GoalExpr, GoalInfo, !Info),
-    check_warn_too_much_overloading(!Info).
+            typecheck_goal_2(GoalExpr0, GoalExpr, GoalInfo, !Info)
+        )
+    ;
+        typecheck_goal_2(GoalExpr0, GoalExpr, GoalInfo, !Info)
+    ).
 
 :- pred typecheck_goal_2(hlds_goal_expr::in, hlds_goal_expr::out,
     hlds_goal_info::in, typecheck_info::in, typecheck_info::out) is det.
@@ -1488,8 +1525,8 @@
         trace [io(!IO)] (
             type_checkpoint("unify", !.Info, !IO)
         ),
-        typecheck_info_set_arg_num(0, !Info),
-        typecheck_info_set_unify_context(UnifyContext, !Info),
+        !:Info = !.Info ^ tc_info_arg_num := 0,
+        !:Info = !.Info ^ tc_info_unify_context := UnifyContext,
         goal_info_get_goal_path(GoalInfo, GoalPath),
         typecheck_unification(LHS, RHS0, RHS, GoalPath, !Info),
         GoalExpr = unify(LHS, RHS, UnifyMode, Unification, UnifyContext)
@@ -1503,7 +1540,7 @@
         % correctly compute the HeadTypeParams that result from existentially
         % typed foreign_procs. (We could probably do that more efficiently
         % than the way it is done below, though.)
-        typecheck_info_get_type_assign_set(!.Info, OrigTypeAssignSet),
+        OrigTypeAssignSet = !.Info ^ tc_info_type_assign_set,
         ArgVars = list.map(foreign_arg_var, Args),
         goal_info_get_goal_path(GoalInfo, GoalPath),
         typecheck_call_pred_id(PredId, ArgVars, GoalPath, !Info),
@@ -1624,7 +1661,7 @@
     typecheck_info::in, typecheck_info::out) is det.
 
 typecheck_event_call(EventName, Args, !Info) :-
-    typecheck_info_get_module_info(!.Info, ModuleInfo),
+    ModuleInfo = !.Info ^ tc_info_module_info,
     module_info_get_event_set(ModuleInfo, EventSet),
     EventSpecMap = EventSet ^ event_set_spec_map,
     ( event_arg_types(EventSpecMap, EventName, EventArgTypes) ->
@@ -1647,15 +1684,16 @@
     is det.
 
 typecheck_call_pred(CallId, Args, GoalPath, PredId, !Info) :-
-    typecheck_info_get_type_assign_set(!.Info, OrigTypeAssignSet),
+    OrigTypeAssignSet = !.Info ^ tc_info_type_assign_set,
 
     % Look up the called predicate's arg types.
-    typecheck_info_get_module_info(!.Info, ModuleInfo),
+    ModuleInfo = !.Info ^ tc_info_module_info,
     module_info_get_predicate_table(ModuleInfo, PredicateTable),
     (
         CallId = simple_call_id(PorF, SymName, Arity),
+        typecheck_info_get_pred_markers(!.Info, PredMarkers),
         predicate_table_search_pf_sym_arity(PredicateTable,
-            calls_are_fully_qualified(!.Info ^ pred_markers),
+            calls_are_fully_qualified(PredMarkers),
             PorF, SymName, Arity, PredIdList)
     ->
         % Handle the case of a non-overloaded predicate specially
@@ -1694,7 +1732,7 @@
     typecheck_info::in, typecheck_info::out) is det.
 
 typecheck_call_pred_id(PredId, Args, GoalPath, !Info) :-
-    typecheck_info_get_module_info(!.Info, ModuleInfo),
+    ModuleInfo = !.Info ^ tc_info_module_info,
     module_info_get_predicate_table(ModuleInfo, PredicateTable),
     predicate_table_get_preds(PredicateTable, Preds),
     map.lookup(Preds, PredId, PredInfo),
@@ -1724,18 +1762,18 @@
     is det.
 
 typecheck_call_overloaded_pred(CallId, PredIdList, Args, GoalPath, !Info) :-
-    typecheck_info_get_context(!.Info, Context),
+    Context = !.Info ^ tc_info_context,
     Symbol = overloaded_pred(CallId, PredIdList),
     typecheck_info_add_overloaded_symbol(Symbol, Context, !Info),
 
     % Let the new arg_type_assign_set be the cross-product of the current
     % type_assign_set and the set of possible lists of argument types
     % for the overloaded predicate, suitable renamed apart.
-    typecheck_info_get_module_info(!.Info, ModuleInfo),
+    ModuleInfo = !.Info ^ tc_info_module_info,
     module_info_get_class_table(ModuleInfo, ClassTable),
     module_info_get_predicate_table(ModuleInfo, PredicateTable),
     predicate_table_get_preds(PredicateTable, Preds),
-    typecheck_info_get_type_assign_set(!.Info, TypeAssignSet0),
+    TypeAssignSet0 = !.Info ^ tc_info_type_assign_set,
     get_overloaded_pred_arg_types(PredIdList, Preds, ClassTable, GoalPath,
         TypeAssignSet0, [], ArgsTypeAssignSet),
 
@@ -1779,7 +1817,7 @@
 
 typecheck_var_has_polymorphic_type_list(Args, PredTypeVarSet, PredExistQVars,
         PredArgTypes, PredConstraints, !Info) :-
-    typecheck_info_get_type_assign_set(!.Info, TypeAssignSet0),
+    TypeAssignSet0 = !.Info ^ tc_info_type_assign_set,
     rename_apart(TypeAssignSet0, PredTypeVarSet, PredExistQVars,
         PredArgTypes, PredConstraints, [], ArgsTypeAssignSet),
     typecheck_var_has_arg_type_list(Args, 1, ArgsTypeAssignSet, !Info).
@@ -1836,11 +1874,11 @@
 typecheck_var_has_arg_type_list([], _, ArgTypeAssignSet, !Info) :-
     TypeAssignSet =
         convert_args_type_assign_set_check_empty_args(ArgTypeAssignSet),
-    typecheck_info_set_type_assign_set(TypeAssignSet, !Info).
+    !:Info = !.Info ^ tc_info_type_assign_set := TypeAssignSet.
 
 typecheck_var_has_arg_type_list([Var | Vars], ArgNum, ArgTypeAssignSet0,
         !Info) :-
-    typecheck_info_set_arg_num(ArgNum, !Info),
+    !:Info = !.Info ^ tc_info_arg_num := ArgNum,
     typecheck_var_has_arg_type(Var, ArgTypeAssignSet0, ArgTypeAssignSet1,
         !Info),
     typecheck_var_has_arg_type_list(Vars, ArgNum + 1, ArgTypeAssignSet1,
@@ -1934,7 +1972,7 @@
     unexpected(this_file, "typecheck_var_has_type_list: length mismatch").
 typecheck_var_has_type_list([], [], _, !Info).
 typecheck_var_has_type_list([Var | Vars], [Type | Types], ArgNum, !Info) :-
-    typecheck_info_set_arg_num(ArgNum, !Info),
+    !:Info = !.Info ^ tc_info_arg_num := ArgNum,
     typecheck_var_has_type(Var, Type, !Info),
     typecheck_var_has_type_list(Vars, Types, ArgNum + 1, !Info).
 
@@ -1942,7 +1980,7 @@
     typecheck_info::in, typecheck_info::out) is det.
 
 typecheck_var_has_type(Var, Type, !Info) :-
-    typecheck_info_get_type_assign_set(!.Info, TypeAssignSet0),
+    TypeAssignSet0 = !.Info ^ tc_info_type_assign_set,
     typecheck_var_has_type_2(TypeAssignSet0, Var, Type, [],
         TypeAssignSet),
     (
@@ -1952,7 +1990,7 @@
         Spec = report_error_var(!.Info, Var, Type, TypeAssignSet0),
         typecheck_info_add_error(Spec, !Info)
     ;
-        typecheck_info_set_type_assign_set(TypeAssignSet, !Info)
+        !:Info = !.Info ^ tc_info_type_assign_set := TypeAssignSet
     ).
 
 :- pred typecheck_var_has_type_2(type_assign_set::in, prog_var::in,
@@ -2025,32 +2063,6 @@
 
 %-----------------------------------------------------------------------------%
 
-    % Because we allow overloading, type-checking is NP-complete.
-    % Rather than disallow it completely, we issue a warning
-    % whenever "too much" overloading is used.  "Too much"
-    % is arbitrarily defined as anything which results in
-    % more than 50 possible type assignments.
-    %
-:- pred check_warn_too_much_overloading(typecheck_info::in,
-    typecheck_info::out) is det.
-
-check_warn_too_much_overloading(!Info) :-
-    (
-        typecheck_info_get_warned_about_overloading(!.Info, AlreadyWarned),
-        AlreadyWarned = no,
-        typecheck_info_get_type_assign_set(!.Info, TypeAssignSet),
-        list.length(TypeAssignSet, Count),
-        Count > 50
-    ->
-        Spec = report_warning_too_much_overloading(!.Info),
-        typecheck_info_add_error(Spec, !Info),
-        typecheck_info_set_warned_about_overloading(yes, !Info)
-    ;
-        true
-    ).
-
-%-----------------------------------------------------------------------------%
-
     % Type check a unification.
     % Get the type assignment set from the type info and then just
     % iterate over all the possible type assignments.
@@ -2062,7 +2074,7 @@
     typecheck_unify_var_var(X, Y, !Info).
 typecheck_unification(X, rhs_functor(Functor, ExistConstraints, Args),
         rhs_functor(Functor, ExistConstraints, Args), GoalPath, !Info) :-
-    typecheck_info_get_type_assign_set(!.Info, OrigTypeAssignSet),
+    OrigTypeAssignSet = !.Info ^ tc_info_type_assign_set,
     typecheck_unify_var_functor(X, Functor, Args, GoalPath, !Info),
     perform_context_reduction(OrigTypeAssignSet, !Info).
 typecheck_unification(X,
@@ -2078,7 +2090,7 @@
     typecheck_info::in, typecheck_info::out) is det.
 
 typecheck_unify_var_var(X, Y, !Info) :-
-    typecheck_info_get_type_assign_set(!.Info, TypeAssignSet0),
+    TypeAssignSet0 = !.Info ^ tc_info_type_assign_set,
     typecheck_unify_var_var_2(TypeAssignSet0, X, Y, [], TypeAssignSet),
     (
         TypeAssignSet = [],
@@ -2087,7 +2099,7 @@
         Spec = report_error_unif_var_var(!.Info, X, Y, TypeAssignSet0),
         typecheck_info_add_error(Spec, !Info)
     ;
-        typecheck_info_set_type_assign_set(TypeAssignSet, !Info)
+        !:Info = !.Info ^ tc_info_type_assign_set := TypeAssignSet
     ).
 
 :- pred typecheck_unify_var_functor(prog_var::in, cons_id::in,
@@ -2110,7 +2122,7 @@
             ConsDefnList = [_]
         ;
             ConsDefnList = [_, _ | _],
-            typecheck_info_get_context(!.Info, Context),
+            Context = !.Info ^ tc_info_context,
             Sources = list.map(project_cons_type_info_source, ConsDefnList),
             Symbol = overloaded_func(Functor, Sources),
             typecheck_info_add_overloaded_symbol(Symbol, Context, !Info)
@@ -2118,7 +2130,7 @@
 
         % Produce the ConsTypeAssignSet, which is essentially the
         % cross-product of the TypeAssignSet0 and the ConsDefnList.
-        typecheck_info_get_type_assign_set(!.Info, TypeAssignSet0),
+        TypeAssignSet0 = !.Info ^ tc_info_type_assign_set,
         typecheck_unify_var_functor_get_ctors(TypeAssignSet0,
             !.Info, ConsDefnList, [], ConsTypeAssignSet),
         (
@@ -2165,10 +2177,10 @@
         % original type assign set.
         (
             TypeAssignSet = [],
-            typecheck_info_set_type_assign_set(TypeAssignSet0, !Info)
+            !:Info = !.Info ^ tc_info_type_assign_set := TypeAssignSet0
         ;
             TypeAssignSet = [_ | _],
-            typecheck_info_set_type_assign_set(TypeAssignSet, !Info)
+            !:Info = !.Info ^ tc_info_type_assign_set := TypeAssignSet
         )
     ).
 
@@ -2442,7 +2454,7 @@
 
 typecheck_lambda_var_has_type(Purity, PredOrFunc, EvalMethod, Var, ArgVars,
         !Info) :-
-    typecheck_info_get_type_assign_set(!.Info, TypeAssignSet0),
+    TypeAssignSet0 = !.Info ^ tc_info_type_assign_set,
     typecheck_lambda_var_has_type_2(TypeAssignSet0, Purity, PredOrFunc,
         EvalMethod, Var, ArgVars, [], TypeAssignSet),
     (
@@ -2453,7 +2465,7 @@
             Var, ArgVars, TypeAssignSet0),
         typecheck_info_add_error(Spec, !Info)
     ;
-        typecheck_info_set_type_assign_set(TypeAssignSet, !Info)
+        !:Info = !.Info ^ tc_info_type_assign_set := TypeAssignSet
     ).
 
 :- pred typecheck_lambda_var_has_type_2(type_assign_set::in, purity::in,
@@ -2542,12 +2554,12 @@
 
 builtin_pred_type(Info, Functor, Arity, GoalPath, PredConsInfoList) :-
     Functor = cons(SymName, _),
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    ModuleInfo = Info ^ tc_info_module_info,
     module_info_get_predicate_table(ModuleInfo, PredicateTable),
     (
+        typecheck_info_get_pred_markers(Info, PredMarkers),
         predicate_table_search_sym(PredicateTable,
-            calls_are_fully_qualified(Info ^ pred_markers),
-            SymName, PredIdList)
+            calls_are_fully_qualified(PredMarkers), SymName, PredIdList)
     ->
         predicate_table_get_preds(PredicateTable, Preds),
         make_pred_cons_info_list(Info, PredIdList, Preds, Arity,
@@ -2574,7 +2586,7 @@
 
 make_pred_cons_info(Info, PredId, PredTable, FuncArity, GoalPath,
         !ConsInfos) :-
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    ModuleInfo = Info ^ tc_info_module_info,
     module_info_get_class_table(ModuleInfo, ClassTable),
     map.lookup(PredTable, PredId, PredInfo),
     PredArity = pred_info_orig_arity(PredInfo),
@@ -2696,7 +2708,7 @@
     % Taking the address of automatically generated field access functions
     % is not allowed, so currying does have to be considered here.
     Functor = cons(Name, Arity),
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    ModuleInfo = Info ^ tc_info_module_info,
     is_field_access_function_name(ModuleInfo, Name, Arity, AccessType,
         FieldName),
 
@@ -2720,7 +2732,8 @@
         MaybeFunctorConsTypeInfo),
     (
         MaybeFunctorConsTypeInfo = ok(FunctorConsTypeInfo),
-        module_info_get_class_table(Info ^ module_info, ClassTable),
+        ModuleInfo = Info ^ tc_info_module_info,
+        module_info_get_class_table(ModuleInfo, ClassTable),
         convert_field_access_cons_type_info(ClassTable, AccessType,
             FieldName, FieldDefn, FunctorConsTypeInfo,
             OrigExistTVars, ConsTypeInfo)
@@ -2743,15 +2756,16 @@
     % the clause introduced for the user-supplied declaration.
     % The user-declared version will be picked up by builtin_pred_type.
 
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    ModuleInfo = Info ^ tc_info_module_info,
     module_info_get_predicate_table(ModuleInfo, PredTable),
     UnqualFuncName = unqualify_name(FuncName),
+    typecheck_info_get_is_field_access_function(Info, IsFieldAccessFunc),
     (
-        Info ^ is_field_access_function = no,
+        IsFieldAccessFunc = no,
         \+ predicate_table_search_func_m_n_a(PredTable, is_fully_qualified,
             TypeModule, UnqualFuncName, Arity, _)
     ;
-        Info ^ is_field_access_function = yes
+        IsFieldAccessFunc = yes
     ),
     module_info_get_cons_table(ModuleInfo, Ctors),
     map.lookup(Ctors, ConsId, ConsDefns0),
@@ -2953,14 +2967,16 @@
 
 typecheck_info_get_ctor_list(Info, Functor, Arity, GoalPath, ConsInfos,
         ConsErrors) :-
+    typecheck_info_get_is_field_access_function(Info, IsFieldAccessFunc),
+    typecheck_info_get_pred_import_status(Info, ImportStatus),
     (
         % If we're typechecking the clause added for a field access function
         % for which the user has supplied type or mode declarations, the goal
         % should only contain an application of the field access function,
         % not constructor applications or function calls. The clauses in
         % `.opt' files will already have been expanded into unifications.
-        Info ^ is_field_access_function = yes,
-        Info ^ import_status \= status_opt_imported
+        IsFieldAccessFunc = yes,
+        ImportStatus \= status_opt_imported
     ->
         (
             builtin_field_access_function_type(Info, GoalPath,
@@ -3172,9 +3188,9 @@
     % allow foreign type constructors in `opt_imported' predicates even
     % if there are no foreign clauses. Errors will be caught when creating
     % the `.opt' file.
-    %
+
     typecheck_info_get_predid(Info, PredId),
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    ModuleInfo = Info ^ tc_info_module_info,
     module_info_get_class_table(ModuleInfo, ClassTable),
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
     (
@@ -3223,7 +3239,6 @@
             % constraints here can be trivially reduced by the assumed ones,
             % we still need to process them so that the appropriate tables
             % get updated.
-            %
             ProgConstraints = constraints(ExistProgConstraints,
                 ExistProgConstraints),
             ExistQVars = ExistQVars0
Index: compiler/typecheck_errors.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck_errors.m,v
retrieving revision 1.37
diff -u -b -r1.37 typecheck_errors.m
--- compiler/typecheck_errors.m	19 Jan 2007 07:04:34 -0000	1.37
+++ compiler/typecheck_errors.m	14 May 2007 00:33:04 -0000
@@ -53,6 +53,8 @@
 
 :- func report_warning_too_much_overloading(typecheck_info) = error_spec.
 
+:- func report_error_too_much_overloading(typecheck_info) = error_spec.
+
 :- func report_error_unif_var_var(typecheck_info, prog_var, prog_var,
     type_assign_set) = error_spec.
 
@@ -121,11 +123,12 @@
 
 report_pred_call_error(Info, PredCallId) = Spec :-
     PredCallId = simple_call_id(PredOrFunc0, SymName, _Arity),
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    ModuleInfo = Info ^ tc_info_module_info,
     module_info_get_predicate_table(ModuleInfo, PredicateTable),
+    typecheck_info_get_pred_markers(Info, PredMarkers),
     (
         predicate_table_search_pf_sym(PredicateTable,
-            calls_are_fully_qualified(Info ^ pred_markers),
+            calls_are_fully_qualified(PredMarkers),
             PredOrFunc0, SymName, OtherIds),
         predicate_table_get_preds(PredicateTable, Preds),
         OtherIds = [_ | _]
@@ -139,7 +142,7 @@
             ; PredOrFunc0 = pf_function, PredOrFunc = pf_predicate
             ),
             predicate_table_search_pf_sym(PredicateTable,
-                calls_are_fully_qualified(Info ^ pred_markers),
+                calls_are_fully_qualified(PredMarkers),
                 PredOrFunc, SymName, OtherIds),
             OtherIds = [_ | _]
         ->
@@ -170,7 +173,7 @@
         error_num_args_to_pieces(yes(PredOrFunc), Arity, Arities) ++ [nl] ++
         [words("in call to"), p_or_f(PredOrFunc), sym_name(SymName),
         suffix("."), nl],
-    typecheck_info_get_context(Info, Context),
+    Context = Info ^ tc_info_context,
     Spec = error_spec(severity_error, phase_type_check,
         [simple_msg(Context, [always(Pieces)])]).
 
@@ -190,14 +193,14 @@
             prefix("*"), p_or_f(PredOrFunc), suffix("*"),
             words("with that name, however.)"), nl]
     ),
-    typecheck_info_get_context(Info, Context),
+    Context = Info ^ tc_info_context,
     Msg = simple_msg(Context, [always(Pieces)]).
 
 :- func report_error_undef_pred(typecheck_info, simple_call_id) = error_msg.
 
 report_error_undef_pred(Info, SimpleCallId) = Msg :-
     SimpleCallId = simple_call_id(_PredOrFunc, PredName, Arity),
-    typecheck_info_get_context(Info, Context),
+    Context = Info ^ tc_info_context,
     InClauseForPieces = in_clause_for_pieces(Info),
     InClauseForComponent = always(InClauseForPieces),
     (
@@ -293,14 +296,14 @@
 %-----------------------------------------------------------------------------%
 
 report_unknown_event_call_error(Info, EventName) = Spec :-
-    typecheck_info_get_context(Info, Context),
+    Context = Info ^ tc_info_context,
     Pieces = [words("Error: there is no event named"),
         quote(EventName), suffix(".")],
     Msg = simple_msg(Context, [always(Pieces)]),
     Spec = error_spec(severity_error, phase_type_check, [Msg]).
 
 report_event_args_mismatch(Info, EventName, EventArgTypes, Args) = Spec :-
-    typecheck_info_get_context(Info, Context),
+    Context = Info ^ tc_info_context,
     Pieces = 
         [words("Error:")] ++
         error_num_args_to_pieces(no, length(Args), [length(EventArgTypes)]) ++
@@ -346,24 +349,40 @@
 %-----------------------------------------------------------------------------%
 
 report_warning_too_much_overloading(Info) = Spec :-
-    Msgs = warning_too_much_overloading_to_msgs(Info),
+    Msgs = too_much_overloading_to_msgs(Info, no),
     Spec = error_spec(severity_warning, phase_type_check, Msgs).
 
-:- func warning_too_much_overloading_to_msgs(typecheck_info) = list(error_msg).
+report_error_too_much_overloading(Info) = Spec :-
+    Msgs = too_much_overloading_to_msgs(Info, yes),
+    Spec = error_spec(severity_error, phase_type_check, Msgs).
+
+:- func too_much_overloading_to_msgs(typecheck_info, bool) = list(error_msg).
 
-warning_too_much_overloading_to_msgs(Info) = Msgs :-
-    typecheck_info_get_context(Info, Context),
-    InitWarningPieces = in_clause_for_pieces(Info) ++
+too_much_overloading_to_msgs(Info, IsError) = Msgs :-
+    Context = Info ^ tc_info_context,
+    (
+        IsError = no,
+        InitPieces = in_clause_for_pieces(Info) ++
         [words("warning: highly ambiguous overloading."), nl],
-    InitWarningComponent = always(InitWarningPieces),
+        InitComponent = always(InitPieces),
 
-    VerboseWarningPieces =
+        VerbosePieces =
         [words("This may cause type-checking to be very slow."),
         words("It may also make your code difficult to understand."), nl],
-    VerboseWarningComponent = verbose_only(VerboseWarningPieces),
+        VerboseComponent = verbose_only(VerbosePieces)
+    ;
+        IsError = yes,
+        InitPieces = in_clause_for_pieces(Info) ++
+            [words("error: excessively ambiguous overloading."), nl],
+        InitComponent = always(InitPieces),
+
+        VerbosePieces =
+            [words("This caused the type checker to exceed its limits."),
+            words("It may also make your code difficult to understand."), nl],
+        VerboseComponent = verbose_only(VerbosePieces)
+    ),
 
-    FirstMsg = simple_msg(Context,
-        [InitWarningComponent, VerboseWarningComponent]),
+    FirstMsg = simple_msg(Context, [InitComponent, VerboseComponent]),
 
     typecheck_info_get_overloaded_symbols(Info, OverloadedSymbolSet),
     map.to_assoc_list(OverloadedSymbolSet, OverloadedSymbols),
@@ -397,7 +416,7 @@
                 words("in the following contexts."), nl]
         ),
         SecondMsg = simple_msg(Context, [always(SecondPieces)]),
-        typecheck_info_get_module_info(Info, ModuleInfo),
+        ModuleInfo = Info ^ tc_info_module_info,
         DetailMsgsList = list.map(describe_overloaded_symbol(ModuleInfo),
             OverloadedSymbolsSortedContexts),
         list.condense(DetailMsgsList, DetailMsgs),
@@ -490,9 +509,9 @@
 %-----------------------------------------------------------------------------%
 
 report_error_unif_var_var(Info, X, Y, TypeAssignSet) = Spec :-
-    typecheck_info_get_context(Info, Context),
+    Context = Info ^ tc_info_context,
+    UnifyContext = Info ^ tc_info_unify_context,
     typecheck_info_get_varset(Info, VarSet),
-    typecheck_info_get_unify_context(Info, UnifyContext),
 
     InClauseForPieces = in_clause_for_pieces(Info),
     unify_context_to_pieces(UnifyContext, [], UnifyContextPieces),
@@ -515,9 +534,9 @@
 
 report_error_lambda_var(Info, PredOrFunc, _EvalMethod, Var, ArgVars,
         TypeAssignSet) = Spec :-
-    typecheck_info_get_context(Info, Context),
+    Context = Info ^ tc_info_context,
+    UnifyContext = Info ^ tc_info_unify_context,
     typecheck_info_get_varset(Info, VarSet),
-    typecheck_info_get_unify_context(Info, UnifyContext),
 
     InClauseForPieces = in_clause_for_pieces(Info),
     unify_context_to_pieces(UnifyContext, [], UnifyContextPieces),
@@ -584,9 +603,9 @@
 
 report_error_functor_type(Info, Var, ConsDefnList, Functor, Arity,
         TypeAssignSet) = Spec :-
-    typecheck_info_get_context(Info, Context),
     typecheck_info_get_varset(Info, VarSet),
-    typecheck_info_get_unify_context(Info, UnifyContext),
+    Context = Info ^ tc_info_context,
+    UnifyContext = Info ^ tc_info_unify_context,
 
     InClauseForPieces = in_clause_for_pieces(Info),
     % XXX We could append UnifyContextPieces after InClauseForPieces
@@ -615,10 +634,10 @@
 
 report_error_functor_arg_types(Info, Var, ConsDefnList, Functor, Args,
         ArgsTypeAssignSet) = Spec :-
-    typecheck_info_get_context(Info, Context),
     typecheck_info_get_varset(Info, VarSet),
-    typecheck_info_get_unify_context(Info, UnifyContext),
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    Context = Info ^ tc_info_context,
+    UnifyContext = Info ^ tc_info_unify_context,
+    ModuleInfo = Info ^ tc_info_module_info,
     list.length(Args, Arity),
 
     InClauseForPieces = in_clause_for_pieces(Info),
@@ -824,9 +843,9 @@
 report_error_var(Info, Var, Type, TypeAssignSet0) = Spec :-
     typecheck_info_get_pred_markers(Info, PredMarkers),
     typecheck_info_get_called_predid(Info, CalledPredId),
-    typecheck_info_get_arg_num(Info, ArgNum),
-    typecheck_info_get_context(Info, Context),
-    typecheck_info_get_unify_context(Info, UnifyContext),
+    ArgNum = Info ^ tc_info_arg_num,
+    Context = Info ^ tc_info_context,
+    UnifyContext = Info ^ tc_info_unify_context,
     get_type_stuff(TypeAssignSet0, Var, TypeStuffList),
     typecheck_info_get_varset(Info, VarSet),
 
@@ -868,9 +887,9 @@
 report_error_arg_var(Info, Var, ArgTypeAssignSet0) = Spec :-
     typecheck_info_get_pred_markers(Info, PredMarkers),
     typecheck_info_get_called_predid(Info, CalledPredId),
-    typecheck_info_get_arg_num(Info, ArgNum),
-    typecheck_info_get_context(Info, Context),
-    typecheck_info_get_unify_context(Info, UnifyContext),
+    ArgNum = Info ^ tc_info_arg_num,
+    Context = Info ^ tc_info_context,
+    UnifyContext = Info ^ tc_info_unify_context,
     get_arg_type_stuff(ArgTypeAssignSet0, Var, ArgTypeStuffList),
     typecheck_info_get_varset(Info, VarSet),
 
@@ -913,9 +932,9 @@
 report_error_undef_cons(Info, ConsErrors, Functor, Arity) = Spec :-
     typecheck_info_get_pred_markers(Info, PredMarkers),
     typecheck_info_get_called_predid(Info, CalledPredId),
-    typecheck_info_get_arg_num(Info, ArgNum),
-    typecheck_info_get_context(Info, Context),
-    typecheck_info_get_unify_context(Info, UnifyContext),
+    ArgNum = Info ^ tc_info_arg_num,
+    Context = Info ^ tc_info_context,
+    UnifyContext = Info ^ tc_info_unify_context,
     InClauseForPieces = in_clause_for_pieces(Info),
     CallContextPieces = call_context_to_pieces(PredMarkers, CalledPredId,
         ArgNum, UnifyContext),
@@ -1173,7 +1192,7 @@
         AmbiguityPieces = [],
         Pieces2 = [],
         VerboseComponents = [],
-        WarningMsgs = warning_too_much_overloading_to_msgs(Info)
+        WarningMsgs = too_much_overloading_to_msgs(Info, no)
     ;
         AmbiguityPieces = [_ | _],
         Pieces2 = [words("Possible type assignments include:"), nl
@@ -1182,7 +1201,7 @@
         WarningMsgs = []
     ),
 
-    typecheck_info_get_context(Info, Context),
+    Context = Info ^ tc_info_context,
     MainMsg = simple_msg(Context,
         [always(InClauseForPieces ++ Pieces1 ++ Pieces2) | VerboseComponents]),
     Spec = error_spec(severity_error, phase_type_check,
@@ -1246,7 +1265,7 @@
     Pieces2 = component_list_to_line_pieces(ConstraintPieceLists,
         [suffix(".")]),
 
-    typecheck_info_get_context(Info, Context),
+    Context = Info ^ tc_info_context,
     Msg = simple_msg(Context,
         [always(InClauseForPieces ++ Pieces1 ++ Pieces2)]),
     Spec = error_spec(severity_error, phase_type_check, [Msg]).
@@ -1281,8 +1300,8 @@
 %-----------------------------------------------------------------------------%
 
 report_missing_tvar_in_foreign_code(Info, VarName) = Spec :-
-    typecheck_info_get_module_info(Info, ModuleInfo),
-    typecheck_info_get_context(Info, Context),
+    ModuleInfo = Info ^ tc_info_module_info,
+    Context = Info ^ tc_info_context,
     typecheck_info_get_predid(Info, PredId),
     Pieces = [words("The foreign language code for") |
         describe_one_pred_name(ModuleInfo, should_module_qualify,
@@ -1549,7 +1568,7 @@
 
 maybe_report_missing_import_addendum(Info, ModuleQualifier) = Pieces :-
     % First check if this module wasn't imported.
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    ModuleInfo = Info ^ tc_info_module_info,
     (
         % If the module qualifier couldn't match any of the visible modules,
         % then we report that the module has not been imported.
@@ -1621,7 +1640,7 @@
 :- func in_clause_for_pieces(typecheck_info) = list(format_component).
 
 in_clause_for_pieces(Info) = Pieces :-
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    ModuleInfo = Info ^ tc_info_module_info,
     typecheck_info_get_predid(Info, PredId),
     PredIdPieces = describe_one_pred_name(ModuleInfo,
         should_not_module_qualify, PredId),
Index: compiler/typecheck_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck_info.m,v
retrieving revision 1.22
diff -u -b -r1.22 typecheck_info.m
--- compiler/typecheck_info.m	19 Jan 2007 07:04:34 -0000	1.22
+++ compiler/typecheck_info.m	14 May 2007 00:21:42 -0000
@@ -40,60 +40,67 @@
 % The typecheck_info data structure.
 %
 
-:- type typecheck_info
-    --->    typecheck_info(
-                module_info     :: module_info,
+:- type typecheck_sub_info
+    --->    typecheck_sub_info(
+                % The id of the pred we're checking.
+                tc_sub_info_pred_id                 :: pred_id,
 
-                call_id         :: call_id,
-                                % The call_id of the pred being called (if
-                                % any).
+                % Import status of the pred being checked.
+                tc_sub_info_pred_import_status      :: import_status,
 
-                arg_num         :: int,
-                                % The argument number within a pred call.
+                % Markers of the pred being checked.
+                tc_sub_info_pred_markers            :: pred_markers,
 
-                pred_id         :: pred_id,
-                                % The pred we're checking.
+                % Is the pred we're checking a field access function? If so,
+                % there should only be a field access function application
+                % in the body, not predicate or function calls or constructor
+                % applications.
+                tc_sub_info_is_field_access_function :: bool,
+
+                % Variable names in the predicate being checked.
+                tc_sub_info_varset                  :: prog_varset,
+
+                % The list of errors found so far (if any), with one exception:
+                % any errors about overloading are in the overload_error field.
+                tc_sub_info_non_overload_errors     :: list(error_spec),
+
+                % Have we already generated a warning or error message about
+                % highly ambiguous overloading? If yes, this has the message.
+                tc_sub_info_overload_error          :: maybe(error_spec),
+
+                % The symbols used by the current predicate that have
+                % more than one accessible definition, mapped to the unsorted
+                % list of the locations that refer to them.
+                tc_sub_info_overloaded_symbols      :: overloaded_symbol_map,
 
-                import_status   :: import_status,
-                                % Import status of the pred being checked.
+                % The value of the option --typecheck-ambiguity-error-limit.
+                tc_sub_info_ambiguity_error_limit   :: int
+            ).
 
-                pred_markers    :: pred_markers,
-                                % Markers of the pred being checked
+:- type typecheck_info
+    --->    typecheck_info(
+                tc_info_sub_info                    :: typecheck_sub_info,
+
+                tc_info_module_info                 :: module_info,
 
-                is_field_access_function :: bool,
-                                % Is the pred we're checking a field access
-                                % function? If so, there should only be
-                                % a field access function application
-                                % in the body, not predicate or function calls
-                                % or constructor applications.
+                % The call_id of the pred being called (if any).
+                tc_info_call_id                     :: call_id,
+
+                % The argument number within that pred call.
+                tc_info_arg_num                     :: int,
 
-                context         :: prog_context,
                                 % The context of the goal we're checking.
+                tc_info_context                     :: prog_context,
+
+                % The original source of the unification we're checking.
+                tc_info_unify_context               :: unify_context,
 
-                unify_context   :: unify_context,
-                                % The original source of the unification
-                                % we're checking.
-
-                varset          :: prog_varset,
-                                % Variable names
-
-                type_assign_set :: type_assign_set,
-                                % This is the main piece of information
-                                % that we are computing and which gets updated
-                                % as we go along.
-
-                found_errors    :: list(error_spec),
-                                % The list of errors found so far (if any).
-
-                overloaded_symbols :: overloaded_symbol_map,
-                                % The symbols used by the current predicate
-                                % that have more than one accessible
-                                % definition, mapped to the unsorted list of
-                                % the locations that refer to them.
-
-                warned_about_overloading :: bool
-                                % Have we already warned about highly
-                                % ambiguous overloading?
+                % This is the main piece of information that we are computing
+                % and which gets updated as we go along.
+                tc_info_type_assign_set             :: type_assign_set,
+
+                % The value of the option --typecheck-ambiguity-warn-limit.
+                tc_info_ambiguity_warn_limit        :: int
             ).
 
 :- type overloaded_symbol_map == map(overloaded_symbol, list(prog_context)).
@@ -113,10 +120,10 @@
 % typecheck_info initialisation and finalisation.
 %
 
-:- pred typecheck_info_init(module_info::in, pred_id::in,
-    bool::in, tvarset::in, prog_varset::in, vartypes::in,
-    head_type_params::in, hlds_constraints::in, import_status::in,
-    pred_markers::in, list(error_spec)::in, typecheck_info::out) is det.
+:- pred typecheck_info_init(module_info::in, pred_id::in, bool::in,
+    tvarset::in, prog_varset::in, vartypes::in, head_type_params::in,
+    hlds_constraints::in, import_status::in, pred_markers::in,
+    list(error_spec)::in, typecheck_info::out) is det.
 
     % typecheck_info_get_final_info(Info, OldHeadTypeParams, OldExistQVars,
     %   OldExplicitVarTypes, NewTypeVarSet, New* ..., TypeRenaming,
@@ -148,44 +155,45 @@
 % Basic access predicates for typecheck_info.
 %
 
-:- pred typecheck_info_get_module_info(typecheck_info::in, module_info::out)
+% :- func tc_info_module_info(typecheck_info) = module_info.
+% :- func tc_info_arg_num(typecheck_info) = int.
+% :- func tc_info_context(typecheck_info) = prog_context.
+% :- func tc_info_unify_context(typecheck_info) = unify_context.
+% :- func tc_info_type_assign_set(typecheck_info) = type_assign_set.
+
+% :- func 'tc_info_arg_num :='(typecheck_info, int) = typecheck_info.
+% :- func 'tc_info_context :='(typecheck_info, prog_context) = typecheck_info.
+% :- func 'tc_info_unify_context :='(typecheck_info, unify_context)
+%     = typecheck_info.
+% :- func 'tc_info_type_assign_set :='(typecheck_info, type_assign_set)
+%     = typecheck_info.
+
+:- pred typecheck_info_get_predid(typecheck_info::in, pred_id::out) is det.
+:- pred typecheck_info_get_pred_import_status(typecheck_info::in,
+    import_status::out) is det.
+:- pred typecheck_info_get_pred_markers(typecheck_info::in, pred_markers::out)
     is det.
+:- pred typecheck_info_get_is_field_access_function(typecheck_info::in,
+    bool::out) is det.
 :- pred typecheck_info_get_called_predid(typecheck_info::in, call_id::out)
     is det.
-:- pred typecheck_info_get_arg_num(typecheck_info::in, int::out) is det.
-:- pred typecheck_info_get_predid(typecheck_info::in, pred_id::out) is det.
-:- pred typecheck_info_get_context(typecheck_info::in,
-    prog_context::out) is det.
-:- pred typecheck_info_get_unify_context(typecheck_info::in,
-    unify_context::out) is det.
+
 :- pred typecheck_info_get_varset(typecheck_info::in, prog_varset::out) is det.
-:- pred typecheck_info_get_type_assign_set(typecheck_info::in,
-    type_assign_set::out) is det.
-:- pred typecheck_info_get_errors(typecheck_info::in, list(error_spec)::out)
-    is det.
-:- pred typecheck_info_get_warned_about_overloading(typecheck_info::in,
-    bool::out) is det.
+:- pred typecheck_info_get_overload_error(typecheck_info::in,
+    maybe(error_spec)::out) is det.
 :- pred typecheck_info_get_overloaded_symbols(typecheck_info::in,
     overloaded_symbol_map::out) is det.
-:- pred typecheck_info_get_pred_import_status(typecheck_info::in,
-    import_status::out) is det.
+:- pred typecheck_info_get_ambiguity_warn_limit(typecheck_info::in,
+    int::out) is det.
+:- pred typecheck_info_get_ambiguity_error_limit(typecheck_info::in,
+    int::out) is det.
 
 :- pred typecheck_info_set_called_predid(call_id::in,
     typecheck_info::in, typecheck_info::out) is det.
-:- pred typecheck_info_set_arg_num(int::in,
-    typecheck_info::in, typecheck_info::out) is det.
-:- pred typecheck_info_set_context(prog_context::in,
-    typecheck_info::in, typecheck_info::out) is det.
-:- pred typecheck_info_set_unify_context(unify_context::in,
-    typecheck_info::in, typecheck_info::out) is det.
-:- pred typecheck_info_set_type_assign_set(type_assign_set::in,
-    typecheck_info::in, typecheck_info::out) is det.
-:- pred typecheck_info_set_warned_about_overloading(bool::in,
+:- pred typecheck_info_set_overload_error(maybe(error_spec)::in,
     typecheck_info::in, typecheck_info::out) is det.
 :- pred typecheck_info_set_overloaded_symbols(overloaded_symbol_map::in,
     typecheck_info::in, typecheck_info::out) is det.
-:- pred typecheck_info_set_pred_import_status(import_status::in,
-    typecheck_info::in, typecheck_info::out) is det.
 
 %-----------------------------------------------------------------------------%
 %
@@ -198,8 +206,6 @@
     is det.
 :- pred typecheck_info_get_types(typecheck_info::in, type_table::out) is det.
 :- pred typecheck_info_get_ctors(typecheck_info::in, cons_table::out) is det.
-:- pred typecheck_info_get_pred_markers(typecheck_info::in, pred_markers::out)
-    is det.
 
 :- pred typecheck_info_add_overloaded_symbol(overloaded_symbol::in,
     prog_context::in, typecheck_info::in, typecheck_info::out) is det.
@@ -207,6 +213,9 @@
 :- pred typecheck_info_add_error(error_spec::in,
     typecheck_info::in, typecheck_info::out) is det.
 
+:- pred typecheck_info_get_all_errors(typecheck_info::in,
+    list(error_spec)::out) is det.
+
 %-----------------------------------------------------------------------------%
 %
 % The type_assign and type_assign_set data structures.
@@ -367,6 +376,7 @@
 :- import_module parse_tree.prog_type_subst.
 
 :- import_module int.
+:- import_module pair.
 :- import_module string.
 :- import_module svmap.
 :- import_module term.
@@ -375,29 +385,36 @@
 %-----------------------------------------------------------------------------%
 
 typecheck_info_init(ModuleInfo, PredId, IsFieldAccessFunction,
-        TypeVarSet, VarSet, VarTypes, HeadTypeParams,
-        Constraints, Status, Markers, Errors, Info) :-
+        TypeVarSet, VarSet, VarTypes, HeadTypeParams, Constraints,
+        Status, PredMarkers, NonOverloadErrors, Info) :-
     CallPredId =
         plain_call_id(simple_call_id(pf_predicate, unqualified(""), 0)),
     term.context_init(Context),
     map.init(TypeBindings),
     map.init(Proofs),
     map.init(ConstraintMap),
-    WarnedAboutOverloading = no,
+    OverloadErrors = no,
     map.init(OverloadedSymbols),
-    Info = typecheck_info(ModuleInfo, CallPredId, 0, PredId, Status, Markers,
-        IsFieldAccessFunction, Context,
-        unify_context(umc_explicit, []), VarSet,
+    module_info_get_globals(ModuleInfo, Globals),
+    globals.lookup_int_option(Globals, typecheck_ambiguity_warn_limit,
+        WarnLimit),
+    globals.lookup_int_option(Globals, typecheck_ambiguity_error_limit,
+        ErrorLimit),
+    SubInfo = typecheck_sub_info(PredId, Status,
+        PredMarkers, IsFieldAccessFunction, VarSet,
+        NonOverloadErrors, OverloadErrors, OverloadedSymbols, ErrorLimit),
+    Info = typecheck_info(SubInfo, ModuleInfo, CallPredId, 0,
+        Context, unify_context(umc_explicit, []),
         [type_assign(VarTypes, TypeVarSet, HeadTypeParams,
             TypeBindings, Constraints, Proofs, ConstraintMap)],
-        Errors, OverloadedSymbols, WarnedAboutOverloading
+        WarnLimit
     ).
 
 typecheck_info_get_final_info(Info, OldHeadTypeParams, OldExistQVars,
         OldExplicitVarTypes, NewTypeVarSet, NewHeadTypeParams,
         NewVarTypes, NewTypeConstraints, NewConstraintProofs,
         NewConstraintMap, TSubst, ExistTypeRenaming) :-
-    typecheck_info_get_type_assign_set(Info, TypeAssignSet),
+    TypeAssignSet = tc_info_type_assign_set(Info),
     (
         TypeAssignSet = [TypeAssign | _],
         type_assign_get_head_type_params(TypeAssign, HeadTypeParams),
@@ -559,55 +576,66 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred typecheck_info_set_errors(list(error_spec)::in,
+:- pred typecheck_info_get_non_overload_errors(typecheck_info::in,
+    list(error_spec)::out) is det.
+:- pred typecheck_info_set_non_overload_errors(list(error_spec)::in,
     typecheck_info::in, typecheck_info::out) is det.
 
-typecheck_info_get_module_info(Info, Info ^ module_info).
-typecheck_info_get_called_predid(Info, Info ^ call_id).
-typecheck_info_get_arg_num(Info, Info ^ arg_num).
-typecheck_info_get_predid(Info, Info ^ pred_id).
-typecheck_info_get_context(Info, Info ^ context).
-typecheck_info_get_unify_context(Info, Info ^ unify_context).
-typecheck_info_get_varset(Info, Info ^ varset).
-typecheck_info_get_type_assign_set(Info, Info ^ type_assign_set).
-typecheck_info_get_errors(Info, Info ^ found_errors).
-typecheck_info_get_warned_about_overloading(Info,
-        Info ^ warned_about_overloading).
-typecheck_info_get_overloaded_symbols(Info, Info ^ overloaded_symbols).
-typecheck_info_get_pred_import_status(Info, Info ^ import_status).
+% These get and set functions are defined automatically.
+
+% get_tc_info_module_info(Info) = Info ^ tc_info_module_info.
+% get_tc_info_arg_num(Info) = Info ^ tc_info_arg_num.
+% get_tc_info_context(Info) = Info ^ tc_info_context.
+% get_tc_info_unify_context(Info) = Info ^ unify_context.
+% get_tc_info_type_assign_set(Info) = Info ^ type_assign_set.
+
+% set_tc_info_arg_num(ArgNum, Info, Info ^ tc_info_arg_num := ArgNum).
+% set_tc_info_context(Context, Info, Info ^ tc_info_context := Context).
+% set_tc_info_unify_context(UnifyContext, Info,
+%        Info ^ tc_info_unify_context := UnifyContext).
+% set_tc_info_type_assign_set(TypeAssignSet, Info,
+%        Info ^ tc_info_type_assign_set := TypeAssignSet).
+
+typecheck_info_get_predid(Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_pred_id).
+typecheck_info_get_pred_markers(Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_pred_markers).
+typecheck_info_get_pred_import_status(Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_pred_import_status).
+typecheck_info_get_is_field_access_function(Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_is_field_access_function).
+typecheck_info_get_called_predid(Info, Info ^ tc_info_call_id).
+typecheck_info_get_varset(Info, Info ^ tc_info_sub_info ^ tc_sub_info_varset).
+typecheck_info_get_non_overload_errors(Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_non_overload_errors).
+typecheck_info_get_overload_error(Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_overload_error).
+typecheck_info_get_overloaded_symbols(Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_overloaded_symbols).
+typecheck_info_get_ambiguity_error_limit(Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_ambiguity_error_limit).
+typecheck_info_get_ambiguity_warn_limit(Info,
+        Info ^ tc_info_ambiguity_warn_limit).
 
 typecheck_info_set_called_predid(PredCallId, Info,
-        Info ^ call_id := PredCallId).
-typecheck_info_set_arg_num(ArgNum, Info, Info ^ arg_num := ArgNum).
-typecheck_info_set_context(Context, Info, Info ^ context := Context).
-typecheck_info_set_unify_context(UnifyContext, Info,
-        Info ^ unify_context := UnifyContext).
-typecheck_info_set_type_assign_set(TypeAssignSet, Info,
-        Info ^ type_assign_set := TypeAssignSet).
-typecheck_info_set_errors(Errors, Info, Info ^ found_errors := Errors).
-typecheck_info_set_warned_about_overloading(Warned, Info,
-        Info ^ warned_about_overloading := Warned).
+        Info ^ tc_info_call_id := PredCallId).
+typecheck_info_set_non_overload_errors(Specs, Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_non_overload_errors := Specs).
+typecheck_info_set_overload_error(OverloadSpec, Info,
+        Info ^ tc_info_sub_info ^ tc_sub_info_overload_error := OverloadSpec).
 typecheck_info_set_overloaded_symbols(Symbols, Info,
-        Info ^ overloaded_symbols := Symbols).
-typecheck_info_set_pred_import_status(Status, Info,
-        Info ^ import_status := Status).
+        Info ^ tc_info_sub_info ^ tc_sub_info_overloaded_symbols := Symbols).
 
 %-----------------------------------------------------------------------------%
 
 typecheck_info_get_module_name(Info, Name) :-
-    module_info_get_name(Info ^ module_info, Name).
+    module_info_get_name(Info ^ tc_info_module_info, Name).
 typecheck_info_get_preds(Info, Preds) :-
-    module_info_get_predicate_table(Info ^ module_info, Preds).
+    module_info_get_predicate_table(Info ^ tc_info_module_info, Preds).
 typecheck_info_get_types(Info, Types) :-
-    module_info_get_type_table(Info ^ module_info, Types).
+    module_info_get_type_table(Info ^ tc_info_module_info, Types).
 typecheck_info_get_ctors(Info, Ctors) :-
-    module_info_get_cons_table(Info ^ module_info, Ctors).
-
-typecheck_info_get_pred_markers(Info, PredMarkers) :-
-    typecheck_info_get_module_info(Info, ModuleInfo),
-    typecheck_info_get_predid(Info, PredId),
-    module_info_pred_info(ModuleInfo, PredId, PredInfo),
-    pred_info_get_markers(PredInfo, PredMarkers).
+    module_info_get_cons_table(Info ^ tc_info_module_info, Ctors).
 
 typecheck_info_add_overloaded_symbol(Symbol, Context, !Info) :-
     typecheck_info_get_overloaded_symbols(!.Info, SymbolMap0),
@@ -621,9 +649,20 @@
     typecheck_info_set_overloaded_symbols(SymbolMap, !Info).
 
 typecheck_info_add_error(Error, !Info) :-
-    typecheck_info_get_errors(!.Info, Errors0),
+    typecheck_info_get_non_overload_errors(!.Info, Errors0),
     Errors = [Error | Errors0],
-    typecheck_info_set_errors(Errors, !Info).
+    typecheck_info_set_non_overload_errors(Errors, !Info).
+
+typecheck_info_get_all_errors(Info, Errors) :-
+    typecheck_info_get_non_overload_errors(Info, Errors0),
+    typecheck_info_get_overload_error(Info, MaybeOverloadError),
+    (
+        MaybeOverloadError = no,
+        Errors = Errors0
+    ;
+        MaybeOverloadError = yes(OverloadError),
+        Errors = [OverloadError | Errors0]
+    ).
 
 %-----------------------------------------------------------------------------%
 
@@ -930,7 +969,7 @@
 %-----------------------------------------------------------------------------%
 
 type_checkpoint(Msg, Info, !IO) :-
-    typecheck_info_get_module_info(Info, ModuleInfo),
+    ModuleInfo = tc_info_module_info(Info),
     module_info_get_globals(ModuleInfo, Globals),
     globals.lookup_bool_option(Globals, debug_types, DoCheckPoint),
     (
@@ -943,14 +982,14 @@
 :- pred do_type_checkpoint(string::in, typecheck_info::in, io::di, io::uo)
     is det.
 
-do_type_checkpoint(Msg, T0, !IO) :-
+do_type_checkpoint(Msg, Info, !IO) :-
     io.write_string("At ", !IO),
     io.write_string(Msg, !IO),
     io.write_string(": ", !IO),
     globals.io_lookup_bool_option(detailed_statistics, Statistics, !IO),
     maybe_report_stats(Statistics, !IO),
     io.write_string("\n", !IO),
-    typecheck_info_get_type_assign_set(T0, TypeAssignSet),
+    TypeAssignSet = tc_info_type_assign_set(Info),
     (
         Statistics = yes,
         TypeAssignSet = [TypeAssign | _]
@@ -962,7 +1001,7 @@
     ;
         true
     ),
-    typecheck_info_get_varset(T0, VarSet),
+    typecheck_info_get_varset(Info, VarSet),
     write_type_assign_set(TypeAssignSet, VarSet, !IO).
 
 :- pred checkpoint_tree_stats(string::in, map(_K, _V)::in, io::di, io::uo)
Index: compiler/typeclasses.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typeclasses.m,v
retrieving revision 1.20
diff -u -b -r1.20 typeclasses.m
--- compiler/typeclasses.m	27 Feb 2007 23:49:56 -0000	1.20
+++ compiler/typeclasses.m	12 May 2007 02:02:33 -0000
@@ -111,10 +111,10 @@
     trace [io(!IO)] (
         type_checkpoint("before context reduction", !.Info, !IO)
     ),
-    typecheck_info_get_module_info(!.Info, ModuleInfo),
+    TypeAssignSet0 = tc_info_type_assign_set(!.Info),
+    ModuleInfo = tc_info_module_info(!.Info),
     module_info_get_class_table(ModuleInfo, ClassTable),
     module_info_get_instance_table(ModuleInfo, InstanceTable),
-    typecheck_info_get_type_assign_set(!.Info, TypeAssignSet0),
     list.filter_map(
         reduce_type_assign_context(ClassTable, InstanceTable),
         TypeAssignSet0, TypeAssignSet),
@@ -137,9 +137,9 @@
             type_assign_set_typeclass_constraints(Constraints, TA0, TA)
         ),
         list.map(DeleteConstraints, OrigTypeAssignSet, NewTypeAssignSet),
-        typecheck_info_set_type_assign_set(NewTypeAssignSet, !Info)
+        !:Info = !.Info ^ tc_info_type_assign_set := NewTypeAssignSet
     ;
-        typecheck_info_set_type_assign_set(TypeAssignSet, !Info)
+        !:Info = !.Info ^ tc_info_type_assign_set := TypeAssignSet
     ).
 
 :- pred reduce_type_assign_context(class_table::in, instance_table::in,
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.518
diff -u -b -r1.518 user_guide.texi
--- doc/user_guide.texi	17 Apr 2007 05:44:12 -0000	1.518
+++ doc/user_guide.texi	10 May 2007 11:43:01 -0000
@@ -8651,6 +8651,20 @@
 process creation for each one.)
 
 @sp 1
+ at item --typecheck-ambiguity-warn-limit @var{n}
+ at findex typecheck-ambiguity-warn-limit
+Set the number of type assignments required to generate a warning
+about highly ambiguous overloading to @var{n}.
+
+ at sp 1
+ at item --typecheck-ambiguity-error-limit @var{n}
+ at findex typecheck-ambiguity-error-limit
+Set the number of type assignments required to generate an error
+excessively ambiguous overloading to @var{n}.
+If this limit is reached,
+the typechecker will not process the predicate or function any further.
+
+ at sp 1
 @item --feedback-file
 @findex --feedback-file
 Use the specified profiling feedback file which may currently only be processed
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.213
diff -u -b -r1.213 Mmakefile
--- tests/invalid/Mmakefile	14 May 2007 08:14:01 -0000	1.213
+++ tests/invalid/Mmakefile	14 May 2007 08:14:32 -0000
@@ -30,6 +30,7 @@
 	after_end_module \
 	ambiguous_method \
 	ambiguous_method_2 \
+	ambiguous_overloading_error \
 	any_mode \
 	any_passed_as_ground \
 	any_should_not_match_bound \
@@ -84,8 +85,8 @@
 	field_syntax_error \
 	foreign_purity_mismatch \
 	foreign_singleton \
-	foreign_type_missing \
 	foreign_type_2 \
+	foreign_type_missing \
 	foreign_type_visibility \
 	fp_dup_bug \
 	freefree \
Index: tests/invalid/ambiguous_overloading_error.err_exp
===================================================================
RCS file: tests/invalid/ambiguous_overloading_error.err_exp
diff -N tests/invalid/ambiguous_overloading_error.err_exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/ambiguous_overloading_error.err_exp	11 May 2007 00:42:43 -0000
@@ -0,0 +1,71 @@
+ambiguous_overloading_error.m:043: In clause for predicate `ambig_overload1'/1:
+ambiguous_overloading_error.m:043:   error: excessively ambiguous overloading.
+ambiguous_overloading_error.m:043:   The following symbol was overloaded in the
+ambiguous_overloading_error.m:043:   following contexts.
+ambiguous_overloading_error.m:041:   The function symbol `f'/0.
+ambiguous_overloading_error.m:041:   The possible matches are:
+ambiguous_overloading_error.m:041:     the type constructor
+ambiguous_overloading_error.m:041:     `ambiguous_overloading_error.foo'/0,
+ambiguous_overloading_error.m:041:     the type constructor
+ambiguous_overloading_error.m:041:     `ambiguous_overloading_error.bar'/0,
+ambiguous_overloading_error.m:041:     the builtin type constructor
+ambiguous_overloading_error.m:041:     `character'.
+ambiguous_overloading_error.m:042:   The function symbol `f'/0 is also
+ambiguous_overloading_error.m:042:   overloaded here.
+ambiguous_overloading_error.m:046: In clause for predicate `ambig_overload2'/1:
+ambiguous_overloading_error.m:046:   warning: highly ambiguous overloading.
+ambiguous_overloading_error.m:046:   The following symbols were overloaded in
+ambiguous_overloading_error.m:046:   the following contexts.
+ambiguous_overloading_error.m:046:   The function symbol `a1'/0.
+ambiguous_overloading_error.m:046:   The possible matches are:
+ambiguous_overloading_error.m:046:     the type constructor
+ambiguous_overloading_error.m:046:     `ambiguous_overloading_error.qux'/0,
+ambiguous_overloading_error.m:046:     the type constructor
+ambiguous_overloading_error.m:046:     `ambiguous_overloading_error.baz'/0.
+ambiguous_overloading_error.m:046:   The function symbol `a2'/0.
+ambiguous_overloading_error.m:046:   The possible matches are:
+ambiguous_overloading_error.m:046:     the type constructor
+ambiguous_overloading_error.m:046:     `ambiguous_overloading_error.qux'/0,
+ambiguous_overloading_error.m:046:     the type constructor
+ambiguous_overloading_error.m:046:     `ambiguous_overloading_error.baz'/0.
+ambiguous_overloading_error.m:100: In clause for predicate `test_lt'/1:
+ambiguous_overloading_error.m:100:   error: excessively ambiguous overloading.
+ambiguous_overloading_error.m:100:   The following symbol was overloaded in the
+ambiguous_overloading_error.m:100:   following contexts.
+ambiguous_overloading_error.m:051:   The predicate symbol predicate `<'/2.
+ambiguous_overloading_error.m:051:   The possible matches are:
+ambiguous_overloading_error.m:051:     predicate `float.<'/2,
+ambiguous_overloading_error.m:051:     predicate `int.<'/2.
+ambiguous_overloading_error.m:052:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:052:   also overloaded here.
+ambiguous_overloading_error.m:053:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:053:   also overloaded here.
+ambiguous_overloading_error.m:054:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:054:   also overloaded here.
+ambiguous_overloading_error.m:055:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:055:   also overloaded here.
+ambiguous_overloading_error.m:056:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:056:   also overloaded here.
+ambiguous_overloading_error.m:057:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:057:   also overloaded here.
+ambiguous_overloading_error.m:058:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:058:   also overloaded here.
+ambiguous_overloading_error.m:059:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:059:   also overloaded here.
+ambiguous_overloading_error.m:060:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:060:   also overloaded here.
+ambiguous_overloading_error.m:061:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:061:   also overloaded here.
+ambiguous_overloading_error.m:062:   The predicate symbol predicate `<'/2 is
+ambiguous_overloading_error.m:062:   also overloaded here.
+ambiguous_overloading_error.m:110: In clause for predicate
+ambiguous_overloading_error.m:110:   `set_browser_param_from_option_table'/3:
+ambiguous_overloading_error.m:110:   warning: highly ambiguous overloading.
+ambiguous_overloading_error.m:110:   The following symbol was overloaded in the
+ambiguous_overloading_error.m:110:   following context.
+ambiguous_overloading_error.m:104:   The function symbol
+ambiguous_overloading_error.m:104:   `lookup_bool_option'/2.
+ambiguous_overloading_error.m:104:   The possible matches are:
+ambiguous_overloading_error.m:104:     predicate `getopt.lookup_bool_option'/3,
+ambiguous_overloading_error.m:104:     function `getopt.lookup_bool_option'/2.
+For more information, recompile with `-E'.
Index: tests/invalid/ambiguous_overloading_error.m
===================================================================
RCS file: tests/invalid/ambiguous_overloading_error.m
diff -N tests/invalid/ambiguous_overloading_error.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/ambiguous_overloading_error.m	11 May 2007 00:42:07 -0000
@@ -0,0 +1,117 @@
+% 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).
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
Index: tests/warnings/ambiguous_overloading.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/warnings/ambiguous_overloading.exp,v
retrieving revision 1.6
diff -u -b -r1.6 ambiguous_overloading.exp
--- tests/warnings/ambiguous_overloading.exp	7 Sep 2006 05:51:46 -0000	1.6
+++ tests/warnings/ambiguous_overloading.exp	10 May 2007 16:37:42 -0000
@@ -25,10 +25,10 @@
 ambiguous_overloading.m:045:     `ambiguous_overloading.qux'/0,
 ambiguous_overloading.m:045:     the type constructor
 ambiguous_overloading.m:045:     `ambiguous_overloading.baz'/0.
-ambiguous_overloading.m:055: In clause for predicate `test_lt'/1:
-ambiguous_overloading.m:055:   warning: highly ambiguous overloading.
-ambiguous_overloading.m:055:   The following symbol was overloaded in the
-ambiguous_overloading.m:055:   following contexts.
+ambiguous_overloading.m:056: In clause for predicate `test_lt'/1:
+ambiguous_overloading.m:056:   warning: highly ambiguous overloading.
+ambiguous_overloading.m:056:   The following symbol was overloaded in the
+ambiguous_overloading.m:056:   following contexts.
 ambiguous_overloading.m:050:   The predicate symbol predicate `<'/2.
 ambiguous_overloading.m:050:   The possible matches are:
 ambiguous_overloading.m:050:     predicate `float.<'/2,
@@ -43,11 +43,11 @@
 ambiguous_overloading.m:054:   overloaded here.
 ambiguous_overloading.m:055:   The predicate symbol predicate `<'/2 is also
 ambiguous_overloading.m:055:   overloaded here.
-ambiguous_overloading.m:071: In clause for predicate
-ambiguous_overloading.m:071:   `set_browser_param_from_option_table'/3:
-ambiguous_overloading.m:071:   warning: highly ambiguous overloading.
-ambiguous_overloading.m:071:   The following symbol was overloaded in the
-ambiguous_overloading.m:071:   following context.
+ambiguous_overloading.m:077: In clause for predicate
+ambiguous_overloading.m:077:   `set_browser_param_from_option_table'/3:
+ambiguous_overloading.m:077:   warning: highly ambiguous overloading.
+ambiguous_overloading.m:077:   The following symbol was overloaded in the
+ambiguous_overloading.m:077:   following context.
 ambiguous_overloading.m:071:   The function symbol `lookup_bool_option'/2.
 ambiguous_overloading.m:071:   The possible matches are:
 ambiguous_overloading.m:071:     predicate `getopt.lookup_bool_option'/3,
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list