Commit Graph

582 Commits

Author SHA1 Message Date
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
e53bc5fbfa Make some predicates naturally tail recursive.
Make some predicate names more expressive.
2023-02-01 18:56:02 +11:00
Zoltan Somogyi
6f82724091 Pass streams explicitly at the top levels.
compiler/mercury_compile_main.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_make_hlds.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
    Pass progress and error streams explicitly in these top modules
    of the compiler. Use "XXX STREAM" to mark places where we could switch
    from using stderr for both the progress and error streams to using
    module-specific files as the progress and/or error streams.

compiler/passes_aux.m:
    Add a "maybe_" prefix to the names of the predicates that print progress
    messages at the appropriate verbosity levels, as their printing of those
    messages is conditional.

    Provide versions of those predicates that take explicitly specified
    streams to write to, and mark the versions that write to the current
    output stream as obsolete.

    The predicate that wrote progress messages for procedures
    used to have two versions, one taking a pred_proc_id, and one taking
    a pred_id/proc_id pair. Delete the latter, because the arity difference
    that differentiated the two versions is now needed for the difference
    between supplying and not supplying an explicit stream.

compiler/file_util.m:
compiler/hlds_error_util.m:
compiler/write_error_spec.m:
    Delete several predicates that wrote to the current output stream,
    since all their callers now use the versions that specify an explicit
    output stream.

compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/cse_detection.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/deps_map.m:
compiler/direct_arg_in_out.m:
compiler/grab_modules.m:
compiler/handle_options.m:
compiler/hhf.m:
compiler/inlining.m:
compiler/make.module_dep_file.m:
compiler/ml_proc_gen.m:
compiler/ml_top_gen.m:
compiler/mode_constraints.m:
compiler/modes.m:
compiler/polymorphism.m:
compiler/purity.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/saved_vars.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/stack_opt.m:
compiler/switch_detection.m:
compiler/typecheck.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/write_module_interface_files.m:
    Get these modules to take an explicitly specified stream to which
    to write progress messages when they are invoked from mercury_compile_*.m.

    For predicates in these modules that can be invoked both directly
    by mercury_compile_*.m *and* by other modules, the latter effectively
    as a subcontractor, make them take a maybe(stream), with the intention
    being that all the other modules that use the predicate as a subcontractor
    would pass a "no". This avoids the need to pass progress streams
    down to the internals of other passes, and also avoids overwhelming
    the user invoking the compiler with unnecessary details.

    As above, and also delete a progress message that shouldn't be needed
    anymore.

    Move a test of option value compatibility from
    mercury_compile_middle_passes.m to handle_options.m, where it belongs.

compiler/float_regs.m:
    Write a debug message to the debug stream.

compiler/pd_info.m:
    Include the progress stream in the pd_info structure, because this is
    the simplest way to ensure that all parts of the partial deduction pass
    have access to it.

compiler/make.build.m:
compiler/make.program_target.m:
compiler/make.track_flags.m:
    Make the minimal changes needed to conform to the changes above.
    The rest can be done when the make package is converted to consistently
    use explicit streams.

compiler/bytecode_gen.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
    Make the minimal changes needed to conform to the changes above.
    The rest can be done when these modules start being maintained again.

compiler/Mercury.options:
    Stop specifying --no-warn-implicit-stream-calls for mercury_compile_*.m,
    since this diff makes that unnecessary.

    Start specifying --no-warn-implicit-stream-calls for some modules that
    are not currently being actively maintained, because the addition of
    progress-reporting predicates that take explicitly specified streams
    would otherwise cause the generation of such warnings for them.
2022-11-01 11:33:41 +11:00
Zoltan Somogyi
9a919b9e41 Give some predicates more meaningful names. 2022-10-21 09:26:15 +11:00
Zoltan Somogyi
6529832f73 Index into arg lists, instead of chopping them up.
compiler/typecheck.m:
    When checking the types of variables representing an argument list
    against arg-type-vectors in args_type_assign_sets, simply index
    into each arg-type-vector with each variable's argument number,
    instead of (a) looking at the first element of each arg-type-vector,
    and then (b) chopping that first element off the arg-type-vector,
    to set it up for checking the next variable in the argument list.

    Move the conversion of the final args_type_assign_set to a plain
    type_assign_set out of the base case of this loop over the argument list,
    and into the callers, since it belongs there.

    Give the predicates involved names that follow a meaningful pattern.

compiler/typecheck_errors.m:
compiler/typecheck_error_type_assign.m:
    Expect an argument number and intact lists of argument types,
    instead of chopped-off lists of argument types that implicitly
    should be accessed at the front.

compiler/type_assign.m:
    Delete a no-longer-needed function.
2022-10-17 21:12:09 +11:00
Zoltan Somogyi
99647fbafe Carve four new modules out of typecheck_errors.m.
The resulting modules have much better cohesion.

compiler/typecheck_error_overload.m:
    New module containing predicates that report type overloading errors.

compiler/typecheck_error_undef.m:
    New module containing predicates that report references to undefined
    predicates, functions, data constructors, and events.

compiler/typecheck_error_type_assign.m:
    New module containing predicates that print and process type_assigns
    and args_type_assigns.

compiler/typecheck_error_util.m:
    New module containing general utility predicates for dealing with
    type errors.

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

compiler/typecheck_errors.m:
    Delete the code that this diff moves to the new modules.

    Reorder the remaining predicates to put related predicates
    next to each other. Give some predicates new names to reflect
    these groupings.

    Mark as such one predicate that has been unused for a while.

    Use different names for variables used for different purposes.

compiler/typecheck.m:
    Conform to the changes in predicate names.

    Move some utility predicates to the end of the module.
2022-10-17 18:29:42 +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
307b1dc148 Split up error_util.m into five modules.
compiler/error_spec.m:
    This new module contains the part of the old error_util.m that defines
    the error_spec type, and some functions that can help construct pieces
    of error_specs. Most modules of the compiler that deal with errors
    will need to import only this part of the old error_util.m.

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

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

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

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

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

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

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

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

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

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

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

compiler/*.m:
    Conform to the changes above, mostly by updating import_module
    declarations, and renaming format_component to format_piece.
2022-10-12 20:50:16 +11:00
Zoltan Somogyi
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
07f877bc3f Carve term_context.m out of term.m.
library/term.m:
library/term_context.m:
    As above.

    Rename the term.context type as term_context.term_context, with
    term.context now being defined as an equivalence type.

    Replace the context_init function and predicate and the dummy_context_init
    function with just one function: dummy_context. This name includes
    the important part (the fact that it return a *dummy* context) and deletes
    the nonimportant part (dummy contexts are just about never updated,
    so the function does not really "initialize" them).

    Reduce function/predicate pairs that do the same thing to just a function.

library/MODULES_DOC:
library/library.m:
    Add the new module to the list of standard library modules.

NEWS:
    Mention the new module, and the obsoleting of the moved predicates
    and functions in term.m.

compiler/*.m:
library/*.m:
    Conform to the changes above.
2022-08-23 12:56:37 +10:00
Zoltan Somogyi
752bb66f5b Carve four modules out of term.m.
Most modules that imported the old term.m need only a small subset
of its functionality. After this diff, most modules that used to import
term.m will need to import just one more module, and will import many
fewer predicates and functions in total.

library/term_int.m:
    A new module carved out of term.m containing the predicates
    that recognize terms containing integers, and the functions
    that construct such terms.

    While this job has *some* similarity to the job of the existing
    term_conversion.m module, most modules in the compiler use only one
    of those two modules, so merging them would not be a good idea.

library/term_subst.m:
    A new module carved out of term.m containing code to do
    substitutions and renames of various kinds.

    Rename the occurs predicate as var_occurs_in_subst_term,
    and occurs_list as var_occurs_in_subst_terms, since the latter
    are much more descriptive. Change the argument order to match
    the new names (var, subst, term/terms), as the old one did not
    even have the term/terms and the substitution next to each other,
    even though neither makes sense without the other.

library/term_unify.m:
    A new module carved out of term.m containing code to do unifications.

    Give all the predicates more meaningful names:

    unify_term ->                   unify_terms
    unify_term_list ->              unify_term_lists
    unify_term_dont_bind ->         unify_terms_dont_bind
    unify_term_list_dont_bind ->    unify_term_lists_dont_bind
    list_subsumes ->                first_term_list_subsumes_second

library/term_vars.m:
    A new module carved out of term.m containing code that find variables
    in terms.

    Give all the predicates more meaningful names:

    vars ->                         vars_in_term
    vars_2 ->                       vars_in_term_acc
    vars_list ->                    vars_in_terms
    contains_var ->                 term_contains_var
    contains_var_list ->            terms_contain_var

    Don't move the function version of vars_2 to term_vars.m, effectively
    deleting it, since operations that update an accumulator are awkward
    for functions.

library/term.m:
    Keep the moved predicates and functions in term.m, but

    - change their implementation to simply call the moved copy, and
    - obsolete the original in favor of the moved copy.

    Eventually, after either the next release or the release after the next,
    we should delete the obsoleted predicates and functions.

library/MODULES_DOC:
library/library.m:
    Add the new modules as documented parts of the standard library.

browser/interactive_query.m:
compiler/analysis.file.m:
compiler/det_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_passes.m:
compiler/parse_class.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_mutable.m:
compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_sym_name.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_defn.m:
compiler/parse_util.m:
compiler/prog_ctgc.m:
compiler/prog_util.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/typecheck.m:
library/io.m:
library/term_conversion.m:
library/varset.m:
    Conform to the changes above.
2022-08-21 01:01:21 +10:00
Zoltan Somogyi
cd8c59cdf5 Improve some comments. 2022-08-18 10:49:53 +10:00
Zoltan Somogyi
bfe869151d Make HLDS dumps of pred_origins comprehensive.
As an example, for one of the most-transformed predicates, the hlds dump
now gives its origin as

    % Origin base: user defined function list.map/2
    % Transform 1 on pred 657, proc 0:
    %  higher order specialization #46
    % Transform 2 on pred 4521, proc 0:
    %  loop invariant hoisting on line 889, #2
    % Transform 3 on pred 4746, proc 0:
    %  unused arg elimination for args 1, 2, 3, 4, 5, 6, 7, 8, 9, 13
    % Transform 4 on pred 5018, proc 0:
    %  last-call-modulo-construct on arg 1, #1

compiler/pred_name.m:
    Rewrite the code that constructs the pred_origin part of HLDS dumps.
    The old code printed nothing for certain kind of original (non-transformed)
    pred_origins, never gave any specific information about any program
    transformation that a predicate has been through, and it never said
    whether a predicate has been through more than one transformation.
    The new code fixes all those issues.

    To make the above possible, for instance method pred_origins, record
    not just the name of the method, but its pred_or_func and user arity
    as well. To avoid unnecessary inconsistency, change the id we record
    for class methods to also contain the user arity (it used to contain
    the pred_form arity).

    To make the description of the ssdebug transformation self-contained,
    record whether the transformed entity is a predicate or a function.

    Fix an old bug. When we construct a new version of a pred_info that is
    optimized in some way, it is possible for all the calls that called
    the original version to now call the transformed version, leaving
    the original version dead, and thus subject to dead predicate/procedure
    elimination. The old code for dumping out pred_origins looked up
    the original version to print into about it, but dead proc elimination
    could make this lookup fail, resulting in a compiler crash. Our new code
    gets the same info from the pred_origin of the original version
    that we keep in origin_{proc,pred}_transform origins, without a lookup.

    Convert the predicate that dumped out the pred_origin to a stream
    to be a function that returns the string to be written out instead.
    This fits in better with the other functions for converting pred_origins
    to strings for other purposes.

compiler/prog_item.m:
        We construct class methods' pred_origins from the compiler_origin
        in the class method's item, so change the method id in this
        to contain user arity as well.

compiler/mercury_to_mercury.m:
    Mercury_output_constraint took a var_name_print parameter, but its
    function version, mercury_constraint_to_string, did not. Add that
    parameter to the function to fix this inconsistency.

compiler/add_class.m:
compiler/add_pred.m:
compiler/check_typeclass.m:
compiler/hlds_out_pred.m:
compiler/mode_errors.m:
compiler/post_typecheck.m:
compiler/ssdebug.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
    Conform to the changes above.
2022-07-24 05:41:34 +10:00
Zoltan Somogyi
4c9d04434a Classify pred_names into four categories.
compiler/pred_name.m:
    Group pred_origins into four categories, giving each category its own
    function symbol. The categories are

    - predicates that contain, or may contain, code directly written
      by the user;
    - predicates created wholly by the compiler,
    - predicates created by the compiler by transforming a predicate, and
    - predicates created by the compiler by transforming a procedure.

    We distinguish between the first two because we want to report
    errors only in user-written code, since reporting an error that
    the user is powerless to fix is not a good idea.

    We distinguish between the last two just to allow us to store
    the proc_id of the transformed procedure next to its pred_id.

compiler/higher_order.m:
    Replace a boolean with value of a bespoke type.

    Rename some predicates to avoid ambiguity.

compiler/*.m:
    Conform to the changes above.
2022-07-23 09:28:40 +10:00
Zoltan Somogyi
1eb1e239b3 Move the pred_origin type to pred_name.m.
compiler/pred_name.m:
    Add the pred_origin type and its component types, moved here from
    hlds_pred.m and hlds_rtti.m.

    Also, add the functions and predicates that convert pred_origins to
    strings, moved here from hlds_pred.m, hlds_out_util.m and layout_out.m.

compiler/hlds_pred.m:
    Delete the pred_origin type moved to pred_name.m.

compiler/hlds_rtti.m:
    Delete the instance_method_constraints type moved to pred_name.m.
    It has nothing to do with RTTI, and was not used in hlds_rtti.m itself.
    The only data structure it is part of is pred_origin, though
    it is used as temporary data by a few other modules.

compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/layout_out.m:
    Delete the functions and predicates moved to pred_name.m.

compiler/*.m:
    Conform to the change above, mostly by adding imports of pred_name.m,
    in a few cases replacing hlds_pred.m or hlds_rtti.m.
2022-07-21 05:02:44 +10:00
Zoltan Somogyi
8122e83d2a Record typechecking results in var_tables.
compiler/hlds_clauses.m:
    The clauses_info type used to have two fields whose type is "vartypes".
    One contained type information we knew before typechecking, e.g. from
    explicit "Var : type" annotations, while the other contained the
    *results* of typechecking. Keep the former, but replace the latter
    with a var_table.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

tests/invalid/try_detism.err_exp:
    Expect a different variable number for an unnamed variable.
2022-05-29 15:22:16 +10:00
Zoltan Somogyi
6f476f8f1e Convert det analysis and simplify to var_tables.
compiler/common.m:
compiler/const_prop.m:
compiler/format_call.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_switch.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
    Convert these modules, which comprise the simplification pass,
    to use var_tables.

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

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

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

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

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

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

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

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

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

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

    Fix some variable names.

tests/invalid/bug257.err_exp:
    Expect the warning that reports an unbound type.
2022-05-01 16:37:18 +10:00
Zoltan Somogyi
ea4f95a7ed Use var_tables in lco.m, and when dumping goals.
Since this is the first converted module that dumps out goals when
debugging trace flags are enabled, this required generalizing the code
that does that, to take either varsets or var_tables as a means of
specifying the names of variables. We do this via a new type,
var_name_source, which contains either a varset or a var_table.

Almost all of this diff is there to implement this generalization.
A large part of it affects code in the parse_tree package that we use
to write out the parts of HLDS goals that are defined by types defined
in that package. Since we want to avoid making any part of the parse_tree
package dependent on the hlds package, this required defining the
var_name_source type in the parse_tree package, which in turn requires
var_table.m to be in that same package.

compiler/lco.m:
    Convert this module to use var_tables instead of varsets and vartypes.

compiler/var_table.m:
    Move this module from the hlds package to the parse_tree package.

    To make this, possible, move the parts that required access to the HLDS
    to hlds_pred.m, from where it was usually invoked.

    Export some utility predicates to allow the moved code to work
    in hlds_pred.m without access to the actual definition of the
    var_table type.

    Define the var_name_source type.

    Add some utility functions for use by code writing out variable names.

compiler/hlds_pred.m:
    Add the code moved from var_table.m.

compiler/vartypes.m:
    Move this module from the hlds package to the parse_tree package,
    for symmetry with var_table.m. It did not depend on being in hlds
    in any way.

compiler/hlds.m:
compiler/parse_tree.m:
    Move vartypes.m and var_table.m from the hlds package
    to the parse_tree package.

compiler/hlds_out_goal.m:
    Change all the predicates in this module to take a var_name_source
    instead of a prog_varset.

    Fix some comments.

compiler/hlds_out_util.m:
    Change some of the predicates in this module (those called from
    hlds_out_goal.m) to take a var_name_source instead of a prog_varset.

compiler/parse_tree_out_term.m:
    Provide variants of some existing predicates and functions that take
    var_name_sources instead of varsets. The code of the copies
    duplicates the logic of the originals, though I hope that this
    duplication can be done away with at the end of the transition.
    (The best solution would be to use a typeclass with methods
    that convert vars to their names, but we would want to ensure
    that the compiler can specialize all the affected predicates
    and functions to the two instances of this typeclass, which is
    something that we cannot do yet. In the meantime, the lack of
    any generalization in the old versions preserves their performance.)

tools/sort_imports:
tools/filter_sort_imports:
    A new tool that automatically sorts any occurrences of consecutive
    ":- import_module" declarations in the named files. The sorting is done
    in filter_sort_imports; sort_imports loops over the named files.

    After automatically replacing all occurrences of hlds.{vartypes,var_table}
    in import_module declarations with their parse_tree versions, the updated
    import_module declarations were usually out of order with respect to
    their neighbours. I used this script to fix that, and some earlier
    out-of-order imports.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_heap_ops.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_trail_ops.m:
compiler/analysis.m:
compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/check_promise.m:
compiler/closure_analysis.m:
compiler/closure_gen.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/const_prop.m:
compiler/constraint.m:
compiler/continuation_info.m:
compiler/convert_parse_tree.m:
compiler/coverage_profiling.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/direct_arg_in_out.m:
compiler/disj_gen.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/file_names.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/generate_dep_d_files.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/goal_mode.m:
compiler/goal_path.m:
compiler/goal_store.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_clauses.m:
compiler/hlds_code_util.m:
compiler/hlds_error_util.m:
compiler/hlds_goal.m:
compiler/hlds_llds.m:
compiler/hlds_out_pred.m:
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/inlining.m:
compiler/inst_check.m:
compiler/inst_test.m:
compiler/inst_user.m:
compiler/instance_method_clauses.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/llds.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_util.m:
compiler/lookup_switch.m:
compiler/loop_inv.m:
compiler/make.module_target.m:
compiler/make.util.m:
compiler/make_goal.m:
compiler/make_hlds_separate_items.m:
compiler/make_hlds_types.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/middle_rec.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_global.m:
compiler/mlds_to_cs_class.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_file.m:
compiler/mlds_to_java_stmt.m:
compiler/mlds_to_java_type.m:
compiler/mmc_analysis.m:
compiler/mode_comparison.m:
compiler/mode_constraints.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/mode_ordering.m:
compiler/modecheck_call.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/module_cmds.m:
compiler/old_type_constraints.m:
compiler/opt_debug.m:
compiler/optimize.m:
compiler/options_file.m:
compiler/ordering_mode_constraints.m:
compiler/par_loop_control.m:
compiler/parse_item.m:
compiler/parse_string_format.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_to_term.m:
compiler/parse_util.m:
compiler/pd_debug.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/polymorphism_info.m:
compiler/polymorphism_lambda.m:
compiler/polymorphism_type_class_info.m:
compiler/polymorphism_type_info.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/pred_name.m:
compiler/pred_table.m:
compiler/prog_item.m:
compiler/prog_rep.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/push_goals_together.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_resurrection_renaming.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
compiler/recompute_instmap_deltas.m:
compiler/resolve_unify_functor.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/saved_vars.m:
compiler/set_of_var.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_switch.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/smm_common.m:
compiler/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/term_constr_main_types.m:
compiler/term_constr_util.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/transform_llds.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/typecheck_debug.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/var_locn.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2022-04-18 02:00:38 +10:00
Zoltan Somogyi
02f0128c5a Use var_tables in more of the later passes.
compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/float_regs.m:
compiler/lambda.m:
compiler/mark_tail_calls.m:
    Convert these passes to use var_tables instead of varsets and vartypes.

compiler/hlds_pred.m:
    Provide predicates to get and set "the var_table" of a procedure.
    The proc_info still stores varsets and vartypes, but these new predicates
    do the required conversions between representations. Likewise, provide
    a version of proc_info_create that takes a var_table argument instead
    of a varset and vartypes arguments. The new predicates should reduce
    the need for such conversions to be done elsewhere during the transition.

compiler/var_table.m:
    Provide a predicate to turn a var_table back into
    a <varset, vartypes> pair.

    Provide two transitional types, var_db and var_type_source, that
    provide either
    - the functionality of both a varset and a vartypes, or
    - just the functionality of a vartypes,
    using either those structure(s), or a var_table.

    Make it possible to allocate new variables from a var_table,
    by including in it a counter that takes on the role played by
    the var_supply in varsets.

    Provide a predicate to look up the types of several variables at once.

    Provide a way to construct a var_table from a reverse sorted assoc list.

compiler/vartypes.m:
    Provide a way to construct a var_table from a reverse sorted assoc list,
    to allow code to operate the same way on vartypes as on var_tables.

library/varset.m:
    Provide predicates to make the changes in var_table.m possible.
    They have to be exported, but they are in the second interface section,
    so they are not publicly documented.

compiler/quantification.m:
compiler/recompute_instmap_deltas.m:
compiler/goal_util.m:
    Provide versions of some exported predicates that take var_tables
    instead of varsets and vartypes, for use by the modules above.

    Rationalize the argument order of some predicates.

compiler/instmap.m:
    Generalize some existing predicates to take type information
    from either vartypes or var_tables, using a transitional mechanism
    now provided by var_table.m.

    Rationalize the argument order of some predicates.

compiler/inlining.m:
    Fix an unrelated bug that just happened to be tickled by the
    rest of this diff. When inlining a call, set the flag that calls
    for rerunning determinism analysis on the procedure in which the
    inlining takes place if the call has an argument variable that
    does not occur outside the call. We need to do this because
    ignoring the last output argument(s) of a call can reduce
    the max possible number of solutions of the call to one.

compiler/set_of_var.m:
    Provide a predicate needed by the fix in inlining.m.

compiler/prog_type.m:
    Give some predicates meaningful names, and create versions that
    return the same info in a different form (set instead of list).

compiler/add_pragma_type_spec.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/continuation_info.m:
compiler/deforest.m:
compiler/error_util.m:
compiler/follow_code.m:
compiler/higher_order.m:
compiler/hlds_class.m:
compiler/hlds_rtti.m:
compiler/ml_gen_info.m:
compiler/old_type_constraints.m:
compiler/parse_class.m:
compiler/parse_type_defn.m:
compiler/pd_util.m:
compiler/polymorphism.m:
compiler/polymorphism_type_class_info.m:
compiler/post_typecheck.m:
compiler/push_goals_together.m:
compiler/qual_info.m:
compiler/saved_vars.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_goal_switch.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/table_gen.m:
compiler/trace_gen.m:
compiler/type_assign.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/typeclasses.m:
compiler/unneeded_code.m:
compiler/unused_args.m:
    Conform to the changes above.
2022-04-17 13:44:10 +10:00
Zoltan Somogyi
fa4e540557 Give more meaningful names to two predicates.
compiler/goal_util.m:
    Rename generate_simple_call to generate_plain_call and
    generate_foreign_proc to generate_call_foreign_proc,
    since they generate plain_call and call_foreign_proc HLDS goals
    respectively. (And the latter most definitely does not generate
    foreign_procs themselves.)

    Rationalize the argument list of both predicates by putting
    related arguments together.

compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/code_gen.m:
compiler/complexity.m:
compiler/dep_par_conj.m:
compiler/direct_arg_in_out.m:
compiler/format_call.m:
compiler/granularity.m:
compiler/lco.m:
compiler/modecheck_goal.m:
compiler/polymorphism_type_class_info.m:
compiler/polymorphism_type_info.m:
compiler/pragma_c_gen.m:
compiler/purity.m:
compiler/rbmm.region_transformation.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_unify.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stm_expand.m:
compiler/table_gen.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unify_proc.m:
    Conform to the changes above,
2022-02-23 01:02:45 +11:00
Zoltan Somogyi
e657a091e4 Encode the arity kind in the type in pred lookups.
compiler/pred_table.m:
    Some predicates in this module have traditionally taken an arity argument
    that *included* function result arguments, while others took an arity
    arguments that *excluded* function result arguments. While the difference
    was documented, it was not enforced in the types. Change this by
    switching the two kinds of arities to pred_form_arities and user_arities
    respectively.

    Change the internal data structures to specify in the types
    that they operate on user_arities.

    Change the operation of lookup_builtin_pred_proc_id as part of the
    change to goal_util.m (described below).

compiler/goal_util.m:
    When looking up the pred_info of a builtin, callers used to pass to the
    predicates that did that (generate_simple_call and generate_foreign_proc)
    a list of the arguments of the call without specifying which arguments
    were type_info/typeclass_info arguments added by polymorphism.
    This meant that the length of the argument list was *not* necessarily
    the called predicate or function's pred form arity, but could exceed it
    by the number of arguments added by polymorphism. The only reason this
    worked was because the lookup_builtin_pred_proc_id procedure they used
    to look up the named predicate in the pred table compensated for it

    - by doing a lookup on the original arity plus one, if the lookup on the
      original arity failed, and

    - in all the calls to generate_simple_call and generate_foreign_proc,
      the number of arguments added by polymorphism was either zero or one.

    Nevertheless, the system was fragile. It could have broken either

    - because when looking up the arity that included a type_info argument,
      (e.g. one typeinfo and two original args) the lookup could have found
      a false match (a predicate with the same name with three original args),

    - or because a new call to a new builtin could need to specify two or more
      arguments added by polymorphism.

    Fix this issue by

    - requiring calls to generate_simple_call and generate_foreign_proc
      to pass the arguments added by polymorphism separately, so the number
      of the original arguments specifies the predicate's pred_form_arity, and

    - deleting the code in lookup_builtin_pred_proc_id that tried to
      compensate for the presence of an "unannounced" typeinfo argument.

compiler/analysis.m:
    Change the type of a slot in a structure from arity to pred_form_arity,
    since that seems to have been how that slot was used.

compiler/recompilation.check.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
    Conform to the changes above, but only in a minimal fashion,
    because I don't *know* whether the values of type 'arity' passed around
    in the recompilation modules represent user arities or pred form arities.
    Record my guesses, but also record the fact that they are *only* guesses.
    Mark suspect code with "XXX ARITY BUG".

compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/stm_expand.m:
compiler/table_gen.m:
    Conform to the changes above.

    Rationalize the argument order of the internal module-specific predicates
    they use to generate calls to builtins.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/analysis.file.m:
compiler/check_typeclass.m:
compiler/complexity.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/format_call.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/higher_order.m:
compiler/hlds_module.m:
compiler/intermod.m:
compiler/lco.m:
compiler/make_hlds_passes.m:
compiler/mmc_analysis.m:
compiler/modecheck_goal.m:
compiler/par_loop_control.m:
compiler/polymorphism_type_class_info.m:
compiler/polymorphism_type_info.m:
compiler/pred_table.m:
compiler/purity.m:
compiler/rbmm.region_transformation.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_unify.m:
compiler/size_prof.m:
compiler/special_pred.m:
compiler/ssdebug.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unify_proc.m:
    Conform to the changes above.
2022-02-22 23:59:20 +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
5cada10369 Rename pred_table to pred_id_table.
compiler/pred_table.m:
    As above. This addresses half of an old XXX, which is that the two types
    defined in this module, predicate_table and pred_table (as it was then)
    should have names that (a) say what they do, and (b) are distinct.
    Addressing the other half requires a more descriptive but not-too-long
    name to replace "predicate_table".

    Rename the predicates that operate on the type to follow the name change.

    Add a distinguishing prefix to the names of the fields of the
    predicate_table type.

compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/arg_info.m:
compiler/bytecode_gen.m:
compiler/clause_to_proc.m:
compiler/closure_gen.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/default_func_mode.m:
compiler/det_analysis.m:
compiler/det_util.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/export.m:
compiler/float_regs.m:
compiler/goal_mode.m:
compiler/granularity.m:
compiler/hlds_defns.m:
compiler/hlds_error_util.m:
compiler/hlds_module.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_module.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/hlds_statistics.m:
compiler/implementation_defined_literals.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/lambda.m:
compiler/lco.m:
compiler/make_hlds_passes.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_proc_gen.m:
compiler/mode_info.m:
compiler/modecheck_call.m:
compiler/modes.m:
compiler/oisu_check.m:
compiler/old_type_constraints.m:
compiler/passes_aux.m:
compiler/polymorphism.m:
compiler/polymorphism_post_copy.m:
compiler/post_typecheck.m:
compiler/pre_typecheck.m:
compiler/proc_gen.m:
compiler/proc_requests.m:
compiler/simplify_proc.m:
compiler/stm_expand.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_sharing.analysis.m:
compiler/switch_detection.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_constr_initial.m:
compiler/term_constr_util.m:
compiler/term_util.m:
compiler/termination.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the change in pred_table.m.

    Refer to values of the renamed type using a consistent naming scheme.

    When the affected code repeats the body of existing helper predicates
    for lookup up a pred_info or proc_info, or updating a proc_info
    inside a pred_info, or updating a pred_info inside a module_info,
    call the helper predicate instead. This makes code shorter and less
    cluttered, and the use of the helper predicates for updates automatically
    ensures that we don't accidentally update a stale version of the relevant
    table. (This has sometimes been a problem in the past.)

    In a few places, carve a new predicate for processing one element
    of a list out of an existing predicate for processing all list elements.
2022-02-03 10:01:21 +11:00
Zoltan Somogyi
243491523d Stop counting errors in module_infos.
Over time, we have almost completely switched over to using error_specs,
using their severity (if not yet printed out) and their effect on the
exit status (if already printed out) to represent the presence of errors,
leaving only a few places that either updated or paid attention to the
num_error field in the module_info. This diff completes that process.

compiler/hlds_module.m:
    Delete the num_errors field in the module_info, and the predicates
    that operate on it.

compiler/hlds_error_util.m:
    Delete module_info arguments whose only purpose was to update the
    now-delete field.

compiler/error_util.m:
    Delete the old write_error_spec predicates that updated a count of warnings
    and a count of errors.

    Rename the write_error_spec_ignore predicates, which ignored those counts,
    by deleting the "_ignore" from their names. This makes them take the
    place of the deleted predicates.

compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/compile_target_code.m:
compiler/cse_detection.m:
compiler/find_module.m:
compiler/generate_dep_d_files.m:
compiler/handle_options.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.top_level.m:
compiler/make.track_flags.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mode_info.m:
compiler/modes.m:
compiler/pd_util.m:
compiler/pred_table.m:
compiler/recompilation.check.m:
compiler/typecheck.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2022-01-15 16:33:38 +11:00
Zoltan Somogyi
afd6764d12 Replace some bools with bespoke types.
compiler/typecheck.m:
    As above. Fix a misleading predicate name.

compiler/mercury_compile_front_end.m:
    Conform to the changes above.
2022-01-08 08:51:57 +11:00
Zoltan Somogyi
3373860871 Prepare for checking insts' "for type_ctor/arity".
This consists of two main parts.

The first part is creating a single point in time in a compiler invocation
when this check can be done. This point in time has to be after typechecking,
because (in the presence of type inference) this is the earliest point
when type information is guaranteed to be available (in the absence of
type errors, of course). The logical time is therefore the post-typecheck pass.
The post-typecheck pass also does the closely related task of propagating type
information into insts, but only the insts inside predicates' mode
declarations. Before this diff, the task of propagating type information
into the insts in the modes in lambda expressions was left to be done
*during*, not *before*, mode checking. (I think the rationale was that
you want to have propagated types into an inst in a procedure signature before
you may see a call to that procedure. Mode checking may encounter a call
to procedure of a predicate before processing that procedure, but due to
mode reordering, it won't ever encounter a call to a lambda expression
before processing the unification whose right hand side contains that
lambda expression.) However, it is conceptually simpler if the post-typecheck
pass takes over the propagation of types into insts even in lambda expressions,
which is what this diff does.

The second part is cleaning up the code that does this propagation,
to allow that cleanup to be reviewed separately from its modification
to check for uses of user-defined insts for values of types other than
the types that they are declared to be for.

compiler/inst_mode_type_prop.m:
    Give most predicates in this module more descriptive names
    that also fit into a single naming scheme.

compiler/hlds_pred.m:
    Add a predicate marker that allows typechecking to tell the
    post-typecheck pass that a predicate contains one or more lambda
    expressions.

compiler/typecheck_info.m:
    Add a slot to the typecheck_info in which we can record the presence
    of a lambda expression.

compiler/typecheck.m:
    When processing lambdas, record this fact in the new typecheck_info slot.

    When processing a predicate bodies causes this slot to be set,
    add the new marker to the predicate.

compiler/post_typecheck.m:
    For predicates for which the typechecking pass left this marker,
    propagate types not just into the insts in the predicate's mode
    declarations, but also into the insts in lambda expressions.
    This is an extra traversal of the predicate body, but only
    a relatively small minority of predicate bodies will need it done.

    Rename a predicate to fit in with the new naming scheme in
    inst_mode_type_prop.m.

    Improve the wording of an error message.

compiler/modecheck_unify.m:
    Do not propagate type info into the insts in lambda expressions,
    since the post-typecheck will have already done that task.

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

tests/invalid_nodepend/invalid_main.err_exp:
    Expect the updated error message from post_typecheck.m..
2021-12-24 23:28:08 +11:00
Zoltan Somogyi
a30c7c32b6 Revise the code printing progress messages.
compiler/passes_aux.m:
    To get the compiler's help in locating all the call sites
    to write_{pred,proc}_progress_message, change the argument order,
    to one that is better anyway.

    Print both the initial "% " at the start of the message, and the space
    between the message and the id of the predicate or procedure, so that
    callers don't have to. The fact that one caller was missing the "% "
    was the motive for this diff.

    After each message, flush the output. This is required in some use cases.
    Some call sites had a call to io.flush_output, but they could easily flush
    the wrong output stream.

compiler/bytecode_gen.m:
compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/dead_proc_elim.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/direct_arg_in_out.m:
compiler/float_regs.m:
compiler/hhf.m:
compiler/inlining.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_proc_gen.m:
compiler/mode_constraints.m:
compiler/modes.m:
compiler/polymorphism.m:
compiler/purity.m:
compiler/saved_vars.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
compiler/switch_detection.m:
compiler/typecheck.m:
compiler/unneeded_code.m:
    Conform to the changes above. Delete messages that should never have
    been there, such as those that would print "done" followed by the
    predicate/procedure id.

    In some places improve predicate names and/or comments.
2021-12-19 20:32:47 +11:00
Zoltan Somogyi
1ce46c2797 Pair lambda arg vars with their modes.
compiler/hlds_goal.m:
    This enforces the invariant that the there is one mode par argument var.

    Document that that "nonlocals" field of the lambda actually contains
    the variables that will be put into the closure.

compiler/assertion.m:
compiler/build_mode_constraints.m:
compiler/check_promise.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/delay_partial_inst.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/hhf.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/hlds_statistics.m:
compiler/implementation_defined_literals.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/lco.m:
compiler/loop_inv.m:
compiler/make_hlds_warn.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/mode_ordering.m:
compiler/mode_util.m:
compiler/modecheck_unify.m:
compiler/old_type_constraints.m:
compiler/polymorphism.m:
compiler/polymorphism_lambda.m:
compiler/pre_quantification.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/simplify_goal_unify.m:
compiler/stratify.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unused_args.m:
compiler/unused_imports.m:
    Conform to the change above.
2021-08-21 17:49:42 +10:00
Zoltan Somogyi
903135abad Add the --debug-types-pred-name <Name> option.
The idea is to allow people debugging the typechecker to restrict
checkpoint output to the typechecking of one or more named predicates.

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

compiler/typecheck_info.m:
    Add a field to the typecheck_info (actually, the typecheck_sub_info)
    that records whether the user wants checkpoint output from the
    typechecking of the current predicate.

compiler/typecheck_debug.m:
    Use this new field to make decisions, instead of looking up options
    in the globals structure at every checkpoint.

compiler/typecheck.m:
compiler/typeclasses.m:
    Conform to the change in typecheck_debug.m.
2021-08-09 09:28:06 +10:00
Zoltan Somogyi
f5fb963c06 Carve typecheck_debug.m out of type_assign.m.
compiler/typecheck_debug.m:
    A new module containing code to help debug typechecking, carved
    out of type_assign.m.

compiler/check_hlds.m:
compiler/notes/compiler_design.html:
    Add the new module to the check_hlds package, and document it.

compiler/typecheck_errors.m:
    Move functions that are only ever called from this module to this module
    from type_assign.m.

compiler/type_assign.m:
    Delete the code moved to other modules.

compiler/typecheck.m:
compiler/typeclasses.m:
    Import the new module.
2021-08-09 08:03:33 +10:00
Zoltan Somogyi
1640e7cb28 Fix spelling error in function name. 2021-08-03 13:10:37 +10:00
Zoltan Somogyi
167f7535a7 Improve variable names. 2021-07-19 11:31:59 +10:00
Zoltan Somogyi
241b70ae21 Fix typos in comments. 2021-07-18 22:40:14 +10:00
Zoltan Somogyi
254cd500bf Add bespoke type for du types' details.
compiler/hlds_data.m:
    As above. The other kinds of types already had bespoke types
    for *their* details.

compiler/add_type.m:
compiler/du_type_layout.m:
    Instead of passing values of the hlds_type_body with an inst
    that said they were du types, pass values of the new types instead,
    which is significantly simpler.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/dead_proc_elim.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type_hlds.m:
compiler/foreign.m:
compiler/hlds_out_module.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/mlds.m:
compiler/mode_util.m:
compiler/post_term_analysis.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_proc.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.
2021-07-01 08:26:04 +10:00
Zoltan Somogyi
40725f170e Replace ten int cons_ids with one.
We currently have one function symbol in the cons_id type for each
of our ten types of integer constants: signed vs unsigned, and
word-sized, 8-bit, 16-bit, 32-bit and 64-bit. In most places in the compiler,
these are all treated the same, and it gets tedious to have to write
the same logic ten times. This diff therefore changes things so that
the distinction between int constants of these ten types is pushed
to one level lower than the cons_id type.

compiler/prog_data.m:
    Replace the ten cons_ids {int,uint}{,8,16,32,64}_const with just one,
    some_int_const, whose argument now has those function symbols.

    Add some utility functions on integer constants.

compiler/prog_out.m:
    Add a utility predicate for converting int constants to strings.

compiler/parse_tree_to_term.m:
    Add a utility predicate for converting int constants to terms.

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

    Fix an old bug, though this does not matter since this module is unused.

compiler/add_pred.m:
compiler/bytecode_gen.m:
compiler/const_prop.m:
compiler/coverage_profiling.m:
compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_out_util.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/make_goal.m:
compiler/mercury_to_mercury.m:
compiler/ml_global_data.m:
compiler/mode_util.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/module_qual.qualify_items.m:
compiler/parse_util.m:
compiler/polymorphism.m:
compiler/polymorphism_type_info.m:
compiler/prog_ctgc.m:
compiler/prog_rep.m:
compiler/prog_type.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.region_transformation.m:
compiler/simplify_goal_call.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/superhomogeneous.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above. Use the new utility predicates
    to avoid code duplication.
2021-06-03 23:58:32 +10:00
Zoltan Somogyi
a72627888e Make the goal_type type more fit for purpose.
compiler/hlds_pred.m:
    Separate out goal types that implement a promise from those that do not.
    Document the latter. (The former is documented elsewhere.)

    When creating a new predicate, require the caller to specify
    the goal type; do not supply a default that may be wrong.

    Give some predicates more meaningful names.

compiler/add_pred.m:
    When adding an implicit predicate declaration for a promise,
    specify that the new predicate is for a promise, instead of letting
    hlds_pred.m assume by default that it is NOT for a promise.

compiler/add_clause.m:
    When adding a clause to the HLDS, do not require callers to supply
    information that they cannot possibly know.

    Specify the goal_type for a promise when creating its predicate,
    not later.

compiler/pre_typecheck.m:
    Record the goal type of field access functions, whose Mercury definition
    we just created, as containing only Mercury code. Previously, we falsely
    recorded it as containing both Mercury clauses and foreign procs.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_foreign_proc.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_special_pred.m:
compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/make_hlds_passes.m:
compiler/par_loop_control.m:
compiler/purity.m:
compiler/stm_expand.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
compiler/typecheck.m:
compiler/untupling.m:
    Conform to the changes above.
2021-05-20 00:46:18 +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
Zoltan Somogyi
dad2467270 Carve typecheck_msgs.m out of two other modules.
compiler/typecheck_msgs.m:
    New module containing code that handles the non-type-error messages
    that typechecking may generate.

compiler/typecheck.m:
compiler/typecheck_errors.m:
    Move such code to the new module.

compiler/check_hlds.m:
    Add the new module to the check_hlds package.

compiler/notes/compiler_design.html:
    Document the role of the new module.
2021-04-27 03:42:26 +10:00
Peter Wang
615e808266 Represent coerce goals as a type of cast.
compiler/hlds_goal.m:
    Move subtype_coerce from a option of hlds_goal_expr into cast_kind.
    It was useful to identify places where we needed to consider
    coercions separately from other types of casts, but that's done now.

compiler/hlds_pred.m:
    Delete gcid_coerce option of generic_call_id.

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/mode_errors.m:
compiler/modecheck_goal.m:
compiler/old_type_constraints.m:
compiler/post_typecheck.m:
compiler/pre_quantification.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:
compiler/superhomogeneous.m:
compiler/tabling_analysis.m:
compiler/term_traversal.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
compiler/typecheck.m:
compiler/unique_modes.m:
compiler/unused_imports.m:
    Conform to changes.

compiler/hlds_statistics.m:
    Count coercions as casts, for consistency in terminology.

compiler/prog_rep.m:
    Delete XXX about adding a coerce_rep in addition to cast_rep.
2021-04-14 15:10:18 +10:00
Zoltan Somogyi
4d14d48991 Use an enum to identify impl defined literals.
compiler/prog_data.m:
    Replace the cons_id impl_defined_const(string), where the string
    has only five legal values, with a impl_defined_const() wrapped
    around an enum with those five values. This makes some illegal states
    unrepresentable.

compiler/superhomogeneous.m:
    Make the predicate that converts term.implementation_defined functors
    to cons_ids check for the five legal strings, convert each to its
    enum value, and return an error message instead of a cons_id if the
    string is *not* one of the permitted five.

    Delete the code moved to parse_util.m (see the next entry).

compiler/prog_util.m:
    There was another predicate in prog_util.m that also converted
    term functors to cons_ids, which had to be kept in sync
    with the code in superhomogeneous.m that did the same job.
    The version in prog_util.m, even though it had code to handle
    all term functors, was only ever called from parse_inst_mode_name.m,
    which called it *only* on integer, float and string constants.

    Converting float and string functors to cons_ids is trivial,
    but converting integer functors is not, due to our support for
    ten different kinds of integers. However, instead of updating
    the integer conversion code in both superhomogeneous.m and prog_util.m,
    replace both with a single predicate. Since this predicate does
    a parsing job, and is used only during the construction of the
    initial HLDS, put it in parse_util.m.

compiler/parse_util.m:
    Base this unified predicate on the code that used to be in
    superhomogeneous.m since this is the only one that can generate
    error messages for integer constants that are outside the range
    of their type.

compiler/parse_inst_mode_name.m:
    Conform to the changes above. The code in parse_util.m now generates
    an error message if an integer const in a bound inst is too big
    to be represented by its type, which is much better than the
    compiler abort by the now-deleted code in prog_util.m that such
    code would have resulted in.

compiler/hlds_out_util.m:
compiler/implementation_defined_literals.m:
compiler/mercury_to_mercury.m:
compiler/old_type_constraints.m:
compiler/parse_tree_to_term.m:
compiler/prog_out.m:
compiler/prog_rep.m:
compiler/typecheck.m:
    Conform to the changes above.

tests/invalid/undef_impl_def_literal.err_exp:
    Expect the error message from the new code in superhomogeneous.m
    for $nosuchthing, instead of the generic error message about
    "undefined symbol `$nosuchthing' (which implicitly implies that
    the error could be fixed by *defining* $nosuchthing).
2021-04-01 20:01:11 +11:00
Zoltan Somogyi
4455f0450e Specify output streams in some places.
Besides this main purpose, this diff also replaces code that calls
io.write_string several times in a row with code that prints the
thing to be printed in one go with io.format. In a couple of places,
this has caught (and fixed) bugs where we wanted to put `' quotes
around a filename, but printed only one of the two quotes.

compiler/file_util.m:
    Provide alternatives to the existing maybe_report_stats,
    maybe_write_string and maybe_flush_output predicates that explicitly
    specify the output stream.

    Rename report_error_to_stream as report_error, to allow
    --warn-implicit-stream-calls to report calls to the existing report_error
    predicate, which does not take an explicit output stream.

    Add a module_name argument to the output_to_file_stream predicate,
    to allow its code to figure out where to print both progress and
    error messages.

compiler/module_cmds.m:
    Add a module_name argument to the predicates that update interface,
    to allow their code to figure out where to print both progress and
    error messages.

    For now, leave the predicates that issue commands that are not
    clearly linked to a single module using implicit streams.

compiler/pd_debug.m:
compiler/analysis.file.m:
    Specify output streams in some places.

    In other places, doing so would require redoing the whole debug
    infrastructure, since the current one is based on higher order predicates
    that always write to the non-explicitly-specified *current* output stream.

compiler/passes_aux.m:
    Provide predicates that get progress, debug and error streams
    given a module_info, by extracting the globals and the module name
    from the module_info, and then calling the predicates in globals.m
    to get those streams. Doing this sequence of actions here factors out
    what would otherwise be repeated code in many other parts of the compiler.

    Delete two predicates that were not used anywhere in the compiler.

compiler/deforest.m:
compiler/export.m:
compiler/intermod.m:
compiler/llds_out_file.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/recompilation.usage.m:
compiler/simplify_goal_conj.m:
compiler/type_assign.m:
compiler/typecheck.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Use explicit streams everywhere where --warn-implicit-stream-calls
    says this is possible.

compiler/Mercury.options:
    Specify --warn-implicit-stream-calls for the modules above
    with the listed exceptions, and with the exception of the modules
    for which it was already specified.

compiler/compile_target_code.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_middle_passes.m:
    Conform to the changes above.
2021-03-21 23:07:59 +11: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
Zoltan Somogyi
7633991604 Simplify the interface to typecheck_info.m.
compiler/typecheck_info.m:
    Take a pred_info argument, whose meaning is obvious, instead of a boolean
    argument, whose meaning is not.

compiler/typecheck.m:
    Pass the pred_info to typecheck_info.m instead of the boolean, thus
    replacing two tests with one.

    Delete excess assignment unifications.

    Add a comment.
2020-12-23 00:42:13 +11:00
Zoltan Somogyi
660cfe4f83 s/predicate symbol predicate/predicate symbol/ in a diagnostic.
We used to generate diagnostics of the form

    The predicate symbol predicate `<'/2 is also overloaded here.

The second "predicate" is pure noise. It could never be "function",
even though the code generating that message was prepared for that.

compiler/typecheck.m:
    When typechecking a *predicate* call, don't specify the predicate
    being called using a data structure that can also refer to functions.

compiler/typecheck_info.m:
    When representing an overloaded predicate name, as opposed to
    an overloaded function name, don't include a pred_or_func indication
    that should *always* be pf_predicate.

compiler/typecheck_errors.m:
    When reporting an overloaded predicate name, or talking about a
    predicate's argument vector, do not take a pred_or_func indication,
    since it should *always* be pf_predicate.

tests/invalid/ambiguous_overloading_error.err_exp:
tests/warnings/ambiguous_overloading.exp:
    Don't expect the redundant "predicate" in the overload error message.

tests/invalid/max_error_line_width.err_exp:
tests/invalid/max_error_line_width.m:
    The deletion of the redundant "predicate" in overload error messages
    made them all fit on one line, robbing this test of its task of testing
    longer-than-80-column output lines. Change the test so that the overload
    is not between int.< and float.<, but between the unchecked_left_shift
    functions in int and uint, since the longer function name yields error
    message lines in the length range this test case wants to test.

tests/invalid/ambiguous_overloading_error.m:
tests/invalid/arg_permutation.m:
tests/invalid/assert_in_interface.m:
tests/invalid/bad_detism_category.m:
    Fix programming style.

tests/invalid/assert_in_interface.err_exp:
    Update a line number.
2020-10-26 20:28:18 +11:00
Zoltan Somogyi
86f8696f32 Put globals before error_specs. 2020-06-04 04:47:00 +10:00
Zoltan Somogyi
66ea153cbc Fix treatment of TypeInfo_{In,Out}_N in foreign_procs.
compiler/polymorphism.m:
    Delete CanOptAwayUnused arguments, since they were always set to "yes".

    If a foreign_proc does not contain a foreign language variable named
    TypeInfo_for_T, but does contain a reference to the corresponding
    TypeInfo_{In,Out}_N variable, do not optimize it away.

compiler/typecheck.m:
    Fix a bug. When testing a foreign_proc that has existentially typed
    output arguments to see whether it contains a reference to the foreign
    language TypeInfo_for_T variable for the existentially quantified type var,
    we looking up the name (e.g. T) of the type var in the wrong tvarset.
    We were using the original type vars in a transformed tvarset. Fix this
    by using the original tvarset, the one that the type_vars came from.

    As in polymorphism, if a foreign_proc does not contain a foreign language
    variable named TypeInfo_for_T for an existentally typed type var T,
    but does contain a reference to the corresponding TypeInfo_Out_N variable,
    don't generate an error complaining about its absence. (Foreign procs
    don't have to consume input type_info variables, but they *do* have to
    generate the output type_variables, which they cannot do if they do not
    even refer to them.)

compiler/ml_foreign_proc_gen.m:
    Use simpler variable names.

    Fix formatting around casts.

compiler/pragma_c_gen.m:
    Delete CanOptAwayUnused arguments, since they were always set to "yes".

compiler/unused_args.m:
    Reword comments to avoid using the TypeInfo_for_T syntax, to make it easier
    to see what parts of the compiler still use it.
2020-04-16 12:03:27 +10:00
Zoltan Somogyi
8a6b33beb1 Run a maybe-expensive computation only if needed.
compiler/typecheck_errors.m:
    If -E is enabled, we print the relevant type assign set
    as a part of most messages about type errors. Until now,
    we constructed this verbose-only part of each error message
    regardless of whether -E was set, but in the case of large
    predicates with many ambiguously-typed variables (probably
    due to many type errors), this can be very expensive.

    With this diff, we now convert type assign sets to something
    human readable *only* if the result is actually going to be used.

    For the source file with many type errors in a big predicate
    that motivated this diff (resulting in more than 1300 lines of
    error message even without -E), the result is a reduction in compile time
    from about 3 minutes to about 6 seconds, i.e. a speedup by a factor
    of about 30.

compiler/typecheck_info.m:
    Record in the typecheck_info whether -E has been given or not.

compiler/typecheck.m:
    Pass the typecheck_info to the predicates in typecheck_errors.m
    that now need it to access that record.
2020-04-04 20:30:52 +11:00
Zoltan Somogyi
3a1ed2efcb Replace simple_call_id with pf_sym_name_arity.
compiler/prog_data.m:
    Delete the simple_call_id data type, since it is isomorphic
    to the pf_sym_name_arity type, which more clearly specifies
    what is stored inside it.

compiler/prog_out.m:
    Rename (all three versions of) simple_call_id_to_string to
    pf_sym_name_orig_arity_to_string, both to conform to the change
    in the input data type, and to emphasize that the resulting string
    will contain the *original* arity of functions (which does not include
    the return value), which is one less than the arity in the
    pf_sym_name_arity structure (which, in accordance with the
    convention inside the compiler that the arity is the length
    of the argument list, *does* include the return value).

    Delete the provision inside simple_call_id_to_string, now
    pf_sym_name_orig_arity_to_string, for special handling of the names
    of the predicates we use to implement promises, because it seems that
    *none* of the call sites to any of the three versions of this function
    can actually pass to it the identity of such a predicate. These calls
    refer to a predicate or mode declaration item (which promise predicates
    do not have), to clause or foreign_proc items (which again, promise
    predicates cannot have) or calls to the predicate (promise predicates
    cannot be called).

    Delete the exported predicate simple_call_id_to_sym_name_arity.
    It was called from exactly one place, inside prog_out.m itself,
    and this diff inlines that call.

    Avoid unnecessary forwarding of work from prog_out.m to error_util.m.

    Delete (all three versions of) write_simple_call_id. The changes
    below replace all their (few) uses with calls to
    pf_sym_name_orig_arity_to_string.

compiler/error_util.m:
    Replace the simple_call() error piece with qual_pf_sym_name_orig_arity,
    and add a new version unqual_pf_sym_name_orig_arity. Their names
    explicitly say that they print the original arities of functions,
    also say whether they strip away any module qualification on the
    sym_name inside the pf_sym_name_arity. We prefer the unqual version
    in situations where the module qualifier is implicit, which usually means
    that it must be the same as the name of the module being compiled, because
    it reduces visual clutter for readers of error messages.

    Put {qual,unqual}_pf_sym_name_orig_arity next to their most closely
    related function symbols, {qual,unqual}_sym_name_arity, in the
    format_component type. (This yields a few inconsequential changes
    in the order of error_specs when sorted.)

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/check_libgrades.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/goal_expr_to_goal.m:
compiler/hlds_data.m:
compiler/hlds_desc.m:
compiler/hlds_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/inst_util.m:
compiler/llds_out_instr.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make_hlds_error.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/ml_unify_gen_construct.m:
compiler/mlds_to_c_stmt.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/modecheck_util.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_type_repn.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/pre_quantification.m:
compiler/pred_table.m:
compiler/prog_item.m:
compiler/recompilation.version.m:
compiler/term_constr_build.m:
compiler/termination.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen_construct.m:
compiler/unused_imports.m:
    Conform to the changes above. Where I am pretty sure that in an error
    message, the module qualifier of a name must be the current module,
    use unqual_pf_sym_name_orig_arity instead of qual_pf_sym_name_orig_arity.

    Add some sanity checks where they seem appropriate.

    Replace sequences of io.write_strings with uses of io.format where this
    yields clearer code. (This is why there were no remaining calls to
    write_simple_call_id.)

    Shorten some too-long lines.

    In add_pred.m, make the order of some predicate definitions match
    the order of the calls to them.

tests/invalid/ambiguous_method.err_exp:
tests/invalid/ambiguous_method_2.err_exp:
tests/invalid/bad_pred_arity.err_exp:
tests/invalid/bad_sv_unify_msg.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/bug113.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/bug278.err_exp:
tests/invalid/bug410.err_exp:
tests/invalid/bug476.err_exp:
tests/invalid/bug487.err_exp:
tests/invalid/complex_constraint_err.err_exp:
tests/invalid/constrained_poly_insts.err_exp:
tests/invalid/errors.err_exp:
tests/invalid/errors1.err_exp:
tests/invalid/errors2.err_exp:
tests/invalid/exported_mode.err_exp:
tests/invalid/field_syntax_error.err_exp:
tests/invalid/foreign_singleton.err_exp:
tests/invalid/funcs_as_preds.err_exp:
tests/invalid/imported_mode.err_exp:
tests/invalid/invalid_binary_literal.err_exp:
tests/invalid/invalid_float_literal.err_exp:
tests/invalid/invalid_hex_literal.err_exp:
tests/invalid/invalid_octal_literal.err_exp:
tests/invalid/make_opt_error.err_exp:
tests/invalid/missing_det_decls.err_exp:
tests/invalid/multimode_syntax.err_exp:
tests/invalid/null_char.err_exp:
tests/invalid/occurs.err_exp:
tests/invalid/record_syntax_errors.err_exp:
tests/invalid/ref_to_implicit_pred.err_exp:
tests/invalid/require_tailrec_1.err_exp:
tests/invalid/require_tailrec_1.err_exp2:
tests/invalid/require_tailrec_2.err_exp:
tests/invalid/require_tailrec_2.err_exp2:
tests/invalid/require_tailrec_3.err_exp:
tests/invalid/require_tailrec_3.err_exp2:
tests/invalid/state_vars_test2.err_exp:
tests/invalid/state_vars_test3.err_exp:
tests/invalid/state_vars_test5.err_exp:
tests/invalid/type_inf_loop.err_exp:
tests/invalid/typeclass_constraint_extra_var.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_test_12.err_exp:
tests/invalid/typeclass_test_2.err_exp:
tests/invalid/typeclass_test_9.err_exp:
tests/invalid/types.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/unbound_type_vars.err_exp:
tests/invalid/with_type.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
tests/warnings/double_underscore.exp:
tests/warnings/pragma_source_file.exp:
tests/warnings/singleton_test.exp:
tests/warnings/singleton_test.exp2:
tests/warnings/singleton_test.exp3:
tests/warnings/singleton_test.exp4:
tests/warnings/singleton_test_state_var.exp:
tests/warnings/warn_return.exp:
tests/warnings/warn_return.exp2:
tests/warnings/warn_return.exp3:
tests/warnings/warn_succ_ind.exp:
tests/warnings/warn_succ_ind.exp2:
tests/warnings/warn_succ_ind.exp3:
tests/warnings/warn_succ_ind.exp4:
    Update all these expected output files. Most changes are due to
    predicate and function names no longer being module qualified when
    the module qualification is obvious. A few changes are due to the
    change in the relative ordering of the function symbols of the
    format_component type.

    For singleton_test, warn_return and warn_succ_ind in warnings,
    the changes to the non-C .exp files were done by hand, so they
    may have the wrong white space.
2020-03-16 12:10:28 +11:00
Zoltan Somogyi
9789375cc5 Make pre-HLDS passes use file-kind-specific parse trees.
Replacing item blocks file-kind-specific kinds of section markers with
file-kind-specific parse trees has several benefits.

- It allows us to encode the structural invariants of each kind of file
  we read in within the type of its representation. This makes the detection
  of any accidental violations of those invariants trivial.

- Since each file-kind-specific parse tree has separate lists for separate
  kinds of items, code that wants to operate on one or a few kinds of items
  can just operate on those kinds of items, without having to traverse
  item blocks containing many other kinds of items as well. The most
  important consequence of this is not the improved efficiency, though
  that is nice, but the increased clarity of the code.

- The new design is much more flexible. For example, it should be possible
  to record that e.g. an interface file we read in as a indirect dependency
  (i.e. a file we read not because its module was imported by the module
  we are compiling, but because its module was imported by *another* imported
  module) should be used *only* for the purpose it was read in for. This should
  avoid situations where deleting an import of A from a module, because it
  is not needed anymore, leads the compiler to generate an error message
  about a missing import of module B. This can happen if (a) module B
  always *should* have been imported, since it is used, but (b) module A's
  import of module B lead to module B's interface being available *without*
  an import of B.

  Specifically, this flexibility should enable us to establish each module's
  .int file as the single source of truth about how values of each type
  defined in that module should be represented. When compiling each source
  file, this approach requires the compiler to read in that module's .int file
  but using only the type_repn items from that .int file, and nothing else.

- By recording a single parse tree for each file we have read, instead of
  a varying number of item blocks, it should be significantly easier to
  derive the contents of .d files directly from the records of those
  parse trees, *without* having to maintain a separate set of fields
  in the module_and_imports structure for that purpose. We could also
  trivially avoid any possibility of inconsistencies between these two
  different sources of truth. (We currently fill in the fields used to
  drive the generation of .d files using two different pieces of code,
  one used for --generate-dependencies and one used for all other invocations,
  and these two *definitely* generate inconsistent results, as the significant
  differences in .d files between (a) just after an invocation of
  --generate-dependencies and (b) just after any other compiler invocation
  can witness.)

This change is big and therefore hard to review. Therefore in many files,
this change adds "XXX CLEANUP" comments to draw attention to places that
have issues that should be fixed, but whose fixes should come later, in
separate diffs.

compiler/module_imports.m:
    The compiler uses the module_and_imports structure defined here
    to go from a raw compilation unit (essentially a module to be compiled)
    to an augmented compilation unit (a raw compilation unit together
    with all the interface and optimization files its compilation needs).
    We used to store the contents of both the source file and of
    the interface and optimization files in the module_and_imports structure
    as item blocks. This diff replaces all those item blocks with
    file-kind-specific parse trees, for the reasons mentioned above.

    Separate out the .int0 files of ancestors modules from the .intN
    files for N>0 of directly imported modules. (Their item blocks
    used to be stored in the same list.)

    Maintain a database of the source, interface and optimization files
    we have read in so far. We use it to avoid reading in interface files
    if we have already read in a file for the same module that contains
    strictly more information (either an interface file with a smaller
    number as a suffix, or the source file itself).

    Shorten some field names.

compiler/prog_item.m:
    Define data structures for storing information about include_module,
    import_module and use_module declarations, both in a form that allows
    the representation of possibly erroneous code in actual source files,
    and in checked-and-cleaned-up form which is guaranteed to be free
    of the relevant kinds of errors. Add a block comment at the start
    of the module about the need for this distinction.

    Define parse_tree_module_src, a data structure for representing
    the source code of a single module. This is different from the existing
    parse_tree_src type, which represents the contents of a single source file
    but which may contain *more* than one module, and also different from
    a raw_compilation_unit, which is based on item blocks and is thus
    unable to express to invariants such as "no clauses in the interface".

    Modify the existing parse_tree_intN types to express the distinction
    mentioned just above, and to unify them "culturally", i.e. if they
    store the same information, make them store it using the same types.

    Fix a mistake by allowing promises to appear in .opt files.
    I originally ruled them out because the code that generates .opt files
    does not have any code to write out promises, but some of the predicates
    whose clauses it writes out have goal_type_promise, which means that
    they originated as promises, and get written out as promises.

    Split the existing pragma item kind into three item kinds, which have
    different invariants applying to them.

    - The decl (short for declarative) pragmas give the compiler some
      information, such as that a predicate is obsolete or that we
      want to type specialize some predicate or function, that is in effect
      part of the module's interface. Decl pragmas may appear in module
      interfaces, and the compiler may put them into interface files;
      neither statement is true of the other two kinds of pragmas.

    - The impl (short for implementation) pragmas are named so
      precisely because they may appear only in implementation sections.
      They give the compiler information that is private to that module.
      Examples include foreign_decls, foreign_codes, foreign_procs,
      and promises of clause equivalence, and requests for inlining,
      tabling etc. These will never be put into interface files,
      though some of them can affect the compilation of other modules
      by being included in .opt files.

    - The gen (short for generated) pragmas can never (legally) appear
      in source files at all. They record the results of compiler
      analyses e.g. about which arguments of a predicate are unused,
      or what exceptions a function can throw, and accordingly they
      should only ever occur in compiler-generated interface files.

    Use the new type differences between the three kinds of pragmas
    to encode the above invariants about which kinds of pragmas can appear
    where into the various kinds of parse trees.

    Make the augmented compilation unit, which is computed from
    the final module_and_imports structure, likewise switch from
    storing item blocks to storing the whole parse trees of the
    files that went into its construction. With each such parse tree,
    record *why* we read it, since this controls what permissions
    the source module being compiled has for access to the entities
    in the parse tree.

    Simplify the contains_foreign_code type, since one of three
    function symbols was equivalent to one possible use of another
    function symbol.

    Provide a way to record which method of which class a compiler-generated
    predicate is for. (See hlds_pred.m below.)

    Move the code of almost all utility operations to item_util.m
    (which is imported by many fewer modules than prog_item.m),
    keeping just the most "popular" ones.

compiler/item_util.m:
    Move most of the previously-existing utility operations here from
    prog_item.m, most in a pretty heavily modified form.

    Add a whole bunch of other utility operations that are needed
    in more than one other module.

compiler/convert_parse_tree.m:
    Provide predicates to convert from raw compilation units to
    parse_tree_module_srcs, and vice versa (though the reverse
    shouldn't be needed much longer).

    Update the conversion operations between the general parse_tree_int
    and the specific parse_tree_intN forms for the changes in prog_item.m
    mentioned above. In doing so, use a consistent approach, based on
    new operations in item_util.m, to detect errors such as duplicate
    include_module and import/use_module declarations in all kinds
    of parse trees.

    Enforce the invariants that the types of parse trees of various kinds
    can now express in types, generating error messages for their violations.

    Delete some utility operations that have been moved to item_util.m
    because now they are also needed by other modules.

compiler/grab_modules.m:
    Delete code that did tests on raw compilation units that are now done
    when that raw compilation unit is converted to a parse_tree_module_src.
    Use the results of the checks done during that conversion to decide
    which modules are imported/used and in which module section.

    Record a single reason for why we reading in each interface and
    optimization file. The code of make_hlds_separate_items.m will use
    this reason to set up the appropriate permissions for each item
    in those files.

    Use separate code for handling different kinds of interface and
    optimization files. Using generic traversal code was acceptable economy
    when we used the same data structure for every kind of interface file,
    but now that we *can* express different invariants for different kinds
    of interface and optimization file, we want to execute not just different
    code for each kind of file, but the data structures we want to work on
    are also of different types. Using file-kind-specific code is a bit
    longer, but it is significantly simpler and more robust, and it is
    *much* easier to read and understand.

    Delete the code that separates the parts of the implementation section
    that are exported to submodules, and the part that isn't, since that task
    is now done in make_hlds_separate_items.m.

    Pass a database of the files we have read through the relevant predicates.

    Give some predicates more meaningful names.

compiler/notes/interface_files.html:
    Note a problem with the current operation of grab_modules.

compiler/get_dependencies.m:
    Add operations to gather implicit references to builtin modules
    (which have to be made available even without an explicit import_module
    or use_module declaration) in all kinds of parse trees. These have
    more code overall, but will be at runtime, since we need only look at
    the item kinds that may *have* such implicit references.

    Add a mechanism to record the result of these gathering operations
    in import_and_or_use_maps.

    Give some types, function symbols, predicates and variables
    more meaningful names.

compiler/make_hlds_separate_items.m:
    When we stored the contents of the source module and the
    interface and optimization files we read in to augment it
    in the module_and_imports structure as a bunch of item blocks,
    the job of this module was to separate out the different kinds of items
    in the item blocks, returning a single list of each kind of item,
    with each such item being packaged up with its status (which encodes
    a set of permissions saying what the source module is allowed
    to do with it).

    Now that the module_and_imports structure stores this info in
    file-kind-specific parse trees, all of which have separate lists
    for each kind of item and none of which contain item blocks,
    the job of this module has changed. Now its job is to convert
    the reason why each file was read in into the (one or more) statuses
    that apply to the different kinds of items stored in it, wrap up
    each item with its status, and return the resulting overall list
    of status/item pairs for each kind of item.

compiler/read_modules.m:
    Add predicates that, when reading an interface file, return its contents
    in the tightest possible file-kind-specific parse tree.

    Refine the database of files we have read to allow us to store
    more file-kind-specific parse trees.

    Don't require that files in the database have associated timestamps,
    since in some cases, we read files we can put into the database
    *without* getting their timestamps.

    Allow the database to record that an attempt to read a file failed.

compiler/split_parse_tree_src.m:
    Rearchitect how this module separates out nested submodules from within
    the main module in a file.

    Another of the jobs of this module is to generate error messages for
    when module A includes module B twice, whether via nesting or via
    include_module declarations, with one special exception for the case
    where A's interface contains nested submodule A.B's interface,
    and A's implementation contains nested submodule A.B's implementation.
    The problem ironically was that while it reported duplicate include_module
    declarations as errors, split_parse_tree_src.m also *generated*
    duplicate include_module declarations. Since it replaced each nested
    submodule occurrence with an include_module declaration, in the scenario
    above, it generated two include_module declarations for A.B. Even worse,
    the interface incarnation of submodule A.B could contain
    (the interface of) its own nested submodule A.B.C, while its
    implementation incarnation could contain (the implementation section of)
    A.B.C. Each occurrence of A.B.C would be its only occurrence in the
    including part of its parent A.B, which means local tests for duplicates
    do not work. (I found this out the hard way.)

    The solution we now adopt adds include_module declarations to the
    parents of any submodule only once the parse tree of the entire
    file has been processed, since only then do we know all the
    includer/included relationships among nested modules. Until then,
    we just record such relationships in a database as we discover them,
    reporting duplicates when needed (e.g. when A includes B twice
    *in the same section*), but not reporting duplicates when not needed
    (e.g. when A.B includes A.B.C in *different* sections).

compiler/prog_data.m:
    Add a new type, pf_sym_name_and_arity, that exactly specifies
    a predicate or function. It is a clone of the existing simple_call_id
    type, but its name does NOT imply that the predicate or function
    is being called.

    Add XXXs that call for some other improvements in type names.

compiler/prog_data_foreign.m:
    Give a type, and the operations on that type, a more specific name.

compiler/error_util.m:
    Add an id field to all error_specs, which by convention should be
    filled in with $pred. Print out the value in this field if the compiler
    is invoked with the developer-only option --print-error-spec-id.
    This allows a person debugging the compiler find out where in the code
    an undesired error message is coming from significantly easier
    than was previously possible.

    Most of the modules that have changes only "to conform to the changes
    above" will be for this change. In many cases, the updated code
    will also simplify the creation of the affected error_specs.

    Fix a bug that looked for a phase in only one kind of error_spec.

    Add some utility operations needed by other parts of this change.

    Delete a previously internal function that has been moved to
    mdbcomp/prim_data.m to make it accessible in other modules as well.

compiler/Mercury.options:
    Ask the compiler to warn about dead predicates in every module
    touched by this change (at least in one its earlier versions).

compiler/add_foreign_enum.m:
    Replace a check for an inappropriately placed foreign_enum declaration
    with a sanity check, since with this diff, the error should be caught
    earlier.

compiler/add_mutable_aux_preds.m:
    Delete a check for an inappropriately placed mutable declaration,
    since with this diff, the error should be caught earlier.

compiler/add_pragma.m:
    Instead of adding pass2 and pass3 pragmas, add decl and impl and
    generated pragmas.

    Delete the tests for generated pragma occurring anywhere except
    .opt files, since those tests are now done earlier.

    Shorten some too-long predicate names.

compiler/comp_unit_interface.m:
    Operate on as specific kinds of parse trees as the interface of this
    module will allow. (We could operate on more specific parse trees
    if we changed the interface, but that is future work).

    Use the same predicates for handling duplicate include_module,
    import_module and use_module declarations as everywhere else.

    Delete the code of an experiment that shouldn't be needed anymore.

compiler/equiv_type.m:
    Replace code that operated on item blocks with code that operates
    on various kinds of parse trees.

    Move a giant block of comments to the front, where it belongs.

compiler/hlds_module.m:
    Add a field to the module_info that lets us avoid generating
    misleading error messages above missing definitions of predicates
    or functions when those definitions were present but were not
    added to the HLDS because they had errors.

    Give a field and its access predicates a more specific name.

    Mark a spot where an existing type cannot express everything
    it is supposed to.

compiler/hlds_pred.m:
    For predicates which the compiler creates to represent a class method
    (the virtual function, in OOP terms), record not just this fact,
    but the id of the class and of the method. Using this extra info
    in progress messages (with mmc -V) prevents the compiler from printing e.g.

        % Checking typeclass constraints on class method
        % Checking typeclass constraints on class method
        % Checking typeclass constraints on class method

    when checking three such predicates.

compiler/make.m:
    Provide a slot in the make_info structure to allow the database
    of the files we have read in to be passed around.

compiler/make_hlds_error.m:
    Delete predicates that are needed in just one other module,
    and have therefore been moved there.

compiler/make_hlds_passes.m:
    Add decl, impl and generated pragma separately, instead of adding
    pass2 and pass3 pragmas separately.

    Do not generate error messages for clauses, initialises or finalises
    in module interfaces, since with this diff, such errors should be
    caught earlier.

compiler/mercury_compile_main.m:
compiler/recompilation.check.m:
    Explicitly pass around the expanded database of parse trees
    of files that have been read in.

compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
    Collect module qualification information, and do module qualification
    respectively on parse trees of various kinds, not item blocks.
    Take information about what the module may do with the contents
    of each interface or optimization file from the record of why
    we read that file, not from the section markers in item blocks.

    Break up some too-large predicates by carving smaller ones out of them.

compiler/options.m:
    Add an option to control whether errors and/or warnings detecting
    when deciding what should go into a .intN file be printed,
    thus (potentially) preventing the creation of that file.

    Add commented-out documentation for a previously totally undocumented
    option.

doc/user_guide.texi:
    Document the new option.

NEWS:
    Announce the new option.

    Mention that we now generate warnings for unused import_module and
    use_module declarations in the interface even if the module has
    submodules.

compiler/write_module_interface_files.m:
    Let the new option control whether we filter out any messages generated
    when deciding what should go into a .intN file.

compiler/parse_item.m:
    Delete actually_read_module_opt, since it is no longer needed;
    its callers now call actually_read_module_{plain,trans}_opt instead.

    Delete unneeded arguments from some predicates.

compiler/parse_module.m:
    Delete some long unused predicates.

compiler/parse_pragma.m:
    When parsing pragmas, wrap them up in the new decl, impl or generated
    pragma kinds.

compiler/parse_tree_out.m:
    Add predicates to write out each of the file-kind-specific parse trees.

compiler/parse_tree_out_pragma.m:
    Add predicates to write out decl, impl and generated pragmas.

compiler/polymorphism.m:
    Add a conditionally-enabled progress message, which can be useful
    in tracking down problems.

compiler/prog_item_stats.m:
    Conform NOT to the changes above beyond what is needed to let this module
    compile. Let that work be done the next time the functionality of
    this module is needed, by which time the affected data structures
    maybe have changed further.

compiler/typecheck.m:
    Fix a performance problem. With intermodule optimization, we read in
    .opt files, some of which (e.g. list.opt and int.opt) contain promises.
    These promises are read in as predicates with goal_type_promise,
    but they do not have declarations of the types of their arguments
    (since promises do not have declarations as such). Those argument types
    therefore have to be inferred. That inference replaces the original
    "I don't know" argument types with their actual types.

    The performance problem is that when we change the recorded argument types
    of a predicate, we require another loop over all the predicates in the
    module, so that any calls to this predicate can be checked against
    the updated types. This is as it should be for callable predicates,
    but promises are not callable. So if all the *only* predicates whose
    recorded argument types change during the first iteration to fixpoint
    are promises, then a second iteration is not needed, yet we used to do it.

    The fix is to replace the "Have the recorded types of this predicate
    changed?" boolean flag with a bespoke enum that says "Did the checking
    of this predicate discover a need for another iteration", and not
    setting it when processing predicates whose type is goal_type_promise.

compiler/typecheck_errors.m:
    Do not generate an error message for a predicate missing its clauses
    is the clauses existed but were not added to the HLDS because they were
    in the interface section.

    When reporting on ambiguities (when a call can match more than one
    predicate or function), sort the possible matches before reporting
    them.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/canonicalize_interface.m:
compiler/check_for_missing_type_defns.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_promise.m:
compiler/check_raw_comp_unit.m:
compiler/check_typeclass.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/compiler_util.m:
compiler/dead_proc_elim.m:
compiler/deps_map.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/field_access.m:
compiler/find_module.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/handle_options.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/introduce_parallelism.m:
compiler/layout_out.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_top_gen.m:
compiler/mmakefiles.m:
compiler/mode_errors.m:
compiler/mode_robdd.equiv_vars.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/oisu_check.m:
compiler/old_type_constraints.m:
compiler/options_file.m:
compiler/parse_class.m:
compiler/parse_dcg_goal.m:
compiler/parse_goal.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_inst_mode_name.m:
compiler/parse_mutable.m:
compiler/parse_sym_name.m:
compiler/parse_type_defn.m:
compiler/parse_type_name.m:
compiler/parse_type_repn.m:
compiler/parse_types.m:
compiler/parse_util.m:
compiler/parse_vars.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/prog_event.m:
compiler/prog_mode.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_proc.m:
compiler/state_var.m:
compiler/stratify.m:
compiler/style_checks.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/write_deps_file.m:
compiler/xml_documentation.m:
    Conform to the changes above.

mdbcomp/prim_data.m:
    Move a utility function on pred_or_funcs here from a compiler module,
    to make it available to other compiler modules as well.

scripts/compare_s1s2_lib:
    A new script that helped debug this diff, and may help debug
    similar diffs the future. It can compare (a) .int* files, (b) .*opt
    files, (c) .mh/.mih files or (d) .c files between the stage 1 and
    stage 2 library directories. The reason for the restriction
    to the library directory is that any problems affecting the
    generation of any of these kinds of files are likely to manifest
    themselves in the library directory, and if they do, the bootcheck
    won't go on to compile any of the other stage 2 directories.

tests/debugger/breakpoints.a.m:
tests/debugger/breakpoints.b.m:
    Move import_module declarations to the implementation section
    when they are not used in the interface. Until now, the compiler
    has ignored this, but this diff causes the compiler to generate
    a warning for such misplaced import_module declarations even modules
    that have submodules. The testing of such warnings is not the point
    of the breakpoints test.

tests/invalid/Mercury.options:
    Since the missing_interface_import test case tests error messages
    generated during an invocation of mmc --make-interface, add the
    new option that *allows* that invocation to generate error messages.

tests/invalid/ambiguous_overloading_error.err_exp:
tests/invalid/max_error_line_width.err_exp:
tests/warnings/ambiguous_overloading.exp:
    Expect the updated error messages for ambiguity, in which
    the possible matches are sorted.

tests/invalid/bad_finalise_decl.m:
tests/invalid/bad_initialise_decl.m:
    Fix programming style.

tests/invalid/bad_item_in_interface.err_exp:
    Expect an error message for a foreign_export_enum item in the interface,
    where it should not be.

tests/invalid/errors.err_exp:
    Expect the expanded wording of a warning message.

tests/invalid/foreign_enum_invalid.err_exp:
    Expect a different wording for an error message. It is more "standard"
    but slightly less informative.

tests/invalid_submodules/children2.m:
    Move a badly placed import_module declaration, to avoid having
    the message the compiler now generates for it from affecting the test.

tests/submodules/parent2.m:
    Move a badly placed import_module declaration, to avoid having
    the message the compiler now generates for it from affecting the test.

    Update programming style.
2020-03-13 12:58:33 +11:00