[m-rev.] for post-commit review: mode analysis error reporting

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Jul 21 10:30:40 AEST 2009


Make the mode analysis pass return errors as a single list of error
specifications, instead of printing those error specifications out
in bits and pieces as it goes along.

Since the mode analysis code now does not need the I/O state to print out
error messages, don't pass the I/O state around in it. Use trace goals
when we need to print progress messages or debugging output.

compiler/modes.m:
compiler/unique_modes.m:
compiler/modecheck_unify.m:
compiler/modecheck_call.m:
	Implement the change described above.

	Rationalize the argument orders of some predicates.

compiler/modes.m:
compiler/unify_proc.m:
	Move the code for modechecking the procedures in the requested unify
	procedure queue from unify_proc.m to modes.m, since that is where
	all the related code is. Export a small, abstract part of the
	representation of the request queue from unify_proc.m to make this
	possible.

compiler/mode_debug.m:
	Delete the checkpoint predicate's I/O state arguments.

compiler/mode_errors.m:
	Replace predicates that print some error messages with functions
	that just return their error specifications.

	Delete some unused predicates.

	Replace a boolean with a purpose-specific type.

	Rationalize the argument orders of some predicates.

compiler/cse_detection.m:
compiler/delay_partial_inst.m:
	Don't pass around the I/O state, since it is now not needed.

	Rename a predicate to avoid ambiguity.

compiler/mercury_compile.m:
	Conform to the changes above. Amongst other things, this means
	printing the error specifications returned by mode analysis.

compiler/pd_util.m:
compiler/try_expand.m:
	Conform to the changes above.

compiler/error_util.m:
	Fix a typo.

tests/invalid/bigtest.err_exp:
tests/invalid/constrained_poly_insts.err_exp:
	Update these expected outputs for the new order of the error messages.
	(Before the error specifications are printed, they are sorted by
	context; this sorting did not occur in the old version.)

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/cse_detection.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/cse_detection.m,v
retrieving revision 1.121
diff -u -b -r1.121 cse_detection.m
--- compiler/cse_detection.m	10 Mar 2009 05:00:29 -0000	1.121
+++ compiler/cse_detection.m	21 Jul 2009 00:23:34 -0000
@@ -24,12 +24,10 @@
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.

-:- import_module io.
-
-:- pred detect_cse(module_info::in, module_info::out, io::di, io::uo) is det.
+:- pred detect_cse_in_module(module_info::in, module_info::out) is det.

 :- pred detect_cse_in_proc(proc_id::in, pred_id::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -60,8 +58,10 @@
 :- import_module assoc_list.
 :- import_module bool.
 :- import_module int.
+:- import_module io.
 :- import_module list.
 :- import_module map.
+:- import_module maybe.
 :- import_module pair.
 :- import_module set.
 :- import_module string.
@@ -71,93 +71,109 @@

 %-----------------------------------------------------------------------------%

-detect_cse(!ModuleInfo, !IO) :-
+detect_cse_in_module(!ModuleInfo) :-
     % Traverse the module structure, calling `detect_cse_in_goal'
     % for each procedure body.
     module_info_predids(PredIds, !ModuleInfo),
-    detect_cse_in_preds(PredIds, !ModuleInfo, !IO).
+    detect_cse_in_preds(PredIds, !ModuleInfo).

 :- pred detect_cse_in_preds(list(pred_id)::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.

-detect_cse_in_preds([], !ModuleInfo, !IO).
-detect_cse_in_preds([PredId | PredIds], !ModuleInfo, !IO) :-
+detect_cse_in_preds([], !ModuleInfo).
+detect_cse_in_preds([PredId | PredIds], !ModuleInfo) :-
     module_info_preds(!.ModuleInfo, PredTable),
     map.lookup(PredTable, PredId, PredInfo),
-    detect_cse_in_pred(PredId, PredInfo, !ModuleInfo, !IO),
-    detect_cse_in_preds(PredIds, !ModuleInfo, !IO).
+    detect_cse_in_pred(PredId, PredInfo, !ModuleInfo),
+    detect_cse_in_preds(PredIds, !ModuleInfo).

 :- pred detect_cse_in_pred(pred_id::in, pred_info::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.

-detect_cse_in_pred(PredId, PredInfo0, !ModuleInfo, !IO) :-
-    ProcIds = pred_info_non_imported_procids(PredInfo0),
-    detect_cse_in_procs(ProcIds, PredId, !ModuleInfo, !IO).
+detect_cse_in_pred(PredId, PredInfo, !ModuleInfo) :-
+    ProcIds = pred_info_non_imported_procids(PredInfo),
+    detect_cse_in_procs(ProcIds, PredId, !ModuleInfo).

 :- pred detect_cse_in_procs(list(proc_id)::in, pred_id::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.

-detect_cse_in_procs([], _PredId, !ModuleInfo, !IO).
-detect_cse_in_procs([ProcId | ProcIds], PredId, !ModuleInfo, !IO) :-
-    detect_cse_in_proc(ProcId, PredId, !ModuleInfo, !IO),
-    detect_cse_in_procs(ProcIds, PredId, !ModuleInfo, !IO).
+detect_cse_in_procs([], _PredId, !ModuleInfo).
+detect_cse_in_procs([ProcId | ProcIds], PredId, !ModuleInfo) :-
+    detect_cse_in_proc(ProcId, PredId, !ModuleInfo),
+    detect_cse_in_procs(ProcIds, PredId, !ModuleInfo).

-detect_cse_in_proc(ProcId, PredId, !ModuleInfo, !IO) :-
-    globals.io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
+detect_cse_in_proc(ProcId, PredId, !ModuleInfo) :-
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, very_verbose, VeryVerbose),
     (
         VeryVerbose = yes,
+        trace [io(!IO)] (
         io.write_string("% Detecting common deconstructions for ", !IO),
         hlds_out.write_pred_id(!.ModuleInfo, PredId, !IO),
         io.write_string("\n", !IO)
+        )
     ;
         VeryVerbose = no
     ),
     detect_cse_in_proc_pass(ProcId, PredId, Redo, !ModuleInfo),
-    globals.io_lookup_bool_option(detailed_statistics, Statistics, !IO),
-    maybe_report_stats(Statistics, !IO),
+    globals.lookup_bool_option(Globals, detailed_statistics, Statistics),
+    trace [io(!IO)] (
+        maybe_report_stats(Statistics, !IO)
+    ),
     (
         Redo = no
     ;
         Redo = yes,
         (
             VeryVerbose = yes,
+            trace [io(!IO)] (
             io.write_string("% Repeating mode check for ", !IO),
             hlds_out.write_pred_id(!.ModuleInfo, PredId, !IO),
             io.write_string("\n", !IO)
+            )
         ;
             VeryVerbose = no
         ),
-        modecheck_proc(ProcId, PredId, !ModuleInfo, ErrorSpecs, _Changed, !IO),
-        maybe_report_stats(Statistics, !IO),
-        module_info_get_globals(!.ModuleInfo, Globals),
-        write_error_specs(ErrorSpecs, Globals, 0, _NumWarnings, 0, NumErrors,
-            !IO),
-        module_info_incr_num_errors(NumErrors, !ModuleInfo),
-        ( NumErrors > 0 ->
+        modecheck_proc(ProcId, PredId, !ModuleInfo, ModeSpecs, _Changed),
+        trace [io(!IO)] (
+            maybe_report_stats(Statistics, !IO)
+        ),
+        ContainsErrors = contains_errors(Globals, ModeSpecs),
+        (
+            ContainsErrors = yes,
             unexpected(this_file, "mode check fails when repeated")
         ;
-            true
+            ContainsErrors = no
+            % There is no point in returning any warnings and/or informational
+            % messages to our caller, since any such messages should already
+            % have been gathered during the initial mode analysis pass.
         ),
         (
             VeryVerbose = yes,
+            trace [io(!IO)] (
             io.write_string("% Repeating switch detection for ", !IO),
             hlds_out.write_pred_id(!.ModuleInfo, PredId, !IO),
             io.write_string("\n", !IO)
+            )
         ;
             VeryVerbose = no
         ),
         detect_switches_in_proc(ProcId, PredId, !ModuleInfo),
-        maybe_report_stats(Statistics, !IO),
+        trace [io(!IO)] (
+            maybe_report_stats(Statistics, !IO)
+        ),
         (
             VeryVerbose = yes,
+            trace [io(!IO)] (
             io.write_string("% Repeating common " ++
                 "deconstruction detection for ", !IO),
             hlds_out.write_pred_id(!.ModuleInfo, PredId, !IO),
             io.write_string("\n", !IO)
+            )
         ;
             VeryVerbose = no
         ),
-        detect_cse_in_proc(ProcId, PredId, !ModuleInfo, !IO)
+        detect_cse_in_proc(ProcId, PredId, !ModuleInfo)
     ).

 :- type cse_info
Index: compiler/delay_partial_inst.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/delay_partial_inst.m,v
retrieving revision 1.14
diff -u -b -r1.14 delay_partial_inst.m
--- compiler/delay_partial_inst.m	16 Jul 2009 07:27:11 -0000	1.14
+++ compiler/delay_partial_inst.m	20 Jul 2009 03:02:14 -0000
@@ -112,13 +112,12 @@
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.

-:- import_module io.
 :- import_module list.

 %-----------------------------------------------------------------------------%

 :- pred delay_partial_inst_preds(list(pred_id)::in, list(pred_id)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+    module_info::in, module_info::out) is det.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -139,9 +138,10 @@
 :- import_module parse_tree.prog_data.

 :- import_module bool.
+:- import_module int.
+:- import_module io.
 :- import_module map.
 :- import_module maybe.
-:- import_module int.
 :- import_module pair.
 :- import_module set.
 :- import_module string.
@@ -186,28 +186,29 @@

 %-----------------------------------------------------------------------------%

-delay_partial_inst_preds([], [], !ModuleInfo, !IO).
-delay_partial_inst_preds([PredId | PredIds], ChangedPreds, !ModuleInfo, !IO) :-
+delay_partial_inst_preds([], [], !ModuleInfo).
+delay_partial_inst_preds([PredId | PredIds], ChangedPreds, !ModuleInfo) :-
     module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
     ProcIds = pred_info_non_imported_procids(PredInfo),
-    list.foldl3(delay_partial_inst_proc(PredId), ProcIds, !ModuleInfo,
-        no, Changed, !IO),
+    list.foldl2(delay_partial_inst_proc(PredId), ProcIds, !ModuleInfo,
+        no, Changed),
     (
         Changed = yes,
-        delay_partial_inst_preds(PredIds, ChangedPreds0, !ModuleInfo, !IO),
+        delay_partial_inst_preds(PredIds, ChangedPreds0, !ModuleInfo),
         ChangedPreds = [PredId | ChangedPreds0]
     ;
         Changed = no,
-        delay_partial_inst_preds(PredIds, ChangedPreds, !ModuleInfo, !IO)
+        delay_partial_inst_preds(PredIds, ChangedPreds, !ModuleInfo)
     ).

 :- pred delay_partial_inst_proc(pred_id::in, proc_id::in,
-    module_info::in, module_info::out, bool::in, bool::out, io::di, io::uo)
-    is det.
+    module_info::in, module_info::out, bool::in, bool::out) is det.

-delay_partial_inst_proc(PredId, ProcId, !ModuleInfo, !Changed, !IO) :-
+delay_partial_inst_proc(PredId, ProcId, !ModuleInfo, !Changed) :-
+    trace [io(!IO)] (
     write_proc_progress_message("% Delaying partial instantiations in ",
-        PredId, ProcId, !.ModuleInfo, !IO),
+            PredId, ProcId, !.ModuleInfo, !IO)
+    ),
     module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId, PredInfo,
         ProcInfo0),
     delay_partial_inst_proc_2(!.ModuleInfo, ProcInfo0, MaybeProcInfo),
Index: compiler/error_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/error_util.m,v
retrieving revision 1.68
diff -u -b -r1.68 error_util.m
--- compiler/error_util.m	16 Jul 2008 03:30:26 -0000	1.68
+++ compiler/error_util.m	21 Jul 2009 00:22:07 -0000
@@ -200,7 +200,8 @@
 :- func actual_error_severity(globals, error_severity)
     = maybe(actual_severity).

-    % Compute the worst actual severity (if any) occurring a list ofmessages.
+    % Compute the worst actual severity (if any) occurring in a list of
+    % error_specs.
     %
 :- func worst_severity_in_specs(globals, list(error_spec))
     = maybe(actual_severity).
@@ -220,11 +221,11 @@
 :- pred sort_error_msgs(list(error_msg)::in, list(error_msg)::out) is det.

 %-----------------------------------------------------------------------------%
+%
 % The error_spec_accumulator type can be used to accumulate errors for
 % multiple modes of a predicate.  accumulate_error_specs_for_proc will
 % eliminate warnings that should only be reported if they occur in every mode,
 % but don't occur in every mode.
-%

 :- type error_spec_accumulator.

Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.496
diff -u -b -r1.496 mercury_compile.m
--- compiler/mercury_compile.m	20 Jul 2009 02:22:51 -0000	1.496
+++ compiler/mercury_compile.m	20 Jul 2009 13:00:26 -0000
@@ -3149,7 +3149,11 @@
     module_info_get_num_errors(!.HLDS, NumErrors0),
     maybe_benchmark_modes(
         (pred(H0::in, {H, U}::out, !.IO::di, !:IO::uo) is det :-
-            modecheck_module(H0, H, U, !IO)
+            modecheck_module(H0, H1, U, Specs),
+            module_info_get_globals(H1, Globals),
+            write_error_specs(Specs, Globals,
+                0, _SpecsNumWarnings, 0, SpecsNumErrors, !IO),
+            module_info_incr_num_errors(SpecsNumErrors, H1, H)
         ),
         "modecheck", !.HLDS, {!:HLDS, SafeToContinue}, !IO),
     module_info_get_num_errors(!.HLDS, NumErrors),
@@ -3224,7 +3228,7 @@
         CommonGoal = yes,
         maybe_write_string(Verbose,
             "% Detecting common deconstructions...\n", !IO),
-        detect_cse(!HLDS, !IO),
+        detect_cse_in_module(!HLDS),
         maybe_write_string(Verbose, "% done.\n", !IO),
         maybe_report_stats(Stats, !IO)
     ;
@@ -3383,7 +3387,11 @@
     maybe_write_string(Verbose,
         "% Checking for backtracking over unique modes...\n", !IO),
     module_info_get_num_errors(!.HLDS, NumErrors0),
-    unique_modes_check_module(!HLDS, !IO),
+    unique_modes_check_module(!HLDS, Specs),
+    module_info_get_globals(!.HLDS, Globals),
+    write_error_specs(Specs, Globals, 0, _SpecsNumWarnings, 0, SpecsNumErrors,
+        !IO),
+    module_info_incr_num_errors(SpecsNumErrors, !HLDS),
     module_info_get_num_errors(!.HLDS, NumErrors),
     ( NumErrors \= NumErrors0 ->
         FoundError = yes,
Index: compiler/mode_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_debug.m,v
retrieving revision 1.32
diff -u -b -r1.32 mode_debug.m
--- compiler/mode_debug.m	23 Dec 2008 01:37:37 -0000	1.32
+++ compiler/mode_debug.m	20 Jul 2009 10:00:24 -0000
@@ -17,13 +17,12 @@
 :- interface.

 :- import_module check_hlds.mode_info.
-:- import_module io.

     % Print a debugging message which includes the port, message string,
     % and the current instmap (but only if `--debug-modes' was enabled).
     %
-:- pred mode_checkpoint(port::in, string::in, mode_info::in, mode_info::out,
-    io::di, io::uo) is det.
+:- pred mode_checkpoint(port::in, string::in, mode_info::in, mode_info::out)
+    is det.

 :- type port
     --->    enter
@@ -45,6 +44,7 @@

 :- import_module assoc_list.
 :- import_module bool.
+:- import_module io.
 :- import_module list.
 :- import_module maybe.
 :- import_module pair.
@@ -53,51 +53,42 @@

 %-----------------------------------------------------------------------------%

-    % This code is used to trace the actions of the mode checker.
-
-mode_checkpoint(Port, Msg, !ModeInfo, !IO) :-
+mode_checkpoint(Port, Msg, !ModeInfo) :-
     mode_info_get_debug_modes(!.ModeInfo, DebugModes),
     (
-        DebugModes = yes(debug_flags(Verbose, Minimal, Statistics)),
-        mode_checkpoint_write(Verbose, Minimal, Statistics, Port, Msg,
-            !ModeInfo, !IO)
-    ;
         DebugModes = no
-    ).
-
-:- pred mode_checkpoint_write(bool::in, bool::in, bool::in, port::in,
-    string::in, mode_info::in, mode_info::out, io::di, io::uo) is det.
-
-mode_checkpoint_write(Verbose, Minimal, Statistics, Port, Msg, !ModeInfo,
-        !IO) :-
+    ;
+        DebugModes = yes(debug_flags(Verbose, Minimal, Statistics)),
     mode_info_get_errors(!.ModeInfo, Errors),
     (
         Port = enter,
-        io.write_string("Enter ", !IO),
+            PortStr = "Enter ",
         Detail = yes
     ;
         Port = wakeup,
-        io.write_string("Wake ", !IO),
+            PortStr = "Wake ",
         Detail = no
     ;
         Port = exit,
         (
             Errors = [],
-            io.write_string("Exit ", !IO),
+                PortStr = "Exit ",
             Detail = yes
         ;
             Errors = [_ | _],
-            io.write_string("Delay ", !IO),
+                PortStr = "Delay ",
             Detail = no
         )
     ),
+        mode_info_get_instmap(!.ModeInfo, InstMap),
+        trace [io(!IO)] (
+            io.write_string(PortStr, !IO),
     io.write_string(Msg, !IO),
     (
         Detail = yes,
         io.write_string(":\n", !IO),
         maybe_report_stats(Statistics, !IO),
         maybe_flush_output(Statistics, !IO),
-        mode_info_get_instmap(!.ModeInfo, InstMap),
         ( instmap_is_reachable(InstMap) ->
             instmap_to_assoc_list(InstMap, NewInsts),
             mode_info_get_last_checkpoint_insts(!.ModeInfo, OldInstMap),
@@ -107,13 +98,20 @@
                 Verbose, Minimal, !IO)
         ;
             io.write_string("\tUnreachable\n", !IO)
-        ),
-        mode_info_set_last_checkpoint_insts(InstMap, !ModeInfo)
+                )
     ;
         Detail = no
     ),
     io.write_string("\n", !IO),
-    io.flush_output(!IO).
+            io.flush_output(!IO)
+        ),
+        (
+            Detail = yes,
+            mode_info_set_last_checkpoint_insts(InstMap, !ModeInfo)
+        ;
+            Detail = no
+        )
+    ).

 :- pred write_var_insts(assoc_list(prog_var, mer_inst)::in, instmap::in,
     prog_varset::in, inst_varset::in, bool::in, bool::in,
Index: compiler/mode_errors.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_errors.m,v
retrieving revision 1.128
diff -u -b -r1.128 mode_errors.m
--- compiler/mode_errors.m	11 Jun 2009 07:00:15 -0000	1.128
+++ compiler/mode_errors.m	20 Jul 2009 02:57:39 -0000
@@ -28,7 +28,6 @@
 :- import_module parse_tree.prog_data.

 :- import_module bool.
-:- import_module io.
 :- import_module list.
 :- import_module set.

@@ -201,12 +200,12 @@
     %
 :- pred mode_context_init(mode_context::out) is det.

-    % Report an error for a predicate with no mode declarations
+    % Return an error for a predicate with no mode declarations
     % unless mode inference is enabled and the predicate is local.
     % XXX This predicate should be included in the types above.
     %
-:- pred maybe_report_error_no_modes(pred_id::in, pred_info::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- func maybe_report_error_no_modes(module_info, pred_id, pred_info)
+    = list(error_spec).

     % Report an error for the case when two mode declarations
     % declare indistinguishable modes.
@@ -215,13 +214,17 @@
 :- func report_indistinguishable_modes_error(module_info, proc_id, proc_id,
     pred_id, pred_info) = error_spec.

+:- type include_detism_on_modes
+    --->    include_detism_on_modes
+    ;       do_not_include_detism_on_modes.
+
     % Write out the inferred `mode' declarations for a list of pred_ids.
     % The bool indicates whether or not to write out determinism
     % annotations on the modes (it should only be set to `yes' _after_
     % determinism analysis).
     %
-:- pred write_mode_inference_messages(list(pred_id)::in, bool::in,
-    module_info::in, io::di, io::uo) is det.
+:- func report_mode_inference_messages(module_info, include_detism_on_modes,
+    list(pred_id)) = list(error_spec).

 :- func mode_decl_to_string(proc_id, pred_info) = string.

@@ -229,8 +232,7 @@

 :- func mode_warning_info_to_spec(mode_info, mode_warning_info) = error_spec.

-:- pred should_report_mode_warning_for_pred_origin(pred_origin::in,
-    bool::out) is det.
+:- func should_report_mode_warning_for_pred_origin(pred_origin) = bool.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -252,6 +254,7 @@

 :- import_module assoc_list.
 :- import_module int.
+:- import_module io.            % used only for a typeclass instance
 :- import_module map.
 :- import_module maybe.
 :- import_module pair.
@@ -498,7 +501,7 @@
         [option_is_set(very_verbose, yes,
             [always([nl]),
              'new print_anything'(
-                write_indented_goal(Goal, ModuleInfo, VarSet))])]),
+                write_indented_goal(ModuleInfo, VarSet, Goal))])]),
     Error = mode_error_info(_, ModeError, ErrorContext, ModeContext),
     mode_info_set_context(ErrorContext, !ModeInfo),
     mode_info_set_mode_context(ModeContext, !ModeInfo),
@@ -507,15 +510,13 @@
     Msgs = [Msg1, Msg2] ++ SubMsgs.

 :- type write_indented_goal
-    --->    write_indented_goal(hlds_goal, module_info, prog_varset).
+    --->    write_indented_goal(module_info, prog_varset, hlds_goal).

 :- instance error_util.print_anything(write_indented_goal) where [
-
-    ( print_anything(write_indented_goal(Goal, ModuleInfo, VarSet), !IO) :-
+    ( print_anything(write_indented_goal(ModuleInfo, VarSet, Goal), !IO) :-
         io.write_string("\t\t", !IO),
         hlds_out.write_goal(Goal, ModuleInfo, VarSet, no, 2, ".\n", !IO)
     )
-
 ].

 %-----------------------------------------------------------------------------%
@@ -1230,28 +1231,29 @@

 %-----------------------------------------------------------------------------%

-should_report_mode_warning_for_pred_origin(origin_special_pred(_), no).
-should_report_mode_warning_for_pred_origin(origin_instance_method(_, _), no).
-should_report_mode_warning_for_pred_origin(origin_transformed(_, _, _), no).
-should_report_mode_warning_for_pred_origin(origin_created(_), no).
-should_report_mode_warning_for_pred_origin(origin_assertion(_, _), no).
-should_report_mode_warning_for_pred_origin(origin_lambda(_, _, _), yes).
-should_report_mode_warning_for_pred_origin(origin_user(_), yes).
+should_report_mode_warning_for_pred_origin(origin_special_pred(_)) = no.
+should_report_mode_warning_for_pred_origin(origin_instance_method(_, _)) = no.
+should_report_mode_warning_for_pred_origin(origin_transformed(_, _, _)) = no.
+should_report_mode_warning_for_pred_origin(origin_created(_)) = no.
+should_report_mode_warning_for_pred_origin(origin_assertion(_, _)) = no.
+should_report_mode_warning_for_pred_origin(origin_lambda(_, _, _)) = yes.
+should_report_mode_warning_for_pred_origin(origin_user(_)) = yes.

 %-----------------------------------------------------------------------------%

-maybe_report_error_no_modes(PredId, PredInfo, !ModuleInfo, !IO) :-
+maybe_report_error_no_modes(ModuleInfo, PredId, PredInfo) = Specs :-
     pred_info_get_import_status(PredInfo, ImportStatus),
+    module_info_get_globals(ModuleInfo, Globals),
     ( ImportStatus = status_local ->
-        globals.io_lookup_bool_option(infer_modes, InferModesOpt, !IO),
+        globals.lookup_bool_option(Globals, infer_modes, InferModesOpt),
         (
-            InferModesOpt = yes
+            InferModesOpt = yes,
+            Specs = []
         ;
             InferModesOpt = no,
-            io.set_exit_status(1, !IO),
             pred_info_get_context(PredInfo, Context),
             MainPieces = [words("Error: no mode declaration for")] ++
-                describe_one_pred_name(!.ModuleInfo, should_not_module_qualify,
+                describe_one_pred_name(ModuleInfo, should_not_module_qualify,
                     PredId) ++ [suffix("."), nl],
             VerbosePieces =
                 [words("(Use `--infer-modes' to enable mode inference.)"), nl],
@@ -1259,52 +1261,51 @@
                 phase_mode_check(report_in_any_mode),
                 [simple_msg(Context,
                     [always(MainPieces), verbose_only(VerbosePieces)])]),
-            module_info_get_globals(!.ModuleInfo, Globals),
-            write_error_spec(Spec, Globals, 0, _NumWarnings, 0, NumErrors,
-                !IO),
-            module_info_incr_num_errors(NumErrors, !ModuleInfo)
+            Specs = [Spec]
         )
     ;
-        io.set_exit_status(1, !IO),
         pred_info_get_context(PredInfo, Context),
         Pieces = [words("Error: no mode declaration for exported")] ++
-            describe_one_pred_name(!.ModuleInfo, should_module_qualify, PredId)
+            describe_one_pred_name(ModuleInfo, should_module_qualify, PredId)
             ++ [suffix("."), nl],
         Spec = error_spec(severity_error, phase_mode_check(report_in_any_mode),
             [simple_msg(Context, [always(Pieces)])]),
-        module_info_get_globals(!.ModuleInfo, Globals),
-        write_error_spec(Spec, Globals, 0, _NumWarnings, 0, NumErrors, !IO),
-        module_info_incr_num_errors(NumErrors, !ModuleInfo)
+        Specs = [Spec]
     ).

 %-----------------------------------------------------------------------------%

     % Write out the inferred `mode' declarations for a list of pred_ids.
     %
-write_mode_inference_messages([], _, _, !IO).
-write_mode_inference_messages([PredId | PredIds], OutputDetism, ModuleInfo,
-        !IO) :-
+report_mode_inference_messages(_, _, []) = [].
+report_mode_inference_messages(ModuleInfo, OutputDetism, [PredId | PredIds]) =
+        Specs :-
+    TailSpecs = report_mode_inference_messages(ModuleInfo, OutputDetism,
+        PredIds),
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
     pred_info_get_markers(PredInfo, Markers),
     ( check_marker(Markers, marker_infer_modes) ->
         ProcIds = pred_info_all_procids(PredInfo),
         pred_info_get_procedures(PredInfo, Procs),
-        write_mode_inference_messages_2(ProcIds, Procs, PredInfo,
-            OutputDetism, ModuleInfo, !IO)
+        HeadSpecs = report_mode_inference_messages_2(ModuleInfo, OutputDetism,
+            PredInfo, Procs, ProcIds),
+        Specs = HeadSpecs ++ TailSpecs
     ;
-        true
-    ),
-    write_mode_inference_messages(PredIds, OutputDetism, ModuleInfo, !IO).
+        Specs = TailSpecs
+    ).

     % Write out the inferred `mode' declarations for a list of proc_ids.
     %
-:- pred write_mode_inference_messages_2(list(proc_id)::in, proc_table::in,
-    pred_info::in, bool::in, module_info::in, io::di, io::uo) is det.
+:- func report_mode_inference_messages_2(module_info, include_detism_on_modes,
+    pred_info, proc_table, list(proc_id)) = list(error_spec).

-write_mode_inference_messages_2([], _, _, _, _, !IO).
-write_mode_inference_messages_2([ProcId | ProcIds], Procs, PredInfo,
-        OutputDetism, ModuleInfo, !IO) :-
-    globals.io_lookup_bool_option(verbose_errors, VerboseErrors, !IO),
+report_mode_inference_messages_2(_, _, _, _, []) = [].
+report_mode_inference_messages_2(ModuleInfo, OutputDetism, PredInfo, Procs,
+        [ProcId | ProcIds]) = Specs :-
+    TailSpecs = report_mode_inference_messages_2(ModuleInfo, OutputDetism,
+        PredInfo, Procs, ProcIds),
+    module_info_get_globals(ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, verbose_errors, VerboseErrors),
     map.lookup(Procs, ProcId, ProcInfo),
     (
         (
@@ -1316,22 +1317,21 @@
             VerboseErrors = yes
         )
     ->
-        write_mode_inference_message(PredInfo, ProcInfo, OutputDetism,
-            ModuleInfo, !IO)
+        HeadSpec = report_mode_inference_message(ModuleInfo, OutputDetism,
+            PredInfo, ProcInfo),
+        Specs = [HeadSpec | TailSpecs]
     ;
-        true
-    ),
-    write_mode_inference_messages_2(ProcIds, Procs, PredInfo, OutputDetism,
-        ModuleInfo, !IO).
+        Specs = TailSpecs
+    ).

-    % Write out the inferred `mode' declaration for a single function
-    % or predicate.
+    % Return a description of the inferred mode declaration for the given
+    % predicate or function.
     %
-:- pred write_mode_inference_message(pred_info::in, proc_info::in, bool::in,
-    module_info::in, io::di, io::uo) is det.
+:- func report_mode_inference_message(module_info, include_detism_on_modes,
+    pred_info, proc_info) = error_spec.

-write_mode_inference_message(PredInfo, ProcInfo, OutputDetism, ModuleInfo,
-        !IO) :-
+report_mode_inference_message(ModuleInfo, OutputDetism, PredInfo, ProcInfo)
+        = Spec :-
     PredName = pred_info_name(PredInfo),
     Name = unqualified(PredName),
     pred_info_get_context(PredInfo, Context),
@@ -1353,11 +1353,11 @@
         varset.init(VarSet),
         PredOrFunc = pred_info_is_pred_or_func(PredInfo),
         (
-            OutputDetism = yes,
+            OutputDetism = include_detism_on_modes,
             proc_info_get_inferred_determinism(ProcInfo, Detism),
             !:MaybeDet = yes(Detism)
         ;
-            OutputDetism = no,
+            OutputDetism = do_not_include_detism_on_modes,
             !:MaybeDet = no
         ),
         ( proc_info_is_valid_mode(ProcInfo) ->
@@ -1390,9 +1390,7 @@
         Pieces = [words(Verb), words(Detail), nl],
         Msg = simple_msg(Context, [always(Pieces)]),
         Spec = error_spec(severity_informational,
-            phase_mode_check(report_in_any_mode), [Msg]),
-        module_info_get_globals(ModuleInfo, Globals),
-        write_error_spec(Spec, Globals, 0, _NumWarnings, 0, _NumErrors, !IO)
+            phase_mode_check(report_in_any_mode), [Msg])
     ).

 %-----------------------------------------------------------------------------%
@@ -1435,11 +1433,6 @@
     String = mercury_mode_subdecl_to_string(PredOrFunc, InstVarSet, Name,
         Modes, MaybeDet, Context).

-:- pred output_inst(mer_inst::in, mode_info::in, io::di, io::uo) is det.
-
-output_inst(Inst0, ModeInfo, !IO) :-
-    io.write_string(inst_to_string(ModeInfo, Inst0), !IO).
-
 :- func inst_to_string(mode_info, mer_inst) = string.

 inst_to_string(ModeInfo, Inst0) = Str :-
@@ -1448,34 +1441,11 @@
     mode_info_get_module_info(ModeInfo, ModuleInfo),
     Str = mercury_expanded_inst_to_string(Inst, InstVarSet, ModuleInfo).

-:- pred output_inst_list(list(mer_inst)::in, mode_info::in, io::di, io::uo)
-    is det.
-
-output_inst_list(Insts, ModeInfo, !IO) :-
-    io.write_string(inst_list_to_string(ModeInfo, Insts), !IO).
-
 :- func inst_list_to_string(mode_info, list(mer_inst)) = string.

 inst_list_to_string(ModeInfo, Insts) =
     string.join_list(", ", list.map(inst_to_string(ModeInfo), Insts)).

-:- pred output_inst_list_sep_lines(prog_context::in, list(mer_inst)::in,
-    mode_info::in, io::di, io::uo) is det.
-
-output_inst_list_sep_lines(_Context, [], _, !IO).
-output_inst_list_sep_lines(Context, [Inst | Insts], ModeInfo, !IO) :-
-    prog_out.write_context(Context, !IO),
-    io.write_string("    ", !IO),
-    output_inst(Inst, ModeInfo, !IO),
-    (
-        Insts = []
-    ;
-        Insts = [_ | _],
-        io.write_string(",", !IO)
-    ),
-    io.nl(!IO),
-    output_inst_list_sep_lines(Context, Insts, ModeInfo, !IO).
-
 :- func inst_list_to_sep_lines(mode_info, list(mer_inst))
     = list(format_component).

Index: compiler/modecheck_unify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modecheck_unify.m,v
retrieving revision 1.128
diff -u -b -r1.128 modecheck_unify.m
--- compiler/modecheck_unify.m	11 Jun 2009 07:00:15 -0000	1.128
+++ compiler/modecheck_unify.m	20 Jul 2009 10:02:46 -0000
@@ -26,13 +26,11 @@
 :- import_module hlds.hlds_goal.
 :- import_module parse_tree.prog_data.

-:- import_module io.
-
     % Modecheck a unification.
     %
 :- pred modecheck_unification(prog_var::in, unify_rhs::in, unification::in,
     unify_context::in, hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

     % Create a unification between the two given variables.
     % The goal's mode and determinism information are not filled in.
@@ -73,6 +71,7 @@

 :- import_module assoc_list.
 :- import_module bool.
+:- import_module io.
 :- import_module list.
 :- import_module map.
 :- import_module maybe.
@@ -101,15 +100,15 @@
     % locals, provided the type of the higher-order value is impure.
     %
 modecheck_unification(LHSVar, RHS, Unification0, UnifyContext, UnifyGoalInfo0,
-        Goal, !ModeInfo, !IO) :-
+        Goal, !ModeInfo) :-
     (
         RHS = rhs_var(RHSVar),
         modecheck_unification_var(LHSVar, RHSVar,
-            Unification0, UnifyContext, UnifyGoalInfo0, Goal, !ModeInfo, !IO)
+            Unification0, UnifyContext, UnifyGoalInfo0, Goal, !ModeInfo)
     ;
         RHS = rhs_functor(ConsId, IsExistConstr, RHSVars),
         modecheck_unification_functor(LHSVar, ConsId, IsExistConstr, RHSVars,
-            Unification0, UnifyContext, UnifyGoalInfo0, Goal, !ModeInfo, !IO)
+            Unification0, UnifyContext, UnifyGoalInfo0, Goal, !ModeInfo)
     ;
         RHS = rhs_lambda_goal(Purity, HOGroundness, _PredOrFunc,
             _LambdaEvalMethod, LambdaNonLocals, _LambdaQuantVars, _ArgModes,
@@ -134,21 +133,21 @@
             ->
                 modecheck_unification_rhs_undetermined_mode_lambda(LHSVar,
                     RHS, Unification0, UnifyContext, UnifyGoalInfo0, Goal,
-                    !ModeInfo, !IO)
+                    !ModeInfo)
             ;
                 modecheck_unification_rhs_lambda(LHSVar,
                     RHS, Unification0, UnifyContext, UnifyGoalInfo0, Goal,
-                    !ModeInfo, !IO)
+                    !ModeInfo)
             )
         )
     ).

 :- pred modecheck_unification_var(prog_var::in, prog_var::in, unification::in,
     unify_context::in, hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_unification_var(X, Y, Unification0, UnifyContext,
-        UnifyGoalInfo0, UnifyGoalExpr, !ModeInfo, !IO) :-
+        UnifyGoalInfo0, UnifyGoalExpr, !ModeInfo) :-
     mode_info_get_module_info(!.ModeInfo, ModuleInfo0),
     mode_info_get_var_types(!.ModeInfo, VarTypes),
     mode_info_get_instmap(!.ModeInfo, InstMap0),
@@ -242,10 +241,10 @@
 :- pred modecheck_unification_functor(prog_var::in, cons_id::in,
     is_existential_construction::in, list(prog_var)::in, unification::in,
     unify_context::in, hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_unification_functor(X0, ConsId0, IsExistConstruction, ArgVars0,
-        Unification0, UnifyContext, GoalInfo0, Goal, !ModeInfo, !IO) :-
+        Unification0, UnifyContext, GoalInfo0, Goal, !ModeInfo) :-
     mode_info_get_module_info(!.ModeInfo, ModuleInfo0),
     mode_info_get_var_types(!.ModeInfo, VarTypes0),
     map.lookup(VarTypes0, X0, TypeOfX),
@@ -283,22 +282,22 @@

         % Modecheck this unification in its new form.
         modecheck_unification(X0, Functor0, Unification0, UnifyContext,
-            GoalInfo0, Goal, !ModeInfo, !IO)
+            GoalInfo0, Goal, !ModeInfo)
     ;
-        % It's not a higher-order pred unification - just
-        % call modecheck_unify_functor to do the ordinary thing.
+        % It's not a higher-order pred unification, so just call
+        % modecheck_unify_functor to do the ordinary thing.
         modecheck_unify_functor(X0, TypeOfX, ConsId0,
             IsExistConstruction, ArgVars0, Unification0,
-            UnifyContext, GoalInfo0, Goal, !ModeInfo, !IO)
+            UnifyContext, GoalInfo0, Goal, !ModeInfo)
     ).

 :- pred modecheck_unification_rhs_lambda(prog_var::in,
     unify_rhs::in(rhs_lambda_goal), unification::in, unify_context::in,
-    hlds_goal_info::in, hlds_goal_expr::out, mode_info::in, mode_info::out,
-    io::di, io::uo) is det.
+    hlds_goal_info::in, hlds_goal_expr::out, mode_info::in, mode_info::out)
+    is det.

 modecheck_unification_rhs_lambda(X, LambdaGoal, Unification0, UnifyContext, _,
-        unify(X, RHS, Mode, Unification, UnifyContext), !ModeInfo, !IO) :-
+        unify(X, RHS, Mode, Unification, UnifyContext), !ModeInfo) :-
     LambdaGoal = rhs_lambda_goal(Purity, Groundness, PredOrFunc, EvalMethod,
         ArgVars, Vars, Modes0, Det, Goal0),

@@ -425,19 +424,19 @@

         mode_info_lock_vars(var_lock_lambda(PredOrFunc), NonLocals, !ModeInfo),

-        mode_checkpoint(enter, "lambda goal", !ModeInfo, !IO),
+        mode_checkpoint(enter, "lambda goal", !ModeInfo),
         % If we're being called from unique_modes.m, then we need to
-        % call unique_modes.check_goal rather than modecheck_goal.
+        % call unique_modes_check_goal rather than modecheck_goal.
         (
             HowToCheckGoal = check_unique_modes,
-            unique_modes_check_goal(Goal0, Goal1, !ModeInfo, !IO)
+            unique_modes_check_goal(Goal0, Goal1, !ModeInfo)
         ;
             HowToCheckGoal = check_modes,
-            modecheck_goal(Goal0, Goal1, !ModeInfo, !IO)
+            modecheck_goal(Goal0, Goal1, !ModeInfo)
         ),
         mode_list_get_final_insts(ModuleInfo0, Modes, FinalInsts),
         modecheck_lambda_final_insts(Vars, FinalInsts, Goal1, Goal, !ModeInfo),
-        mode_checkpoint(exit, "lambda goal", !ModeInfo, !IO),
+        mode_checkpoint(exit, "lambda goal", !ModeInfo),

         mode_info_remove_live_vars(LiveVars, !ModeInfo),
         mode_info_unlock_vars(var_lock_lambda(PredOrFunc), NonLocals,
@@ -529,11 +528,11 @@

 :- pred modecheck_unification_rhs_undetermined_mode_lambda(prog_var::in,
     unify_rhs::in(rhs_lambda_goal), unification::in, unify_context::in,
-    hlds_goal_info::in, hlds_goal_expr::out, mode_info::in, mode_info::out,
-    io::di, io::uo) is det.
+    hlds_goal_info::in, hlds_goal_expr::out, mode_info::in, mode_info::out)
+    is det.

 modecheck_unification_rhs_undetermined_mode_lambda(X, RHS0, Unification,
-        UnifyContext, GoalInfo0, Goal, !ModeInfo, !IO) :-
+        UnifyContext, GoalInfo0, Goal, !ModeInfo) :-
     RHS0 = rhs_lambda_goal(_, _, _, _, _, _, _, _, Goal0),
     % Find out the predicate called in the lambda goal.
     ( predids_with_args_from_goal(Goal0, [{PredId, ArgVars}]) ->
@@ -558,7 +557,7 @@
                 GoalInfo0, GoalInfo),
             % Modecheck this unification in its new form.
             modecheck_unification_rhs_lambda(X, RHS, Unification, UnifyContext,
-                GoalInfo, Goal, !ModeInfo, !IO)
+                GoalInfo, Goal, !ModeInfo)
         ;
             MatchResult = possible_modes([_, _ | _]),
             mode_info_error(set.make_singleton_set(X),
@@ -576,10 +575,10 @@
 :- pred modecheck_unify_functor(prog_var::in, mer_type::in, cons_id::in,
     is_existential_construction::in, list(prog_var)::in, unification::in,
     unify_context::in, hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_unify_functor(X0, TypeOfX, ConsId0, IsExistConstruction, ArgVars0,
-        Unification0, UnifyContext, GoalInfo0, Goal, !ModeInfo, !IO) :-
+        Unification0, UnifyContext, GoalInfo0, Goal, !ModeInfo) :-
     mode_info_get_module_info(!.ModeInfo, ModuleInfo0),
     mode_info_get_how_to_check(!.ModeInfo, HowToCheckGoal),

@@ -784,8 +783,10 @@
         % Unifying two preds is not erroneous as far as the mode checker
         % is concerned, but a mode _error_.
         Goal = disj([]),
-        globals.io_lookup_bool_option(warn_unification_cannot_succeed,
-            WarnCannotSucceed, !IO),
+        mode_info_get_module_info(!.ModeInfo, ModuleInfo),
+        module_info_get_globals(ModuleInfo, Globals),
+        globals.lookup_bool_option(Globals, warn_unification_cannot_succeed,
+            WarnCannotSucceed),
         (
             WarnCannotSucceed = yes,
             mode_info_get_in_dupl_for_switch(!.ModeInfo, InDuplForSwitch),
@@ -796,11 +797,10 @@
             ;
                 InDuplForSwitch = not_in_dupl_for_switch,
                 mode_info_get_pred_id(!.ModeInfo, PredId),
-                mode_info_get_module_info(!.ModeInfo, ModuleInfo),
                 module_info_pred_info(ModuleInfo, PredId, PredInfo),
                 pred_info_get_origin(PredInfo, Origin),
-                should_report_mode_warning_for_pred_origin(Origin,
-                    ReportWarning),
+                ReportWarning =
+                    should_report_mode_warning_for_pred_origin(Origin),
                 (
                     ReportWarning = yes,
                     Warning = cannot_succeed_var_functor(X, InstOfX, ConsId),
@@ -837,7 +837,7 @@
             true
         ),
         handle_extra_goals(Unify, ExtraGoals, GoalInfo0,
-            [X0 | ArgVars0], [X | ArgVars], InstMap0, Goal, !ModeInfo, !IO)
+            [X0 | ArgVars0], [X | ArgVars], InstMap0, Goal, !ModeInfo)
     ).

 :- pred all_arg_vars_are_non_free_or_solver_vars(list(prog_var)::in,
@@ -1096,7 +1096,7 @@
             mode_info_get_pred_id(!.ModeInfo, PredId),
             module_info_pred_info(ModuleInfo, PredId, PredInfo),
             pred_info_get_origin(PredInfo, Origin),
-            should_report_mode_warning_for_pred_origin(Origin, ReportWarning),
+            ReportWarning = should_report_mode_warning_for_pred_origin(Origin),
             (
                 ReportWarning = yes,
                 Warning = cannot_succeed_var_var(X, Y, InstOfX, InstOfY),
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.378
diff -u -b -r1.378 modes.m
--- compiler/modes.m	20 Jul 2009 02:22:52 -0000	1.378
+++ compiler/modes.m	21 Jul 2009 00:28:58 -0000
@@ -123,6 +123,10 @@
 % For example, `p(X) :- X = f(A, B), B is A + 1.', where p is declared as
 % `:- mode p(bound(f(ground,free))->ground).'.
 %
+% XXX At the moment we don't check for circular modes or insts.
+% If they aren't used, the compiler will probably not detect the error;
+% if they are, it will probably go into an infinite loop.
+%
 %-----------------------------------------------------------------------------%

 :- module check_hlds.modes.
@@ -139,7 +143,6 @@
 :- import_module parse_tree.prog_data.

 :- import_module bool.
-:- import_module io.
 :- import_module list.
 :- import_module maybe.

@@ -149,7 +152,7 @@
     --->    modes_safe_to_continue
     ;       modes_unsafe_to_continue.

-    % modecheck_module(!HLDS, safeToContinue, !IO):
+    % modecheck_module(!HLDS, SafeToContinue, Specs):
     %
     % Perform mode inference and checking for a whole module.
     %
@@ -158,14 +161,14 @@
     % not perform determinism-checking, because we might get internal errors.
     %
 :- pred modecheck_module(module_info::in, module_info::out,
-    modes_safe_to_continue::out, io::di, io::uo) is det.
+    modes_safe_to_continue::out, list(error_spec)::out) is det.

     % Mode-check or unique-mode-check the code of all the predicates
     % in a module.
     %
 :- pred check_pred_modes(how_to_check_goal::in, may_change_called_proc::in,
     module_info::in, module_info::out, modes_safe_to_continue::out,
-    io::di, io::uo) is det.
+    list(error_spec)::out) is det.

     % Mode-check the code for the given predicate in a given mode.
     % Returns the number of errs found and a bool `Changed'
@@ -173,7 +176,7 @@
     %
 :- pred modecheck_proc(proc_id::in, pred_id::in,
     module_info::in, module_info::out, list(error_spec)::out,
-    bool::out, io::di, io::uo) is det.
+    bool::out) is det.

     % Mode-check or unique-mode-check the code for the given predicate
     % in a given mode.
@@ -182,7 +185,7 @@
     %
 :- pred modecheck_proc_general(proc_id::in, pred_id::in, how_to_check_goal::in,
     may_change_called_proc::in, module_info::in, module_info::out,
-    list(error_spec)::out, bool::out, io::di, io::uo) is det.
+    list(error_spec)::out, bool::out) is det.

 %-----------------------------------------------------------------------------%

@@ -198,15 +201,15 @@

     % Calculate the argument number offset that needs to be passed to
     % modecheck_var_list_is_live, modecheck_var_has_inst_list, and
-    % modecheck_set_var_inst_list.  This offset number is calculated
-    % so that real arguments get positive argument numbers and
-    % type_info arguments get argument numbers less than or equal to 0.
+    % modecheck_set_var_inst_list. This offset number is calculated so that
+    % real arguments get positive argument numbers and type_info arguments
+    % get argument numbers less than or equal to 0.
     %
 :- pred compute_arg_offset(pred_info::in, int::out) is det.

     % Given a list of variables and a list of expected liveness, ensure
     % that the inst of each variable satisfies the corresponding expected
-    % liveness.  If the bool argument is `yes', then require an exact match.
+    % liveness. See below for the difference between the two variants.
     %
 :- pred modecheck_var_list_is_live_exact_match(list(prog_var)::in,
     list(is_live)::in, int::in, mode_info::in, mode_info::out) is det.
@@ -215,9 +218,9 @@

     % Given a list of variables and a list of initial insts, ensure that
     % the inst of each variable matches the corresponding initial inst.
-    % If the bool argument is `yes', then we require an exact match
-    % (using inst_matches_final), otherwise we allow the var to be more
-    % instantiated than the inst (using inst_matches_initial).
+    % The first variant requires an exact match (using inst_matches_final),
+    % while the second we allow the var to be more instantiated than the inst
+    % (using inst_matches_initial).
     %
 :- pred modecheck_var_has_inst_list_exact_match(list(prog_var)::in,
     list(mer_inst)::in, int::in, inst_var_sub::out,
@@ -226,7 +229,7 @@
     list(mer_inst)::in, int::in, inst_var_sub::out,
     mode_info::in, mode_info::out) is det.

-    % modecheck_set_var_inst(Var, Inst, MaybeUInst, ModeInfo0, ModeInfo):
+    % modecheck_set_var_inst(Var, Inst, MaybeUInst, !ModeInfo):
     %
     % Assign the given Inst to the given Var, after checking that it is
     % okay to do so.  If the inst to be assigned is the result of an
@@ -244,8 +247,8 @@
     list(mer_inst)::in, int::in, list(prog_var)::out, extra_goals::out,
     mode_info::in, mode_info::out) is det.

-    % Check that the final insts of the head vars of a lambda
-    % goal matches their expected insts.
+    % Check that the final insts of the head vars of a lambda goal
+    % matches their expected insts.
     %
 :- pred modecheck_lambda_final_insts(list(prog_var)::in, list(mer_inst)::in,
     hlds_goal::in, hlds_goal::out, mode_info::in, mode_info::out) is det.
@@ -273,15 +276,15 @@
 :- pred modecheck_functors_test(prog_var::in, cons_id::in, list(cons_id)::in,
     mode_info::in, mode_info::out) is det.

-    % compute_goal_instmap_delta(InstMap0, GoalExpr, GoalInfo0, GoalInfo,
-    %   !ModeInfo):
+    % compute_goal_instmap_delta(InstMap0, GoalExpr, !GoalInfo, !ModeInfo):
     %
     % Work out the instmap_delta for a goal from the instmaps before and after
-    % the goal.
+    % the goal. The instmap before the goal is given by InstMap0; the instmap
+    % after the goal is given by !.ModeInfo.
     %
 :- pred compute_goal_instmap_delta(instmap::in, hlds_goal_expr::in,
-    hlds_goal_info::in, hlds_goal_info::out,
-    mode_info::in, mode_info::out) is det.
+    hlds_goal_info::in, hlds_goal_info::out, mode_info::in, mode_info::out)
+    is det.

 %-----------------------------------------------------------------------------%

@@ -301,12 +304,12 @@
     %  Error Messages   Output directly to stdout.
     %
 :- pred modecheck_goal(hlds_goal::in, hlds_goal::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

     % Mode-check a single goal-expression.
     %
 :- pred modecheck_goal_expr(hlds_goal_expr::in, hlds_goal_info::in,
-    hlds_goal_expr::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

 :- type extra_goals
     --->    no_extra_goals
@@ -338,8 +341,7 @@
     %
 :- pred handle_extra_goals(hlds_goal_expr::in, extra_goals::in,
     hlds_goal_info::in, list(prog_var)::in, list(prog_var)::in,
-    instmap::in, hlds_goal_expr::out, mode_info::in, mode_info::out,
-    io::di, io::uo) is det.
+    instmap::in, hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

 :- pred mode_context_to_unify_context(mode_info::in, mode_context::in,
     unify_context::out) is det.
@@ -361,8 +363,10 @@
 :- implementation.

 :- import_module check_hlds.clause_to_proc.
+:- import_module check_hlds.cse_detection.
 :- import_module check_hlds.delay_info.
 :- import_module check_hlds.delay_partial_inst.
+:- import_module check_hlds.det_analysis.
 :- import_module check_hlds.inst_match.
 :- import_module check_hlds.inst_util.
 :- import_module check_hlds.mode_debug.
@@ -371,12 +375,14 @@
 :- import_module check_hlds.modecheck_call.
 :- import_module check_hlds.modecheck_unify.
 :- import_module check_hlds.polymorphism.
+:- import_module check_hlds.switch_detection.
 :- import_module check_hlds.type_util.
 :- import_module check_hlds.unify_proc.
 :- import_module check_hlds.unique_modes.
 :- import_module hlds.goal_util.
 :- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
+:- import_module hlds.hlds_out.
 :- import_module hlds.passes_aux.
 :- import_module hlds.pred_table.
 :- import_module hlds.quantification.
@@ -399,9 +405,11 @@
 :- import_module assoc_list.
 :- import_module bag.
 :- import_module int.
+:- import_module io.
 :- import_module list.
 :- import_module map.
 :- import_module pair.
+:- import_module queue.
 :- import_module set.
 :- import_module string.
 :- import_module svmap.
@@ -410,49 +418,67 @@

 %-----------------------------------------------------------------------------%

-modecheck_module(!Module, SafeToContinue, !IO) :-
-    globals.io_lookup_bool_option(statistics, Statistics, !IO),
-    globals.io_lookup_bool_option(verbose, Verbose, !IO),
-
-    maybe_write_string(Verbose, "% Mode-checking clauses...\n", !IO),
-    check_pred_modes(check_modes, may_change_called_proc, !Module,
-        SafeToContinue, !IO),
-    maybe_report_stats(Statistics, !IO).
+modecheck_module(!ModuleInfo, SafeToContinue, Specs) :-
+    module_info_get_globals(!.ModuleInfo, Globals),
+    trace [io(!IO)] (
+        globals.lookup_bool_option(Globals, verbose, Verbose),
+        maybe_write_string(Verbose, "% Mode-checking clauses...\n", !IO)
+    ),
+    check_pred_modes(check_modes, may_change_called_proc, !ModuleInfo,
+        SafeToContinue, Specs),
+    trace [io(!IO)] (
+        globals.lookup_bool_option(Globals, statistics, Statistics),
+        maybe_report_stats(Statistics, !IO)
+    ).

 %-----------------------------------------------------------------------------%

-    % Mode-check the code for all the predicates in a module.
-
-check_pred_modes(WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, SafeToContinue, !IO) :-
+check_pred_modes(WhatToCheck, MayChangeCalledProc, !ModuleInfo,
+        SafeToContinue, !:Specs) :-
     module_info_predids(PredIds, !ModuleInfo),
-    globals.io_lookup_int_option(mode_inference_iteration_limit,
-        MaxIterations, !IO),
+    module_info_get_globals(!.ModuleInfo, Globals),
+    globals.lookup_int_option(Globals, mode_inference_iteration_limit,
+        MaxIterations),
     modecheck_to_fixpoint(PredIds, MaxIterations, WhatToCheck,
-        MayChangeCalledProc, !ModuleInfo, SafeToContinue0, !IO),
+        MayChangeCalledProc, !ModuleInfo, SafeToContinue0, !:Specs),
     (
         WhatToCheck = check_unique_modes,
-        write_mode_inference_messages(PredIds, yes, !.ModuleInfo, !IO),
-        check_eval_methods(!ModuleInfo, !IO),
+        InferenceSpecs = report_mode_inference_messages(!.ModuleInfo,
+            include_detism_on_modes, PredIds),
+        !:Specs = InferenceSpecs ++ !.Specs,
+        check_eval_methods(!ModuleInfo, !Specs),
         SafeToContinue = SafeToContinue0
     ;
         WhatToCheck = check_modes,
         (
             SafeToContinue0 = modes_unsafe_to_continue,
-            write_mode_inference_messages(PredIds, no, !.ModuleInfo, !IO),
+            InferenceSpecs = report_mode_inference_messages(!.ModuleInfo,
+                do_not_include_detism_on_modes, PredIds),
+            !:Specs = InferenceSpecs ++ !.Specs,
             SafeToContinue = modes_unsafe_to_continue
         ;
             SafeToContinue0 = modes_safe_to_continue,
-            globals.io_lookup_bool_option(delay_partial_instantiations,
-                DelayPartialInstantiations, !IO),
+            globals.lookup_bool_option(Globals, delay_partial_instantiations,
+                DelayPartialInstantiations),
             (
                 DelayPartialInstantiations = yes,
-                delay_partial_inst_preds(PredIds, ChangedPreds, !ModuleInfo,
-                    !IO),
+                delay_partial_inst_preds(PredIds, ChangedPreds, !ModuleInfo),
                 % --delay-partial-instantiations requires mode checking to be
                 % run again.
                 modecheck_to_fixpoint(ChangedPreds, MaxIterations, WhatToCheck,
-                    MayChangeCalledProc, !ModuleInfo, SafeToContinue, !IO)
+                    MayChangeCalledProc, !ModuleInfo,
+                    SafeToContinue, FixpointSpecs),
+                % !.Specs and FixpointSpecs are two sets of warning messages
+                % about the program, with !.Specs being derived from the
+                % version before delay_partial_inst_preds, and FixpointSpecs
+                % being derived from the version after. They ought to be the
+                % same, but just in case they are not, we do not want to
+                % confuse users by reporting the same problem twice.
+                % Which version we pick is a question of taste. !.Specs
+                % is more closely related to the compiler's original expansion
+                % of the program, but FixpointSpecs may be more closely related
+                % to the expansion intended by the programmer.
+                !:Specs = FixpointSpecs
             ;
                 DelayPartialInstantiations = no,
                 SafeToContinue = modes_safe_to_continue
@@ -465,41 +491,59 @@
 :- pred modecheck_to_fixpoint(list(pred_id)::in, int::in,
     how_to_check_goal::in, may_change_called_proc::in,
     module_info::in, module_info::out, modes_safe_to_continue::out,
-    io::di, io::uo) is det.
+    list(error_spec)::out) is det.

 modecheck_to_fixpoint(PredIds, MaxIterations, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, SafeToContinue, !IO) :-
+        !ModuleInfo, SafeToContinue, !:Specs) :-
     % Save the old procedure bodies so that we can restore them for the
     % next pass.
     module_info_preds(!.ModuleInfo, OldPredTable0),

     % Analyze everything which has the "can-process" flag set to `yes'.
-    list.foldl4(maybe_modecheck_pred(WhatToCheck, MayChangeCalledProc),
-        PredIds, !ModuleInfo, no, Changed1, 0, NumErrors, !IO),
+    list.foldl3(maybe_modecheck_pred(WhatToCheck, MayChangeCalledProc),
+        PredIds, !ModuleInfo, no, Changed1, [], !:Specs),

     % Analyze the procedures whose "can-process" flag was no;
     % those procedures were inserted into the unify requests queue.
     modecheck_queued_procs(WhatToCheck, OldPredTable0, OldPredTable,
-        !ModuleInfo, Changed2, !IO),
-    io.get_exit_status(ExitStatus, !IO),
-
+        !ModuleInfo, Changed2, QueuedSpecs),
+    !:Specs = QueuedSpecs ++ !.Specs,
     bool.or(Changed1, Changed2, Changed),

-    % Stop if we have reached a fixpoint or found any errors.
-    ( Changed = no ->
+    module_info_get_globals(!.ModuleInfo, Globals),
+    ErrorsSoFar = contains_errors(Globals, !.Specs),
+    (
+        Changed = no,
+        % Stop if we have reached a fixpoint.
         SafeToContinue = modes_safe_to_continue
-    ; ( NumErrors > 0 ; ExitStatus \= 0 ) ->
+    ;
+        Changed = yes,
+        (
+            ErrorsSoFar = yes,
+            % Stop if we have found any errors.
         SafeToContinue = modes_unsafe_to_continue
     ;
-        % Stop if we have exceeded the iteration limit.
+            ErrorsSoFar = no,
         ( MaxIterations =< 1 ->
-            report_max_iterations_exceeded(!.ModuleInfo, !IO),
+                % Stop if we have exceeded the iteration limit.
+                MaxIterSpec = report_max_iterations_exceeded(!.ModuleInfo),
+                !:Specs = [MaxIterSpec | !.Specs],
             SafeToContinue = modes_unsafe_to_continue
         ;
-            globals.io_lookup_bool_option(debug_modes, DebugModes, !IO),
+                % Otherwise, continue iterating.
+                globals.lookup_bool_option(Globals, debug_modes, DebugModes),
             (
                 DebugModes = yes,
-                write_mode_inference_messages(PredIds, no, !.ModuleInfo, !IO)
+                    InferenceSpecs =
+                        report_mode_inference_messages(!.ModuleInfo,
+                            do_not_include_detism_on_modes, PredIds),
+                    trace [io(!IO)] (
+                        io.write_string("Inferences by current iteration:\n",
+                            !IO),
+                        write_error_specs(InferenceSpecs, Globals,
+                            0, _NumWarnings, 0, _NumErrors, !IO),
+                        io.write_string("End of inferences.\n", !IO)
+                    )
             ;
                 DebugModes = no
             ),
@@ -528,13 +572,14 @@

             MaxIterations1 = MaxIterations - 1,
             modecheck_to_fixpoint(PredIds, MaxIterations1, WhatToCheck,
-                MayChangeCalledProc, !ModuleInfo, SafeToContinue, !IO)
+                    MayChangeCalledProc, !ModuleInfo, SafeToContinue, !:Specs)
+            )
         )
     ).

-:- pred report_max_iterations_exceeded(module_info::in, io::di, io::uo) is det.
+:- func report_max_iterations_exceeded(module_info) = error_spec.

-report_max_iterations_exceeded(ModuleInfo, !IO) :-
+report_max_iterations_exceeded(ModuleInfo) = Spec :-
     module_info_get_globals(ModuleInfo, Globals),
     globals.lookup_int_option(Globals, mode_inference_iteration_limit,
         MaxIterations),
@@ -546,9 +591,7 @@
         words("iterations.)"), nl],
     Msg = error_msg(no, do_not_treat_as_first, 0, [always(Pieces)]),
     Spec = error_spec(severity_error, phase_mode_check(report_in_any_mode),
-        [Msg]),
-    % XXX _NumErrors
-    write_error_spec(Spec, Globals, 0, _NumWarnings, 0, _NumErrors, !IO).
+        [Msg]).

     % copy_pred_bodies(OldPredTable, ProcId, ModuleInfo0, ModuleInfo):
     %
@@ -629,10 +672,10 @@

 :- pred maybe_modecheck_pred(how_to_check_goal::in, may_change_called_proc::in,
     pred_id::in, module_info::in, module_info::out, bool::in, bool::out,
-    int::in, int::out, io::di, io::uo) is det.
+    list(error_spec)::in, list(error_spec)::out) is det.

 maybe_modecheck_pred(WhatToCheck, MayChangeCalledProc, PredId,
-        !ModuleInfo, !Changed, !NumErrors, !IO) :-
+        !ModuleInfo, !Changed, !Specs) :-
     module_info_preds(!.ModuleInfo, Preds0),
     map.lookup(Preds0, PredId, PredInfo0),
     ShouldModeCheck = should_modecheck_pred(PredInfo0),
@@ -640,27 +683,36 @@
         ShouldModeCheck = no
     ;
         ShouldModeCheck = yes,
-        write_modes_progress_message(PredId, PredInfo0, !.ModuleInfo,
-            WhatToCheck, !IO),
+        trace [io(!IO)] (
+            write_modes_progress_message(!.ModuleInfo, WhatToCheck,
+                PredId, PredInfo0, !IO)
+        ),
         modecheck_pred_mode_2(PredId, PredInfo0, WhatToCheck,
-            MayChangeCalledProc, !ModuleInfo, !Changed, ErrsInThisPred, !IO),
-        ( ErrsInThisPred = 0 ->
-            true
-        ;
-            module_info_get_num_errors(!.ModuleInfo, ModNumErrors0),
-            ModNumErrors1 = ModNumErrors0 + ErrsInThisPred,
-            module_info_set_num_errors(ModNumErrors1, !ModuleInfo),
+            MayChangeCalledProc, !ModuleInfo, !Changed,
+            ThisPredDeclSpecs, ThisPredProcSpecs),
+        !:Specs = ThisPredDeclSpecs ++ ThisPredProcSpecs ++ !.Specs,
+        % The lack of a mode declaration for the predicate is not a reason
+        % to stop mode inference on the predicate. That is why we check for
+        % errors only in ThisPredProcSpecs, not in ThisPredDeclSpecs.
+        module_info_get_globals(!.ModuleInfo, Globals),
+        ContainsError = contains_errors(Globals, ThisPredProcSpecs),
+        (
+            ContainsError = yes,
             module_info_remove_predid(PredId, !ModuleInfo)
+        ;
+            ContainsError = no
         ),
-        !:NumErrors = !.NumErrors + ErrsInThisPred,
-        globals.io_lookup_bool_option(detailed_statistics, Statistics, !IO),
+
+        globals.lookup_bool_option(Globals, detailed_statistics, Statistics),
+        trace [io(!IO)] (
         maybe_report_stats(Statistics, !IO)
+        )
     ).

-:- pred write_modes_progress_message(pred_id::in, pred_info::in,
-    module_info::in, how_to_check_goal::in, io::di, io::uo) is det.
+:- pred write_modes_progress_message(module_info::in, how_to_check_goal::in,
+    pred_id::in, pred_info::in, io::di, io::uo) is det.

-write_modes_progress_message(PredId, PredInfo, ModuleInfo, WhatToCheck, !IO) :-
+write_modes_progress_message(ModuleInfo, WhatToCheck, PredId, PredInfo, !IO) :-
     pred_info_get_markers(PredInfo, Markers),
     ( check_marker(Markers, marker_infer_modes) ->
         (
@@ -685,11 +737,11 @@

 :- pred modecheck_pred_mode_2(pred_id::in, pred_info::in,
     how_to_check_goal::in, may_change_called_proc::in,
-    module_info::in, module_info::out, bool::in, bool::out, int::out,
-    io::di, io::uo) is det.
+    module_info::in, module_info::out, bool::in, bool::out,
+    list(error_spec)::out, list(error_spec)::out) is det.

 modecheck_pred_mode_2(PredId, PredInfo0, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, !Changed, NumErrors, !IO) :-
+        !ModuleInfo, !Changed, DeclSpecs, ProcSpecs) :-
     (
         WhatToCheck = check_modes,
         pred_info_get_procedures(PredInfo0, ProcTable),
@@ -700,76 +752,71 @@
             )
         ->
             % There was at least one declared mode for this procedure.
-            true
+            DeclSpecs = []
         ;
             % There were no declared modes for this procedure.
-            maybe_report_error_no_modes(PredId, PredInfo0, !ModuleInfo, !IO)
+            DeclSpecs = maybe_report_error_no_modes(!.ModuleInfo, PredId,
+                PredInfo0)
         )
     ;
-        WhatToCheck = check_unique_modes
+        WhatToCheck = check_unique_modes,
+        DeclSpecs = []
     ),
     % Note that we use pred_info_procids rather than pred_info_all_procids
     % here, which means that we don't process modes that have already been
     % inferred as invalid.
     ProcIds = pred_info_procids(PredInfo0),
     modecheck_procs(ProcIds, PredId, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, !Changed, init_error_spec_accumulator, ErrorSpecs, !IO),
-
-    % Report errors and warnings.
-    module_info_get_globals(!.ModuleInfo, Globals),
-    ErrorSpecsList = error_spec_accumulator_to_list(ErrorSpecs),
-    write_error_specs(ErrorSpecsList, Globals, 0, _NumWarnings, 0, NumErrors,
-        !IO),
-    module_info_incr_num_errors(NumErrors, !ModuleInfo).
+        !ModuleInfo, !Changed, init_error_spec_accumulator, SpecsAcc),
+    ProcSpecs = error_spec_accumulator_to_list(SpecsAcc).

     % Iterate over the list of modes for a predicate.
     %
 :- pred modecheck_procs(list(proc_id)::in, pred_id::in, how_to_check_goal::in,
     may_change_called_proc::in, module_info::in, module_info::out,
     bool::in, bool::out,
-    error_spec_accumulator::in, error_spec_accumulator::out,
-    io::di, io::uo) is det.
+    error_spec_accumulator::in, error_spec_accumulator::out) is det.

-modecheck_procs([], _PredId, _, _, !ModuleInfo, !Changed, !ErrorSpecs, !IO).
+modecheck_procs([], _PredId, _, _, !ModuleInfo, !Changed, !Specs).
 modecheck_procs([ProcId | ProcIds], PredId, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, !Changed, !ErrorSpecs, !IO) :-
+        !ModuleInfo, !Changed, !SpecsAcc) :-
     % Mode-check that mode of the predicate.
     maybe_modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, !Changed, ProcSpecs, !IO),
-    accumulate_error_specs_for_proc(ProcSpecs, !ErrorSpecs),
+        !ModuleInfo, !Changed, ProcSpecs),
+    accumulate_error_specs_for_proc(ProcSpecs, !SpecsAcc),
     % Recursively process the remaining modes.
     modecheck_procs(ProcIds, PredId, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, !Changed, !ErrorSpecs, !IO).
+        !ModuleInfo, !Changed, !SpecsAcc).

 %-----------------------------------------------------------------------------%

     % Mode-check the code for predicate in a given mode.
     %
-modecheck_proc(ProcId, PredId, !ModuleInfo, Errors, Changed, !IO) :-
+modecheck_proc(ProcId, PredId, !ModuleInfo, Specs, Changed) :-
     modecheck_proc_general(ProcId, PredId, check_modes, may_change_called_proc,
-        !ModuleInfo, Errors, Changed, !IO).
+        !ModuleInfo, Specs, Changed).

 modecheck_proc_general(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, Errors, Changed, !IO) :-
+        !ModuleInfo, Specs, Changed) :-
     maybe_modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, no, Changed, Errors, !IO).
+        !ModuleInfo, no, Changed, Specs).

 :- pred maybe_modecheck_proc(proc_id::in, pred_id::in, how_to_check_goal::in,
     may_change_called_proc::in, module_info::in, module_info::out,
-    bool::in, bool::out, list(error_spec)::out, io::di, io::uo) is det.
+    bool::in, bool::out, list(error_spec)::out) is det.

 maybe_modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, !Changed, Errors, !IO) :-
+        !ModuleInfo, !Changed, Specs) :-
     module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId,
         _PredInfo0, ProcInfo0),
     proc_info_get_can_process(ProcInfo0, CanProcess),
     (
         CanProcess = no,
-        Errors = []
+        Specs = []
     ;
         CanProcess = yes,
         do_modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
-            !ModuleInfo, ProcInfo0, ProcInfo, !Changed, Errors, !IO),
+            !ModuleInfo, ProcInfo0, ProcInfo, !Changed, Specs),
         module_info_preds(!.ModuleInfo, Preds1),
         map.lookup(Preds1, PredId, PredInfo1),
         pred_info_get_procedures(PredInfo1, Procs1),
@@ -782,10 +829,10 @@
 :- pred do_modecheck_proc(proc_id::in, pred_id::in, how_to_check_goal::in,
     may_change_called_proc::in, module_info::in, module_info::out,
     proc_info::in, proc_info::out, bool::in, bool::out,
-    list(error_spec)::out, io::di, io::uo) is det.
+    list(error_spec)::out) is det.

 do_modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
-        !ModuleInfo, !ProcInfo, !Changed, ErrorAndWarningSpecs, !IO) :-
+        !ModuleInfo, !ProcInfo, !Changed, ErrorAndWarningSpecs) :-
     % Extract the useful fields in the proc_info.
     proc_info_get_headvars(!.ProcInfo, HeadVars),
     proc_info_get_argmodes(!.ProcInfo, ArgModes0),
@@ -867,17 +914,17 @@
                 (
                     ClausesForm0 = clause_disj(Disjuncts1),
                     Disjuncts2 = flatten_disjs(Disjuncts1),
-                    list.map_foldl2(
+                    list.map_foldl(
                         modecheck_clause_disj(HeadVars, InstMap0,
                             ArgFinalInsts0),
-                        Disjuncts2, Disjuncts, !ModeInfo, !IO),
+                        Disjuncts2, Disjuncts, !ModeInfo),
                     NewGoalExpr = disj(Disjuncts)
                 ;
                     ClausesForm0 = clause_switch(SwitchVar, CanFail, Cases1),
-                    list.map_foldl2(
+                    list.map_foldl(
                         modecheck_clause_switch(HeadVars, InstMap0,
                             ArgFinalInsts0, SwitchVar),
-                        Cases1, Cases, !ModeInfo, !IO),
+                        Cases1, Cases, !ModeInfo),
                     NewGoalExpr = switch(SwitchVar, CanFail, Cases)
                 )
             ;
@@ -900,18 +947,18 @@
                     ;
                         true
                     ),
-                    list.map_foldl2(
+                    list.map_foldl(
                         unique_modecheck_clause_disj(HeadVars, InstMap0,
                             ArgFinalInsts0, Detism, NonLocals,
                             NondetLiveVars0),
-                        Disjuncts2, Disjuncts, !ModeInfo, !IO),
+                        Disjuncts2, Disjuncts, !ModeInfo),
                     NewGoalExpr = disj(Disjuncts)
                 ;
                     ClausesForm0 = clause_switch(SwitchVar, CanFail, Cases1),
-                    list.map_foldl2(
+                    list.map_foldl(
                         unique_modecheck_clause_switch(HeadVars, InstMap0,
                             ArgFinalInsts0, SwitchVar),
-                        Cases1, Cases, !ModeInfo, !IO),
+                        Cases1, Cases, !ModeInfo),
                     NewGoalExpr = switch(SwitchVar, CanFail, Cases)
                 )
             ),
@@ -930,10 +977,10 @@
             % Modecheck the procedure body as a single goal.
             (
                 WhatToCheck = check_modes,
-                modecheck_goal(Body0, Body1, !ModeInfo, !IO)
+                modecheck_goal(Body0, Body1, !ModeInfo)
             ;
                 WhatToCheck = check_unique_modes,
-                unique_modes_check_goal(Body0, Body1, !ModeInfo, !IO)
+                unique_modes_check_goal(Body0, Body1, !ModeInfo)
             ),

             % Check that final insts match those specified in the
@@ -948,7 +995,7 @@
             % For inferred predicates, we don't report the error(s) here;
             % instead we just save them in the proc_info, thus marking that
             % procedure as invalid.
-            !:ProcInfo = !.ProcInfo ^ mode_errors := ModeErrors,
+            !ProcInfo ^ mode_errors := ModeErrors,
             ErrorAndWarningSpecs = []
         ;
             InferModes = no,
@@ -994,18 +1041,159 @@

 %-----------------------------------------------------------------------------%

+    % Do mode analysis of the queued procedures. If the first argument is
+    % `unique_mode_check', then also go on and do full determinism analysis
+    % and unique mode analysis on them as well. The pred_table arguments
+    % are used to store copies of the procedure bodies before unique mode
+    % analysis, so that we can restore them before doing the next analysis
+    % pass.
+    %
+:- pred modecheck_queued_procs(how_to_check_goal::in,
+    pred_table::in, pred_table::out, module_info::in, module_info::out,
+    bool::out, list(error_spec)::out) is det.
+
+modecheck_queued_procs(HowToCheckGoal, !OldPredTable, !ModuleInfo, Changed,
+        Specs) :-
+    module_info_get_proc_requests(!.ModuleInfo, Requests0),
+    get_req_queue(Requests0, RequestQueue0),
+    ( queue.get(RequestQueue0, PredProcId, RequestQueue1) ->
+        set_req_queue(RequestQueue1, Requests0, Requests1),
+        module_info_set_proc_requests(Requests1, !ModuleInfo),
+
+        % Check that the procedure is valid (i.e. type-correct), before
+        % we attempt to do mode analysis on it. This check is necessary
+        % to avoid internal errors caused by doing mode analysis on
+        % type-incorrect code.
+        % XXX inefficient! This is O(N*M).
+
+        PredProcId = proc(PredId, _ProcId),
+        module_info_predids(ValidPredIds, !ModuleInfo),
+        ( list.member(PredId, ValidPredIds) ->
+            trace [io(!IO)] (
+                queued_proc_progress_message(!.ModuleInfo, PredProcId,
+                    HowToCheckGoal, !IO)
+            ),
+            modecheck_queued_proc(HowToCheckGoal, PredProcId,
+                !OldPredTable, !ModuleInfo, HeadChanged, HeadSpecs)
+        ;
+            HeadSpecs = [],
+            HeadChanged = no
+        ),
+        modecheck_queued_procs(HowToCheckGoal, !OldPredTable, !ModuleInfo,
+            TailChanged, TailSpecs),
+        bool.or(HeadChanged, TailChanged, Changed),
+        Specs = HeadSpecs ++ TailSpecs
+    ;
+        Changed = no,
+        Specs = []
+    ).
+
+:- pred queued_proc_progress_message(module_info::in, pred_proc_id::in,
+    how_to_check_goal::in, io::di, io::uo) is det.
+
+queued_proc_progress_message(ModuleInfo, PredProcId, HowToCheckGoal, !IO) :-
+    module_info_get_globals(ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, very_verbose, VeryVerbose),
+    (
+        VeryVerbose = yes,
+        (
+            HowToCheckGoal = check_modes,
+            io.write_string("% Mode-analyzing ", !IO)
+        ;
+            HowToCheckGoal = check_unique_modes,
+            io.write_string("% Analyzing modes, determinism, " ++
+                "and unique-modes for\n% ", !IO)
+        ),
+        hlds_out.write_pred_proc_id(ModuleInfo, PredProcId, !IO),
+        io.write_string("\n", !IO)
+%       /*****
+%       mode_list_get_initial_insts(Modes, ModuleInfo1,
+%           InitialInsts),
+%       io.write_string("% Initial insts: `", !IO),
+%       varset.init(InstVarSet),
+%       mercury_output_inst_list(InitialInsts, InstVarSet, !IO),
+%       io.write_string("'\n", !IO)
+%       *****/
+    ;
+        VeryVerbose = no
+    ).
+
+:- pred modecheck_queued_proc(how_to_check_goal::in, pred_proc_id::in,
+    pred_table::in, pred_table::out, module_info::in, module_info::out,
+    bool::out, list(error_spec)::out) is det.
+
+modecheck_queued_proc(HowToCheckGoal, PredProcId, !OldPredTable, !ModuleInfo,
+        !:Changed, Specs) :-
+    % Mark the procedure as ready to be processed.
+    PredProcId = proc(PredId, ProcId),
+    module_info_preds(!.ModuleInfo, Preds0),
+    map.lookup(Preds0, PredId, PredInfo0),
+    pred_info_get_procedures(PredInfo0, Procs0),
+    map.lookup(Procs0, ProcId, ProcInfo0),
+    proc_info_set_can_process(yes, ProcInfo0, ProcInfo1),
+    map.det_update(Procs0, ProcId, ProcInfo1, Procs1),
+    pred_info_set_procedures(Procs1, PredInfo0, PredInfo1),
+    map.det_update(Preds0, PredId, PredInfo1, Preds1),
+    module_info_set_preds(Preds1, !ModuleInfo),
+
+    % Modecheck the procedure.
+    modecheck_proc(ProcId, PredId, !ModuleInfo, ModeSpecs, !:Changed),
+
+    module_info_get_globals(!.ModuleInfo, Globals),
+    ModeErrors = contains_errors(Globals, ModeSpecs),
+    (
+        ModeErrors = yes,
+        module_info_remove_predid(PredId, !ModuleInfo),
+        Specs = ModeSpecs
+    ;
+        ModeErrors = no,
+        (
+            HowToCheckGoal = check_unique_modes,
+            detect_switches_in_proc(ProcId, PredId, !ModuleInfo),
+            detect_cse_in_proc(ProcId, PredId, !ModuleInfo),
+            determinism_check_proc(ProcId, PredId, !ModuleInfo, DetismSpecs),
+            expect(unify(DetismSpecs, []), this_file,
+                "modecheck_queued_proc: found detism error"),
+            save_proc_info(ProcId, PredId, !.ModuleInfo, !OldPredTable),
+            unique_modes_check_proc(ProcId, PredId, !ModuleInfo,
+                NewChanged, UniqueSpecs),
+            bool.or(NewChanged, !Changed),
+            Specs = ModeSpecs ++ UniqueSpecs
+        ;
+            HowToCheckGoal = check_modes,
+            Specs = ModeSpecs
+        )
+    ).
+
+    % Save a copy of the proc info for the specified procedure in
+    % !OldProcTable.
+    %
+:- pred save_proc_info(proc_id::in, pred_id::in, module_info::in,
+    pred_table::in, pred_table::out) is det.
+
+save_proc_info(ProcId, PredId, ModuleInfo, !OldPredTable) :-
+    module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
+        _PredInfo, ProcInfo),
+    map.lookup(!.OldPredTable, PredId, OldPredInfo0),
+    pred_info_get_procedures(OldPredInfo0, OldProcTable0),
+    map.set(OldProcTable0, ProcId, ProcInfo, OldProcTable),
+    pred_info_set_procedures(OldProcTable, OldPredInfo0, OldPredInfo),
+    map.det_update(!.OldPredTable, PredId, OldPredInfo, !:OldPredTable).
+
+%-----------------------------------------------------------------------------%
+
 :- type clause_form
     --->    clause_disj(list(hlds_goal))
     ;       clause_switch(prog_var, can_fail, list(case)).

 :- pred modecheck_clause_disj(list(prog_var)::in, instmap::in,
     list(mer_inst)::in, hlds_goal::in, hlds_goal::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_clause_disj(HeadVars, InstMap0, ArgFinalInsts0, Disjunct0, Disjunct,
-        !ModeInfo, !IO) :-
+        !ModeInfo) :-
     mode_info_set_instmap(InstMap0, !ModeInfo),
-    modecheck_goal(Disjunct0, Disjunct1, !ModeInfo, !IO),
+    modecheck_goal(Disjunct0, Disjunct1, !ModeInfo),

     % Check that final insts match those specified in the mode declaration.
     modecheck_final_insts(HeadVars, no, ArgFinalInsts0,
@@ -1013,10 +1201,10 @@

 :- pred modecheck_clause_switch(list(prog_var)::in, instmap::in,
     list(mer_inst)::in, prog_var::in, case::in, case::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_clause_switch(HeadVars, InstMap0, ArgFinalInsts0, Var, Case0, Case,
-        !ModeInfo, !IO) :-
+        !ModeInfo) :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
     mode_info_set_instmap(InstMap0, !ModeInfo),

@@ -1025,7 +1213,7 @@
     % Modecheck this case (if it is reachable).
     mode_info_get_instmap(!.ModeInfo, InstMap1),
     ( instmap_is_reachable(InstMap1) ->
-        modecheck_goal(Goal0, Goal1, !ModeInfo, !IO),
+        modecheck_goal(Goal0, Goal1, !ModeInfo),
         mode_info_get_instmap(!.ModeInfo, InstMap)
     ;
         % We should not mode-analyse the goal, since it is unreachable.
@@ -1045,16 +1233,15 @@

 :- pred unique_modecheck_clause_disj(list(prog_var)::in, instmap::in,
     list(mer_inst)::in, determinism::in, set(prog_var)::in, bag(prog_var)::in,
-    hlds_goal::in, hlds_goal::out, mode_info::in, mode_info::out,
-    io::di, io::uo) is det.
+    hlds_goal::in, hlds_goal::out, mode_info::in, mode_info::out) is det.

 unique_modecheck_clause_disj(HeadVars, InstMap0, ArgFinalInsts0, DisjDetism,
-        DisjNonLocals, NondetLiveVars0, Disjunct0, Disjunct, !ModeInfo, !IO) :-
+        DisjNonLocals, NondetLiveVars0, Disjunct0, Disjunct, !ModeInfo) :-
     mode_info_set_instmap(InstMap0, !ModeInfo),
     mode_info_set_nondet_live_vars(NondetLiveVars0, !ModeInfo),
     unique_modes.prepare_for_disjunct(Disjunct0, DisjDetism, DisjNonLocals,
         !ModeInfo),
-    unique_modes_check_goal(Disjunct0, Disjunct1, !ModeInfo, !IO),
+    unique_modes_check_goal(Disjunct0, Disjunct1, !ModeInfo),

     % Check that final insts match those specified in the mode declaration.
     modecheck_final_insts(HeadVars, no, ArgFinalInsts0,
@@ -1062,10 +1249,10 @@

 :- pred unique_modecheck_clause_switch(list(prog_var)::in, instmap::in,
     list(mer_inst)::in, prog_var::in, case::in, case::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 unique_modecheck_clause_switch(HeadVars, InstMap0, ArgFinalInsts0, Var,
-        Case0, Case, !ModeInfo, !IO) :-
+        Case0, Case, !ModeInfo) :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
     mode_info_set_instmap(InstMap0, !ModeInfo),

@@ -1073,7 +1260,7 @@

     mode_info_get_instmap(!.ModeInfo, InstMap1),
     ( instmap_is_reachable(InstMap1) ->
-        unique_modes_check_goal(Goal0, Goal1, !ModeInfo, !IO)
+        unique_modes_check_goal(Goal0, Goal1, !ModeInfo)
     ;
         % We should not mode-analyse the goal, since it is unreachable.
         % Instead we optimize the goal away, so that later passes
@@ -1269,7 +1456,7 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%

-modecheck_goal(Goal0, Goal, !ModeInfo, !IO) :-
+modecheck_goal(Goal0, Goal, !ModeInfo) :-
     Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
     % Note: any changes here may need to be duplicated in unique_modes.m.

@@ -1284,112 +1471,110 @@
     ( goal_info_has_feature(GoalInfo0, feature_duplicated_for_switch) ->
         mode_info_get_in_dupl_for_switch(!.ModeInfo, InDuplForSwitch),
         mode_info_set_in_dupl_for_switch(in_dupl_for_switch, !ModeInfo),
-        modecheck_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo, !IO),
+        modecheck_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo),
         mode_info_set_in_dupl_for_switch(InDuplForSwitch, !ModeInfo)
     ;
-        modecheck_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo, !IO)
+        modecheck_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo)
     ).

 :- pred modecheck_goal_2(hlds_goal_expr::in, hlds_goal_info::in,
-    hlds_goal::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal::out, mode_info::in, mode_info::out) is det.

-:- pragma inline(modecheck_goal_2/7).
+:- pragma inline(modecheck_goal_2/5).

-modecheck_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo, !IO) :-
+modecheck_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo) :-
     % Modecheck the goal, and then store the changes in instantiation
     % of the vars in the delta_instmap in the goal's goal_info.
     mode_info_get_instmap(!.ModeInfo, InstMap0),
-    modecheck_goal_expr(GoalExpr0, GoalInfo0, GoalExpr, !ModeInfo, !IO),
+    modecheck_goal_expr(GoalExpr0, GoalInfo0, GoalExpr, !ModeInfo),
     compute_goal_instmap_delta(InstMap0, GoalExpr, GoalInfo0, GoalInfo,
         !ModeInfo),
     Goal = hlds_goal(GoalExpr, GoalInfo).

-modecheck_goal_expr(GoalExpr0, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
+modecheck_goal_expr(GoalExpr0, GoalInfo0, GoalExpr, !ModeInfo) :-
     % XXX The predicates we call here should have their definitions
     % in the same order as this switch.
     (
         GoalExpr0 = unify(LHS0, RHS0, _UniMode, Unification0, UnifyContext),
         modecheck_goal_unify(LHS0, RHS0, Unification0, UnifyContext, GoalInfo0,
-            GoalExpr, !ModeInfo, !IO)
+            GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = plain_call(PredId, ProcId0, Args0, _Builtin,
             MaybeCallUnifyContext, PredName),
         modecheck_goal_plain_call(PredId, ProcId0, Args0,
             MaybeCallUnifyContext, PredName, GoalInfo0, GoalExpr,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ;
         GoalExpr0 = generic_call(GenericCall, Args0, Modes0, _Detism),
         modecheck_goal_generic_call(GenericCall, Args0, Modes0, GoalInfo0,
-            GoalExpr, !ModeInfo, !IO)
+            GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = call_foreign_proc(Attributes, PredId, ProcId0,
             Args0, ExtraArgs, MaybeTraceRuntimeCond, PragmaCode),
         modecheck_goal_call_foreign_proc(Attributes, PredId, ProcId0,
             Args0, ExtraArgs, MaybeTraceRuntimeCond, PragmaCode,
-            GoalInfo0, GoalExpr, !ModeInfo, !IO)
+            GoalInfo0, GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = conj(ConjType, Goals),
         modecheck_goal_conj(ConjType, Goals, GoalInfo0, GoalExpr,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ;
         GoalExpr0 = disj(Goals),
-        modecheck_goal_disj(Goals, GoalInfo0, GoalExpr, !ModeInfo, !IO)
+        modecheck_goal_disj(Goals, GoalInfo0, GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = switch(Var, CanFail, Cases0),
         modecheck_goal_switch(Var, CanFail, Cases0, GoalInfo0, GoalExpr,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ;
         GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
         modecheck_goal_if_then_else(Vars, Cond0, Then0, Else0, GoalInfo0,
-            GoalExpr, !ModeInfo, !IO)
+            GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = negation(SubGoal0),
-        modecheck_goal_negation(SubGoal0, GoalInfo0, GoalExpr, !ModeInfo, !IO)
+        modecheck_goal_negation(SubGoal0, GoalInfo0, GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = scope(Reason, SubGoal0),
-        modecheck_goal_scope(Reason, SubGoal0, GoalInfo0, GoalExpr,
-            !ModeInfo, !IO)
+        modecheck_goal_scope(Reason, SubGoal0, GoalInfo0, GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = shorthand(ShortHand0),
-        modecheck_goal_shorthand(ShortHand0, GoalInfo0, GoalExpr,
-            !ModeInfo, !IO)
+        modecheck_goal_shorthand(ShortHand0, GoalInfo0, GoalExpr, !ModeInfo)
     ).

 %-----------------------------------------------------------------------------%

 :- pred modecheck_goal_conj(conj_type::in, list(hlds_goal)::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-modecheck_goal_conj(ConjType, Goals0, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
+modecheck_goal_conj(ConjType, Goals0, GoalInfo0, GoalExpr, !ModeInfo) :-
     (
         ConjType = plain_conj,
-        mode_checkpoint(enter, "conj", !ModeInfo, !IO),
+        mode_checkpoint(enter, "conj", !ModeInfo),
         (
             Goals0 = [],
             % Optimize the common case for efficiency.
             GoalExpr = conj(plain_conj, [])
         ;
             Goals0 = [_ | _],
-            modecheck_conj_list(ConjType, Goals0, Goals, !ModeInfo, !IO),
+            modecheck_conj_list(ConjType, Goals0, Goals, !ModeInfo),
             conj_list_to_goal(Goals, GoalInfo0, hlds_goal(GoalExpr, _GoalInfo))
         ),
-        mode_checkpoint(exit, "conj", !ModeInfo, !IO)
+        mode_checkpoint(exit, "conj", !ModeInfo)
     ;
         ConjType = parallel_conj,
-        mode_checkpoint(enter, "par_conj", !ModeInfo, !IO),
+        mode_checkpoint(enter, "par_conj", !ModeInfo),
         % Empty parallel conjunction should not be a common case.
-        modecheck_conj_list(ConjType, Goals0, Goals, !ModeInfo, !IO),
+        modecheck_conj_list(ConjType, Goals0, Goals, !ModeInfo),
         par_conj_list_to_goal(Goals, GoalInfo0,
             hlds_goal(GoalExpr, _GoalInfo)),
-        mode_checkpoint(exit, "par_conj", !ModeInfo, !IO)
+        mode_checkpoint(exit, "par_conj", !ModeInfo)
     ).

 :- pred modecheck_goal_disj(list(hlds_goal)::in, hlds_goal_info::in,
-    hlds_goal_expr::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

-modecheck_goal_disj(Disjuncts0, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "disj", !ModeInfo, !IO),
+modecheck_goal_disj(Disjuncts0, GoalInfo0, GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "disj", !ModeInfo),
     (
         Disjuncts0 = [],    % for efficiency, optimize common case
         GoalExpr = disj(Disjuncts0),
@@ -1401,7 +1586,7 @@
         Disjuncts0 = [_ | _],
         NonLocals = goal_info_get_nonlocals(GoalInfo0),
         modecheck_disj_list(Disjuncts0, Disjuncts1, InstMaps0,
-            NonLocals, LargeFlatConstructs, !ModeInfo, !IO),
+            NonLocals, LargeFlatConstructs, !ModeInfo),
         ( mode_info_solver_init_is_supported(!.ModeInfo) ->
             mode_info_get_var_types(!.ModeInfo, VarTypes),
             handle_solver_vars_in_disjs(set.to_sorted_list(NonLocals),
@@ -1416,15 +1601,14 @@
             Disjuncts3, Disjuncts, InstMaps, !ModeInfo),
         disj_list_to_goal(Disjuncts, GoalInfo0, hlds_goal(GoalExpr, _GoalInfo))
     ),
-    mode_checkpoint(exit, "disj", !ModeInfo, !IO).
+    mode_checkpoint(exit, "disj", !ModeInfo).

 :- pred modecheck_goal_switch(prog_var::in, can_fail::in, list(case)::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-modecheck_goal_switch(Var, CanFail, Cases0, GoalInfo0, GoalExpr,
-        !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "switch", !ModeInfo, !IO),
+modecheck_goal_switch(Var, CanFail, Cases0, GoalInfo0, GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "switch", !ModeInfo),
     (
         Cases0 = [],
         Cases = [],
@@ -1436,12 +1620,12 @@
         Cases0 = [_ | _],
         NonLocals = goal_info_get_nonlocals(GoalInfo0),
         modecheck_case_list(Cases0, Var, Cases1, InstMaps,
-            NonLocals, LargeFlatConstructs, !ModeInfo, !IO),
+            NonLocals, LargeFlatConstructs, !ModeInfo),
         merge_switch_branches(NonLocals, LargeFlatConstructs,
             Cases1, Cases, InstMaps, !ModeInfo)
     ),
     GoalExpr = switch(Var, CanFail, Cases),
-    mode_checkpoint(exit, "switch", !ModeInfo, !IO).
+    mode_checkpoint(exit, "switch", !ModeInfo).

 :- pred merge_disj_branches(set(prog_var)::in, set(prog_var)::in,
     list(hlds_goal)::in, list(hlds_goal)::out, list(instmap)::in,
@@ -1506,11 +1690,11 @@
 :- pred modecheck_goal_if_then_else(list(prog_var)::in,
     hlds_goal::in, hlds_goal::in, hlds_goal::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_goal_if_then_else(Vars, Cond0, Then0, Else0, GoalInfo0, GoalExpr,
-        !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "if-then-else", !ModeInfo, !IO),
+        !ModeInfo) :-
+    mode_checkpoint(enter, "if-then-else", !ModeInfo),
     NonLocals = goal_info_get_nonlocals(GoalInfo0),
     ThenVars = goal_get_nonlocals(Then0),
     mode_info_get_instmap(!.ModeInfo, InstMap0),
@@ -1520,12 +1704,12 @@

     mode_info_lock_vars(var_lock_if_then_else, NonLocals, !ModeInfo),
     mode_info_add_live_vars(ThenVars, !ModeInfo),
-    modecheck_goal(Cond0, Cond, !ModeInfo, !IO),
+    modecheck_goal(Cond0, Cond, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMapCond),
     mode_info_remove_live_vars(ThenVars, !ModeInfo),
     mode_info_unlock_vars(var_lock_if_then_else, NonLocals, !ModeInfo),
     ( instmap_is_reachable(InstMapCond) ->
-        modecheck_goal(Then0, Then1, !ModeInfo, !IO),
+        modecheck_goal(Then0, Then1, !ModeInfo),
         mode_info_get_instmap(!.ModeInfo, InstMapThen1)
     ;
         % We should not mode-analyse the goal, since it is unreachable.
@@ -1535,7 +1719,7 @@
         InstMapThen1 = InstMapCond
     ),
     mode_info_set_instmap(InstMap0, !ModeInfo),
-    modecheck_goal(Else0, Else1, !ModeInfo, !IO),
+    modecheck_goal(Else0, Else1, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMapElse1),
     mode_info_get_var_types(!.ModeInfo, VarTypes),
     handle_solver_vars_in_ite(set.to_sorted_list(NonLocals), VarTypes,
@@ -1557,13 +1741,13 @@
     ;
         InPromisePurityScope = in_promise_purity_scope
     ),
-    mode_checkpoint(exit, "if-then-else", !ModeInfo, !IO).
+    mode_checkpoint(exit, "if-then-else", !ModeInfo).

 :- pred modecheck_goal_negation(hlds_goal::in, hlds_goal_info::in,
-    hlds_goal_expr::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

-modecheck_goal_negation(SubGoal0, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "not", !ModeInfo, !IO),
+modecheck_goal_negation(SubGoal0, GoalInfo0, GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "not", !ModeInfo),
     NonLocals = goal_info_get_nonlocals(GoalInfo0),
     mode_info_get_instmap(!.ModeInfo, InstMap0),

@@ -1579,7 +1763,7 @@
     % We need to lock the non-local variables, to ensure that
     % the negation does not bind them.
     mode_info_lock_vars(var_lock_negation, NonLocals, !ModeInfo),
-    modecheck_goal(SubGoal0, SubGoal, !ModeInfo, !IO),
+    modecheck_goal(SubGoal0, SubGoal, !ModeInfo),
     mode_info_set_live_vars(LiveVars0, !ModeInfo),
     mode_info_unlock_vars(var_lock_negation, NonLocals, !ModeInfo),
     mode_info_set_instmap(InstMap0, !ModeInfo),
@@ -1594,37 +1778,37 @@
         InPromisePurityScope = in_promise_purity_scope
     ),
     GoalExpr = negation(SubGoal),
-    mode_checkpoint(exit, "not", !ModeInfo, !IO).
+    mode_checkpoint(exit, "not", !ModeInfo).

 :- pred modecheck_goal_scope(scope_reason::in, hlds_goal::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-modecheck_goal_scope(Reason, SubGoal0, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
+modecheck_goal_scope(Reason, SubGoal0, GoalInfo0, GoalExpr, !ModeInfo) :-
     (
         Reason = trace_goal(_, _, _, _, _),
-        mode_checkpoint(enter, "scope", !ModeInfo, !IO),
+        mode_checkpoint(enter, "scope", !ModeInfo),
         mode_info_get_instmap(!.ModeInfo, InstMap0),
         NonLocals = goal_info_get_nonlocals(GoalInfo0),
         % We need to lock the non-local variables, to ensure that
         % the trace goal does not bind them. If it did, then the code
         % would not be valid with the trace goal disabled.
         mode_info_lock_vars(var_lock_trace_goal, NonLocals, !ModeInfo),
-        modecheck_goal(SubGoal0, SubGoal, !ModeInfo, !IO),
+        modecheck_goal(SubGoal0, SubGoal, !ModeInfo),
         mode_info_unlock_vars(var_lock_trace_goal, NonLocals, !ModeInfo),
         mode_info_set_instmap(InstMap0, !ModeInfo),
-        mode_checkpoint(exit, "scope", !ModeInfo, !IO),
-        GoalExpr = scope(Reason, SubGoal)
+        GoalExpr = scope(Reason, SubGoal),
+        mode_checkpoint(exit, "scope", !ModeInfo)
     ;
         ( Reason = exist_quant(_)
         ; Reason = promise_solutions(_, _)
         ; Reason = commit(_)
         ; Reason = barrier(_)
         ),
-        mode_checkpoint(enter, "scope", !ModeInfo, !IO),
-        modecheck_goal(SubGoal0, SubGoal, !ModeInfo, !IO),
-        mode_checkpoint(exit, "scope", !ModeInfo, !IO),
-        GoalExpr = scope(Reason, SubGoal)
+        mode_checkpoint(enter, "scope", !ModeInfo),
+        modecheck_goal(SubGoal0, SubGoal, !ModeInfo),
+        GoalExpr = scope(Reason, SubGoal),
+        mode_checkpoint(exit, "scope", !ModeInfo)
     ;
         Reason = from_ground_term(TermVar, _OldKind),
         % The original goal does no quantification, so deleting the `scope'
@@ -1675,21 +1859,21 @@
             ;
                 SubGoal2 = SubGoal1
             ),
-            mode_checkpoint(enter, "scope", !ModeInfo, !IO),
-            modecheck_goal(SubGoal2, SubGoal, !ModeInfo, !IO),
-            mode_checkpoint(exit, "scope", !ModeInfo, !IO),
+            mode_checkpoint(enter, "scope", !ModeInfo),
+            modecheck_goal(SubGoal2, SubGoal, !ModeInfo),
             UpdatedReason = from_ground_term(TermVar, Kind),
-            GoalExpr = scope(UpdatedReason, SubGoal)
+            GoalExpr = scope(UpdatedReason, SubGoal),
+            mode_checkpoint(exit, "scope", !ModeInfo)
         )
     ;
         Reason = promise_purity(_Purity),
         mode_info_get_in_promise_purity_scope(!.ModeInfo, InPPScope),
         mode_info_set_in_promise_purity_scope(in_promise_purity_scope,
             !ModeInfo),
-        mode_checkpoint(enter, "scope", !ModeInfo, !IO),
-        modecheck_goal(SubGoal0, SubGoal, !ModeInfo, !IO),
-        mode_checkpoint(exit, "scope", !ModeInfo, !IO),
+        mode_checkpoint(enter, "scope", !ModeInfo),
+        modecheck_goal(SubGoal0, SubGoal, !ModeInfo),
         GoalExpr = scope(Reason, SubGoal),
+        mode_checkpoint(exit, "scope", !ModeInfo),
         mode_info_set_in_promise_purity_scope(InPPScope, !ModeInfo)
     ).

@@ -1849,13 +2033,13 @@
 :- pred modecheck_goal_plain_call(pred_id::in, proc_id::in,
     list(prog_var)::in, maybe(call_unify_context)::in, sym_name::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_goal_plain_call(PredId, ProcId0, Args0, MaybeCallUnifyContext,
-        PredName, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
+        PredName, GoalInfo0, GoalExpr, !ModeInfo) :-
     PredNameString = sym_name_to_string(PredName),
     CallString = "call " ++ PredNameString,
-    mode_checkpoint(enter, CallString, !ModeInfo, !IO),
+    mode_checkpoint(enter, CallString, !ModeInfo),

     mode_info_get_call_id(!.ModeInfo, PredId, CallId),
     mode_info_set_call_context(call_context_call(plain_call_id(CallId)),
@@ -1872,18 +2056,18 @@
     Call = plain_call(PredId, ProcId, Args, Builtin, MaybeCallUnifyContext,
         PredName),
     handle_extra_goals(Call, ExtraGoals, GoalInfo0, Args0, Args,
-        InstMap0, GoalExpr, !ModeInfo, !IO),
+        InstMap0, GoalExpr, !ModeInfo),

     mode_info_unset_call_context(!ModeInfo),
-    mode_checkpoint(exit, CallString, !ModeInfo, !IO).
+    mode_checkpoint(exit, CallString, !ModeInfo).

 :- pred modecheck_goal_generic_call(generic_call::in, list(prog_var)::in,
     list(mer_mode)::in, hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_goal_generic_call(GenericCall, Args0, Modes0, GoalInfo0, GoalExpr,
-        !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "generic_call", !ModeInfo, !IO),
+        !ModeInfo) :-
+    mode_checkpoint(enter, "generic_call", !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMap0),

     hlds_goal.generic_call_id(GenericCall, CallId),
@@ -1896,7 +2080,7 @@
         AllArgs0 = [PredVar | Args0],
         AllArgs = [PredVar | Args],
         handle_extra_goals(GoalExpr1, ExtraGoals, GoalInfo0, AllArgs0, AllArgs,
-            InstMap0, GoalExpr, !ModeInfo, !IO)
+            InstMap0, GoalExpr, !ModeInfo)
     ;
         % Class method calls are added by polymorphism.m.
         % XXX We should probably fill this in so that
@@ -1956,38 +2140,37 @@
         modecheck_builtin_cast(Modes, Args0, Args, Det, ExtraGoals, !ModeInfo),
         GoalExpr1 = generic_call(GenericCall, Args, Modes, Det),
         handle_extra_goals(GoalExpr1, ExtraGoals, GoalInfo0, Args0, Args,
-            InstMap0, GoalExpr, !ModeInfo, !IO)
+            InstMap0, GoalExpr, !ModeInfo)
     ),

     mode_info_unset_call_context(!ModeInfo),
-    mode_checkpoint(exit, "generic_call", !ModeInfo, !IO).
+    mode_checkpoint(exit, "generic_call", !ModeInfo).

 :- pred modecheck_goal_unify(prog_var::in, unify_rhs::in,
     unification::in, unify_context::in, hlds_goal_info::in,
-    hlds_goal_expr::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

 modecheck_goal_unify(LHS0, RHS0, Unification0, UnifyContext, GoalInfo0,
-        GoalExpr, !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "unify", !ModeInfo, !IO),
+        GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "unify", !ModeInfo),
     mode_info_set_call_context(call_context_unify(UnifyContext), !ModeInfo),
     modecheck_unification(LHS0, RHS0, Unification0, UnifyContext, GoalInfo0,
-        GoalExpr, !ModeInfo, !IO),
+        GoalExpr, !ModeInfo),
     mode_info_unset_call_context(!ModeInfo),
-    mode_checkpoint(exit, "unify", !ModeInfo, !IO).
+    mode_checkpoint(exit, "unify", !ModeInfo).

 :- pred modecheck_goal_call_foreign_proc(pragma_foreign_proc_attributes::in,
     pred_id::in, proc_id::in, list(foreign_arg)::in, list(foreign_arg)::in,
     maybe(trace_expr(trace_runtime))::in, pragma_foreign_code_impl::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_goal_call_foreign_proc(Attributes, PredId, ProcId0, Args0, ExtraArgs,
-        MaybeTraceRuntimeCond, PragmaCode, GoalInfo0, GoalExpr,
-        !ModeInfo, !IO) :-
+        MaybeTraceRuntimeCond, PragmaCode, GoalInfo0, GoalExpr, !ModeInfo) :-
     % To modecheck a foreign_proc, we just modecheck the proc for
     % which it is the goal.

-    mode_checkpoint(enter, "pragma_foreign_code", !ModeInfo, !IO),
+    mode_checkpoint(enter, "pragma_foreign_code", !ModeInfo),
     mode_info_get_call_id(!.ModeInfo, PredId, CallId),
     mode_info_get_instmap(!.ModeInfo, InstMap0),
     DeterminismKnown = no,
@@ -2004,15 +2187,15 @@
     Pragma = call_foreign_proc(Attributes, PredId, ProcId, Args0, ExtraArgs,
         MaybeTraceRuntimeCond, PragmaCode),
     handle_extra_goals(Pragma, ExtraGoals, GoalInfo0, ArgVars0, ArgVars,
-        InstMap0, GoalExpr, !ModeInfo, !IO),
+        InstMap0, GoalExpr, !ModeInfo),

     mode_info_unset_call_context(!ModeInfo),
-    mode_checkpoint(exit, "pragma_foreign_code", !ModeInfo, !IO).
+    mode_checkpoint(exit, "pragma_foreign_code", !ModeInfo).

 :- pred modecheck_goal_shorthand(shorthand_goal_expr::in, hlds_goal_info::in,
-    hlds_goal_expr::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

-modecheck_goal_shorthand(ShortHand0, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
+modecheck_goal_shorthand(ShortHand0, GoalInfo0, GoalExpr, !ModeInfo) :-
     (
         ShortHand0 = atomic_goal(_, Outer, Inner, MaybeOutputVars,
             MainGoal0, OrElseGoals0, OrElseInners),
@@ -2022,7 +2205,7 @@
         % "stm_outer_to_inner_io" during the construction of the HLDS.
         % These calls are removed when atomic goals are expanded.

-        mode_checkpoint(enter, "atomic", !ModeInfo, !IO),
+        mode_checkpoint(enter, "atomic", !ModeInfo),
         AtomicGoalList0 = [MainGoal0 | OrElseGoals0],
         NonLocals = goal_info_get_nonlocals(GoalInfo0),

@@ -2034,7 +2217,7 @@

         % mode_info_lock_vars(var_lock_atomic_goal, OuterVars, !ModeInfo),
         modecheck_orelse_list(AtomicGoalList0, AtomicGoalList1, InstMapList0,
-            !ModeInfo, !IO),
+            !ModeInfo),
         mode_info_get_var_types(!.ModeInfo, VarTypes),
         % mode_info_unlock_vars(var_lock_atomic_goal, OuterVars, !ModeInfo),

@@ -2087,14 +2270,14 @@
         ShortHand = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
             MainGoal, OrElseGoals, OrElseInners),
         GoalExpr = shorthand(ShortHand),
-        mode_checkpoint(exit, "atomic", !ModeInfo, !IO)
+        mode_checkpoint(exit, "atomic", !ModeInfo)
     ;
         ShortHand0 = try_goal(MaybeIO, ResultVar, SubGoal0),
-        mode_checkpoint(enter, "try", !ModeInfo, !IO),
-        modecheck_goal(SubGoal0, SubGoal, !ModeInfo, !IO),
+        mode_checkpoint(enter, "try", !ModeInfo),
+        modecheck_goal(SubGoal0, SubGoal, !ModeInfo),
         ShortHand = try_goal(MaybeIO, ResultVar, SubGoal),
         GoalExpr = shorthand(ShortHand),
-        mode_checkpoint(exit, "try", !ModeInfo, !IO)
+        mode_checkpoint(exit, "try", !ModeInfo)
     ;
         ShortHand0 = bi_implication(_, _),
         % These should have been expanded out by now.
@@ -2102,16 +2285,16 @@
     ).

 :- pred modecheck_orelse_list(list(hlds_goal)::in, list(hlds_goal)::out,
-    list(instmap)::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    list(instmap)::out, mode_info::in, mode_info::out) is det.

-modecheck_orelse_list([], [], [], !ModeInfo, !IO).
+modecheck_orelse_list([], [], [], !ModeInfo).
 modecheck_orelse_list([Goal0 | Goals0], [Goal | Goals], [InstMap | InstMaps],
-        !ModeInfo, !IO) :-
+        !ModeInfo) :-
     mode_info_get_instmap(!.ModeInfo, InstMap0),
-    modecheck_goal(Goal0, Goal, !ModeInfo, !IO),
+    modecheck_goal(Goal0, Goal, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMap),
     mode_info_set_instmap(InstMap0, !ModeInfo),
-    modecheck_orelse_list(Goals0, Goals, InstMaps, !ModeInfo, !IO).
+    modecheck_orelse_list(Goals0, Goals, InstMaps, !ModeInfo).

     % If the condition of a negation or if-then-else contains any inst any
     % non-locals (a potential referential transparency violation), then
@@ -2149,9 +2332,9 @@
     AfterGoals = AfterGoals0 ++ AfterGoals1.

 handle_extra_goals(MainGoal, no_extra_goals, _GoalInfo0, _Args0, _Args,
-        _InstMap0, MainGoal, !ModeInfo, !IO).
+        _InstMap0, MainGoal, !ModeInfo).
 handle_extra_goals(MainGoal, extra_goals(BeforeGoals0, AfterGoals0),
-        GoalInfo0, Args0, Args, InstMap0, Goal, !ModeInfo, !IO) :-
+        GoalInfo0, Args0, Args, InstMap0, Goal, !ModeInfo) :-
     mode_info_get_errors(!.ModeInfo, Errors),
     (
         % There's no point adding extra goals if the code is
@@ -2216,7 +2399,7 @@
         % argument unifications, which turns them into assignments,
         % and we end up repeating the process forever.
         mode_info_add_goals_live_vars(plain_conj, GoalList0, !ModeInfo),
-        modecheck_conj_list_no_delay(GoalList0, GoalList, !ModeInfo, !IO),
+        modecheck_conj_list_no_delay(GoalList0, GoalList, !ModeInfo),
         Goal = conj(plain_conj, GoalList),
         mode_info_set_checking_extra_goals(no, !ModeInfo),
         mode_info_set_may_change_called_proc(MayChangeCalledProc0, !ModeInfo)
@@ -2371,14 +2554,13 @@
     % This is used by handle_extra_goals above.
     %
 :- pred modecheck_conj_list_no_delay(list(hlds_goal)::in, list(hlds_goal)::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-modecheck_conj_list_no_delay([], [], !ModeInfo, !IO).
-modecheck_conj_list_no_delay([Goal0 | Goals0], [Goal | Goals], !ModeInfo,
-        !IO) :-
+modecheck_conj_list_no_delay([], [], !ModeInfo).
+modecheck_conj_list_no_delay([Goal0 | Goals0], [Goal | Goals], !ModeInfo) :-
     NonLocals = goal_get_nonlocals(Goal0),
     mode_info_remove_live_vars(NonLocals, !ModeInfo),
-    modecheck_goal(Goal0, Goal, !ModeInfo, !IO),
+    modecheck_goal(Goal0, Goal, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMap),
     ( instmap_is_unreachable(InstMap) ->
         % We should not mode-analyse the remaining goals, since they
@@ -2387,16 +2569,16 @@
         mode_info_remove_goals_live_vars(Goals0, !ModeInfo),
         Goals  = []
     ;
-        modecheck_conj_list_no_delay(Goals0, Goals, !ModeInfo, !IO)
+        modecheck_conj_list_no_delay(Goals0, Goals, !ModeInfo)
     ).

 %-----------------------------------------------------------------------------%

 :- pred modecheck_conj_list(conj_type::in,
     list(hlds_goal)::in, list(hlds_goal)::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-modecheck_conj_list(ConjType, Goals0, Goals, !ModeInfo, !IO) :-
+modecheck_conj_list(ConjType, Goals0, Goals, !ModeInfo) :-
     mode_info_get_errors(!.ModeInfo, OldErrors),
     mode_info_set_errors([], !ModeInfo),

@@ -2414,7 +2596,7 @@
     mode_info_set_may_init_solver_vars(may_not_init_solver_vars, !ModeInfo),

     modecheck_conj_list_2(ConjType, Goals0, Goals1,
-        [], RevImpurityErrors0, !ModeInfo, !IO),
+        [], RevImpurityErrors0, !ModeInfo),

     mode_info_get_delay_info(!.ModeInfo, DelayInfo2),
     delay_info_leave_conj(DelayInfo2, DelayedGoals0, DelayInfo3),
@@ -2425,7 +2607,7 @@
     %
     modecheck_delayed_solver_goals(ConjType, Goals2,
         DelayedGoals0, DelayedGoals, RevImpurityErrors0, RevImpurityErrors,
-        !ModeInfo, !IO),
+        !ModeInfo),
     Goals = Goals1 ++ Goals2,

     mode_info_get_errors(!.ModeInfo, NewErrors),
@@ -2503,27 +2685,27 @@
 :- pred modecheck_conj_list_2(conj_type::in,
     list(hlds_goal)::in, list(hlds_goal)::out,
     impurity_errors::in, impurity_errors::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-modecheck_conj_list_2(_ConjType, [], [], !ImpurityErrors, !ModeInfo, !IO).
+modecheck_conj_list_2(_ConjType, [], [], !ImpurityErrors, !ModeInfo).
 modecheck_conj_list_2(ConjType, [Goal0 | Goals0], Goals, !ImpurityErrors,
-        !ModeInfo, !IO) :-
+        !ModeInfo) :-
     (
         Goal0 = hlds_goal(conj(plain_conj, ConjGoals), _),
         ConjType = plain_conj
     ->
         Goals1 = ConjGoals ++ Goals0,
         modecheck_conj_list_2(ConjType, Goals1, Goals, !ImpurityErrors,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ;
         modecheck_conj_list_3(ConjType, Goal0, Goals0, Goals, !ImpurityErrors,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ).

 :- pred modecheck_conj_list_3(conj_type::in, hlds_goal::in,
     list(hlds_goal)::in, list(hlds_goal)::out,
     impurity_errors::in, impurity_errors::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

     % Schedule a conjunction. If it is empty, then there is nothing to do.
     % For non-empty conjunctions, we attempt to schedule the first goal
@@ -2532,13 +2714,13 @@
     % to schedule all the rest of the goals.
     %
 modecheck_conj_list_3(ConjType, Goal0, Goals0, Goals, !ImpurityErrors,
-        !ModeInfo, !IO) :-
+        !ModeInfo) :-
     Purity = goal_get_purity(Goal0),
     (
         Purity = purity_impure,
         Impure = yes,
         check_for_impurity_error(Goal0, ScheduledSolverGoals,
-            !ImpurityErrors, !ModeInfo, !IO)
+            !ImpurityErrors, !ModeInfo)
     ;
         ( Purity = purity_pure
         ; Purity = purity_semipure
@@ -2555,7 +2737,7 @@
     % which occur in the goal might not be live anymore.
     NonLocalVars = goal_get_nonlocals(Goal0),
     mode_info_remove_live_vars(NonLocalVars, !ModeInfo),
-    modecheck_goal(Goal0, Goal, !ModeInfo, !IO),
+    modecheck_goal(Goal0, Goal, !ModeInfo),

     % Now see whether the goal was successfully scheduled. If we didn't manage
     % to schedule the goal, then we restore the original instmap, delay_info
@@ -2595,10 +2777,10 @@
         WokenGoals = []
     ;
         WokenGoals = [_],
-        mode_checkpoint(wakeup, "goal", !ModeInfo, !IO)
+        mode_checkpoint(wakeup, "goal", !ModeInfo)
     ;
         WokenGoals = [_, _ | _],
-        mode_checkpoint(wakeup, "goals", !ModeInfo, !IO)
+        mode_checkpoint(wakeup, "goals", !ModeInfo)
     ),
     mode_info_set_delay_info(DelayInfo, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMap),
@@ -2611,7 +2793,7 @@
     ;
         % The remaining goals may still need to be flattened.
         modecheck_conj_list_2(ConjType, Goals1, Goals2, !ImpurityErrors,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ),
     (
         Errors = [_ | _],
@@ -2641,19 +2823,19 @@
 :- pred modecheck_delayed_solver_goals(conj_type::in, list(hlds_goal)::out,
     list(delayed_goal)::in, list(delayed_goal)::out,
     impurity_errors::in, impurity_errors::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_delayed_solver_goals(ConjType, Goals, !DelayedGoals,
-        !ImpurityErrors, !ModeInfo, !IO) :-
+        !ImpurityErrors, !ModeInfo) :-
     % Try to handle any unscheduled goals by inserting solver
     % initialisation calls, aiming for a deterministic schedule.
     modecheck_delayed_goals_try_det(ConjType, !DelayedGoals,
-        Goals0, !ImpurityErrors, !ModeInfo, !IO),
+        Goals0, !ImpurityErrors, !ModeInfo),

     % Try to handle any unscheduled goals by inserting solver
     % initialisation calls, aiming for *any* workable schedule.
     modecheck_delayed_goals_eager(ConjType, !DelayedGoals,
-        Goals1, !ImpurityErrors, !ModeInfo, !IO),
+        Goals1, !ImpurityErrors, !ModeInfo),
     Goals = Goals0 ++ Goals1.

     % We may still have some unscheduled goals.  This may be because some
@@ -2687,10 +2869,10 @@
 :- pred modecheck_delayed_goals_try_det(conj_type::in, list(delayed_goal)::in,
     list(delayed_goal)::out, list(hlds_goal)::out,
     impurity_errors::in, impurity_errors::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_delayed_goals_try_det(ConjType, DelayedGoals0, DelayedGoals, Goals,
-        !ImpurityErrors, !ModeInfo, !IO) :-
+        !ImpurityErrors, !ModeInfo) :-
     (
         % There are no unscheduled goals, so we don't need to do anything.

@@ -2748,7 +2930,7 @@
             mode_info_add_goals_live_vars(ConjType, InitGoals, !ModeInfo),

             modecheck_conj_list_2(ConjType, Goals1, Goals, !ImpurityErrors,
-                !ModeInfo, !IO),
+                !ModeInfo),

             mode_info_get_delay_info(!.ModeInfo, DelayInfo2),
             delay_info_leave_conj(DelayInfo2, DelayedGoals, DelayInfo3),
@@ -3001,10 +3183,10 @@
 :- pred modecheck_delayed_goals_eager(conj_type::in, list(delayed_goal)::in,
     list(delayed_goal)::out, list(hlds_goal)::out,
     impurity_errors::in, impurity_errors::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 modecheck_delayed_goals_eager(ConjType, DelayedGoals0, DelayedGoals, Goals,
-        !ImpurityErrors, !ModeInfo, !IO) :-
+        !ImpurityErrors, !ModeInfo) :-
     (
         % There are no unscheduled goals, so we don't need to do anything.
         DelayedGoals0 = [],
@@ -3026,7 +3208,7 @@
             "modecheck_delayed_goals_eager: may init solver vars"),
         mode_info_set_may_init_solver_vars(may_init_solver_vars, !ModeInfo),
         modecheck_conj_list_2(ConjType, Goals0, Goals1, !ImpurityErrors,
-            !ModeInfo, !IO),
+            !ModeInfo),
         mode_info_set_may_init_solver_vars(may_not_init_solver_vars,
             !ModeInfo),

@@ -3040,7 +3222,7 @@
             % flounder or succeed.
             modecheck_delayed_goals_eager(ConjType,
                 DelayedGoals1, DelayedGoals, Goals2,
-                !ImpurityErrors, !ModeInfo, !IO),
+                !ImpurityErrors, !ModeInfo),
             Goals = Goals1 ++ Goals2
         ;
             DelayedGoals = DelayedGoals1,
@@ -3064,9 +3246,9 @@
     %
 :- pred check_for_impurity_error(hlds_goal::in, list(hlds_goal)::out,
     impurity_errors::in, impurity_errors::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-check_for_impurity_error(Goal, Goals, !ImpurityErrors, !ModeInfo, !IO) :-
+check_for_impurity_error(Goal, Goals, !ImpurityErrors, !ModeInfo) :-
     mode_info_get_delay_info(!.ModeInfo, DelayInfo0),
     delay_info_leave_conj(DelayInfo0, DelayedGoals0, DelayInfo1),
     mode_info_set_delay_info(DelayInfo1, !ModeInfo),
@@ -3079,7 +3261,7 @@
         HeadVarUnificationGoals, NonHeadVarUnificationGoals0),
     modecheck_delayed_solver_goals(plain_conj, Goals,
         NonHeadVarUnificationGoals0, NonHeadVarUnificationGoals,
-        !ImpurityErrors, !ModeInfo, !IO),
+        !ImpurityErrors, !ModeInfo),
     mode_info_get_delay_info(!.ModeInfo, DelayInfo2),
     delay_info_enter_conj(DelayInfo2, DelayInfo3),
     redelay_goals(HeadVarUnificationGoals, DelayInfo3, DelayInfo),
@@ -3148,26 +3330,26 @@

 :- pred modecheck_disj_list(list(hlds_goal)::in, list(hlds_goal)::out,
     list(instmap)::out, set(prog_var)::in, set(prog_var)::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-modecheck_disj_list([], [], [], !LargeFlatConstructs, !ModeInfo, !IO).
+modecheck_disj_list([], [], [], !LargeFlatConstructs, !ModeInfo).
 modecheck_disj_list([Goal0 | Goals0], [Goal | Goals], [InstMap | InstMaps],
-        !LargeFlatConstructs, !ModeInfo, !IO) :-
+        !LargeFlatConstructs, !ModeInfo) :-
     mode_info_get_instmap(!.ModeInfo, InstMap0),
-    modecheck_goal(Goal0, Goal, !ModeInfo, !IO),
+    modecheck_goal(Goal0, Goal, !ModeInfo),
     accumulate_large_flat_constructs(Goal, !LargeFlatConstructs),
     mode_info_get_instmap(!.ModeInfo, InstMap),
     mode_info_set_instmap(InstMap0, !ModeInfo),
     modecheck_disj_list(Goals0, Goals, InstMaps, !LargeFlatConstructs,
-        !ModeInfo, !IO).
+        !ModeInfo).

 :- pred modecheck_case_list(list(case)::in, prog_var::in, list(case)::out,
     list(instmap)::out, set(prog_var)::in, set(prog_var)::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-modecheck_case_list([], _Var, [], [], !LargeFlatConstructs, !ModeInfo, !IO).
+modecheck_case_list([], _Var, [], [], !LargeFlatConstructs, !ModeInfo).
 modecheck_case_list([Case0 | Cases0], Var, [Case | Cases],
-        [InstMap | InstMaps], !LargeFlatConstructs, !ModeInfo, !IO) :-
+        [InstMap | InstMaps], !LargeFlatConstructs, !ModeInfo) :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
     mode_info_get_instmap(!.ModeInfo, InstMap0),

@@ -3178,7 +3360,7 @@
     % Modecheck this case (if it is reachable).
     mode_info_get_instmap(!.ModeInfo, InstMap1),
     ( instmap_is_reachable(InstMap1) ->
-        modecheck_goal(Goal0, Goal1, !ModeInfo, !IO),
+        modecheck_goal(Goal0, Goal1, !ModeInfo),
         mode_info_get_instmap(!.ModeInfo, InstMap)
     ;
         % We should not mode-analyse the goal, since it is unreachable.
@@ -3195,7 +3377,7 @@
     accumulate_large_flat_constructs(Goal, !LargeFlatConstructs),
     mode_info_set_instmap(InstMap0, !ModeInfo),
     modecheck_case_list(Cases0, Var, Cases, InstMaps, !LargeFlatConstructs,
-        !ModeInfo, !IO).
+        !ModeInfo).

 :- pred accumulate_large_flat_constructs(hlds_goal::in,
     set(prog_var)::in, set(prog_var)::out) is det.
@@ -3932,13 +4114,17 @@

 %-----------------------------------------------------------------------------%

-mode_context_to_unify_context(_, mode_context_unify(UnifyContext, _),
-        UnifyContext).
-mode_context_to_unify_context(_, mode_context_call(CallId, Arg),
-        unify_context(umc_call(CallId, Arg), [])).
-mode_context_to_unify_context(_, mode_context_uninitialized, _) :-
+mode_context_to_unify_context(_ModeInfo, ModeContext, UnifyContext) :-
+    (
+        ModeContext = mode_context_unify(UnifyContext, _)
+    ;
+        ModeContext = mode_context_call(CallId, Arg),
+        UnifyContext = unify_context(umc_call(CallId, Arg), [])
+    ;
+        ModeContext = mode_context_uninitialized,
     unexpected(this_file,
-        "mode_context_to_unify_context: uninitialized context").
+            "mode_context_to_unify_context: uninitialized context")
+    ).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -3947,45 +4133,46 @@
     % We also check the mode of main/2 here.
     %
 :- pred check_eval_methods(module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    list(error_spec)::in, list(error_spec)::out) is det.

-check_eval_methods(!ModuleInfo, !IO) :-
+check_eval_methods(!ModuleInfo, !Specs) :-
     module_info_predids(PredIds, !ModuleInfo),
-    pred_check_eval_methods(PredIds, !ModuleInfo, !IO).
+    pred_check_eval_methods(!.ModuleInfo, PredIds, !Specs).

-:- pred pred_check_eval_methods(list(pred_id)::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- pred pred_check_eval_methods(module_info::in, list(pred_id)::in,
+    list(error_spec)::in, list(error_spec)::out) is det.

-pred_check_eval_methods([], !ModuleInfo, !IO).
-pred_check_eval_methods([PredId | Rest], !ModuleInfo, !IO) :-
-    module_info_preds(!.ModuleInfo, Preds),
+pred_check_eval_methods(_, [], !Specs).
+pred_check_eval_methods(ModuleInfo, [PredId | PredIds], !Specs) :-
+    module_info_preds(ModuleInfo, Preds),
     map.lookup(Preds, PredId, PredInfo),
     ProcIds = pred_info_procids(PredInfo),
-    proc_check_eval_methods(ProcIds, PredId, !ModuleInfo, !IO),
-    pred_check_eval_methods(Rest, !ModuleInfo, !IO).
+    proc_check_eval_methods(ModuleInfo, PredId, ProcIds, !Specs),
+    pred_check_eval_methods(ModuleInfo, PredIds, !Specs).

-:- pred proc_check_eval_methods(list(proc_id)::in, pred_id::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- pred proc_check_eval_methods(module_info::in, pred_id::in,
+    list(proc_id)::in, list(error_spec)::in, list(error_spec)::out) is det.

-proc_check_eval_methods([], _, !ModuleInfo, !IO).
-proc_check_eval_methods([ProcId | Rest], PredId, !ModuleInfo, !IO) :-
-    module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId,
-        PredInfo, ProcInfo),
+proc_check_eval_methods(_, _, [], !Specs).
+proc_check_eval_methods(ModuleInfo, PredId, [ProcId | ProcIds], !Specs) :-
+    module_info_pred_proc_info(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo),
     proc_info_get_eval_method(ProcInfo, EvalMethod),
     proc_info_get_argmodes(ProcInfo, Modes),
     (
         eval_method_requires_ground_args(EvalMethod) = yes,
-        \+ only_fully_in_out_modes(Modes, !.ModuleInfo)
+        \+ only_fully_in_out_modes(Modes, ModuleInfo)
     ->
-        report_eval_method_requires_ground_args(ProcInfo, !ModuleInfo, !IO)
+        GroundArgsSpec = report_eval_method_requires_ground_args(ProcInfo),
+        !:Specs = [GroundArgsSpec | !.Specs]
     ;
         true
     ),
     (
         eval_method_destroys_uniqueness(EvalMethod) = yes,
-        \+ only_nonunique_modes(Modes, !.ModuleInfo)
+        \+ only_nonunique_modes(Modes, ModuleInfo)
     ->
-        report_eval_method_destroys_uniqueness(ProcInfo, !ModuleInfo, !IO)
+        UniquenessSpec = report_eval_method_destroys_uniqueness(ProcInfo),
+        !:Specs = [UniquenessSpec | !.Specs]
     ;
         true
     ),
@@ -3993,13 +4180,14 @@
         pred_info_name(PredInfo) = "main",
         pred_info_orig_arity(PredInfo) = 2,
         pred_info_is_exported(PredInfo),
-        \+ check_mode_of_main(Modes, !.ModuleInfo)
+        \+ check_mode_of_main(Modes, ModuleInfo)
     ->
-        report_wrong_mode_for_main(ProcInfo, !ModuleInfo, !IO)
+        MainSpec = report_wrong_mode_for_main(ProcInfo),
+        !:Specs = [MainSpec | !.Specs]
     ;
         true
     ),
-    proc_check_eval_methods(Rest, PredId, !ModuleInfo, !IO).
+    proc_check_eval_methods(ModuleInfo, PredId, ProcIds, !Specs).

 :- pred only_fully_in_out_modes(list(mer_mode)::in, module_info::in)
     is semidet.
@@ -4047,10 +4235,9 @@
     ( Free = free ; Free = free(_Type) ),
     inst_expand(ModuleInfo, UoFinalInst, ground(unique, none)).

-:- pred report_eval_method_requires_ground_args(proc_info::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- func report_eval_method_requires_ground_args(proc_info) = error_spec.

-report_eval_method_requires_ground_args(ProcInfo, !ModuleInfo, !IO) :-
+report_eval_method_requires_ground_args(ProcInfo) = Spec :-
     proc_info_get_eval_method(ProcInfo, EvalMethod),
     proc_info_get_context(ProcInfo, Context),
     EvalMethodS = eval_method_to_string(EvalMethod),
@@ -4064,15 +4251,11 @@
     Msg = simple_msg(Context,
         [always(MainPieces), verbose_only(VerbosePieces)]),
     Spec = error_spec(severity_error, phase_mode_check(report_in_any_mode),
-        [Msg]),
-    module_info_get_globals(!.ModuleInfo, Globals),
-    write_error_spec(Spec, Globals, 0, _NumWarnings, 0, NumErrors, !IO),
-    module_info_incr_num_errors(NumErrors, !ModuleInfo).
+        [Msg]).

-:- pred report_eval_method_destroys_uniqueness(proc_info::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- func report_eval_method_destroys_uniqueness(proc_info) = error_spec.

-report_eval_method_destroys_uniqueness(ProcInfo, !ModuleInfo, !IO) :-
+report_eval_method_destroys_uniqueness(ProcInfo) = Spec :-
     proc_info_get_eval_method(ProcInfo, EvalMethod),
     proc_info_get_context(ProcInfo, Context),
     EvalMethodS = eval_method_to_string(EvalMethod),
@@ -4088,23 +4271,16 @@
     Msg = simple_msg(Context,
         [always(MainPieces), verbose_only(VerbosePieces)]),
     Spec = error_spec(severity_error, phase_mode_check(report_in_any_mode),
-        [Msg]),
-    module_info_get_globals(!.ModuleInfo, Globals),
-    write_error_spec(Spec, Globals, 0, _NumWarnings, 0, NumErrors, !IO),
-    module_info_incr_num_errors(NumErrors, !ModuleInfo).
+        [Msg]).

-:- pred report_wrong_mode_for_main(proc_info::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- func report_wrong_mode_for_main(proc_info) = error_spec.

-report_wrong_mode_for_main(ProcInfo, !ModuleInfo, !IO) :-
+report_wrong_mode_for_main(ProcInfo) = Spec :-
     proc_info_get_context(ProcInfo, Context),
     Pieces = [words("Error: main/2 must have mode `(di, uo)'."), nl],
     Msg = simple_msg(Context, [always(Pieces)]),
     Spec = error_spec(severity_error, phase_mode_check(report_in_any_mode),
-        [Msg]),
-    module_info_get_globals(!.ModuleInfo, Globals),
-    write_error_spec(Spec, Globals, 0, _NumWarnings, 0, NumErrors, !IO),
-    module_info_incr_num_errors(NumErrors, !ModuleInfo).
+        [Msg]).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -4127,17 +4303,6 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%

-    % XXX - At the moment we don't check for circular modes or insts.
-    % (If they aren't used, the compiler will probably not detect the error;
-    % if they are, it will probably go into an infinite loop).
-    %
-:- pred check_circular_modes(module_info::in, module_info::out,
-    io::di, io::uo) is det.
-
-check_circular_modes(!Module, !IO).
-
-%-----------------------------------------------------------------------------%
-
 :- func this_file = string.

 this_file = "modes.m".
Index: compiler/pd_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/pd_util.m,v
retrieving revision 1.71
diff -u -b -r1.71 pd_util.m
--- compiler/pd_util.m	23 Dec 2008 01:37:38 -0000	1.71
+++ compiler/pd_util.m	20 Jul 2009 09:46:59 -0000
@@ -293,7 +293,7 @@
     mode_info_init(ModuleInfo1, PredId, ProcId, Context, LiveVars, InstMap0,
         check_unique_modes, MayChangeCalledProc, ModeInfo0),

-    unique_modes_check_goal(Goal0, Goal, ModeInfo0, ModeInfo, !IO),
+    unique_modes_check_goal(Goal0, Goal, ModeInfo0, ModeInfo),
     globals.io_lookup_bool_option(debug_pd, Debug, !IO),
     (
         Debug = yes,
Index: compiler/try_expand.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/try_expand.m,v
retrieving revision 1.4
diff -u -b -r1.4 try_expand.m
--- compiler/try_expand.m	11 Jun 2009 07:00:20 -0000	1.4
+++ compiler/try_expand.m	20 Jul 2009 09:46:16 -0000
@@ -313,7 +313,7 @@
     module_info_set_pred_proc_info(PredId, ProcId, PredInfo, !.ProcInfo,
         !ModuleInfo),

-    modecheck_proc(ProcId, PredId, !ModuleInfo, ErrorSpecs, _Changed, !IO),
+    modecheck_proc(ProcId, PredId, !ModuleInfo, ErrorSpecs, _Changed),
     module_info_get_globals(!.ModuleInfo, Globals),
     write_error_specs(ErrorSpecs, Globals, 0, _NumWarnings, 0, NumErrors, !IO),
     module_info_incr_num_errors(NumErrors, !ModuleInfo),
Index: compiler/unify_proc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_proc.m,v
retrieving revision 1.204
diff -u -b -r1.204 unify_proc.m
--- compiler/unify_proc.m	11 Jun 2009 07:00:22 -0000	1.204
+++ compiler/unify_proc.m	20 Jul 2009 13:30:00 -0000
@@ -47,27 +47,29 @@
 :- module check_hlds.unify_proc.
 :- interface.

-:- import_module check_hlds.mode_info.
 :- import_module hlds.
 :- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
-:- import_module hlds.pred_table.
 :- import_module mdbcomp.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.
 :- import_module parse_tree.prog_data.

-:- import_module bool.
-:- import_module io.
 :- import_module list.
 :- import_module maybe.
+:- import_module queue.

 %-----------------------------------------------------------------------------%

 :- type proc_requests.
+:- type req_queue == queue(pred_proc_id).
+
+:- pred get_req_queue(proc_requests::in, req_queue::out) is det.
+:- pred set_req_queue(req_queue::in,
+    proc_requests::in, proc_requests::out) is det.

 :- type unify_proc_id
     --->    unify_proc_id(type_ctor, uni_mode).
@@ -109,17 +111,6 @@
 :- pred add_lazily_generated_compare_pred_decl(type_ctor::in, pred_id::out,
     module_info::in, module_info::out) is det.

-    % Do mode analysis of the queued procedures. If the first argument is
-    % `unique_mode_check', then also go on and do full determinism analysis
-    % and unique mode analysis on them as well. The pred_table arguments
-    % are used to store copies of the procedure bodies before unique mode
-    % analysis, so that we can restore them before doing the next analysis
-    % pass.
-    %
-:- pred modecheck_queued_procs(how_to_check_goal::in,
-    pred_table::in, pred_table::out, module_info::in, module_info::out,
-    bool::out, io::di, io::uo) is det.
-
     % Given the type and mode of a unification, look up the mode number
     % for the unification proc.
     %
@@ -139,14 +130,11 @@
 :- implementation.

 :- import_module check_hlds.clause_to_proc.
-:- import_module check_hlds.cse_detection.
-:- import_module check_hlds.det_analysis.
 :- import_module check_hlds.inst_match.
 :- import_module check_hlds.mode_util.
 :- import_module check_hlds.modes.
 :- import_module check_hlds.polymorphism.
 :- import_module check_hlds.post_typecheck.
-:- import_module check_hlds.switch_detection.
 :- import_module check_hlds.type_util.
 :- import_module check_hlds.unique_modes.
 :- import_module hlds.goal_util.
@@ -155,6 +143,7 @@
 :- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module hlds.make_hlds.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module hlds.special_pred.
 :- import_module libs.
@@ -168,10 +157,10 @@
 :- import_module parse_tree.prog_type.
 :- import_module recompilation.

+:- import_module bool.
 :- import_module int.
 :- import_module map.
 :- import_module pair.
-:- import_module queue.
 :- import_module set.
 :- import_module string.
 :- import_module svmap.
@@ -188,8 +177,6 @@
     %
 :- type unify_req_map == map(unify_proc_id, proc_id).

-:- type req_queue == queue(pred_proc_id).
-
 :- type proc_requests
     --->    proc_requests(
                 unify_req_map   :: unify_req_map,
@@ -212,11 +199,8 @@
     % Boring access predicates

 :- pred get_unify_req_map(proc_requests::in, unify_req_map::out) is det.
-:- pred get_req_queue(proc_requests::in, req_queue::out) is det.
 :- pred set_unify_req_map(unify_req_map::in,
     proc_requests::in, proc_requests::out) is det.
-:- pred set_req_queue(req_queue::in,
-    proc_requests::in, proc_requests::out) is det.

 get_unify_req_map(PR, PR ^ unify_req_map).
 get_req_queue(PR, PR ^ req_queue).
@@ -394,132 +378,6 @@
     ).

 %-----------------------------------------------------------------------------%
-
-    % XXX these belong in modes.m
-
-modecheck_queued_procs(HowToCheckGoal, !OldPredTable, !ModuleInfo, Changed,
-        !IO) :-
-    module_info_get_proc_requests(!.ModuleInfo, Requests0),
-    get_req_queue(Requests0, RequestQueue0),
-    ( queue.get(RequestQueue0, PredProcId, RequestQueue1) ->
-        set_req_queue(RequestQueue1, Requests0, Requests1),
-        module_info_set_proc_requests(Requests1, !ModuleInfo),
-
-        % Check that the procedure is valid (i.e. type-correct), before
-        % we attempt to do mode analysis on it. This check is necessary
-        % to avoid internal errors caused by doing mode analysis on
-        % type-incorrect code.
-        % XXX inefficient! This is O(N*M).
-
-        PredProcId = proc(PredId, _ProcId),
-        module_info_predids(ValidPredIds, !ModuleInfo),
-        ( list.member(PredId, ValidPredIds) ->
-            queued_proc_progress_message(PredProcId, HowToCheckGoal,
-                !.ModuleInfo, !IO),
-            modecheck_queued_proc(HowToCheckGoal, PredProcId,
-                !OldPredTable, !ModuleInfo, Changed1, !IO)
-        ;
-            Changed1 = no
-        ),
-        modecheck_queued_procs(HowToCheckGoal, !OldPredTable, !ModuleInfo,
-            Changed2, !IO),
-        bool.or(Changed1, Changed2, Changed)
-    ;
-        Changed = no
-    ).
-
-:- pred queued_proc_progress_message(pred_proc_id::in, how_to_check_goal::in,
-    module_info::in, io::di, io::uo) is det.
-
-queued_proc_progress_message(PredProcId, HowToCheckGoal, ModuleInfo, !IO) :-
-    globals.io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
-    (
-        VeryVerbose = yes,
-        (
-            HowToCheckGoal = check_modes,
-            io.write_string("% Mode-analyzing ", !IO)
-        ;
-            HowToCheckGoal = check_unique_modes,
-            io.write_string("% Analyzing modes, determinism, " ++
-                "and unique-modes for\n% ", !IO)
-        ),
-        hlds_out.write_pred_proc_id(ModuleInfo, PredProcId, !IO),
-        io.write_string("\n", !IO)
-%       /*****
-%       mode_list_get_initial_insts(Modes, ModuleInfo1,
-%           InitialInsts),
-%       io.write_string("% Initial insts: `", !IO),
-%       varset.init(InstVarSet),
-%       mercury_output_inst_list(InitialInsts, InstVarSet, !IO),
-%       io.write_string("'\n", !IO)
-%       *****/
-    ;
-        VeryVerbose = no
-    ).
-
-:- pred modecheck_queued_proc(how_to_check_goal::in, pred_proc_id::in,
-    pred_table::in, pred_table::out, module_info::in, module_info::out,
-    bool::out, io::di, io::uo) is det.
-
-modecheck_queued_proc(HowToCheckGoal, PredProcId, !OldPredTable, !ModuleInfo,
-        !:Changed, !IO) :-
-    % Mark the procedure as ready to be processed.
-    PredProcId = proc(PredId, ProcId),
-    module_info_preds(!.ModuleInfo, Preds0),
-    map.lookup(Preds0, PredId, PredInfo0),
-    pred_info_get_procedures(PredInfo0, Procs0),
-    map.lookup(Procs0, ProcId, ProcInfo0),
-    proc_info_set_can_process(yes, ProcInfo0, ProcInfo1),
-    map.det_update(Procs0, ProcId, ProcInfo1, Procs1),
-    pred_info_set_procedures(Procs1, PredInfo0, PredInfo1),
-    map.det_update(Preds0, PredId, PredInfo1, Preds1),
-    module_info_set_preds(Preds1, !ModuleInfo),
-
-    % Modecheck the procedure.
-    modecheck_proc(ProcId, PredId, !ModuleInfo, ErrorSpecs, !:Changed, !IO),
-
-    module_info_get_globals(!.ModuleInfo, Globals),
-    write_error_specs(ErrorSpecs, Globals, 0, _NumWarnings, 0, NumErrors, !IO),
-    module_info_incr_num_errors(NumErrors, !ModuleInfo),
-    ( NumErrors > 0 ->
-        module_info_remove_predid(PredId, !ModuleInfo)
-    ;
-        (
-            HowToCheckGoal = check_unique_modes,
-            detect_switches_in_proc(ProcId, PredId, !ModuleInfo),
-            detect_cse_in_proc(ProcId, PredId, !ModuleInfo, !IO),
-            determinism_check_proc(ProcId, PredId, !ModuleInfo, Specs),
-            (
-                Specs = []
-            ;
-                Specs = [_ | _],
-                unexpected(this_file, "modecheck_queued_proc: found error")
-            ),
-            save_proc_info(ProcId, PredId, !.ModuleInfo, !OldPredTable),
-            unique_modes_check_proc(ProcId, PredId, !ModuleInfo, NewChanged,
-                !IO),
-            bool.or(NewChanged, !Changed)
-        ;
-            HowToCheckGoal = check_modes
-        )
-    ).
-
-    % Save a copy of the proc info for the specified procedure in
-    % !OldProcTable.
-    %
-:- pred save_proc_info(proc_id::in, pred_id::in, module_info::in,
-    pred_table::in, pred_table::out) is det.
-
-save_proc_info(ProcId, PredId, ModuleInfo, !OldPredTable) :-
-    module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
-        _PredInfo, ProcInfo),
-    map.lookup(!.OldPredTable, PredId, OldPredInfo0),
-    pred_info_get_procedures(OldPredInfo0, OldProcTable0),
-    map.set(OldProcTable0, ProcId, ProcInfo, OldProcTable),
-    pred_info_set_procedures(OldProcTable, OldPredInfo0, OldPredInfo),
-    map.det_update(!.OldPredTable, PredId, OldPredInfo, !:OldPredTable).
-
-%-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%

 add_lazily_generated_unify_pred(TypeCtor, PredId, !ModuleInfo) :-
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unique_modes.m,v
retrieving revision 1.131
diff -u -b -r1.131 unique_modes.m
--- compiler/unique_modes.m	11 Jun 2009 07:00:22 -0000	1.131
+++ compiler/unique_modes.m	20 Jul 2009 12:04:12 -0000
@@ -40,10 +40,11 @@
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
 :- import_module parse_tree.
+:- import_module parse_tree.error_util.
 :- import_module parse_tree.prog_data.

 :- import_module bool.
-:- import_module io.
+:- import_module list.
 :- import_module set.

 %-----------------------------------------------------------------------------%
@@ -51,17 +52,18 @@
     % Check every predicate in a module.
     %
 :- pred unique_modes_check_module(module_info::in, module_info::out,
-    io::di, io::uo) is det.
+    list(error_spec)::out) is det.

     % Just check a single procedure.
     %
 :- pred unique_modes_check_proc(proc_id::in, pred_id::in,
-    module_info::in, module_info::out, bool::out, io::di, io::uo) is det.
+    module_info::in, module_info::out, bool::out, list(error_spec)::out)
+    is det.

     % Just check a single goal.
     %
 :- pred unique_modes_check_goal(hlds_goal::in, hlds_goal::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

     % Prepare for checking a disjunct in a disjunction.
     %
@@ -92,12 +94,11 @@
 :- import_module libs.compiler_util.
 :- import_module mdbcomp.
 :- import_module mdbcomp.prim_data.
-:- import_module parse_tree.error_util.
 :- import_module parse_tree.prog_mode.

 :- import_module bag.
 :- import_module int.
-:- import_module list.
+:- import_module io.
 :- import_module map.
 :- import_module maybe.
 :- import_module pair.
@@ -106,18 +107,15 @@

 %-----------------------------------------------------------------------------%

-unique_modes_check_module(!ModuleInfo, !IO) :-
+unique_modes_check_module(!ModuleInfo, Specs) :-
     check_pred_modes(check_unique_modes, may_change_called_proc,
-        !ModuleInfo, _UnsafeToContinue, !IO).
+        !ModuleInfo, _SafeToContinue, Specs).

-unique_modes_check_proc(ProcId, PredId, !ModuleInfo, Changed, !IO) :-
+unique_modes_check_proc(ProcId, PredId, !ModuleInfo, Changed, Specs) :-
     modecheck_proc_general(ProcId, PredId, check_unique_modes,
-        may_change_called_proc, !ModuleInfo, ErrorSpecs, Changed, !IO),
-    module_info_get_globals(!.ModuleInfo, Globals),
-    write_error_specs(ErrorSpecs, Globals, 0, _NumWarnings, 0, NumErrors, !IO),
-    module_info_incr_num_errors(NumErrors, !ModuleInfo).
+        may_change_called_proc, !ModuleInfo, Specs, Changed).

-unique_modes_check_goal(Goal0, Goal, !ModeInfo, !IO) :-
+unique_modes_check_goal(Goal0, Goal, !ModeInfo) :-
     Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
     Context = goal_info_get_context(GoalInfo0),
     term.context_init(EmptyContext),
@@ -129,18 +127,18 @@
     ( goal_info_has_feature(GoalInfo0, feature_duplicated_for_switch) ->
         mode_info_get_in_dupl_for_switch(!.ModeInfo, InDuplForSwitch),
         mode_info_set_in_dupl_for_switch(in_dupl_for_switch, !ModeInfo),
-        unique_modes_check_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo, !IO),
+        unique_modes_check_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo),
         mode_info_set_in_dupl_for_switch(InDuplForSwitch, !ModeInfo)
     ;
-        unique_modes_check_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo, !IO)
+        unique_modes_check_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo)
     ).

 :- pred unique_modes_check_goal_2(hlds_goal_expr::in, hlds_goal_info::in,
-    hlds_goal::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal::out, mode_info::in, mode_info::out) is det.

-:- pragma inline(unique_modes_check_goal_2/7).
+:- pragma inline(unique_modes_check_goal_2/5).

-unique_modes_check_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo, !IO) :-
+unique_modes_check_goal_2(GoalExpr0, GoalInfo0, Goal, !ModeInfo) :-
     mode_info_get_instmap(!.ModeInfo, InstMap0),
     % Grab the original bag of nondet-live vars.
     mode_info_get_nondet_live_vars(!.ModeInfo, NondetLiveVars0),
@@ -155,7 +153,7 @@
     ),

     unique_modes_check_goal_expr(GoalExpr0, GoalInfo0, GoalExpr,
-        !ModeInfo, !IO),
+        !ModeInfo),
     % Restore the original bag of nondet-live vars.
     mode_info_set_nondet_live_vars(NondetLiveVars0, !ModeInfo),

@@ -261,55 +259,55 @@
 %-----------------------------------------------------------------------------%

 :- pred unique_modes_check_goal_expr(hlds_goal_expr::in, hlds_goal_info::in,
-    hlds_goal_expr::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

-unique_modes_check_goal_expr(GoalExpr0, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
+unique_modes_check_goal_expr(GoalExpr0, GoalInfo0, GoalExpr, !ModeInfo) :-
     % XXX The predicates we call here should have their definitions
     % in the same order as this switch.
     (
         GoalExpr0 = unify(LHS0, RHS0, _UniModes0, Unification0, UnifyContext0),
         unique_modes_check_goal_unify(LHS0, RHS0, Unification0, UnifyContext0,
-            GoalInfo0, GoalExpr, !ModeInfo, !IO)
+            GoalInfo0, GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = plain_call(PredId0, ProcId0, ArgVars0, Builtin0,
             MaybeUnifyContext0, SymName0),
         unique_modes_check_goal_plain_call(PredId0, ProcId0, ArgVars0,
             Builtin0, MaybeUnifyContext0, SymName0, GoalInfo0, GoalExpr,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ;
         GoalExpr0 = generic_call(GenericCall0, ArgVars0, ArgModes0, Detism0),
         unique_modes_check_goal_generic_call(GenericCall0, ArgVars0, ArgModes0,
-            Detism0, GoalExpr, !ModeInfo, !IO)
+            Detism0, GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = call_foreign_proc(Attributes0, PredId0, ProcId0,
             Args0, ExtraArgs0, MaybeTraceRuntimeCond0, PragmaCode0),
         unique_modes_check_goal_call_foreign_proc(Attributes0,
             PredId0, ProcId0, Args0, ExtraArgs0, MaybeTraceRuntimeCond0,
-            PragmaCode0, GoalInfo0, GoalExpr, !ModeInfo, !IO)
+            PragmaCode0, GoalInfo0, GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = conj(GoalType0, Goals0),
         unique_modes_check_goal_conj(GoalType0, Goals0, GoalExpr,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ;
         GoalExpr0 = disj(Goals0),
         unique_modes_check_goal_disj(Goals0, GoalInfo0, GoalExpr,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ;
         GoalExpr0 = switch(Var0, CanFail0, Cases0),
         unique_modes_check_goal_switch(Var0, CanFail0, Cases0, GoalInfo0,
-            GoalExpr, !ModeInfo, !IO)
+            GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = if_then_else(Vars0, Cond0, Then0, Else0),
         unique_modes_check_goal_if_then_else(Vars0, Cond0, Then0, Else0,
-            GoalInfo0, GoalExpr, !ModeInfo, !IO)
+            GoalInfo0, GoalExpr, !ModeInfo)
     ;
         GoalExpr0 = negation(SubGoal0),
         unique_modes_check_goal_negation(SubGoal0, GoalInfo0, GoalExpr,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ;
         GoalExpr0 = scope(Reason0, SubGoal0),
         unique_modes_check_goal_scope(Reason0, SubGoal0, GoalExpr,
-            !ModeInfo, !IO)
+            !ModeInfo)
     ;
         GoalExpr0 = shorthand(ShortHand0),
         (
@@ -317,14 +315,14 @@
                 MainGoal0, OrElseGoals0, OrElseInners0),
             unique_modes_check_goal_atomic_goal(GoalType, Outer, Inner,
                 MaybeOutputVars, MainGoal0, OrElseGoals0, OrElseInners0,
-                GoalInfo0, GoalExpr, !ModeInfo, !IO)
+                GoalInfo0, GoalExpr, !ModeInfo)
         ;
             ShortHand0 = try_goal(MaybeIO, ResultVar, SubGoal0),
-            mode_checkpoint(enter, "try", !ModeInfo, !IO),
-            unique_modes_check_goal(SubGoal0, SubGoal, !ModeInfo, !IO),
+            mode_checkpoint(enter, "try", !ModeInfo),
+            unique_modes_check_goal(SubGoal0, SubGoal, !ModeInfo),
             ShortHand = try_goal(MaybeIO, ResultVar, SubGoal),
             GoalExpr = shorthand(ShortHand),
-            mode_checkpoint(exit, "try", !ModeInfo, !IO)
+            mode_checkpoint(exit, "try", !ModeInfo)
         ;
             ShortHand0 = bi_implication(_, _),
             % These should have been expanded out by now.
@@ -334,10 +332,10 @@
     ).

 :- pred unique_modes_check_goal_conj(conj_type::in, list(hlds_goal)::in,
-    hlds_goal_expr::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

-unique_modes_check_goal_conj(ConjType, Goals0, GoalExpr, !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "*conj", !ModeInfo, !IO),
+unique_modes_check_goal_conj(ConjType, Goals0, GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "*conj", !ModeInfo),
     (
         Goals0 = [],
         % For efficiency, optimize common case.
@@ -345,17 +343,17 @@
     ;
         Goals0 = [_ | _],
         mode_info_add_goals_live_vars(ConjType, Goals0, !ModeInfo),
-        unique_modes_check_conj(ConjType, Goals0, Goals, !ModeInfo, !IO)
+        unique_modes_check_conj(ConjType, Goals0, Goals, !ModeInfo)
     ),
     GoalExpr = conj(ConjType, Goals),
-    mode_checkpoint(exit, "*conj", !ModeInfo, !IO).
+    mode_checkpoint(exit, "*conj", !ModeInfo).

 :- pred unique_modes_check_goal_disj(list(hlds_goal)::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-unique_modes_check_goal_disj(Goals0, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "disj", !ModeInfo, !IO),
+unique_modes_check_goal_disj(Goals0, GoalInfo0, GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "disj", !ModeInfo),
     (
         Goals0 = [],
         Goals = [],
@@ -387,20 +385,20 @@
         % Now just modecheck each disjunct in turn, and then
         % merge the resulting instmaps.
         unique_modes_check_disj(Goals0, Determinism, NonLocals, Goals,
-            InstMaps, !ModeInfo, !IO),
+            InstMaps, !ModeInfo),
         instmap_merge(NonLocals, InstMaps, merge_disj, !ModeInfo)
     ),
     GoalExpr = disj(Goals),
-    mode_checkpoint(exit, "disj", !ModeInfo, !IO).
+    mode_checkpoint(exit, "disj", !ModeInfo).

 :- pred unique_modes_check_goal_if_then_else(list(prog_var)::in,
     hlds_goal::in, hlds_goal::in, hlds_goal::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 unique_modes_check_goal_if_then_else(Vars, Cond0, Then0, Else0, GoalInfo0,
-        GoalExpr, !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "if-then-else", !ModeInfo, !IO),
+        GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "if-then-else", !ModeInfo),
     NonLocals = goal_info_get_nonlocals(GoalInfo0),
     CondVars = goal_get_nonlocals(Cond0),
     ThenVars = goal_get_nonlocals(Then0),
@@ -443,12 +441,12 @@
     mode_info_remove_live_vars(ElseVars, !ModeInfo),

     mode_info_add_live_vars(ThenVars, !ModeInfo),
-    unique_modes_check_goal(Cond0, Cond, !ModeInfo, !IO),
+    unique_modes_check_goal(Cond0, Cond, !ModeInfo),
     mode_info_remove_live_vars(ThenVars, !ModeInfo),
     mode_info_unlock_vars(var_lock_if_then_else, NonLocals, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMapCond),
     ( instmap_is_reachable(InstMapCond) ->
-        unique_modes_check_goal(Then0, Then, !ModeInfo, !IO),
+        unique_modes_check_goal(Then0, Then, !ModeInfo),
         mode_info_get_instmap(!.ModeInfo, InstMapThen)
     ;
         % We should not mode-analyse the goal, since it is unreachable.
@@ -458,21 +456,20 @@
         InstMapThen = InstMapCond
     ),
     mode_info_set_instmap(InstMap0, !ModeInfo),
-    unique_modes_check_goal(Else0, Else, !ModeInfo, !IO),
+    unique_modes_check_goal(Else0, Else, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMapElse),
     mode_info_set_instmap(InstMap0, !ModeInfo),
     instmap_merge(NonLocals, [InstMapThen, InstMapElse], merge_if_then_else,
         !ModeInfo),
     GoalExpr = if_then_else(Vars, Cond, Then, Else),
-    mode_checkpoint(exit, "if-then-else", !ModeInfo, !IO).
+    mode_checkpoint(exit, "if-then-else", !ModeInfo).

 :- pred unique_modes_check_goal_negation(hlds_goal::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-unique_modes_check_goal_negation(SubGoal0, GoalInfo0, GoalExpr,
-        !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "not", !ModeInfo, !IO),
+unique_modes_check_goal_negation(SubGoal0, GoalInfo0, GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "not", !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMap0),

     % We need to mark all the variables which are live after the negation
@@ -493,18 +490,18 @@
     % We need to lock the non-local variables, to ensure that the negation
     % does not bind them.
     mode_info_lock_vars(var_lock_negation, NonLocals, !ModeInfo),
-    unique_modes_check_goal(SubGoal0, SubGoal, !ModeInfo, !IO),
+    unique_modes_check_goal(SubGoal0, SubGoal, !ModeInfo),
     mode_info_unlock_vars(var_lock_negation, NonLocals, !ModeInfo),
     mode_info_set_live_vars(LiveVars0, !ModeInfo),
     mode_info_set_instmap(InstMap0, !ModeInfo),
     GoalExpr = negation(SubGoal),
-    mode_checkpoint(exit, "not", !ModeInfo, !IO).
+    mode_checkpoint(exit, "not", !ModeInfo).

 :- pred unique_modes_check_goal_scope(scope_reason::in, hlds_goal::in,
-    hlds_goal_expr::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

-unique_modes_check_goal_scope(Reason, SubGoal0, GoalExpr, !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "scope", !ModeInfo, !IO),
+unique_modes_check_goal_scope(Reason, SubGoal0, GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "scope", !ModeInfo),
     ( Reason = from_ground_term(TermVar, from_ground_term_construct) ->
         % The subgoal was left in its final state during (non-unique) mode
         % checking. All we need to do here is to add the relevant information
@@ -521,18 +518,18 @@
                 "unique_modes_check_goal_scope: term var not in InstMapDelta")
         )
     ;
-        unique_modes_check_goal(SubGoal0, SubGoal, !ModeInfo, !IO)
+        unique_modes_check_goal(SubGoal0, SubGoal, !ModeInfo)
     ),
     GoalExpr = scope(Reason, SubGoal),
-    mode_checkpoint(exit, "scope", !ModeInfo, !IO).
+    mode_checkpoint(exit, "scope", !ModeInfo).

 :- pred unique_modes_check_goal_generic_call(generic_call::in,
     list(prog_var)::in, list(mer_mode)::in, determinism::in,
-    hlds_goal_expr::out, mode_info::in, mode_info::out, io::di, io::uo) is det.
+    hlds_goal_expr::out, mode_info::in, mode_info::out) is det.

 unique_modes_check_goal_generic_call(GenericCall, ArgVars, Modes, Detism,
-        GoalExpr, !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "generic_call", !ModeInfo, !IO),
+        GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "generic_call", !ModeInfo),
     hlds_goal.generic_call_id(GenericCall, CallId),
     mode_info_set_call_context(call_context_call(CallId), !ModeInfo),
     ( determinism_components(Detism, _, at_most_zero) ->
@@ -560,18 +557,18 @@
         NeverSucceeds, !ModeInfo),
     GoalExpr = generic_call(GenericCall, ArgVars, Modes, Detism),
     mode_info_unset_call_context(!ModeInfo),
-    mode_checkpoint(exit, "generic_call", !ModeInfo, !IO).
+    mode_checkpoint(exit, "generic_call", !ModeInfo).

 :- pred unique_modes_check_goal_plain_call(pred_id::in, proc_id::in,
     list(prog_var)::in, builtin_state::in, maybe(call_unify_context)::in,
     sym_name::in, hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 unique_modes_check_goal_plain_call(PredId, ProcId0, ArgVars, Builtin,
-        MaybeUnifyContext, PredName, GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
+        MaybeUnifyContext, PredName, GoalInfo0, GoalExpr, !ModeInfo) :-
     PredNameString = sym_name_to_string(PredName),
     string.append("call ", PredNameString, CallString),
-    mode_checkpoint(enter, CallString, !ModeInfo, !IO),
+    mode_checkpoint(enter, CallString, !ModeInfo),
     mode_info_get_call_id(!.ModeInfo, PredId, CallId),
     mode_info_set_call_context(call_context_call(plain_call_id(CallId)),
         !ModeInfo),
@@ -580,29 +577,29 @@
     GoalExpr = plain_call(PredId, ProcId, ArgVars, Builtin, MaybeUnifyContext,
         PredName),
     mode_info_unset_call_context(!ModeInfo),
-    mode_checkpoint(exit, "call", !ModeInfo, !IO).
+    mode_checkpoint(exit, "call", !ModeInfo).

 :- pred unique_modes_check_goal_unify(prog_var::in, unify_rhs::in,
     unification::in, unify_context::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 unique_modes_check_goal_unify(LHS0, RHS0, Unification0, UnifyContext,
-        GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "unify", !ModeInfo, !IO),
+        GoalInfo0, GoalExpr, !ModeInfo) :-
+    mode_checkpoint(enter, "unify", !ModeInfo),
     mode_info_set_call_context(call_context_unify(UnifyContext), !ModeInfo),
     modecheck_unification(LHS0, RHS0, Unification0, UnifyContext, GoalInfo0,
-        GoalExpr, !ModeInfo, !IO),
+        GoalExpr, !ModeInfo),
     mode_info_unset_call_context(!ModeInfo),
-    mode_checkpoint(exit, "unify", !ModeInfo, !IO).
+    mode_checkpoint(exit, "unify", !ModeInfo).

 :- pred unique_modes_check_goal_switch(prog_var::in, can_fail::in,
     list(case)::in, hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 unique_modes_check_goal_switch(Var, CanFail, Cases0, GoalInfo0, GoalExpr,
-        !ModeInfo, !IO) :-
-    mode_checkpoint(enter, "switch", !ModeInfo, !IO),
+        !ModeInfo) :-
+    mode_checkpoint(enter, "switch", !ModeInfo),
     (
         Cases0 = [],
         Cases = [],
@@ -611,26 +608,25 @@
     ;
         Cases0 = [_ | _],
         NonLocals = goal_info_get_nonlocals(GoalInfo0),
-        unique_modes_check_case_list(Cases0, Var, Cases, InstMaps,
-            !ModeInfo, !IO),
+        unique_modes_check_case_list(Cases0, Var, Cases, InstMaps, !ModeInfo),
         instmap_merge(NonLocals, InstMaps, merge_disj, !ModeInfo)
     ),
     GoalExpr = switch(Var, CanFail, Cases),
-    mode_checkpoint(exit, "switch", !ModeInfo, !IO).
+    mode_checkpoint(exit, "switch", !ModeInfo).

 :- pred unique_modes_check_goal_call_foreign_proc(
     pragma_foreign_proc_attributes::in, pred_id::in, proc_id::in,
     list(foreign_arg)::in, list(foreign_arg)::in,
     maybe(trace_expr(trace_runtime))::in, pragma_foreign_code_impl::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 unique_modes_check_goal_call_foreign_proc(Attributes, PredId, ProcId0,
         Args, ExtraArgs, MaybeTraceRuntimeCond, PragmaCode,
-        GoalInfo0, GoalExpr, !ModeInfo, !IO) :-
+        GoalInfo0, GoalExpr, !ModeInfo) :-
     % To modecheck a pragma_c_code, we just modecheck the proc for
     % which it is the goal.
-    mode_checkpoint(enter, "foreign_proc", !ModeInfo, !IO),
+    mode_checkpoint(enter, "foreign_proc", !ModeInfo),
     mode_info_get_call_id(!.ModeInfo, PredId, CallId),
     mode_info_set_call_context(call_context_call(plain_call_id(CallId)),
         !ModeInfo),
@@ -640,22 +636,22 @@
     GoalExpr = call_foreign_proc(Attributes, PredId, ProcId, Args, ExtraArgs,
         MaybeTraceRuntimeCond, PragmaCode),
     mode_info_unset_call_context(!ModeInfo),
-    mode_checkpoint(exit, "foreign_proc", !ModeInfo, !IO).
+    mode_checkpoint(exit, "foreign_proc", !ModeInfo).

 :- pred unique_modes_check_goal_atomic_goal(atomic_goal_type::in,
     atomic_interface_vars::in, atomic_interface_vars::in,
     maybe(list(prog_var))::in, hlds_goal::in, list(hlds_goal)::in,
     list(atomic_interface_vars)::in,
     hlds_goal_info::in, hlds_goal_expr::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 unique_modes_check_goal_atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
-        MainGoal0, OrElseGoals0, OrElseInners, GoalInfo0, GoalExpr, !ModeInfo,
-        !IO) :-
-    mode_checkpoint(enter, "atomic_goal", !ModeInfo, !IO),
+        MainGoal0, OrElseGoals0, OrElseInners, GoalInfo0, GoalExpr,
+        !ModeInfo) :-
+    mode_checkpoint(enter, "atomic_goal", !ModeInfo),
     (
         OrElseGoals0 = [],
-        unique_modes_check_goal(MainGoal0, MainGoal, !ModeInfo, !IO),
+        unique_modes_check_goal(MainGoal0, MainGoal, !ModeInfo),
         OrElseGoals = []
     ;
         OrElseGoals0 = [_ | _],
@@ -674,7 +670,7 @@
         ),
         Goals0 = [MainGoal0 | OrElseGoals0],
         unique_modes_check_disj(Goals0, Determinism, NonLocals, Goals,
-            InstMapList, !ModeInfo, !IO),
+            InstMapList, !ModeInfo),
         (
             Goals = [MainGoal | OrElseGoals]
         ;
@@ -687,7 +683,7 @@
     ShortHand = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
         MainGoal, OrElseGoals, OrElseInners),
     GoalExpr = shorthand(ShortHand),
-    mode_checkpoint(exit, "atomic_goal", !ModeInfo, !IO).
+    mode_checkpoint(exit, "atomic_goal", !ModeInfo).

 %-----------------------------------------------------------------------------%

@@ -821,31 +817,30 @@
 %-----------------------------------------------------------------------------%

 :- pred unique_modes_check_conj(conj_type::in,
-    list(hlds_goal)::in, list(hlds_goal)::out, mode_info::in, mode_info::out,
-    io::di, io::uo) is det.
+    list(hlds_goal)::in, list(hlds_goal)::out, mode_info::in, mode_info::out)
+    is det.

     % Just process each conjunct in turn.  Note that we don't do any
     % reordering of conjuncts here, although we do flatten conjunctions.
     %
-unique_modes_check_conj(_ConjType, [], [], !ModeInfo, !IO).
-unique_modes_check_conj(ConjType, [Goal0 | Goals0], Goals, !ModeInfo, !IO) :-
+unique_modes_check_conj(_ConjType, [], [], !ModeInfo).
+unique_modes_check_conj(ConjType, [Goal0 | Goals0], Goals, !ModeInfo) :-
     ( Goal0 = hlds_goal(conj(ConjType, ConjGoals), _) ->
         list.append(ConjGoals, Goals0, Goals1),
-        unique_modes_check_conj(ConjType, Goals1, Goals, !ModeInfo, !IO)
+        unique_modes_check_conj(ConjType, Goals1, Goals, !ModeInfo)
     ;
-        unique_modes_check_conj_2(ConjType, Goal0, Goals0, Goals, !ModeInfo,
-            !IO)
+        unique_modes_check_conj_2(ConjType, Goal0, Goals0, Goals, !ModeInfo)
     ).

 :- pred unique_modes_check_conj_2(conj_type::in,
     hlds_goal::in, list(hlds_goal)::in, list(hlds_goal)::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-unique_modes_check_conj_2(ConjType, Goal0, Goals0, [Goal | Goals], !ModeInfo,
-        !IO) :-
+unique_modes_check_conj_2(ConjType, Goal0, Goals0, [Goal | Goals],
+        !ModeInfo) :-
     NonLocals = goal_get_nonlocals(Goal0),
     mode_info_remove_live_vars(NonLocals, !ModeInfo),
-    unique_modes_check_goal(Goal0, Goal, !ModeInfo, !IO),
+    unique_modes_check_goal(Goal0, Goal, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMap),
     ( instmap_is_unreachable(InstMap) ->
         % We should not mode-analyse the remaining goals, since they are
@@ -854,7 +849,7 @@
         mode_info_remove_goals_live_vars(Goals0, !ModeInfo),
         Goals = []
     ;
-        unique_modes_check_conj(ConjType, Goals0, Goals, !ModeInfo, !IO)
+        unique_modes_check_conj(ConjType, Goals0, Goals, !ModeInfo)
     ).

 %-----------------------------------------------------------------------------%
@@ -885,12 +880,12 @@
     %
 :- pred unique_modes_check_par_conj(list(hlds_goal)::in, bag(prog_var)::in,
     list(hlds_goal)::out, list(pair(instmap, set(prog_var)))::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

 unique_modes_check_par_conj(Goals0, NonLocalVarsBag, Goals, Instmaps,
-        !ModeInfo, !IO) :-
+        !ModeInfo) :-
     unique_modes_check_par_conj_0(NonLocalVarsBag, !ModeInfo),
-    unique_modes_check_par_conj_1(Goals0, Goals, Instmaps, !ModeInfo, !IO).
+    unique_modes_check_par_conj_1(Goals0, Goals, Instmaps, !ModeInfo).

     % Figure out which variables occur in more than one conjunct and make them
     % shared.
@@ -920,17 +915,17 @@
     %
 :- pred unique_modes_check_par_conj_1(list(hlds_goal)::in,
     list(hlds_goal)::out, list(pair(instmap, set(prog_var)))::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-unique_modes_check_par_conj_1([], [], [], !ModeInfo, !IO).
+unique_modes_check_par_conj_1([], [], [], !ModeInfo).
 unique_modes_check_par_conj_1([Goal0 | Goals0], [Goal | Goals],
-        [InstMap - NonLocals | InstMaps], !ModeInfo, !IO) :-
+        [InstMap - NonLocals | InstMaps], !ModeInfo) :-
     NonLocals = goal_get_nonlocals(Goal0),
     mode_info_get_instmap(!.ModeInfo, InstMap0),
-    unique_modes_check_goal(Goal0, Goal, !ModeInfo, !IO),
+    unique_modes_check_goal(Goal0, Goal, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMap),
     mode_info_set_instmap(InstMap0, !ModeInfo),
-    unique_modes_check_par_conj_1(Goals0, Goals, InstMaps, !ModeInfo, !IO).
+    unique_modes_check_par_conj_1(Goals0, Goals, InstMaps, !ModeInfo).

 %-----------------------------------------------------------------------------%

@@ -940,21 +935,21 @@
     %
 :- pred unique_modes_check_disj(list(hlds_goal)::in, determinism::in,
     set(prog_var)::in, list(hlds_goal)::out, list(instmap)::out,
-    mode_info::in, mode_info::out, io::di, io::uo) is det.
+    mode_info::in, mode_info::out) is det.

-unique_modes_check_disj([], _, _, [], [], !ModeInfo, !IO).
+unique_modes_check_disj([], _, _, [], [], !ModeInfo).
 unique_modes_check_disj([Goal0 | Goals0], DisjDetism, DisjNonLocals,
-        [Goal | Goals], [InstMap | InstMaps], !ModeInfo, !IO) :-
+        [Goal | Goals], [InstMap | InstMaps], !ModeInfo) :-
     mode_info_get_instmap(!.ModeInfo, InstMap0),
     % If you modify this code, you may also need to modify
     % unique_modecheck_clause_disj or the code that calls it.

     prepare_for_disjunct(Goal0, DisjDetism, DisjNonLocals, !ModeInfo),
-    unique_modes_check_goal(Goal0, Goal, !ModeInfo, !IO),
+    unique_modes_check_goal(Goal0, Goal, !ModeInfo),
     mode_info_get_instmap(!.ModeInfo, InstMap),
     mode_info_set_instmap(InstMap0, !ModeInfo),
     unique_modes_check_disj(Goals0, DisjDetism, DisjNonLocals, Goals, InstMaps,
-        !ModeInfo, !IO).
+        !ModeInfo).

 prepare_for_disjunct(Goal0, DisjDetism, DisjNonLocals, !ModeInfo) :-
     (
@@ -982,12 +977,11 @@
 %-----------------------------------------------------------------------------%

 :- pred unique_modes_check_case_list(list(case)::in, prog_var::in,
-    list(case)::out, list(instmap)::out, mode_info::in, mode_info::out,
-    io::di, io::uo) is det.
+    list(case)::out, list(instmap)::out, mode_info::in, mode_info::out) is det.

-unique_modes_check_case_list([], _Var, [], [], !ModeInfo, !IO).
+unique_modes_check_case_list([], _Var, [], [], !ModeInfo).
 unique_modes_check_case_list([Case0 | Cases0], Var, [Case | Cases],
-        [InstMap | InstMaps], !ModeInfo, !IO) :-
+        [InstMap | InstMaps], !ModeInfo) :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
     mode_info_get_instmap(!.ModeInfo, InstMap0),

@@ -1000,7 +994,7 @@

     mode_info_get_instmap(!.ModeInfo, InstMap1),
     ( instmap_is_reachable(InstMap1) ->
-        unique_modes_check_goal(Goal0, Goal1, !ModeInfo, !IO)
+        unique_modes_check_goal(Goal0, Goal1, !ModeInfo)
     ;
         % We should not mode-analyse the goal, since it is unreachable.
         % Instead we optimize the goal away, so that later passes
@@ -1013,7 +1007,7 @@
     Case = case(MainConsId, OtherConsIds, Goal),

     mode_info_set_instmap(InstMap0, !ModeInfo),
-    unique_modes_check_case_list(Cases0, Var, Cases, InstMaps, !ModeInfo, !IO).
+    unique_modes_check_case_list(Cases0, Var, Cases, InstMaps, !ModeInfo).

 %-----------------------------------------------------------------------------%

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
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/posix/samples
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 ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
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/bigtest.err_exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/invalid/bigtest.err_exp,v
retrieving revision 1.15
diff -u -b -r1.15 bigtest.err_exp
--- tests/invalid/bigtest.err_exp	16 Jul 2008 03:30:58 -0000	1.15
+++ tests/invalid/bigtest.err_exp	20 Jul 2009 14:49:48 -0000
@@ -19,7 +19,7 @@
 bigtest.m:005: Error: clause for predicate `bigtest.fact'/0
 bigtest.m:005:   without preceding `pred' declaration.
 bigtest.m:005: Inferred :- pred fact.
-bigtest.m:010: Error: no mode declaration for predicate `p'/1.
-bigtest.m:010:   (Use `--infer-modes' to enable mode inference.)
 bigtest.m:005: Error: no mode declaration for predicate `fact'/0.
 bigtest.m:005:   (Use `--infer-modes' to enable mode inference.)
+bigtest.m:010: Error: no mode declaration for predicate `p'/1.
+bigtest.m:010:   (Use `--infer-modes' to enable mode inference.)
Index: tests/invalid/constrained_poly_insts.err_exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/invalid/constrained_poly_insts.err_exp,v
retrieving revision 1.11
diff -u -b -r1.11 constrained_poly_insts.err_exp
--- tests/invalid/constrained_poly_insts.err_exp	16 Jul 2008 03:30:58 -0000	1.11
+++ tests/invalid/constrained_poly_insts.err_exp	20 Jul 2009 14:49:57 -0000
@@ -22,6 +22,7 @@
 constrained_poly_insts.m:025: Inferred :- func s(T1) = T1.
 constrained_poly_insts.m:006: Error: no mode declaration for exported predicate
 constrained_poly_insts.m:006:   `constrained_poly_insts.p'/2.
+constrained_poly_insts.m:023: Error: no mode declaration for predicate `q'/2.
 constrained_poly_insts.m:027: In clause for `t(in((I =< ground)), out((I =<
 constrained_poly_insts.m:027:   ground)))':
 constrained_poly_insts.m:027:   mode error: argument 2 became too instantiated.
@@ -29,5 +30,4 @@
 constrained_poly_insts.m:027:   `unique(42)',
 constrained_poly_insts.m:027:   expected final instantiatedness was `(I =<
 constrained_poly_insts.m:027:   ground)'.
-constrained_poly_insts.m:023: Error: no mode declaration for predicate `q'/2.
 For more information, recompile with `-E'.
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/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
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
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