Commit Graph

397 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
1e097a8d18 Avoid some make warnings about overriding recipes. 2022-12-07 11:18:00 +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
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
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
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
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
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
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
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
bb1b900ba6 Check "for type_ctor" annotations on user insts.
NEWS:
doc/reference_manual.texi:
    Document the fact that the compiler now does such checks.

compiler/post_typecheck.m:
    When propagating types into insts, ask inst_mode_type_prop.m to check
    whether the types being propagated into user defined insts violate the
    "for type_ctor" annotations on those insts.

    Fix a bug in my earlier change. We want to propagate types into insts,
    and check for applications of insts to values of inappropriate types
    for lambda expressions. We used try to do it by traversing each procedure's
    body goal, but this did nothing, because we copy goals to procedure bodies
    in a pass that happens *after* the post-typecheck pass. During the
    post-typecheck pass, these lambda expressions exist only in the predicate's
    clauses, so that is where now we process them.

compiler/inst_mode_type_prop.m:
    The code in this module is called not just from post_typecheck.m,
    which needs this new check, but also from other modules, which do not.
    To avoid excessive performance impact on the latter, make the
    checking optional through a typeclass with two instances,
    one of which prepares for and then does the checking, while the other
    replaces all those operations with no-ops. Then use type_spec pragmas
    to create two versions of all the predicates using this type class,
    effectively creating two versions, one with the checks and the other
    without the checks.

    Change the name of all the exported predicates of this module
    to specify whether they do these checks or not.

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

    Note a possible performance problem.

compiler/add_special_pred.m:
compiler/inst_user.m:
    Conform to the changes above.

tests/invalid/bad_type_for_inst.{m,err_exp}:
    A test case for the error messages.

tests/invalid/Mmakefile:
    Enable the new test case.
2021-12-30 23:39:20 +11:00
Zoltan Somogyi
8827b6a466 Make --halt-at-invalid-interface the default.
NEWS:
    Mention this fact.

    Group related changes together.

    Fix some typos.

compiler/error_util.m:
    Let the halt_at_invalid_interface option govern whether we print error
    messages when we generate .int/.int2 files, rather than
    the print_errors_warnings_when_generating_interface option.
    This simplifies the use of that option.

compiler/options.m:
doc/user_guide.texi:
    Document the halt_at_invalid_interface option.

    Delete the print_errors_warnings_when_generating_interface option,
    since its functionality has been subsumed into halt_at_invalid_interface.

compiler/grab_modules.m:
    Check the accessibility of imported modules not just when generating target
    language code, but also when generating .int/.int2 files. Without this,
    the test_nested test case, which this diff moves from invalid to
    invalid_make_int, would miss out on some errors being reported
    in its new home.

    To make the above possible, refactor the code that does the check
    to let it work on aug_make_int_units as well as from aug_compilation_units.
    Make the wording of any error message depend on where the info came from,
    because unlike aug_comp_units, aug_make_int_units work with an
    known-incomplete picture of the relevant info.

    Update some obsolete comments.

compiler/write_module_interface_files.m:
    Add a comment about a design decision that affects this diff.

tests/invalid_make_int/Mercury.options:
tests/invalid_make_int/Mmakefile:
    Add to this directory's list the test cases that this diff moves
    to this directory from other test directories, because the errors
    that they test for are now reported at interface generation time.

    Fix the rule handling multimodule tests, now that we have some :-(

    Specify -j1 for this directory, since the two tests moved here
    from invalid_submodules include nested submodules.

tests/invalid_make_int/bad_type_class_constraint_intermodule.{m,int_err_exp}:
    Move this test case here from invalid, renaming files slightly,
    and update the expected output.

tests/invalid_make_int/bug499.{m,int_err_exp}:
    Move this test case here from invalid, and update the expected output.

tests/invalid_make_int/int_impl_imports.{m,int_err_exp}:
tests/invalid_make_int/int_impl_imports_2.m:
    Move this test case here from invalid, and update the expected output.

tests/invalid_make_int/missing_interface_import2.{m,int_err_exp}:
tests/invalid_make_int/missing_interface_import3.m:
    Move this test case here from invalid, and update the expected output.

tests/invalid_make_int/missing_parent_import.{m,int_err_exp}:
tests/invalid_make_int/children.m:
tests/invalid_make_int/children2.m:
    Move this test case here from invalid_submodules,
    and update the expected output.

tests/invalid_make_int/sub_c.{m,int_err_exp}:
tests/invalid_make_int/sub_a.m:
    Move this test case here from invalid_submodules,
    and update the expected output.

tests/invalid_make_int/test_nested.{m,int_err_exp}:
tests/invalid_make_int/parent.m:
tests/invalid_make_int/parent.private_child.m:
tests/invalid_make_int/parent.public_child.m:
tests/invalid_make_int/parent.undeclared_child.m:
tests/invalid_make_int/parent2.child.m:
tests/invalid_make_int/parent2.m:
    Move this test case here from invalid, and update the expected output.

tests/invalid_make_int/transitive_import.{m,int_err_exp}:
    Move this test case here from invalid, update it,
    and update the expected output.

tests/invalid/Mmakefile:
    Delete from the list of tests in this directory the tests
    moved to invalid_make_int, and test bug521.

tests/invalid/bug521.{m,err_exp}:
tests/invalid/bug521_sub.m:
    Delete this test. invalid_make_int already had a copy of the relevant
    part of this test.

tests/invalid_submodules/Mmakefile:
    Delete from the list of tests in this directory the two tests
    moved to invalid_make_int.

    Delete from the list of tests in this directory two other tests
    for which we now detect some or all of the errors tested for
    at interface generation time, but which are already covered
    by other tests.

tests/valid_make_int/Mmakefile:
    Delete from the list of tests in this directory the test
    moved to invalid_make_int. (We could successfully generate
    a .int file for that test case *only if* we did not check it
    for errors :-)

tests/valid_seq/intermod_nested_module_bug2.m:
tests/valid_seq/intermod_nested_module_bug2.sub.m:
    Move two module imports from the parent to the child module,
    because only the child needs them, and any compiler with this diff
    will now complain about them being unused in the parent
    at interface generation time. Delete a third import, which was
    not used anywhere.
2021-11-20 23:49:19 +11:00
Zoltan Somogyi
d64961d79d Use checked types/insts/modes in parse_tree_module_src.
This means that we can do the exact same checks (and, if needed, generate
the exact same error messages) when generating interface files as when
generating target language code.

This should also allow us to simplify the process of adding type, inst
and mode definitions to the HLDS.

compiler/prog_item.m:
    As above.

    Delete unused function.

compiler/error_util.m:
    Add mechanisms that allow us to distinguish (a) error specs that represent
    a type, inst or mode name definition being invalid, from (b) other error
    specs.

compiler/check_type_inst_mode_defns.m:
    Improve the error messages we generate, in several ways.

    First, for each message, specify a real severity. When the messages
    could be seen only when generating interface files, making them all
    warnings was fine and preserved old behavior, but since soon these
    will be the only place for these checks, we need to call errors errors.

    Second, specify, in the phase, which errors represent a invalid type,
    inst or mode definition, and which don't.

    Third, improve the wording of messages. In some places, do this by
    being clearer about the distinction between declarations and definitions.
    In others, do it by including more information in the message. In yet
    others, do it by recovering some kinds of mistakes (mostly items being
    in the wrong section) enough to avoid avalanche errors.

    Fourth, fix a bug. If a type ctor has an exported *declaration*,
    then it is ok for any foreign type definitions for that type_ctor
    being in the implementation section, but if the type_ctor has an
    exported Mercury *definition*, then any foreign_type definitions
    must be in the interface section as well. The code that handled
    both these situations did not enforce that.

    Fifth, fix another bug: do not include foreign type definitions
    in the source definitions of a type_ctor twice, once as a "du" (sic)
    definition, and once as itself.

compiler/convert_parse_tree.m:
    Check type, inst and mode definitions in raw_compilation_units
    when creating parse_tree_module_srcs.

compiler/comp_unit_interface.m:
    Make the code constructing interface files work from the checked maps
    in parse_tree_module_srcs.

compiler/make_hlds_passes.m:
    Set the flags that say we have found invalid type, inst or mode definitions
    from the error specs constructed during the creation of the checked
    type, inst and mode maps.

compiler/add_type.m:
    Comment out an error message for a condition that will be detected and
    reported by check_type_inst_mode_defns.m.

compiler/make_hlds_separate_items.m:
    For now, turn checked maps of type, inst and mode definitions
    back to item lists for addition to the HLDS. Adding whole checked
    definitions to the HLDS will be done by a future change.

compiler/make_hlds_error.m:
    Fix misleading indentation in an error message.

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

    Generate output whose indentation does not depend on tab settings.

compiler/check_raw_comp_unit.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
    Conform to the changes above.

compiler/parse_type_defn.m:
    Fix misleading error message for ":- type <name> = <type>".

tests/debugger/foreign_type.{m,exp}:
    Delete a redundant type declaration to avoid a warning, and update
    the .exp file to expect the new line numbers.

tests/invalid/any_mode.err_exp:
tests/invalid/bug436.err_exp:
tests/invalid/bug476.err_exp:
tests/invalid/exported_foreign_enum.err_exp:
tests/invalid/fe_unmapped_nonverbose.err_exp:
tests/invalid/fe_unmapped_verbose.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
tests/invalid/foreign_solver_type.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/pragma_qual_error.err_exp:
tests/invalid/repeated_field_name.err_exp:
tests/invalid/subtype_foreign.err_exp:
tests/invalid/type_with_no_defn.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/user_field_access_decl_conflict.err_exp:
tests/invalid_nodepend/bad_foreign_type.err_exp:
tests/invalid_nodepend/bigtest.err_exp:
tests/invalid_nodepend/invalid_typeclass.err_exp:
tests/invalid_nodepend/types.err_exp:
tests/invalid_nodepend/uu_type.err_exp:
tests/invalid_nodepend/where_abstract_enum.err_exp:
    Expect the new error messages.

tests/invalid/abstract_solver_type.{m,err_exp}:
tests/warnings/abstract_solver_type.{m,exp}:
    Move the abstract_solver_type test case from invalid to warnings, because
    this diff changes its only error to be only a warning.

tests/invalid/Mmakefile
2021-10-16 17:37:36 +11:00
Zoltan Somogyi
7f76db2471 Don't override make rules in tests/invalid.
tests/invalid/Mmakefile:
    Some test cases have long had separate make rules for them,
    which specified what actions should be taken for them.
    However, these test cases were also included in either
    the list of single-module test cases, or the list of multi-module
    test cases, each of which had a generic rule that *also* include actions.
    This got the right result because the specific rules are all
    after the generic rules, and later applicable rules override earlier ones.
    However, make print expressed its displease by printing not one but two
    separate warnings for each such test case, warnings like this:

        warning: overriding recipe for target 'illtyped_compare.err'
        warning: ignoring old recipe for target 'illtyped_compare.err'

    Currently, there is no mechanism to shut up these warnings for overrides.
    (A bug report filed against GNU make in 2019 asks for a mechanism
    that could do this, but it seems to have been completely ignored.)
    The only way to get rid of the warnings is therefore to eliminate
    the override.

    This diff does that by

    - introducing separate make variables to hold the list of plain
      single-module, plain multi-module, and C-interface-using test cases
      that have special make rules for them;

    - restricting the generic rules to the single-module and multi-module
      test cases that do NOT have special rules for them; but

    - including the test cases with special rules in the list of test cases
      to be executed.
2021-10-12 18:34:04 +11:00
Zoltan Somogyi
fdeea98339 Fix a misleading context.
compiler/state_var.m:
    When replacing the argument terms !.X or !:X with a reference to
    the relevant instance of the state var, make the updated form of
    the argument inherit its context from the original form.
    The dummy context we used to use would lead to a misleading context
    in any error message about that argument.

compiler/superhomogeneous.m:
    Fix an unrelated problem I came across while tracking down the above bug.
    The problem was that we used to tell people that lambda expressions
    had to have the form "<lambda head> :- <lambda body>", even if the
    malformed lambda expression had "-->" as its top functor, i.e. if it
    used DCG syntax.

    Simplify a comment.

tests/invalid/bad_statevar_bad_context.{m,err_exp}:
    A new test case for the state var bug above.

tests/invalid/Mmakefile:
    Enable the new test case.
2021-08-03 13:01:59 +10:00
Zoltan Somogyi
aed31c7eda Fix several test case failures.
tests/debugger/user_event_shallow.{m,exp}:
    Mark a predicate with no_inline to prevent -O5 from optimizing
    away an event that the .inp of this case depends on.

tests/invalid/Mmakefile:
    Make the test cases in this directory work even if code generation
    requires reading in the module's own .int file.

tests/invalid/bad_item_in_interface.err_exp2:
    Add an expected output file for grades that do not support memoisation.

tests/invalid/bad_item_in_interface.m:
    Document the reason for the existence of the .err_exp2 file.

tests/options_file/Mmakefile:
    Make the test cases in this directory work even if code generation
    requires reading in the module's own .int file.

    Conform to the changes below.

compiler/options.m:
doc/user_guide.texi:
    Make the --dump-options-file file take an argument that specifies
    the file to which the contents of the options file should be dumped.

compiler/mercury_compile_main.m:
compiler/options_file.m:
    Dump the options file to the specified file, if the filename is not "".
2021-07-30 01:43:59 +10:00
Zoltan Somogyi
6413b4fb08 Create invalid_nodepend and invalid_onlydepend.
tests/invalid_onlydepend:
    Move the one test case in tests/invalid for which we want to check
    the error messages generated during the generation of dependencies
    to this new test directory.

tests/invalid_nodepend:
    Move all test cases in tests/invalid which get errors during the
    generation of dependencies but for which we want to check the error
    messages generated during normal compilation to this new test directory.

tests/invalid_nodepend/Mmakefile:
tests/invalid_nodepend/Mercury.options:
tests/invalid_onlydepend/Mmakefile:
tests/invalid_onlydepend/Mercury.options:
    Versions of the same files in tests/invalid, but containing only
    the entries relevant to the moved test cases.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
    Delete the entries that refer to the moved test cases.

tests/README:
    Document the two new test directories.

tools/bootcheck:
    Add invalid_onlydepend and invalid_nodepend to the list of
    test directories.
2021-07-28 00:59:04 +10:00
Zoltan Somogyi
de1d35257f Avoid double negation in an if-then-else. 2021-07-25 01:01:23 +10:00
Zoltan Somogyi
21574b7c8f Separate semantic checks on fact table preds ...
from code generation for them.

compiler/fact_table.m:
    Add a separate predicate to do all the required type and mode checks
    on the fact table predicate and all its procedures. If this finds errors,
    return error messages describing them. If there are no errors, then return
    a data structure containing all the semantic information that later passes
    will need, which records both type and mode information in a form
    in which unsupported types and modes cannot be represented.

    Significantly improve the text of most error messages.

    Rewrite large chunks of this module to use this data structure (GenInfo)
    instead of the predicate's arg types and the procedure's arg modes,
    since the latter could not be used without effectively being checked
    for validity over and over again. The rewrite of the call tree of the
    first exported pred also cuts out of it the semantic checks that are
    now in their own pass.

    Replace some uses of the ok/error type with empty/nonempty lists
    of error_specs.

    Replace several uses of bools with bespoke types.

    In several related predicates, replace a flag argument and a set of
    other arguments that were meaningful only with one setting of the flag
    with a maybe-like type that specified those other arguments only when
    needed.

    Use the tight new types to replace some if-then-else chains
    with switches.

    Move the task of generating the pragma_vars and the prog_varset
    of the foreign_proc implementing each procedure from add_pragma.m
    to here, to let fact_table.m control this aspect of the foreign_proc
    along with all the others.

    Reorder several argument vectors to put bigger/slower-moving inputs
    first.

compiler/add_pragma.m:
    If a fact table pragma is for a predicate that whose declarations
    are not compatible with fact tables, then do not try to generate
    those fact tables, but do record the presence of the error.

    Don't do work that is now done in fact_table.m.

    Reorder several argument vectors to put bigger/slower-moving inputs
    first.

compiler/hlds_pred.m:
    Provide a mechanism for add_pragma to record the presence of those errors.

compiler/typecheck_errors.m:
    If a predicate has a fact_table for it, then its clauses (actually,
    foreign_procs) are supposed to be provided by the compiler;
    the absence of user-supplied clauses is to be expected.
    If, due to incompatibility between the predicate's declarations
    and the requirements of fact tables, the compiler cannot generate
    those foreign_procs, do not generate an error message about
    the absence of clauses, since such an error message would be misleading.
    The problem *will* be reported by fact_table.m.

compiler/hlds_out_pred.m:
compiler/intermod.m:
compiler/table_gen.m:
    Conform to the change in hlds_pred.m.

compiler/export.m:
    Note the fact that fact_table.m now contains cut-down versions
    of two of the predicates here.

tests/invalid/bad_fact_table_decls.{m,err_exp}:
    A new test case testing the error messages involving problems
    with the type and mode declarations of fact table predicates.

tests/invalid/bad_fact_table_data.{m,err_exp}:
tests/invalid/fact_table_data_file_x:
    A new test case testing the error messages involving problems
    with the contents of fact table files.

tests/invalid/Mmakefile:
    Enable the two new test cases.
2021-06-11 12:48:26 +10:00
Zoltan Somogyi
6229771305 Propagate type char into bound_insts.
compiler/mode_util.m:
    As above. This is needed to allow the compiler to check whether
    a char constant matches an inst that is specific to the char type.

tests/invalid/char_inst.{m,err_exp}:
    A new test case for the fixed functionality.

tests/invalid/Mmakefile:
    Enable the new test case.
2021-06-08 07:57:52 +10:00
Peter Wang
233874403f Improve coerce mode error messages.
compiler/mode_errors.m:
    Replace the two existing options for coerce mode errors with one
    that includes:
    - the path to the input subterm where the error was detected
    - the type of the input subterm
    - the target type that the subterm should be converted to
    - the reason for the error

compiler/modecheck_coerce.m:
    Modify the code to produce the above information.
    Semidet predicates that previously failed when an error is detected
    are changed to det predicates that return the error information.

    In a couple of places where predicates previously would fail,
    we now abort because the conditions should not occur.

compiler/hlds_out_util.m:
    Describe coerce as "coerce expression" (shows up in mode errors).

tests/invalid/Mmakefile:
tests/invalid/coerce_mode_error2.err_exp:
tests/invalid/coerce_mode_error2.m:
    Add test case.

tests/invalid/coerce_clobbered.err_exp:
tests/invalid/coerce_implied_mode.err_exp:
tests/invalid/coerce_instvar.err_exp:
tests/invalid/coerce_int.err_exp:
tests/invalid/coerce_mode_error.err_exp:
tests/invalid/coerce_recursive_inst.err_exp:
tests/invalid/coerce_recursive_type.err_exp:
tests/invalid/coerce_unreachable.err_exp:
    Update expected error messages.
2021-05-17 12:55:58 +10:00
Peter Wang
43d7e737dc Allow duplicate field names in the same module.
Allow the same field name to be used in different types in the same
module. The main motivation is that when defining a subtype it often
makes sense to use the same field names as in the base/super type,
rather than trying to invent unique field names.

compiler/add_type.m:
    Check for duplicate field names within a type only,
    not across the module.

compiler/check_parse_tree_type_defns.m:
    Only report duplicate field names within the same type.

compiler/typecheck.m:
    Make user-supplied declarations for field access functions only
    override automatically generated declarations for the same type
    constructor, e.g. a user declaration ':- func foo ^ f1 = int'
    should not affect 'X ^ f1' for X of type 'bar'.

doc/reference_manual.texi:
    Allow duplicate field names in a module, but not within a type.

    Describe how user-supplied declarations interact with duplicate
    field names.

NEWS:
    Announce change.

tests/invalid/repeated_field_name.err_exp:
    Update expected error messages.

tests/invalid/Mmakefile:
tests/invalid/user_field_access_decl_conflict.err_exp:
tests/invalid/user_field_access_decl_conflict.m:
tests/invalid/user_field_access_decl_override.err_exp:
tests/invalid/user_field_access_decl_override.m:
tests/invalid/user_field_access_decl_override2.err_exp:
tests/invalid/user_field_access_decl_override2.m:
    Add test cases.
2021-05-07 17:07:39 +10:00
Peter Wang
7bcab5e7bd Implement modechecking of coerce more efficiently.
Implement modechecking of coerce in a direct and efficient way.
The old implementation worked by generating a 'bound' inst node for each
node in the type tree (recursively, as far as possible),
calling abstractly_unify_inst, then checking the resulting inst is valid
for the result type. The insts could explode in size for large types.

The new implementation works by simultaneously traversing the input inst
tree, the input type tree, and the result type tree, and producing the
result inst tree for a valid conversion or rejecting the coercion.
Where the input and result types are equal, the result inst can just be
'ground' instead of expanding to a 'bound' inst. Therefore the
result inst does not explode in size compared to the input inst.

While testing, I discovered a couple of cases where the old
implementation would accept coercions that it should not have,
which are rejected by the new implementation.

compiler/modecheck_coerce.m:
    Implement the new algorithm.

compiler/mode_errors.m:
    Change how we report coerce mode errors as we cannot generate the
    same messages as before.

compiler/typecheck.m:
compiler/type_util.m:
    Move get_supertype into type_util.m.

doc/reference_manual.texi:
    Describe how coerce is mode checked now.

tests/invalid/Mmakefile:
tests/invalid/coerce_int.err_exp:
tests/invalid/coerce_int.m:
tests/invalid/coerce_recursive_inst.err_exp:
tests/invalid/coerce_recursive_inst.m:
tests/invalid/coerce_recursive_type.err_exp:
tests/invalid/coerce_recursive_type.m:
    Add new test cases.

tests/invalid/coerce_mode_error.m:
tests/invalid/coerce_mode_error.err_exp:
tests/invalid/coerce_instvar.err_exp:
tests/invalid/coerce_uniq.err_exp:
tests/invalid/coerce_unreachable.err_exp:
    Update expected error messages.
2021-05-05 16:21:13 +10:00
Peter Wang
150cf5233c Fix test failures with intermodule optimisation.
tests/invalid/Mmakefile:
    Add type_error_use_module to list of REDIRECT_OPT_ERROR_MODULES
    as it produces error messages while making the .opt file.

tests/invalid/multiply_star.m:
    Add description of .err_exp files.

tests/invalid/multiply_star.err_exp:
    Update line numbers.

tests/invalid/multiply_star.err_exp2:
    Add expected error output when compiling with intermodule
    optimisation.
2021-05-05 12:24:03 +10:00
Zoltan Somogyi
bd6e6fca8c Diagnose names with non-full qualifications.
compiler/typecheck_errors.m:
    When the program refers to a predicate, function or data constructor
    from a module with only a use_module declaration, it must do so
    using its fully qualified name. If it refers to it with an unqualified
    or only partially qualified name, the typechecker won't find it,
    because the predicate_table and the cons_table record non-fully-qualified
    names only for the entities imported with import_module declarations.

    When generating error_specs for such errors, look for matches with
    the relevant name among the fully-qualified entries in the predicate
    and cons tables. If we find some, add a sentence to the error message
    about the modules defining such names being imported with use_module,
    not import_module.

compiler/hlds_cons.m:
    Add a way to look up the definitions of all the constructors with
    a given name.

compiler/pred_table.m:
    Add a way to look up the definitions of all the predicates or functions
    with a given name.

mdbcomp/sym_name.m:
    Add some functionality for use by typecheck_errors.m.

tests/invalid/type_error_use_module.m:
tests/invalid/type_error_use_module_2.m:
tests/invalid/type_error_use_module.err_exp:
    A test case for the new functionality.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
    Enable the new test case. Sort the list of multimodule tests.

tests/invalid/errors2.err_exp:
    Expect the new addendum to an existing error message.
2021-04-26 23:47:03 +10:00
Peter Wang
e9dafb3ec6 Add foreign_proc attributes may_export_body/may_not_export_body.
Add an attribute may_not_export_body to prevent a foreign_proc from
being opt-exported. Also add may_export_body for completeness.

compiler/prog_data_foreign.m:
    Add type to represent those attributes.

    Add a field for that attribute to pragma_foreign_proc_attributes,
    plus getters and setters.

compiler/parse_pragma_foreign.m:
    Parse may_export_body and may_not_export_body attributes on
    foreign_proc declarations.

    Detect conflicting attributes.

compiler/parse_tree_out_pragma.m:
    Write out may_export_body and may_not_export_body attributes.

compiler/intermod.m:
    Do not write a foreign_proc with may_not_export_body to .opt files.

compiler/simplify_proc.m:
    Report an error if a foreign_proc with may_export_body is
    also marked with pragma no_inline.

compiler/add_mutable_aux_preds.m:
    Mark auxiliary predicates for mutables with may_not_export_body
    instead of may_not_duplicate. This allows calls to those predicates
    to be inlined.

doc/reference_manual.texi:
    Document the new attributes.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/intermod_may_export_body.exp:
tests/hard_coded/intermod_may_export_body.m:
tests/hard_coded/intermod_may_export_body2.m:
tests/invalid/Mmakefile:
tests/invalid/test_may_export_body.err_exp:
tests/invalid/test_may_export_body.m:
    Add test cases.

vim/syntax/mercury.vim:
    Update vim syntax file.

NEWS:
    Announce addition.
2021-04-20 11:05:29 +10:00
Peter Wang
d1522cbcb2 Make subtypes inherit user-defined equality/comparison from base type.
Since values of a subtype are tested for equality or compared
by first converting to the base type then testing/comparing,
it means that subtypes implicitly inherited any user-defined
equality/comparison from the base type. Allowing a subtype to also
define its own equality/comparison predicates seems more confusing
than useful, so disallow it.

compiler/prog_data.m:
    Add a option noncanon_subtype to maybe_canonical.

compiler/add_type.m:
    Report an error if a subtype defined in the current module
    has user-defined equality or comparison.

    Set the maybe_canonical field of hlds_type_defn for a subtype if the
    if the base type is noncanonical. Setting it to noncanon() makes the
    type_ctor_info have a MR_TypeCtorRep value of
    MR_TYPECTOR_REP_*_USEREQ.

compiler/unify_proc.m:
    Handle subtypes ahead of (other) noncanonical types when generating
    unify or compare proc clauses.

compiler/dead_proc_elim.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/post_term_analysis.m:
compiler/special_pred.m:
    Conform to changes.

doc/reference_manual.texi:
    Document change.

tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_user_compare.exp:
tests/hard_coded/subtype_user_compare.m:
tests/hard_coded/subtype_user_compare2.m:
tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/subtype_user_compare.err_exp:
tests/invalid/subtype_user_compare.m:
    Add test cases.
2021-04-13 11:38:15 +10:00
Peter Wang
ac70f6d36b Parse and check coerce expressions.
This change implements parsing, typechecking, and modechecking of
"coerce" expressions from my subtypes proposal, i.e. coerce(Term).
Backends currently will abort if asked to generate code for coercions,
as subtypes do not yet share data representations with their base types,
so most coercions would lead to crashes at runtime anyway.

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

compiler/hlds_goal.m:
    Add new type of generic_call to represent coerce expressions.

compiler/hlds_pred.m:
    Add new generic_call_id for coerce expressions.

compiler/superhomogeneous.m:
    Treat var-functor unifications of the form "Var = coerce(Term)"
    as special, producing coerce generic_calls.

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

compiler/type_assign.m:
    Add a field to type_assign to hold coerce constraints to be checked,
    or known to be unsatisfiable, in the given type assignment.

compiler/typecheck.m:
compiler/typecheck_errors.m:
    Implement typechecking of coerce expressions.

compiler/prog_type.m:
    Add a predicate type_is_ground_except_vars.

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

compiler/check_hlds.m:
    Add new module modecheck_coerce.

compiler/modecheck_coerce.m:
    Implement modechecking of coerce expressions.

compiler/modecheck_goal.m:
    Call modecheck_coerce at a coerce generic call.

compiler/mode_errors.m:
    Add two mode errors relating to coerce expressions.

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

compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/coverage_profiling.m:
compiler/deep_profiling.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_desc.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/mode_constraints.m:
compiler/old_type_constraints.m:
compiler/post_typecheck.m:
compiler/pre_quantification.m:
compiler/tabling_analysis.m:
compiler/term_traversal.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
compiler/unique_modes.m:
compiler/unused_imports.m:
compiler/purity.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
    Conform to changes.

compiler/prog_rep.m:
    Conform to changes. Reuse cast_rep for coercions for now.

compiler/hlds_statistics.m:
    Count coercions in proc stats.

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

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/coerce_ambig.err_exp:
tests/invalid/coerce_ambig.m:
tests/invalid/coerce_clobbered.err_exp:
tests/invalid/coerce_clobbered.m:
tests/invalid/coerce_disambig.err_exp:
tests/invalid/coerce_disambig.m:
tests/invalid/coerce_implied_mode.err_exp:
tests/invalid/coerce_implied_mode.m:
tests/invalid/coerce_infer.err_exp:
tests/invalid/coerce_infer.m:
tests/invalid/coerce_instvar.err_exp:
tests/invalid/coerce_instvar.m:
tests/invalid/coerce_mode_error.err_exp:
tests/invalid/coerce_mode_error.m:
tests/invalid/coerce_non_du.err_exp:
tests/invalid/coerce_non_du.m:
tests/invalid/coerce_syntax.err_exp:
tests/invalid/coerce_syntax.m:
tests/invalid/coerce_type_error.err_exp:
tests/invalid/coerce_type_error.m:
tests/invalid/coerce_unify_tvars.err_exp:
tests/invalid/coerce_unify_tvars.m:
tests/invalid/coerce_uniq.err_exp:
tests/invalid/coerce_uniq.m:
tests/invalid/coerce_unreachable.err_exp:
tests/invalid/coerce_unreachable.m:
tests/invalid/coerce_void.err_exp:
tests/invalid/coerce_void.m:
    Add test cases.

tests/typeclasses/arbitrary_constraint_class.m:
tests/typeclasses/arbitrary_constraint_pred_1.m:
tests/typeclasses/arbitrary_constraint_pred_2.m:
    Wrap parentheses around calls to a coerce/1 method
    to prevent them being treated as coerce expressions.

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

doc/reference_manual.texi:
    Rewrite chapter on Type conversions (still commented out).
    In particular, the typechecking rules that I had written
    previously were insufficient.

NEWS:
    Mention backwards incompatibility.
2021-03-15 11:16:31 +11:00
Peter Wang
74a31ba8ef Parse and check subtype definitions.
This is the first step towards implementing a subtypes feature.
It introduces type definitions of the form

    :- type subtype =< supertype ---> body.

Later, terms of a subtype should share a data representation with their
supertype, and it will be possible to convert terms between two types
that share "base types" using a coerce operation.

doc/reference_manual.texi:
    Add documentation for subtypes.

    Add documentation for a proposed `coerce' operation, commented out
    for now.

    Add "=<" to the list of reserved type names.

compiler/hlds_data.m:
    Add supertype field to hlds_du_type.

compiler/prog_data.m:
    Add du_supertype field to type_details_du.

    Add comment for future work.

compiler/parse_type_defn.m:
    Parse subtype definitions.

    Check that variables which occur in the "=< supertype" part
    also occur on the left hand side of the subtype definition.

compiler/parse_type_name.m:
    Add a new context for why_no_ho_inst_info.

    Add "=<" to is_known_type_name, i.e. prevent the user from defining
    a type of that name (any longer).

compiler/add_type.m:
    Rename add_du_ctors_check_foreign_type_for_cur_backend to
    add_du_ctors_check_subtype_check_foreign_type.

    In add_du_ctors_check_subtype_check_foreign_type, check that
    subtype definitions satisfy the conditions documented in the
    reference manual.

compiler/make_hlds_passes.m:
    Conform to previous renaming.

compiler/comp_unit_interface.m:
    Follow supertypes when computing the required type constructors
    whose definitions need to be kept in the implementation section
    of a .int file.

compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
    Replace equivalence types in supertypes.

compiler/module_qual.qualify_items.m:
    Perform module qualification in supertypes.

compiler/hlds_out_module.m:
    Write out the "=< supertype" part of subtype definitions.

compiler/parse_tree_out.m:
    Write out the "=< supertype" part of subtype definitions.

compiler/recompilation.usage.m:
    Follow supertypes when finding used items.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/dead_proc_elim.m:
compiler/decide_type_repn.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/du_type_layout.m:
compiler/foreign.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/post_term_analysis.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to HLDS changes.

    Add comments for future work.

tests/invalid/Mmakefile:
tests/invalid/subtype_abstract.err_exp:
tests/invalid/subtype_abstract.m:
tests/invalid/subtype_circular.err_exp:
tests/invalid/subtype_circular.m:
tests/invalid/subtype_ctor_arg.err_exp:
tests/invalid/subtype_ctor_arg.m:
tests/invalid/subtype_eqv.err_exp:
tests/invalid/subtype_eqv.m:
tests/invalid/subtype_exist_constraints.err_exp:
tests/invalid/subtype_exist_constraints.m:
tests/invalid/subtype_exist_vars.err_exp:
tests/invalid/subtype_exist_vars.m:
tests/invalid/subtype_foreign.err_exp:
tests/invalid/subtype_foreign.m:
tests/invalid/subtype_foreign_supertype.err_exp:
tests/invalid/subtype_foreign_supertype.m:
tests/invalid/subtype_foreign_supertype2.err_exp:
tests/invalid/subtype_foreign_supertype2.err_exp2:
tests/invalid/subtype_foreign_supertype2.m:
tests/invalid/subtype_ho.err_exp:
tests/invalid/subtype_ho.m:
tests/invalid/subtype_invalid_supertype.err_exp:
tests/invalid/subtype_invalid_supertype.m:
tests/invalid/subtype_not_subset.err_exp:
tests/invalid/subtype_not_subset.m:
tests/invalid/subtype_syntax.err_exp:
tests/invalid/subtype_syntax.m:
tests/invalid_submodules/Mercury.options:
tests/invalid_submodules/Mmakefile:
tests/invalid_submodules/subtype_submodule.err_exp:
tests/invalid_submodules/subtype_submodule.m:
tests/valid/Mmakefile:
tests/valid/subtype_basic.m:
    Add test cases.
2021-03-15 11:16:31 +11:00
Zoltan Somogyi
4ebe95672d Don't crash on inst_name nested inside itself.
This fixes Mantis bug #528.

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

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

tests/invalid/Mmakefile:
    Enable the Mantis test case.
2021-01-30 01:45:26 +11:00
Zoltan Somogyi
5a5a35bd09 Don't crash for type errors in foreign_procs.
Normally, foreign_procs are assumed to be type correct, because they
have to be: a Mercury compiler cannot check foreign code. However,
in one case, we can get type errors for foreign_procs That case is when
a predicate has

- an existentially typed argument, and
- two or more modes implemented by foreign procs.

The compiler has never been able to correctly handle more than one clause
defining the type_info of an existentially typed argument. When those clauses
were Mercury clauses, it generated an error; when those "clauses" were
foreign_procs, it *tried* to generate an error, but the code that did that
crashed the compiler.

compiler/typecheck_errors.m:
    Fix the compiler abort, letting the error message be generated.

tests/invalid/foreign_procs_exist_type.{m,err_exp}:
    Add a test case for this fix.

tests/invalid/Mmakefile:
    Enable the new test case.
2021-01-27 14:40:49 +11:00
Zoltan Somogyi
63dabcfcf8 Fix filling in partial terms that use direct_arg tags.
This fix uses the approach discussed on m-dev 2020 nov 16/17 for fixing
github issue #72, whose core problem is a need for information flow
back to a the caller from a callee when the callee fills in the
argument of a function symbol whose representation is a direct_arg tag.
In most cases when the callee fills in the value of an argument,
the caller can see it because the argument is in a word on the heap,
but when the function symbol uses a direct_arg tag, that is not the case.

compiler/direct_arg_in_out.m:
    A new module that implements the transformation proposed on m-dev.
    It creates a fresh clone variable every time an argument of a direct_arg
    tag function symbol is (or may be) updated. This can happen several
    times if a type has more than one function symbol with a direct_arg tag.
    Since the affected variable can be bound to only one function symbol
    at the start, its argument can be filled in only once, but the
    compiler cannot know in advance what function symbol the variable
    contains, and therefore which of the possibly several fill-in sites
    (which fill in the arguments of different function symbols) executed
    in sequence will actually update the variable.

    The transformation ensures that once a variable is cloned, it is
    never referred to again. It also ensures that in a branched control
    structure (if-then-else, disjunction or switch), all branches will use
    the *same* variable to represent the latest version of each cloned
    variable at the end, so that following code has a consistent view
    regardless of through which branch execution has reached it.

    There are three situations that the transformation cannot and does not
    handle.

    1. Situations in which the mode of an argument is either an inst variable,
       or an abstract inst. In either case, the pass cannot know whether
       it should apply its transformation to the argument.

    2. Situations where a procedure that has such an argument is
       exported to C code as a function. In that case, the C signature
       of the function we would generate would be different from what
       the user would normally expect. We could modify the documentation
       of the export pragma, but I don't think there much point due to
       lack of demand. (The problem cannot arise when targeting any language
       other than C, because we use direct_arg tags only with the low level
       data representation, which we only use for C.)

    3. Situations where a procedure that has such an argument is defined
       by foreign_proc. Again, dealing with the problem would require
       nontrivial changes to the documented interface between code in
       foreign_procs and the surrounding Mercury code, and I see no demand
       for code that could benefit from that.

    In these cases, this module generates error messages.

compiler/transform_hlds.m:
    Include the new module in the transform_hlds package.

    Delete unnecessary module qualification on some existing inclusions.
    Put some existing inclusions into a more meaningful order.

compiler/notes/compiler_design.html:
    Document the new pass. Fix some nearby prose.

compiler/lambda.m:
compiler/simplify_proc.m:
    Use a predicate exported by direct_arg_in_out.m to test, for each
    procedure, whether the procedure has any argument positions that are
    subject to the problem that direct_arg_in_out.m addresses.
    simplify_proc.m does this for all procedures it processes;
    lambda.m does this for all the procedures it creates from
    lambda expressions.

    Give a predicate in simplify_proc.m a better name.

    Sort a list of predicate names.

compiler/hlds_module.m:
    Add a field to the module_info that simplify_proc.m and lambda.m
    can use to tell direct_arg_in_out.m what work (if any) it needs to do.

compiler/mercury_compile_middle_passes.m:
    Invoke direct_arg_in_out.m if the new field in the HLDS indicates
    that it has some work to do. (In the vast majority of compiler invocations,
    it won't have any.)

compiler/hlds_pred.m:
    The new code in direct_arg_in_out.m creates a clone of each procedure
    affected by the problem, before deleting the originals (to make sure that
    no references to the unfixed versions of now-fixed procedures remain.)
    Make it possible to create exact clones of both predicates and procedures
    by adding two pairs of predicates, {pred,proc}_prepare_to_clone and
    {pred,proc}_create.

    Add the direct_arg_in_out transformation as a possible source
    of transformed predicates.

library/private_builtin.m:
    Add a new builtin operation, partial_inst_copy, that the new module
    generates calls to.

configure.ac:
    Require the installed compiler to recognize partial_inst_copy
    as a no_type_info builtin.

compiler/builtin_ops.m:
    Recognize the new builtin. (This was committed before the rest; the diff
    to private_builtin.m can be done only once the change to builtin_ops.m
    is part of the installed compiler.)

compiler/options.m:
    Add a way to test whether the builtin_ops.m in the installed compiler
    recognizes the new builtin.

compiler/dead_proc_elim.m:
    Do not delete the new primitive before direct_arg_in_out.m has had
    a chance to generate calls to it.

    Add an XXX.

compiler/error_util.m:
    Recognize the new module as a source of error messages.

compiler/pred_table.m:
    Add a pair of utility predicates to be used when looking up
    builtin predicates, for which the compiler writer knows that
    there should be exactly one match. These are used in direct_arg_in_out.m.

compiler/simplify_goal_call.m:
    Replace some existing code with calls to the new predicates
    in pred_table.m.

compiler/hlds_goal.m:
    Add modes to rename_vars_in_goal_expr that express the fact
    that when an atomic goal_expr has some variables renamed inside it,
    it does not suddenly become some *other* kind of goal_expr.
    New code in direct_arg_in_out.m relies on this.

compiler/hlds_out_goal.m:
    When the HLDS we are dumping out is malformed because it contains
    calls to predicates that have been deleted, the compiler used to abort
    at such calls. (I ran into this while debugging direct_arg_in_out.m.)

    Fix this. When such calls are encountered, we now print out as much
    information we can about the call, and prefix the call with an
    unmistakable prefix to draw attention to the problem.

compiler/inst_util.m:
    Fix a bug that prevented direct_arg_in_out.m from even being invoked
    on some test code for it.

    The bug was in code that we use to unify a headvar's initial inst
    with its final inst. When the initial inst was a non-ground bound_inst
    such as the ones used in tests/hard_coded/gh72.m, and the final inst
    was simply "ground", this code quite properly returned a bound_inst
    (which, unlike ground, can show the exact set of function symbols
    that the headvar could be bound to). The problem was that it
    reused the original bound_inst's test results, including the one
    that said the final inst is NOT ground, which of course is wrong
    for any inst unified with ground. Fix two instances of this bug.

compiler/modes.m:
    Make some of the code I had to traverse to find the bug in inst_util.m
    easier to read and understand.

    Replace some uses of booleans with bespoke enum types.

    Change the argument lists of some predicates to put related arguments
    next to each other.

    Give some variables more descriptive names.

compiler/layout_out.m:
    Conform to the change in hlds_pred.m.

compiler/var_locn.m:
    Fix a code generation bug. When filling-in the value of the argument
    of a function symbol represented by a direct_arg tag, the code we
    generated for it worked only if the direct_arg tag used 0
    as its ptag value. In the test cases we initially used for
    github issue 72, that was the case, but the new tests/hard_coded/gh72.m
    has direct_tag args that use other ptag values as well.

    Document the reason why the updated code works.

compiler/term_constr_initial.m:
    Add the new primitive predicate added to private_builtin.m,
    partial_inst_copy, to a table of builtins that do not take type_infos,
    even though their signatures contain type variables.

    Fix a bunch of old bugs: most other such primitives were not listed
    either.

mdbcomp/program_representation.m:
    Add partial_inst_copy to the master list of builtins that do not take
    type_infos even though their signatures contain type variables. (Done
    by an earlier commit.)

    Document the fact that any updates here require updates to
    term_constr_initial.m.

library/multi_map.m:
    We have long had multi_map.add and multi_map.set as synonyms,
    but we only had multi_map.reverse_set. Add multi_map.reverse_add
    as a synonym for it.

    Define the "set" versions in terms of the "add" versions,
    instead of vice versa.

NEWS:
    Document the new predicates in multi_map.m.

tests/hard_coded/gh72a.m:
    Fix typo.

tests/hard_coded/gh72.{m,exp}:
    A new, much more comprehensive test case than gh72a.m.
    This one tries to tickle github issue 72 in as many forms of code
    as I can think of.

tests/invalid/gh72_errors.{m,err_exp}:
    A test case for testing the generation of error messages for
    two out of the three kinds of situations that direct_arg_in_out.m
    cannot handle. (Proposals for how to test the third category welcome.)

tests/hard_coded/Mmakefile:
tests/invalid/Mmakefile:
    Enable the two new test cases, as well as two old ones, gh72[ab].m,
    that previously we didn't pass.

tests/invalid/Mercury.option:
    Do not compile gh72_error.m with --errorcheck-only, since its errors
    are reported by a pass that --errorcheck-only does not invoke.
2021-01-13 05:35:40 +11:00
Julien Fischer
1e5f1c9b59 Use the correct comment character in a Mmakefile.
tests/invalid/Mmakefile:
    As above.
2021-01-07 16:14:46 +11:00
Peter Wang
332002da68 Avoid tests/invalid failures with intermodule optimisation.
tests/invalid/Mmakefile:
    For modules for which the compiler may emit errors while making
    their .opt files, redirect the errors to a .err file and ignore the
    exit status. The .err file will then be compared to .err_exp* files.
2020-11-10 13:06:22 +11:00
Zoltan Somogyi
1045c37bd3 Report references to nonexistent typeclasses.
compiler/check_typeclass.m:
    Look for typeclass constraints on predicates and data constructors
    that refer to nonexistent typeclasses. We already report such references
    when they occur in the module being compiled, but not when they occur
    in declarations imported from other modules.

    Before this diff, the compiler used to abort with a failed map.lookup
    when this occurred. With this diff, the compiler prints a diagnostic
    and exits normally.

    Give some predicates more meaningful names. Update an accumulator
    using a predicate, not a function. Exploit capabilities in error_util.m
    that did not exist when this module first started to use it.
    Use set operations instead of solutions to compute an intersection.
    Avoid repeated string copying. Fix indentation.

tests/invalid/bad_type_class_constraint_intermodule.err_exp:
tests/invalid/bad_type_class_constraint_intermodule.m:
tests/invalid/bad_type_class_constraint_intermodule_2.m:
    A new test case for this problem.

tests/invalid/Mmakefile:
    Enable the new test case.
2020-11-07 11:28:39 +11:00
Peter Wang
524f4d72e2 Delete references to Erlang backend in makefiles.
Mmake.workspace:
Mmakefile:
*/Mmakefile:
tests/*/Mmakefile:
tests/valid/Mmake.valid.common:
trace/Mmakefile:
    As above.
2020-10-27 11:10:11 +11:00
Zoltan Somogyi
409cbcb6a3 Unify getopt.m and getopt_io.m ...
... using an approach proposed by Peter, with an extra twist from Julien.

Instead of having two modules, getopt.m and getopt_io.m, with the former
defining predicates that do not take an I/O state pair, and the latter
defining predicates that do take an I/O state pair, put both kinds of
predicates into a single module. The versions with an I/O state pair
have an "_io" suffix added to their names for disambiguation.
Both versions are a veneer on top of a common infrastructure,
which relies on a simple type class to implement the operation
"give the contents of the file with this name". The predicate versions
with I/O state pairs have a normal implementation of this typeclass,
while the predicate versions that do not have I/O state pairs
have an implementation that always returns an error indication.

The above change just about doubles the number of exported predicates.
We already had two versions of most exported predicates that differed
in whether we returned errors in the form of a string, or in the form
of a structured representation, with names of the latter having
an "_se" suffix. Since we agreed that the structured representation
is the form we want to encourage, this diff deletes the string versions,
and deletes the "_se" suffix from the predicate names that used to have them.
(It still remains at the end of the name of a type.) This "undoubling"
should offset the effect of the doubling in the previous paragraph.

Eventually, we want to have just one module, getopt.m, containing
the updated code described above, but for now, we put the same code
into both getopt_io.m and getopt.m to prevent too big a shock to
people with existing code that uses getopt_io.m.

library/getopt.m:
library/getopt_io.m:
    Make the changes described above.

library/Mmakefile:
    Instead of building both getopt_io.m and getopt.m from getopt_template,
    build getopt.m from getopt_io.m.

tools/bootcheck:
    Delete references to getopt_template.

compiler/typecheck_errors.m:
    When a type error involves one of the getopt/getopt_io predicates
    whose interfaces are changed by this diff, tell the user about
    how these changes could have caused the error, and thus what the
    probable fix is.

compiler/handle_options.m:
browser/parse.m:
deep_profiler/mdprof_cgi.m:
deep_profiler/mdprof_create_feedback.m:
deep_profiler/mdprof_dump.m:
deep_profiler/mdprof_procrep.m:
deep_profiler/mdprof_report_feedback.m:
deep_profiler/mdprof_test.m:
profiler/mercury_profile.m:
slice/mcov.m:
slice/mdice.m:
slice/mslice.m:
slice/mtc_diff.m:
slice/mtc_union.m:
tests/hard_coded/space.m:
    Use the updated getopt interface.

compiler/compile_target_code.m:
compiler/compute_grade.m:
compiler/deforest.m:
compiler/det_report.m:
compiler/format_call.m:
compiler/globals.m:
compiler/goal_expr_to_goal.m:
compiler/make.build.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/mercury_compile_main.m:
compiler/ml_top_gen.m:
compiler/module_cmds.m:
compiler/op_mode.m:
compiler/optimization_options.m:
compiler/options.m:
compiler/write_module_interface_files.m:
tools/make_optimization_options_middle:
tools/make_optimization_options_start:
    Replace references to getopt_io.m with references to getopt.m.

tests/invalid/getopt_io_old.{m,err_exp}:
tests/invalid/getopt_old.{m,err_exp}:
tests/invalid/getopt_old_se.{m, err_exp}:
    New test cases for the extra help

tests/invalid/Mmakefile:
    Enable the new test cases.
2020-10-09 19:30:46 +11:00
Zoltan Somogyi
7583d27f21 Warn about missing information in .int files.
compiler/add_pred.m:
    When recording the declaration of a predicate or function that is
    imported from another module, report an error for any types in the
    argument list that were not module qualified when the .int file
    was constructed.

    Eventually, once the cleanup of our system of managing interface files
    is done, we can switch to preventing the generation of .int files
    with missing information. The above change should help until then.

tests/invalid/bug521.m:
tests/invalid/bug521_sub.m:
tests/invalid/bug521.err_exp:
    A new test case for the new error message.

tests/invalid_make_int/bug521_sub.m:
tests/invalid_make_int/bug521_sub.int_err_exp:
tests/invalid_make_int/Mercury.options:
    A new test case for how we would diagnose the same problem
    at interface-generation time.

tests/invalid/Mmakefile:
tests/invalid_make_int/Mmakefile:
    Enable the new test cases.
2020-10-08 16:04:02 +11:00
Zoltan Somogyi
f52d2381cc Make pred/func types more readable in error messages.
Until now, mismatches between expected and actual types, when they were
higher order types, got reported like this (the motivating example):

handle_options.m:158: In clause for predicate `process_given_options'/8:
handle_options.m:158:   in argument 3 of functor `option_ops_userdata/3':
handle_options.m:158:   type error in unification of argument
handle_options.m:158:   and constant `special_handler'.
handle_options.m:158:   argument has type `pred(libs.options.option,
handle_options.m:158:   getopt_io.special_data,
handle_options.m:158:   tree234.tree234(libs.options.option,
handle_options.m:158:   getopt_io.option_data),
handle_options.m:158:   getopt_io.maybe_option_table(libs.options.option),
handle_options.m:158:   UserDataType, UserDataType)',
handle_options.m:158:   constant `special_handler' has type
handle_options.m:158:   `pred(libs.options.option, getopt_io.special_data,
handle_options.m:158:   tree234.tree234(libs.options.option,
handle_options.m:158:   getopt_io.option_data),
handle_options.m:158:   getopt_io.maybe_option_table(libs.options.option))'.

This is hard to read

- because there is no visual break between the expected and the actual type,
  and

- because the different initial prefixes before the starts of the types
  prevent corresponding argument types in the expected and actual types
  from lining up.

compiler/typecheck_errors.m:
    Fix the above by always putting the argument types of higher order values
    on lines of their own in such error messages. One side effect of this is
    that we don't wrap predicate types in parentheses. (The parentheses' job
    is to prevent unwanted interactions with surrounding code, but in
    error messages, there *is* no surrounding code.)

    Reorder the argument lists of some predicates and functions
    to let them be used as the first argument of list.map.

compiler/parse_tree_to_term.m:
    Delete a predicate that duplicates another predicate.

tests/invalid/ho_type_arity_bug.{m,err_exp}:
    A new test case for the updated error message format.

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

tests/invalid/bug197.err_exp:
tests/invalid/nullary_ho_func_error.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/invalid/types2.err_exp:
tests/invalid_purity/impure_func_t5.err_exp:
tests/invalid_purity/impure_pred_t1.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
    Expect updated error messages.
2020-09-25 14:38:58 +10:00
Zoltan Somogyi
35a4f3a2dd Fix some error messages for malformed pragmas.
compiler/parse_pragma.m:
    Improve error handling in several respects.

    First, for several kinds of pragmas the only error message we printed
    was some form of "something went wrong". Fix this by generating messages
    that say what part of the pragma has a problem, and what that problem is.

    Second, specify the "where" part more precisely, as a nested context
    (in construct A: in construct B: etc).

    Third, make the text of error messages more consistent, using patterns
    such as "expected abc, got def", and "In the Nth argument of xyz:".

    Fourth, don't stop looking for errors after finding one; keep looking
    for others.

    Also, replace a bunch of if-then-elses with switches, and break up
    a too-large predicate.

compiler/parse_sym_name.m:
    Add parse_sym_name_and_no_args, a version of the existing predicate
    try_parse_sym_name_and_no_args that generates an error message if it
    does not find what it is asked to look for.

    Use the same consistent error message phraseology as above (which we
    also use elsewhere in the compiler).

compiler/parse_item.m:
    Put a newline at the end of context pieces such as "In clause head:",
    so that the "error:" that follows is not buried in the middle of a line.

tests/invalid/bad_pragma.{m,err_exp}:
    Add a news test case for some of the updated error messages.

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

tests/invalid/bad_foreign_enum.m:
    Add another bad foreign_enum to this test.

tests/invalid/bad_detism_category.err_exp:
tests/invalid/bad_foreign_code.err_exp:
tests/invalid/bad_foreign_enum.err_exp:
tests/invalid/bad_foreign_export.err_exp:
tests/invalid/bad_foreign_export_enum.err_exp:
tests/invalid/bad_foreign_import_module.err_exp:
tests/invalid/bad_foreign_proc.err_exp:
tests/invalid/bad_foreign_type.err_exp:
tests/invalid/bad_with_inst.err_exp:
tests/invalid/impl_def_literal_syntax.err_exp:
tests/invalid/invalid_float_literal.err_exp:
tests/invalid/null_char.err_exp:
tests/invalid/predmode.err_exp:
tests/invalid/require_tailrec_invalid.err_exp:
tests/invalid/some.err_exp:
tests/invalid/specified.err_exp:
tests/invalid/vars_in_wrong_places.err_exp:
    Expect the updated error messages.
2020-08-23 10:29:34 +10:00
Zoltan Somogyi
523e897a31 Get "make clean" to delete some intermediate files. 2020-08-11 20:46:21 +10:00
Zoltan Somogyi
1f45f91886 Make "mmake runtests" work again.
My commit afe2887882 broke the ability
to run the test suite outside of a bootcheck by executing "mmake runtests"
in the tests directory. This diff fixes that.

tests/Mmake.common:
    Don't define "TESTS_DIR = ..". While every single tests/*/Mmakefile
    defined it as such, I overlooked the fact that tests/Mmakefile itself
    defined it ".", referring to the same directory from a different starting
    point. Document this easily-overlooked fact.

    Rename the old runtests target, which after afe2887 runs the tests
    in a single directory, as runtests_dir, to leave the target name
    "runtests" itself free for tests/Mmakefile to use.

tests/Mmakefile:
    Define "TESTS_DIR = .", and add a target "runtests" which invokes
    "mmake runtests_dir" in each test directory.

tools/bootcheck:
    Invoke "mmake runtests_dir" instead of "mmake runtests" in each
    test directory.

    Initialize a variable just before it is used.

tests/*/Mmakefile:
    Add back the definition "TESTS_DIR = .."
2020-06-10 01:05:15 +10:00
Zoltan Somogyi
86adb6e1f4 Test the error message for bad type arities.
tests/invalid/type_arity.{m,err_exp}:
    A new test case that uses a type constructor with the wrong arity.

tests/invalid/Mmakefile:
    Enable the new test case.
2020-05-22 06:42:35 +10:00
Zoltan Somogyi
840c12c0cf Improve doc and error messages for existential types.
doc/reference_manual.texi:
    Document the restrictions that the parse_type_defn.m implements
    (or at least tries to).

    Fix three bugs in one of the "supposed to be correct" examples,
    as well as the formatting that previously made the bugs harder to see.

compiler/parse_type_defn.m:
    Improve the wording of error messages for errors involving existentially
    typed data constructors.

    Simplify the structure of one of the predicates that generate such
    messages.

compiler/parse_class.m:
    Add a period to the end of an error message.

tests/invalid/bad_existential_data_type.{m,err_exp}:
    A new test case for the updated error messages, most of which
    weren't being tested before.

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

tests/invalid/fundeps_unbound_in_ctor.err_exp:
tests/invalid/type_vars.err_exp:
    Update the expected wording of some error messages.
2020-05-06 15:32:33 +10:00