Commit Graph

888 Commits

Author SHA1 Message Date
Zoltan Somogyi
00e1a62ab4 Fix a misleading error message.
compiler/det_report.m:
    In some cases described in the new test case, the error message
    we print for a missing switch inside an arm of a larger switch
    is misleading unless we print *which* arm of the larger switch
    we are complaining about, so print that information.

tests/invalid/require_complete_nested_switch.{m,err_exp}:
    A test case derived from the real-life error that motivated this diff.

tests/invalid/Mmakefile:
    Enable the new test case.
2023-04-19 19:57:51 +10:00
Zoltan Somogyi
1ca63c2867 Run string_format_{bad,unknown} in profdeep grades.
tests/invalid/Mmakefile:
    These tests have not needed to catch exceptions in a long time,
    so there is no need to avoid running them in profdeep grades.
2023-03-19 14:10:29 +11:00
Zoltan Somogyi
2c866fb4d2 Avoid "overriding recipe" messages in tests/invalid.
tests/invalid/Mmakefile:
    Some tests cases in this directory have target-specific make rules
    if (and only if) the test flags include --intermod-opt. We used to include
    these tests in the lists of tests that do not have target-specific rules,
    which lead to messages about "overriding recipe for <target>" from make.
    Fix this by including test cases in the list of tests that do not have
    target-specific rules only if they belong there.

    Delete inappropriate entries from  REDIRECT_OPT_ERROR_MODULES, the list
    of tests cases that have target-specific make rules if (and only if)
    the test flags include --intermod-opt. Some of the modules that used
    to be in this list have since been moved to the invalid_make_int directory,
    where they don't need special handling (because what is special here
    is standard there). Some other modules in this list either never existed
    or have been deleted from the test suite as a whole. Delete both of these
    kinds of test case names from that list.

    Move the rules that figure out whether to enable a category of tests
    (e.g. the trailed tests) just after the definition of the list of tests
    in that category.

    Delete an obsolete comment, whose up-to-date form has been nearby
    for a while now.

    Add an XXX.

tests/invalid_make_int/Mmakefile:
    Note which test cases that have been moved here were included in
    REDIRECT_OPT_ERROR_MODULES, in case that does turn out to be useful later.
2023-03-19 02:49:22 +11:00
Zoltan Somogyi
40ff19acbb Standardize mode names in argument lists.
compiler/hlds_error_util.m:
    When converting lists of arguments mode to strings for error messages,
    replace from/to pairs of insts that stand for standard modes with the
    names of those standard modes.

compiler/prog_mode.m:
    Add a utility function for doing that standardization.

tests/invalid/io_in_ite_cond.err_exp:
tests/invalid_manual/gh118.err_exp:
    Expect the standard forms of modes.

tests/invalid_manual/Mmakefile:
    Specify the grade for the test independently of the grade of the
    workspace or of the last bootcheck. Make the Mercury compiler flags
    specific to the test.
2023-03-19 00:24:25 +11:00
Zoltan Somogyi
8758df5518 Fix compiler abort on non-model_det procedures.
Github issue #118 reports a compiler abort that happens when
table_gen.m attempts to perform that transformation that implements
the tabling of I/O actions for declarative debugging, and a sanity check
finds that the procedure's determinism is not model_det.

We could change table_gen.m to not transform the affected predicate
in such cases. This change could fix *this specific* compiler abort,
but it is better to fix the root cause, which is that our semantic analysis
passes have not detected and reported a violation of our semantic rules,
and have allowed the affected predicate to flow through to the middle end
to be processed.

compiler/det_analysis.m:
compiler/det_report.m:
    We used to check whether predicates with I/O state arguments have
    one of the permitted model_det determinisms as part of det_infer_proc.
    Github issue #118 arose because det_infer_proc processes only
    predicates defined in the current module. It was also strange that
    some properties of mode declarations were checked by det_infer_proc
    in det_analysis.m (which can be invoked on a procedure more than once
    during mode inference), while others were checked by
    check_determinism_of_procs in det_report.m (which is only ever invoked
    on a procedure once, at the end of determinism analysis).

    Move the checks on mode declarations all to det_report.m. Partly
    this is to fix the above code smell, but mainly so that we can add
    check_determinism_of_imported_procs, which performs the part of
    the job of check_determinism_of_procs that is appropriate for
    imported procedures.

    Make the error message for invalid mode declarations more specific
    by listing the given invalid determinism as well as the possible
    valid determinisms.

    To make the above possible without doing unnecessary checks on
    compiler-constructed procedures that are "born correct", separate out
    imported procedures from born-correct procedures. Previously, they
    were lumped together as "no inference needed" procedures.

tests/invalid/ho_unique_error.err_exp:
tests/invalid/mostly_uniq1.err_exp:
tests/invalid/mostly_uniq2.err_exp:
    Expect the extra detail in error messages.

tests/invalid/io_in_ite_cond.err_exp:
tests/invalid/magicbox.err_exp:
tests/invalid/try_detism.err_exp:
    Expect an error message about the invalid determinism of a procedure
    with I/O state args. Previously, we did not generate an error message
    for these issues.
2023-03-16 16:27:03 +11:00
Zoltan Somogyi
1e9eb51c8b Break det_infer_proc into smaller pieces.
compiler/det_analysis.m:
    Carve three separate predicates out of det_infer_proc. Besides improving
    readability, one of the new predicates should be useful in the fix for
    github issue #118.

    Factor out the common initial and final parts of two related but
    different long error messages.

    Improve the wording of some error messages.

    Replace two separate traversals of the list of pragma exported procedures
    with one.

tests/invalid/ho_unique_error.err_exp:
tests/invalid/mostly_uniq1.err_exp:
tests/invalid/mostly_uniq2.err_exp:
tests/invalid/one_member.err_exp:
    Expect the updated wording in error messages.
2023-03-16 09:46:04 +11:00
Zoltan Somogyi
eecf8b6b15 Complain about no clauses for pred/func ...
compiler/typecheck_error_undef.m:
    ... only if that predicate or function was declared by the user.
    If the compiler itself added the pred/func declaration implicitly
    because it saw a clause for that pred/func, but then decided not to
    add that clause to the HLDS after all because it had syntax errors,
    then don't complain about the absence of a clause for a pred/func
    that the user did not declare.

tests/invalid/state_vars_test3.err_exp:
    Expect no complaint about a missing clause in the above situation.
2023-02-08 14:55:40 +11:00
Zoltan Somogyi
b843d53a4c Improve actual/expected mismatch diagnostics.
compiler/typecheck_errors.m:
    Improve the diagnostics we generate for mismatches between actual and
    expected types. If the mismatch was between a single actual type and
    a single expected type, we already printed a message whose format
    was specialized for that case, but in every other case, we fell back
    to a more general but less readable error message template. Improve on this
    by splitting the task into two halves, one for the actual type(s) and one
    for the expected type(s), each of which generates simpler text if
    there is only one such type.

    Separate the actual type part of the diagnostic from the expected type part
    using a semicolon instead of a comma, because we now use commas to
    separate multiple actual types from each other, and multiple expected
    types from each other.

    Don't insist on putting a newline after the "type error:" part of the
    diagnostic.

    Do all of the above in just one predicate, factoring out code that
    used to be duplicated.

    Delete a function that has never been used. (I added it around 2008
    for later use by a student working on software transactional memory,
    but that use never happened.) This used to contain a third copy
    of the code that was factored out.

    For functions that used to take both a typecheck_info and a
    type_error_clause_context, delete the latter argument, since the caller
    invariably took it out of the typecheck_info that it also passed.

compiler/typecheck.m:
    Don't pass now-unneeded type_error_clause_contexts.

compiler/typecheck_error_type_assign.m:
    Fix typo in a field name.

tests/invalid/abstract_eqv.err_exp:
tests/invalid/actual_expected.err_exp:
tests/invalid/actual_more_expected.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/foreign_procs_exist_type.err_exp:
tests/invalid/higher_order_mode_mismatch.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/try_bad_params.err_exp:
tests/invalid/type_diff.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/invalid/types2.err_exp:
tests/invalid_nodepend/errors2.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:
    Update expected error messages.
2023-02-02 15:44:11 +11:00
Zoltan Somogyi
1e097a8d18 Avoid some make warnings about overriding recipes. 2022-12-07 11:18:00 +11:00
Zoltan Somogyi
c5fc9a929d Print the contexts of later disjuncts ...
compiler/det_report.m:
    ... when a "declared det, inferred multi" kind of determinism error
    is caused by the (probably unexpected, possibly hard-to-see) presence
    of a disjunction.

    Change the wording to refer to "disjuncts" instead of "clauses";
    while in Mercury, all clauses in multi-clause definitions are implicitly
    also disjuncts, not all disjuncts are whole clauses.

tests/invalid/bug496.err_exp:
tests/invalid/det_errors.err_exp:
tests/invalid/not_a_switch.err_exp:
tests/invalid/require_scopes.err_exp:
tests/invalid/switch_arm_multi_not_det.err_exp:
    Expect the updated form of the error message.
2022-12-04 23:33:37 +11:00
Zoltan Somogyi
4bf9b33481 Warn about the need to import intN/uintN modules.
compiler/typecheck_errors.m:
    When we are reporting a type error in a var-functor unification
    where the functor is the name of a function defined in library/int.m,
    such as A = B - C or D = E + F, check whether

    (a) the types of any of the variables involved in the error, *and*
    (b) the expected argument or result types involved

    are builtin integer types whose modules have NOT been imported.
    If so, then add a note to the error message that points out
    that operations on these type(s) require importing the corresponding
    modules.

    Do the same when reporting type errors in calls to predicates
    whose name is the name of a predicate defined in library/int.m.

    Fix an old ZZZ.

compiler/type_assign.m:
    Fix typo in a (so far unused) field name.

tests/invalid/arith_wrong_module.{m,err_exp}:
    A new test case with three errors, which respectively test the changes
    to the three error-message-generating predicates modified by this diff.

tests/invalid/Mmakefile:
    Enable the new test case.
2022-11-25 03:18:29 +11:00
Zoltan Somogyi
f1745bba2d Systematize error reporting in check_typeclass.m.
compiler/check_typeclass.m:
    As above. This makes future changes to the main code of the module easier.
    In some cases, this required carving error message generating code
    out of larger predicates.

    Some errors were being generated by functions that returned an error_spec,
    and others by predicates that added the new error_spec to !Specs.
    Standardize on the latter scheme.

    Use some recently-added auxiliary functions to generate parts of some
    error messages, to present the same info the same way in different
    error messages. This part of the diff causes the changes to .err_exp files
    below.

    Start the name of all the predicates that generate error with "report_".

    Return !:Specs. Do not take an an initial !.Specs argument, because
    any error_specs in it would screw up a test. Our caller always passed us
    [] anyway.

    The non-error-reporting code in this module is (currently) divided into
    six passes. The code that checks for cycles between typeclasses is the
    third pass, but its code was after the code of the fourth pass; fix that.

    Turn some functions into predicates to allow the use of state variables.

    Rename a function symbol to avoid an ambiguity.

    Fix comment rot.

compiler/mercury_compile_front_end.m:
    Don't pass [] as the initial !.Specs.

compiler/hlds_class.m:
    Move a type definition to its proper place.

tests/invalid/bad_instance2.err_exp:
tests/invalid/constraint_proof_bug_lib.err_exp:
tests/invalid/invalid_instance_declarations.err_exp:
    Expect updated error messages.
2022-11-24 10:05:06 +11: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
5eca1f9666 Improve presentation of actual/expected types.
Before this diff, typecheck_error.m could generate error messages like this:

a02x.m:020: In clause for predicate `p1'/3:
a02x.m:020:   in argument 1 of call to predicate `foldl'/4:
a02x.m:020:   type error: type of argument does not match its expected type;
a02x.m:020:   argument has overloaded actual/expected types {
a02x.m:020:     (expected) pred(L, A, A),
a02x.m:020:     (expected) pred(character, A, A),
a02x.m:020:     (inferred) pred(int, a02x.dir, int),
a02x.m:020:     (inferred) pred(int, a02x.dir, int)

As evidenced by a post on m-users, this can be confusing, because the message
says nothing about where the expected types came from.

This diff changes the way we generate error message for errors in which
there is one actual inferred type, but two or more expected types.
It changes the output in two ways:

- it identifies the sources of the expected types, and
- it prints the inferred type just once.

The message we generate for the same code is now

a02x.m:020: In clause for predicate `p1'/3:
a02x.m:020:   in argument 1 of call to predicate `foldl'/4:
a02x.m:020:   type error: type of argument does not match its expected type;
a02x.m:020:   its inferred type is
a02x.m:020:     pred(int, a02x.dir, int),
a02x.m:020:   the type expected by predicate `list.foldl'/4 is:
a02x.m:020:     pred(L, A, A),
a02x.m:020:   the type expected by predicate `string.foldl'/4 is:
a02x.m:020:     pred(character, A, A).

compiler/type_assign.m:
    Expand the args_type_assign type to include a source of the expected type.

    To make this possible, move the cons_type_info type here from
    typecheck_info.m.

    In the process, both simplify and expand one of the cons_type_info type's
    components, the cons_type_info_source type. Simplify it by replacing
    the two sources source_{get}_field_access, which are always treated
    near-identically, with just one source, source_field_access, which has
    an extra field specifying get vs set. Expand it by specifying two details
    we didn't need before: the cons_id if the cons_type_info came from
    a data constructor in a type_ctor, and the field name if it came from
    a field access function.

    Give some fields less misleading names. Update the names of functions
    returning these fields accordingly.

compiler/typecheck_info.m:
    Delete the code moved to type_assign.m.

compiler/typecheck.m:
    Record the sources of args_type_assigns.

    Use more consistent variable names.

    Fix some misleading predicate names.

    Put loop-invarient input arguments before non-loop-invariant arguments.

    Fix bit-rot in some comments.

compiler/typecheck_errors.m:
    As mentioned above, if there is just one actual (inferred) type,
    but two or more expected types, then

    - print the inferred type just once, and
    - identify the sources of the expected types.

    Put the fields of the arg_type_stuff in the same order as our
    error message: inferred, then expected.

    Add some XXXs.

compiler/post_typecheck.m:
    Fix a comment.

tests/invalid/actual_more_expected.{m,err_exp}:
    Add this test case, which is derived from the program on m-users.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
    Enable the new test case, and invoke it with -E.
2022-10-16 15:42:30 +11:00
Zoltan Somogyi
3fb55722be Print structured terms on one line if they fit.
The compiler's diagnostic outputs often contain terms, representing
either terms in the program, or other entities such as types or modes.
These can be printed either as

    f(a, b)

or as

    f(
        a,
        b
    )

We usually want the former if the term fits on one line, but the latter
if it is too big to fit on one line. The problem is that the code
generating the diagnostic often does not know what fits on one line.

compiler/error_spec.m:
    This diff adds two new format pieces that respectively stand for
    each half of a matched pair of left and right parentheses.
    The idea is that these can be printed

    - either with a newline, and an indent increment, after the left paren,
      and an indent decrement, and a newline, before the right paren,
      and with all newlines being honored between them,
    - or with no newline after the left paren or before the right paren,
      and all newlines between them being replaced by spaces.

compiler/write_error_spec.m:
    Implement the new format pieces, using the one-line format above
    if the term fits in the space available, or the multi-line format
    if it does not.

compiler/error_type_util.m:
    Use the new mechanism to represent the structure of types.

    Delete an old piece of code that had the same objective,
    but was much cruder and less effective.

tests/invalid/actual_expected.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/ho_type_arity_bug.err_exp:
tests/invalid/overloading.err_exp:
tests/invalid/type_diff.err_exp:
    Expect more compact representations of the structure of types.

tests/invalid/type_error_ambiguous.err_exp:
    Expect a different ordering of the same information.
    The difference is due to the changed internal representation
    (in terms of format_pieces) of a type.
2022-10-14 19:13:38 +11:00
Zoltan Somogyi
50c3301737 Simplify some code in error_util.m.
compiler/error_util.m:
    Interpret each context just once per error_msg, not once per line.

    Add the fixed indent after the context, creating a prefix string,
    just once per error_msg, not once per line.

    Compute the length of the prefix directly from the prefix string,
    instead of counting the characters that go into its components.

    Don't print out the line-specific indent on blank lines.

    Replace a quadratic algorithm with a linear one.

    For each line we output, record the total length of its words,
    and the total length available for those words. This prepares
    for a future change that will try to replace several lines, even if
    they ended with "nl" pieces, with one,

    - if the result fits in the available space, and
    - if the text of the lines indicates this is desirable.

compiler/hlds_out_util.m:
compiler/prog_out.m:
    Move the code for writing out indents from hlds_out_util.m to prog_out.m.
    We now want to call it from error_util.m, and it does not depend on the
    HLDS at all.

tests/invalid/anys_in_negated_contexts.err_exp:
tests/invalid/ho_default_func_1.err_exp:
tests/invalid/ho_default_func_3.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/modes_erroneous.err_exp:
tests/invalid_nodepend/errors2.err_exp:
tests/warnings/inconsistent_pred_order.exp:
tests/warnings/subtype_order.exp:
    Don't expect the line-specific indent on blank lines.
2022-10-12 15:34:49 +11:00
Zoltan Somogyi
0f75764e41 Pinpoint more actual/expected type differences.
compiler/typecheck_errors.m:
    When there is a difference between actual and expected types
    in predicate calls, do not just print the actual and expected types,
    but if possible, point out the specific part(s) that cause the difference.
    For example, report differences in arities, purity, determinism etc.
    Also point out cases where the code is trying to specify the value
    of an existentially quantified type variable.

    When higher order types are printed as part of an error message,
    strip any builtin qualifiers not just from the names of types,
    but also from the names of the argument modes.

    Start each part of an actual/expected pair at the same level of
    indentation.

compiler/error_util.m:
    Add a way to print out small integers as english names (one, two etc)
    instead as numerals (1, 2 etc).

    Add a way to print out purity descriptions.

    Add a component, treat_next_as_first, that specifies that the next
    format_component should be treated as the first part of a sentence
    with respect to (de)capitalization by lower_next_if_not_first,
    even if it is preceded by other format_components in a message.
    This is useful in cases where the code that generates part of an
    error message does not know whether that part will end up at the start
    of the sentence, as the

        <preceding sentence, ending in a period>
        treat_next_as_first <context> lower_next_if_not_first, Words ...

    sequence will keep Words capitalized if <context> is empty,
    but will decapitalize it if <context> is not empty.

    Rename {qual,unqual}_pf_sym_name_orig_arity as
    {qual,unqual}_pf_sym_name_pred_form_arity, since this is clearer.

compiler/prog_out.m:
    Apply the same s/orig_arity/pred_form_arity/ rename to some functions.

compiler/module_qual.qual_errors.m:
    Fix an unrelated problem I came across while working on the changes above:
    stray spaces at the ends of words(...) format_components, which screwed up
    some error messages.

    Simplify the description of classes and predicates by using facilities
    in error_util.m that did not yet exist when this code was converted
    to use error_util.m.

compiler/prog_type.m:
    When stripping builtin qualifiers from types, strip them from the
    modes stored in the higher_order inst into of higher order types as well,
    for the same reason: to eliminate clutter in error messages.

    Make the strip_kind_annotation function return a value that
    shows in its type that the result will *not* be a kinded_type.
    THIS IS THE FIRST USE OF SUBTYPES IN THE COMPILER.

compiler/type_assign.m:
    Fix a long-standing documentation problem.

    The type_assign type has long had a field named ta_external_type_params,
    whose type was external_type_params, which was defined as equivalent
    to a list of type variables. The name does not say what kinds of type
    variables it contains, but the only two places that add type vars to
    this field add type vars that are existentially quantified, either
    by a predicate, or a cons_id. This diff therefore renames this field
    to ta_existq_tvars, and changes its type to be just plain list(tvar).
    (The external_type_params type has no documentation, so it may be used
    to store different kinds of type variables in different places,
    some of which may *not* be existentially quantified. Using the same name
    for different purposes may be confusing.)

compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/convert_parse_tree.m:
compiler/hhf.m:
compiler/hlds_desc.m:
compiler/hlds_out_util.m:
compiler/make_hlds_error.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/module_qual.qualify_items.m:
compiler/post_typecheck.m:
compiler/pred_table.m:
compiler/typecheck.m:
compiler/typecheck_debug.m:
compiler/typeclasses.m:
    Conform to the changes above.

tests/invalid/fbnf.{m,err_exp}:
    The motivating test case for this diff, slightly modified
    from the code posted to m-users.

tests/invalid/type_diff.{m,err_exp}:
    A test case to test the parts of the new code in typecheck_errors.m
    that are not covered by other tests.

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

tests/invalid/ext_type_bug.{m,err_exp}:
    Extend this test case to test the pinpointing of errors that try to bind
    existentially quantified type variables, at both the top level
    and nested inside other type constructors.

tests/invalid/bug197.err_exp:
tests/invalid/higher_order_mode_mismatch.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:
    Expect pinpointed type differences in these error messages.

tests/invalid/abstract_eqv.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/try_bad_params.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/invalid/types2.err_exp:
tests/invalid_nodepend/errors2.err_exp:
    Expected updated formatting in these error messages.
2022-10-11 22:59:03 +11:00
Zoltan Somogyi
2028df3f20 Fix references to func results in a mode error.
compiler/mode_errors.m:
    If the argument whose instantiation we are complaining about is
    the result of a function, say so.

tests/invalid/mode_error_arg_number.{m,err_exp}:
    Add a test of this message.

tests/invalid/bug117.err_exp:
tests/invalid/coerce_int.err_exp:
tests/invalid/html.err_exp:
tests/invalid/inst_matches_final_bug.err_exp:
    Expect the correct reference to function results in these test cases.
2022-10-01 13:06:20 +10:00
Zoltan Somogyi
4615e7f559 Fix an argument number in a mode error.
This fixes an issue reported on m-users on sep 23, which was caused by
the compiler counting a type_info argument added by the polymorphism pass.

compiler/hlds_pred.m:
    Add a field for recording the number of arguments added by the
    polymorphism transformation. We could try to figure this out
    by counting how many type_info and/or typeclass info args
    the argument list contains as an initial subsequence,
    and the compiler has code that does that, but this approach
    is vulnerable if user code ever passes around e.g. type_infos
    *explicitly*, which would be very unusual, but not impossible.

compiler/polymorphism.m:
    Fill in this new field.

compiler/mode_errors.m:
    Use the new field to fix the argument number in the error message.
    (This seems to be the only mode error that makes such a reference.)

compiler/direct_arg_in_out.m:
    Conform to the change in hlds_pred.m above.

compiler/mode_info.m:
    Clarify some comments.

compiler/modes.m:
    Fix indentation.

tests/invalid/mode_error_arg_number.{m,err_exp}:
    The code in the original bug report, made into a new test case.
tests/invalid/Mmakefile:
    Enable the new test case.

tests/invalid/bug278.err_exp:
tests/invalid/bug415.err_exp:
tests/invalid/merge_ground_any.err_exp:
    Expect the correct argument number in these test cases. The old
    expected argument numbers were wrong, which means that we had missed
    at least three chances to find the bug that this diff fixes. The
    wrong argument number was in merge_ground_any.err_exp at its creation
    in 2001.
2022-09-26 08:40:40 +10:00
Zoltan Somogyi
66873a528a Fix the handling of status in add_pragma.m.
compiler/add_pragma.m:
    The status checks in this module used to check for only one
    of the four possible combinations of <is pragma exported, is the
    pred the pragma is for expored>, even though we may want to generate
    errors or warnings in three of those combinations. Fix this.

    If an ambiguous pragma applies to more than one predicate, handle
    the status checks of each separately.

    When adding fact table pragmas to the HLDS, replace several lines
    of code that reuse an existing largish predicate with the single line
    of code from that predicate that we actually need.

    Stop representing the statuses of pragmas using the pred_status type,
    since the item_mercury_status that all items come with is adequate
    for all our needs, and is impossible to confuse with the status
    of the pred_info they refer to.

library/exception.m:
library/require.m:
    Move termination pragmas for exported predicates and functions
    from the implementation section to the interface section. This
    avoids a warning that we now generate in such situations.

tests/term/exception_analysis_test.trans_opt_exp:
tests/term/exception_analysis_test2.trans_opt_exp:
    Expected improved termination analysis results now that we export
    termination pragmas that used to be kept private.

tests/warnings/foreign_term_invalid.{m,exp}:
    Avoid warnings about keeping decl pragmas about exported predicates
    private by moving them into the interface.

    Fix the formatting of the top-of-module comment.

    Expect updated line numbers.

tests/warnings/pragma_term_conflict.{m,exp}:
    Don't avoid a warning about keeping decl pragmas about exported predicates
    private. Instead, document it as an additional purpose of this test.

    Expect both the extra warning and updated line numbers.

tests/invalid/pragma_export.{m,err_exp}:
    A new test case for testing the error message for inappropriately
    exported pragmas.

tests/invalid/Mmakefile:
    Enable the new test case.
2022-09-24 19:12:18 +10:00
Zoltan Somogyi
a32d6a16f4 Add the format_call pragma to the language.
doc/reference_manual.texi:
NEWS:
    Document and announce the new pragma.

compiler/prog_data_pragma.m:
compiler/prog_item.m:
    Provide a representation for the new pragma. The part that ends up
    being referred to from the HLDS goes into prog_data_pragma.m,
    the part that is not needed once the HLDS has been constructed
    goes into prog_item.m.

compiler/hlds_pred.m:
    Add a slot to pred_infos for info from the new pragma.

    Fix a bug in the comment on marker_has_format_call.

compiler/add_pragma.m:
    Add the information in these pragmas to the HLDS.

compiler/check_pragma_format_call.m:
    A new module to check the validity of format_call pragmas.
    These checks test whether the arguments named in such pragmas
    have the expected types and modes, which means that
    the check must be done after both type and mode checking.

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

compiler/hlds_module.m:
    Add a field to the module_info that records the set of pred_ids
    that have format_call pragmas.

compiler/mercury_compile_front_end.m:
    Invoke the check_pragma_format_call pass *provided* that
    the new field in the module_info says it has any pragmas to check.

compiler/parse_pragma.m:
    Add code to parse the new pragma.

compiler/format_call.m:
    Check calls to predicates and functions with the new pragma
    the same way as we check calls to string.format, io.format,
    and stream.string_writer.format.

    This required separating the code that checked calls to such predicates
    from the code that optimized calls to such predicates, since

    - a predicate or function with a format_call pragma that specifies
      more than one argument pair has to have its correctness checked
      for each pair, and

    - a predicate or function with a format_call pragma does not actually
      do any formatting, so that formatting cannot be optimized.

    Fix an old bug, where we included the function result in the function's
    reported arity, which meant that an error message could mention a call
    to a nonexistent function. As part of that fix, the error message
    now specifies whether it is complaining about a call to a predicate
    or a function.

    Change the exported interface of this module a bit
    in order to allow the factoring out of repeated code.

compiler/parse_string_format.m:
    Separate the parsing of format strings from their optimization,
    again because calls to predicates and functions with format_call
    pragmas need to be checked but cannot be optimized.

compiler/polymorphism.m:
    Record the effect on argument numbers of any type_info and/or
    typeclass_info arguments added by this pass.

compiler/convert_parse_tree.m:
compiler/det_analysis.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/hlds_out_pred.m:
compiler/item_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
compiler/simplify_proc.m:
    Conform to the changes above.

tests/invalid/bad_format_call.{m,err_exp}:
    A new test case to see whether check_pragma_format_call.m detects
    and reports invalid format_call pragmas as expected.

tests/warnings/format_call_warning.{m,exp}:
tests/warnings/format_call_warning_helper.m:
    A new test case to see whether we generate the expected set of error
    messages for incorrect calls to a predicate with a format_call pragma.

tests/invalid/Mmakefile:
tests/warnings/Mercury.options:
tests/warnings/Mmakefile:
    Enable the new test cases.

tests/invalid/string_format_bad.err_exp:
tests/invalid/string_format_unknown.err_exp:
tests/warnings/disabled_warning.exp:
    Expect the predicate vs function distinction to the printed in
    error messages about bad calls to formatting predicates and functions.
2022-09-24 08:42:36 +10:00
Zoltan Somogyi
26be4bb8e3 Add --warn-ambiguous-pragmas.
The new option is on by default, and it generates a warning about pragmas
that specify a name/arity pair that matches both a predicate and a function,
but does not say which one it is intended to apply to.

compiler/options.m:
doc/user_guide.texi:
    Add the new option.

NEWS:
    Announce the new option.

compiler/add_pragma.m:
    Implement the new option.

    Move to one predicate, get_matching_pred_ids, the code for dealing with
    both the absence of any matches, and the presence of more than one match,
    when looking up name/arity pairs in the predicate table. This allows us
    to delete the mostly-duplicate code fragments that did the same thing
    in all of get_matching_pred_ids's callers.

    Simplify the handling of conflicts between marker pragmas.

compiler/hlds_pred.m:
    Separate out no_inline decisions made by the compiler itself from
    the similar decisions made by users, in order to allow that simplification.

    Move the two inline markers next to each other.

compiler/make_hlds_error.m:
    Change a predicate called from add_pragma*.m to take user arities
    in their semantic form, not their int form, which raises the level
    of the predicate's interface, and factors out duplicate code in its
    callers.

compiler/add_pragma_type_spec.m:
compiler/intermod.m:
compiler/table_gen.m:
    Conform to the changes above.

doc/reference_manual.texi:
    Document pred(...) and func(...) wrappers around name/arity pairs
    in pragmas.

    Delete the commented out section on reserve_tag pragmas, which were
    deleted a while ago.

tests/invalid/inline_conflict.m:
    Expand this test case to test the *absence* of a warning for an
    ambiguous pragma with --no-warn-ambiguous-pragma.

tests/invalid/inline_conflict_warn.{m,err_exp}:
tests/invalid/Mercury.options:
    Add a copy of the inline_conflict test case to test the presence of
    a warning for an actually ambiguous pragma.

tests/invalid_nodepend/fact_table_in_interface.err_exp:
    Expect the updated wording of a warning.
2022-07-31 18:17:02 +10:00
Zoltan Somogyi
7d11ba1e5c Fix a bug in handling badly qualified sym names.
Type specialization pragmas allow the procedure to be specialized
to be specified either as a sym_name/arity pair, or as a sym_name
followed by a list of argument modes. In both cases, the sym_name
is implicitly qualified with the name of the current module.

The problem that this diff fixes arose when the type_spec pragma
specified the procedure as a sym_name/arity pair, but the sym_name
had a qualification that is inconsistent with the current module.
The code for parsing such pragmas should report this qualification
inconsistency, but the old code did not do that. Instead, it took
the failure of the attempt to parse the sym_name/arity pair as a
*properly qualified* sym_name pair to mean that the procedure specification
must be a sym_name applied to argument modes, and as a consequence,
generated a report that said "In the first argument `:- pragma type_spec'
declaration: error: `1' is not a valid inst", which definitely violates
the law of least astonishment.

The fix is to commit to interpreting a procedure specification
as a sym_name/arity pair as soon as we see that the relevant term
has this structure, and report any problem during the implicit qualification
of the sym_name using an error message appropriate to that commitment.

compiler/parse_util.m:
    Delete parse_implicitly_qualified_name_and_arity, because it inherently
    does not allow the failure of implicitly module qualifying of a sym_name
    to be treated differently from the failure to parse a term as a sym_name
    and arity pair. This deletion thus requires all its callers to handle
    the implicit qualification themselves.

    Rename the parse_unqualified_name_and_arity predicate, which does the
    initial part of the job of the deleted predicate, to just
    parse_sym_name_and_arity, because the sym_name it returns may in fact
    be qualified in the input data; the predicate just doesn't *force* it
    to be qualified.

compiler/parse_pragma.m:
compiler/parse_type_defn.m:
    Replace calls to the deleted predicate with code that explicitly does
    implicit qualification of the symbol name in sym_name/arity pairs.

compiler/parse_sym_name.m:
    When implicitly module qualifying sym_names fails, replace the word
    "definition" in the error message with the sym_name itself, since
    the sym_name does not HAVE to be the name of something being defined.
    In the two test cases affected by this diff, they are in fact a type_spec
    pragma, and an include_module declaration.

    In another pair of cases, change the wording of some error messages
    to match our usual phraseology. Those error messages are apparently
    not tested by any test case.

compiler/parse_inst_mode_defn.m:
compiler/parse_pragma_foreign.m:
compiler/parse_type_repn.m:
compiler/recompilation.used_file.m:
    Conform to the rename above.

tests/invalid/type_spec.{m,err_exp}:
    Extend this existing test case with an incorrectly module-qualified
    procedure name in a type_spec declaration.

tests/invalid_nodepend/bad_include.err_exp:
    Expect the updated wording of the error message about an incorrectly
    module-qualified include declaration.
2022-07-05 14:52:56 +10:00
Zoltan Somogyi
8122e83d2a Record typechecking results in var_tables.
compiler/hlds_clauses.m:
    The clauses_info type used to have two fields whose type is "vartypes".
    One contained type information we knew before typechecking, e.g. from
    explicit "Var : type" annotations, while the other contained the
    *results* of typechecking. Keep the former, but replace the latter
    with a var_table.

    Allow compiler passes that construct clauses to fill in the first field
    with the types of the head variables, because for the clauses of some
    kinds of predicates (such as predicates implementing builtins) that are
    "constructed correct" and do not need typechecking, this is all we need.

    Put the fields of clauses_info that deal with variables and their types
    next to each other, in the order in which they are filled in.

compiler/add_clause.m:
    Don't construct the context pieces needed for parsing mode annotations
    on arguments in the clause head unless the clause head's arguments
    *have* mode annotations, which they virtually never do.

compiler/add_pred.m:
compiler/add_special_pred.m:
    Put the types of the head variables into the var_table in the clauses_info
    we create for clauses for builtin predicates and unify/compare/index
    predicates respectively, for use by unused_imports.m.

compiler/typecheck.m:
    Fill in the var_table field in

    - predicates we have typechecked,
    - predicates for which we have created stub clauses that are
      "born type-correct", and
    - predicates for class methods whose code will be created later,
      during the polymorphism pass.

    In the last case, we fill in only the types of the head variables,
    preserving old behavior.

    Give some predicates more meaningful names. Inline a predicate at its
    only call site.

compiler/post_typecheck.m:
    Switch to using the var_tables computed by typechecking.

    Reset varsets in clauses_infos to empty, to tell hlds_out_pred.m
    not use it as the source of variable name info.

compiler/hlds_pred.m:
    Provide functionality to record the types of head variables
    in both vartypes and in var_tables.

compiler/hlds_out_pred.m:
    Get information about variable names from either the clauses_info's
    varset field (if the varset is nonempty, not yet having been reset
    by post_typecheck.m), or from its var_table field (if the varset
    *has* been reset to empty).

    Likewise, get information about variable types from either the
    clauses_info's var_table field (if it is not empty, having been filled in
    either by typechecking or by code created the type clauses "type-correct"
    at the start), or from its explicit_vartypes field (if the var_table field
    has not yet been filled in).

    It is possible that in the future, we may want to dump out the
    contents of the explicit_vartypes field even if the var_table
    has also been filled in. However, since the old code of write_pred
    had no such functionality, the chance we will need that in the future
    is small, and we can deal with it when the issue does arise.

compiler/goal_path.m:
compiler/hlds_out_goal.m:
compiler/intermod.m:
compiler/unify_proc.m:
    Convert these modules to use var_tables.

compiler/prog_type.m:
compiler/type_util.m:
    Record the fact that the builtin type "store_at_ref_type" is not a dummy
    type. Without this special-casing, the creation of a var_table containing
    a variable of this type would crash the compiler, because

    - unlike other builtin types, this one *has* a definition, in
      private_builtin.m, but
    - since it is a builtin type, its "definition" in the type table
      has no representation information, so the code of is_type_a_dummy
      cannot tell if that "definition" is a dummy or not.

compiler/prog_util.m:
    Provide the var_table equivalent of an existing utility predicate
    for varsets.

compiler/qual_info.m:
    Give a field of the qual_info type a more meaningful name.

compiler/typecheck_errors.m:
    Fix argument order and variable names.

compiler/vartypes.m:
compiler/var_table.m:
    Add a predicate to check whether a variable has a user-given name.

    Replace the varset_vartypes type in vartypes.m with the type_qual type
    in var_table.m, which uses var_tables, since its user, hlds_out_goal.m,
    has been converted to use var_tables. (Most variables of this type
    have been named TypeQual, which is why the type now has that name.)

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

    Export the definition of the inst_graph_info type, instead of exporting
    a getter and a setter for every one of its fields.

compiler/higher_order.m:
    Conform to the changes above, by calling clauses_info_init,
    instead of repeating its code here.

compiler/accumulator.m:
compiler/add_foreign_proc.m:
compiler/add_pragma_type_spec.m:
compiler/build_mode_constraints.m:
compiler/check_promise.m:
compiler/clause_to_proc.m:
compiler/format_call.m:
compiler/hhf.m:
compiler/instance_method_clauses.m:
compiler/lambda.m:
compiler/mode_constraints.m:
compiler/old_type_constraints.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/polymorphism_info.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/stm_expand.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
    Conform to the changes above.

tests/invalid/illtyped_compare.err_exp:
    Expect an improved variable name from unify_proc.m.

tests/invalid/try_detism.err_exp:
    Expect a different variable number for an unnamed variable.
2022-05-29 15:22:16 +10:00
Zoltan Somogyi
03c9135991 Stop using varsets/vartypes in the MLDS backend.
compiler/ml_args_util.m:
compiler/ml_closure_gen.m:
compiler/ml_code_util.m:
compiler/ml_proc_gen.m:
    As above.

compiler/hlds_pred.m:
    The code in the MLDS code generator that handles calls reuses
    some code in ml_args_util.m that it uses for the clause head,
    and thus derived the names of some MLDS variables from the
    varset of the callee. In the case where the callee is a unify
    or compare predicate for an imported type, the varset contained
    the names of the argument variables, but not their type. This means
    that looking up their names in the var_table instead of the varset
    requires the var_table to contain every variable that the varset contains,
    so change the code that constructs the var_table to ensure this.

    Add a var_table version of another predicate to prepare for a future
    change.

tests/invalid/try_detism.err_exp:
    Update the variable number of an unnamed variable after the changes
    in hlds_pred.m.
2022-05-15 11:49:22 +10:00
Zoltan Somogyi
b96a90f948 Parse disjunctions using tail recursive code ...
to allow even very long disjunctions to be parsed in constant stack space.
This fixes Mantis bug #559.

compiler/prog_item.m:
    We used to represent a disjunction like ( GoalA ; GoalB ; GoalC ; GoalD )
    in the parse tree as

        disj_expr(ContextA, GoalA,
            disj_expr(ContextB, GoalB,
                disj_expr(ContextC, GoalC,
                    GoalD)))

    To enable the changes in parse_goal.m and parse_dcg_goal.m, switch over
    to representing them as

        disj_expr(ContextA, GoalA, GoalB, [GoalC, GoalD])

    The type of this term enforces the invariant that a disjunction
    must have at least two disjuncts.

    The fact that this throws away ContextB and ContextC is not a problem;
    they were never used, being thrown away when converting the parse tree
    to the HLDS.

compiler/parse_goal.m:
compiler/parse_dcg_goal.m:
    After seeing the first comma in the above disjunction, these parsers
    used to (1) parse its left operand, GoalA, (2) parse its right operand,
    ( GoalB ; GoalC ; GoalD), and then (3) check for errors. This code
    was prevented from being tail recursive both by the presence of step 3,
    and the fact that step 2 indirectly invokes another predicate that
    (until my previous change to parse_goal.m) had a different determinism.

    Fix the first issue by having the new predicate parse_goal_disjunction,
    and its DCG variant, accumulate errors *alongside* disjuncts,
    to be checked just once, at the end, outside the loop. Fix the second
    issue by having parse_goal_disjunction test whether the right operand
    of the semicolon has the form of a disjunction, and if it does,
    recursing on it directly. This makes parse_goal_disjunction
    self-tail-recursive, which should allow it to process disjunctions
    of arbtrary length using fixed stack space (in grades that support
    tail recursion, that is).

    Move the code to flatten disjunctions from goal_expr_to_goal.m to
    these modules, because it is simpler to get the right result this way
    in DCG clauses (for non-DCG clauses, it works simply either way).

compiler/goal_expr_to_goal.m:
    Convert the updated parse tree representation of disjunctions to HLDS,
    and don't flatten disjunctions here anymore.

compiler/parse_item.m:
    Add some infrastructure for debugging changes like this.

compiler/add_clause.m:
    Improve the infrastructure of debugging changes like this, by making it
    more selective.

    To make this possible, pass the predicate name to a predicate
    that did not need it before. Fix the argument order of that predicate.

compiler/make_hlds_warn.m:
    Don't flatten parse tree disjunctions, since the code constructing them
    has done it already.

compiler/get_dependencies.m:
compiler/module_qual.collect_mq_info.m:
compiler/parse_tree_out_clause.m:
compiler/prog_item_stats.m:
compiler/prog_util.m:
    Conform to the change in prog_item.m.

compiler/instance_method_clauses.m:
    Conform to the change in add_clause.m.

tests/hard_coded/flatten_disjunctions.{m,exp}:
    A new test case both testing and documenting the need for flattening
    disjunctions.

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

tests/invalid/require_switch_arms_detism.err_exp:
    Expect updated numbers for anonymous variables. This is due to
    goal_expr_to_goal.m now processing disjuncts in a different order
    than before.
2022-05-06 15:19:49 +10:00
Zoltan Somogyi
425e873124 Convert purity analysis to var_tables.
compiler/purity.m:
compiler/resolve_unify_functor.m:
    As above. (resolve_unify_functor is invoked as part of the purity pass.)

    Fix argument order.

tests/invalid/try_detism.err_exp:
    Expect an updated number for an unnamed variable. Until now,
    the compiler's vartypes table had a hole; it had entries for
    variables 16, 17 and 18, but not 15. This means that a compiler
    pass allocated var 15 from the varset, but did not add an entry
    to the vartypes, which is an invariant violation, though since there
    the HLDS for the affected predicate has no reference to var15,
    it is a harmless violation. Now that the purity pass uses var_tables,
    the act of putting the var_table (which has an entry for each entry
    in the vartypes) back into the pred_info effectively deletes var 15,
    so all variables allocated later get a variable one smaller
    than they did before.
2022-05-02 16:55:51 +10:00
Zoltan Somogyi
0ab6993894 Convert mode analysis to use var_tables.
compiler/instmap.m:
compiler/mode_comparison.m:
compiler/mode_debug.m:
compiler/mode_info.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/unique_modes.m:
    Convert these modules to use var_tables.

compiler/mode_errors.m:
    Convert this module to use var_tables.

    Fix an ancient error that I think has escaped detection until now
    because it arises only in the presence of a mode error in a procedure
    whose mode is being inferred. The bug is that when we modecheck a call,
    say from p to q, and find no matching modes in the callee because
    its mode inference has generated errors, then we report those errors
    in the callee as part of the explanation of the error in the caller.
    That is fine. What was not fine is that we printed any variables
    in the callee's mode_error using the *caller's* varset. We now
    print them using the callee's var table.

compiler/type_util.m:
    Add a var_table-using variant of an existing predicate,
    for use in new code above.

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

tests/invalid/mode_inf.m:
    Modify this test case to make the caller and callee use disjoint
    sets of variable names, which is probably why the incorrect variables
    in the error message about the callee has not been noticed.

tests/invalid/mode_inf.err_exp:
    Expect the updated, and now correct, version of that error message.
2022-05-02 11:36:42 +10:00
Zoltan Somogyi
6f476f8f1e Convert det analysis and simplify to var_tables.
compiler/common.m:
compiler/const_prop.m:
compiler/format_call.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_switch.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
    Convert these modules, which comprise the simplification pass,
    to use var_tables.

compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
    Convert the modules of determinism analysis to use var_tables.

compiler/direct_arg_in_out.m:
    Convert this module to use var_tables, because simplification uses it,
    though it is also invoked separately. And this conversion is limited;
    it still uses varsets and vartypes in the code that clones a procedure.
    It will be simpler to fix this when pred_infos and proc_info switch over
    to actually storing var_tables, not making them up on demand.

compiler/hlds_pred.m:
    Export a predicate for use by new code in direct_arg_in_out.m.

compiler/goal_path.m:
    Allow the code in this module to get its type information either
    from vartypes or from var_tables, since some of the modules above
    now need the latter.

compiler/instmap.m:
    Provide a var_table variant of an existing predicate.

compiler/lambda.m:
compiler/par_loop_control.m:
compiler/pd_util.m:
    Conform to the changes above.

compiler/typecheck.m:
compiler/typecheck_errors.m:
    Fix an arguable bug exposed by the changes above. The invalid/bug257.m
    test case contains a variable, Gee, which occurs only in a
    "require_complete_switch [Gee]" scope. Typechecking did not assign it
    even a dummy type, and this was not a problem, because the only
    compiler pass that looked it, determinism analysis, needed only its name.
    However, determinism analysis now gets the name from the var_table,
    which has entries only for variables that have a type (since all variables
    are supposed to have one after typechecking). This meant that the
    old code of typecheck.m lead to a compiler crash when det_report.m
    tried to look up this variable's name for the error report saying that
    the goal in that require_complete_switch scope is not a switch on Gee.

    Fix this by ensuring that variable appearing in scope_reasons
    always have a type, even if that type is a type variable.

compiler/var_table.m:
    Fix the code of the deletion predicates for situations in which
    the highest numbered variable is deleted.

    Delete the var_table_add_corresponding_lists predicate,
    since its implementation cannot be made to work without access to the
    module_info, which, due to being in parse_tree package, var_tables.m
    cannot have.

    Fix some variable names.

tests/invalid/bug257.err_exp:
    Expect the warning that reports an unbound type.
2022-05-01 16:37:18 +10:00
Julien Fischer
f3a34e4651 Replace uses of __ as a module qualifier.
samples/muz.zbstract.m:
tests/*/*.m:
    As above.
2022-04-14 20:25:10 +10:00
Julien Fischer
99cd93dcfb Shift some tests.
The tests below are not actually invalid, they cause the compiler to emit only
warnings and properly belong in the warnings directory.

tests/invalid/empty_interface.{m,err_exp}:
tests/invalid/foreign_singleton.{m,err_exp}:
tests/invalid/obsolete_proc_pragma.{m,err_exp}:
     Shift these tests into the warnings directory and use the
     appropriate extension for expected outputs in that directory

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/warnings/Mercury.options:
tests/warnings/Mmakefile:
     Conform to the above changes.
2022-04-14 16:13:37 +10:00
Zoltan Somogyi
0186a64520 Warn for unneeded use of mode-specific clauses.
compiler/add_clause.m:
    Generate a warning for mode-specific clauses when the clause is for
    a predicate that has only one mode, provided that the warning is enabled.

compiler/options.m:
    Add an option to enable this warning.

doc/user_guide.texi:
    Document this option.

library/exception.m:
library/int.m:
library/rtti_implementation.m:
library/string.m:
    Delete modes from clause heads that would get this warning.

tests/valid/spurious_purity_warning.m:
    Delete modes from clause heads that would get this warning.

    Do not interleave predicate definitions.

tests/warnings/unneeded_mode_specific_clause.{m,exp}:
    A test case for this warning.
tests/warnings/Mmakefile:
    Enable the new test case.

tests/invalid/multimode_syntax.err_exp:
    Expect the new warning.
2022-04-13 23:39:23 +10:00
Zoltan Somogyi
a31f448ecd Accept inst definitions for char.char.
compiler/mercury_compile_front_end.m:
    Invoke inst_check.m even when warn_insts_without_matching_type
    is not enabled, in order to get both

    - the errors it can generate, and
    - its canonicalization effect.

    The latter fixes Mantis bug #556.

compiler/inst_check.m:
    Document the fact that this module canonicalizes references to
    char.char to refer to the builtin type representing characters.

    Test whether warn_insts_without_matching_type is enabled before
    generating warnings for inst definitions without a "for type_ctor" clause
    that don't match any types.

    Test whether warn_insts_without_matching_type is enabled before
    generating errors for inst definitions *with* a "for type_ctor" clause
    that do not match their declared type, because the mismatch may be
    (and, in the most relevant cases, definitely is) due to a limitation
    of the current compiler.

    Generate a specific error message when an inst definition says
    it is for a user type constructor that is an equivalence type.

compiler/fact_table.m:
    Delete a now-obsolete XXX.

tests/invalid/inst_for_eqv_type.{m,err_exp}:
    A new test case to show that we report inst definitions that specify
    they are for a user-defined equivalence type.

tests/valid/inst_for_char_type.m:
    A new test case to show that we *don't* report inst definitions
    that specify they are for "char.char".

tests/invalid/Mmakefile:
tests/valid/Mmakefile:
    Enable the new test cases.
2022-04-07 12:55:38 +10:00
Zoltan Somogyi
381847e3e1 Fix failure of invalid/duplicate_instance_2
by disabling intermodule optimization for it. The error we are looking for
is detected when building the .opt file, but the test's actions don't capture
the error message then.
2022-04-07 06:41:29 +10:00
Julien Fischer
105580a765 Delete the trseg component and --trail-segments option.
Trail segments have been the default in trailing grades since Mercury 20.06.
Delete the trseg grade components and --trail-segment option since apart from
acting as synonyms for the tr component and --use-trail option repsectively,
they no longer do anything.

compiler/compute_grade.m:
compiler/handle_options.m:
compiler/options.m:
doc/user_guide.texi:
grade_lib/grade_vars.m:
scripts/parse_grade_option.sh-subr:
grade_lib/grade_string.m:
grade_lib/grade_vars.m:
   Delete the trseg grade component and --trail-segments option.

compiler/add_pragma.m:
   Update the wording of an error message.

NEWS:
   Announce the above.

extras/trail/Mercury.options:
extras/trailed_update/Mmakefile:
extras/references/Mercury.options:
tests/invalid/test_feature_set.err_exp:
    Conform to the above changes
2022-04-05 17:02:40 +10:00
Zoltan Somogyi
41d133b8ad Update the "no export" criteria and message.
compiler/check_module_interface.m:
    Generate a "this module does not export anything" warning for modules
    that contain only single include_module declaration, since such modules
    could be deleted with no effect.

    Change the warning message to list every kind of declaration/definition
    that does not depend on the presence of other kinds of declarations or
    definitions.

deep_profiler/Mercury.options:
    Shut up this warning for mdprof_fb, since right now, it contains
    only a single include_module, even it is designed to later contain more.

tests/invalid/empty_interface.err_exp:
tests/invalid/typeclass_missing_det_3.err_exp:
tests/invalid_nodepend/bigtest.err_exp:
tests/invalid_nodepend/duplicate_modes.err_exp:
tests/invalid_nodepend/errors2.err_exp:
tests/invalid_nodepend/no_exports.err_exp:
tests/invalid_nodepend/prog_io_erroneous.err_exp:
tests/invalid_nodepend/typeclass_test_11.err_exp:
tests/invalid_nodepend/vars_in_wrong_places.err_exp:
    Expect the updated wording of the warning message.
2022-04-05 10:32:10 +10:00
Zoltan Somogyi
3a306a7f1f Prepare to add new warnings about instances.
Prepare for these new options, --warn-unnecessarily-private-instance and
--warn-inconsistent-instance-order, by

- moving some checks on instance declarations to a point in time
  when the set of instance declarations in the module is complete, and

- adding a new field to instance declarations to record a context needed
  for the second of the above warnings.

compiler/add_class.m
compiler/check_typeclass.m
    Move some checks on instances from add_class.m, where they have to
    work with incomplete data, to check_typeclass.m, where they have access
    to all instance declarations. The tests moved are

    - the test whether the abstract and concrete forms of an instance
      specify the same constraints or not,
    - the test for duplicate concrete instances, and
    - the test for overlapping instances.

    The new code can be, and is, much more systematic in looking for
    inconsistencies between instance declarations. For example,
    it distinguishes between duplicate and overlapping instance declarations,
    whereas the old code did not. This allows it to generate more precise
    messages.

    We do in fact generate a new warning message, for duplicate abstract
    instance declarations.

    Crucially, the new code can also gather the information needed
    for --warn-inconsistent-instance-order, although the gathered info
    is then throw away. This will change soon.

    Record phase_type_check as the phase of all the error_specs generated
    in this module, not just most of them.

    Avoid constructing doing a global traversal of the entire instance table
    when a local traversal of just the part for one class_id will do.

    Give some predicates more meaningful names.

compiler/hlds_class.m
    To check whether abstract instance declarations are in the same order
    as concrete instance declarations, check_typeclass.m needs to record,
    with each concrete instance declaration, the context of the corresponding
    abstract instance declaration (if any). Add a slot for this information.

    Change instance_id from an equivalence type to a notag type,
    to reduce the chances of values of that type being confused
    with integers whose semantics is something else.

    Document why the structure of the instance table is what it is.

compiler/base_typeclass_info.m
compiler/dead_proc_elim.m
compiler/higher_order.m
compiler/hlds_code_util.m
compiler/hlds_defns.m
compiler/hlds_out_typeclass_table.m
compiler/intermod.m
compiler/polymorphism_type_class_info.m
compiler/recompilation.usage.m
compiler/typeclasses.m
compiler/unused_imports.m
    Conform to the change in hlds_class.m.

compiler/hlds_out_util.m
    Add a utility function for use by new code in hlds_out_typeclass_table.m.

tests/invalid/incompatible_instance_constraints.err_exp
tests/invalid/missing_concrete_instance.err_exp
tests/invalid/typeclass_test_9.err_exp
    Expect updated error messages.
2022-03-19 14:41:58 +11: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
7424f93a30 Use one error msg for undeclared mode references.
compiler/add_clause.m:
compiler/make_hlds_passes.m:
    We used to have two separate predicates for generating error messages
    about references to undeclared modes of predicates and functions.
    One, in add_clause.m, was for undeclared modes in mode-specific clauses,
    and generated messages that were as informative as possible.
    The other, in make_hlds_passes.m, which was used for undeclared modes
    in type_spec in foreign_export pragmas, was perfunctory, and gave
    no details.

    Act on an old XXX and delete the second predicate, replacing its uses
    by calls to the first. To make this possible, move the first predicate,
    which used to be private to add_clause.m, to make_hlds_passes.m.

compiler/add_pragma.m:
compiler/add_pragma_type_spec.m:
    Call the first predicate, not the second.

compiler/prog_item.m:
    The first predicate requires access to a varset that describes the names
    of any inst variables in the undeclared mode. Include a varset for this
    purpose in foreign_export pragmas. (type_spec pragmas already had the
    required varset.)

compiler/convert_parse_tree.m:
compiler/get_dependencies.m:
compiler/item_util.m:
compiler/make_hlds_error.m:
compiler/module_qual.qualify_items.m:
compiler/parse_pragma_foreign.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_mutable.m:
    Conform to the change in prog_item.m.

tests/invalid/pragma_qual_error.err_exp:
tests/invalid/type_spec.err_exp:
    Expect updated error messages.
2022-02-23 04:31:38 +11:00
Zoltan Somogyi
bc1bf0470f Get type_to_pieces to generate structured output.
compiler/error_util.m:
    Rewrite the type_to_pieces function, which typecheck_errors.m uses
    to format types in error messages, in order to fix five problems.

    The first two problems were with formatting higher order types.
    First, if a higher order type included an existentially quantified
    type variable, that quantification was *not* printed around the
    higher order type. Second, that quantification *was* printed around
    the type of every (non-higher-order) argument of the higher order value.
    The only reason why this has not been a problem so far is that
    we have no test case that contains a higher order type with an
    existentially quantified type variable :-(

    The fix to both these problems is to always put the existential
    quantification of any such type variables at the top level, regardless
    of the kind of type the quantification ranges over, and to never print
    any quantification of any of its component types.

    The third problem was that non-higher-order types were output in a
    non-structured fashion. (The special-case code we used to format
    higher order types did already output *them* in a structured fashion,
    though only at the top level.) We did this by converting (unparsing)
    the type to a term, and then calling mercury_term_to_string.

    Generating structured output by replacing only the mercury_term_to_string
    part would not worked well; most of the code would have been devoted
    to working out what kind of type the given term was representing.
    Therefore this diff changes the approach to formatting types without
    converting them to a term. The output we generate for each type
    uses indentation levels to show the type's structure, but for
    types whose formatted form is sufficiently short, we delete all
    the newlines from that representation.

    The fourth problem was while most of the existing code took care
    to treat function names as unbreakable, one part of it did not,
    which caused the name of a field update function, "f1 :=",
    to be split across two lines. This diff fixes that bug as well.

    A fifth problem, pointed out by Peter, was that we were printing
    arity-0 functions as "func" instead of as "(func)", even though
    Mercury syntax for types demands the latter.

    An arguable sixth problem was that we formatted existential
    quantifications as
        (some [Vars] Type)
    We now format that as
        some [Vars] (Type)

    Change the order of the arguments of type_to_pieces to reduce
    the difference between it and type_pieces, its internal version,
    which we use to format types that do not need existential quantification.

    Export the function that filters newlines out of lists of format
    components, since other parts of the compiler may also need it
    in the future.

    Fix two occurrences of a bug that is totally unrelated to the above:
    list_to_pieces and strict_list_to_pieces treated the last element
    in their input list differently from all the other elements.

compiler/parse_tree_out_term.m:
    Add a utility function for use by new code in error_util.m.

compiler/typecheck_errors.m:
    Conform to the new argument order of type_to_pieces.

tests/invalid/actual_expected.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/ext_type.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/foreign_procs_exist_type.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid/ho_type_arity_bug.err_exp:
tests/invalid/no_method.err_exp:
tests/invalid/nullary_ho_func_error.err_exp:
tests/invalid/overloading.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/invalid/type_mismatch.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/user_field_access_decl_override2.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:
    Expect types in error messages in their updated format.
2022-02-21 17:56:52 +11:00
Zoltan Somogyi
a832857b5e Give more precise context in an error message.
compiler/check_typeclass.m:
    When reporting an error for an instance declaration that has
    just one unrecognized method, use the context of the method itself
    in the error message. (If there is more than one unrecognized method,
    continue to use the context of the instance declaration as a whole.)

    Make the test of whether a method is recognized or not clearer.

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_2.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_9.err_exp:
    Update the expected context.
2022-02-21 15:24:17 +11:00
Zoltan Somogyi
29ff7d5732 Improve diagnostics for type- and mode-errors.
compiler/mode_errors.m:
    When generating an error message for a bad higher order inst,
    print the specific cause of the mismatch, instead of just
    "actual inst is X, expected inst was Y".

compiler/modecheck_call.m:
    Change the code that generates that error to record the specific cause
    in the mode_error structure of the error.

tests/invalid/higher_order_mode_mismatch.{m,err_exp}:
    Add a new test case for the specific causes that other test cases
    don't already cover. (As it happens, most of those causes can't be
    caught by mode analysis because typechecking reports them first,
    but it did so in ways that could be improved. Hence the change to
    typecheck_errors.m and most of the .err_exp files below.)

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

compiler/typecheck_errors.m:
    Instead of generating output of the form

        <something> has type `abc',
        expected type was `def'

    generate output of the form

        <something> has type
            abc,
        expected type was
            def

    The indentation directs the eye to the differences that matter,
    and automatically lines up any corresponding parts of the actual
    and expected types. It also replaces the quotes as a method
    of separating the types being referred to from their surroundings.

tests/invalid/abstract_eqv.err_exp:
tests/invalid/actual_expected.err_exp:
tests/invalid/anys_in_negated_contexts.err_exp:
tests/invalid/arg_permutation.err_exp:
tests/invalid/bad_statevar_bad_context.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/comparison.err_exp:
tests/invalid/error_in_list.err_exp:
tests/invalid/ext_type.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/foreign_procs_exist_type.err_exp:
tests/invalid/getopt_old.err_exp:
tests/invalid/ho_type_arity_bug.err_exp:
tests/invalid/ho_type_mode_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_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_nonsense2.err_exp:
tests/invalid_purity/purity_type_error.err_exp:
    Expect the updated error messages.

tests/invalid/ho_type_mode_bug.m:
    Update obsolete comments.
2022-02-19 00:03:45 +11:00
Zoltan Somogyi
ee0a21b98c Replace some 'arity's with {pred_form,user}_arity.
This removes uncertainty in the affected places in the compiler,
because unlike the 'arity' type, the pred_form_arity and user_arity
types specify *which definition* of arity they represent.

Whether I replaced a use of arity with pred_form_arity or user_arity
depended on whether I believed the original arity to have been intended to be
- a pred_form_arity without the wrapper, or
- a user_arity without the wrapper.
The reason for the size of this diff is that when I replaced one use of
arity with pred_form_arity or user_arity, I often could not be sure about
the right way to propagate this change to the rest of the affected code
without making similar replacements elsewhere, and seeing whether
*that* worked. This diff is in effect the "smallest fixpoint" of this process.

In places where the pred form arity of predicate or function
is inherent in a list which has one element for each argument
(the element may be a term, a type, a mode, etc), do not take
a separate arity argument as well, since (a) it is not needed, and
(b) it is a potential source of inconsistencies. The only downside
is that we may need to take the length of a list in both the caller
and the callee, but this cost is negligible.

Add "XXX ARITY" comments to mark opportunities for future improvements.

compiler/hlds_clauses.m:
    Make clauses_info_init take a pred_form_arity instead of an arity
    as argument.

compiler/hlds_pred.m:
    Make pred_info_init take a pred_form_arity instead of an arity
    as argument.

compiler/prog_data.m:
    Specify that the arity part of the pf_sym_name_arity type
    is a pred_form_arity.

    Add a variant of the sym_name_arity type, which does not say
    what kind of arity it contains, which does say that it contains
    a pred_form_arity.

    Store the arities of instance methods as user_arity, not arity.

    Move the definition of an instance method out of between
    the instance's name and its arity.

    Add a convenience function for computing the pred_form_arity
    of an argument list.

    Delete a type moved to parse_sym_name.m.

compiler/prog_item.m:
    Use user_arities in item_initialise_infos and item_finalise_infos.

compiler/typecheck_errors.m:
    Specify that the arity in an arg_vector_plain_pred_call,
    and in the argument list of a function that construct a message
    for a related type error, is a pred_form_arity.

compiler/add_class.m:
    In the predicate that converts clauses to instance methods,
    delete its arity argument, given that another argument is
    the list of argument terms.

    Move the generator of a variable before its first consumer.

compiler/add_clause.m:
    In predicates that add clauses to the HLDS, delete their arity argument
    where another argument is the list of argument terms.

compiler/superhomogeneous.m:
    Explicit specify that the arity of a clause is recorded as a
    pred_form_arity.

compiler/add_foreign_proc.m:
    In predicates that add foreign_procs to the HLDS, delete their arity
    argument where another argument is the list of argument terms.

compiler/check_typeclass.m:
    Record the arity of the method being checked as user_arity.

    Fix incorrect arities in the error messages we generate.

compiler/make_hlds_error.m:
    Get callers to specify the pred_form_arity of a missing predicate or
    function. If that predicate or function exists with other arities,
    we try to be helpful and print out those arities in the error message.
    This process had some bugs, which this diff fixes.

compiler/typecheck_info.m:
    Specify that the arity we record for overloaded symbols is the
    pred_form_arity.

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

    Move a comment to the code it is about.

compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
    Conform to the changes above.

    In two comments, write out the user arities of function methods,
    not their pred form arity.

compiler/make_hlds_passes.m:
    Conform to the change in the representation of initialise and finalise
    items.

    Use the new method for constructing target names in prog_foreign.m.

    Indent the code example part of an error message.

compiler/prog_foreign.m:
    Provide a single predicate for creating target language names
    for initialise and finalise predicates. This new predicate factors out
    what used to be duplicate code in make_hlds_passes.m.

compiler/parse_sym_name.m:
    Move a type here from prog_data.m, since it is used only by
    parse_sym_name.m and the modules that call it.

compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/check_promise.m:
compiler/det_report.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/higher_order.m:
compiler/hlds_out_typeclass_table.m:
compiler/intermod.m:
compiler/mark_tail_calls.m:
compiler/parse_class.m:
compiler/parse_mutable.m:
compiler/parse_tree_out.m:
compiler/pred_name.m:
compiler/prog_mutable.m:
compiler/prog_out.m:
compiler/state_var.m:
compiler/table_gen.m:
compiler/typecheck.m:
compiler/unused_args.m:
    Conform to the changes above.

compiler/make_hlds.m:
    Conform to the change in add_class.m.

tests/invalid/bad_pred_arity.err_exp:
tests/invalid/mode_decl_in_wrong_section.err_exp:
tests/invalid/pragma_c_code_dup_var.err_exp:
tests/invalid/state_vars_test3.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
    Update these expected outputs for the bug fixes above.

tests/invalid_nodepend/bad_finalise_decl.err_exp:
tests/invalid_nodepend/bad_initialise_decl.err_exp:
    Update these expected outputs for formatting change above.

tests/invalid/no_method.{m,err_exp}:
    A new test case for an arity-related error message that wasn't
    being exercised before.

tests/invalid/Mmakefile:
    Enable the new test case.
2022-02-17 22:21:16 +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
068fc20006 Improve error management in convert_parse_tree.m.
compiler/hlds_module.m:
compiler/prog_item.m:
    Record the identity of predicates and functions that have misplaced
    attempts at definition in the interface section using the
    pred_pf_name_arity type instead of the pf_sym_name_arity type.
    They both specify an arity, but only in pred_pf_name_arity is it clear
    *which kind* of arity this is.

compiler/convert_parse_tree.m:
    Record external declarations and foreign_procs in the interface
    as misplaced attempts at predicate or function definition using
    pred_pf_name_arity, so that the code obviously has no arity bugs,
    whereas the old code merely had no obvious bugs. (It did actually work.)

    Record fact_table pragmas in the interface as similar misplaced attempts
    as predicate or function definition, *if* the pragma contains
    a pred_or_func indication.

    Factor out some common code.

compiler/hlds_pred.m:
    Add predicates to return a pred_info's arity as pred_form_arity
    and as user_arity.

compiler/make_hlds_separate_items.m:
compiler/typecheck_errors.m:
    Conform to the changes above.

tests/invalid_nodepend/external_in_interface.{m,err_exp}:
tests/invalid_nodepend/foreign_proc_in_interface.{m,err_exp}:
tests/invalid_nodepend/fact_table_in_interface.{m,err_exp}:
    Three new test cases to test the

tests/invalid_nodepend/Mmakefile:
    Enable the new tests.

tests/invalid/external2.m:
    Fix typo in comment.
2022-02-04 03:14:36 +11:00
Zoltan Somogyi
adf6c55847 Shut up mmake actions for check_namespace.
This reduces the size of the output of tools/bootcheck by 3700+ lines,
or about 25%.

Mmake.common.in:
    Don't print the actions implementing namespace cleanliness checks.
    To allow the attribution of any violations of the namespace rules,
    print the name of the C module before any list of detected
    nonallowed symbols.

    To avoid mmake printing the actions for creating the .o files
    that some of the check_namespace actions later check, rename
    the affected object files .pseudo_o files, so that we can specify
    a rule for them that is a copy of the rule for .o files, differing
    only in not printing the compilation command.

    Mark the files involved in check_namespace actions as dependencies
    of .SECONDARY, which means that mmake does not automatically delete them
    after building them as intermediate files. The reason for this is that
    there is no way to tell make to delete intermediate files *silently*,
    i.e. without writing out the rm command that deletes them.
    To make up for this, tools/bootcheck now cleans up each directory
    immediately after "mmake check_namespace" with "mmake clean_check",
    which invokes mmake rules that do not print the rm commands.

    This change does have the effect that these intermediate files *will*
    hang around if the check_namespace target is every invoked manually.
    However,

    - we just about never run check_namespace in a directory manually, and
    - when we do, a simple "mmake clean_check" will do the required cleanup.

scripts/Mmake.rules:
    Move the vim tag line to its usual place at the top.

    Replace old-school rules such as .m.err with their modern equivalents
    (such as %.err: %.m).

scripts/Mmakefile:
    Instead of printing the rules that make test_mdbrc, print only a
    "making test_mdbrc" message.

runtime/Mmakefile:
    Conform to the change of the name of a make variable in Mmake.common.in.

ssdb/Mmakefile:
    Fix an old bug that something else in this diff tickled: make the
    .depend target of each main module depend on SSDB_FLAGS, *not* just
    the phony general "depend" target. This was a bug because tools/bootcheck

    - copied across to stage 2 ONLY SSDB_FLAGS.in, and NOT SSDB_FLAGS,

    - did NOT explicitly make SSDB_FLAGS from SSDB_FLAGS.in, even though
      pretty much invocations of the Mercury compiler in this directory
      have "--flags SSDB_FLAGS" as an implicit argument, and then

    - built dependencies in the ssdb directory by invoking the top
      Mmakefile's dep_ssdb target, which (indirectly) invokes
      $(SSDB_LIB_NAME).depend.

    Due to all the above, I don't actually know how tools/bootcheck
    could ever build stage2/ssdb until now :-(

tools/bootcheck:
    Invoke "mmake clean_check" after each "mmake check_namespace".

    Change the code that explicitly builds the directory-specific
    X_FLAGS file in each directory (which is invoked only when using
    mmc --make) to actually build all such files, when previously
    it built only a subset.

tests/invalid/Mmakefile:
tests/invalid_nodepend/Mmakefile:
tests/invalid_onlydepend/Mmakefile:
tests/invalid_options_file/Mmakefile:
tests/invalid_purity/Mmakefile:
tests/invalid_submodules/Mmakefile:
tests/stm/Mmakefile:
    Fix an unintended consequence of replacing the .m.err rule in
    scripts/Mmake.rules with %.err: %.m, which is that the %.err: %.m
    rules in these mmakefiles became ineffective, because they appear
    in the makefile we construct *after* the rule in scripts/Mmake.rules,
    which specify a different action (the rules here return a nonzero
    status in the *absence* of failure, which would be ridiculous
    for the rule in scripts/Mmake.rules). Apparently, the %.err: %.m rules
    overrode the rule in scripts/Mmake.rules while it had the old form,
    but do not do so now it has the new form.

    The fix is to make replace all the "%.err: %.m" rules in these Mmakefiles
    with "$(PROGS:%=%.err): %.err: %.m" rules, which specify that they
    override the generic rule for the .err files of the test cases
    in each directory.

    In invalid_purity/Mmakefile, fix a bug: -nodepend suffixes make sense
    in only in the name of a *test*, not the name of a *program*, so
    move such a suffix from a program name to a test name. Without this,
    the program's .err file would be included in the list of .err files
    to which the ".err: .m" rule applies under the wrong name.

    In invalid_submodules/Mmakefile, fix the misleading names of some
    make variables, and fix a misspelt directory name.

    Standardize on "$(PROGS:%=%.err)" notation, replacing earlier instances
    of "$(addsuffix .err,$(PROGS))". The reason for this is that when I tried
    using "$addsuffix .int_err,$(PROGS))" in tests/invalid/invalid_make_int,
    it did not work. (A google search on "gnu make addsuffix" did not yield
    any clues as to why. Maybe you can only add suffixes that do not contain
    underscores?)
2022-01-24 17:38:35 +11:00
Zoltan Somogyi
ec22ea43bd Specify --no-intermodule-opt for two tests.
For these two tests in tests/invalid, enabling intermodule optimization
allows the errors we are testing for to be detecting while making the .opt
files, which means we don't get to the compilation step whose output
we want to compare against the expected error output.
2022-01-10 14:44:19 +11:00
Zoltan Somogyi
bfaf6d04f6 Fix frivolous test case failure ...
by also expecting an unnamed variable with a different number.
2022-01-03 02:39:01 +11:00
Zoltan Somogyi
a9c2e88cab Improve diagnostics for type mismatches.
compiler/typecheck_errors.m:
    Improve diagnostics for some type errors in two separate ways.

    First, when printing an error message for a type mismatch,
    replace messages of the form

        ... has type T1,
        expected type was T2

    with messages of the form

        ... has type
            T1,
        expected type was
            T2.

    This way, the types both (a) stand out from the rest of the message,
    and (b) any corresponding parts will line up, making discrepancies
    easier to see.

    Second, avoid messages of the form

        ... has type `some [T] T'
        expected type was `some [T] T'.

    which can be both baffling and infuriating, by including the variable
    numbers of the type variables if this is needed to make two different
    types *visibly* different, yielding messages such as

        ... has type
            `some [T_2] T2',
        expected type was
            `some [T_3] T3'.

    which can still be baffling, in the absence of any info about where T_2
    and T_3 came from, but at least should not be infuriating, since it
    *does* show a difference between actual and expected.

compiler/error_util.m:
    Provide the infrastructure for the second part, by letting callers
    control how type variables are printed.

tests/invalid/actual_expected.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/coerce_ambig.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/foreign_procs_exist_type.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:
    Expect the updated error messages.
2022-01-01 06:02:07 +11:00