Commit Graph

363 Commits

Author SHA1 Message Date
Zoltan Somogyi
a2cdba85bd Reduce duplication of code about int type names.
compiler/prog_data.m:
    Give two predicates dealing with the names of builtin types
    more meaningful names. Document the semantics of both predicates,
    and document the reason why the definition of one is effectively
    inlined into the definition of the other.

compiler/builtin_ops.m:
    Make a copy of one of the predicates easier to read, even though
    the copy cannot be replaced by a call.

compiler/module_qual.qualify_items.m:
    Do replace such copy by a call.

compiler/error_type_util.m:
compiler/parse_tree_out_type.m:
compiler/parse_tree_to_term.m:
compiler/pred_name.m:
compiler/prog_event.m:
compiler/prog_type.m:
compiler/table_gen.m:
compiler/typecheck_errors.m:
compiler/xml_documentation.m:
    Refer to the predicates by their new names.
2023-05-21 11:33:20 +10:00
Zoltan Somogyi
18817d62d0 Record more than a pred_proc_id for each method.
Class and instance definitions both contain lists of methods,
predicates and/or functions, that each have one or more procedures.
Until now, we represented the methods in class and instance definitions
as lists of nothing more than pred_proc_ids. This fact complicated
several operations,

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

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

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

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

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

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

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

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

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

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

    Add some utility functions.

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

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

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

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

    Give some predicates better names.

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

    Give some predicates better names.

    Some error messages about problems in instance definitions started with

        In instance declaration for class/arity:

    while others started with

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

    Replace both with

        In instance declaration for class(foo, bar):

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

    Factor out some common code.

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

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

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

compiler/polymorphism_type_info.m:
    Fix some comment rot.

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

tests/invalid/bug476.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_mode.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_mode_3.err_exp:
tests/invalid/typeclass_mode_4.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_9.err_exp:
    Expect the updated wording of some error messages.
2022-11-22 02:27:33 +11:00
Zoltan Somogyi
daa4513894 Add the new compiler option --show-local-call-tree.
When specified, this option causes the compiler to output,
to <module>.local_call_tree, a flattened form of the part of the
module call tree restricted to local predicates and functions, like this:

    pred polymorphism_process_module/5
        pred maybe_polymorphism_process_pred/7
        pred polymorphism_update_arg_types/5

    pred maybe_polymorphism_process_pred/7
        pred polymorphism_process_pred_msg/7

    pred polymorphism_process_pred_msg/7
        pred polymorphism_process_pred/6

    pred polymorphism_process_pred/6
        pred polymorphism_process_clause_info/6
        pred add_extra_arg_modes_to_proc/3

This output consists of a list of entries, with each entry naming
a predicate or function, and listing all the local predicates and functions
it calls. Both the callees in a single entry and the entries themselves
are in the order in which a depth-first left-to-right traversal of the
module, starting at the exported predicates and functions, would encounter
them. That order is also output to <module>.local_call_tree_order.
This information can give useful guidance about how the contents
of a module should be ordered.

doc/user_guide.texi:
compiler/options.m:
    As above.

NEWS:
    Announce the new option.

compiler/hlds_call_tree.m:
    A new module to implement the new option.

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

compiler/mercury_compile_front_end.m:
    Invoke the new module if the new option is set.

compiler/hlds_desc.m:
    Add describe_pred and describe_pred_from_id. Reimplement
    describe_proc and describe_proc_from_id in terms of those.
    Allow callers of all four to decide whether we want the descriptions
    to include the names of the defining module.

compiler/dead_proc_elim.m:
compiler/ml_proc_gen.m:
compiler/proc_gen.m:
    Conform to the change to hlds_desc.m.

compiler/hlds_goal.m:
    Document when it is ok for traversals of goals to assume that
    they won't find any rhs_lambda_goals or complicated_unifys
    in unifications.

    Change the documentation of the five classes of unifications
    (construct/deconstruct/assign/simple_test/complicated_unify)
    to refer to the LHS as X and the RHS as Y, since pretty much
    all the modules focusing on unifications (such as superhomoneous.m)
    use that naming convention. Having the opposite convention here
    was not a good idea.

compiler/prog_data.m:
    Fix comment rot.
2022-09-25 18:04:20 +10:00
Zoltan Somogyi
47ca4f9a66 Let disable_warning apply to unknown_format_calls.
doc/reference_manual.texi:
NEWS:
    Allow a disable_warning scope to override the setting of the
    --warn-unknown-format-calls option to "yes" inside its scope.

compiler/prog_data.m:
    Provide a representation for the new kind of disable-able warning.

compiler/parse_goal.m:
    Parse the new kind of disable-able warning.

compiler/prog_out.m:
    Print out the new kind of disable-able warning.

compiler/format_call.m:
    Add a parameter to the format checking code to control whether
    we generate this warning. Using this parameter yields clearer code
    that locally overriding the value of the option.

compiler/simplify_goal_scope.m:
    Ignore the new kind of disable-able warning in code that has nothing
    to do with it.

compiler/options.m:
doc/user_guide.texi:
    Fix an old issue: include stream.string_writer.format in the description
    of --warn-unknown-format-calls.

tests/warnings/disabled_warning.{m,exp}:
    Add a test of the new functionality.

tests/warnings/Mmakefile:
tests/warnings/Mercury.options:
    Enable the new test case.
2022-08-24 16:33:46 +10: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
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
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
Julien Fischer
093018109c Update references to LIMITATIONS file.
BUGS:
README.md:
bindist/Mmakefile:
compiler/notes/release_checklist.html:
compiler/prog_data.m:
doc/reference_manual.texi:
library/list.m:
runtime/mercury_type_desc.h:
    As above.
2022-01-01 15:53:34 +11:00
Zoltan Somogyi
4126519139 Separate subtypes from du types in parse trees.
compiler/prog_data.m:
    Split type_details_sub from type_details_du, and separate
    parse_tree_sub_type from parse_tree_du_type. This gets us two things:

    - It allows us to encode the prohibition on user-specified equality and
      comparison predicates, and "where direct_arg is" clauses,
      on subtype definitions.

    - It gives us data types we can use to represent (a) only subtype
      definitions, and (b) only non-subtype du definitions.

    Note that this diff deliberately leaves the HLDS representation
    of subtypes unchanged. This is because while a subtype *definition*
    may not specify e.g. equality and comparison predicates, a subtype *can*
    have equality and comparison predicates; it just has to get them from
    its base type. And the same applies to direct args.

compiler/parse_type_defn.m:
    Enforce the invariant that subtypes may not have user-specified equality
    and comparison predicates, or "where direct_arg is" clauses.

    If we find a subtype definition that does have one or both of these
    non-allowed and now-nonrepresentable components, we do still want to
    return the rest of the type definition, in order to avoid misleading
    error messages about that type having no definition at all. To make this
    possible, allow the parsing predicate to return error_specs "alongside",
    as well as "instead of", the item or marker being parsed.

compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_class.m:
    Handle these "alongside" error messages.

compiler/prog_item.m:
    Separate out subtypes from other du types in type definition maps.

compiler/add_type.m:
    Delete a semantic check that is now in parse_type_defn.m.

    Conform to the change to the representations of subtypes/du types
    in the parse tree.

compiler/item_util.m:
    Add a new utility function for subtypes.

compiler/check_type_inst_mode_defns.m:
compiler/comp_unit_interface.m:
compiler/convert_parse_tree.m:
compiler/decide_type_repn.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/intermod.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the change to the representations of subtypes/du types
    in the parse tree.
2021-10-02 16:45:26 +10:00
Zoltan Somogyi
12605f8c10 Use checked type/inst/modes in parse_tree_int[123]s.
With this change, we guarantee that if any type, inst or mode
has inconsistent definitions in its defining module, those inconsistencies
will not make it into the the module's .int/.int2/.int3 files, where
they would confuse any compiler invocation that reads them in.

compiler/prog_item.m:
    Replace {type,inst,mode}_ctor_defn_maps, which are unchecked,
    with {type,inst,mode}_ctor_checked_maps in parse_tree_int[123]s.

    To make this possible,

    - generalize the items containing inst and mode definitions the way that
      items containing type definitions have been generalized previously,
      to allow them to store particular *kinds* of inst or mode definitions;

    - move the definitions of type_ctor_checked_map and its components
      here from check_type_inst_mode_defns.m; and

    - add similar, but simpler, definitions for {inst,mode}_ctor_checked_map.

compiler/check_type_inst_mode_defns.m:
    Delete the type definitions moved to prog_item.m.

    Modify the checking process slightly to allow it to check properly
    the definitions we now put into .int, .int2 and .int3 files.

    Add code to check inst and mode definitions as well as type definitions.
    Since insts and modes have only one non-abstract kind of definition,
    these codes are much simpler than the code for checking types.

compiler/comp_unit_interface.m:
    Construct checked type, inst and mode definitions to put into
    .int, .int2 and .int3 files. The .int2 and .int3 parts were
    reasonably simple, but the .int part requires some detailed
    case-by-case analysis.

compiler/convert_parse_tree.m:
    Check the type, inst and mode definitions read in from .int/.int2/.int3
    files when creating their parse trees. If those files were generated
    by a compiler that has this diff, then this checking process should
    not find any problems.

compiler/equiv_type.m:
    Operate on checked type, inst and mode definitions instead of their
    unchecked versions.

    Delete an unneeded field from a structure.

compiler/error_util.m:
    Add {qual,unqual}_{inst,mode}_ctor as format components, so that
    any error messages about inst and mode definitions do not have to convert
    inst_ctors and mode_ctors to symname/arity pairs.

compiler/item_util.m:
    Add some utility predicates and functions needed by the changes above.

compiler/module_qual.collect_mq_info.m:
    Since checked type, inst and mode definitions can contain info that is
    derived from both the interface and implementation sections of a module,
    add the capability to get only the *publicly* declared types, insts and
    modes from their respective kinds of checked definitions.

compiler/module_qual.qualify_items.m:
    Module qualify checked type, inst and mode definitions.

compiler/module_qual.qual_errors.m:
    Treat references to inst_ctors and mode_ctors in qualification error
    messages the same way as we treat type_ctors.

    Also replace mq_ids that are intended to represent classes with class_ids,
    to represent the intent better.

compiler/parse_tree_out.m:
    Output the updated parse_trees of .int/.int2/.int3 files.

compiler/prog_data.m:
    Add an XXX about a future change.

compiler/decide_type_repn.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/make_hlds_separate_items.m:
compiler/pred_table.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the changes above.

library/maybe.m:
    Add utility predicates needed by the code above.

NEWS:
    Announce the new predicates in maybe.m.

tools/intdiffall:
    A script that shows differences between the automatically generated
    interface files between stage 1 and stage 2, which helped debug this diff.
2021-10-01 17:57:15 +10:00
Zoltan Somogyi
78df274d79 Give a field a more accurate name. 2021-09-08 06:49:13 +10:00
Zoltan Somogyi
1f328fe18b More recompilation type specializations.
compiler/recompilation.m:
    Introduce a new enum type, used_item_type, which has equivalents
    of those item_types for which we collect used item sets. This allows us
    to delete several calls to unexpected.

    Rename type_abstract_item to type_name_item and type_body_item to
    type_defn_item.

compiler/recompilation.used_file.m:
    Tighten the definition of the resolved_functor type by changing the types
    of some fields from generic (e.g. item_name) to specific (e.g. type_ctor).
    Specify that the arity recorded for predicates and functions is
    pred_form_arity, since that is what the code that actually resolves
    references in the pred table uses, even though some other parts of
    the code took it to be user arity, which is different for functions.
    Mark one of these differences with XXXs, since they are likely to be bugs.
    Fix another, since in that case it is *clear* that it was a bug.

    Also give some of the function symbols clearer names, and put their
    arguments in their conventional order.

compiler/prog_data.m:
    Add a type for use in recompilation.used_file.m.

compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/module_qual.id_set.m:
compiler/module_qual.qualify_items.m:
compiler/proc_requests.m:
compiler/qual_info.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
    Conform to the changes above.

    In some cases, give some predicates and/or variables more meaningful names,
    or convert clause lists into explicit disjunctions. (In some cases,
    the latter revealed arguments that all clauses ignored.)
2021-08-29 00:41:14 +10:00
Zoltan Somogyi
09aff57259 Represent "is this a subtype" using a bespoke type.
compiler/prog_data.m:
compiler/hlds_data.m:
    Use a new type, maybe_subtype, to say whether a du type is a subtype.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_parse_tree_type_defns.m:
compiler/comp_unit_interface.m:
compiler/decide_type_repn.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/hlds_out_module.m:
compiler/ml_type_gen.m:
compiler/mlds.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/parse_type_defn.m:
compiler/prog_type.m:
compiler/recompilation.usage.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
    Conform to the changes above.
2021-07-09 09:25:04 +10:00
Zoltan Somogyi
e627efcf50 A start on getting type_repn info from .int files.
compiler/du_type_layout.m:
    Add a first draft of the code that will eventually get type representation
    information from .int files. Invoke the new code only if undocumented,
    developer-only experiment flags are set, and when invoked, compare
    its output with the output of the old algorithm it is intended to
    eventually replace.

    The new code is not yet complete, and thus has not yet been tested.

compiler/prog_item.m:
    Add a new field to the augmented compilation unit data type
    that is intended to hold the .int file of the main module, the module
    that the augmented compilation unit is for. For every module imported
    by the main module, we read its .int or .int2 file and get the
    representation information for the types they define from those files,
    but we need this info for the main module's own types as well.

    Add "need type representation information" as reason for reading
    a .int file.

    Break some types down into smaller types, to allow their components
    to be manipulated individually by du_type_layout.m.

    Start using uint8, not uint, in situations where we want to store
    values that select bits in words, which fit into 6 bits.

    Add XXXs where we could, and maybe should switch to uint8s.

    Add extra documentation.

compiler/grab_modules.m:
    Read in the main module's own .int file.

    Replace a bool with a bespoke type.

compiler/module_imports.m:
    Provide a slot for the main module's own interface file,
    which will be used to set the new slot in augmented compilation units.

compiler/comp_unit_interface.m:
    Put the exact same type_ctor_repn_map into .int2 files as .int files.
    This should prevent the scenario where a compilation reads
    e.g. mod_x.int2, gains access to the definitions of the exported types
    of module mod_x,  but then needs to read mod_x.int as well to find out
    how those types are represented. Since neither type checking nor any
    other semantic analysis pass pays any attention to type_repn items,
    the additional type_repn items in mod_x.int2 cannot turn an otherwise
    illegal program into a legal one.

compiler/hlds_data.m:
    Clarify a comment.

compiler/maybe_error.m:
    Provide a utility predicate.

compiler/prog_data.m:
    Add XXXs about possible future improvements.

compiler/decide_type_repn.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_type_repn.m:
compiler/parse_type_repn.m:
compiler/prog_item_stats.m:
compiler/write_deps_file.m:
    Conform to the changes above.
2021-07-01 06:12:21 +10:00
Zoltan Somogyi
d02751a38b Add name_arity as a format_component.
compiler/error_util.m:
    As above.

compiler/prog_data.m:
    To make this possible, move the existing definitions of name_arity here.

compiler/hlds_defns.m:
compiler/pred_table.m:
    Delete two the old copies of that definition.
2021-06-27 20:39:50 +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
e10bc34a74 Implement mutables only in prog_mutable.m.
compiler/prog_mutable.m:
    Move code implementing mutables here, mostly from add_mutable_aux_preds.m,
    but some from comp_unit_interface.m. Export only what those two modules
    need.

    Replace the

compiler/add_mutable_aux_preds.m:
compiler/comp_unit_interface.m:
    Delete the code moved to prog_mutable. In add_mutable_aux_preds.m,
    make minor rearrangements to make this possible.

compiler/hlds_module.m:
compiler/prog_foreign.m:
    Move the pred_target_names type, and two predicates that operate
    on it, from hlds_module.m to prog_foreign.m, to make it accessible
    from prog_mutable.m, which is part of the parse_tree package, and thus
    should not import anything from the hlds package.

compiler/prog_item.m:
    Move a (renamed) type here from add_mutable_aux_preds.m, since
    prog_mutable.m now needs access to it as well.

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

compiler/prog_data.m:
    Fix some old comments.
2021-05-27 22:06:33 +10:00
Zoltan Somogyi
99334e8469 Switch to structured item sequence numbers.
compiler/prog_data.m:
    Define a data type that encodes the distinction between valid
    and dummy item sequence numbers in the type. Previously, different
    parts of the compiler expressed this distinction in two different ways,
    either using "-1" to represent a dummy sequence number, or using "no"
    in a maybe(int) type.

compiler/prog_item.m:
    Use the new type instead of plain "int" as the sequence number in items.

compiler/hlds_pred.m:
    Use the new type instead of plain "int" as the sequence number
    in cur_user_decl_infos. Document the fact that the presence of a
    cur_user_decl_info in a pred_info does NOT guarantee a valid
    item sequence number.

compiler/add_foreign_proc.m:
    When adding a foreign_proc to the HLDS, pass a whole item_pragma_info,
    not its components. (This change is what this diff started as, before
    the item_seq_num changes overwhelmed it.)

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/comp_unit_interface.m:
compiler/decide_type_repn.m:
compiler/default_func_mode.m:
compiler/hlds_clauses.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/make_hlds_passes.m:
compiler/par_loop_control.m:
compiler/parse_class.m:
compiler/parse_dcg_goal.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_mutable.m:
compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_pragma_foreign.m:
compiler/parse_pragma_tabling.m:
compiler/parse_type_defn.m:
compiler/parse_type_repn.m:
compiler/parse_types.m:
compiler/proc_requests.m:
compiler/prog_mutable.m:
compiler/split_parse_tree_src.m:
compiler/stm_expand.m:
compiler/style_checks.m:
compiler/table_gen.m:
    Conform to the changes above.
2021-05-19 13:27:27 +10:00
Zoltan Somogyi
8355718b16 Allow pred pragmas to specify pred_or_func.
Pragmas that apply to a pred_info have traditionally specified that
pred_info by a symname/arity pair. However, this can be ambiguous
if there is both a predicate and a function with that symname/arity pair.
This diff therefore allows pragmas that previously took "symname/arity"
to also take "pred(symname/arity)" and "func(symname/arity").
If e.g. there is both a pred foo/2 and a func foo/2 accessible from
the current module, the old form applied to both, while the new forms
apply to just one.

Later, we could change the behavior of the old form to insist on a
unique match, but before we do, we should have a mechanism that allows
programmers to resolve the ambiguity. (They could rename either the
pred or the func, but it is less intrusive for the compiler not to
insist on that.) This is that mechanism.

In the process of implementing this change, I had to update lots of code
that dealt with arities, since one main difference between predicates
and functions is that for the latter, the user visible arity and
the internal compiler arity are different, in that the former does not
count the return value, and the latter does. The existing "arity" type
is an equivalence to int, and thus does not indicate which notion is meant.
I therefore added two notag types, user_arity and pred_form_arity,
for the two notions above respectively, and made a start on using them,
though for now, only in the code sections affected by the main change above.

compiler/prog_item.m:
    Change the types that represent the specifications of predicates
    (in the sense of pred_infos) and functions to allow the representation
    of not just "symname/arity," but also "pred(symname/arity)" and
    "func(symname/arity"). There is one exception: for the oisu (order
    independent state update) pragma, require the presence of either
    a pred() vs func() wrapper. This is not a breaking change, since oisu
    pragmas are neither publicly documented or really implemented.

    Pragmas that allow the representation of argument modes implicitly
    specify pred vs func by taking the mode list either as
    (m1, m2, ... mn) or as (m1, m2, ...) = mn. Encode this invariant
    in the representation type. Make this type also include an arity
    only in the absence of a mode list, to make unrepresentable
    any inconsistent state in which the stated arity and the length
    of the mode list disagree.

    Give the new types used for these updated representations names
    that state whether they specify a pred_info or a proc_info
    (or in one case that we should later fix, that they can specify either).

    Put the pred or func indication before the symname and arity
    both in these new types, and in some old types. Do this both because
    the pred or func indication comes before the name in Mercury declarations,
    and to help the compiler find all the places where code using the old
    forms had to be revisited and checked for any needed updates.

    Provide utility operations on the new types involved in the
    updated representations.

compiler/prog_data.m:
    Add the user_arity and pred_form_arity types, as mentioned above.

    Add a type that is mostly used in item representations, but is also
    useful elsewhere.

compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_pragma_foreign.m:
compiler/parse_pragma_tabling.m:
compiler/parse_util.m:
    Accept the pred() or func() wrappers mentioned above, and generate
    the updated representations when parsing terms containing pragmas.

compiler/parse_tree_out_pragma.m:
    Accept the updated representations of pragmas when printing them out.

compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
    Use the updated representations when adding pragmas to the HLDS.

compiler/error_util.m:
    Provide mechanisms for use above when printing references to pred_infos
    using user arities, to complement the existing mechanisms which use
    arities that they treat as pred form arities. The latter is what
    you want when generating error messages about pred_infos that
    already included functions' return types in the argument list;
    the former is what you want when generating error messages
    about user input that has not yet been subject to that treatment,
    such as a pragma that has just been read in. (The difference is
    only in what form of arity these mechanisms take as *input*;
    the output is always user arity, which after all is what users
    are interested in.)

compiler/hlds_error_util.m:
    Provide a user_arity equivalent to a piece of existing pred_form_arity
    functionality, for use by the modules above.

    Provide utility functions used when generating error messages.

compiler/fact_table.m:
    Replace most uses of the "arity" type with the "user_arity" type.
    Done mostly in the process of figuring out which kind of arity
    the top predicates took as arguments.

    Put argument lists into a sensible order.

compiler/prog_out.m:
compiler/prog_util.m:
    Add utility functionality needed above.

compiler/add_mutable_aux_preds.m:
compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/module_qual.qualify_items.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/typecheck_errors.m:
compiler/unused_args.m:
    Conform to the changes above.

compiler/hlds_pred.m:
    Add an XXX.

compiler/notes/order_indep_state_update:
    Fix typos.

tests/hard_coded/bad_direct_reuse.m:
tests/hard_coded/bad_indirect_reuse.m:
tests/hard_coded/bitmap_simple.m:
tests/hard_coded/constraint_order.m:
tests/hard_coded/equality_pred_which_requires_boxing.m:
tests/hard_coded/fact_table_test_1.m:
tests/hard_coded/float_consistency.m:
tests/hard_coded/foreign_enum_rtti.m:
tests/hard_coded/foreign_enum_switch.m:
tests/hard_coded/foreign_import_module_2.m:
tests/hard_coded/gh72.m:
tests/hard_coded/gh72a.m:
tests/hard_coded/heap_ref_mask_tag.m:
tests/hard_coded/intermod_multimode.m:
tests/hard_coded/mode_check_clauses.m:
tests/hard_coded/multimode_addr.m:
tests/hard_coded/type_spec_ho_term.m:
tests/hard_coded/user_defined_equality2.m:
    Add pred() or func() wrappers to symname/arity pairs in pragmas,
    to test whether the parser accepts them.

    Fix deviations from our current coding standards.

tests/hard_coded/oisu_check_db.m:
tests/invalid/oisu_check_add_pragma_errors.{m,err_exp}:
tests/invalid/oisu_check_semantic_errors.m:
    Add the pred() wrappers now required in oisu pragmas.
    Expect the improved wording of an error message.
2021-05-06 07:19:25 +10:00
Peter Wang
2589f360f9 Add get_ctor_arg_types predicate.
compiler/prog_data.m:
    Add get_ctor_arg_types predicate.

compiler/check_typeclass.m:
compiler/modecheck_coerce.m:
compiler/old_type_constraints.m:
    Use get_ctor_arg_types instead of similar predicates or functions.
2021-05-05 17:49:20 +10:00
Peter Wang
d1522cbcb2 Make subtypes inherit user-defined equality/comparison from base type.
Since values of a subtype are tested for equality or compared
by first converting to the base type then testing/comparing,
it means that subtypes implicitly inherited any user-defined
equality/comparison from the base type. Allowing a subtype to also
define its own equality/comparison predicates seems more confusing
than useful, so disallow it.

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

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

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

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

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

doc/reference_manual.texi:
    Document change.

tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_user_compare.exp:
tests/hard_coded/subtype_user_compare.m:
tests/hard_coded/subtype_user_compare2.m:
tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/subtype_user_compare.err_exp:
tests/invalid/subtype_user_compare.m:
    Add test cases.
2021-04-13 11:38:15 +10:00
Peter Wang
6a345ff5dc Make subtypes share low-level data representation with base type.
Make subtypes share data representation with base type when using
low-level data. High-level data grades are unchanged, so subtypes
are still represented with distinct classes from their base types.

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

compiler/prog_data.m:
    Add abstract_subtype option for type_details_abstract.

    Correct XXX comment.

compiler/prog_item.m:
    Add type item_type_repn_info_subtype.

    Add tcrepn_is_subtype_of option for type_ctor_repn_info.

compiler/equiv_type.m:
    Replace equivalences in tcrepn_is_subtype_of.

compiler/module_qual.qualify_items.m:
    Module qualify in tcrepn_is_subtype_of.

compiler/prog_type.m:
    Rename some predicates that can only work on non-subtype du types.

    Update comments.

compiler/check_parse_tree_type_defns.m:
    Classify subtype type definitions as std_mer_type_du_subtype
    instead of std_mer_type_du_all_plain_constants or
    std_mer_type_du_not_all_plain_constants.

    Update some comments.

compiler/du_type_layout.m:
    Add two sub-passes to handle subtypes.

compiler/comp_unit_interface.m:
    Extend this module to handle subtype type definitions,
    analogous to the way equivalence type definitions are handled.

    Rename some predicates to clarify that they must not be used
    to test subtypes.

    Record an abstract version of a subtype type definition using
    the abstract_subtype option in type_details_abstract.
    This allows the super type ctor of the subtype to be known,
    and hence the base type ctor, when a subtype is abstract exported.

    Update comments.

compiler/decide_type_repn.m:
    Extend this module to handle subtype type definitions.

    Generate type_representation items for subtype type definitions
    which include the super type ctor of the subtype.

compiler/parse_tree_out.m:
    Write out abstract_subtype as
    "where type_is_abstract_subtype(Name/Arity)" on type definitions.

compiler/parse_type_defn.m:
    Parse "type_is_abstract_subtype(Name/Arity)" declarations.

compiler/parse_tree_out_type_repn.m:
    Write type_representation items with "is_subtype_of(TypeCtor/Arity)".

compiler/parse_type_repn.m:
    Parse "is_subtype_of(TypeCtor/Arity)" in type_representation items.

compiler/add_type.m:
compiler/convert_parse_tree.m:
compiler/opt_debug.m:
compiler/type_util.m:
    Conform to changes.

    Update comments.

compiler/direct_arg_in_out.m:
    Delete XXX, nothing to do.

compiler/parse_util.m:
    Rename overly specific variable.

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

runtime/mercury_type_info.h:
    Add a flag in MR_TypeCtorInfo to indicate if the enum/du layout
    array may be indexed by an enum value or du ptag value.
    Subtypes break the invariant that the layout array contains entries
    for every enum/ptag value from 0 up to the maximum value.
    The presence of the flag MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE tells
    the runtime that it can directly index the layout array instead of
    searching through it (which is the common case, for non-subtypes).

    Add a field MR_du_ptag to MR_DuPtagLayout. This is necessary to find
    an entry for a given primary tag value in a MR_DuPtagLayout array.

    Add a field MR_du_ptag_flags to MR_DuPtagLayout, currently with one
    possible flag MR_DU_PTAG_FLAG_SECTAG_ALTERNATIVES_INDEXABLE.
    As with primary tags, subtypes break the invariant that the
    sectag_alternatives array contains entries for every secondary tag
    value from 0 up to the maximum value. The presence of the flag tells
    the runtime that it can directly index the sectag_alternatives array
    (which is the common case, for non-subtypes).

    The two fields added to MR_DuPtagLayout occupy space that was
    previously padding, so the size of MR_DuPtagLayout is unchanged.

    In MR_EnumFunctorDesc, replace the MR_enum_functor_ordinal field by
    MR_enum_functor_value, i.e. the integer value representing the
    functor in memory. Storing *both* the functor ordinal and enum value
    would increase the size of the MR_EnumFunctorDesc struct, and would
    be redundant in the common case of non-subtype enums (both fields
    would contain equal values). We forgo having the functor ordinal
    directly available, at the cost of needing to search through an
    MR_EnumFunctorDesc array when a functor ordinal is required for a
    subtype enum, which should be rare.

compiler/rtti.m:
    Swap enum "functor ordinal" and "value" in places.

    Use a type 'enum_value' to try to ensure we do not mix up enum
    functor ordinals and enum values.

    Add code to encode the MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE flag.

    Add code to encode the MR_DU_PTAG_FLAG_SECTAG_ALTERNATIVES_INDEXABLE
    flag.

compiler/rtti_out.m:
    Write out "enum_ordinal_ordered_tables" ordered by functor ordinals
    instead of "enum_value_ordered_tables" ordered by enum values.

    Output the enum value for MR_EnumFunctorDesc instead of functor
    ordinal.

    Output the MR_du_ptag and MR_du_ptag_flags fields for
    MR_DuPtagLayout.

    Relax sanity check on primary tags. A subtype may not necessarily
    use ptag 0, and may skip ptag values.

compiler/rtti_to_mlds.m:
    Generate "enum_ordinal_ordered_tables" instead of
    "enum_value_ordered_tables".

    Fill in the enum value for a MR_EnumFunctorDesc instead of
    the functor ordinal.

compiler/type_ctor_info.m:
    Add predicate to generate the MR_du_ptag_flags field.

    Add the MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE flag to type_ctor_infos
    when appropriate.

    Bump the type_ctor_info_rtti_version.

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

runtime/mercury_ml_expand_body.h:
    Search through an enum layout array to find the matching enum value,
    unless the array can be indexed.

    Search through a ptag layout array to find the matching ptag value,
    unless the array can be indexed.

    Search through a sectag_alternatives array to find the matching
    secondary tag value, unless the array can be indexed.

    Factor out the code to search through a foreign enum layout array
    into a separate macro.

runtime/mercury_construct.c:
runtime/mercury_construct.h:
    Add a functor_ordinal field to the MR_Construct_Info_Struct.
    This will hold the functor ordinal now that it is not available in
    MR_EnumFunctorDesc.

    Make MR_get_functors_check_range take an argument to indicate if the
    functor_ordinal field needs to be filled in properly. Most callers
    do not need the field.

library/construct.m:
    Conform to changes to MR_get_functors_check_range and
    MR_EnumFunctorDesc.

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

runtime/mercury_dotnet.cs.in:
    Modify RTTI classes for C# backend, analogous to the changes for the
    C runtime.

    Add methods to index/search through enum layout arrays, ptag layout
    arrays, and sectag_alternatives arrays.

java/runtime/DuPtagLayout.java:
java/runtime/EnumFunctorDesc.java:
java/runtime/TypeCtorInfo_Struct.java:
    Modify RTTI classes for Java backend, analogous to the changes for the
    C runtime.

    Add methods to index/search through enum layout arrays, ptag layout
    arrays, and sectag_alternatives arrays.

library/rtti_implementation.m:
    Conform to MR_EnumFunctorDesc field change.

    Index or search through the enum layout array or ptag layout array
    based on the MR_TYPE_CTOR_FLAG_LAYOUT_INDEXABLE flag.

    Index or search through the sectag_alternatives array depending on
    the MR_DU_PTAG_FLAG_SECTAG_ALTERNATIVES_INDEXABLE flag.

    Add separator lines.

    Slightly reorder some code.

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

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_pack.m:
tests/hard_coded/subtype_pack_2.m:
tests/hard_coded/subtype_pack.exp:
tests/hard_coded/subtype_rtti.m:
tests/hard_coded/subtype_rtti.exp:
tests/hard_coded/subtype_rtti.exp2:
    Add test cases.
2021-04-09 17:36:38 +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
Peter Wang
74a31ba8ef Parse and check subtype definitions.
This is the first step towards implementing a subtypes feature.
It introduces type definitions of the form

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

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

doc/reference_manual.texi:
    Add documentation for subtypes.

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

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

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

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

    Add comment for future work.

compiler/parse_type_defn.m:
    Parse subtype definitions.

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

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

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

compiler/add_type.m:
    Rename add_du_ctors_check_foreign_type_for_cur_backend to
    add_du_ctors_check_subtype_check_foreign_type.

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

compiler/make_hlds_passes.m:
    Conform to previous renaming.

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

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

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

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

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

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

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

    Add comments for future work.

tests/invalid/Mmakefile:
tests/invalid/subtype_abstract.err_exp:
tests/invalid/subtype_abstract.m:
tests/invalid/subtype_circular.err_exp:
tests/invalid/subtype_circular.m:
tests/invalid/subtype_ctor_arg.err_exp:
tests/invalid/subtype_ctor_arg.m:
tests/invalid/subtype_eqv.err_exp:
tests/invalid/subtype_eqv.m:
tests/invalid/subtype_exist_constraints.err_exp:
tests/invalid/subtype_exist_constraints.m:
tests/invalid/subtype_exist_vars.err_exp:
tests/invalid/subtype_exist_vars.m:
tests/invalid/subtype_foreign.err_exp:
tests/invalid/subtype_foreign.m:
tests/invalid/subtype_foreign_supertype.err_exp:
tests/invalid/subtype_foreign_supertype.m:
tests/invalid/subtype_foreign_supertype2.err_exp:
tests/invalid/subtype_foreign_supertype2.err_exp2:
tests/invalid/subtype_foreign_supertype2.m:
tests/invalid/subtype_ho.err_exp:
tests/invalid/subtype_ho.m:
tests/invalid/subtype_invalid_supertype.err_exp:
tests/invalid/subtype_invalid_supertype.m:
tests/invalid/subtype_not_subset.err_exp:
tests/invalid/subtype_not_subset.m:
tests/invalid/subtype_syntax.err_exp:
tests/invalid/subtype_syntax.m:
tests/invalid_submodules/Mercury.options:
tests/invalid_submodules/Mmakefile:
tests/invalid_submodules/subtype_submodule.err_exp:
tests/invalid_submodules/subtype_submodule.m:
tests/valid/Mmakefile:
tests/valid/subtype_basic.m:
    Add test cases.
2021-03-15 11:16:31 +11:00
Zoltan Somogyi
5ec405ac0a Add an XXX about tuple_cons cons_ids.
compiler/prog_data.m:
    As above.

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

compiler/error_msg_inst.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/mode_errors.m:
compiler/parse_tree_out_inst.m:
compiler/prog_ctgc.m:
    Pass the language (debug or not) to mercury_to_mercury.m
    when printing cons_ids.
2021-02-26 20:40:23 +11:00
Zoltan Somogyi
a19a5f0267 Delete the Erlang backend from the compiler.
compiler/elds.m:
compiler/elds_to_erlang.m:
compiler/erl_backend.m:
compiler/erl_call_gen.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/erl_rtti.m:
compiler/erl_unify_gen.m:
compiler/erlang_rtti.m:
compiler/mercury_compile_erl_back_end.m:
    Delete these modules, which together constitute the Erlang backend.

compiler/notes/compiler_design.html:
    Delete references to the deleted modules.

compiler/parse_tree_out_type_repn.m:
    Update the format we use to represent the sets of foreign_type and
    foreign_enum declarations for a type as part of its item_type_repn_info,
    now that Erlang is no longer a target language.

compiler/parse_type_repn.m:
    Accept both the updated version of the item_type_repn_info and the
    immediately previous version, since the installed compiler will
    initially generate that previous version. However, stop accepting
    an even older version that we stopped generating several months ago.

compiler/parse_pragma_foreign.m:
    When the compiler finds a reference to Erlang as a foreign language,
    add a message about support for Erlang being discontinued to the error
    message.

    Make the code parsing foreign_decls handle the term containing
    the foreign language the same way as the codes parsing foreign
    codes, procs, types and enums.

    Add a mechanism to help parse_mutable.m to do the same.

compiler/parse_mutable.m:
    When the compiler finds a reference to Erlang as a foreign language,
    print an error message about support for Erlang being discontinued.

compiler/compute_grade.m:
    When the compiler finds a reference to Erlang as a grade component,
    print an informational message about support for Erlang being discontinued.

compiler/pickle.m:
compiler/make.build.m:
    Delete Erlang foreign procs and types.

compiler/add_foreign_enum.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_type.m:
compiler/check_libgrades.m:
compiler/check_parse_tree_type_defns.m:
compiler/code_gen.m:
compiler/compile_target_code.m:
compiler/compute_grade.m:
compiler/const_struct.m:
compiler/convert_parse_tree.m:
compiler/dead_proc_elim.m:
compiler/decide_type_repn.m:
compiler/deps_map.m:
compiler/du_type_layout.m:
compiler/export.m:
compiler/foreign.m:
compiler/globals.m:
compiler/granularity.m:
compiler/handle_options.m:
compiler/hlds_code_util.m:
compiler/hlds_data.m:
compiler/hlds_module.m:
compiler/inlining.m:
compiler/int_emu.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/lco.m:
compiler/llds_out_file.m:
compiler/make.dependencies.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/make_hlds_separate_items.m:
compiler/make_hlds_warn.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/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_target_util.m:
compiler/ml_top_gen.m:
compiler/mlds.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_export.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_cs_export.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_export.m:
compiler/mlds_to_java_file.m:
compiler/mlds_to_java_type.m:
compiler/module_imports.m:
compiler/parse_pragma_foreign.m:
compiler/parse_tree_out.m:
compiler/polymorphism.m:
compiler/pragma_c_gen.m:
compiler/prog_data.m:
compiler/prog_data_foreign.m:
compiler/prog_foreign.m:
compiler/prog_item.m:
compiler/simplify_goal_scope.m:
compiler/special_pred.m:
compiler/string_encoding.m:
compiler/top_level.m:
compiler/uint_emu.m:
compiler/write_deps_file.m:
    Remove references to Erlang as a backend or as a target language.

tests/invalid/bad_foreign_code.{m,err_exp}:
tests/invalid/bad_foreign_decl.{m,err_exp}:
tests/invalid/bad_foreign_enum.{m,err_exp}:
tests/invalid/bad_foreign_export.{m,err_exp}:
tests/invalid/bad_foreign_export_enum.{m,err_exp}:
tests/invalid/bad_foreign_import_module.{m,err_exp}:
tests/invalid/bad_foreign_proc.{m,err_exp}:
tests/invalid/bad_foreign_type.{m,err_exp}:
    Add a test for Erlang as an invalid foreign language. Expect both the
    new error message for this new error, and the updated list of now-valid
    foreign languages on all errors.
2020-10-29 13:24:49 +11:00
Zoltan Somogyi
9cbe5d2caf Put type_repn items for complex types into .int files.
compiler/decide_type_repn.m:
    Previously, this module computed type_repn items to put into .int3 files
    for a subset of the type constructors defined in the current module:
    the direct_dummy, enum and notag types (the *simple* types),
    and the du types whose representation is guaranteed to be
    a word-aligned pointer when targeting C. (We care about pointers
    being word-aligned only when applying the direct arg optimization.
    This optimization is applicable only with the low level data
    representation, which we use only when targeting C.)

    This diff adds code to decide the representations of *all* the
    type constructors defined in the current module.

    This code is based on the existing code in du_type_layout.m,
    which it is intended to eventually replace, but its job is more general,
    because it decides the representation of each type not just for
    one platform (the one we want to generate code), but for all possible
    platforms. This is because we want to put the descriptions of type
    representations into the module's .int file to serve as a single source
    of truth for all modules that use the types defined in this module,
    and the contents of .int files should be platform-independent.
    For our purposes, there are six kinds of platforms, which are
    distinguished along three axes: 64 vs 32 bit machines, spf vs non-spf
    grades, and direct arg optimization enabled vs disabled. That is eight
    combinations, but on 64 bit machines, a float takes up one word whether
    that float is single or double precision, so two combinations aren't valid.

    Some of the change to this module consists of generalizing the existing
    code so that it can decide simple types not just when targeting .int3 files
    but .int files as well. However, the bulk of it is code for deciding
    the representations of non-simple types. The code is not lifted straight
    from du_type_layout.m. There are two main kinds of changes.

    First, I took the opportunity to simplify the algorithms used.
    For example, while du_type_layout.m passes over each function symbol
    in the most general kind of type twice: once to assign it a cons_tag,
    and once to decide how to pack its arguments, the code here does both jobs
    in one pass. Another example is that for historical reasons,
    du_type_layout.m computed the amount of space needed for an argument
    in one place for sub-word-sized arguments, and in another place
    for more-than-word-sized arguments; decide_type_repn.m does it all
    in one place.

    Second, since we compute a representation for each type six times,
    I tried to avoid obvious inefficiencies, but only if the code
    remained simple. In the future, we may want to use an approach
    based on the idea that in the process of computing the first
    representation, we look out for any indication that the representation
    may be different on any of the other five platforms, and if not,
    we just reuse the first representation on the other five platforms as well.
    However, that would be appropriate only *after* we have a simpler
    system that has proven to work in practice.

    There is a third, smaller change: when deciding whether an argument
    is packable, we take into account not just equivalence type
    definitions, but the definitions of notag types as well.
    This takes advantage of the fact that if a notag type is abstract
    exported, its representation is put into the relevant .int3 file
    even though its definition isn't. (This is why du_type_layout.m
    couldn't "see through" notag types: it couldn't depend on knowing
    which types were notags.)

compiler/prog_item.m:
    Change the types we use for type representation information.
    Their previous definitions baked in the assumption that the only
    distinction between platforms that mattered was the 64 vs 32 bit
    distinction, which is not the case.

    Use a more consistent naming scheme for the types we use
    to represent type representation information.

    Include the "dereferenced" types of the arguments in functors'
    representations. (I use "dereferencing" here to mean expanding
    equivalence types and throwing away any notag wrappers.).
    We don't need it when generating C code using the low level
    data representation, but we do need it to create constructors
    when generating e.g. Java code that uses the high level data
    representation.

compiler/parse_type_repn.m:
    Rewrite most of this module due to the changes in prog_item.m.

compiler/parse_tree_out_type_repn.m:
    A new module containing the code for writing out type representations.
    The original code used to be in parse_tree_out.m, but it has been
    mostly rewritten. Partly this is due the changes in prog_item.m,
    but partly it is to provide much more structured output for humans,
    since this makes debugging so much easier.

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

compiler/parse_tree_out.m:
    Delete the code moved to parse_tree_out_type_repn.m.

compiler/parse_tree_out_info.m:
    Provide a mechanism for selecting between output for machines
    (the default) and output for humans.

compiler/hlds_data.m:
compiler/prog_data.m:
    Move the ptag type from hlds_data.m to prog_data.m, to make it
    accessible in prog_item.m.

    Add some documentation in prog_data.m.

compiler/comp_unit_interface.m:
    If the experiment1 option is enabled, invoke decide_type_repn.m
    to decide what type_repn items to put into the .int file we are
    generating. Otherwise, maintain the status quo.

compiler/write_module_interface_files.m:
    Pass the globals to comp_unit_interface.m so it can look up experiment1.

compiler/equiv_type.m:
    Add a predicate for expanding equivalence types for use by
    decide_type_repn.m. This predicate expands just one type,
    but reports any use of circular equivalence types in that type.

    Improve the error message for circular equivalence types by *naming*
    the type constructors involved. To make this possible, pass around
    sets of such type constructors instead of just a boolean saying
    *whether* we have found *some* circular equivalence type.

    Replace bools used as changed/unchanged flag with a bespoke type.

    Standardize some variable names.

compiler/options.m:
    Add the developer-only option --pack-everything, which, if set,
    tells decide_type_repn.m to turn on all the packing options
    that currently work. This is to allow the testing of decide_type_repn.m
    in the eventual intended mode of operation, even if the various
    allow-packing-... options used by du_type_layout.m are set to "no".

compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/llds_out_data.m:
compiler/lookup_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/mlds_to_c_data.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/tag_switch.m:
    Conform to the changes above (mostly the move of ptag to prog_data.m.)

compiler/parse_pragma.m:
    Improve indentation.

tests/valid_make_int/test_repn.m:
tests/valid_make_int/test_repn_sub.m:
    A fairly comprehensive test case of the new functionality.
    test_repn_sub.m defines one ore more simple type constructors
    of each possible kind, and test_repn.m uses them to define types
    that use each possible kind of complex type representation.

tests/valid_make_int/Mmakefile:
tests/valid_make_int/Mercury.options:
    Enable the new test case.
2020-05-28 07:41:44 +10:00
Julien Fischer
4f696d49b9 Fix comments.
compiler/superhomogeneous.m:
    Add a missing word.

    Fix typos.

compiler/prog_data.m:
    Fix spelling and doubled-up words.
2020-04-15 17:02:51 +10:00
Zoltan Somogyi
9a909ddc7f Avoid misleading occurs check warnings.
compiler/superhomogeneous.m:
    Record a unification between X and f(Yi) as possibly leading to
    an occurs check warning only if f is known to be a data constructor,
    either user defined or the builtin tuple constructor.

compiler/hlds_cons.m:
    Add a version of the search_cons_table predicate that does not construct
    the list of hlds_cons_defns that match the given cons_id. The new code
    in superhomogeneous.m needs to know whether a cons_id is a known data
    constructor, but it does not need to know its matching definitions,
    and constructing that list is reasonably expensive when it has to be
    executed for every single function symbol in every clause.

    Add some documentation of the existing predicates, and separate their
    implementations from each other with lines.

tests/warnings/occurs.{m,exp}:
    Extend this test case both with a unifications we should warn about
    (a circular unification whose top level cons_id is a tuple constructor)
    and one we should not warn about (when the cons_is is NOT a data
    constructor of any kind).

compiler/implementation_defined_literals.m:
compiler/prog_data.m:
    Clarify related documentation.
2020-04-15 02:57:16 +10:00
Zoltan Somogyi
5a6c4502f6 Document some problems with writing out parse trees. 2020-03-27 17:41:28 +11:00
Zoltan Somogyi
79e8804db9 Fix "this disjunct can't have solutions" warnings in multimode preds.
This fixes github issue #85.

A complication is that the compiler itself has code, in make.util.m,
in which a disjunct has no solutions in only one mode of a two mode
function, but in this case, the code works (though its programming style
is pretty bad), so to get this change to bootstrap, we also need
a way to disable the "this disjunct can't have solutions" warning
in a scope.

compiler/simplify_goal_disj.m:
    When we generate a "this disjunct can't succeed" warning,
    do not insist on all modes generating that warning.
    We used to insist on that because in a multi-mode predicate,
    such warnings can be inappropriate for other modes.
    Instead, achieve the same objective of minimizing programmer
    confusion by adding a codicil explicitly mentioninging
    this possibility.

    Make the generation of this warning conditional on a simplify task
    that can be disabled by "disable_warnings" scope.

compiler/prog_data.m:
    Add "no_solution_disjunct" as a warning kind that may be disabled.

compiler/parse_goal.m:
    Parse the new kind of warning.

compiler/prog_out.m:
    Output the new kind of warning.

    Improve some adjacent though unrelated code.

compiler/make.util.m:
    Add code disable this warning in the affected predicate.
    Comment out this code until installed compilers know how
    to parse it and understand it.

compiler/Mercury.options:
    Don't turn warnings into errors for make.util.m until then.

compiler/simplify_goal_scope.m:
compiler/simplify_info.m:
compiler/simplify_tasks.m:
    Provide the mechanism needed to make it possible to disable
    warnings about no solution disjuncts.

doc/reference_manual.texi:
    Document the new disable-able warning.

NEWS:
    Document both the changed behavior of the old warning
    and the new way to disable it.

tests/warnings/gh85.{m,exp}:
    A regression test for the bug, based on the code in the
    github issue. It also tests the way to disable the warning.

tests/warnings/Mmakefile:
    Enable the new test case.
2020-03-24 15:20:59 +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
5c52cf0cde Standardize on "sym_name_arity" ...
... replacing "sym_name_AND_arity".
2020-03-15 19:37:18 +11:00
Zoltan Somogyi
c5a65723c3 Replace {inst,mode}_id with {inst,mode}_ctor ...
.. since these two types play the same role for insts and modes respectively
as type_ctors do for types.

compiler/prog_data.m:
    As above.

compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/equiv_type.m:
compiler/hlds_defns.m:
compiler/hlds_inst_mode.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/inst_user.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/prog_mode.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
compiler/unused_imports.m:
    Conform to the above changes.
2020-03-15 11:45:04 +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
Zoltan Somogyi
36c2000516 Add the one_or_more and one_or_more_map modules to the library.
library/one_or_more.m:
    We used to have a type named one_or_more in the list module representing
    nonempty lists. It had literally just two predicates and two functions
    defined on it, three of which did conversions to and from lists, which
    limited their usefulness.

    This new module is the new home of the one_or_more type, together with
    a vastly expanded set of utility predicates and functions. Specifically,
    it implements every operation in list.m which makes sense for nonempty
    lists.

library/list.m:
    Delete the code moved over to one_or_more.m.

library/one_or_more_map.m:
    This new module is a near copy of multi_map.m, with the difference being
    that while the multi_map type defined in multi_map.m maps each key
    to a list(V) of values (a list that happens to always be nonempty),
    the one_or_more_map type defined in one_or_more_map.m maps each key
    to a one_or_more(V) of values (which enforces the presence of at least
    one value for each key in the type).

library/map.m:
    Mention the existence of one_or_more_map.m as well as multi_map.m.

library/MODULES_DOC:
library/library.m:
    List the new modules as belonging to the standard library.

NEWS:
    Mention the new modules, and the non-backwards-compatible changes to
    list.m.

compiler/*.m:
    Import the one_or_more module when needed.

tests/hard_coded/test_one_or_more_chunk.{m,exp}:
    Test the one predicate in one_or_more.m that is non-trivially different
    from the corresponding predicate in list.m: the chunk predicate.

tests/hard_coded/Mmakefile:
    Enable the new test case.
2020-02-28 14:29:05 +11:00
Zoltan Somogyi
48305bcb62 Add a missing word. 2020-01-12 16:21:25 +11:00
Zoltan Somogyi
2c2fc0daf8 Document the non-obvious complexity of insts. 2020-01-11 18:09:02 +11:00
Zoltan Somogyi
fbcd431d36 Decide simple representations using checked type definitions.
compiler/check_parse_tree_type_defns.m:
    Change the definition of a checked type to distinguish direct_dummy
    and enum types on the one hand, which may have foreign enum definitions,
    from other du types, which may not.

    Change the definition of a checked type to record the names of the
    function symbols in direct_dummy and enum types, since type representation
    items need this information, we have it, and requiring decide_type_repn.m
    to compute it again from scratch is wasteful.

    Do not explicitly record the number of function symbols in direct_dummy
    % and enum types, and the number bits needed to represent values of
    such types. We now store the list of function symbols in such types,
    and this information is trivially computable from that.

    Check foreign enum definitions for correctness. At the moment,
    this sort-of duplicates related functionality in add_foreign_enum.m,
    but the intention is that eventually, these checks will be done only here,
    with the sort-of duplicated code in add_foreign_enum.m being deleted there.

compiler/prog_item.m:
    Change the data structures we use to record type representation information
    in items to encode all the invariants that the updated checked type
    definition map encodes. This should allow code that reads such items
    from interface files to avoid having to check for violations of those
    invariants.

    Document the relationship between checked type definitions and
    type representation items, including why neither can subsume the other.

compiler/decide_type_repn.m:
    Rewrite this module almost completely. The old version gathered up
    all the type and enum definitions for each type constructor, and then
    did a limited, purpose-specific job of checking their consistency,
    before using the information in them to decide on the representations
    of simple types. The new version takes a checked type definition map
    as input, and so its task is limited to deciding type representations.

    The switch has two main benefits.

    - The consistency checks we now do in check_parse_tree_type_defns.m
      can replace not just the consistency checks we used to do in
      decide_type_repn.m, but in the future, it can also replace
      the consistency checks we now do in add_type.m and add_foreign_enum.m.
      Having a *consistent* set of consistency checks is a good idea,
      even though it is a bit too meta :-)

    - The consistency checks in check_parse_tree_type_defns.m
      are significantly more thorough than both the ones in the version
      of decide_type_repn.m, and the current version distributed through
      add_type.m and add_foreign_enum.m.

    The changes in check_parse_tree_type_defns.m and prog_item.m to bring
    the two representations as close together as possible should significantly
    simplify the code we will need to add to decide_type_repn.m to decide
    the representations of complex types.

compiler/comp_unit_interface.m:
    Pass the checked type definition map to decide_type_repn.m.

compiler/parse_type_repn.m:
    Parse the updated type representations.

compiler/parse_tree_out.m:
    Output the updated type representations.

compiler/du_type_layout.m:
compiler/prog_data.m:
    Move a predicate from du_type_layout.m to prog_data.m (split into
    two predicates), since decide_type_repn.m now wants access to its
    functionality as well.

compiler/prog_type.m:
    Export a utility predicate.

compiler/add_foreign_enum.m:
    Export some functionality to check_parse_tree_type_defns.m.
    That functionality should in fact be moved to check_parse_tree_type_defns,
    but that would make this diff harder to review, so that will be done later
    in a separate commit.

compiler/equiv_type.m:
compiler/module_qual.qualify_items.m:
    Conform to the changes above.

compiler/Mercury.options:
    Specify --warn-dead-preds for the modules touched by this change.
    Since several of them had large parts replaced by new code, this was
    needed to catch left-over parts of their old and now obsolete contents.
2019-10-26 19:30:07 +11:00
Zoltan Somogyi
52b3fc68a2 Warn about occurs check violations in parse trees.
Until now, we have generated warnings about occurs check violations
in the HLDS. Since the HLDS is in superhomogeneous form, this means
we warn for X = f(X), but not for Xs = [X1, X2 | Xs]. The reason is
that the latter expands to Xs = [X1 | Xs1], Xs1 = [X2 | Xs],
and neither of those two unifications fails the occurs check by itself.

This diff switches to having that warning be generated during the creation
of the HLDS, by code that works on the original parse tree. That means
we can now generate warnings for code such as Xs = [X1, X2 | Xs].

NEWS:
    Mention that fact.

compiler/superhomogeneous.m:
    While expanding terms into superhomogeneous form, keep track
    of which variables have been unified with a term *or an ancestor
    of that term*. In the case above, we know that Xs1 is *part of* Xs,
    so unifying it with [X2 | Xs] is an occurs check violation.

    Conditionally generate a warning for such violations. This is only
    a warning, because in the parse tree, function symbols can be not just
    data constructors but also function applications, and we can't
    say which is which. While X = f(X) is a real problem if f is
    a data constructor, it may be perfectly ok code (a test for a
    fixpoint) if f is a function.

compiler/modecheck_unify.m:
    Disable the HLDS version of this warning, to avoid warning
    about the problem twice. (This diff leaves the infrastructure
    supporting the HLDS warning remains in place, in case we want
    to enable it again.)

compiler/options.m:
    Add the new warning option that the new warning is conditional on.

compiler/prog_data.m:
    Add the new warning to the list of warnings that may be disabled
    by a disable_warnings scope.

    Change code to avoid the new warning.

compiler/goal_expr_to_goal.m:
    Disable the new warning in goals inside a disable_warnings scope
    that asks for it to be disabled.

compiler/parse_goal.m:
    Parse the new warning in disable_warnings scopes.

compiler/prog_out.m:
    Output the new warning in disable_warnings scopes.

compiler/simplify_goal_scope.m:
    Ignore the new warning in disable_warnings scopes, since it is not
    for use here.

library/term_to_xml.m:
    Change code to avoid the new warning.

doc/reference_manual.texi:
doc/user_guide.texi:
    Document the new warning option, and the means of suppressing the
    warning using a disable_warnings scope.

tests/invalid/ambiguous_overloading_error.err_exp:
tests/invalid/max_error_line_width.err_exp:
tests/invalid/occurs.err_exp:
tests/warnings/unify_x_f_x.exp:
    Update these expected outputs to expect the new warning,
    and (in some cases) not to expect its HLDS version.

tests/warnings/occurs.{m,exp}:
    A new test case to test not just the warning (the tests above do that
    already) but also its suppression.

tests/warnings/Mmakefile:
    Enable the new test case.
2019-10-03 10:13:57 +10:00
Zoltan Somogyi
d113e2f206 Use similar foreign type representations for parse_tree and HLDS.
The parse tree need to represent foreign_type pragmas without knowing which
foreign language it is for, while the HLDS wants to represent all the
foreign_type pragmas for a given type constructor for all foreign languages.
They used to use separate types to do this. This diff eliminates as much
of this difference as possible.

compiler/prog_data.m:
    Generalize the type (type_details_foreign) we use to represent the
    information content of foreign type pragma. Document the use of
    this type both in the parse tree (the generic version) and in the HLDS
    (versions specific to each foreign language).

compiler/hlds_data.m:
    Use instances of the newly generalized type_details_foreign type
    instead of a separate type.

compiler/add_type.m:
compiler/dead_proc_elim.m:
compiler/du_type_layout.m:
compiler/foreign.m:
compiler/intermod.m:
compiler/mlds.m:
compiler/mlds_to_java_type.m:
compiler/parse_pragma.m:
compiler/pragma_c_gen.m:
compiler/prog_foreign.m:
2019-09-10 21:53:09 +10:00
Zoltan Somogyi
7430f64d20 Address review comments. 2019-09-02 11:59:37 +10:00
Zoltan Somogyi
315c7758a4 Add all predicates via item_pred_decl_infos.
compiler/add_pred.m:
    Don't export the predicate that used to allow other parts of the compiler
    to create new predicates without constructing a new item_pred_decl_info.
    In fact, inline this predicate in its only caller.

    Base decisions about what predicates are exported based on the predicate
    status, which is always there, not on an optionally supplied
    item_mercury_status.

    Standardize some variable names.

compiler/prog_item.m:
    Since the change to add_pred.m does not allow other compiler modules
    to specify a pred_origin for the new predicate *directly*, make it
    possible for them to specify it *indirectly*. This centralises handling
    of the implications of the origins of new compiler-generated predicates
    in one place in add_pred.m.

    Delete the maybe_allow_export attribute from items. It had no meaningful
    semantics, so there was no correct way to fill in that field.

compiler/prog_data.m:
    Move the definitions of the types that describe the auxiliary predicates
    used by solver types and tabling here from hlds_pred.m, since prog_item.m
    now needs access to them.

compiler/hlds_pred.m:
    Delete the type definitions moved to prog_data.m.

    Add three new kinds of origins for predicates, which we have previously
    ignored.

compiler/add_class.m:
compiler/add_foreign_proc.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_solver.m:
    Change the code that adds new predicates to the HLDS to conform
    to the changes above.

compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/layout_out.m:
compiler/make_hlds_passes.m:
compiler/mode_errors.m:
compiler/polymorphism.m:
compiler/prog_mutable.m:
compiler/trace_params.m:
    Conform to the changes above.
2019-09-02 00:45:45 +10:00
Zoltan Somogyi
a39adc549d Centralize decisions about which aux preds a mutable needs.
The implementation of a mutable requires several predicates, some user visible,
some not. Exactly what set of predicates a mutable needs depends both on its
attributes and on the target platform. Previously, we computed that set of
predicates three times:

- when adding their declarations to the HLDS,
- when adding their definitions to the HLDS, and
- when adding (a subset of) their declarations to a .int0 file.

This diff tries to centralizes these decisions in one place. It does not
quite get there, because getting there would require compromises that are
undesirable for other reasons, but it gets close.

compiler/prog_data.m:
    Document the uses of the various kinds of predicates we can generate
    for a mutable.

compiler/prog_mutable.m:
    Add a predicate that decides which public auxiliary predicates
    a mutable needs, for use by both add_mutable_aux_preds.m and by
    comp_unit_interface.m.

    Add a predicate that constructs the pred_decl item of any given
    mutable auxiliary predicate, again for use by add_mutable_aux_preds.m
    and by comp_unit_interface.m.

    Move predicates that are used only by add_mutable_aux_preds.m
    to add_mutable_aux_preds.m.

    Delete predicates that are no longer needed.

compiler/add_mutable_aux_preds.m:
    Add a predicate that decides which private auxiliary predicates
    a mutable needs,

    Use the new mechanisms above to declare a mutable's auxiliary procedures.

    Use the new mechanisms above to define a mutable's auxiliary procedures,
    mostly. There is still some code that repeats the logic of the decision
    predicate for public auxiliary predicates, but now a sanity check
    ensures that the two decision procedures arrived at the same result.

    Move predicates that are used only by add_mutable_aux_preds.m
    here from prog_mutable.m.

    Delete predicates that are no longer needed.

    Give several predicates more descriptive names. Standardize
    argument orders.

compiler/add_pred.m:
    Add a mechanism for adding a pred_decl item as a whole to the HLDS.
    (Previously, we could a pred_decl to the HLDS by first breaking it down
    to its components.) The code is mostly copied from make_hlds_passes.m.

compiler/comp_unit_interface.m:
    Use the new mechanisms above to declare a mutable's auxiliary procedures.
    The new code does not need any knowledge of what auxiliary predicates
    a mutable needs.

compiler/make_hlds_passes.m:
    Use the new mechanism in add_pred.m, in order to avoid code duplication.

library/set.m:
    Add a new predicate for add_mutable_aux_preds.m.
2019-09-01 18:22:06 +10:00
Zoltan Somogyi
ce65f6b2aa Fix more issues reported by --warn-inconsistent-pred-order-clauses.
compiler/assertion.m:
compiler/clause_to_proc.m:
compiler/compute_grade.m:
compiler/const_struct.m:
compiler/export.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_out_mode.m:
compiler/hlds_promise.m:
compiler/lambda.m:
compiler/lp_rational.m:
compiler/make_goal.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_type_gen.m:
compiler/name_mangle.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_name.m:
compiler/passes_aux.m:
compiler/polyhedron.m:
compiler/pred_table.m:
compiler/process_util.m:
compiler/prog_data.m:
compiler/prog_data_foreign.m:
compiler/prog_mutable.m:
compiler/rat.m:
compiler/recompilation.m:
compiler/source_file_map.m:
compiler/timestamp.m:
compiler/trace_params.m:
compiler/write_deps_file.m:
    As above.

compiler/Mercury.options:
    Don't pass --no-warn-inconsistent-pred-order-clauses for the above modules.
2019-08-23 20:54:27 +10:00
Zoltan Somogyi
df95d9a0c6 Fix a typo, and add an XXX. 2019-07-16 10:21:46 +02:00
Zoltan Somogyi
ebd551ce90 Establish and document an invariant.
compiler/parse_type_defn.m:
    When reading in a data constructor with no arguments, generate an
    error message if that data constructor nevertheless has some
    existential type constraints. Since the constructor has no arguments,
    its (empty) argument list has no type variables that may be constrained.

    We already depend on this invariant, but never generated an explicit
    error message when reading in type definitions that violate it.

compiler/hlds_cons.m:
compiler/hlds_data.m:
compiler/prog_data.m:
    Document this invariant.
2019-05-31 13:45:24 +02:00
Zoltan Somogyi
26c596186e Move an XXX about a type to the place of its definition. 2019-05-30 12:25:21 +02:00
Zoltan Somogyi
0b60daa112 Record the origin of mutable aux predicates.
compiler/prog_item.m:
    If a predicate declaration is created for an auxiliary predicate
    for an operation on a mutable, add slots for recording the details
    of the item's origin.

compiler/hlds_pred.m:
compiler/prog_data.m:
    Move the mutable_pred_kind type from hlds_pred.m to prog_data.m
    to make the above possible.

compiler/prog_mutable.m:
    Fill the slots added to prog_item.m for some kinds of mutable
    aux predicates.

compiler/add_mutable_aux_preds.m:
    Fill the slots added to prog_item.m for the other kinds of mutable
    aux predicates.

    Fix an old typo: record a mutable's init predicate as its init predicate,
    not as its pre-init predicate.

compiler/make_hlds_passes.m:
    Use the new info in predicate declaration items to create an accurate
    predicate origin for mutable aux predicates.

compiler/dead_proc_elim.m:
    Conform to the change above.
2019-05-30 12:13:54 +02:00
Zoltan Somogyi
e9430b115a Prep for recording simple type representations in .int3 files.
compiler/decide_type_repn.m:
    New module for computing the set of type representation items
    to put into the interface files of a module. For now, it generates
    this information only for .int3 files.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Add the new module to the parse_tree package.

compiler/comp_unit_interface.m:
    Invoke the new module to add type representation items to .int3 files
    if the experiment option has the right value. Give it the information
    it needs to do its job.

compiler/add_foreign_enum.m:
    Export a predicate for use by decide_type_repn.m. Maybe eventually
    it should be *moved* to decide_type_repn.m.

compiler/hlds_data.m:
compiler/prog_data.m:
    Change the representation of lists of constructors in a type
    from lists, which can be empty, with one_or_more, which cannot.
    This encodes the invariant that a type constructor cannot have
    zero data constructors in the structure of the type.

compiler/prog_item.m:
    Change the representation of lists of constructors in a type
    from lists, which can be empty, with one_or_more, which cannot.
    This encodes the invariant that a type constructor cannot have
    zero data constructors in the structure of the type.

    Include information about assertions in type representation items
    about foreign types.

    Do not record whether a type whose representation item says its values
    are guaranteed to be word aligned is a Mercury type or a foreign type.
    We generate such items only for Mercury types; for foreign types,
    their assertions will contain that information. We need this separation
    because when we generate .int3 files, we don't the backend that we will
    eventually generate code for, and thus do not know whether a given
    foreign type declaration is in effect on that backend or not.

compiler/parse_tree_out.m:
    Fix the printing of type representation items.

compiler/prog_type.m:
    Conform to the changes above, and delete an unused predicate.

compiler/parse_type_repn.m:
    Factor out some common code.

    Fix an old bug about yes/no vs du_repn/no_du_repn.

    Conform to the changes above.

compiler/parse_pragma.m:
    Export a predicate for parse_type_repn.m.

    Note a possible improvement.

    Conform to the changes above.

compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_type_defn.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_util.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.

compiler/simplify_goal_ite.m:
    Add a comment.

compiler/canonicalize_interface.m:
compiler/get_dependencies.m:
    Do not abort when seeing type representation items.

compiler/mmakefiles.m:
    Delete a predicate that this diff adds to list.m.

library/list.m:
    Add new predicates to convert from one_or_more to list
    and vice versa.

NEWS:
    Announce the new predicates.

library/bimap.m:
library/map.m:
library/tree234.m:
    Expand a comment.
2019-05-27 11:45:10 +02:00