Commit Graph

62 Commits

Author SHA1 Message Date
Zoltan Somogyi
bdd2a574a8 Replace conditional_specs with a new severity.
compiler/error_spec.m:
    Delete conditional_spec from the error_spec type, which had
    exactly one use left in the compiler. Replace it with a conditional form
    of severity_error, which handles that use case.

    Rename error_severity to spec_severity, since obviously not all severities
    represent errors.

    For the same reason, rename error_phase to spec_phase.

compiler/error_util.m:
    Export a predicate for write_error_spec.m.

compiler/write_error_spec.m:
    Use that export to delete what used to be duplicate code.

compiler/add_pragma.m:
compiler/check_typeclass.m:
compiler/compiler_util.m:
compiler/error_sort.m:
compiler/mark_tail_calls.m:
compiler/parse_error.m:
compiler/parse_item.m:
    Conform to the changes above.
2025-11-15 10:29:23 +11:00
Zoltan Somogyi
c643291d1f Add cons_list and snoc_list to cord.m.
library/cord.m:
    Add those two new predicates.

NEWS.md:
    Announce the additions.

compiler/*.m:
    Use snoc_list in many places.

tests/hard_coded/test_cord_2.{m,exp}:
    Extend this test case to test cons_list.
2025-10-10 18:48:26 +11:00
Zoltan Somogyi
c53f9ab46e Don't output lines that end with a space.
compiler/write_error_spec.m:
    When error_specs include blank lines, we used to output lines
    of the form "filename:linenumber: ". Stop generating the final space.

compiler/parse_tree_out_misc.m:
    Add a new version of an existing function.

tests/invalid/actual_more_expected.err_exp:
tests/invalid/ambiguous_overloading_error.err_exp:
tests/invalid/any_passed_as_ground.err_exp:
tests/invalid/anys_in_negated_contexts.err_exp:
tests/invalid/bad_ambiguity_msg.err_exp:
tests/invalid/bug150.err_exp:
tests/invalid/bug150_partial_color.err_exp:
tests/invalid/bug496.err_exp:
tests/invalid/det_atomic_goal_msgs.err_exp:
tests/invalid/det_errors.err_exp:
tests/invalid/det_errors_and_io.err_exp:
tests/invalid/det_errors_deep.err_exp:
tests/invalid/ho_default_func_1.err_exp:
tests/invalid/ho_default_func_3.err_exp:
tests/invalid/ho_default_func_4.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/magicbox.err_exp:
tests/invalid/max_error_line_width.err_exp:
tests/invalid/mode_inf.err_exp:
tests/invalid/modes_erroneous.err_exp:
tests/invalid/no_ho_inst.err_exp:
tests/invalid/not_a_switch.err_exp:
tests/invalid/state_vars_test_1.err_exp:
tests/invalid/try_detism.err_exp:
tests/invalid/user_field_access_decl_override_1.err_exp:
tests/invalid_nodepend/errors_2.err_exp:
tests/warnings/ambiguous_overloading.err_exp:
tests/warnings/inconsistent_pred_order.err_exp:
tests/warnings/subtype_order.err_exp:
tests/warnings/test_tscp.err_exp:
    Stop expecting a final space.
2025-09-15 06:28:07 +10:00
Zoltan Somogyi
823de2d37b Require warning/info messages to specify an option.
The objective of this step is two-fold:

- to fix --inhibit-warnings, making it shut up all warning
  and informational messages; and

- to ensure that it *stays* fixed, even when after new diagnostics
  are added.

As part of this fix, this diff adds a whole bunch of new warning
options, in order to control the warnings that previously were
not controlled by any option. (There was no need for new
informational options.)

As it happens, we have long used severity_informational for messages
that did not report any information about the code being compiled,
but to report actions that the compiler was taking. Create a new
option category, oc_report, for the new options that now control
those diagnostics.

---------------------

compiler/error_spec.m:
    Change severity_warning and severity_informational to take an option
    as as argument. The semantics is that the diagnostic in which
    the severity occurs is conditional on that option, meaning that
    it is printed only if that option is set to "yes".

    Delete the severity_conditional function symbol from the severity
    type, since the mechanism just above handles its only use case.

    Define subtypes to represent error_specs in a standard form.

compiler/error_sort.m:
    Provide operations to convert error specs into their standard form.

    Make the sorting operation itself operate on the standard form.

compiler/write_error_spec.m:
    Convert error_specs to standard form before writing them out,
    in order to avoid duplicating the code for their standardization.

    Change the code that writes out error_specs to operate on the
    standard form. Implement the test implicit in the warning and
    and informational severities in this code.

compiler/error_util.m:
compiler/compiler_util.m:
    Delete operations that do not make sense with the new severity type.

---------------------

compiler/options.m:
    Add new options to control all the previously-uncontrolled
    warning and informational messages.

NEWS.md:
    Announce the *public* new options.

compiler/option_categories.m:
compiler/print_help.m:
    Add the new option category, and fake-include it in the help text
    and the user guide. (The inclusion is fake because none of the
    options in the new category are user visible, meaning the section
    containing them is not visible either.)

---------------------

compiler/det_infer_goal.m:
    Start a severity warning diagnostic with "Warning:"
    instead of "Error:".

compiler/mark_trace_goals.m:
    Fix an incorrect error message.

compiler/purity.m:
    Replace a correct/incorrect color pair with two inconsistent colors,
    because there is a reasonable probability of each one being right.

---------------------

compiler/accumulator.m:
compiler/add_clause.m:
compiler/add_mode.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/check_module_interface.m:
compiler/check_type_inst_mode_defns.m:
compiler/check_typeclass.m:
compiler/color_schemes.m:
compiler/common.m:
compiler/convert_import_use.m:
compiler/convert_parse_tree.m:
compiler/dead_proc_elim.m:
compiler/det_check_proc.m:
compiler/det_check_switch.m:
compiler/det_infer_goal.m:
compiler/du_type_layout.m:
compiler/format_call_errors.m:
compiler/grab_modules.m:
compiler/hlds_call_tree.m:
compiler/inst_check.m:
compiler/introduce_parallelism.m:
compiler/make_hlds_error.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/mark_trace_goals.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_make_hlds.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/opt_deps_spec.m:
compiler/options_file.m:
compiler/parse_goal.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/pre_typecheck.m:
compiler/purity.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/split_parse_tree_src.m:
compiler/state_var.m:
compiler/stratify.m:
compiler/style_checks.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
compiler/termination.m:
compiler/typecheck_clauses.m:
compiler/typecheck_error_overload.m:
compiler/typecheck_error_undef.m:
compiler/typecheck_errors.m:
compiler/typecheck_msgs.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/warn_unread_modules.m:
compiler/write_module_interface_files.m:
    Conform to the changes above, mostly by either

    - adding an option to all warning and informational messages,
      sometimes using existing warning options and sometimes new ones,
      or

    - turning already explicitly-conditional-on-an-option messages
      into implicitly-conditional-on-that-option messages.

---------------------

tests/invalid/one_member.m:
    Conform to the change in det_infer_goal.m.

tests/invalid/require_tailrec_1.err_exp:
tests/invalid/require_tailrec_2.err_exp:
    Actually obey the options for these modules in Mercury.options.

tests/invalid_purity/purity.err_exp:
tests/warnings/purity_warnings.err_exp:
    Conform to the change in purity.m.

tests/warnings/moved_trace_goal.err_exp:
    Conform to the change in mark_trace_goals.m.

tests/warnings/help_text.err_exp:
    Expect the documentation of all the new options.
2025-08-18 12:07:38 +02:00
Zoltan Somogyi
f70b5d6de7 Implement options to warn about unused state vars.
The new --warn-unneeded-initial-statevar option asks the compiler
to warn about code such as

    pred_a(!.X, ...) :-
        ... code that uses !.X, but does not update it ...

In this case, the preferred fix is to just replace all occurrences
of !.X with X.

The new --warn-unneeded-final-statevar option asks the compiler
to warn about code such as

    pred_a(!X, ...) :-
        ... code that maybe uses !.X, but does not update it ...

In this case, the preferred fix also involves replacing all occurrences
of !.X with X, but it also involves either deleting the argument
containing !:X (the best option), or, if there is some reason why
the predicate's signature must stay unchanged, to replace !:X with X as well.
And if the clause body does not actually refer to either !.X or !:X, then
*both* arguments represented by !X should be deleted.

The first option is a style warning; the second option, due to the
signature change it may call for, is a non-style warning.

Both options have a version whose name adds a "-lambda" suffix, and which
does the same warnings for the heads of lambda expressions, not clauses.

Note that several of the modules below, including some that help to implement
the warnings, also contain code changes that result from *acting* on
the new warnings, e.g. by deleting unneeded statevar arguments.
Other, similar changes will also come after this diff is committed.

compiler/options.m:
doc/user_guide.texi:
    Document the new options.

compiler/state_var.m:
    Gather the information needed to decide what code merits the new warnings.
    Do so in three stages:

    - when processing the head of a clause or of a lambda expression,
    - when processing the body goal of that clause or lambda expression,
    - when finishing up the processing of the clause or lambda expression.

    Add a predicate to generate the warnings for lambda expressions.

    Do not generate the warnings for clauses. This is because whether or not
    we want to warn about state vars in some clauses depends on the properties
    of *other* clauses of the same predicate, and state_var.m has access
    to only one clause at a time. Instead,

    - return the info needed by the warning-generating code in pre_typecheck.m
      (one of the first passes we execute after adding all clauses
      to the HLDS), and

    - we export some functionality for use by that code.

    Switch to a convention for naming the program variables corresponding
    to the middle (non-initial, non-final) versions of state variables
    whose output is affected by changes in the code of the clause body goal
    only if they involve that specific state variable.

    Give some predicates more descriptive names.

compiler/make_hlds.m:
    Make state_var.m and its new functionality visible from outside
    the make_hlds package.

compiler/add_clause.m:
    Record the information gathered by state_var.m in each clause.

compiler/hlds_clauses.m:
    Add a slot to each clause for this information.

    Give some predicates more descriptive names.

compiler/headvar_names.m:
    Use the contents of the new slots to detect whether any clauses
    have unused state vars, and if so, return the chosen consensus names
    of the head vars to the code of pre_typecheck.m, which uses this info
    as part of the implementation of the new warnings.

compiler/pre_typecheck.m:
    Implement the new warnings.

compiler/mercury_compile_front_end.m:
    Record the warnings that pre_typecheck.m can now return.

compiler/error_spec.m:
compiler/write_error_spec.m:
    Add unsigned versions of the format pieces involving ints, for use
    by the new code in pre_typecheck.m, and implement them.

compiler/hlds_out_util.m:
compiler/maybe_util.m:
    Move two related types from hlds_out_util.m to maybe_util.m,
    in order to allow pre_typecheck.m to use one of them.

compiler/hlds_args.m:
    Add a new utility function for use by the new code above.

compiler/foreign.m:
    Act on the new warnings by deleting the long-unused predicates
    being warned about.

compiler/post_typecheck.m:
    Speed up this traversal. (I originally thought to implement
    the new warnings in this pass.)

compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/build_mode_constraints.m:
compiler/call_gen.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
compiler/code_loc_dep.m:
compiler/delay_info.m:
compiler/delay_partial_inst.m:
compiler/dense_switch.m:
compiler/det_check_goal.m:
compiler/det_infer_goal.m:
compiler/disj_gen.m:
compiler/du_type_layout.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_out_pred.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/inst_merge.m:
compiler/instance_method_clauses.m:
compiler/intermod.m:
compiler/interval.m:
compiler/ite_gen.m:
compiler/lookup_switch.m:
compiler/make_hlds_passes.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mode_errors.m:
compiler/parse_string_format.m:
compiler/passes_aux.m:
compiler/polymorphism.m:
compiler/polymorphism_info.m:
compiler/polymorphism_type_info.m:
compiler/pragma_c_gen.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/quantification.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/string_switch.m:
compiler/superhomogeneous.m:
compiler/switch_gen.m:
compiler/tag_switch.m:
compiler/type_constraints.m:
compiler/typecheck.m:
compiler/typecheck_clauses.m:
compiler/typecheck_coerce.m:
compiler/typecheck_error_unify.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_proc.m:
compiler/var_origins.m:
    Conform to the changes above, and/or act on the new warnings.

browser/diff.m:
library/bit_buffer.m:
library/getopt.m:
library/getopt_io.m:
library/io.error_util.m:
library/io.file.m:
library/mercury_term_lexer.m:
library/parsing_utils.m:
library/pretty_printer.m:
library/robdd.m:
library/rtti_implementation.m:
library/string.builder.m:
library/string.parse_runtime.m:
mdbcomp/feedback.m:
    Act on the new warnings.

tests/hard_coded/sv_nested_closures.m:
    Change this test's code to avoid the new warnings, since
    (if --halt-at-warn is ever enabled) the warnings would interfere
    with its job .

tests/invalid/bug197.err_exp:
tests/invalid/bug487.err_exp:
tests/invalid/nullary_ho_func_error.err_exp:
tests/invalid/try_detism.err_exp:
tests/warnings/singleton_test_state_var.err_exp:
    Expect variable names for the middle versions of state vars
    using the new naming scheme.
2025-05-18 06:43:24 +10:00
Zoltan Somogyi
1533f86811 Simplify a predicate, and add some comments. 2025-03-14 02:24:09 +11:00
Zoltan Somogyi
59cdbaafd8 Move a predicate to its natural home.
compiler/hlds_error_util.m:
    Move the maybe_write_out_errors predicate from hlds_error_util.m
    to write_error_spec.m.

    Delete the definitely_write_out_errors predicate, because (a) it is
    currently unused, and (b) its definition is so trivial that
    it won't be needed again.

compiler/write_error_spec.m:
    Add the moved predicate. Update its documentation.

    Delete the pre_hlds_maybe_write_out_errors predicate that was
    already here, because its definition was identical to that of the
    moved predicate, and is very likely to remain so from now on.

compiler/grab_modules.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_make_hlds.m:
compiler/mercury_compile_middle_passes.m:
    Conform to the changes above.
2025-01-10 18:29:01 +11:00
Julien Fischer
a5fdde0ae2 Update and fix more copyright notices.
compiler/*.m:
    As above.
2024-12-30 17:03:37 +11:00
Zoltan Somogyi
702ede3f8b Carve color_schemes.m out of globals.m.
compiler/color_schemes.m:
compiler/globals.m:
    As above.

    In globals.m, delete some obsolete comments.

compiler/libs.m:
compiler/notes/compiler_design.html:
    Include and document the new module.

compiler/handle_options.m:
compiler/write_error_spec.m:
    Conform to the changes above.
2024-12-04 04:30:26 +11:00
Zoltan Somogyi
407525af59 Describe calls using not strings, but pieces.
compiler/hlds_out_util.m:
    Make the functions that describe calls return format_pieces instead of
    strings, and rename them accordingly.

compiler/det_report.m:
compiler/mode_errors.m:
compiler/typecheck_error_util.m:
    Use the returned pieces.

compiler/error_spec.m:
    Add a new format_piece, upper_case_next, for use in one of the modules
    above.

compiler/write_error_spec.m:
    Implement the new format_piece, by generalizing
    lower_case_next_if_not_first.
2024-11-01 16:46:28 +11:00
Zoltan Somogyi
07109943df Better diagnostics for "no matching mode" errors.
compiler/mode_errors.m:
    Completely rewrite the code that generates diagnostics for
    calls to predicates and functions where the insts of the arguments
    in the caller don't meet the requirements of any of the modes
    of the callee.

    The old code printed

    - a list of the arguments in the call together with their insts, and
    - a list of the arguments that do not match *any* of the modes.

    This was both too much and too little. It was too much in that
    arguments that match the initial inst requirements of all the modes
    cannot possibly be the cause of the mode error, so including
    their inst in the output adds only clutter. In was too little
    in that it did not identify arguments that failed to match
    the requirements of some modes while matching others.

    The new code prints the names of all the arguments, but

    - it prints the insts of only the arguments that fail to match
      the requirements of at one least mode, and
    - for each such argument, it specifies *which* modes of the callee
      its inst is incompatible with.

    An unrelated change: use lagged iteration to format lists of insts.

compiler/modecheck_util.m:
    Fix an old issue that wasn't a problem until now: when reporting
    a "no matching mode" error, include the mode that wasn't matched
    in the representation of the error. (The old code did not assume
    the presence of at least one mode, but the new one does.)

    Add an XXX about a desirable improvement, and make the first step
    towards implementing it.

compiler/modecheck_call.m:
    Fix comment rot.

compiler/write_error_spec.m:
    Fix an old bug that affected the updated output for one of the
    changed .err_exp files below. The bug was that when a word is
    followed by a color change, we assumed that it is ok to break the line
    after the color change. When e.g. some text wrapped up in a color
    is followed by a suffix, this assumption is false.

    The fix is to include the last word before the color change
    on the current line only if there is also room on the line
    for any following suffix.

    Document an invariant.

compiler/inst_mode_type_prop.m:
    Fix a typo in an error message.

tests/invalid/any_passed_as_ground.err_exp:
tests/invalid/constrained_poly_insts_2.err_exp:
tests/invalid/ho_default_func_1.err_exp:
tests/invalid/ho_default_func_3.err_exp:
tests/invalid/ho_default_func_4.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/state_vars_test_1.err_exp:
tests/invalid/try_detism.err_exp:
    Expect the updated diagnostics.
2024-10-27 21:53:38 +11:00
Zoltan Somogyi
454a9e2d84 Make --print-error-spec-id apply to extracted msgs.
When e.g. mode analysis prints a diagnostic for a mode error,
it does so by taking an error_spec generated for the *actual* error,
extracing the error_msgs from it, and wrapping a new error_spec around them.
This has meant that if you specify --print-error-spec-id, you get the
id of the predicate that does the wrapping, NOT the id of the predicate
that generated the message describing the actual error.

This diff fixes this.

compiler/error_spec.m:
    Make the predicates that extract error_msgs from error_specs
    also return the error_spec's id.

    Add a version of those predicates that adds a final error_msg
    to the extracted error_msgs that includes this id at the end
    of the message, if --print-error-spec-id is specified.

    To do that, move here the code from write_error_spec.m that
    has always done this job for --print-error-spec-id, and wrap
    an (exported) predicate around it.

compiler/write_error_spec.m:
    Replace the moved code with that predicate.

compiler/mode_errors.m:
compiler/recompilation.check.m:
    Include the id in any extracted error_msgs if asked for.

compiler/error_sort.m:
    Ignore extracted ids.
2024-10-25 16:18:17 +11:00
Zoltan Somogyi
c7a72fee02 Add a blank before "possible reason" messages.
Mode analysis and determinism analysis can generate error_specs that
have long had the form:

    context1:   There was a problem with X. The following messages give
    context1:    possible reasons for this problem.
    context2:   Possible reason 1.
    context3:   Possible reason 2.

This diff adds a line containing only a context before every reason, yielding
this modified output:

    context1:   There was a problem with X. The following messages give
    context1:    possible reasons for this problem.
    context2:
    context2:   Possible reason 1.
    context3:
    context3:   Possible reason 2.

The new layout makes it significantly easier for readers to find
where each reason's description begins, especially when a single reason's
description itself takes several lines.

compiler/error_spec.m:
    Add a new kind of error_msg for the new lines, which are blank
    except possibly (usually) for a context.

    Move a utility predicate here from error_sort.m, to make it available
    to error_util.m.

compiler/error_util.m:
    Add a predicate that prefaces each reason's error_msg with the new
    blank line error_msg.

compiler/write_error_spec.m:
    Implement the new kind of error_msg.

compiler/det_report.m:
compiler/mode_errors.m:
    Use the new capability in the error_specs that list possible reasons
    for a problem.

compiler/error_sort.m:
    Conform to the changes above.

    Delete a predicate moved to error_spec.

tests/invalid/bug150.err_exp:
tests/invalid/bug150_partial_color.err_exp:
tests/invalid/bug496.err_exp:
tests/invalid/det_atomic_goal_msgs.err_exp:
tests/invalid/det_errors.err_exp:
tests/invalid/det_errors_and_io.err_exp:
tests/invalid/det_errors_deep.err_exp:
tests/invalid/magicbox.err_exp:
tests/invalid/mode_inf.err_exp:
tests/invalid/not_a_switch.err_exp:
tests/invalid/try_detism.err_exp:
tests/invalid/user_field_access_decl_override_1.err_exp:
    Expect updated diagnostics.
2024-10-01 13:34:26 +02:00
Zoltan Somogyi
d25d99d6dd Sort imports. 2024-08-01 15:29:44 +02:00
Zoltan Somogyi
7a9464551d Clarify a comment. 2024-07-15 15:51:05 +02:00
Zoltan Somogyi
0e2997dc1e Enable, document and announce color diagnostics.
compiler/options.m:
    Make --color-diagnostics enabled by default.

    Add a synonym for the --color-scheme option that uses British spelling.
    (We already had such a synonym for --color-diagnostics.)

    Document the user-visible options controlling colors in diagnostics.

    Delete old, now-superseded commented-out documentation.

doc/user_guide.texi:
    Document the user-visible options and environment variables
    controlling colors in diagnostics.

    Add a new chapter that explains in some detail not only the use of color
    in diagnostics, but also the effects of the --verbose-error-messages,
    --reverse-error-order and --limit-error-contexts options.

    Delete old, now-superseded commented-out documentation.

NEWS.md:
    Announce the compiler's new capabilities.

The rest of this diff is concerned with fixing an old issue with
--limit-error-contexts, which is that it operated on error_msgs.
If an error_spec contained two or more error_msgs, the compiler
could print some error_msgs whose contexts fell into one of the to-be-printed
ranges of line numbers, while NOT printing some other error_msgs whose
contexts did not do so. Since the wording of a non-first error_msg
often builds upon and references the wording of previous error_msgs
in the same error_spec, this was a problem. This diff changes things
so that if *any* error_msg in an error_spec has a context that falls into
one of the to-be-printed ranges of line numbers, we print *all* of the
error_msgs in that error_spec.

compiler/write_error_spec.m:
    To make the above possible, separate out the task of deciding which parts
    of error_specs to print, and which parts not to print, from the task
    of actually writing them out. The decision part takes into account
    the conditional-on-verbosity-level and conditional-on-an-option-value
    parts of error_msgs, as well as the effect of --limit-error-contexts.

    Construct the color database and look up the max line width exactly once
    for each call to the exported predicates of this module.

compiler/error_spec.m:
    Delete the print_anything function symbol from the error_msg_component
    type. Its presence would have made the separation of making-decisions code
    from writing-out code in write_error_spec.m more complicated. Since
    the stuff it prints is not a list of pieces, handling it would have
    required using a data structure containing either lists of (either pieces
    or anythings) to communicate between the decision code and the writing
    code. While this is doable, it is not elegant, and it turns out to be
    far simpler to just eliminate print_anything.

    Take the opportunity to change the type of the extra indent field
    in error_msgs from int to uint.

compiler/mode_errors.m:
    Replace the only use of print_anything in the compiler with code
    that just uses lists of pieces. (This is possible now due to the
    rewrite of write_goal in terms of format_goal, which happened many years
    *after* we implemented print_anything specifically for this use case.)

compiler/accumulator.m:
    Fix the only place in the compiler that actually depended on the
    implicit newline we used to add between consecutive error_msgs in an
    error_spec (at least according to our test suite). Everywhere else,
    we routine end every error_msg with an *explicit* nl piece, and now
    we do so here as well.

    Simplify the code constructing the one error_spec here by replacing
    several conditional-on-an-option-value error_messages with a simple
    test of that option, since its value is trivially available here.
    (Two components of that error_spec *should* have been conditional
    on the same option but were not, so this is a bug fix as well.)

    Rename some predicates to avoid ambiguity.

compiler/check_typeclass.m:
compiler/common.m:
compiler/error_sort.m:
compiler/error_util.m:
compiler/fact_table.m:
compiler/mercury_compile_main.m:
compiler/options_file.m:
compiler/parse_module.m:
compiler/post_typecheck.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
    Conform to the int->uint change in error_spec.m.
2024-06-23 14:37:27 +10:00
Zoltan Somogyi
ae38bb3ebf Add support for 24 bit color.
compiler/globals.m:
    Expand the representation of colors to include 24 bit color.

    Expand the syntax of color specifications to allow strings of the form
    #RRGGBB to specify 24 bit colors.

    Factor out common code in report syntax errors in color specifications.

compiler/write_error_spec.m:
    Output the appropriate SGR escape codes when switching to a 24 bit color.

tests/invalid/bug150_bad_color.err_exp:
    Expect an updated diagnostic.
2024-06-12 00:31:49 +10:00
Zoltan Somogyi
d9f1a99823 Print a message if we find color scheme errors.
compiler/globals.m:
    If we find errors in a color scheme specification, record a message
    reporting that error in a mutable in write_error_spec.m.

    Update the colors in used in the 16 bit light and dark color schemes
    to the ones proposed by Peter.

compiler/write_error_spec.m:
    Change the operation the maybe_print_delayed_error_message predicate,
    which we invoke when we finish dealing with a module, to print any
    diagnostics recorded by globals.m about malformed color scheme
    specifications, but only if we actually printed at least one message
    that could have been affected by such problems.

compiler/handle_options.m:
    Conform to the change in globals.m.
2024-06-08 04:43:27 +10:00
Zoltan Somogyi
2526c4b8cb Split possible_cause into hint and inconsistent.
compiler/error_spec.m:
    Replace the possible_cause color name with the hint and inconsistent
    color names, as agreed on m-rev.

compiler/globals.m:
compiler/write_error_spec.m:
    Update the code handling color names and their mapping to color shades.

compiler/options.m:
    Update the invisible options that record that mapping.

tools/bootcheck:
    Update the color scheme used for the test suite.

compiler/accumulator.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/equiv_type.m:
compiler/format_call_errors.m:
compiler/inst_check.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_warn.m:
compiler/mode_errors.m:
compiler/module_qual.qual_errors.m:
compiler/parse_item.m:
compiler/parse_mutable.m:
compiler/parse_pragma.m:
compiler/parse_type_defn.m:
compiler/post_typecheck.m:
compiler/simplify_goal_call.m:
compiler/simplify_proc.m:
compiler/split_parse_tree_src.m:
compiler/state_var.m:
compiler/termination.m:
compiler/typecheck_error_overload.m:
compiler/typecheck_error_undef.m:
compiler/typecheck_errors.m:
    Replace uses of the possible_cause color with one of its replacements.
    In a few cases, adjust some other colors as well.

tests/invalid/bad_statevar_bad_context.err_exp:
tests/invalid/bind_in_negated.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/bug487.err_exp:
tests/invalid/coerce_disambig.err_exp:
tests/invalid/coerce_implied_mode.err_exp:
tests/invalid/coerce_infer.err_exp:
tests/invalid/coerce_non_du.err_exp:
tests/invalid/coerce_type_error.err_exp:
tests/invalid/coerce_unify_tvars.err_exp:
tests/invalid/conflicting_tabling_pragmas.err_exp:
tests/invalid/dcg_context.err_exp:
tests/invalid/default_ho_inst_2.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/freefree.err_exp:
tests/invalid/functor_ho_inst_bad_1.err_exp:
tests/invalid/functor_ho_inst_bad_3.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/merge_inst_error.err_exp:
tests/invalid/mode_inf.err_exp:
tests/invalid/modes_erroneous.err_exp:
tests/invalid/multimode_dcg.err_exp:
tests/invalid/partial_implied_mode.err_exp:
tests/invalid/quant_constraint_1.err_exp:
tests/invalid/quant_constraint_2.err_exp:
tests/invalid/string_format_bad.err_exp:
tests/invalid/string_format_unknown.err_exp:
tests/invalid/test_may_duplicate.err_exp:
tests/invalid/test_may_export_body.err_exp:
tests/invalid/type_diff.err_exp:
tests/invalid/typeclass_dup_method_mode.err_exp:
tests/invalid_make_int/bad_mutable_int.int_err_exp:
tests/invalid_nodepend/duplicate_modes.err_exp:
tests/invalid_nodepend/errors_2.err_exp:
tests/invalid_nodepend/occurs.err_exp:
tests/invalid_nodepend/require_tailrec_invalid.err_exp:
tests/invalid_nodepend/test_with_type.err_exp:
tests/invalid_nodepend/unbound_type_vars.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense_1.err_exp:
tests/invalid_purity/purity_nonsense_2.err_exp:
tests/warnings/foreign_term_invalid.err_exp:
tests/warnings/format_call_multi.err_exp:
tests/warnings/format_call_warning.err_exp:
tests/warnings/table_with_inline.err_exp:
tests/warnings/warn_succ_ind.err_exp:
tests/warnings/warn_succ_ind.err_exp2:
tests/warnings/warn_succ_ind.err_exp3:
    Expect updated diagnostics.
2024-06-07 08:42:26 +10:00
Zoltan Somogyi
7501c52c8b Allow some colors to be left unspecified.
compiler/globals.m:
    When a @specified color scheme leaves some colors unspecified,
    do not generate an error; generate an informational message instead.
    Change the data structure we use to record color schemes to accommodate
    this fact.

compiler/options.m:
    Add the option on which the new informational message is conditional.
    Do not document it yet.

compiler/handle_options.m:
    Ignore those informational messages for now.

compiler/error_spec.m:
    When coloring a list of pieces, record the color in the piece
    that marks the end of the list, as well as in the start,
    since new code in write_error_spec.m now needs this.

compiler/write_error_spec.m:
    When processing a piece that marks either the start or the end
    of a colored region, ignore the piece of the color role named
    in that piece has no assigned color. This leaves all the pieces
    in between with the same color as the pieces on the two sides
    of the to-be-ostensibly-colored region.
2024-06-07 00:58:14 +10:00
Zoltan Somogyi
b3c6950cf4 Add draft support for color schemes.
compiler/write_error_spec.m:
    Delete the code that fills in the default colors for each role.

compiler/globals.m:
    Move that code here, into the implementation of
    convert_color_spec_options, which is the function that
    write_error_spec.m uses to set up the color database it uses
    by looking up the right options in the option_table.

    The main part of this diff is the addition of a new predicate,
    record_color_scheme_in_options, whose job is to *set up* those
    options.

    It does so by allowing the user to specify a *color scheme*,
    which may be a builtin scheme (of which we now support four,
    {dark,light}{16,256}), or a scheme that the user specifies directly
    using a string of the form

        specified@subject=C:correct=C:incorrect=C:possible_cause:C

    where each C is either a color name, or an SGR color number in 0..255.
    (And possibly something like rgb-R-G-B later.)

    There is also the pseudo-color-scheme named none, which is not a
    color scheme at all, but rather a way to turn off all use of color.

compiler/handle_options.m:
    Add code to allow the user to specify a color scheme using either

    - a new maybe_string option named --color-scheme, or
    - an environment variable named MERCURY_COLOR_SCHEME.

    Also add code to allow an environment variable named NO_COLOR
    to turn off the use of color regardless of any other color settings.

    Add a mechanism to avoid getting stuck in an infinite loop
    in the presence of errors in the values of environment variables
    that we use to set up the first globals structure.

compiler/options.m:
    Add the options needed by the new code in handle_options.m.
    Some are not yet documented, the rest are intended never to be documented,
    so there is no corresponding change to doc/user_guidet.texi (yet).

tools/bootcheck:
    Set the MERCURY_COLOR_SCHEME environment variable to specify
    the colors now in .err_exp files.
2024-06-06 10:15:17 +10:00
Zoltan Somogyi
8bedb6b189 Use color in add_pragma_tabling.m.
compiler/add_pragma_tabling.m:
    Add color to the diagnostics in this module, and improve their wording.

compiler/write_error_spec.m:
    Add a way to catch redundant spaces at the start and the end of
    strings that are to be formatted as words.

compiler/parse_pragma_foreign.m:
compiler/post_typecheck.m:
    Fix two such redundant spaces.

tests/invalid/conflicting_tabling_pragmas.err_exp:
tests/invalid/pragma_qual_error.err_exp:
tests/invalid_nodepend/specified.err_exp:
tests/warnings/table_with_inline.err_exp:
    Expect updated diagnostics.
2024-05-28 03:37:22 +10:00
Zoltan Somogyi
0e1e909f80 More minor updates to diagnostics.
compiler/det_analysis.m:
compiler/post_typecheck.m:
compiler/typecheck_errors.m:
    Use color more sparingly. Improve wording.

compiler/error_spec.m:
    Add two new utility functions for coloring lists of items, and
    add a new kind of piece, purity_desc_article. Both are for use by
    new code in the modules above.

compiler/write_error_spec.m:
    Implement the new kind of piece.

tests/invalid/arg_permutation.err_exp:
tests/invalid/arith_wrong_module.err_exp:
tests/invalid/bad_sv_unify_msg.err_exp:
tests/invalid/bug184.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/bug214.err_exp:
tests/invalid/bug257.err_exp:
tests/invalid/coerce_void.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/freefree.err_exp:
tests/invalid/getopt_old.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid/integral_constant_no_suffix.err_exp:
tests/invalid/one_member.err_exp:
tests/invalid/pragma_c_code_no_det.err_exp:
tests/invalid/type_diff.err_exp:
tests/invalid/typeclass_test_8.err_exp:
tests/invalid/unsatisfiable_constraint.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense_1.err_exp:
tests/invalid_purity/purity_nonsense_2.err_exp:
tests/warnings/singleton_test.err_exp:
    Expect updated diagnostics.
2024-05-21 23:40:31 +10:00
Zoltan Somogyi
a16cd8c725 Replace three pred_or_func_to_* functions with two.
mdbcomp/prim_data.m:
    Delete the pred_or_func_to_string function that used to be defined here,
    and replace it with pred_or_func_to_str and pred_or_func_to_full_str
    that used to be in parse_tree_out_misc.m. These two names make it
    clear which one returns "pred" or "func", and which returns "predicate"
    or "function".

compiler/parse_tree_out_misc.m:
    Delete the functions moved to prim_data.m.

compiler/add_clause.m:
compiler/add_pred.m:
compiler/hlds_desc.m:
compiler/hlds_out_typeclass_table.m:
compiler/hlds_out_util.m:
compiler/make_hlds_error.m:
compiler/mlds_to_target_util.m:
compiler/mode_errors.m:
compiler/module_qual.qual_errors.m:
compiler/optimize.m:
compiler/parse_tree_out_sym_name.m:
compiler/polymorphism_lambda.m:
compiler/pred_name.m:
compiler/pred_table.m:
compiler/prog_type_test.m:
compiler/recompilation.check.m:
compiler/recompilation.used_file.m:
compiler/style_checks.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/write_error_spec.m:
    Conform to the changes above, mostly by not importing
    parse_tree_out_misc.m.
2024-05-12 15:41:09 +10:00
Zoltan Somogyi
75dc210ab3 Color subjects in mode errors.
compiler/mode_errors.m:
    Use color to emphasize the subject variables and terms of mode errors.

    Use color to emphasize disagreements as possible causes
    in a few more places.

    Require reporters of the "no matching mode" error to specify
    what the match was against. This is to allow us to generate
    better diagnostics. Note the things that should still be improved.

    Use the names of numbers (as in two, three etc) instead of their numeral
    versions.

    Improve the wording and/or the punctuation of some error messages.

compiler/inst_mode_type_prop.m:
    Use the names of numbers (as in two, three etc) instead of their numeral
    versions.

compiler/error_spec.m:
compiler/write_error_spec.m:
    Move two formerly private utility functions of write_error_spec.m
    to error_spec.m, and export them. One of them is now used in
    the modules above.

compiler/modecheck_call.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/unique_modes.m:
    Pass around info about "what the match was against" for the change
    in mode_errors.m descrived above.

compiler/hlds_out_util.m:
    Improve variable name.

compiler/hlds_module.m:
    Add an XXX.

tests/invalid/any_mode.err_exp:
tests/invalid/any_passed_as_ground.err_exp:
tests/invalid/any_should_not_match_bound.err_exp:
tests/invalid/any_to_ground_in_ite_cond.err_exp:
tests/invalid/any_to_ground_in_ite_cond_nomax.err_exp:
tests/invalid/anys_in_negated_contexts.err_exp:
tests/invalid/bad_sv_unify_msg.err_exp:
tests/invalid/bind_in_negated.err_exp:
tests/invalid/bind_var_errors.err_exp:
tests/invalid/bug117.err_exp:
tests/invalid/bug191.err_exp:
tests/invalid/bug278.err_exp:
tests/invalid/bug415.err_exp:
tests/invalid/bug487.err_exp:
tests/invalid/char_inst.err_exp:
tests/invalid/coerce_clobbered.err_exp:
tests/invalid/coerce_disambig.err_exp:
tests/invalid/coerce_implied_mode.err_exp:
tests/invalid/coerce_instvar.err_exp:
tests/invalid/coerce_int.err_exp:
tests/invalid/coerce_mode_error.err_exp:
tests/invalid/coerce_mode_error2.err_exp:
tests/invalid/coerce_recursive_inst.err_exp:
tests/invalid/coerce_recursive_type.err_exp:
tests/invalid/coerce_uniq.err_exp:
tests/invalid/constrained_poly_insts2.err_exp:
tests/invalid/currying_multimode_func.err_exp:
tests/invalid/dcg_context.err_exp:
tests/invalid/default_ho_inst.err_exp:
tests/invalid/default_ho_inst_2.err_exp:
tests/invalid/freefree.err_exp:
tests/invalid/functor_ho_inst_bad.err_exp:
tests/invalid/functor_ho_inst_bad_2.err_exp:
tests/invalid/functor_ho_inst_bad_3.err_exp:
tests/invalid/ho_any_inst.err_exp:
tests/invalid/ho_default_func_1.err_exp:
tests/invalid/ho_default_func_2.err_exp:
tests/invalid/ho_default_func_3.err_exp:
tests/invalid/ho_default_func_4.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/ho_unique_error.err_exp:
tests/invalid/html.err_exp:
tests/invalid/inst_matches_final_bug.err_exp:
tests/invalid/invalid_integral_call_inst.err_exp:
tests/invalid/io_in_ite_cond.err_exp:
tests/invalid/merge_ground_any.err_exp:
tests/invalid/merge_inst_error.err_exp:
tests/invalid/mode_error_arg_number.err_exp:
tests/invalid/mode_inf.err_exp:
tests/invalid/modes_erroneous.err_exp:
tests/invalid/mostly_uniq1.err_exp:
tests/invalid/mostly_uniq2.err_exp:
tests/invalid/multimode_dcg.err_exp:
tests/invalid/no_ho_inst.err_exp:
tests/invalid/partial_implied_mode.err_exp:
tests/invalid/polymorphic_unification.err_exp:
tests/invalid/state_vars_test1.err_exp:
tests/invalid/state_vars_test5.err_exp:
tests/invalid/try_detism.err_exp:
tests/invalid/unify_mode_error.err_exp:
tests/invalid/uniq_modes.err_exp:
tests/invalid/uniq_neg.err_exp:
tests/invalid_nodepend/constrained_poly_insts.err_exp:
tests/invalid_nodepend/occurs.err_exp:
tests/invalid_purity/impure_func_t5_fixed.err_exp:
tests/invalid_purity/purity.err_exp:
tests/warnings/simple_code.err_exp:
tests/warnings/unify_f_g.err_exp:
    Expect the updated versions of diagnostics.
2024-05-07 10:11:11 +10:00
Zoltan Somogyi
2fef92cfa8 Color the subjects of error messages.
compiler/error_spec.m:
    Add a new color name, color_subject, which is intended to be used
    as the color for the subject of an error message. The subject is
    usually a variable or a term.

compiler/options.m:
doc/user_guide.texi:
    Add an option to control the actual color for this color name.

compiler/globals.m:
    Include the new color in the color specification database.

compiler/write_error_spec.m:
    Handle the conversion of the new color name to the selected
    corresponding actual color.

compiler/typecheck_errors.m:
    Color the subjects of (most of) the error messages generated by
    this module with the new color.

tests/invalid/abstract_eqv.err_exp:
tests/invalid/actual_expected.err_exp:
tests/invalid/actual_more_expected.err_exp:
tests/invalid/arg_permutation.err_exp:
tests/invalid/arith_wrong_module.err_exp:
tests/invalid/bad_statevar_bad_context.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/coerce_infer.err_exp:
tests/invalid/coerce_non_du.err_exp:
tests/invalid/coerce_type_error.err_exp:
tests/invalid/coerce_unify_tvars.err_exp:
tests/invalid/comparison.err_exp:
tests/invalid/error_in_list.err_exp:
tests/invalid/exist_foreign_error.err_exp:
tests/invalid/ext_type.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/foreign_procs_exist_type.err_exp:
tests/invalid/getopt_old.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid/ho_type_arity_bug.err_exp:
tests/invalid/illtyped_compare.err_exp:
tests/invalid/integral_constant_no_suffix.err_exp:
tests/invalid/method_impl.err_exp:
tests/invalid/mixed_up_streams.err_exp:
tests/invalid/mpj1.err_exp:
tests/invalid/mpj4.err_exp:
tests/invalid/no_method.err_exp:
tests/invalid/nullary_ho_func_error.err_exp:
tests/invalid/overloading.err_exp:
tests/invalid/record_syntax_errors.err_exp:
tests/invalid/try_bad_params.err_exp:
tests/invalid/type_diff.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/invalid/type_error_in_arg.err_exp:
tests/invalid/type_mismatch.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/user_field_access_decl_override2.err_exp:
tests/invalid_nodepend/errors2.err_exp:
tests/invalid_purity/impure_func_t5.err_exp:
tests/invalid_purity/impure_pred_t1.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
tests/invalid_purity/purity_type_error.err_exp:
    Expect the new-colored output.
2024-05-05 09:49:35 +10:00
Zoltan Somogyi
05512c422b Add omitted word. 2024-05-04 01:04:34 +10:00
Zoltan Somogyi
59c9a45cc8 Update a comment. 2024-05-04 00:58:22 +10:00
Zoltan Somogyi
66b309dcd4 Handle color changes next to prefixes/suffixes.
compiler/write_error_spec.m:
    Redesign the code we use to decide what text goes onto each line.
    The new design rests on these two new principles:

    - Representing the current word separately from the words before it
      on the line. This allows us to merge together an arbitrary number
      of prefixes, a plain word, and an arbitrary number of suffixes
      without the two additional passes that the old algorithm used
      to accomplish the same goal.

    - Representing the spaces between words *explicitly*. Together with
      the previous principle, this allows us to do case analyses of the
      possible configurations of text, spaces and color changes with
      significantly simpler code than was possible with the previous design.
      The new code is longer, but

      - it is easier to see both that it does the right thing in each
        of these situations, including interactions between prefixes and
        suffixes on the one hand and color changes on the other, and

      - it is easier to check that all possible combinations of the
        relevant circumstances have code to handle them.

compiler/typecheck_error_undef.m:
    Use the new capability by using color in arity mismatch reports,
    which have the form of "(4, should be 2, 3 or 5)", where the numbers,
    which are surrounded by two parentheses which are respectively
    a prefix and a suffix, are colored.

compiler/error_spec.m:
    Exclude from the list of pieces to be colored not just any final
    subsequence of newline pieces, but any initial subsequence of newlines
    as well. This avoids the output having lines which end in two consecutive
    color changes with nothing between them: the first of which switches
    to a color, and the second of which resets the current color to neutral.

library/cord.m:
library/list.m:
library/one_or_more.m:
library/ra_list.m:
    Add a predicate named is_non_empty, which does what its name says,
    to each of these modules. In cord.m, this is new functionality,
    which is now used by write_error_spec.m. In the other modules,
    this new predicate is a synonym for the existing predicate
    is_not_empty. These modules were in a minority; all other modules
    that had a predicate to test for nonemptyness named it is_noN_empty,
    not is_noT_empty.

NEWS.md:
    Announce the new is_non_empty predicates.

tests/invalid/constructor_warning.err_exp:
tests/invalid/getopt_io_old.err_exp:
tests/invalid/invalid_event.err_exp:
tests/invalid/no_method.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/wrong_arity_function.err_exp:
    Expect the new colored output from typecheck_error_undef.m,
    without the extra spaces around parentheses that the version
    of write_error_spec.m before this diff would have put around them.

tests/invalid/bug117.err_exp:
tests/invalid/bug191.err_exp:
tests/invalid/bug415.err_exp:
tests/invalid/char_inst.err_exp:
tests/invalid/coerce_int.err_exp:
tests/invalid/coerce_mode_error.err_exp:
tests/invalid/coerce_recursive_type.err_exp:
tests/invalid/constrained_poly_insts2.err_exp:
tests/invalid/default_ho_inst.err_exp:
tests/invalid/det_errors.err_exp:
tests/invalid/det_errors_and_io.err_exp:
tests/invalid/functor_ho_inst_bad.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/html.err_exp:
tests/invalid/merge_ground_any.err_exp:
tests/invalid/mode_error_arg_number.err_exp:
tests/invalid/partial_implied_mode.err_exp:
tests/invalid/polymorphic_unification.err_exp:
tests/invalid/require_scopes.err_exp:
tests/invalid/type_prop_into_inst.err_exp:
    Expect the absence of switches to a color followed IMMEDIATELY
    by a color reset, thanks to the update of error_spec.m.
2024-05-04 00:27:34 +10:00
Zoltan Somogyi
8ef12bbd3b Convert pieces to words to paragraphs.
compiler/write_error_spec.m:
    Until now, we have converted pieces directly into paragraphs,
    using a single predicate that both

    - converted pieces into words, and then
    - converted those words into paragraphs.

    The latter part does not currently do the right thing in the presence of
    color changes next to prefixes and suffixes. Fixing that requires
    code that takes more considerations into account than the current code.
    Doing that in a predicate that *also* does the conversion of pieces
    into words would lead to over-complex code. To avoid that over-complexity,
    this diff therefore, as a first step,

    - splits things so that each of the tasks above is done by
      a separate predicate, and

    - have that predicate fully implement lower_next_if_not_first pieces,
      thus leaving one less task for the rest of the code.

    This diff also deletes the special-casing of color changes that end
    just past a newline, since the problem that this special-casing solved
    is now solved by more general code in the function (in error_spec.m)
    that applies color to piece lists.
2024-05-03 04:29:03 +10:00
Zoltan Somogyi
8e335f5c56 Use color in purity diagnostics.
compiler/purity.m:
    Add color to diagnostics about purity where appropriate.

    To make this exercise worthwhile, this diff also fixes the wording
    of many of the diagnostics, rewriting them completely in some cases.

    It splits one function for generating diagnostics into two, because
    its two use cases require totally different wording for clarity.

    It stops exporting a function that is not used outside this module.

compiler/write_error_spec.m:
    Fix a bug that resulted in output that was colored differently than
    intended. The bug occurred when a color start fit at the end of a line
    (not surprising, since its width is zero), but the next word did not.
    The bug was that the code let the color start take effect at the end
    of the first line, but processed it again at the start of the next line.
    This put the color on the stack *twice*, which meant that the next
    color end, which popped the top color stack, still left one copy of
    the color on the stack, and therefore in effect.

tests/invalid/foreign_purity_mismatch.err_exp:
tests/invalid/impure_method_impl.err_exp:
tests/invalid/multimode_missing_impure.err_exp:
tests/invalid/test_promise_equivalent_clauses.err_exp:
tests/invalid_purity/impure_func_t2.err_exp:
tests/invalid_purity/impure_func_t3.err_exp:
tests/invalid_purity/impure_func_t4.err_exp:
tests/invalid_purity/impure_func_t7.err_exp:
tests/invalid_purity/impure_par_conj.err_exp:
tests/invalid_purity/pragma_c_and_mercury.err_exp:
tests/invalid_purity/purity.err_exp:
tests/warnings/purity_warnings.exp:
    Expect the updated diagnostics.
2024-04-30 00:45:21 +10:00
Zoltan Somogyi
9ab507e5ae Add color to the output of typecheck_error_undef.m.
compiler/typecheck_error_undef.m:
    Use color as appropriate in diagnostics.

    Mark one place where color would be useful, but which write_error_spec.m
    cannot handle without formatting errors.

    Use more specific wording for an error message.

compiler/typecheck_msgs.m:
compiler/error_spec.m:
    Add colors in these subconstractors of typecheck_error_undef.m.

compiler/write_error_spec.m:
    Fix a bug: make the piece that lower-cases the first character
    of the next word have effect through color changes.

    Move two predicates to their relatives.

    Replace a use of reversed lists with cords.

tests/invalid_submodules/Mmakefile:
    Enable the use of color for diagnostics in this test directory.

tests/invalid/bad_pred_arity.err_exp:
tests/invalid/bug113.err_exp:
tests/invalid/getopt_io_old.err_exp:
tests/invalid/multimode_syntax.err_exp:
tests/invalid/multiply_star.err_exp:
tests/invalid/qual_basic_test2.err_exp:
tests/invalid/transitive_import_class.err_exp:
tests/invalid/type_diff.err_exp:
tests/invalid/type_error_use_module.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/undef_symbol.err_exp:
tests/invalid_nodepend/errors2.err_exp:
tests/invalid_nodepend/funcs_as_preds.err_exp:
tests/invalid_nodepend/kind.err_exp:
tests/invalid_nodepend/reserved_type_name.err_exp:
tests/invalid_submodules/undef_mod_qual.err_exp:
    Expect color, and in one case, revised wording.
2024-04-28 23:06:22 +10:00
Zoltan Somogyi
39b5e3439a Add color to the output of typecheck_errors.m.
compiler/typecheck_errors.m:
    Add colors to the parts of diagnostics that contrast incorrect type
    with the expected correct types, and the parts that document possible
    causes.

compiler/error_spec.m:
    Add some utility functions needed by the above.

compiler/write_error_spec.m:
    Fix several issues revealed by the effect of the above changes
    on the outputs we generate for invalid test cases.

    Issue one. We had a sanity check that, after joining two lines,
    checked whether the sum of the recorded line lengths matched
    the number of code points in the joined string. Delete this check,
    because it does the wrong thing in the presence of color changes.
    The reason is that the recorded lengths consider the escape sequences
    implementing them to be zero length (since they occupy zero columns),
    but string.count_code_points counts them anyway.

    Issue two. We used to handle colors in each paragraph separately,
    effectively starting each paragraph with an empty color stack.
    This caused problems with messages in which a color change is supposed
    to affect several lines *that have explicit newlines between them*,
    since the code puts paragraph breaks after each explicit newline.
    Fix this by setting the initial color stack of each nonfirst
    paragraph to the final color stack of the previous paragraph.

    Issue three. It is possible for an unbreakable string (such as the name
    of a predicate) that is too long to fit in the space available on a line.
    We have to include such strings in a line despite the violation of the
    length limit. Previously, we had to do only when the string was the first
    thing on the line. Now, it is possible for such a string to be preceded
    by one or more color changes, which occupy zero columns. Include
    too-long-to-fit unbreakable strings on the line in such cases as well.

    Issue four. Some callers of the color_pieces functions pass them
    piece lists that end in newlines. In such cases, we don't want
    the color reset to take place at the start of the next line after the
    colored pieces, because that makes the output harder to check visually
    for correctness in .err_exp files. In such cases, swap the order
    of the color_end and newline pieces. (Since newlines cannot be colored,
    this has no semantic effect.)

    Issue five. If a line either started out colored or contained pieces
    that started a new color, we marked it to be followed by a color reset
    when it is printed. However, if the color was already reset by pieces
    that are also contained in the line, so that the color stack was empty
    at the end of the line, then this final additional reset was redundant.
    Arrange not to print such redundant resets, also in the interest of
    making .err_exp files easier to check.

    Improve the debugging infrastructure a bit.

    Don't duplicate blank lines zero times.

tests/invalid/Mmakefile:
tests/invalid_nodepend/Mmakefile:
tests/invalid_purity/Mmakefile:
tests/warnings/Mmakefile:
    Enable color diagnostics in these test directories.

tests/invalid/abstract_eqv.err_exp:
tests/invalid/actual_expected.err_exp:
tests/invalid/actual_more_expected.err_exp:
tests/invalid/arith_wrong_module.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/error_in_list.err_exp:
tests/invalid/ext_type.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/foreign_procs_exist_type.err_exp:
tests/invalid/getopt_old.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid/ho_type_arity_bug.err_exp:
tests/invalid/integral_constant_no_suffix.err_exp:
tests/invalid/method_impl.err_exp:
tests/invalid/mixed_up_streams.err_exp:
tests/invalid/mpj1.err_exp:
tests/invalid/mpj4.err_exp:
tests/invalid/no_method.err_exp:
tests/invalid/nullary_ho_func_error.err_exp:
tests/invalid/overloading.err_exp:
tests/invalid/record_syntax_errors.err_exp:
tests/invalid/try_bad_params.err_exp:
tests/invalid/type_diff.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/invalid/type_error_in_arg.err_exp:
tests/invalid/type_mismatch.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/user_field_access_decl_override2.err_exp:
tests/invalid_nodepend/errors2.err_exp:
tests/invalid_purity/impure_func_t5.err_exp:
tests/invalid_purity/impure_pred_t1.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
tests/invalid_purity/purity_type_error.err_exp:
tests/warnings/inconsistent_pred_order.exp:
tests/warnings/subtype_order.exp:
    Expect color in these expected output files.
2024-04-28 17:12:36 +10:00
Zoltan Somogyi
f6024c75e8 Fix a bug in color output.
compiler/write_error_spec.m:
    When writing out an error line, reset the colors at the end of the line
    if there were color changes within the line OR if the line *started out*
    being in color.
2024-04-27 12:54:54 +10:00
Zoltan Somogyi
cbd54592ce Set up options to control colors in diagnostics.
compiler/options.m:
    Define options to control the use of color by diagnostics.
    The default disallows the use of colors, and the options intended
    for use by programmers are not yet documented.

compiler/error_spec.m:
    Add a third use for color, intended to be used for the descriptions of
    possible causes of the error being reported.

compiler/globals.m:
    Add a function for checking whether the options intended to select colors
    have meaningful values.

compiler/handle_options.m:
    Call that function to check the values of those options, and use
    the values of the options intended to control the use of color,
    and the values of the relevant environment variable, to decide
    whether to actually use color.

compiler/write_error_spec.m:
    Base the decision about whether to use color, and if so what colors to use,
    on the values of the new options.
2024-04-27 01:08:07 +10:00
Zoltan Somogyi
132168d6ee Switch spelling from colour to color. 2024-04-26 03:13:12 +10:00
Zoltan Somogyi
c5c50008cd Add prelim support for colour in error messages.
compiler/error_spec.m:
    Add and export two functions, which promise to make a given piece list
    will be printed in colour (if colour capability is enabled).
    Support two colours for now: one each indicating correct and incorrect
    code. The intention is to draw programmers eyes to these parts of
    error messages.

    The new capability extends the format_piece type, but in a way that
    asks users to leave its use to code inside error_spec.m itself
    (at least for now).

    As a trial, change the implementation of change_hunk_to_pieces,
    which transforms the output of diff algorithms into parts of
    error_specs. We use this capability to point out inconsistencies
    between the order in which preds/funcs are declared and the order
    in which they are defined.

compiler/write_error_spec.m:
    Add code to turn the semantic colour names defined in error_spec.m
    into actual colors we can print using the escape sequences supported
    by many (most?) kinds of terminals, if this capability is enabled.

    Extend each stage of the multi-stage machinery we use to convert
    format_piece sequences into error lines to handle colour changes.

    This required changes in how we handle string lengths and spaces.
    Previously, we could compute the length of a string on the screen
    by calling string.count_code_points, but this does not work when
    some of those code points represent terminal control sequences
    (that set a new current colour) that take no space on screen.
    Also, we could just put a space between each pair of strings on a line
    when those string were each one word, but that would lead to incorrect
    output when some of those strings are terminal control sequences.
    This required adding support for setting up an initial colour
    on each line, and resetting the colour at the end of each line.

    Change the representation of unlimited length lines. Instead of the
    representation being "no", i.e. the absence of a limit, it is now
    int.max_int, a limit that is impossible to reach in practice.
    The reason for this is that we used to compute the length of a line
    using string.count_code_points if MaybeLimit was "no", and as mentioned
    above, this does not work anymore.

    This new machinery has been tested manually, and it works.
    It is disabled for now,

    - until we figure out how we want to control it,
    - until we figure out how we want to test it, and
    - until we start using it in more commonly seen error messages.
2024-04-24 22:54:57 +10:00
Zoltan Somogyi
68dab655d2 Mark obsolete predicates as such.
compiler/write_error_spec.m:
    Add obsolete pragmas for three old predicates.

    Delete an unused predicate.

compiler/Mercury.options:
    Add --no-warn-obsolete options for three old, now unused and
    unmaintained modules that still call those predicates.
2024-04-23 22:37:03 +10:00
Zoltan Somogyi
dc12878708 Shorten function symbols in error_specs.
compiler/error_spec.m:
    Replace simplest_spec with spec, and simplest_no_context_spec with
    no_ctxt_spec. These are now the most frequently used function symbols
    to create error specs, so their name should not make them out to be
    the exception.

    Replace simplest_msg with msg, and simplest_no_context_msg with
    no_ctxt_msg for the same reason.

    Abbreviate some of the long phase names.

compiler/*.m:
    Conform to the changes above. Most of these changes were done by a script,
    with minor manual tidying up, which consisted mostly of fitting code
    constructing error specs onto fewer lines than before.
2024-04-20 21:51:15 +10:00
Zoltan Somogyi
065a18d15a Clarify two of higher_order.m's submodules.
compiler/higher_order.make_specialized_preds.m:
compiler/higher_order.specialize_calls.m:
    Clarify code and comments.

compiler/parse_tree_out_misc.m:
    Make context_to_string a function, since other X_to_string's are
    functions.

compiler/prog_ctgc.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/write_error_spec.m:
    Conform to the change in parse_tree_out_misc.m.
2024-02-29 21:50:11 +11:00
Julien Fischer
4cd5c17f61 Fix more copyright notices ...
... and other minor fixes.

library/*.m:
library/LIB_FLAGS.in:
compiler/*.m:
mdbcomp/*.m:
    Fix and update copyright notices.

    Fix spelling.

    Delete trailing whitespace.
2024-02-20 17:18:52 +11:00
Zoltan Somogyi
a9c76976b4 Make indents unsigned.
compiler/indent.m:
    Make the indent type a synonym for uint.

compiler/*.m:
    Conform to the change above.
2023-11-22 07:46:14 +11:00
Zoltan Somogyi
1319819ec2 Use only explicit streams in make.module_target.m.
compiler/Mercury.options:
    Stop specifying --no-warn-implicit-stream-calls for make.module_target.m.

compiler/make.module_target.m:
    Use explicit streams when invoking mmc recursively for a target.

    Add a call to maybe_print_delayed_error_messages. It does not fix
    the problem it looks like it *should* fix, but it is almost certainly
    a required step for that fix.

compiler/mercury_compile_main.m:
    Take the explicit streams that make.module_target.m now passes.

compiler/write_error_spec.m:
    Make the mutables consulted by maybe_print_delayed_error_messages
    thread local. This should help, but it does not solve the problem.
2023-10-19 11:32:10 +11:00
Zoltan Somogyi
25f8a6cc99 Add new option --generate-dependencies-ints.
This new option extends --generate-dependencies to take advantage of the
opportunity afforded by the fact that "mmc --generate-dependencies prog.m"
reads in every Mercury source file in the current directory that is
part of "prog". It does this by

- generating the .int3 file of all local-directory modules of the program;
- generating the .int0 file for each these modules that has submodules;
- generating the .int and .int2 files of all local-directory modules
  of the program.

Normally, the process of creating .int0, .int and .int3 files would
need to read in .int0 and .int3 files, but in every one of these cases,
we have just written out those files, so simply holding onto their
parse trees, we can skip this step. On my laptop, on a directory
containing library/*.m, mdbcomp/*.m and compiler/*.m, generating
the dependencies and generating all the .int3/.int0/.int/.int2 files
takes just over 25 seconds. Using the new option, the same process
takes less than 10 seconds.

compiler/options.m:
    Add the new option.

compiler/op_mode.m:
    Add a new variant of the existing op_mode for --generate-dependencies,
    which we select in the presence of the new option.

compiler/mercury_compile_main.m:
    Implement the new op_mode.

    Fix an old issue, which is that "mmc --make-private-interface x.m"
    generated a .int0 file for *every* module in x.m, even the modules
    that don't have any submodules.

compiler/deps_map.m:
    The code implementing the new option needs to know which modules
    of the program are in the current directory. The deps_map structure
    built by the code shared with the implementation of --generate-dependencies
    has not needed that info until now, so add a new field to the deps
    structure of each module to provide this info.

compiler/generate_dep_d_files.m:
    Return the deps_map created by the code that implements both
    --generate-dependencies and the new option to mercury_compile_main.m.

compiler/write_module_interface_files.m:
    Add a flag to the predicates that first construct the parse trees of,
    and then write out, .int3/.int0/.int/.int2 files, that
    mercury_compile_main.m can use to tell them to record the parse trees
    in the have read module maps.

    Add new variants of two of those predicates that take some of their
    arguments from burdened_module structures, since that is the form
    in which mercury_compile_main.m has that info.

compiler/module_baggage.m:
    The predicates in write_module_interface_files.m that generate
    .int0/.int/.int2 files take an argument that should be the timestamp
    of the source file they are being derived from, if that timestamp
    is needed for smart recompilation. Until now, we only ever invoked
    those predicates when we have just read in the source file,
    and this timestamp was readily available. The code implementing
    the new option needs to store this info for a short time, and
    the module baggage is the obvious place to store it, so add this field
    to the baggage.

compiler/error_spec.m:
    An invocation of the compiler with new option may report errors that
    prevent the construction of interface files for several modules.
    The new code in mercury_compile.m prints the error_specs that have
    contexts in the order of those contexts, but we want to print
    the messages without contexts (which in this case report that
    certain files could not be written or copied) to have a useful
    order too. Make this possible by allowing the invisible pieces
    we use for ordering to specify that order via a string (in this case,
    the name of the file that e.g. could not be written), rather than
    the only previous option, an integer.

compiler/grab_modules.m:
compiler/make.get_module_dep_info.m:
compiler/make.module_dep_file.m:
    Fill in the new field in the module baggage.

compiler/check_module_interface.m:
compiler/handle_options.m:
compiler/make_hlds_error.m:
compiler/parse_module.m:
compiler/prog_foreign_enum.m:
compiler/typecheck_error_util.m:
compiler/typecheck_msgs.m:
compiler/write_deps_file.m:
compiler/write_error_spec.m:
    Conform to the changes above.
2023-10-12 06:50:07 +11:00
Zoltan Somogyi
b7d83d291c Delete some no-longer-needed predicate versions. 2023-09-13 19:46:00 +10:00
Zoltan Somogyi
bb5b24173c Add an explicit stream to the print_anything method.
compiler/error_spec.m:
    As above.

compiler/mode_errors.m:
    Get the stream from this extra arg.

compiler/write_error_spec.m:
    Supply the stream argument.
2023-09-13 10:19:52 +10:00
Zoltan Somogyi
6777ae8391 Require explicit streams for write_error_specs.
compiler/write_error_spec.m:
    As above.

compiler/find_module.m:
compiler/source_file_map.m:
    Require the callers of predicates that call write_error_specs
    to supply an explicit stream.

compiler/make.program_target.m:
compiler/mercury_compile_main.m:
    Pass explicit streams where required.
2023-09-09 19:19:44 +10:00
Zoltan Somogyi
dd11a47a1a Provide a mechanism to avoid duplicate work.
compiler/write_error_spec.m:
    Several operations in the compiler want to convert a list of format pieces
    either to single line (if they fit there) or to several lines
    (if they don't). The significant part of those two operations
    consists of constructing the same intermediate data structure,
    If the pieces don't fit on one line, and we have to fall back to
    generating multiple lines of output, we want to avoid constructing
    this intermediate data structure for a second time. Provide
    operations that

    - return this intermediate data structure,
    - allow it to be tested whether it fits in a given number of characters,
    - and then convert it to either to a single line or a multi-line output.

compiler/hlds_out_goal.m:
compiler/hlds_out_inst_table.m:
    Use the new mechanisms to avoid constructing the intermediate structure
    more than once.
2023-08-31 18:27:50 +10:00
Zoltan Somogyi
2b38350dc2 Split error_pieces_to_string into two versions.
compiler/write_error_spec.m:
    One version returns everthing on one line; the other returns
    as many lines as the given pieces call for.

compiler/det_report.m:
compiler/error_msg_inst.m:
compiler/hlds_out_module.m:
compiler/hlds_statistics.m:
compiler/style_checks.m:
compiler/tabling_analysis.m:
compiler/trailing_analysis.m:
compiler/typecheck.m:
    Conform to the changes above.
2023-08-06 01:45:59 +02:00
Zoltan Somogyi
1b2ba54277 Make error_pieces_to_string use write_error_spec's code.
compiler/write_error_spec.m:
    The do_write_error_pieces predicate is part of the implementation of
    write_error_spec. Move to a new predicate the part that oversees the
    process of converting the pieces to lines.

    Replace the whole code of error_pieces_to_string with code that
    invokes the new predicate, and then post-processes it just slightly
    differently.

    This replacement has two advantages.

    First, it removes the need for double maintenance e.g. when new kinds
    of pieces are added.

    Second, unlike the old code, it preserves indentation in
    multi-line messages.
2023-08-05 18:46:14 +02:00