[m-rev.] for review: --max-error-line-width

Peter Wang novalazy at gmail.com
Tue Mar 30 16:39:36 AEDT 2010


Branches: main, 10.04

Add an option `--max-error-line-width <n>' to adjust the maximum line width for
error messages.

compiler/options.m:
doc/user_guide.texi:
NEWS:
        Add and document the option.

compiler/error_util.m:
        Make error message output predicates take globals arguments and get the
        maximum line width from that.

        Delete write_error_pieces_not_first_line and
        write_error_pieces_maybe_first_line which are obsolete and unused.

compiler/abstract_mode_constraints.m:
compiler/accumulator.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/fact_table.m:
compiler/mercury_compile.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/module_cmds.m:
compiler/options_file.m:
compiler/ordering_mode_constraints.m:
compiler/pred_table.m:
compiler/prop_mode_constraints.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
        Conform to changes.

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/max_error_line_width.err_exp:
tests/invalid/max_error_line_width.m:
        Add a test case.

diff --git a/NEWS b/NEWS
index fa0bdc3..995e22e 100644
--- a/NEWS
+++ b/NEWS
@@ -338,6 +338,9 @@ Changes to the Mercury compiler:
 * We have removed support for Managed C++ as a foreign language for the IL
   backend.
 
+* The width of error message lines can be adjusted with a new option,
+  `--max-error-line-width'.
+
 Changes to the Mercury deep profiler:
 
 * The deep profiler now supports measuring a proxy for time: a counter that
diff --git a/compiler/abstract_mode_constraints.m b/compiler/abstract_mode_constraints.m
index 5b43b56..381a49a 100644
--- a/compiler/abstract_mode_constraints.m
+++ b/compiler/abstract_mode_constraints.m
@@ -20,6 +20,8 @@
 
 :- import_module hlds.
 :- import_module hlds.hlds_pred.
+:- import_module libs.
+:- import_module libs.globals.
 :- import_module parse_tree.
 :- import_module parse_tree.prog_data.
 
@@ -152,7 +154,7 @@
 
     % Print the mc_constraints it is passed in a human readable format.
     %
-:- pred dump_constraints_and_annotations(mc_varset::in,
+:- pred dump_constraints_and_annotations(globals::in, mc_varset::in,
     list(mc_ann_constraint)::in, io::di, io::uo) is det.
 
     % Print a list of models for the constraint system.
@@ -409,74 +411,81 @@ xor(MCVarSet, Context, A, B, !Constraints) :-
 % Dumping constraints for --debug-mode-constraints
 %
 
-dump_constraints_and_annotations(VarSet, AnnConstraints, !IO) :-
+dump_constraints_and_annotations(Globals, VarSet, AnnConstraints, !IO) :-
     Indent = 0,
-    list.foldl(dump_ann_constraint(VarSet, Indent), AnnConstraints, !IO).
+    list.foldl(dump_ann_constraint(Globals, VarSet, Indent), AnnConstraints,
+        !IO).
 
     % Dumps a list of constraints using the same constraint annotation
     % at indent level indicated by the int.
     %
-:- pred dump_constraints(mc_varset::in, int::in, mc_annotation::in,
-    list(mc_constraint)::in, io::di, io::uo) is det.
+:- pred dump_constraints(globals::in, mc_varset::in, int::in,
+    mc_annotation::in, list(mc_constraint)::in, io::di, io::uo) is det.
 
-dump_constraints(VarSet, Indent, Annotation, Constraints, !IO) :-
-    list.foldl(dump_constraint(VarSet, Indent, Annotation), Constraints, !IO).
+dump_constraints(Globals, VarSet, Indent, Annotation, Constraints, !IO) :-
+    list.foldl(dump_constraint(Globals, VarSet, Indent, Annotation),
+        Constraints, !IO).
 
-:- pred dump_ann_constraint(mc_varset::in, int::in, mc_ann_constraint::in,
-    io::di, io::uo) is det.
+:- pred dump_ann_constraint(globals::in, mc_varset::in, int::in,
+    mc_ann_constraint::in, io::di, io::uo) is det.
 
-dump_ann_constraint(VarSet, Indent, AnnConstraint, !IO) :-
+dump_ann_constraint(Globals, VarSet, Indent, AnnConstraint, !IO) :-
     AnnConstraint = mc_ann_constraint(Constraint, Annotation),
-    dump_constraint(VarSet, Indent, Annotation, Constraint, !IO).
+    dump_constraint(Globals, VarSet, Indent, Annotation, Constraint, !IO).
 
     % Prints one mc_constraint to the output. The int is an indent level.
     %
-:- pred dump_constraint(mc_varset::in, int::in, mc_annotation::in,
+:- pred dump_constraint(globals::in, mc_varset::in, int::in, mc_annotation::in,
     mc_constraint::in, io::di, io::uo) is det.
 
-dump_constraint(VarSet, Indent, Annotation, Constraint, !IO) :-
+dump_constraint(Globals, VarSet, Indent, Annotation, Constraint, !IO) :-
     (
         Constraint = mc_disj(Constraints),
         Context = context(Annotation),
-        write_error_pieces(Context, Indent, [words("disj(")], !IO),
-        dump_constraints(VarSet, Indent+1, Annotation, Constraints, !IO),
-        write_error_pieces(Context, Indent, [words(") end disj")], !IO)
+        write_error_pieces(Globals, Context, Indent, [words("disj(")], !IO),
+        dump_constraints(Globals, VarSet, Indent+1, Annotation, Constraints,
+            !IO),
+        write_error_pieces(Globals, Context, Indent, [words(") end disj")],
+            !IO)
     ;
         Constraint = mc_conj(Constraints),
         Context = context(Annotation),
-        write_error_pieces(Context, Indent, [words("conj(")], !IO),
-        dump_constraints(VarSet, Indent+1, Annotation, Constraints, !IO),
-        write_error_pieces(Context, Indent, [words(") end conj")], !IO)
+        write_error_pieces(Globals, Context, Indent, [words("conj(")], !IO),
+        dump_constraints(Globals, VarSet, Indent+1, Annotation, Constraints,
+            !IO),
+        write_error_pieces(Globals, Context, Indent, [words(") end conj")],
+            !IO)
     ;
         Constraint = mc_atomic(AtomicConstraint),
-        dump_var_constraint(VarSet, Indent, Annotation, AtomicConstraint, !IO)
+        dump_var_constraint(Globals, VarSet, Indent, Annotation,
+            AtomicConstraint, !IO)
     ).
 
     % Prints a var_constraint to the output. The int is an indent level.
     %
-:- pred dump_var_constraint(mc_varset::in, int::in, mc_annotation::in,
-    var_constraint::in, io::di, io::uo) is det.
+:- pred dump_var_constraint(globals::in, mc_varset::in, int::in,
+    mc_annotation::in, var_constraint::in, io::di, io::uo) is det.
 
-dump_var_constraint(VarSet, Indent, Annotation, Constraint, !IO) :-
+dump_var_constraint(Globals, VarSet, Indent, Annotation, Constraint, !IO) :-
     (
         Constraint = equiv_bool(X, Val),
         mc_var_list_to_string(VarSet, [X], VarName),
         mc_var_val_to_string(Val, ValString),
         Context = context(Annotation),
-        write_error_pieces(Context, Indent,
+        write_error_pieces(Globals, Context, Indent,
             [words(VarName ++ " = " ++ ValString)], !IO)
     ;
         Constraint = equivalent(Xs),
         mc_var_list_to_string(VarSet, Xs, VarsString),
         Context = context(Annotation),
-        write_error_pieces(Context, Indent,
+        write_error_pieces(Globals, Context, Indent,
             [words("equivalent(" ++ VarsString ++ ")")], !IO)
     ;
         Constraint = implies(X, Y),
         mc_var_list_to_string(VarSet, [X], XName),
         mc_var_list_to_string(VarSet, [Y], YName),
         Context = context(Annotation),
-        write_error_pieces(Context, Indent,
+        write_error_pieces(Globals, Context, Indent,
             [words(XName ++ " -> " ++ YName)], !IO)
     ;
         Constraint = equiv_disj(X, Xs),
@@ -484,19 +493,19 @@ dump_var_constraint(VarSet, Indent, Annotation, Constraint, !IO) :-
         mc_var_list_to_string(VarSet, Xs, XsString),
         Context = context(Annotation),
         Pieces = [words(XName ++ " <-> disj(" ++ XsString ++ ")")],
-        write_error_pieces(Context, Indent, Pieces, !IO)
+        write_error_pieces(Globals, Context, Indent, Pieces, !IO)
     ;
         Constraint = at_most_one(Xs),
         mc_var_list_to_string(VarSet, Xs, XsString),
         Pieces = [words("at_most_one(" ++ XsString ++ ")")],
         Context = context(Annotation),
-        write_error_pieces(Context, Indent, Pieces, !IO)
+        write_error_pieces(Globals, Context, Indent, Pieces, !IO)
     ;
         Constraint = exactly_one(Xs),
         mc_var_list_to_string(VarSet, Xs, XsString),
         Pieces = [words("exactly_one(" ++ XsString ++ ")")],
         Context = context(Annotation),
-        write_error_pieces(Context, Indent, Pieces, !IO)
+        write_error_pieces(Globals, Context, Indent, Pieces, !IO)
     ).
 
     % mc_var_list_to_string(VarSet, MCVars, MCVarsString):
diff --git a/compiler/accumulator.m b/compiler/accumulator.m
index 19889cd..80536e3 100644
--- a/compiler/accumulator.m
+++ b/compiler/accumulator.m
@@ -262,7 +262,8 @@ process_proc(PredId, ProcId, !ProcInfo, !ModuleInfo, !IO) :-
             pred_info_get_context(PredInfo, Context),
             PredPieces = describe_one_pred_name(!.ModuleInfo,
                 should_module_qualify, PredId),
-            write_error_pieces(Context, 0, [words("In") | PredPieces], !IO),
+            write_error_pieces(Globals, Context, 0, [words("In") | PredPieces],
+                !IO),
 
             proc_info_get_varset(!.ProcInfo, VarSet),
             output_warnings(Warnings, VarSet, !.ModuleInfo, !IO),
@@ -272,7 +273,7 @@ process_proc(PredId, ProcId, !ProcInfo, !ModuleInfo, !IO) :-
                 words("performance problems."),
                 words("These warnings can be suppressed by"),
                 words("`--inhibit-accumulator-warnings'.")],
-            write_error_pieces(Context, 2, Pieces1, !IO),
+            write_error_pieces(Globals, Context, 2, Pieces1, !IO),
 
             globals.lookup_bool_option(Globals, verbose_errors, VerboseErrors),
             (
@@ -290,7 +291,7 @@ process_proc(PredId, ProcId, !ProcInfo, !ModuleInfo, !IO) :-
                     words("the optimization off, or "),
                     words("`--inhibit-accumulator-warnings' to turn off"),
                     words("the warnings.")],
-                write_error_pieces(Context, 2, Pieces2, !IO)
+                write_error_pieces(Globals, Context, 2, Pieces2, !IO)
             ;
                 VerboseErrors = no,
                 globals.io_set_extra_error_info(yes, !IO)
@@ -317,7 +318,8 @@ process_proc(PredId, ProcId, !ProcInfo, !ModuleInfo, !IO) :-
 output_warnings([], _, _, !IO).
 output_warnings([W | Ws], VarSet, ModuleInfo, !IO) :-
     output_warning(W, VarSet, ModuleInfo, Context, Format),
-    write_error_pieces(Context, 2, Format, !IO),
+    module_info_get_globals(ModuleInfo, Globals),
+    write_error_pieces(Globals, Context, 2, Format, !IO),
     output_warnings(Ws, VarSet, ModuleInfo, !IO).
 
 :- pred output_warning(warning::in, prog_varset::in, module_info::in,
diff --git a/compiler/compile_target_code.m b/compiler/compile_target_code.m
index f39a44c..fbc23d9 100644
--- a/compiler/compile_target_code.m
+++ b/compiler/compile_target_code.m
@@ -2347,7 +2347,8 @@ process_link_library(Globals, MercuryLibDirs, LibName, LinkerOpt, !Succeeded,
         ;
             SearchResult = error(Error),
             LinkerOpt = "",
-            write_error_pieces_maybe_with_context(no, 0, [words(Error)], !IO),
+            write_error_pieces_maybe_with_context(Globals, no, 0,
+                [words(Error)], !IO),
             !:Succeeded = no
         )
     ;
diff --git a/compiler/complexity.m b/compiler/complexity.m
index 5efb859..763820d 100644
--- a/compiler/complexity.m
+++ b/compiler/complexity.m
@@ -175,7 +175,7 @@ process_proc_msg(NumProcs, ProcMap, PredId, ProcId, !ProcInfo, !ModuleInfo,
                 fixed(FullName ++ ":"),
                 fixed(int_to_string(PredIdInt) ++ "/" ++
                     int_to_string(ProcIdInt))],
-            write_error_pieces_plain(Pieces, !IO)
+            write_error_pieces_plain(Globals, Pieces, !IO)
         ;
             Verbose = no
         ),
diff --git a/compiler/error_util.m b/compiler/error_util.m
index 3e8e81b..8dca4e5 100644
--- a/compiler/error_util.m
+++ b/compiler/error_util.m
@@ -23,8 +23,8 @@
 % with spaces between each pair of words, subject to the constraints
 % that every line starts with a context, followed by Indent+1 spaces
 % on the first line and Indent+3 spaces on later lines, and that every
-% line contains at most 79 characters (unless a long single word
-% forces the line over this limit).
+% line contains at most <n> characters (unless a long single word
+% forces the line over this limit) where --max-error-line-width <n>.
 %
 % The caller supplies the list of words to be printed in the form
 % of a list of error message components. Each component may specify
@@ -395,7 +395,7 @@
     % Display the given error message, without a context and with standard
     % indentation.
     %
-:- pred write_error_pieces_plain(list(format_component)::in,
+:- pred write_error_pieces_plain(globals::in, list(format_component)::in,
     io::di, io::uo) is det.
 
     % write_error_plain_with_progname(ProgName, Msg):
@@ -406,29 +406,17 @@
 :- pred write_error_plain_with_progname(string::in, string::in,
     io::di, io::uo) is det.
 
-    % write_error_pieces(Context, Indent, Components):
+    % write_error_pieces(Globals, Context, Indent, Components):
     %
     % Display `Components' as the error message, with `Context' as a context
     % and indent by `Indent'.
     %
-:- pred write_error_pieces(prog_context::in, int::in,
+:- pred write_error_pieces(globals::in, prog_context::in, int::in,
     list(format_component)::in, io::di, io::uo) is det.
 
-    % Display the given error message, but indent the first line.
-    % This is useful when adding extra lines to an already displayed message.
-    %
-:- pred write_error_pieces_not_first_line(prog_context::in, int::in,
-    list(format_component)::in, io::di, io::uo) is det.
-
-    % Display the given error message. The first argument tells us whether
-    % to treat this as the first line.
-    %
-:- pred write_error_pieces_maybe_first_line(maybe_treat_as_first::in,
-    prog_context::in, int::in, list(format_component)::in, io::di, io::uo)
-    is det.
-
-:- pred write_error_pieces_maybe_with_context(maybe(prog_context)::in, int::in,
-    list(format_component)::in, io::di, io::uo) is det.
+:- pred write_error_pieces_maybe_with_context(globals::in,
+    maybe(prog_context)::in, int::in, list(format_component)::in,
+    io::di, io::uo) is det.
 
 :- func error_pieces_to_string(list(format_component)) = string.
 
@@ -817,7 +805,8 @@ write_msg_components([Component | Components], MaybeContext, Indent, Globals,
         !First, !PrintedSome, !IO) :-
     (
         Component = always(ComponentPieces),
-        do_write_error_pieces(!.First, MaybeContext, Indent,
+        globals.lookup_int_option(Globals, max_error_line_width, MaxWidth),
+        do_write_error_pieces(!.First, MaybeContext, Indent, MaxWidth,
             ComponentPieces, !IO),
         !:First = do_not_treat_as_first,
         !:PrintedSome = printed_something
@@ -835,7 +824,9 @@ write_msg_components([Component | Components], MaybeContext, Indent, Globals,
         globals.lookup_bool_option(Globals, verbose_errors, VerboseErrors),
         (
             VerboseErrors = yes,
-            do_write_error_pieces(!.First, MaybeContext, Indent,
+            globals.lookup_int_option(Globals, max_error_line_width,
+                MaxWidth),
+            do_write_error_pieces(!.First, MaybeContext, Indent, MaxWidth,
                 ComponentPieces, !IO),
             !:First = do_not_treat_as_first,
             !:PrintedSome = printed_something
@@ -846,13 +837,14 @@ write_msg_components([Component | Components], MaybeContext, Indent, Globals,
     ;
         Component = verbose_and_nonverbose(VerbosePieces, NonVerbosePieces),
         globals.lookup_bool_option(Globals, verbose_errors, VerboseErrors),
+        globals.lookup_int_option(Globals, max_error_line_width, MaxWidth),
         (
             VerboseErrors = yes,
-            do_write_error_pieces(!.First, MaybeContext, Indent,
+            do_write_error_pieces(!.First, MaybeContext, Indent, MaxWidth,
                 VerbosePieces, !IO)
         ;
             VerboseErrors = no,
-            do_write_error_pieces(!.First, MaybeContext, Indent,
+            do_write_error_pieces(!.First, MaybeContext, Indent, MaxWidth,
                 NonVerbosePieces, !IO),
             globals.io_set_extra_error_info(yes, !IO)
         ),
@@ -924,33 +916,31 @@ is_or_are([]) = "" :-
 is_or_are([_]) = "is".
 is_or_are([_, _ | _]) = "are".
 
-write_error_pieces_plain(Components, !IO) :-
-    do_write_error_pieces(treat_as_first, no, 0, Components, !IO).
+write_error_pieces_plain(Globals, Components, !IO) :-
+    globals.lookup_int_option(Globals, max_error_line_width, MaxWidth),
+    do_write_error_pieces(treat_as_first, no, 0, MaxWidth, Components, !IO).
 
 write_error_plain_with_progname(ProgName, Msg, !IO) :-
-    write_error_pieces_plain([fixed(ProgName ++ ":"), words(Msg)], !IO).
-
-write_error_pieces(Context, Indent, Components, !IO) :-
-    do_write_error_pieces(treat_as_first, yes(Context), Indent,
-        Components, !IO).
+    MaxWidth = 79,
+    Components = [fixed(ProgName ++ ":"), words(Msg)],
+    do_write_error_pieces(treat_as_first, no, 0, MaxWidth, Components, !IO).
 
-write_error_pieces_not_first_line(Context, Indent, Components, !IO) :-
-    do_write_error_pieces(do_not_treat_as_first, yes(Context), Indent,
+write_error_pieces(Globals, Context, Indent, Components, !IO) :-
+    globals.lookup_int_option(Globals, max_error_line_width, MaxWidth),
+    do_write_error_pieces(treat_as_first, yes(Context), Indent, MaxWidth,
         Components, !IO).
 
-write_error_pieces_maybe_first_line(TreatAsFirst, Context, Indent, Components,
-        !IO) :-
-    do_write_error_pieces(TreatAsFirst, yes(Context), Indent, Components, !IO).
-
-write_error_pieces_maybe_with_context(MaybeContext, Indent, Components, !IO) :-
-    do_write_error_pieces(treat_as_first, MaybeContext, Indent,
+write_error_pieces_maybe_with_context(Globals, MaybeContext, Indent,
+        Components, !IO) :-
+    globals.lookup_int_option(Globals, max_error_line_width, MaxWidth),
+    do_write_error_pieces(treat_as_first, MaybeContext, Indent, MaxWidth,
         Components, !IO).
 
 :- pred do_write_error_pieces(maybe_treat_as_first::in,
-    maybe(prog_context)::in, int::in, list(format_component)::in,
+    maybe(prog_context)::in, int::in, int::in, list(format_component)::in,
     io::di, io::uo) is det.
 
-do_write_error_pieces(TreatAsFirst, MaybeContext, FixedIndent,
+do_write_error_pieces(TreatAsFirst, MaybeContext, FixedIndent, MaxWidth,
         Components, !IO) :-
     % The fixed characters at the start of the line are:
     % filename
@@ -978,7 +968,7 @@ do_write_error_pieces(TreatAsFirst, MaybeContext, FixedIndent,
     ),
     convert_components_to_paragraphs(Components, Paragraphs),
     FirstIndent = (TreatAsFirst = treat_as_first -> 0 ; 1),
-    Remain = 79 - (ContextLength + FixedIndent),
+    Remain = MaxWidth - (ContextLength + FixedIndent),
     group_words(TreatAsFirst, FirstIndent, Paragraphs, Remain, Lines),
     write_lines(Lines, MaybeContext, FixedIndent, !IO).
 
@@ -1509,7 +1499,7 @@ capitalize(Str0) = Str :-
 
 report_warning(Globals, Context, Indent, Components, !IO) :-
     record_warning(Globals, !IO),
-    write_error_pieces(Context, Indent, Components, !IO).
+    write_error_pieces(Globals, Context, Indent, Components, !IO).
 
 %-----------------------------------------------------------------------------%
 
diff --git a/compiler/fact_table.m b/compiler/fact_table.m
index 92ce26b..99940c1 100644
--- a/compiler/fact_table.m
+++ b/compiler/fact_table.m
@@ -215,15 +215,15 @@ fact_table_size(Globals, FactTableSize) :-
 
 fact_table_compile_facts(PredName, Arity, FileName, !PredInfo, Context,
         ModuleInfo, C_HeaderCode, PrimaryProcID, !IO) :-
-    see_input_handle_error(yes(Context), FileName, SeeResult, !IO),
+    module_info_get_globals(ModuleInfo, Globals),
+    see_input_handle_error(Globals, yes(Context), FileName, SeeResult, !IO),
     (
         SeeResult = ok,
-        module_info_get_globals(ModuleInfo, Globals),
         module_info_get_name(ModuleInfo, ModuleName),
         fact_table_file_name(Globals, ModuleName, FileName, ".c",
             do_create_dirs, OutputFileName, !IO),
-        open_output_handle_error(yes(Context), OutputFileName, OpenResult,
-            !IO),
+        open_output_handle_error(Globals, yes(Context), OutputFileName,
+            OpenResult, !IO),
         (
             OpenResult = ok(OutputStream),
             fact_table_compile_facts_2(PredName, Arity, FileName, !PredInfo,
@@ -313,7 +313,7 @@ fact_table_compile_facts_2(PredName, Arity, FileName, !PredInfo, Context,
                 C_HeaderCode2, C_HeaderCode3], C_HeaderCode)
         ;
             OpenCompileErrors = [_ | _],
-            print_error_reports(OpenCompileErrors, !IO),
+            print_error_reports(Globals, OpenCompileErrors, !IO),
             C_HeaderCode = C_HeaderCode0,
             PrimaryProcID = invalid_proc_id,
             DataFileName = ""
@@ -324,7 +324,7 @@ fact_table_compile_facts_2(PredName, Arity, FileName, !PredInfo, Context,
         % `:- pred' or `:- func' declaration had some types that are not
         % supported in fact tables so there is no point trying to type-check
         % all the facts.
-        print_error_reports(Pass1HeaderErrors, !IO),
+        print_error_reports(Globals, Pass1HeaderErrors, !IO),
         C_HeaderCode = C_HeaderCode0,
         PrimaryProcID = invalid_proc_id,
         WriteDataAfterSorting = no,
@@ -1175,13 +1175,13 @@ infer_determinism_pass_2([ProcID - FileName | ProcFiles], Globals,
                 "%s: an error occurred in the `sort' program "
                 ++ "during fact table determinism inference.",
                 [s(ProgName)], Msg),
-            write_error_pieces_plain([words(Msg)], !IO),
+            write_error_pieces_plain(Globals, [words(Msg)], !IO),
             io.set_exit_status(1, !IO),
             Determinism = detism_erroneous
         )
     ;
         Result = error(ErrorCode),
-        write_call_system_error_msg("sort", ErrorCode, !IO),
+        write_call_system_error_msg(Globals, "sort", ErrorCode, !IO),
         Determinism = detism_erroneous
     ),
     proc_info_set_inferred_determinism(Determinism, ProcInfo0, ProcInfo),
@@ -1354,14 +1354,14 @@ maybe_append_data_table(Globals, yes, OutputFileName, DataFileName, !IO) :-
         ;
             Msg = "An error occurred while concatenating" ++
                 "fact table output files.",
-            write_error_pieces_plain([words(Msg)], !IO),
+            write_error_pieces_plain(Globals, [words(Msg)], !IO),
             io.set_exit_status(1, !IO)
         )
     ;
         Result = error(ErrorCode),
-        write_call_system_error_msg("cat", ErrorCode, !IO)
+        write_call_system_error_msg(Globals, "cat", ErrorCode, !IO)
     ),
-    delete_temporary_file(DataFileName, !IO).
+    delete_temporary_file(Globals, DataFileName, !IO).
 
     % Write hash tables for the primary key. Create a map from indices in the
     % original input table to the table sorted on the primary key.
@@ -1376,12 +1376,13 @@ write_primary_hash_table(ProcID, FileName, DataFileName, StructName, ProcTable,
         ModuleInfo, OutputStream, FactArgInfos, WriteDataTable,
         NumFacts, CreateFactMap, Result, FactMap, C_HeaderCode, !IO) :-
     map.init(FactMap0),
-    see_input_handle_error(no, FileName, Result0, !IO),
+    module_info_get_globals(ModuleInfo, Globals),
+    see_input_handle_error(Globals, no, FileName, Result0, !IO),
     (
         Result0 = ok,
         (
             WriteDataTable  = yes,
-            open_output_handle_error(no, DataFileName, Result1, !IO),
+            open_output_handle_error(Globals, no, DataFileName, Result1, !IO),
             (
                 Result1 = ok(DataStream),
                 MaybeDataStream = yes(DataStream),
@@ -1433,7 +1434,6 @@ write_primary_hash_table(ProcID, FileName, DataFileName, StructName, ProcTable,
             MaybeDataStream = yes(DataStream1),
             % Closing brace for last fact data array.
             write_closing_brace(DataStream1, !IO),
-            module_info_get_globals(ModuleInfo, Globals),
             fact_table_size(Globals, FactTableSize),
             write_fact_table_pointer_array(NumFacts, FactTableSize,
                 StructName, DataStream1, C_HeaderCode1, !IO),
@@ -1444,7 +1444,7 @@ write_primary_hash_table(ProcID, FileName, DataFileName, StructName, ProcTable,
             C_HeaderCode = C_HeaderCode0
         ),
         io.seen(!IO),
-        delete_temporary_file(FileName, !IO)
+        delete_temporary_file(Globals, FileName, !IO)
     ;
         Result0 = error(_),
         Result = error,
@@ -1463,7 +1463,8 @@ write_secondary_hash_tables([], _, _, _, _, _, _, !C_HeaderCode, !IO).
 write_secondary_hash_tables([ProcID - FileName | ProcFiles], StructName,
         ProcTable, ModuleInfo, OutputStream, FactMap, FactArgInfos,
         !C_HeaderCode, !IO) :-
-    see_input_handle_error(no, FileName, SeeResult, !IO),
+    module_info_get_globals(ModuleInfo, Globals),
+    see_input_handle_error(Globals, no, FileName, SeeResult, !IO),
     (
         SeeResult = ok,
         proc_id_to_int(ProcID, ProcInt),
@@ -1486,7 +1487,7 @@ write_secondary_hash_tables([ProcID - FileName | ProcFiles], StructName,
                 ModuleInfo, FactArgInfos, no, OutputStream, FirstFact, no, no,
                 FactMap, _, !IO),
             io.seen(!IO),
-            delete_temporary_file(FileName, !IO),
+            delete_temporary_file(Globals, FileName, !IO),
             write_secondary_hash_tables(ProcFiles, StructName, ProcTable,
                 ModuleInfo, OutputStream, FactMap, FactArgInfos,
                 !C_HeaderCode, !IO)
@@ -1518,7 +1519,9 @@ read_sort_file_line(FactArgInfos, ArgModes, ModuleInfo, MaybeSortFileLine,
         io.error_message(ErrorCode, ErrorMessage),
         io.input_stream_name(FileName, !IO),
         string.format("Error reading file `%s':", [s(FileName)], Msg),
-        write_error_pieces_plain([words(Msg), nl, words(ErrorMessage)], !IO),
+        module_info_get_globals(ModuleInfo, Globals),
+        write_error_pieces_plain(Globals,
+            [words(Msg), nl, words(ErrorMessage)], !IO),
         io.set_exit_status(1, !IO),
         MaybeSortFileLine = no
     ).
@@ -3285,9 +3288,9 @@ void mercury_sys_init_%s_module(void) {
 
     % Delete a file. Report an error message if something goes wrong.
     %
-:- pred delete_temporary_file(string::in, io::di, io::uo) is det.
+:- pred delete_temporary_file(globals::in, string::in, io::di, io::uo) is det.
 
-delete_temporary_file(FileName, !IO) :-
+delete_temporary_file(Globals, FileName, !IO) :-
     io.remove_file(FileName, Result, !IO),
     (
         Result = ok
@@ -3297,14 +3300,15 @@ delete_temporary_file(FileName, !IO) :-
         io.progname_base("mercury_compile", ProgName, !IO),
         string.format("%s: error deleting file `%s:",
             [s(ProgName), s(FileName)], Msg),
-        write_error_pieces_plain([words(Msg), nl, words(ErrorMsg)], !IO),
+        write_error_pieces_plain(Globals, [words(Msg), nl, words(ErrorMsg)],
+            !IO),
         io.set_exit_status(1, !IO)
     ).
 
-:- pred open_output_handle_error(maybe(context)::in, string::in,
+:- pred open_output_handle_error(globals::in, maybe(context)::in, string::in,
     io.res(io.output_stream)::out, io::di, io::uo) is det.
 
-open_output_handle_error(MaybeContext, FileName, Result, !IO) :-
+open_output_handle_error(Globals, MaybeContext, FileName, Result, !IO) :-
     io.open_output(FileName, Result, !IO),
     (
         Result = ok(_)
@@ -3313,30 +3317,14 @@ open_output_handle_error(MaybeContext, FileName, Result, !IO) :-
         io.error_message(ErrorCode, ErrorMsg),
         string.format("Error opening file `%s' for output:",
             [s(FileName)], Msg),
-        write_error_msg(MaybeContext, Msg, ErrorMsg, !IO),
-        io.set_exit_status(1, !IO)
-    ).
-
-:- pred open_input_handle_error(maybe(context)::in, string::in,
-    io.res(io.input_stream)::out, io::di, io::uo) is det.
-
-open_input_handle_error(MaybeContext, FileName, Result, !IO) :-
-    io.open_input(FileName, Result, !IO),
-    (
-        Result = ok(_)
-    ;
-        Result = error(ErrorCode),
-        io.error_message(ErrorCode, ErrorMsg),
-        string.format("Error opening file `%s' for input:",
-            [s(FileName)], Msg),
-        write_error_msg(MaybeContext, Msg, ErrorMsg, !IO),
+        write_error_msg(Globals, MaybeContext, Msg, ErrorMsg, !IO),
         io.set_exit_status(1, !IO)
     ).
 
-:- pred see_input_handle_error(maybe(context)::in, string::in,
+:- pred see_input_handle_error(globals::in, maybe(context)::in, string::in,
     io.res::out, io::di, io::uo) is det.
 
-see_input_handle_error(MaybeContext, FileName, Result, !IO) :-
+see_input_handle_error(Globals, MaybeContext, FileName, Result, !IO) :-
     io.see(FileName, Result, !IO),
     (
         Result = ok
@@ -3345,31 +3333,33 @@ see_input_handle_error(MaybeContext, FileName, Result, !IO) :-
         io.error_message(ErrorCode, ErrorMsg),
         string.format("Error opening file `%s' for input:",
             [s(FileName)], Msg),
-        write_error_msg(MaybeContext, Msg, ErrorMsg, !IO),
+        write_error_msg(Globals, MaybeContext, Msg, ErrorMsg, !IO),
         io.set_exit_status(1, !IO)
     ).
 
-:- pred write_error_msg(maybe(context)::in, string::in, string::in,
-    io::di, io::uo) is det.
+:- pred write_error_msg(globals::in, maybe(context)::in,
+    string::in, string::in, io::di, io::uo) is det.
 
-write_error_msg(MaybeContext, Msg, ErrorMsg, !IO) :-
+write_error_msg(Globals, MaybeContext, Msg, ErrorMsg, !IO) :-
     (
         MaybeContext = yes(Context),
-        write_error_pieces(Context, 0, [words(Msg), nl, words(ErrorMsg)], !IO)
+        write_error_pieces(Globals, Context, 0,
+            [words(Msg), nl, words(ErrorMsg)], !IO)
     ;
         MaybeContext = no,
-        write_error_pieces_plain([words(Msg), nl, words(ErrorMsg)], !IO)
+        write_error_pieces_plain(Globals, [words(Msg), nl, words(ErrorMsg)],
+            !IO)
     ).
 
-:- pred write_call_system_error_msg(string::in, io.error::in, io::di, io::uo)
-    is det.
+:- pred write_call_system_error_msg(globals::in, string::in, io.error::in,
+    io::di, io::uo) is det.
 
-write_call_system_error_msg(Cmd, ErrorCode, !IO) :-
+write_call_system_error_msg(Globals, Cmd, ErrorCode, !IO) :-
     io.error_message(ErrorCode, ErrorMsg),
     io.progname_base("mercury_compile", ProgName, !IO),
     string.format("%s: error executing system command `%s:",
         [s(ProgName), s(Cmd)], Msg),
-    write_error_pieces_plain([words(Msg), nl, words(ErrorMsg)], !IO),
+    write_error_pieces_plain(Globals, [words(Msg), nl, words(ErrorMsg)], !IO),
     io.set_exit_status(1, !IO).
 
 %-----------------------------------------------------------------------------%
@@ -3393,21 +3383,23 @@ add_error_report(Context, Components, !Errors) :-
 add_error_report(Components, !Errors) :-
     !:Errors = [no - Components | !.Errors].
 
-:- pred print_error_reports(error_reports::in, io::di, io::uo) is det.
+:- pred print_error_reports(globals::in, error_reports::in, io::di, io::uo)
+    is det.
 
-print_error_reports(RevErrors, !IO) :-
+print_error_reports(Globals, RevErrors, !IO) :-
     list.reverse(RevErrors, Errors),
-    list.foldl(print_error_report, Errors, !IO).
+    list.foldl(print_error_report(Globals), Errors, !IO).
 
-:- pred print_error_report(error_report::in, io::di, io::uo) is det.
+:- pred print_error_report(globals::in, error_report::in, io::di, io::uo)
+    is det.
 
-print_error_report(MaybeContext - Components, !IO) :-
+print_error_report(Globals, MaybeContext - Components, !IO) :-
     (
         MaybeContext = yes(Context),
-        write_error_pieces(Context, 0, Components, !IO)
+        write_error_pieces(Globals, Context, 0, Components, !IO)
     ;
         MaybeContext = no,
-        write_error_pieces_plain(Components, !IO)
+        write_error_pieces_plain(Globals, Components, !IO)
     ),
     io.set_exit_status(1, !IO).
 
diff --git a/compiler/mercury_compile.m b/compiler/mercury_compile.m
index 5198d84..a0b31f0 100644
--- a/compiler/mercury_compile.m
+++ b/compiler/mercury_compile.m
@@ -405,7 +405,7 @@ main_after_setup(OptionVariables, OptionArgs, Args, Link, Globals, !IO) :-
                 words(compilation_target_string(Target)),
                 suffix(".")
             ],
-            write_error_pieces_plain(NYIMsg, !IO),
+            write_error_pieces_plain(Globals, NYIMsg, !IO),
             io.set_exit_status(1, !IO)
         ;
             ( Target = target_c
@@ -517,7 +517,7 @@ process_all_args(Globals, OptionVariables, OptionArgs, Args,
                     Msg = "Sorry, not implemented: " ++
                         "`--target asm' with `--smart-recompilation' " ++
                         "with more than one module to compile.",
-                    write_error_pieces_plain([words(Msg)], !IO),
+                    write_error_pieces_plain(Globals, [words(Msg)], !IO),
                     io.set_exit_status(1, !IO),
                     ModulesToLink = [],
                     ExtraObjFiles = [],
@@ -535,7 +535,7 @@ process_all_args(Globals, OptionVariables, OptionArgs, Args,
             Args = [],
             Msg = "Sorry, not implemented: `--target asm' " ++
                 "with `--filenames-from-stdin",
-            write_error_pieces_plain([words(Msg)], !IO),
+            write_error_pieces_plain(Globals, [words(Msg)], !IO),
             io.set_exit_status(1, !IO),
             ModulesToLink = [],
             ExtraObjFiles = []
@@ -1027,7 +1027,7 @@ read_module_or_file(Globals0, Globals, FileOrModuleName, ReturnTimestamp,
                         words("Smart recompilation will not work unless"),
                         words("a module name to file name mapping is created"),
                         words("using `mmc -f *.m'."), nl],
-                    write_error_pieces_plain(Pieces, !IO),
+                    write_error_pieces_plain(Globals, Pieces, !IO),
                     record_warning(Globals, !IO)
                 ;
                     Warn = no
diff --git a/compiler/mercury_compile_mlds_back_end.m b/compiler/mercury_compile_mlds_back_end.m
index 2de0d0a..3aa9c06 100644
--- a/compiler/mercury_compile_mlds_back_end.m
+++ b/compiler/mercury_compile_mlds_back_end.m
@@ -355,7 +355,7 @@ maybe_add_heap_ops(Verbose, Stats, !HLDS, !IO) :-
             "`--reclaim-heap-on-semidet-failure' and " ++
             "`--reclaim-heap-on-nondet-failure'. " ++
             "Use `--(no-)reclaim-heap-on-failure' instead.",
-        write_error_pieces_plain([words(Msg)], !IO),
+        write_error_pieces_plain(Globals, [words(Msg)], !IO),
         io.set_exit_status(1, !IO)
     ).
 
diff --git a/compiler/module_cmds.m b/compiler/module_cmds.m
index 63d1c84..1e322a9 100644
--- a/compiler/module_cmds.m
+++ b/compiler/module_cmds.m
@@ -952,7 +952,8 @@ find_erlang_library_path(Globals, MercuryLibDirs, LibName, LibPath,
     ;
         SearchResult = error(Error),
         LibPath = "",
-        write_error_pieces_maybe_with_context(no, 0, [words(Error)], !IO),
+        write_error_pieces_maybe_with_context(Globals, no, 0, [words(Error)],
+            !IO),
         !:Succeeded = no
     ).
 
diff --git a/compiler/options.m b/compiler/options.m
index 7eb8887..2cc2e7c 100644
--- a/compiler/options.m
+++ b/compiler/options.m
@@ -247,6 +247,7 @@
     ;       line_numbers
     ;       auto_comments
     ;       frameopt_comments
+    ;       max_error_line_width
     ;       show_dependency_graph
     ;       imports_graph
     ;       dump_trace_counts
@@ -1163,6 +1164,7 @@ option_defaults_2(aux_output_option, [
     line_numbers                        -   bool(yes),
     auto_comments                       -   bool(no),
     frameopt_comments                   -   bool(no),
+    max_error_line_width                -   int(79),
     show_dependency_graph               -   bool(no),
     imports_graph                       -   bool(no),
     dump_trace_counts                   -   accumulating([]),
@@ -2010,6 +2012,7 @@ long_option("generate-bytecode",        generate_bytecode).
 long_option("line-numbers",             line_numbers).
 long_option("auto-comments",            auto_comments).
 long_option("frameopt-comments",        frameopt_comments).
+long_option("max-error-line-width",     max_error_line_width).
 long_option("show-dependency-graph",    show_dependency_graph).
 long_option("imports-graph",            imports_graph).
 long_option("dump-trace-counts",        dump_trace_counts).
@@ -3733,6 +3736,9 @@ options_help_aux_output -->
 %       "\tGet frameopt.m to generate comments describing its operation.",
         "\t(The code may be easier to understand if you also",
         "\tuse the `--no-llds-optimize' option.)",
+        "--max-error-line-width <n>",
+        "\tSet the maximum width of an error message line to <n> characters",
+        "\t(unless a long single word forces the line over this limit).",
         "--show-dependency-graph",
         "\tWrite out the dependency graph to `<module>.dependency_graph'.",
         "--imports-graph",
diff --git a/compiler/options_file.m b/compiler/options_file.m
index f7c227b..49d91f4 100644
--- a/compiler/options_file.m
+++ b/compiler/options_file.m
@@ -335,8 +335,8 @@ read_options_lines(Globals, Dir, !Variables, !IO) :-
         LineResult = exception(Exception),
         ( Exception = univ(options_file_error(Error)) ->
             io.input_stream_name(FileName, !IO),
-            write_error_pieces(term.context_init(FileName, LineNumber),
-                0, [words(Error)], !IO),
+            Context = term.context_init(FileName, LineNumber),
+            write_error_pieces(Globals, Context, 0, [words(Error)], !IO),
 
             % This will be caught by `read_options_files'. The open options
             % files aren't closed on the way up, but we will be exiting
@@ -567,7 +567,7 @@ report_undefined_variables_2(Globals, [_ | Rest] @ UndefVars, !IO) :-
         ),
         Pieces = [words("Warning: "), words(Word) | VarList]
             ++ [words(IsOrAre), words("undefined.")],
-        write_error_pieces(Context, 0, Pieces, !IO),
+        write_error_pieces(Globals, Context, 0, Pieces, !IO),
 
         globals.lookup_bool_option(Globals, halt_at_warn, Halt),
         (
diff --git a/compiler/ordering_mode_constraints.m b/compiler/ordering_mode_constraints.m
index 9569cd4..8ce8458 100644
--- a/compiler/ordering_mode_constraints.m
+++ b/compiler/ordering_mode_constraints.m
@@ -108,6 +108,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module libs.
 :- import_module libs.compiler_util.
+:- import_module libs.globals.
 :- import_module mdbcomp.
 :- import_module mdbcomp.program_representation.
 :- import_module parse_tree.
@@ -715,13 +716,14 @@ dump_pred_goal_paths(ModuleInfo, PredId, !IO) :-
     ProcIds = map.keys(ProcTable),
 
     % Start with a blank line.
-    write_error_pieces_plain([fixed("")], !IO),
+    module_info_get_globals(ModuleInfo, Globals),
+    write_error_pieces_plain(Globals, [fixed("")], !IO),
 
     PredHeaderFormat = [words("Goal paths for")] ++
         describe_one_pred_info_name(should_module_qualify, PredInfo) ++
         [suffix("."), nl],
 
-    write_error_pieces_plain(PredHeaderFormat, !IO),
+    write_error_pieces_plain(Globals, PredHeaderFormat, !IO),
 
     (
         ProcIds = [],
@@ -730,43 +732,45 @@ dump_pred_goal_paths(ModuleInfo, PredId, !IO) :-
         get_clause_list(ClausesRep, Clauses),
         Goals = list.map(func(Clause) = clause_body(Clause), Clauses),
         Indent = 0,
-        list.foldl(dump_goal_goal_paths(Indent), Goals, !IO)
+        list.foldl(dump_goal_goal_paths(Globals, Indent), Goals, !IO)
     ;
         ProcIds = [_ | _],
-        list.foldl(dump_proc_goal_paths(ProcTable), ProcIds, !IO)
+        list.foldl(dump_proc_goal_paths(Globals, ProcTable), ProcIds, !IO)
     ).
 
-    % dump_proc_goal_paths(ProcTable, ProcId, !IO)
+    % dump_proc_goal_paths(Globals, ProcTable, ProcId, !IO)
     %
     % Dumps the goal paths of each goal in the order they appear for
     % procedure ProcId for the purposes of visually checking re-ordering.
     %
-:- pred dump_proc_goal_paths(proc_table::in, proc_id::in, io::di, io::uo)
-    is det.
+:- pred dump_proc_goal_paths(globals::in, proc_table::in, proc_id::in,
+    io::di, io::uo) is det.
 
-dump_proc_goal_paths(ProcTable, ProcId, !IO) :-
+dump_proc_goal_paths(Globals, ProcTable, ProcId, !IO) :-
     ProcIdString = string.from_int(proc_id_to_int(ProcId)),
     ProcHeaderFormat = [words("mode"), words(ProcIdString), suffix(":")],
-    write_error_pieces_plain(ProcHeaderFormat, !IO),
+    write_error_pieces_plain(Globals, ProcHeaderFormat, !IO),
     map.lookup(ProcTable, ProcId, ProcInfo),
     proc_info_get_goal(ProcInfo, Goal),
     Indent = 0,
-    dump_goal_goal_paths(Indent, Goal, !IO).
+    dump_goal_goal_paths(Globals, Indent, Goal, !IO).
 
-    % dump_goal_goal_paths(Indent, Goal, !IO)
+    % dump_goal_goal_paths(Globals, Indent, Goal, !IO)
     %
     % Dumps the goal paths for this goal at the indent depth Indent, then
     % recurses for each sub-goal at one further level of indent,
     % in the order they appear, for the purposes of visually checking
     % re-ordering.
     %
-:- pred dump_goal_goal_paths(int::in, hlds_goal::in, io::di, io::uo) is det.
+:- pred dump_goal_goal_paths(globals::in, int::in, hlds_goal::in,
+    io::di, io::uo) is det.
 
-dump_goal_goal_paths(Indent, Goal, !IO) :-
+dump_goal_goal_paths(Globals, Indent, Goal, !IO) :-
     Goal = hlds_goal(GoalExpr, GoalInfo),
     GoalPath = goal_info_get_goal_path(GoalInfo),
     GoalPathFormat = [words(goal_path_to_string(GoalPath)), nl],
-    write_error_pieces_maybe_with_context(no, Indent, GoalPathFormat, !IO),
+    write_error_pieces_maybe_with_context(Globals, no, Indent, GoalPathFormat,
+        !IO),
 
     % Dump the goal paths for each subgoal in GoalExpr at SubGoalIndent,
     % in the order they appear, for the purposes of visually checking
@@ -781,29 +785,30 @@ dump_goal_goal_paths(Indent, Goal, !IO) :-
         % There are no subgoals to recurse on.
     ;
         GoalExpr = conj(_, Goals),
-        list.foldl(dump_goal_goal_paths(SubGoalIndent), Goals, !IO)
+        list.foldl(dump_goal_goal_paths(Globals, SubGoalIndent), Goals, !IO)
     ;
         GoalExpr = disj(Goals),
-        list.foldl(dump_goal_goal_paths(SubGoalIndent), Goals, !IO)
+        list.foldl(dump_goal_goal_paths(Globals, SubGoalIndent), Goals, !IO)
     ;
         GoalExpr = switch(_, _, _),
         unexpected(this_file, "switch")
     ;
         GoalExpr = if_then_else(_, CondGoal, ThenGoal, ElseGoal),
         Goals = [CondGoal, ThenGoal, ElseGoal],
-        list.foldl(dump_goal_goal_paths(SubGoalIndent), Goals, !IO)
+        list.foldl(dump_goal_goal_paths(Globals, SubGoalIndent), Goals, !IO)
     ;
         GoalExpr = negation(SubGoal),
-        dump_goal_goal_paths(SubGoalIndent, SubGoal, !IO)
+        dump_goal_goal_paths(Globals, SubGoalIndent, SubGoal, !IO)
     ;
         GoalExpr = scope(_, SubGoal),
-        dump_goal_goal_paths(SubGoalIndent, SubGoal, !IO)
+        dump_goal_goal_paths(Globals, SubGoalIndent, SubGoal, !IO)
     ;
         GoalExpr = shorthand(ShortHand),
         (
             ShortHand = atomic_goal(_, _, _, _, MainGoal, OrElseGoals, _),
             Goals = [MainGoal | OrElseGoals],
-            list.foldl(dump_goal_goal_paths(SubGoalIndent), Goals, !IO)
+            list.foldl(dump_goal_goal_paths(Globals, SubGoalIndent), Goals,
+                !IO)
         ;
             ShortHand = try_goal(_, _, _),
             unexpected(this_file, "try_goal")
diff --git a/compiler/pred_table.m b/compiler/pred_table.m
index 9c6ebf9..2b602c2 100644
--- a/compiler/pred_table.m
+++ b/compiler/pred_table.m
@@ -1031,13 +1031,14 @@ find_matching_pred_id(ModuleInfo, [PredId | PredIds], TVarSet, ExistQTVars,
             pred_info_get_call_id(OtherPredInfo, OtherPredCallId),
             % XXX this is not very nice
             trace [io(!IO)] (
+                module_info_get_globals(ModuleInfo, Globals),
                 Pieces = [
                     words("Error: unresolved predicate overloading, matched"),
                     simple_call(PredCallId), words("and"),
                     simple_call(OtherPredCallId), suffix("."),
                     words("You need to use an explicit module qualifier."),
                     nl],
-                write_error_pieces(Context, 0, Pieces, !IO)
+                write_error_pieces(Globals, Context, 0, Pieces, !IO)
             ),
             unexpected(this_file,
                 "find_matching_pred_id: unresolvable predicate overloading")
diff --git a/compiler/prop_mode_constraints.m b/compiler/prop_mode_constraints.m
index 24a63f5..0cb2c7c 100644
--- a/compiler/prop_mode_constraints.m
+++ b/compiler/prop_mode_constraints.m
@@ -520,18 +520,20 @@ pretty_print_pred_constraints_map(ModuleInfo, ConstraintVarset,
 
 pretty_print_pred_constraints(ModuleInfo, ConstraintVarset,
         PredConstraintsMap, PredId, !IO) :-
+    module_info_get_globals(ModuleInfo, Globals),
+
     % Start with a blank line.
-    write_error_pieces_plain([fixed("")], !IO),
+    write_error_pieces_plain(Globals, [fixed("")], !IO),
 
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
-    write_error_pieces_plain([words("Constraints for")] ++
+    write_error_pieces_plain(Globals, [words("Constraints for")] ++
         describe_one_pred_info_name(should_module_qualify, PredInfo) ++
         [suffix(":")], !IO),
 
     map.lookup(PredConstraintsMap, PredId, PredConstraints),
     AllProcAnnConstraints = allproc_annotated_constraints(PredConstraints),
-    dump_constraints_and_annotations(ConstraintVarset, AllProcAnnConstraints,
-        !IO),
+    dump_constraints_and_annotations(Globals, ConstraintVarset,
+        AllProcAnnConstraints, !IO),
     list.foldl(
         pretty_print_proc_constraints(ModuleInfo, ConstraintVarset,
             PredConstraints, PredId),
@@ -546,15 +548,17 @@ pretty_print_pred_constraints(ModuleInfo, ConstraintVarset,
 
 pretty_print_proc_constraints(ModuleInfo, ConstraintVarset, PredConstraints,
         PredId, ProcId, !IO) :-
+    module_info_get_globals(ModuleInfo, Globals),
+
     % Start with a blank line.
-    write_error_pieces_plain([fixed("")], !IO),
+    write_error_pieces_plain(Globals, [fixed("")], !IO),
 
-    write_error_pieces_plain(describe_one_proc_name(ModuleInfo,
+    write_error_pieces_plain(Globals, describe_one_proc_name(ModuleInfo,
         should_module_qualify, proc(PredId, ProcId)) ++ [suffix(":")], !IO),
     ProcSpecAnnConstraints =
         proc_specific_annotated_constraints(ProcId, PredConstraints),
-    dump_constraints_and_annotations(ConstraintVarset, ProcSpecAnnConstraints,
-        !IO).
+    dump_constraints_and_annotations(Globals, ConstraintVarset,
+        ProcSpecAnnConstraints, !IO).
 
 %-----------------------------------------------------------------------------%
 
diff --git a/compiler/term_constr_errors.m b/compiler/term_constr_errors.m
index 6410844..551b64f 100644
--- a/compiler/term_constr_errors.m
+++ b/compiler/term_constr_errors.m
@@ -167,19 +167,20 @@ report_term_errors(SCC, Errors, Module, !IO) :-
         Pieces1 = Pieces0 ++ ProcNames,
         Single = no
     ),  
+    module_info_get_globals(Module, Globals),
     (
         Errors = [],
         Pieces2 = [words("not proven, for unknown reason(s).")],
-        write_error_pieces(Context, 0, Pieces1 ++ Pieces2, !IO)
+        write_error_pieces(Globals, Context, 0, Pieces1 ++ Pieces2, !IO)
     ;
         Errors = [Error],
         Pieces2 = [words("not proven for the following reason:")],
-        write_error_pieces(Context, 0, Pieces1 ++ Pieces2, !IO),
+        write_error_pieces(Globals, Context, 0, Pieces1 ++ Pieces2, !IO),
         output_error(Error, Single, no, 0, Module, !IO)
     ;
         Errors = [_, _ | _],
         Pieces2 = [words("not proven for the following reasons:")],
-        write_error_pieces(Context, 0, Pieces1 ++ Pieces2, !IO),
+        write_error_pieces(Globals, Context, 0, Pieces1 ++ Pieces2, !IO),
         output_errors(Errors, Single, 1, 0, Module, !IO)
     ).
 
@@ -206,7 +207,8 @@ output_error(Context - Error, Single, ErrorNum, Indent, Module, !IO) :-
         ErrorNum = no,
         Pieces = Pieces0
     ),
-    write_error_pieces(Context, Indent, Pieces, !IO).
+    module_info_get_globals(Module, Globals),
+    write_error_pieces(Globals, Context, Indent, Pieces, !IO).
 
 :- pred description(termination2_error::in,
     maybe(pred_proc_id)::in, module_info::in, list(format_component)::out,
diff --git a/compiler/term_errors.m b/compiler/term_errors.m
index f2f671b..3625976 100644
--- a/compiler/term_errors.m
+++ b/compiler/term_errors.m
@@ -224,6 +224,7 @@ is_fatal_error(inconsistent_annotations) = no.
 %-----------------------------------------------------------------------------%
 
 report_term_errors(SCC, Errors, Module, !IO) :-
+    module_info_get_globals(Module, Globals),
     get_context_from_scc(SCC, Module, Context),
     ( SCC = [PPId] ->
         Pieces1 = [words("Termination of")] ++
@@ -241,18 +242,18 @@ report_term_errors(SCC, Errors, Module, !IO) :-
         % error("empty list of errors")
         Pieces2 = [words("not proven, for unknown reason(s).")],
         list.append(Pieces1, Pieces2, Pieces),
-        write_error_pieces(Context, 0, Pieces, !IO)
+        write_error_pieces(Globals, Context, 0, Pieces, !IO)
     ;
         Errors = [Error],
         Pieces2 = [words("not proven for the following reason:")],
         list.append(Pieces1, Pieces2, Pieces),
-        write_error_pieces(Context, 0, Pieces, !IO),
+        write_error_pieces(Globals, Context, 0, Pieces, !IO),
         output_term_error(Error, Single, no, 0, Module, !IO)
     ;
         Errors = [_, _ | _],
         Pieces2 = [words("not proven for the following reasons:")],
         list.append(Pieces1, Pieces2, Pieces),
-        write_error_pieces(Context, 0, Pieces, !IO),
+        write_error_pieces(Globals, Context, 0, Pieces, !IO),
         output_term_errors(Errors, Single, 1, 0, Module, !IO)
     ).
 
@@ -261,6 +262,7 @@ report_term_errors(SCC, Errors, Module, !IO) :-
     io::di, io::uo) is det.
 
 report_arg_size_errors(SCC, Errors, Module, !IO) :-
+    module_info_get_globals(Module, Globals),
     get_context_from_scc(SCC, Module, Context),
     ( SCC = [PPId] ->
         Pieces1 = [words("Termination constant of")] ++
@@ -280,13 +282,13 @@ report_arg_size_errors(SCC, Errors, Module, !IO) :-
         Errors = [Error],
         Piece3 = words("reason:"),
         list.append(Pieces1, [Piece2, Piece3], Pieces),
-        write_error_pieces(Context, 0, Pieces, !IO),
+        write_error_pieces(Globals, Context, 0, Pieces, !IO),
         output_term_error(Error, Single, no, 0, Module, !IO)
     ;
         Errors = [_, _ | _],
         Piece3 = words("reasons:"),
         list.append(Pieces1, [Piece2, Piece3], Pieces),
-        write_error_pieces(Context, 0, Pieces, !IO),
+        write_error_pieces(Globals, Context, 0, Pieces, !IO),
         output_term_errors(Errors, Single, 1, 0, Module, !IO)
     ).
 
@@ -315,7 +317,8 @@ output_term_error(TermErrorContext, Single, ErrorNum, Indent, Module, !IO) :-
         ErrorNum = no,
         Pieces = Pieces0
     ),
-    write_error_pieces(Context, Indent, Pieces, !IO),
+    module_info_get_globals(Module, Globals),
+    write_error_pieces(Globals, Context, Indent, Pieces, !IO),
     (
         Reason = yes(InfArgSizePPId),
         lookup_proc_arg_size_info(Module, InfArgSizePPId, ArgSize),
diff --git a/doc/user_guide.texi b/doc/user_guide.texi
index d62012f..be80566 100644
--- a/doc/user_guide.texi
+++ b/doc/user_guide.texi
@@ -6965,6 +6965,12 @@ The generated code may be in C (the usual case)
 or in Mercury (with @samp{--convert-to-mercury}).
 
 @sp 1
+ at item --max-error-line-width <n>
+ at findex --max-error-line-width
+Set the maximum width of an error message line to <n> characters
+(unless a long single word forces the line over this limit).
+
+ at sp 1
 @item --show-dependency-graph
 @findex --show-dependency-graph
 Write out the dependency graph to @var{module}.dependency_graph.
diff --git a/tests/invalid/Mercury.options b/tests/invalid/Mercury.options
index 63c8970..1235a3a 100644
--- a/tests/invalid/Mercury.options
+++ b/tests/invalid/Mercury.options
@@ -42,6 +42,8 @@ MCFLAGS-invalid_mllibs =	--no-errorcheck-only --no-verbose-make \
 MCFLAGS-instance_var_bug =      --verbose-error-messages
 MCFLAGS-loopcheck =		--warn-inferred-erroneous \
 				--verbose-error-messages
+MCFLAGS-max_error_line_width =	--max-error-line-width 120 \
+				--verbose-error-messages
 MCFLAGS-method_impl =		--no-intermodule-optimization \
 				--verbose-error-messages
 MCFLAGS-missing_det_decls =	--no-infer-det --verbose-error-messages
diff --git a/tests/invalid/Mmakefile b/tests/invalid/Mmakefile
index 2cafaed..3dcf856 100644
--- a/tests/invalid/Mmakefile
+++ b/tests/invalid/Mmakefile
@@ -135,6 +135,7 @@ SINGLEMODULE= \
 	loopcheck \
 	magicbox \
 	make_opt_error \
+	max_error_line_width \
 	merge_ground_any \
 	method_impl \
 	missing_concrete_instance \
diff --git a/tests/invalid/max_error_line_width.err_exp b/tests/invalid/max_error_line_width.err_exp
new file mode 100644
index 0000000..1480c73
--- /dev/null
+++ b/tests/invalid/max_error_line_width.err_exp
@@ -0,0 +1,53 @@
+max_error_line_width.m:042: In clause for predicate `ambig_overload1'/1:
+max_error_line_width.m:042:   error: excessively ambiguous overloading.
+max_error_line_width.m:042:   This caused the type checker to exceed its limits. It may also make your code difficult to
+max_error_line_width.m:042:   understand.
+max_error_line_width.m:042:   The following symbol was overloaded in the following contexts.
+max_error_line_width.m:040:   The function symbol `f'/0.
+max_error_line_width.m:040:   The possible matches are:
+max_error_line_width.m:040:     the type constructor `max_error_line_width.bar'/0,
+max_error_line_width.m:040:     the type constructor `max_error_line_width.foo'/0,
+max_error_line_width.m:040:     the builtin type constructor `character'.
+max_error_line_width.m:041:   The function symbol `f'/0 is also overloaded here.
+max_error_line_width.m:045: In clause for predicate `ambig_overload2'/1:
+max_error_line_width.m:045:   warning: highly ambiguous overloading.
+max_error_line_width.m:045:   This may cause type-checking to be very slow. It may also make your code difficult to
+max_error_line_width.m:045:   understand.
+max_error_line_width.m:045:   The following symbols were overloaded in the following contexts.
+max_error_line_width.m:045:   The function symbol `a1'/0.
+max_error_line_width.m:045:   The possible matches are:
+max_error_line_width.m:045:     the type constructor `max_error_line_width.baz'/0,
+max_error_line_width.m:045:     the type constructor `max_error_line_width.qux'/0.
+max_error_line_width.m:045:   The function symbol `a2'/0.
+max_error_line_width.m:045:   The possible matches are:
+max_error_line_width.m:045:     the type constructor `max_error_line_width.baz'/0,
+max_error_line_width.m:045:     the type constructor `max_error_line_width.qux'/0.
+max_error_line_width.m:099: In clause for predicate `test_lt'/1:
+max_error_line_width.m:099:   error: excessively ambiguous overloading.
+max_error_line_width.m:099:   This caused the type checker to exceed its limits. It may also make your code difficult to
+max_error_line_width.m:099:   understand.
+max_error_line_width.m:099:   The following symbol was overloaded in the following contexts.
+max_error_line_width.m:050:   The predicate symbol predicate `<'/2.
+max_error_line_width.m:050:   The possible matches are:
+max_error_line_width.m:050:     predicate `int.<'/2,
+max_error_line_width.m:050:     predicate `float.<'/2.
+max_error_line_width.m:051:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:052:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:053:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:054:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:055:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:056:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:057:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:058:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:059:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:060:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:061:   The predicate symbol predicate `<'/2 is also overloaded here.
+max_error_line_width.m:109: In clause for predicate `set_browser_param_from_option_table'/3:
+max_error_line_width.m:109:   warning: highly ambiguous overloading.
+max_error_line_width.m:109:   This may cause type-checking to be very slow. It may also make your code difficult to
+max_error_line_width.m:109:   understand.
+max_error_line_width.m:109:   The following symbol was overloaded in the following context.
+max_error_line_width.m:103:   The function symbol `lookup_bool_option'/2.
+max_error_line_width.m:103:   The possible matches are:
+max_error_line_width.m:103:     predicate `getopt.lookup_bool_option'/3,
+max_error_line_width.m:103:     function `getopt.lookup_bool_option'/2.
diff --git a/tests/invalid/max_error_line_width.m b/tests/invalid/max_error_line_width.m
new file mode 100644
index 0000000..e1d294c
--- /dev/null
+++ b/tests/invalid/max_error_line_width.m
@@ -0,0 +1,116 @@
+:- module max_error_line_width.  % was ambiguous_overloading_error.
+
+:- interface.
+
+:- import_module getopt.
+:- import_module io.
+:- import_module list.
+
+:- type foo ---> f ; g.
+:- type bar ---> f ; h.
+
+:- pred ambig_overload1(list(foo)::out) is det.
+
+:- type baz ---> a1 ; a2 ; a3.
+:- type qux ---> a1 ; a2 ; a4.
+
+:- pred ambig_overload2(list(baz)::out) is det.
+
+:- pred test_lt(int::out) is det.
+
+:- type set_param
+	--->	set_print
+	;	set_browse
+	;	set_print_all
+	;	set_flat
+	;	set_raw_pretty
+	;	set_verbose
+	;	set_pretty.
+
+:- pred set_browser_param_from_option_table(option_table(set_param)::in,
+	io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module bool.
+:- import_module int.
+:- import_module float.
+
+ambig_overload1(L) :-
+	A = f, B = f, C = f, D = f, E = f, F = f,
+	G = f, H = f, I = f, J = f, K = f, L = f,
+	L = [A, B, C, D, E, F, G, H, I, J, K, L].
+
+ambig_overload2(L) :-
+	A = a1, B = a1, C = a2, D = a2, E = a1, F = a1, G = a2,
+	L = [A, B, C, D, E, F, G].
+
+test_lt(X) :-
+	(
+		X1 < Y1,
+		X2 < Y2,
+		X3 < Y3,
+		X4 < Y4,
+		X5 < Y5,
+		X6 < Y6,
+		X7 < Y7,
+		X8 < Y8,
+		X9 < Y9,
+		XA < YA,
+		XB < YB,
+		XC < YC,
+		XD < YD,
+		XE < YE,
+		XF < YF,
+		XG < YG,
+		XH < YH,
+		XI < YI,
+		XJ < YJ,
+		XK < YK,
+		XL < YL,
+		XM < YM,
+		XN < YN,
+		X1 = 1, Y1 = 11,
+		X2 = 2, Y2 = 12,
+		X3 = 3, Y3 = 13,
+		X4 = 4.0, Y4 = 14.0,
+		X5 = 5.0, Y5 = 15.0,
+		X6 = 6.0, Y6 = 16.0,
+		X7 = 7.0, Y7 = 17.0,
+		X8 = 8.0, Y8 = 18.0,
+		X9 = 9.0, Y9 = 19.0,
+		XA = 10.0, YA = 20.0,
+		XB = 11.0, YB = 21.0,
+		XC = 12.0, YC = 22.0,
+		XD = 13.0, YD = 23.0,
+		XE = 14.0, YE = 24.0,
+		XF = 15.0, YF = 25.0,
+		XG = 16.0, YG = 26.0,
+		XH = 17.0, YH = 27.0,
+		XI = 18.0, YI = 28.0,
+		XJ = 19.0, YJ = 29.0,
+		XK = 20.0, YK = 30.0,
+		XL = 21.0, YL = 31.0,
+		XM = 22.0, YM = 32.0,
+		XN = 23.0, YN = 33.0
+	->
+		X = 0
+	;
+		X = 1
+	).
+
+set_browser_param_from_option_table(OptionTable, !IO) :-
+    set_browser_param(
+        lookup_bool_option(OptionTable, set_print),
+        lookup_bool_option(OptionTable, set_browse),
+        lookup_bool_option(OptionTable, set_print_all),
+        lookup_bool_option(OptionTable, set_flat),
+        lookup_bool_option(OptionTable, set_raw_pretty),
+        lookup_bool_option(OptionTable, set_verbose),
+        lookup_bool_option(OptionTable, set_pretty),
+	!IO).
+
+:- pred set_browser_param(bool::in, bool::in, bool::in, bool::in,
+	bool::in, bool::in, bool::in, io::di, io::uo) is det.
+
+set_browser_param(_, _, _, _, _, _, _, !IO).

--------------------------------------------------------------------------
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