Commit Graph

917 Commits

Author SHA1 Message Date
Zoltan Somogyi
ce3e48d5ed Fix an ninth batch of C# invalid test failures.
tests/invalid/foreign_enum_invalid.{m,err_exp}:
    Delete the "foreign enum in interface" error from this test case,
    moving it to invalid_make_int/bad_in_interface.

tests/invalid/foreign_type_visibility.err_exp2:
tests/invalid/foreign_type_visibility.err_exp3:
    Add these expected outputs for Java and C# respectively.
tests/invalid/foreign_type_visibility.m:
    Document the new expected output files.
tests/invalid/foreign_type_visibility.err_exp:
    Update for changed line numbers.

tests/invalid/foreign_include_file_missing.m:
    Fix indentation.

tests/invalid/Mercury.options:
    Allow a test case to get past the creation of interface files.

tests/invalid_make_int/bad_in_interface.{m,int_err_exp}:
    Move the "foreign enum in interface" part of invalid/foreign_enum_invalid
    here.
2023-10-30 15:54:22 +11:00
Zoltan Somogyi
68cf30cb37 Fix a fifth batch of C# invalid test failures.
compiler/det_analysis.m:
    Improve an error message about foreign_procs by printing it with
    the context of the foreign_proc itself, not the context of the
    procedure it is for. Also, make the wording more specific.

compiler/prog_event.m:
    Reading event sets is currently implemented when the compiler
    is compiled for the C backend (because its parser uses lex/flex
    and yacc/bison). However, that is no reason for crashing the compiler if
    - someone asks it to read an event set
    - while the compiler is compiled to a target language other than C.
    Fix this by returning an apology message instead of crashing.

tests/invalid/pragma_c_code_no_det.m:
tests/invalid/test_may_duplicate.m:
tests/invalid/test_may_export_body.m:
    Add foreign procs for Java and C# as well as for C.

tests/invalid/pragma_c_code_no_det.err_exp{,2,3}:
tests/invalid/test_may_duplicate.err_exp{,2,3}:
tests/invalid/test_may_export_body.err_exp{,2,3}:
    Add expected output files for Java and C#. Update the line numbers
    in the expected file for C.

tests/invalid/test_type_spec.m:
    Delete the parts of this test case that contain errors that we now report
    when creating .int files. We now test for those errors using the new test
    case tests/invalid_make_int/test_type_spec_int.
tests/invalid/test_type_spec.err_exp:
    Delete the messages for the deleted errors, expect verbose errors
    (see the update of Mercury.options below), and update the line numbers.

tests/invalid/try_detism.m:
    Explain the reason for the need for the new .err_exp2 file.
tests/invalid/try_detism.err_exp{,2}:
    Add the new .err_exp2 file for C#, which differs from the .err_exp file
    only in the variable number of a compiler-generated variable.
    Update the line numbers in the .err_exp file.

tests/invalid/undef_type.m:
    Fix the one problem in this test case that we now report when we create
    .int files. The handling of that problem is now tested in the new
    tests/invalid_make_int/undef_type_int test case.

tests/invalid/undef_type.err_exp:
    Don't expect a report for the fixed error.

tests/invalid/Mercury.options:
    Run the test_type_spec test case with verbose errors.

tests/invalid/Mmakefile:
    Don't try to execute the test cases that this diff moves to
    tests/invalid_make_int.

    Execute the test cases that try to read event set specifications
    only when targeting C. This is not the exact condition we want,
    but it is the closest to that condition that we can actually get.

tests/invalid_make_int/bad_instance.{m,int_err_exp}:
tests/invalid_make_int/type_arity.{m,int_err_exp}:
tests/invalid_make_int/undef_inst.{m,int_err_exp}:
tests/invalid_make_int/undef_mode.{m,int_err_exp}:
tests/invalid_make_int/undef_type_mod_qual.{m,int_err_exp}:
    Move these tests here from tests/invalid.

tests/invalid_make_int/test_type_spec_int.{m,int_err_exp}:
tests/invalid_make_int/undef_type_int.{m,int_err_exp}:
    The parts of the test_type_spec and undef_type test cases in tests/invalid
    that get error messages generarated for them while making .int files.

tests/invalid_make_int/Mercury.options:
tests/invalid_make_int/Mmakefile:
    Add the tests moved here, in whole or in part, from tests/invalid.
2023-10-27 15:52:11 +11:00
Zoltan Somogyi
5193012242 Fix a fourth batch of C# invalid test fails.
compiler/add_foreign_proc.m:
    Don't module qualify the named of predicates/functions
    defined by foreign_procs when generating an error message
    about that foreign_proc, since

    - you can add foreign_procs only for local predicates/functions, and
    - even if you one for a NON-local predicate/function, the context will
      tell you exactly which foreign_proc is being complained about.

    Also, improve the wording of the error message.

tests/invalid/instances_pc.instances_pc_helper_1.err_exp2:
tests/invalid/instances_pc.m:
    Add a new expected output file for bootchecks in C# and Java grades,
    and document the new expected output file.

tests/invalid/pragma_c_code_dup_var.{err_exp2,err_exp3}:
tests/invalid/pragma_c_code_dup_var.{m,err_exp}:
    Add two new expected output files for bootchecks in C# and Java grades.
    Note the role of each expected output file, and apply the resulting
    line number changes to the expected output file for C.

tests/invalid_make_int/instance_no_type.{m,int_err_exp}:
    Move this test case from tests/invalid to tests/invalid_make_int,
    since the compiler now diagnoses the bug it tests for
    during the creation of the .int file.

tests/invalid_make_int/pragma_export_int.{m,err_exp}:
    Move half of the pragma_export test case here from tests/invalid,
    since the compiler now diagnoses the bug it tests for
    during the creation of the .int file.

tests/invalid_nodepend/pragma_export.{m,err_exp}:
    Move the other half of the pragma_export test case here from tests/invalid.
    With mmc --make, the diagnosable-at-.int-file-creation-time errors
    prevent the compiler from ever getting to the errors that are not
    diagnosable at that time, so delete the code that gives rise to those
    diagnosable-at-that-time errors from this version of the test case..

tests/invalid/Mmakefile:
    Delete the tests moved to other test directories.

tests/invalid_make_int/Mercury.options:
tests/invalid_make_int/Mmakefile:
tests/invalid_nodepend/Mmakefile:
    Add the tests moved to these directories from tests/invalid.
2023-10-26 15:18:41 +11:00
Zoltan Somogyi
f7a06c1f24 Fix a third batch of C# invalid test fails.
compiler/make.program_target.m:
    All the multimodule tests in tests/invalid_make_int have been failing
    in C# grades. The script for these tests has two main steps:

    - build all the .int3 files involved, and then
    - build the .int file.

    The second step is expected to fail, with its error messages being tested,
    but the first step is expected to succeed. The test cases were failing
    because mmc --make built the .int files as part of the FIRST stage.

    The cause was code that built all interface files (.int3, .int0,
    .int/.int2 and even .opt) as a preliminary first step before actually
    trying to act on *any* build-all target. The fix is to make this
    preliminary step build only the interface files that come before
    the build-all target's file kind in the build order. In this case,
    that means not building anything in the preliminatu step of the
    build-all-int3s target before building all the .int3s, thus leaving
    the construction of the .int file for the second step, which is
    *expected* to fail.

tests/invalid/exported_unify_helper_1.m:
    Rename exported_unify2.m to exported_unify_helper_1.m in accordance
    with our usual scheme.

tests/invalid/exported_unify.{m.err_exp,err_exp2}:
    Update both expected error files for the rename. Since the .err_exp2 file
    was ancient, this update fixed the test case failure for C# (and almost
    certainly for Java) bootchecks. Note the role of each expected output
    file in the source code.

tests/invalid/foreign_procs_exist_type.err_exp2:
tests/invalid/foreign_procs_exist_type.err_exp3:
    Add these files containing the expected outputs for Java and C#.

tests/invalid/foreign_procs_exist_type.m:
    Add a note about the role of each expected output file.

tests/invalid/foreign_procs_exist_type.err_exp:
    Update the line numbers for this file containing the C expected output.

tests/invalid/foreign_purity_mismatch.m:
tests/invalid/fp_dup_bug.m:
    For each C foreign proc being tested, add C# and Java foreign_procs
    as well.

    Add a note about the role of each expected output file.

tests/invalid/foreign_purity_mismatch.err_exp2:
tests/invalid/foreign_purity_mismatch.err_exp3:
tests/invalid/fp_dup_bug.err_exp2:
tests/invalid/fp_dup_bug.err_exp3:
    Add these files containing the expected outputs for Java and C#.

tests/invalid/foreign_purity_mismatch.err_exp:
tests/invalid/fp_dup_bug.err_exp:
    Update the line numbers for this file containing the C expected output.

tests/invalid/gh72_errors.m:
    This test case tests an error message from the direct arg transformation.
    This transform does not apply to C# and Java grades, so in those grades,
    the compiler does not generate those messages. In those grades, this
    test case failed because the compilation succeeds, instead of failing
    (with the expected message, or not).

    Fix this failure by adding to gh72_errors.m C# and Java foreign_procs
    that do get error messages.

tests/invalid/gh72_errors.err_exp2:
tests/invalid/gh72_errors.err_exp3:
    Expect these error messages in C# and Java grades respectively.

tests/invalid/gh72_errors.err_exp:
    Update the line numbers in the error messages during C compilations.
2023-10-26 08:47:39 +11:00
Zoltan Somogyi
a3ea222883 Fix more C# test case failures in tests/invalid*.
compiler/options.m:
doc/user_guide.texi:
    Add a new developer-only option, --std-int-file-not-written-msgs,
    which, if specified, calls for the "file not written" messages
    we generate when we want to write interface files but can't
    to be written out in a standard form that deletes the directory
    path component from the names of the files not written out.
    In the long term, it is less work to add this option once
    than to add a separate .err_exp file for each affected test case.

compiler/write_module_interface_files.m:
    Obey the new option.

tests/invalid/ee_invalid.m:
    Add C# and Java foreign_types next to the C foreign_type.

tests/invalid/erroneous_throw_promise.m:
    Add C# foreign_procs next to the C and Java foreign_procs.

tests/invalid/exist_foreign_error.m:
    Add C# and Java foreign_procs next to a C foreign_proc.
tests/invalid/exist_foreign_error.err_exp:
tests/invalid/exist_foreign_error.err_exp2:
tests/invalid/exist_foreign_error.err_exp3:
    Update the line number in the expected error output file for C,
    and add expected error output files for Java and C#.

tests/invalid_make_int/bug17.{m,int_err_exp}:
tests/invalid_make_int/builtin_int.{m,int_err_exp}:
    Move these test cases here from tests/invalid, since all the errors
    we test for are reported when making the .int file.

tests/invalid/Mmakefile:
    Delete the tests moved to tests/invalid_make_int.

tests/invalid_make_int/Mercury.options:
tests/invalid_make_int/Mmakefile:
    Add the tests moved from tests/invalid. Specify the new option
    for all the test cases.
2023-10-25 19:21:06 +11:00
Julien Fischer
658385479f Fix a typo.
tests/invalid/bad_fact_table_data.m:
    We expect to match the .err_exp2 file when targeting non-C
    grades.
2023-10-24 16:27:11 +11:00
Zoltan Somogyi
c964bc5267 Fix two C# test case failures in tests/invalid.
tests/invalid/any_to_ground_in_ite_cond_nomax.m:
    Add C# and Java foreign_procs next to a C foreign_proc.

tests/invalid/bad_fact_table_data.err_exp2:
    Add the expected output for this test case in grades that
    do not support fact tables.

tests/invalid/bad_fact_table_data.m:
    Document which expected output files is expected to be matched
    in which bootchecks.
2023-10-24 14:04:23 +11:00
Zoltan Somogyi
db9d91713a Add missing C# and Java foreign_procs for a test case. 2023-10-20 14:16:57 +11:00
Zoltan Somogyi
5a57f28d03 Don't repeat an error explanation.
compiler/check_typeclass.m:
    Delete the verbose_only part of an error message, because it duplicated
    almost exactly the always-printed part of the same error message.

tests/invalid/instance_var_bug.err_exp:
    Don't expect the verbose part.

tests/invalid/bad_instance2.err_exp:
tests/invalid/invalid_instance_declarations.err_exp:
    Don't expect a reminder about the existence of the verbose part.
2023-10-19 16:09:36 +11:00
Zoltan Somogyi
df189347c4 Update an .err_exp file for a recently changed filename.
tests/invalid/bad_exported_mode.err_exp2:
    Update the name of a recently moved file in the context.

tests/invalid/bad_exported_mode.m:
    Add a comment specifying when we expect each .exp_exp* file to match.
2023-10-19 16:05:55 +11:00
Zoltan Somogyi
68c3d4040b Let callers of write_*interface_file* print errors.
compiler/write_module_interface_files.m:
    When the process of generating the contents of an interface file
    finds some errors, don't print those errors immediately. Just return
    them instead, letting the caller decide what to do with them.

    Fix comment rot.

compiler/make.get_module_dep_info.m:
compiler/mercury_compile_main.m:
    Print the error specs returned by the updated predicates (for now,
    at least).

compiler/error_sort.m:
    Fix an issue exposed by the changes above. When comparing two error_specs
    to see which one should be printed first, don't take the lack of a content
    in an error_spec as a sign that it should be printed first. Instead,
    pay attention to the comparison of contexts *only* if both of the
    error_specs being compared actually *have* contexts.

tests/invalid/type_inf_loop.err_exp:
    Expect the contextless message about exceeding the type inference
    iteration limit to come after the other messages, due to the update
    to error_sort.m.

tests/invalid/type_inf_loop.err_exp2:
    Delete this file. It can't match the compiler's current output,
    or (it seems) the output of any compiler version since we switched
    to reporting type errors using error_specs.
2023-10-08 10:11:08 +11:00
Zoltan Somogyi
457dba0c6c Fix the failure of invalid/multiply_star in debug grades.
tests/invalid/multiply_star.err_exp3:
    Add a file for the expected error message in debug grades.

tests/invalid/multiply_star.m:
    Add a description of the reason for the difference in expected
    error messages in debug grades.

tests/invalid/Mercury.options:
    Specify verbose errors, which affects the .err_exp2 file.

tests/invalid/multiply_star.err_exp:
tests/invalid/multiply_star.err_exp2:
    Update the line numbers in the error messages.
2023-10-05 00:32:47 +11:00
Zoltan Somogyi
f508f24b79 Extend "did you mean" suggestions beyond preds.
compiler/typecheck_error_undef.m:
    Suggest possible "did you mean" names when reporting references
    to undefined functions, not just undefined predicates.

    Generalize the infrastructure used for predicate name suggestions
    to work for function name suggestions as well.

    Delete the code moved to error_spec.m.

compiler/module_qual.qual_errors.m:
    When reporting an undefined entity name that has way to become defined
    without changing its name, suggest possible names.

compiler/error_spec.m:
    Move the code for constructing "did you mean" suggestions here from
    typecheck_error_undef.m, to make it accessible from
    module_qual.qual_errors.m as well.

compiler/hlds_cons.m:
    Add a way to retrieve the names of all the function symbols,
    for use by the new code in typecheck_error_undef.m.

compiler/module_qual.id_set.m:
    Add a way to retrieve the names of all the ids in an id_set,
    for use by the new code in module_qual.qual_errors.m.

    Expand a old comment.

tests/invalid/bug113.err_exp:
tests/invalid/multiply_star.err_exp:
tests/invalid/multiply_star.m:
tests/invalid_nodepend/kind.err_exp:
tests/invalid_nodepend/reserved_type_name.err_exp:
    Expect the "did you mean" messages we now generate.
2023-09-26 18:51:18 +10:00
Zoltan Somogyi
427f67ffda Allow module qualification using mixed operators ...
... such as a__b.c__d.

compiler/parse_sym_name.m:
    Allow the operands of terms module qualified with "." to contain
    terms module qualified with "__".

    Stop allowing ":" as a module qualifier.

compiler/parse_dcg_goal.m:
compiler/parse_goal.m:
    Make the code parsing DCG and non-DCG goals as similar as possible.

tests/invalid/qual_basic_test2.err_exp:
    Expect "io.io__write_string" to be parsed as "io.io.write_string".

tests/invalid_make_int/test_nested_helper_1.test_nested_helper_3.m:
tests/invalid_make_int/test_nested_helper_1.test_nested_helper_4.m:
tests/invalid_make_int/test_nested_helper_2.test_nested_helper_6.m:
tests/invalid_submodules/nested_impl_in_int.m:
    Stop using ":" as module qualifier.
2023-09-26 01:59:33 +10:00
Zoltan Somogyi
c69b7e4b9a Add "did you mean ..." to undef pred reports.
compiler/typecheck_error_undef.m:
    If we are reporting an error for a reference to an undefined predicate,
    check whether any predicates exist whose names are "close enough"
    to the name of the referenced predicate, and if yes, add to the
    error message a line containing "(Did you mean x, y or z?)".

    (Doing the same for references to undefined functions is future work.
    The two are separate because things that look like function references
    can also refer to e.g. data constructors.)

library/edit_distance.m:
    Add this new module to implement the "close enough" check.
    This new module is similar to the existing edit_seq.m module,
    but it is designed to serve different requirements, and it seems to me
    to be far from trivial to write code to meet both sets of requirements
    at once.

library/library.m:
library/MODULES_DOC:
    Include the new module in the standard library.

NEWS.md:
    Announce the new library module.

tests/hard_coded/edit_distance_test_closest.{m,exp}:
tests/hard_coded/edit_distance_test_cost.{m,exp}:
    Two new test cases, each of which tests one of the two predicates
    exported by the new library module.

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

tests/invalid/qual_basic_test2.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/undef_symbol.err_exp:
tests/invalid_submodules/undef_mod_qual.err_exp:
    Expect the new "did you mean" additions to error messages.
2023-09-26 00:56:19 +10:00
Zoltan Somogyi
76ddf450b4 Delete stray .err_exp2 file.
Its test was moved to a different test directory, and the file
has suffered bit rot.
2023-09-04 15:27:48 +10:00
Zoltan Somogyi
0c76e78ed6 Factor out common code in error_msg_inst.m.
compiler/error_msg_inst.m:
    Most parts of this module consisted of pairs of predicates following
    the naming scheme X_to_pieces and X_to_inline_pieces. Replace each such
    pair of predicates with one predicate that takes a flag that says
    which version we want, since this allows us to avoid doing double
    maintenance. (The overall logic of the two versions was always the same;
    the differences affected only the construction of the piece sequence.)

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

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

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

    Fix three minor bugs in the process.

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

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

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

tests/invalid/bug415.err_exp:
    Update this expected output to account for the first bug fix.
2023-08-30 06:52:49 +10:00
Zoltan Somogyi
f3b31079db Run tests/invalid/test_feature_set with --no-intermod-opt.
Intermodule optimization is irrelevant to its purpose,
and without it, it now gets errors for .opt file grade mismatch.
2023-07-29 02:45:21 +02:00
Zoltan Somogyi
75320f5d14 Update the error message for missing ho insts.
compiler/mode_errors.m:
    Improve the error message you get when you pass a higher order value
    without specifying its higher order inst, along the lines in the
    discussion on m-rev over the last week.

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

tests/invalid/no_ho_inst.err_exp:
    Update the expected error message.
2023-07-25 00:16:24 +02:00
Zoltan Somogyi
92941c4239 Delete mer_inst's abstract_inst functor.
We have never supported abstract insts, and we are not likely to start
using them any time soon, but we have had them in the representation of insts
since the beginning. Since they were never actually generated, the code
that operated on them was never really tested, which is good, because
in many places, that code simply threw an exception. The code that didn't
throw an exception when it found an abstract inst had to work correctly
for the abstract_insts that we actually generated, which were abstract
only in the sense that they were references to a would-be user-defined inst
name that wasn't actually defined.

There were two sources of such "abstract" insts.

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

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

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

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

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

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

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

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

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

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

tests/invalid_nodepend/kind.{m,err_exp}:
    Add some invalid code to this test, and update the expected output
    accordingly.
2023-07-21 21:03:40 +02:00
Zoltan Somogyi
fde993b523 Improve diagnostics for missing higher order insts.
compiler/mode_errors.m:
    Generate a significantly more detailed error message, including an example,
    when a higher order value is used in a call without having higher order
    inst information.

compiler/write_error_spec.m:
    Fix a bug I encountered with a draft of the diff to mode_errors.m:
    don't let the indent of a paragraph become negative.

compiler/indent.m:
    Fix an effective infinite loop when the indent function is asked
    to convert a negative indent to a string.

tests/invalid/no_ho_inst.{m,err_exp}:
    A test case derived from the code on mercury-users.

tests/invalid/Mmakefile:
    Enable the new test case.
2023-07-19 00:06:41 +02:00
Zoltan Somogyi
1e05c08426 Fix off-by-one mistake in error message.
compiler/hlds_out_util.m:
    As above. The first element of a list is element #1, not #0.
    (Humans don't use C's array index conventions.)

tests/invalid/error_in_list.err_exp:
tests/invalid/functor_ho_inst_bad.err_exp:
tests/invalid/getopt_old.err_exp:
    Expect the updated element numbers.
2023-07-18 21:53:00 +02:00
Julien Fischer
8a130986d5 Fix a test failure on Windows.
tests/invalid/foreign_include_file_missing.{m,err_exp2}:
    Handle the case where "\" is used as the directory separator.
2023-07-08 16:58:44 +10:00
Zoltan Somogyi
b6ec42a132 Make some arities into pred_form_arities.
compiler/hlds_pred.m:
    Replace the arity field in pred_infos with a pred_form_arity field.

    Move the pred_info's pred_or_func field to its usual position
    in predicate/function descriptions: at the front (pred/func name/arity).

compiler/hlds_pred.m:
    Change two utility operations to return pred_form_arities instead of
    just arities, since they get them from pred_infos.

compiler/inst_mode_type_prop.m:
compiler/llds.m:
compiler/rtti.m:
    Change some fields whose types used to be arity (or int) to be
    pred_form_arity.

    In llds.m, include a pred_or_func field in c_procedures,
    for use in procedure-start comments.

mdbcomp/prim_data.m:
mdbcomp/program_representation.m:
    Add notes about two possible future improvements along similar lines.

compiler/prog_data.m:
    Add a utility function to calculate the number of extra arguments
    added to predicates/functions by compiler passes such as polymorphism.

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

    Fix a bug in an error message about ":- external" pragmas:
    the message used the pred_form arity instead of the user arity.
    (See the diff to external2.err_exp below.)

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

    Include pred/func prefixes before name/arity pairs in the output
    where relavnt. (The user guide does not need to be updated, because
    its wording permits both the old and the new behavior.)

    Fix two separate bugs that referred to functions in user-facing output
    with the predicate form of their arity.

compiler/table_gen.m:
compiler/unused_args.m:
    Conform to the changes above.

    Fix a bug in each module that referred to functions in user-facing output
    with the predicate form of their arity.

compiler/recompilation.usage.m:
compiler/xml_documentation.m:
    Conform to the changes above.

    Mark a probable bug in each module with an XXX.

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

    Improve the wording of an error message a bit.
    (See the diff to gh72_errors.err_exp below.)

compiler/accumulator.m:
compiler/bytecode_gen.m:
compiler/complexity.m:
compiler/default_func_mode.m:
compiler/det_report.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/higher_order.m:
compiler/hlds_defns.m:
compiler/hlds_error_util.m:
compiler/hlds_module.m:
compiler/intermod.m:
compiler/intermod_order_pred_info.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/llds_out_file.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/mode_errors.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/old_type_constraints.m:
compiler/optimize.m:
compiler/polymorphism.m:
compiler/polymorphism_goal.m:
compiler/post_typecheck.m:
compiler/pre_typecheck.m:
compiler/pred_table.m:
compiler/proc_gen.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.usage.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/simplify_goal_call.m:
compiler/ssdebug.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_initial.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/transform_llds.m:
compiler/tupling.m:
compiler/type_class_info.m:
compiler/typecheck.m:
compiler/typecheck_error_undef.m:
compiler/types_into_modes.m:
compiler/xml_documentation.m:
    Conform to the changes above.

compiler/recompilation.m:
    Add a note.

compiler/parse_tree_out_sym_name.m:
    Improve variable names.

tests/invalid/external2.err_exp:
    Expect the fixed arity in an error message.

tests/invalid/gh72_errors.err_exp:
    Expect the expanded text of an error message.
2023-07-03 01:57:10 +02:00
Zoltan Somogyi
7292ecb571 Don't generate duplicate instance declarations.
We used to include in the .int0 file the abstract form of all the instance
declarations in both the interface and the implementation sections.
When an instance is declared (in an already-abstract form) in the interface
section and defined in the implementation section, this resulted in the
abstract interface declaration being included in the .int0 file twice,
once in the interface section, and once in the implementation section.

compiler/comp_unit_interface.m:
    Fix this by including an abstract instance declaration in the
    implementation section of a .int0 file only if it does not also appear
    in the interface section.

    Conform to the changes in prog_item.m below.

compiler/parse_tree_out.m:
    To help implement the above test, add a function to return the string
    form of an abstract instance declaration.

    It is easy to make this change for *abstract* instance declarations,
    but not *concrete* instance definitions, because (in order to handle
    instances that define methods by clauses, instead of by pred/func names)
    the latter would require generalizing *all* the code for writing out
    clauses, with all the overhead associated with replacing first order calls
    with method calls.

    Another change (unrelated to the problem above) is to write out
    typeclass and instance definitions for typeclasses with no methods
    in a nicer form. Instead of looking like this:

        :- instance classname(argtypes) where [

        ].

    they now look like this:

        :- instance classname(argtypes) where [].

    Another formatting change unrelated to the above: don't put parentheses
    around typeclass names in instance declarations/definitions if the name
    is all alphanumeric and not an operator.

    Conform to the changes in prog_item.m below.

compiler/prog_data.m:
compiler/prog_item.m:
    To be able to use the new code to convert abstract instances to strings
    in comp_unit_interface, and to write out abstract instance declarations
    inside .int0 (and other .intN) files, it helps to know which instance
    items can only be abstract in these files. As it turns out, none can be
    concrete. So define a subtype of item_instance_info that can contain
    only abstract instance declarations, and use it to replace
    item_instance_info in parse_tree_intN for all N.

compiler/parse_tree_out_info.m:
    Add a utility function for new code in comp_unit_interface.m
    invoking new code in parse_tree_out.m.

compiler/convert_parse_tree.m:
    Conform to the changes in prog_item.m by insisting that instances
    read in from .intN files are all abstract.

    Fix some typos in some error messages (which people can see only if
    something has screwed up a .intN file).

compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/recompilation.version.m:
    Conform to the changes above.

compiler/intermod.m:
    Simplify some code.

tests/invalid/Mercury.options:
    Fix the failure of the instances_pc.instances_pc_helper_1 test case
    when intermodule optimization is enabled for a bootcheck by disabling
    intermodule optimization for this test. The old code to do so didn't
    work due to typos.

tests/invalid/instances_pc.instances_pc_helper_1.err_exp:
    Expect a reference to only ONE old instance declaration in
    instances_pc.int0. Expect it at a new line number, due to the first
    formatting change above.

tests/misc_tests/pretty_print_test.exp:
    Expect no unnecessary parentheses around a class name in an
    instance definition, due to the second formatting change.
2023-06-30 09:34:01 +02:00
Zoltan Somogyi
d03f200889 Add missing import. 2023-06-23 12:14:36 +02:00
Zoltan Somogyi
81b4c3272e Stop using digraph.tsort and digraph.atsort ...
... and start using their more descriptively-named synonyms.

In some cases, instead of getting and then reversing a list of sccs,
ask for the sccs in the needed order in the first place.

compiler/dependency_graph.m:
compiler/generate_dep_d_files.m:
compiler/make.program_target.m:
compiler/mlds_to_java_global.m:
compiler/mode_ordering.m:
compiler/rtti_to_mlds.m:
compiler/stratify.m:
    As above.

compiler/prog_event.m:
    As above.

    Address an old and now-inaccurate XXX. When a synthesized attribute
    depends on its value, either directly or through the values of other
    synthesized attributes, include the names of the attributes involved
    in the error message, instead of just saying that there is circular
    dependency *somewhere* among the attributes.

tests/invalid/synth_attr_error.err_exp:
    Expect the updated, more specific error messages.

tests/invalid/Mmakefile:
    Enable the synth_attr_error test case, which wasn't enabled before
    (though it does have an entry in Mercury.options.)

tests/invalid/invalid_event_spec:
tests/invalid/syntax_error_event_spec:
tests/invalid/synth_attr_error_spec:
    Replace tabs with spaces.
2023-06-22 00:25:26 +02:00
Zoltan Somogyi
f345d20e33 Rename X's aux modules as X_helper_N in invalid.
tests/invalid/*.m:
    Rename modules as mentioned above.

    In two cases where the main module name is a Mercury keyword (to the
    extent that Mercury has keywords), add a "test_" prefix to the
    module name.

    Reorganize the ho_default_func_2 test case. The original code
    of this test had three modules, a parent and two children,
    with the module being tested being one of the *child* modules
    (ho_default_func_2.sub). This does not work; the .log file
    from the successful execution of this test case showed that
    there was no actual compilation involved; the test stopped
    after invoking "mmc --generate-dependencies" on that child module.
    The new version of this test makes that child module the main module,
    and moves the relevant parts of the other two original modules
    into a single new child module.

    Rename ii_parent to instance_pc (pc being short for parent-child).
    This test case still has the child module listed as the target
    in Mmakefile, so it still does not progress past generating its
    dependencies.

    Rename the imported_mode test case as bad_exported_mode,
    because this is what it was testing.

    exported_mode.m was used both as the main module of a test,
    and as a helper module in the imported_mode test (now renamed
    to bad_exported_mode). Make a copy of it as a helper module
    for bad_exported_mode.

    Update all references to the moved modules.

    General updates to programming style, such as

    - replacing DCG notation with state var notation
    - adding lines around vim modelines
    - fixing indentation
    - fixing grammar errors in comments

tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
    Update all references to the moved modules and/or moved lines.
2023-06-16 20:18:36 +02:00
Zoltan Somogyi
16b964be81 Improve warnings about unbound type variables.
compiler/post_typecheck.m:
    Do not generate warnings abouts unbound type variables in code
    that is not in the current module.

    If all the variables we are generating a report for have types
    that are *just* type variables, then report just the names
    of the variables; the names of the associated type variables
    are just clutter in that case (especially when those type variables
    are compiler-generated).

    If some of the variables we are generating a report for have types
    that are not just type variables (which can happen when the type is
    e.g. list(T)), then report the type of each variable as before,
    but try to line things up so that all the types start in the same column.
    This should make the message easier to read.

    In both cases, sort the list of variables on their names.

    Update the wording of the warning to accommodate the changes above,
    and to expand contractions.

tests/invalid/bad_sv_unify_msg.err_exp:
tests/invalid/bug257.err_exp:
tests/invalid/coerce_void.err_exp:
tests/invalid/freefree.err_exp:
tests/invalid/typeclass_test_8.err_exp:
tests/invalid/unsatisfiable_constraint.err_exp:
tests/warnings/singleton_test.exp:
tests/warnings/singleton_test.exp2:
tests/warnings/singleton_test.exp3:
    Expect the updated warning text.
2023-06-08 18:58:06 +02:00
Zoltan Somogyi
00e1a62ab4 Fix a misleading error message.
compiler/det_report.m:
    In some cases described in the new test case, the error message
    we print for a missing switch inside an arm of a larger switch
    is misleading unless we print *which* arm of the larger switch
    we are complaining about, so print that information.

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

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

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

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

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

    Add an XXX.

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

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

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

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

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

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

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

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

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

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

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

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

    Improve the wording of some error messages.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Fix an old ZZZ.

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

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

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

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

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

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

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

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

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

    Rename a function symbol to avoid an ambiguity.

    Fix comment rot.

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

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

tests/invalid/bad_instance2.err_exp:
tests/invalid/constraint_proof_bug_lib.err_exp:
tests/invalid/invalid_instance_declarations.err_exp:
    Expect updated error messages.
2022-11-24 10:05:06 +11:00
Zoltan Somogyi
18817d62d0 Record more than a pred_proc_id for each method.
Class and instance definitions both contain lists of methods,
predicates and/or functions, that each have one or more procedures.
Until now, we represented the methods in class and instance definitions
as lists of nothing more than pred_proc_ids. This fact complicated
several operations,

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

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

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

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

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

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

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

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

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

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

    Add some utility functions.

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

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

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

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

    Give some predicates better names.

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

    Give some predicates better names.

    Some error messages about problems in instance definitions started with

        In instance declaration for class/arity:

    while others started with

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

    Replace both with

        In instance declaration for class(foo, bar):

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

    Factor out some common code.

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

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

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

compiler/polymorphism_type_info.m:
    Fix some comment rot.

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

tests/invalid/bug476.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_mode.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_mode_3.err_exp:
tests/invalid/typeclass_mode_4.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_9.err_exp:
    Expect the updated wording of some error messages.
2022-11-22 02:27:33 +11:00
Zoltan Somogyi
5eca1f9666 Improve presentation of actual/expected types.
Before this diff, typecheck_error.m could generate error messages like this:

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

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

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

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

The message we generate for the same code is now

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

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

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

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

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

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

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

    Use more consistent variable names.

    Fix some misleading predicate names.

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

    Fix bit-rot in some comments.

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

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

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

    Add some XXXs.

compiler/post_typecheck.m:
    Fix a comment.

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

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

    f(a, b)

or as

    f(
        a,
        b
    )

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

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

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

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

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

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

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

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

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

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

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

    Replace a quadratic algorithm with a linear one.

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

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

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

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

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

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

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

    Add a way to print out purity descriptions.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

tests/invalid/bug197.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
    Expect pinpointed type differences in these error messages.

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

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

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

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

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

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

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

compiler/mode_info.m:
    Clarify some comments.

compiler/modes.m:
    Fix indentation.

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

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

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

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

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

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

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

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

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

    Expect updated line numbers.

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

    Expect both the extra warning and updated line numbers.

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

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

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

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

    Fix a bug in the comment on marker_has_format_call.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

tests/invalid/string_format_bad.err_exp:
tests/invalid/string_format_unknown.err_exp:
tests/warnings/disabled_warning.exp:
    Expect the predicate vs function distinction to the printed in
    error messages about bad calls to formatting predicates and functions.
2022-09-24 08:42:36 +10:00