Commit Graph

25 Commits

Author SHA1 Message Date
Zoltan Somogyi
b2ba2dd917 Extend and fix the code for dumping insts.
The motivation for this diff is something I saw when I fixed the bug in
equiv_type_hlds.m on aug 13. During the bootcheck to verify the bug fix,
I enabled the end-of-front-end HLDS dump, and I saw that one module,
deep_profiler/display_report.m, had some references to MISSING_INSTs
in its HLDS dump. Since these could be signs of a bug in mode analysis,
I tracked them down. It turns out that the cause was an incompatibility
between the code that existed in error_msg_inst.m before that fix,
and the new code there added by that fix. But ironically, to find that
incompatibility, I first had to extend error_msg_inst.m's functionality
still further, specifically to make it possible to use it to write out insts
in HLDS dumps.

The reason for this need is that that the old code for dumping out insts
left a lot to be desired. It ignored (as in, it never wrote out) some parts
of specific kinds insts, such as the types in typed insts, without which
some parts of HLDS dumps did not make sense. For example, the ground inst
table in the HLDS dump of display_report.m contained several keys whose
printed versions were identical, seemingly indicating a bug in the code
that added new entries to that table (since it is supposed to add a new entry
to the table if the relevant key does not yet exist in the table). It turns
out that there was no bug; the keys differed, but only in the types.

compiler/error_msg_inst.m:
    Fix the incompatibility, and document both it, and its solution.

    Besides error_msg_inst, export a new function error_msg_inst_name,
    which does the same thing for inst_names as error_msg_inst does for insts.

    Add a flag to both functions that specifies whether the intended use
    of the return value is in an error message (whose audience is usually
    an ordinary Mercury user) or a HLDS dump (whose audience is always
    a Mercury developer). Include details such as the types in typed insts,
    and the structure of the compiler-generated inst names generally,
    which involve concepts that users do not know about, in the output
    only if the flag says the audience is Mercury developers.

    When printing out type or inst variables, use their actual names
    if these are available. To make this possible, require the callers
    of error_msg_{inst,inst_name} to provide tvarsets and inst_varsets,
    instead of always using empty varsets. The caller may still pass
    empty varsets if cannot do better than that, but most callers can,
    and now do pass valid varsets.

compiler/hlds_out_goal.m:
    Since we now want to pass a valid tvarset to error_msg_inst.m
    when printing the insts in goals' instmap_deltas, we need to pass around
    the tvarset, as well as the inst_varset, of the procedure that the goal
    was taken from. Instead of adding yet another parameter to all the affected
    predicates, replace all the existing parameters that have the same role
    (of which there were already about half a dozen) with a parameter
    of a new type named hlds_out_info_goal, which contains the values of
    all these old parameters, and the new one.

compiler/hlds_out_inst_table.m:
    Use the same setting to govern whether we use error_msg_inst.m's
    facilities for writing out insts and inst names in both the keys
    and the values of the various inst tables.

compiler/simplify_info.m:
    Include tvarsets in simplify_infos, since dumping out goals during
    simplification pass can now use this information.

compiler/add_clause.m:
compiler/add_mutable_aux_preds.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/direct_arg_in_out.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/hlds_out_pred.m:
compiler/inst_abstract_unify.m:
compiler/inst_lookup.m:
compiler/intermod.m:
compiler/lco.m:
compiler/liveness.m:
compiler/make_hlds_warn.m:
compiler/mode_errors.m:
compiler/pd_debug.m:
compiler/prog_mode.m:
compiler/push_goals_together.m:
compiler/saved_vars.m:
compiler/simplify_goal.m:
compiler/simplify_goal_conj.m:
compiler/simplify_proc.m:
compiler/stack_opt.m:
compiler/superhomogeneous.m:
compiler/unneeded_code.m:
    Conform to the changes above.
2023-08-31 16:25:31 +10:00
Zoltan Somogyi
0c76e78ed6 Factor out common code in error_msg_inst.m.
compiler/error_msg_inst.m:
    Most parts of this module consisted of pairs of predicates following
    the naming scheme X_to_pieces and X_to_inline_pieces. Replace each such
    pair of predicates with one predicate that takes a flag that says
    which version we want, since this allows us to avoid doing double
    maintenance. (The overall logic of the two versions was always the same;
    the differences affected only the construction of the piece sequence.)

    Get the compiler to recreate the original pair of procedures
    by using two separate specialized mode declarations to require
    the callers of each such predicate to specify whether they want
    to generate multi line or inline piece sequences.

    Move the !Expansion argument pairs to the end of the argument list
    in each of the updated predicates, in order to conform to our usual
    programming style.

    Eliminate differences between the codes used to construct the multi line
    and inline piece sequences that had no effect on the final output.

    Fix three minor bugs in the process.

    The first bug was that inst_name_to_pieces, which was intended to generate
    structured multi line inst descriptions, called inst_to_inline_pieces
    instead of inst_to_pieces in some cases.

    The second bug involved code in pred_inst_info_to_pieces and its inline
    version to special case the formatting of higher order values with no
    arguments. (The special casing omits what would be an empty pair of
    parentheses around the empty argument list.) While this is the right thing
    to do for predicates, it is nonsense for functions, because functions
    have at least one argument: the return value. Fix the code to special case
    functions having no *non-return-value* arguments.

    The third bug was a call to component_lists_to_pieces which could generate
    a list of argument modes in pred_inst_info_to_pieces and its inline version
    that could leave the last two modes *not* being separated by a comma.

tests/invalid/bug415.err_exp:
    Update this expected output to account for the first bug fix.
2023-08-30 06:52:49 +10:00
Zoltan Somogyi
eba4f307d9 Add inst_lookup_debug, and use it to fix a bug.
compiler/inst_lookup.m:
    Add inst_lookup_debug, a new version of the inst_lookup predicate
    intended to debug problems with inst names. It can recognize and report
    without crashing two kinds of problems with inst names:

    - unknown inst names, situations in which an inst name identifies
      an entry in an inst table that indicates that an operation on insts
      has begun but has not yet completed, which is a problem if all such
      operations are supposed to have completed, abd

    - missing inst names, situations in which an inst name *should* identify
      an entry in an inst table, but that entry does not exist. In such cases,
      the inst name is effectively a form of dangling pointer.

    It reports both kinds of problems by return user insts of a special form
    that another predicate can recognize, and which contain all the info
    available about the error.

compiler/hlds_inst_mode.m:
    Add predicates to search the inst tables, to allow inst_lookup_debug
    to use its own code to handle search failures.

    Add predicates to return the contents of the four subtables of the
    unify inst table separately, and to rebuild the unify inst table
    from the versions of those four components. This is to help with
    a change to equiv_type_hlds.m that is explained below.

    Delete a no-longer-needed predicate.

compiler/parse_tree_to_term.m:
    Export some utility functions for use by inst_lookup_debug.

compiler/error_msg_inst.m:
    Use inst_lookup_debug instead of inst_lookup to "look up" inst names.
    When this returns an indication of an error, format the component insts
    of the erroneous insts nicely.

compiler/hlds_out_inst_table.m:
    When we print out entries in the unify inst table, merge inst table
    and the other inst tables, make it easier to see *which* table's entry
    we are looking at.

compiler/equiv_type_hlds.m:
    Fix a bug. The bug was this code in expanding out equivalence types
    in merge_inst_infos:

    ( if ChangedA = unchanged, ChangedB = unchanged then
        Changed = unchanged,
        MergeInstInfo = merge_inst_info(InstA, InstB)
    else
        Changed = changed,
        MergeInstInfo = MergeInstInfo0
    ).

    The lack of the update in the changed case led to properly-updated
    merge insts becoming dangling insts, which caused a compiler abort
    on their next lookup in the merge inst table. The reason why this
    bug hasn't appeared before is that such lookups are rarely done
    after equiv_type_hlds is invoked.

    Change a lambda expression involved in this bug to a predicate,
    to simplify putting an mdb breakpoint on it.

    Since the error may have been caused by the inconsistency of

    - some switches on Changed having the unchanged case first,
    - with other switches on Changed having the changed case first,

    make all switches put the unchanged case first, checking that
    none make the same mistake.

    Expand out type equivalences in each of the four subtables of the
    unify inst table separately, to both simplify and speed up the process
    of getting the key/value pairs out of the table and putting them
    back again.

tests/valid_seq/merge_inst_bug.m:
tests/valid_seq/merge_inst_bug_helper_1.m:
    Add a cut-down version of the original bug report program
    as a regression test.

tests/valid_seq/Mmakefile:
    Enable the new test case.
2023-08-13 12:39:56 +02: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
75320f5d14 Update the error message for missing ho insts.
compiler/mode_errors.m:
    Improve the error message you get when you pass a higher order value
    without specifying its higher order inst, along the lines in the
    discussion on m-rev over the last week.

compiler/error_msg_inst.m:
    Make some variables more descriptive.

tests/invalid/no_ho_inst.err_exp:
    Update the expected error message.
2023-07-25 00:16:24 +02:00
Zoltan Somogyi
dde8c1f396 Delete mer_inst's free/1 functor.
This functor was intended to have the same semantics as free/0, while
containing the type of the value it was applied to. However, commit
87e7e3bafa, the commit in which Fergus
introduced this function symbol, also contained an "XXX temporary hack"
in which the code that was supposed to create a value using this function
symbol when propagating a type into a free/0 inst, just ignored the type,
and left the inst as free/0. THIS TEMPORARY HACK HAS REMAINED IN THE CODE
SINCE 1994.

In a few places, we did hand-create insts using free/1 for code created
by the compiler itself. However, as far as I can tell, no free/1 inst
ever described any code read in from source files. This meant that
any code in switch arms for free/1 in switches on insts was never tested
in any meaningful sense. And predicates such as inst_merge_4, which
processed several kinds of insts without doing a complete switch on insts,
simply lacked code handle free/1 at all.

This diff deletes the free/1 function symbol. It does so NOT because
the type stored as its argument is not useful, but because it is useful
NOT JUST for free insts, but for ALL insts. This means that any mechanism
for providing information about the type of the value that an inst applies to
should work for all insts. This can be done

- either by passing along the type with every inst, and stepping into
  the argument types of each argument of a function symbol as we process
  bound insts, in every operation that operates on insts that needs
  type information.

- or by including a type in ALL the function symbols of the inst type.
  (We could do this either by adding a maybe(mer_type) field to each
  function symbol, which would be "no" before the propagate-types-
  into-modes pass, or by adding just a mer_type field, which would
  be a special dummy value before that pass. I (zs) prefer the latter,
  and so would juliensf.)

The second option would involve reintroducing a free/1 function symbol
into the inst type, but this would replace the existing free/0
function symbol, and it would inherit all the code that currently
handles free/0, NOT the code being deleted by this diff for handling
the *current* free/1.

The first option would be easier to implement if only one or maybe two
operations needed type info, the second would be both easier to implement
and more efficient if more operations needed that info.

compiler/prog_data.m:
    Delete free/1.

compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/comp_unit_interface.m:
compiler/dep_par_conj.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type_hlds.m:
compiler/error_msg_inst.m:
compiler/float_regs.m:
compiler/hlds_code_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_mode.m:
compiler/hlds_statistics.m:
compiler/inst_abstract_unify.m:
compiler/inst_check.m:
compiler/inst_match.m:
compiler/inst_merge.m:
compiler/inst_mode_type_prop.m:
compiler/inst_test.m:
compiler/inst_user.m:
compiler/inst_util.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/mode_top_functor.m:
compiler/modecheck_coerce.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_to_term.m:
compiler/pd_util.m:
compiler/prog_mode.m:
compiler/prog_rep.m:
compiler/recompilation.usage.m:
compiler/types_into_modes.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the change above.
2023-07-22 12:26:55 +02:00
Zoltan Somogyi
92941c4239 Delete mer_inst's abstract_inst functor.
We have never supported abstract insts, and we are not likely to start
using them any time soon, but we have had them in the representation of insts
since the beginning. Since they were never actually generated, the code
that operated on them was never really tested, which is good, because
in many places, that code simply threw an exception. The code that didn't
throw an exception when it found an abstract inst had to work correctly
for the abstract_insts that we actually generated, which were abstract
only in the sense that they were references to a would-be user-defined inst
name that wasn't actually defined.

There were two sources of such "abstract" insts.

- One was failed calls to inst_lookup that specified an user_inst inst_name.

- The other consisted of predicates whose job was to construct error messages
  involving insts. These either converted cons_ids into abstract insts,
  or mangled valid user_inst inst_names into invalid user_inst inst_names,
  because error_msg_inst.m generated good-looking messages when given
  the results of such conversions.

The first is handled by the fact that module qualification detects and
reports references to undefined insts and modes, and does not let the
compiler proceed to the compiler phases that may call inst_lookup.

The second is handled by the changes to error_msg_inst.m below.
These change to handle the use cases of the two error-message-constructing
predicates that used to employ abstract_insts, but now employ user_inst
defined_insts with a two particular kinds of undefined inst ctor,
one for each use case.

compiler/prog_data.m:
    Delete the abstract_int function symbol from the mer_inst type.

compiler/inst_lookup.m:
    When the lookup of an user_inst inst_name inside a defined_inst
    fails, don't convert that defined_inst into abstract inst,
    throw an exception.

compiler/error_msg_inst.m:
    Add code to deal with the insts that add_mutable_aux_preds.m and
    mode_errors.m generate for us to convert to lists of error message pieces.
    The addition is done twice, in an as identical a fashion as possible,
    when generating non-inline pieces and when generating inline pieces.

compiler/add_mutable_aux_preds.m:
compiler/mode_errors.m:
    Document how these modules cooperates with error_msg_inst.m.

compiler/add_mode.m:
compiler/comp_unit_interface.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type_hlds.m:
compiler/float_regs.m:
compiler/hlds_code_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_mode.m:
compiler/hlds_statistics.m:
compiler/inst_abstract_unify.m:
compiler/inst_check.m:
compiler/inst_match.m:
compiler/inst_merge.m:
compiler/inst_mode_type_prop.m:
compiler/inst_test.m:
compiler/inst_user.m:
compiler/inst_util.m:
compiler/make_hlds_passes.m:
compiler/mode_top_functor.m:
compiler/modecheck_coerce.m:
compiler/modecheck_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_to_term.m:
compiler/pd_util.m:
compiler/prog_mode.m:
compiler/recompilation.usage.m:
compiler/types_into_modes.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above, mostly by deleting code dealing with
    abstract_insts.

tests/invalid/functor_ho_inst_bad.err_exp:
tests/invalid/functor_ho_inst_bad_3.err_exp:
tests/invalid/partial_implied_mode.err_exp:
tests/invalid_nodepend/occurs.err_exp:
    Update these expected outputs, which each involve errors generated
    by the modified code in mode_errors.m or add_mutable_aux_preds.m.
    Some of these referred to some things as "named insts" when they were
    *not* named insts in the program.

tests/invalid_nodepend/kind.{m,err_exp}:
    Add some invalid code to this test, and update the expected output
    accordingly.
2023-07-21 21:03:40 +02:00
Zoltan Somogyi
b6178ef723 Delete prog_out.m, moving its code to other modules.
compiler/parse_tree_out_cons_id.m:
    Move the predicates and functions in prog_out.m that deal with cons_ids
    to this module.

compiler/parse_tree_out_sym_name.m:
    Move the predicates and functions in prog_out.m that deal with sym_names
    and similar entities to this module.

compiler/parse_tree_out_type.m:
    Move the predicates and functions in prog_out.m that deal with types
    to this module.

compiler/parse_tree_out_misc.m:
    Move the predicates and functions in prog_out.m that deal with simple
    types to this module.

    Delete mercury_output_det and mercury_format_det, replacing all their
    uses with calls to mercury_det_to_string.

compiler/prog_out.m:
    Delete this module.

compiler/parse_tree.m:
    Delete prog_out from the parse_tree package.

compiler/Mercury.options:
compiler/notes/compiler_design.html:
    Delete references to prog_out.m.

compiler/*.m:
    Update imports and any explicit module qualifications to account
    for the moved code.

tools/filter_sort_imports:
    Automatically filter out any repeated imports. This can help with
    changes like this that redistribute the contents of one module to other
    modules. In this case, after a global replacement of prog_out's import
    with the import of parse_tree_out_misc, this updated script could
    remove this changed import from modules that already imported
    parse_tree_out_misc.
2023-04-09 16:23:13 +10:00
Zoltan Somogyi
e2a8a8cbfa Break up mercury_to_mercury.m.
compiler/mercury_to_mercury.m:
    Delete this module, and replace it with ...

compiler/parse_tree_out_cons_id.m:
compiler/parse_tree_out_sym_name.m:
compiler/parse_tree_out_type.m:
compiler/parse_tree_out_misc.m:
    ... these four modules. The first three write out the entities
    in their names: cons_ids, sym_names, and types. The fourth contains
    the rest of the old mercury_to_mercury.m, plus a few predicates
    moved there from prog_out.m that deal with indentation.

compiler/parse_tree.m:
    Include the four new modules, and stop including the deleted module.

compiler/notes/compiler_design.html:
    Document the new modules.

compiler/prog_out.m:
    Delete the code moved to parse_tree_out_misc.m.

compiler/*.m:
    Adjust the imports as needed. Most modules need only one, maybe two
    of mercury_to_mercury's four successor modules.
2023-04-06 15:32:48 +10:00
Zoltan Somogyi
18817d62d0 Record more than a pred_proc_id for each method.
Class and instance definitions both contain lists of methods,
predicates and/or functions, that each have one or more procedures.
Until now, we represented the methods in class and instance definitions
as lists of nothing more than pred_proc_ids. This fact complicated
several operations,

- partly because there was no simple way to tell which procedures
  were part of the same predicate or function, and

- partly because the order of the list is important (we identify
  each method procedure in our equivalent of vtables with a number,
  which is simply the procedure's position in this list), but there was
  absolutely no information about recorded about this.

This diff therefore replaces the lists of pred_proc_ids with lists of
method_infos. Each method_info contains

- the method procedure number, i.e. the vtable index,

- the pred_or_func, sym_name and user arity of the predicate or function
  that the method procedure is a part of, to make it simple to test
  whether two method_infos represent different modes of the same predicate
  or function, or not,

- the original pred_proc_id of the method procedure, which never changes,
  and

- the current pred_proc_id, which program transformations *can* change.

compiler/hlds_class.m:
    Make the change above in the representations of class and instance
    definitions.

    Put the fields of both types into a better order, by putting
    related fields next to each other.

    Put a notag wrapper around method procedure numbers to prevent
    accidentally mixing them up with plain integers.

    Add some utility functions.

compiler/prog_data.m:
    Replace three fields containing pred_or_func, sym_name and arity
    in the parse tree representation of instance methods with just one,
    which contains all three pieces of info. This makes it easier to operate
    on them as a unit.

    Change the representation of methods defined by clauses from a list
    of clauses to a cord of clauses, since this supports constant-time
    append.

compiler/hlds_goal.m:
    Switch from plain ints to the new notag representation of method
    procedure numbers in method call goals.

compiler/add_class.m:
    Simplify the code for adding new classes to the HLDS.

    Give some predicates better names.

compiler/check_typeclass.m:
    Significantly simplify the code for that generates the pred_infos and
    proc_infos implementing all the methods of an instances definition,
    and construct lists of method_infos instead of lists of pred_proc_ids.

    Give some predicates better names.

    Some error messages about problems in instance definitions started with

        In instance declaration for class/arity:

    while others started with

        In instance declaration for class(module_a.foo, module_b.bar):

    Replace both with

        In instance declaration for class(foo, bar):

    because it contains more useful information than the first, and less
    non-useful information than the second. Improve the wording of some
    error messages.

    Factor out some common code.

compiler/prog_mode.m:
compiler/prog_type.m:
compiler/prog_util.m:
    Generalize the existing predicates for stripping "builtin.m" module
    qualifiers from sym_names, cons_ids, insts, types and modes
    to allow also the stripping of *all* module qualifiers. This capability
    is now used when we print an instance's type vector as a context
    for diagnostics about problems inside instance definitions.

compiler/add_pred.m:
    Add a mechanism for returning the pred_id of a newly created pred_info,
    whether or not it was declared using a predmode declaration. This
    capability is now needed by add_class.m.

    Move the code creating an error message into its own function, and export
    that function for add_class.m.

compiler/polymorphism_type_info.m:
    Fix some comment rot.

compiler/base_typeclass_info.m:
compiler/call_gen.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/direct_arg_in_out.m:
compiler/error_msg_inst.m:
compiler/float_regs.m:
compiler/get_dependencies.m:
compiler/higher_order.m:
compiler/hlds_error_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_typeclass_table.m:
compiler/instance_method_clauses.m:
compiler/intermod.m:
compiler/make_hlds_error.m:
compiler/ml_call_gen.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qualify_items.m:
compiler/old_type_constraints.m:
compiler/parse_class.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_inst.m:
compiler/polymorphism_post_copy.m:
compiler/polymorphism_type_class_info.m:
compiler/prog_item.m:
compiler/prog_rep.m:
compiler/recompilation.usage.m:
compiler/state_var.m:
compiler/type_class_info.m:
compiler/typecheck_debug.m:
compiler/typecheck_error_type_assign.m:
compiler/typecheck_errors.m:
compiler/typecheck_msgs.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.

tests/invalid/bug476.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_mode.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_mode_3.err_exp:
tests/invalid/typeclass_mode_4.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_9.err_exp:
    Expect the updated wording of some error messages.
2022-11-22 02:27:33 +11:00
Zoltan Somogyi
307b1dc148 Split up error_util.m into five modules.
compiler/error_spec.m:
    This new module contains the part of the old error_util.m that defines
    the error_spec type, and some functions that can help construct pieces
    of error_specs. Most modules of the compiler that deal with errors
    will need to import only this part of the old error_util.m.

    This change also renames the format_component type to format_piece,
    which matches our long-standing naming convention for variables containing
    (lists of) values of this type.

compiler/write_error_spec.m:
    This new module contains the part of the old error_util.m that
    writes out error specs, and converts them to strings.

    This diff marks as obsolete the versions of predicates that
    write out error specs to the current output stream, without
    *explicitly* specifying the intended stream.

compiler/error_sort.m:
    This new module contains the part of the old error_util.m that
    sorts lists of error specs and error msgs.

compiler/error_type_util.m:
    This new module contains the part of the old error_util.m that
    convert types to format_pieces that generate readable output.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Include and document the new modules.

compiler/error_util.m:
    The code remaining in the original error_util.m consists of
    general utility predicates and functions that don't fit into
    any of the modules above.

    Delete an unneeded pair of I/O states from the argument list
    of a predicate.

compiler/file_util.m:
    Move the unable_to_open_file predicate here from error_util.m,
    since it belongs here. Mark another predicate that writes
    to the current output stream as obsolete.

compiler/hlds_error_util.m:
    Mark two predicates that wrote out error_spec to the current output
    stream as obsolete, and add versions that take an explicit output stream.

compiler/Mercury.options:
    Compile the modules that call the newly obsoleted predicates
    with --no-warn-obsolete, for the time being.

compiler/*.m:
    Conform to the changes above, mostly by updating import_module
    declarations, and renaming format_component to format_piece.
2022-10-12 20:50:16 +11:00
Zoltan Somogyi
f7355f708b Move var_db and var_{name,type}_source to var_db.m.
In the process, restrict the use of these types to just those modules
that need to provide services both other modules that use var_tables,
and modules that do not. The latter are modules that either can,
or always do, execute before var_tables are set up.

In some cases, code that previously operated on e.g. var_name_sources
had all its callers converted to use var_tables. In those cases, replace
the use of var_name_sources with var_tables directly.

In other cases, code that previously operated on e.g. var_name_sources
still has some callers that use varsets. In those cases,

- provide versions using var_tables if most callers use var_tables,
  renaming predicates/functions to make this the version seem the default,

- leave the operation to work on var_name_sources if some its callers
  also have only var_name_sources,

- if there are no such callers, keep just the two versions operating
  on varsets and var_tables respectively.

compiler/var_db.m:
compiler/var_table.m:
    Move the part of var_table.m that contains the definitions
    of the above three types, and the operations on them, to the
    new module var_db.m. Only 25 modules currently need var_db.m,
    compared to 176 for var_table.m.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Add and document the new module.

compiler/parse_tree_out_term.m:
    Add a "_vs" suffix to the names of operations that print variables
    or terms using varsets, and reuse their old names for versions
    that use var_table arguments. For the operations that need var_name_source
    versions, make it just select between the varset and var_table versions.

compiler/hlds_out_goal.m:
compiler/instmap.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/pd_info.m:
    Change some predicates that used to operate on var_{name,type}_sources
    to operate on var_tables.

    In hlds_out_mode.m, delete some unused predicates, and stop exporting
    a predicate whose only caller is local.

compiler/*.m:
    Conform to the changes above.
2022-08-19 10:44:39 +10:00
Zoltan Somogyi
e8503e890c Fix formatting of "no matching mode" error msgs.
compiler/error_msg_inst.m:
    When printing constrained insts, add the ")" at the end separately,
    not as part of a suffix. When it was printed as part of a suffix,
    it could be printed before a nl_indent_delta(-1) that balanced
    an earlier nl_indent_delta(1).

compiler/mode_errors.m:
    Don't get error_msg_inst.m, through the report_inst function, add
    an nl_indent_delta(-1) as part of the formatting of an inst,
    when it is in fact needed only *after* the inst.

    Change the representation of "no matching mode" errors to implicitly
    encode the invariant that every argument variable has its own inst.

compiler/modecheck_call.m:
compiler/modecheck_util.m:
    Conform to the changed representation of "no matching mode" errors.

tests/invalid/constrained_poly_insts2.err_exp:
    Expect the fixed formatting.
2022-02-24 06:37:23 +11:00
Zoltan Somogyi
dd632327db Generalize component_list_to_line_pieces.
compiler/error_util.m:
    Do not automatically add an nl to the end of the output
    of component_list_to_line_pieces; instead, let the callers specify
    how the last line should end. Most will pass nl, but some will pass
    an nl_indent_delta to undo an earlier nl_indent_delta.

compiler/add_clause.m:
compiler/add_foreign_enum.m:
compiler/add_mode.m:
compiler/add_pragma.m:
compiler/error_msg_inst.m:
compiler/post_typecheck.m:
compiler/prog_foreign_enum.m:
compiler/typecheck_errors.m:
    Conform to the change in error_util.m.
2022-02-16 13:59:55 +11:00
Zoltan Somogyi
60783563cd Don't expand insts in inst names.
compiler/error_msg_inst.m:
    When the first occurrence of a named inst I2 is an argument of another
    named inst I1, do *not* expand I2 there. Instead, expand it one of its
    occurrences in the *expansion* of I1.

    To expand I2 at its *first* occurrence in the expansion of I1,
    change the way to format lists of insts to format the head inst
    before formatting the tail insts.

    Shorten a field name.

tests/invalid/html.err_exp:
    Expect the fix for the "omitted insts" bug above.
2022-02-06 08:29:19 +11:00
Zoltan Somogyi
52c0c52cfd Fix formatting when reporting problem insts.
compiler/error_msg_inst.m:
    Fix a bug that caused the suffix that all paths in two predicates
    were supposed to add at the logical end of the constructed pieces
    (though it could be followed by some punctuation) to *not* be added
    to the constructed pieces on some paths. Since with our current approach,
    the suffix for one inst in a list of insts can be the description
    of *all the insts following it in the list*, this bug could delete
    not just punctuation, but entire insts from the output. This did actually
    happen for the invalid/html text case below.

    Fix a problem that could cause each inst in a list of insts
    to be indented one more level than the previous inst, which can be
    very confusing.

    Delete the comma from "instname, which expands to ...". When this output
    occurs in an argument list, the presence of the comma can make it
    harder to recognize where one argument ends and the next argument begins.

    Factor out some common code.

    Add an XXX noting a problem.

    Fix documentation.

compiler/parse_tree_out_inst.m:
    Provide two functions for use by error_msg_inst.m.

compiler/prog_mode.m:
    Fix a comment.

tests/invalid/html.m:
    Fix the description of the problem we are testing for.

tests/invalid/html.err_exp:
    Expect the fix for the "omitted insts" bug above.

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/constrained_poly_insts2.err_exp:
tests/invalid/ho_default_func_4.err_exp:
tests/invalid/merge_ground_any.err_exp:
tests/invalid/polymorphic_unification.err_exp:
    Do not expect the deleted comma.
2022-02-05 19:40:51 +11:00
Zoltan Somogyi
d76c7bf617 Break up inst_util.m and mode_util.m.
This step significantly improves module cohesion.

compiler/inst_abstract_unify.m:
    New module carved out of inst_util.m, which does abstract unifications
    on insts.

compiler/inst_merge.m:
    New module carved out of inst_util.m, which merges insts.

compiler/inst_lookup.m:
    New module carved partly out of inst_util.m and partly out of mode_util.m,
    which looks up insts in the module_info, and then possibly expands out
    the result.

compiler/mode_test.m:
    New module carved out of mode_util.m, whose predicates
    perform tests on modes.

compiler/mode_top_functor.m:
    New module carved out of mode_util.m, which computes top_functor_modes
    from modes.

compiler/inst_mode_type_prop.m:
    New module carved out of mode_util.m, which propagates type information
    into both insts and modes.

compiler/recompute_instmap_deltas.m:
    New module carved out of mode_util.m, which recomputes goals'
    instmap_deltas.

compiler/inst_test.m:
    Move here the predicates in inst_util.m that perform tests on insts.

compiler/inst_util.m:
compiler/mode_util.m:
    Delete the code that this diff moves to other modules.

compiler/check_hlds.m:
    Add the new modules to the check_hlds package, the package that also
    contains inst_util.m and mode_util.m. (Some of these modules could
    be argued to fit better in the hlds package, but moving them there
    would not be desirable while they depend on code that is still in the
    check_hlds package.)

compiler/notes/compiler_design.html:
    Document the new modules.

compiler/add_pragma_tabling.m:
compiler/arg_info.m:
compiler/bytecode_gen.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/error_msg_inst.m:
compiler/fact_table.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/inlining.m:
compiler/inst_match.m:
compiler/inst_user.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/lambda.m:
compiler/lco.m:
compiler/liveness.m:
compiler/lookup_util.m:
compiler/loop_inv.m:
compiler/mark_tail_calls.m:
compiler/ml_args_util.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_util.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/modecheck_call.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/oisu_check.m:
compiler/par_conj_gen.m:
compiler/pd_util.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/proc_requests.m:
compiler/prog_rep.m:
compiler/push_goals_together.m:
compiler/rbmm.region_transformation.m:
compiler/saved_vars.m:
compiler/simplify_goal_switch.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_pass2.m:
compiler/term_util.m:
compiler/tupling.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_util.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
    Conform to the changes above by importing the required new modules,
    sometimes in addition to inst_util.m or mode_util.m, but more usually
    instead of them.
2021-12-16 01:31:35 +11:00
Zoltan Somogyi
5ec405ac0a Add an XXX about tuple_cons cons_ids.
compiler/prog_data.m:
    As above.

compiler/mercury_to_mercury.m:
    When generating debugging output, generate different output
    for tuple_cons cons_ids than for the initial representation
    of the tuple constructor, cons(unqualified("{}"), ...).
    To make this possible, take an argument that specifies whether
    we are generating debugging output.

compiler/error_msg_inst.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/mode_errors.m:
compiler/parse_tree_out_inst.m:
compiler/prog_ctgc.m:
    Pass the language (debug or not) to mercury_to_mercury.m
    when printing cons_ids.
2021-02-26 20:40:23 +11:00
Zoltan Somogyi
4ebe95672d Don't crash on inst_name nested inside itself.
This fixes Mantis bug #528.

compiler/error_msg_inst.m:
    Since an inst_name IN may be used nested inside itself, as in
    IN(..., IN(...), ...), do not insist that both occurrences of IN
    in such cases lead to the insertion of a new entry in the inst name
    expansion map.

tests/invalid/html.{m,err_exp}:
    The Mantis test case.

tests/invalid/Mmakefile:
    Enable the Mantis test case.
2021-01-30 01:45:26 +11:00
Zoltan Somogyi
3ac1073811 Factor out common code for simplifying modes.
We used to have several predicates whose job was to simplify modes for
presentation to users. Their jobs were slightly different, but contained
a shared core: recognizing the exploded (from_inst >> to_inst)
forms of the standard builtin modes. Replace these

compiler/prog_mode.m:
    Moves an existing predicate in parse_tree_out_inst.m for recognizing
    the standard builtin modes to prog_mode.m, to make it generally available.

    Refactor the existing insts_to_mode predicate to use this predicate.
    Make insts_to_mode recognize mdi(I) modes as well.

    Add utility predicates for stripping all type_inst wrappers from
    insts and modes. Base these on the similar utility predicates
    for stripping builtin qualifiers from insts and modes. Export
    all meaningful variants of both sets of utilities.

    Use variables named InstNameX for inst names; the old InstX names
    were misleading, since the inst_name type is different from mer_inst.

compiler/parse_tree_out_inst.m:
    Delete the code moved to prog_mode.m.

    Use the updated functionality in prog_mode to simplify modes.
    This means that we can now simplify all in(...) modes, not just
    when the ... is a higher order inst.

    Strip module qualifiers from modes when printing output for humans
    (and *only* for humans), since in 99.9+% of cases they are clutter.

compiler/error_msg_inst.m:
    Replace the old code for recognizing standard modes with calls
    to the predicates in prog_mode.m. They can do a better job than
    the old code did. The recognize arity 1 standard modes, not just
    arity 0, and they remove typed_inst wrappers everywhere in insts,
    not just at the top level.

compiler/hlds_out_util.m:
    Fix an old bug: don't *assume* that any modes being converted to string
    are intended only for humans; get our callers to *tell us* whether
    that is the case. When intermod.m uses hlds_out_goal.m to write out
    the modes on the arguments of lambda goals, this is *not* the case,
    since some transformations intended for humans, such as stripping
    module qualifications, can actually break things.

    Give a field in the hlds_out_info a more meaningful name.

compiler/hlds_out_goal.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/mode_errors.m:
    Conform to the changes in hlds_out_util.m.

tests/invalid/ho_any_inst.err_exp:
tests/invalid/ho_default_func_4.err_exp:
tests/invalid/mode_inf.err_exp:
    Expect the updated forms of modes in error messages.
2020-11-15 08:19:30 +11:00
Zoltan Somogyi
5f50259d16 Write to explicitly named streams in many modules.
Right now, most parts of the compiler write to the "current output stream".
This was a pragmatic choice at the time, but has not aged well. The problem
is that the answer to the question "where is the current output stream going?"
is not obvious in *all* places in the compiler (although it is obvious in
most). When using such implicit streams, finding where the output is going
to in a given predicate requires inspecting not just the ancestors of that
predicate, but also all their older siblings (since any of them could have
changed the current stream), *including* their entire call trees. This is
usually an infeasible task. By constrast, if we explicitly pass streams
to all output operations, we need only follow the places where the variable
representing that stream is bound, which the mode system makes easy.

This diff switches large parts of the compiler over to doing output only
to explicitly passed streams, never to the implicit "current output stream".
The parts it switches over are the parts that rely to a significant degree
on the innermost change, which is to the "output" typeclass in
parse_tree_out_info.m. This is the part that has to be switched over to
explicit streams first, because (a) many modules such as mercury_to_mercury.m
rely on the output typeclass, and (b) most other modules that do output
call predicates in these modules. Starting anywhere else would be like
building a skyscraper starting at the top.

This typeclass, output(U), has two instances: output(io), and output(string),
so you could output either to the current output stream, or to a string.
To allow the specification of the destination stream in the first case,
this diff changes the typeclass to output(S, U) with a functional dependency
from U to S, with the two instances being output(io.text_output_stream, io)
and output(unit, string). (The unit arg is ignored in the second case.)

There is a complication with the output typeclass method, add_list, that
outputs a list of items. The complication is that each item is output
by a predicate supplied by the caller, but the separator between the items
(usually a comma) is output by add_list itself. We don't want to give
callers of this method the opportunity to screw up by specifying (possibly
implicitly) two different output streams for these two purposes, so we want
(a) the caller to tell add_list where to put the separators, and then
(b) for add_list, not its caller, tell the user-supplied predicate what
stream to write to. This works only if the stream argument is just before
the di,uo pair of I/O state arguments, which differs from our usual practice
of passing the stream at or near the left edge of the argument list,
not near the right. The result of this complication is that two categories
of predicates that are and are not used to print items in a list differ
in where they put the stream in their argument lists. This makes it easy
to pass the stream in the wrong argument position if you call a predicate
without looking up its signature, and may require *changing* the argument
order when a predicate is used to print an item in a list for the first time.
A complete switch over to always passing the stream just before !IO
would fix this inconsistency, but is far to big a change to make all at once.

compiler/parse_tree_out_info.m:
    Make the changes described above.

    Add write_out_list, which is a variant of io.write_list specifically
    designed to address the "complication" described above. It also has
    the arguments in an order that is better suited for higher-order use.

    Make the same change to argument order in the class method add_list
    as well.

Almost all of the following changes consist of passing an extra stream
argument to output predicates. In some places, where I thought this would
aid readability, I replaced sequences of calls to output predicates
with a single io.format.

compiler/prog_out.m:
    This module had many predicates that wrote things to the current output
    stream. This diff adds versions of these predicates that take an
    explicit stream argument.

    If the originals are still needed after the changes to the other modules,
    keep them, but add "_to_cur_stream" to the end of their names.
    Otherwise, delete them. (Many of the changes below replace
    write_xyz(..., !IO) with io.write_string(Stream, xyz_to_string(...), !IO),
    especially when write_xyz did nothing except call xyz_to_string
    and wrote out the result.)

compiler/c_util.m:
    Add either an explicit stream argument to the argument list, or a
    "_current_stream" suffix to the name, of every predicate defined
    in this module that does output.

    Add a new predicate to print out the block comment containing
    input for mkinit. This factors out common code in the LLDS and MLDS
    backends.

compiler/name_mangle.m:
    Delete all predicates that used to write to the current output stream,
    after replacing them if necessary with functions that return a string,
    which the caller can print to wherever it wants. (The "if necessary"
    part is there because some of the "replacement" functions already
    existed.)

    When converting a proc_label to a string, *always* require the caller
    to say whether the label prefix should be added to the string,
    instead of silently assuming "yes, add it", as calls to one of the old,
    now deleted predicates had it.

compiler/file_util.m:
    Add output_to_file_stream, a version of output_to_file which
    simply passes the output file stream it opens to the predicate
    that is intended to define the contents of the newly created or
    updated file. The existing output_to_file, which instead sets
    and resets the current output stream around the equivalent
    predicate call, is still needed e.g. by the MLDS backend,
    but hopefully for not too long.

compiler/mercury_to_mercury.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_clause.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_tree_out_pred_decl.m:
compiler/parse_tree_out_term.m:
compiler/parse_tree_out_type_repn.m:
    Change the code writing out parse trees to explicitly pass a stream
    to every predicate that does output.

    In some places, this allows us to avoid changing the identity
    of the current output stream.

compiler/hlds_out.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
    Change the code writing out HLDS code to explicitly pass a stream
    to every predicate that does output. (The changes to these modules
    belong in this diff because these modules call many of the output
    predicates in the parse tree package.)

    In hlds_out_util.m, delete some write_to_xyz(...) predicates that wrote
    the result of xyz_to_string(...) to the current output stream.
    Replace calls to the deleted predicates with calls to io.write_string
    with the string being written being computed by xyz_to_string.

    Add a predicate to hlds_out_util.m that outputs a comment containing
    the current context, if it is valid. This factors out code that used
    to be common to several of the other modules.

    In a few places in hlds_out_module.m, the new code generates a
    slighly different set of blank lines, but this should not be a problem.

compiler/layout_out.m:
compiler/llds_out_code_addr.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/llds_out_util.m:
compiler/opt_debug.m:
compiler/rtti_out.m:
    Change the code writing out the LLDS to explicitly pass a stream
    to every predicate that does output. (The changes to these modules
    belong in this diff because layout_out.m and rtti_out.m call
    many of the output predicates in the parse tree package,
    and through them, the rest of the LLDS backend is affected as well.)

compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
    Replace code that sets and resets the current output stream
    with code that simply passes an explicit output stream to a
    predicate that now *takes* an explicit stream as an argument.

compiler/accumulator.m:
compiler/add_clause.m:
compiler/code_gen.m:
compiler/code_loc_dep.m:
compiler/cse_detection.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/error_msg_inst.m:
compiler/export.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/ite_gen.m:
compiler/lco.m:
compiler/liveness.m:
compiler/lp_rational.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_c_global.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/optimize.m:
compiler/passes_aux.m:
compiler/pd_debug.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/prog_ctgc.m:
compiler/push_goals_together.m:
compiler/rat.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/rtti.m:
compiler/saved_vars.m:
compiler/simplify_goal_conj.m:
compiler/stack_opt.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/superhomogeneous.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_fixpoint.m:
compiler/term_constr_pass2.m:
compiler/term_constr_util.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/unneeded_code.m:
compiler/write_deps_file.m:
    Conform to the changes above, mostly by passing streams explicitly.

compiler/hlds_dependency_graph.m:
    Conform to the changes above, mostly by passing streams explicitly.
    Move a predicate's definition next it only use.

compiler/Mercury.options:
    Specify --warn-implicit-stream-calls for all the modules in which
    this diff has replaced all implicit streams with explicit streams.
    (Unfortunately, debugging this diff has shown that --warn-implicit-
    stream-calls detects only *some*, and not *all*, uses of implicit
    streams.)

library/term_io.m:
    Fix documentation.
2020-11-14 15:07:55 +11:00
Zoltan Somogyi
d64966713c Fix an infinite loop when prettyprinting insts for error messages.
compiler/error_msg_inst.m:
    When prettyprinting insts for use in error messages, we have to be careful
    to generate finite output even for recursive insts. Previously, we did
    the required check when processing user-defined inst names, but not when
    processing compiler-generated inst names, which can also be recursive.
    Fix this bug, which is Mantis bug 415.

    Previously, we passed information about what potentially-recursive inst
    names we have seen so far only downward. With the fix above, this avoids
    infinite loops, but in some cases, it leads us to print the definition
    of a given named inst more than once. Change our approach so that we
    now pass information about the set of potentially-recursive inst names
    we have seen sideways as well. This can make us generate more compact
    and therefore more understandable output when prettyprinting insts that
    contain such non-nested duplication.

    When printing something that says "inst name x, which expands to ...",
    indent the "..." one level deeper than the "inst name x". This visually
    separates the thing being defined and its definition.

    When prettyprinting complex insts, we show their structure using
    indentation levels in the output. Each increase of indentation
    should be balanced by a later matching decrease. Move the code that
    does the increase and the decrease next to each other, to make it easier
    to see the implicit correctness argument.

tests/invalid/bug415.{m,err_exp}:
    A new test case for this bug.

tests/invalid/Mmakefile:
    Enable the new test case.

tests/invalid/bug117.err_exp:
tests/invalid/bug191.err_exp:
tests/invalid/constrained_poly_insts2.err_exp:
tests/invalid/merge_ground_any.err_exp:
tests/invalid/polymorphic_unification.err_exp:
    Expect the extra level of indentation after "which expands to".

tests/invalid/ho_default_func_4.err_exp:
    Expect the extra level of indentation after "which expands to",
    and expect a repeated inst name NOT to have its definition repeated.
2016-08-30 18:37:19 +10:00
Zoltan Somogyi
cfcfde1db7 Simplify the representation of modes of unifications.
Unifications (x = y) have long had two descriptions of their modes.
One is the unify_mode, which used to look like this:
    (initx -> finalx) - (inity -> finaly)
and other is the uni_mode, which used to look like this:
    (initx - inity) -> (finalx - finaly)
Each unification had one unify_mode, and each unification that includes
a function symbol had one uni_mode per argument of that function symbol.

The two forms of mode information looked similar enough to be easily
confusable, but were subtly different. As it turns out, there was no
particular reason for the difference, so this diff eliminates the
uni_mode type, and the difference along with it.

What rationale there was for the uni_mode type was that the two modes
it represented (one for each side of the unification) both had their
initial and final insts directly available. This is not true for modes
in general: a value of the mer_mode type could have the form
"InitInst -> FinalInst" (which this diff renames "from_to_mode(InitInst,
FinalInst)", but could also be a "user_defined_inst(...)", which required
a table lookup to turn it into an initial/final pair of insts. This matters,
because almost all code that processes the modes of unifications
works with the initial and final insts.

This diff therefore creates a new type, from_to_insts, which represents
mode information only in the form of terms such as "from_to_insts(InitInst,
FinalInst)", and makes a unify_mode take two values of this type, not mer_mode,
as arguments.

As discussed on m-rev, this diff also renames the old, deceptively named
"arg_mode" type: its new name is "top_functor_mode".

compiler/prog_data.m:
compiler/hlds_goal.m:
    As mentioned above, avoid using "->" as a function symbol, and replace
    both -> and - with bespoke function symbols.

compiler/mode_util.m:
    Add some utility predicates and functions on the new types, and
    delete the old utility routines that operated on uni_modes.

    Code that uses the new functions and predicates should have a higher level
    of abstraction than the code that used to do the same job "manually".

compiler/*.m:
    Conform to the changes above, using the new utility predicates and
    functions where relevant. In several cases, this required fixing
    confusion of the kind described at the top. In all but one case,
    the confusion affected only variable names, but in one case,
    deconstruct_functor in make_goal.m, it caused a bug. The bug has
    had no effect up till now because deconstruct_functor is called
    only from three places: try_expand.m, stm_expand.m, and untupling.m.
    The incorrect mode (which was the nonsensical ground -> free)
    generated by the code of try_expand.m itself was discarded and
    overwritten when try_expand.m invoked the modechecker. (I don't
    know whether this bugfix makes that invocation redundant or not.)
    The other two modules, stm_expand.m and untupling.m, may do something
    similar, but in any case, they don't yet work for other reasons.
    (A bootcheck with --untupling causes a compiler abort when compiling
    deep_profiler/query.m in stage 2 both without and with this fix.)

    Delete no-longer-needed imports of the pair module (and of some other
    modules).

    Put the arguments of some predicates into a more logical order.

    In bytecode_gen.m, replace clauses with disjunctions, and delete the
    arguments that this step has revealed to be unused.
2016-05-19 10:43:24 +10:00
Zoltan Somogyi
828ed30fa6 Fix copyright message. 2015-12-12 12:48:32 +11:00
Zoltan Somogyi
5da837cc30 Carve error_msg_inst.m out of mode_errors.m.
compiler/error_msg_inst.m:
compiler/mode_errors.m:
    As above.

    Generalize the code now in error_msg_inst.m to allow it to be also used
    from add_mutable_aux_preds.m.

compiler/add_mutable_aux_preds.m:
    Use the facilities of error_msg_inst.m.

compiler/hlds.m:
compiler/notes/compiler_design.html:
    Add the new module.

compiler/hlds_out_mode.m:
compiler/parse_tree_out_inst.m:
    Add comments about obsolescence.
2015-11-30 03:36:32 +11:00