Commit Graph

127 Commits

Author SHA1 Message Date
Zoltan Somogyi
f355497087 Delete include context maps from parse_tree_int[012].
compiler/prog_item.m:
    We used to record information about include declarations
    in parse_tree_int[012] in two forms:

    - as a pair of maps from module names to contexts (one each for
      includes in the interface and implementation sections), and
    - as a single map from module names to an include_module_info, which
      recorded the section of its appearance along with its context.

    The second of these data structures is derived from the first,
    in a process that can result in the generation of diagnostic messages.
    In the absence of any issues reported by these diagnostics, the two forms
    contain the same information.

    Avoid this redundancy by keeping only the second form in the parse trees
    of .int0, .int and .int2 files. (.int3 files cannot contain include_module
    declarations.)

    Since .int2 files may contain include_module declarations only in
    the interface section, change the representation of the second form
    to a type that expresses this invariant: int_include_module_map,
    which is a subtype of the existing type include_module_map.

compiler/comp_unit_interface.m:
compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/parse_tree_out.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the change above.

compiler/item_util.m:
    Add a utility predicate for use by new code above.
2023-01-22 19:01:42 +11:00
Zoltan Somogyi
5ae7d25740 Delete import/use context maps from parse_tree_int[012].
compiler/prog_item.m:
    We used to record information about import and use declarations
    in parse_tree_int[012] in two forms:

    - as a quartet of maps from module names to contexts (one each for
      int imports, int uses, imp imports and imp uses), and
    - as a single map from module names to a section_import_and_or_use,
      which recorded the section and kind (import or use) of its appearance
      along with its one context, except for the case of modules that have
      an use_module declaration in the interface section and an import_module
      declaration in the implementation section.

    The second of these data structures is derived from the first,
    in a process that can result in the generation of diagnostic messages.
    In the absence of any issues reported by these diagnostics, the two forms
    contain the same information.

    Avoid this redundancy by keeping only the second form in the parse trees
    of .int0, .int and .int2 files. (For .int3 files, which can contain
    only import_modules, and only in the interface section, this redundancy
    has not been present even before now.)

    Since .int and .int2 files may contain only use_module declarations
    and not import_module declarations, change the representation of the
    second form to a type that expresses this invariant: the new type
    section_use_map, which is a subtype of the existing type
    section_import_and_or_use_map.

    For .int2 files, we could use an even tighter type right now, but
    a fix for Mantis bug #563 would have to undo such a change, so
    don't bother.

compiler/comp_unit_interface.m:
    Delete the code that used to construct the first form above
    for these interface file kinds. Conform to the changes above.

compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/parse_tree_out.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the changes above.

compiler/item_util.m:
    Add new, specialized versions of existing utility predicates
    to make that conformance possible.
2023-01-21 21:31:00 +11:00
Zoltan Somogyi
faf9ebf5e3 Don't provide for implicit imports in .intN parse trees.
compiler/prog_item.m:
    The ptiN_import_use_map fields in the representations of .int0, .int
    and .int2 files had the same type as the ptms_import_use_map field
    in the parse trees of .m files, which is where they were derived from.
    However, while the ptms_import_use_map field needs to be able to represent
    implicit imports, the parse trees of .int0, .int and .int2 files
    should never include any implicit imports, and in fact any implicit
    imports in these fields were already ignored.

    Encode the invariant that interface files never include implicit imports
    in the types of these fields.

compiler/comp_unit_interface.m:
    Discard the implicit part of the source file's import_and_or_use_map
    when computing the contents of .int0, .int and .int2 files.

compiler/item_util.m:
    Provide the facilities used by the updated code in the modules above.

compiler/convert_parse_tree.m:
compiler/grab_modules.m:
compiler/make_hlds_separate_items.m:
    Conform to the changes above.
2023-01-21 06:38:17 +11:00
Zoltan Somogyi
307b1dc148 Split up error_util.m into five modules.
compiler/error_spec.m:
    This new module contains the part of the old error_util.m that defines
    the error_spec type, and some functions that can help construct pieces
    of error_specs. Most modules of the compiler that deal with errors
    will need to import only this part of the old error_util.m.

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

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

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

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

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

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

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

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

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

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

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

compiler/*.m:
    Conform to the changes above, mostly by updating import_module
    declarations, and renaming format_component to format_piece.
2022-10-12 20:50:16 +11:00
Zoltan Somogyi
30cb4f0ba3 Tighten representation of include/import/use decls.
compiler/prog_item.m:
    Change the representation of include, import and use declarations
    in the data structures of .int0 and .int3 files.

    For both .int0 and .int3 files, switch from data structures that can
    associate one or more contexts with each such declaration with
    data structures that can associate just one. Any duplicates would be
    errors, and we don't want to allow the representation of errors in
    compiler-generated interface files. (Similar updates to .int/.int2
    files are coming soon.)

    For .int3 files, delete two fields that hold information about include
    declarations and import/use declarations respectively in a fully checked
    form. They are not needed, because with invariants that .int3 files
    are subject to (no uses, no implementation section, no implicit imports),
    they contain just the same info as the new data structures mentioned
    in the paragraph above.

compiler/comp_unit_interface.m:
    Update the code that computes the contents of .int0/.int3 files.

    Fix some out-of-sequence variable names.

compiler/convert_parse_tree.m:
    Update the code that converts the generic parsed representation of
    interface files to the specific representations of .int0/.int3 files.

compiler/item_util.m:
    Update the utility predicates that comp_unit_interface.m and
    convert_parse_tree.m use to do their jobs. Add new variants
    of some existing predicates.

compiler/grab_modules.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/recompilation.check.m:
2022-09-03 11:01:08 +10:00
Zoltan Somogyi
c7171d0acf Simplify parameter passing. 2022-04-04 05:10:28 +10:00
Zoltan Somogyi
924f47b5bd Put all accumulate_modules_* predicates together ...
at the end of the module, in a top-down order, and with a consistent
naming scheme.
2022-01-25 23:01:49 +11:00
Zoltan Somogyi
0fa22b6e5a Update a comment. 2022-01-25 22:15:58 +11:00
Zoltan Somogyi
d64961d79d Use checked types/insts/modes in parse_tree_module_src.
This means that we can do the exact same checks (and, if needed, generate
the exact same error messages) when generating interface files as when
generating target language code.

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

compiler/prog_item.m:
    As above.

    Delete unused function.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Generate output whose indentation does not depend on tab settings.

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

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

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

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

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

tests/invalid/Mmakefile
2021-10-16 17:37:36 +11:00
Zoltan Somogyi
4548706b85 Switch to checked type/inst/mode maps for .int0.
compiler/prog_item.m:
    As above.

compiler/comp_unit_interface.m:
compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/parse_tree_out.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the change above.
2021-10-03 06:21:44 +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
22038a5b28 Rename check_parse_tree_type_defns.m ...
... to check_type_inst_mode_defns.m.

compiler/parse_tree.m:
    Change the name in the include_module declaration.

compiler/comp_unit_interface.m:
compiler/convert_parse_tree.m:
compiler/decide_type_repn.m:
compiler/prog_foreign_enum.m:
compiler/prog_item.m:
    Change the name in import_module declarations.

compiler/notes/compiler_design.html:
    Change the name in the documentation.
2021-09-08 06:59:35 +10:00
Zoltan Somogyi
7194baab3c Rename version_numbers to module_item_version_numbers.
Also, turn some semidet functions into predicates, and given them
more meaningful names.

compiler/recompilation.m:
compiler/timestamp.m:
    As above.

compiler/comp_unit_interface.m:
compiler/grab_modules.m:
compiler/make_hlds_passes.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_tree_out.m:
compiler/parse_types.m:
compiler/prog_item.m:
compiler/recompilation.check.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2021-08-28 00:05:34 +10:00
Zoltan Somogyi
163af89c98 Don't put duplicate imports/uses in .int{,0,2}.
The problem addressed by this diff is that copying any duplicate
import_module and/or use_module declarations in .m files to
automatically generated .intN files will cause those errors to be
reported 1+M times, once when compiling the source module, and
once for each of the M modules that import it. Those extra M reports
are not useful; they are only clutter.

compiler/comp_unit_interface.m:
    Do not copy the raw set of import_module and use_module declarations
    from the source file to the .int0 file. Instead, compute them anew
    from the import_and_or_use map, which was built by discarding any
    duplicate declarations, either within a single section, or across
    both sections.

    When deciding which modules to generate a use_module declaration for
    in the implementation section of a .int or .int2 file, do not include
    one for any module which has a use_module declaration in the interface.

compiler/item_util.m:
    Add a predicate that comp_unit_interface.m uses in the first task above.
2021-08-20 20:36:54 +10:00
Zoltan Somogyi
15c6fcabda Fix comment rot. 2021-08-17 23:12:51 +10:00
Zoltan Somogyi
8d513a9954 Delete some use unused types and preds. 2021-08-17 20:22:46 +10:00
Zoltan Somogyi
428aa400eb Introduce aug_make_int_unit.
compiler/prog_item.m:
    Split aug_compilation_unit into two types. One, aug_make_int_unit,
    is a new type, and it is a version of the old aug_compilation_unit
    that contains only what is needed when making .int{,0,2} files.
    The other, the new aug_compilation_unit, contains what is needed
    when generating target language code. Both encode in their argument types
    stronger invariants that the old aug_compilation_unit type did.

compiler/comp_unit_interface.m:
compiler/decide_type_repn.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/parse_tree_out.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the change above.

    In some cases, this means passing around aug_make_int_units instead of
    aug_compilation_units.

    In a few cases, it means creating two copies of a predicate,
    one for aug_compilation_units and one for aug_make_int_units.
    In such cases, factor out any commonalities between the copies.

    In many cases, it means updates to account for the specialized types
    of the fields of aug_compilation_unit or aug_make_int_unit.

    In some cases, it means deleting code that was always unreachable,
    but the not-tight-enough types did not make this fact visible.
    (Due to this effect, this diff removes more lines than it adds.)
2021-08-17 19:23:55 +10:00
Zoltan Somogyi
80798bff2b Put related code together. 2021-08-17 12:09:43 +10:00
Zoltan Somogyi
b3748a367b Separate self-FIM languages by module section.
compiler/prog_item.m:
    Split the parse_tree_module_src that holds the languages for which
    the module needs a self-foreign-import into two, depending on the
    section (interface or implementation) into which the self-FIM should go.

compiler/convert_parse_tree.m:
    When computing the self-FIM languages, put each one into its section.

compiler/comp_unit_interface.m:
    Don't compute the interface self-FIMs, since they are now available
    in the parse_tree_module_src.

    Document why we *do* compute the implementation self-FIMs
    for the interface file we are constructing.

compiler/check_raw_comp_unit.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.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:
    Conform to the changes above.
2021-08-17 12:01:52 +10:00
Zoltan Somogyi
5c3d4fe4f0 Replace module_and_imports with aug_compilation_unit.
compiler/module_imports.m:
    Delete the module_and_imports type, and replace its uses with
    aug_compilation_units.

    The structure of module_and_imports used to be private, but the
    structure of aug_compilation_units is public. Delete the getter/setter
    predicates on module_and_imports structures that can now be done
    using field names on aug_compilation_units. Delete, along with this,
    the infrastructure for keeping track of which module_and_imports fields
    are ever accessed. It has served its purpose, but it won't be needed
    anymore.

    Change types that used to include module_and_imports to include
    aug_compilation_units instead.

    Rename any types, predicates and functions that used to contain
    the "module_and_imports" string in their name.

compiler/prog_item.m:
    Move the version number map to be the last field of aug_compilation_units,
    as it used to be in module_and_imports structures, since this fits better.

compiler/get_dependencies.m:
    Make the name of a predicate more reflective of the type it returns.

compiler/comp_unit_interface.m:
compiler/deps_map.m:
compiler/equiv_type.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_separate_items.m:
compiler/mercury_compile_main.m:
compiler/module_qual.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2021-08-17 09:11:53 +10:00
Zoltan Somogyi
e2abe444f4 Always compute the self-import FIMs.
compiler/convert_parse_tree.m:
    Always compute the set of foreign languages for which
    the current module needs a self-import FIM. Use the algorithm
    that grab_unqual_imported_modules_make_int used to use to fill in
    that slot in the parse_tree_module_src.

    Stop computing some values whose only user was a sanity check.
    If it hasn't triggered by now, it won't.

    Delete an unused predicate that won't be needed.

compiler/prog_item.m:
    Since that field in the parse_tree_module_src is now always filled in
    when the parse_tree_module_src is created, delete the maybe wrapper
    around it.

compiler/grab_modules.m:
    Don't fill in the already-filled-in field.

compiler/comp_unit_interface.m:
    Conform to the changes above, and add an XXX.

compiler/parse_tree_out.m:
    Conform to the changes above.
2021-08-14 14:45:10 +10:00
Zoltan Somogyi
d84571c0c2 Delete redundant fields in aug_compilation_units.
compiler/prog_item.m:
    Delete the module name and module name context fields from
    aug_compilation_units, since the same info is available from
    the parse_tree_module_src field.

compiler/comp_unit_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/mercury_compile_main.m:
compiler/module_imports.m:
compiler/module_qual.m:
compiler/prog_item_stats.m:
compiler/write_deps_file.m:
    Conform to the change above.
2021-07-20 06:13:55 +10:00
Zoltan Somogyi
f1927afe0b Break a source file info parse_tree_module_srcs ...
... instead of into raw_compilation_units. Besides being more convenient to
work on, a parse_tree_module_src encodes in its type a significant number
of invariants that a raw_compilation unit does not.

compiler/split_parse_tree_src.m:
    Immediately after creating a raw_compilation_unit for one of the modules
    in a potentially multi-module source file, convert it to a
    parse_tree_module_src.

    Fix an old problem that can come up in contrived erroneous code.
    Specifically, when a submodule is both nested inside its parent module,
    *and* it also has an explicit include_module declaration, we used to
    record the contexts of both "inclusions", after generating an error
    message. The more rigorous checking that later code now does on the
    resulting inclusion map would look at this "duplicate inclusion"
    and generate *another* error message. To avoid this redundant message,
    do not record the contexts of erroneous inclusions for which a message
    has already been generated.

compiler/grab_modules.m:
    Operate on parse_tree_module_srcs instead of raw_compilation_units.
    This allows us to avoid having code for doing what converting the
    raw_compilation_unit to a parse_tree_module_src has already done.
    In fact, that conversion code does a better job. The old code assumed
    that all implicitly available modules are used in the interface,
    whereas in fact only some should be used in the interface, with
    the rest being used in the implementation section.

compiler/module_imports.m:
    Make the predicates that create module_and_imports structures
    take a parse_tree_module_src instead of a raw_compilation_unit
    as input. For now, we convert the parse_tree_module_src back to
    a raw_compilation_unit for further processing, but I intend
    a later diff to change this. Nevertheless, one immediate change
    is that init_module_and_imports now stores the *actual*
    parse_tree_module_src in the module_and_imports structure,
    not a dummy.

compiler/prog_item.m:
    Do not include a list of foreign_enum items in the interface section
    of a parse_tree_module_src, since such items are not allowed to occur
    in interface sections.

    For the same reason, delete the field for foreign_enums in the interface
    sections of .int0 and .int files.

compiler/check_raw_comp_unit.m:
    Operate on parse_tree_module_srcs instead of raw_compilation_units.

compiler/comp_unit_interface.m:
    Operate on parse_tree_module_srcs instead of raw_compilation_units.

    Do not expect any foreign_enum items in interface sections, since
    they are not allowed there.

compiler/read_modules.m:
    Provide a mechanism to remember having read a parse_tree_module_src.

compiler/write_module_interface_files.m:
    Operate on parse_tree_module_srcs instead of raw_compilation_units.

compiler/get_dependencies.m:
    Add a new version of an existing utility predicate. The old one operated
    on raw item lists, the new one operates on parse_tree_module_srcs.
    To make this possible, factor out the code pieces that operate on
    each non-ignored kind of item.

compiler/item_util.m:
    Add some new utility predicates/functions.

compiler/convert_parse_tree.m:
    Conform to the change in prog_item.m. (We already generated an error
    message for a foreign_enum item in the interface, but still passed around
    a list of foreign_enum items that was guaranteed to be stay empty.)

compiler/make.module_dep_file.m:
    Conform to the changes above.

    Use explicit streams in one place.

    Do not pass an unneeded argument.

compiler/check_parse_tree_type_defns.m:
compiler/equiv_type.m:
compiler/make_hlds_separate_items.m:
    Conform to the change in prog_item.m.

compiler/mercury_compile_main.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
    Conform to the changes above.

library/map.m:
library/tree234.m:
    Add foldl6, foldl6_values and foldr6 predicates. An earlier version
    of this diff needed foldl6, and I added the others for symmetry.

NEWS:
    Announce the new library predicates.

tests/invalid/bad_mutable.m:
    Export something, to avoid a warning about not exporting anything.

tests/invalid_submodules/duplicate_module.m:
tests/invalid_submodules/duplicate_module_test.m:
    Update programming style.
2021-07-19 13:23:28 +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
Julien Fischer
48a8d92585 Fix doubled-up words and spelling.
compiler/*.m:
compiler/notes/*:
    As above.
2021-06-20 20:29:50 +10:00
Zoltan Somogyi
c1f0913996 Simplify the logic of prog_mutable.m.
compiler/prog_mutable.m:
    The old logic was complicated by the need to have some decisions
    made by prog_mutable.m and some by add_mutable_aux_preds.m,
    which had different tasks (generating public declarations
    vs generating both public and private definitions), and thus
    used different approaches.

    Replace this with code in which for each kind of auxiliary predicate,
    the code to generate its declaration is just before the code
    to generate its definition. And the code that decides what public
    declarations to generate is just before the code that decides
    what public and private definitions to generate.

    Make this latter logic operate as directly as possible on the mutable's
    attributes, instead of first calling a separate predicate to compute
    the set of auxiliary predicates the mutable needs, recording the results
    in the mutable_target_params structure, and then generating definitions
    as directed by this structure.

    To make this possible, split some existing predicates that used
    to do two related but nevertheless separate jobs, such as defining
    get and set predicates for both constant and nonconstant mutables.

    Give a bunch of predicates names that better reflect whether they
    generate declarations only, definitions only, or both.

    Consistently refer to the name of the mutable as MutableName,
    since the code handles the names of other kinds of things as well.

    Give some predicates slightly shorter names, so calls to them
    fit on just one line.

compiler/prog_item.m:
    Change the arg type of a function based on the updated needs of
    prog_mutable.m.

compiler/add_mutable_aux_preds.m:
compiler/comp_unit_interface.m:
    Conform to the changes above.
2021-05-29 20:40:18 +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
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
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
effb79f3ee Delete an overstrong sanity check.
compiler/comp_unit_interface.m:
    As above.

tests/valid/int_imp_test.m:
tests/valid/int_imp_test_2.m:
    A regression test for the abort that the sanity check caused.

tests/valid/Mmakefile:
    Enable the new test case.
2020-09-27 16:49:14 +10: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
Zoltan Somogyi
4fdda27890 Temporary fix for a compiler abort.
This is for Mantis bug #499.
2020-04-08 04:38:47 +10:00
Zoltan Somogyi
57d937943b Put type_repn items into .int3 files.
compiler/comp_unit_interface.m:
    We used to put type_repn items for the simple types defined in a module
    into the module's .int3 file if the option --experiment1 was given.
    Change this to *always* do this. (What makes a type "simple" is defined
    in du_type_layout.m; roughly a type is simple if its representation
    does not depend on the representation of any other type.) It is
    from these type_repn items in .int3 files that we should be able to
    compute type representations for *all* types when creating a module's
    .int file.

    Don't take a globals parameter, as it is no longer needed.

compiler/write_module_interface_files.m:
    Don't pass a globals parameter.

compiler/options.m:
    Add a synonym for --compiler-sufficiently-recent, so a later diff
    to configure.ac can test for the presence of this functionality
    in the installed compiler.
2020-03-22 10:56:10 +11:00
Zoltan Somogyi
40f90403ee Get decide_type_repn.m to return a map.
It constructs the data it returns in maps (keyed on type_ctors),
but used to turn those maps into lists before returning them.
This was wasteful, as comp_unit_interface.m promptly turned them back
into the maps that decide_type_repn.m constructed those lists from.

compiler/decide_type_repn.m:
compiler/comp_unit_interface.m:
    Get the data from decide_type_repn.m to comp_unit_interface.m
    in the form of a map.
2020-03-21 20:35:27 +11:00
Zoltan Somogyi
ac466a3531 Avoid almost all conversions to parse_tree_int.
For a while now, we have been generating interface files into
file-kind-specific parse trees, but we then converted those into
the generic parse_tree_int type for further processing, because
the old code for doing that further processing operated on
parse_tree_ints. This diff replaces most of that "further processing"
code with code that operates on int-file-kind-specific parse trees,
thus avoiding the cost of conversion. The main cost is not performance
(the effect of this change on compiler speed is negligible), but loss
of code clarity through the loss of invariants.

compiler/comp_unit_interface.m:
    After generating a parse_tree_intN for N in {0,1,2,3}, do NOT convert it
    to a generic parse_tree_int.

    When constructing a parse_tree_int3 from a raw_compilation_unit,
    guard against a situation where we could unintentionally create
    a duplicate of an abstract type definition. The solution here
    is not the most elegant possible, but a better one requires other
    changes that don't really fit in this diff.

compiler/canonicalize_interface.m:
    Put two large blocks of code (dealing with the canonicalization
    of pred and mode declarations respectively) into their own predicates.

    Expose a mechanism to standardize not the contents of a whole
    interface file, but just the predicate and mode declarations in it.
    (These are the tricky kinds of items to canonicalize, because sorting
    a set of mode declarations can change the meaning of the program.)
    This mechanism is just a specialized version of the existing machinery.

    Since this diff leaves the existing machinery unused, the next diff
    will delete it, and since that will probably leave a too-small module,
    delete the whole module, after moving the remaining small piece of code
    to the only module that uses it, parse_tree_out.m.

compiler/parse_module.m:
    Instead of implementing actually_read_module_intN in terms of
    actually_read_module_int, do the reverse, which avoids the unnecessary
    conversion from parse_tree_intN to parse_tree_int.

compiler/parse_tree_out.m:
    Provide predicates, output_parse_tree_intN, to write out parse_tree_intN,
    not just a generic parse_tree_int.

    Change the existing service routines, mercury_output_parse_tree_intN,
    that do all the work of the above new predicates to write out the contents
    of each parse tree in the canonical order, using the newly exposed
    functionality in canonicalize_interface.m where needed. (Previously,
    write_module_interface_files.m invoked canonicalize_interface.m to do this
    before calling parse_tree_out.m.)

    These service routines were originally written for debugging; make them
    suitable for creating proper .intN files by removing unneeded output.

compiler/write_module_interface_files.m:
    Call the newly provided predicates in parse_tree_out.m to output
    interface files. To make this possible, break up the old predicate
    actually_write_interface_file into smaller predicates, so that the
    new predicates actually_write_interface_fileN can each call whichever
    of these are relevant for the given interface-file-kind. (Some pieces
    are relevant to only a subset of these kinds.)

compiler/convert_parse_tree.m:
    Note the reason why this diff is not deleting the functions that convert
    parse_tree_intN to parse_tree_int.

compiler/read_modules.m:
    Note the reason why this diff is not deleting the functions that read in
    generic parse_tree_ints.
2020-03-20 22:00:41 +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
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
6245b6e54d Allow reading parse_tree_{plain,trans}_opt.
compiler/prog_item.m:
    Fix a bug: provide a slot for foreign_procs in parse_tree_plain_opts.

    Eliminate unnecessary differences between parse_tree_{plain,trans}_opt
    and parse_tree_int[0123].

compiler/parse_module.m:
    As a temporary measure for testing,

    - convert every .opt and .trans_opt file read in from its generic
      parse_tree_opt representation to its specific parse_tree_plain_opt
      or parse_tree_trans_opt representation, in order to check for
      items that should not occur in the purpose-specific representations,
    - and then convert it back.

    Provide (not yet used) predicates for reading in optimization files
    into their specific parse tree formats. These do the first conversion
    but not the second.

compiler/parse_tree_out.m:
    Add predicates for writing out parse_tree_{plain,trans}_opt directly,
    without conversion to a generic opt file.

compiler/convert_parse_tree.m:
    Make the above possible by adding conversions to and from
    parse_tree_{plain,trans}_opt.

    Give exported predicates more expressive names.

compiler/comp_unit_interface.m:
compiler/intermod.m:
    Conform to the changes above.

compiler/add_pred.m:
compiler/grab_modules.m:
    Minor style improvements.

compiler/add_foreign_proc.m:
    Fix the wording of an error message.

tests/invalid/fp_dup_bug.err_exp:
    Expect the updated wording.
2019-11-08 13:52:10 +11:00
Zoltan Somogyi
c7bc31f2d2 Rename convert_interface.m to convert_parse_tree.m.
compiler/convert_interface.m:
    As above. I am about to add code to convert optimization files as well.

compiler/parse_tree.m:
    Include the module under its new name.

compiler/notes/compiler_design.html:
    Document the module under its new name.

compiler/comp_unit_interface.m:
compiler/intermod.m:
compiler/parse_module.m:
    Import the module under its new name.
2019-10-30 12:10:16 +11:00
Zoltan Somogyi
ab8c2771f7 Move towards generating .opt/.trans_opt files via items.
compiler/prog_item.m:
    Add types for representing .opt and .trans_opt files that specify
    exactly what kinds of items may appear in them.

    Provide a mechanism for representing just the kinds of pragmas
    that we may want to put into .opt files to represent a predicate marker.

    To make the above possible, generalize the item_pragma_info type.

    Do not store the "maybe attributes" field in all pragmas; store it
    in just the one pragma for which it had pragma-specific code (which code
    is dubious anyway). Its only use is to suppress error messages about
    incorrect pragmas if that pragma was created by the compiler, on the
    theory that the user cannot do anything about any such error messages.
    However, if such errors are never reported to anyone, then they won't
    be fixed. I think it is better to allow such problems to be discovered,
    even if they cause a bit of annoyance to the discoverer. The default
    content of the field as set by the parser, item_origin_user, can be
    misleading anway; it is correct when the pragma is read in from a .m file
    or from a .int* file, but it is wrong when read in from a .*opt file,
    since the contents of those are decided by the compiler.

    Store a varset and tvarset in structure sharing and reuse pragmas,
    since without this, one cannot print them out properly.

compiler/intermod.m:
    Change the predicates that write out .opt and .trans_opt files
    to return as large a fraction of the parse trees of those files
    as possible, as a step towards generating those files not directly,
    but by building and then writing out those parse trees. For now,
    we cannot do this fully for .opt files, because for a few item kinds,
    it is far from obvious how to represent as a item what we write out.

    Leave the opening and closing of the file streams for writing out
    .opt and .trans_opt files to our caller, because for .opt files,
    this allows us to avoid having to open the file *twice*.

    Put the output of result-of-analysis pragmas into a standard order.

    Factor out as common code the process for deciding what should go into
    .opt files.

    Give a field of the intermod_info structure a more precise name.

compiler/mercury_compile_front_end.m:
    Hold the stream of the .opt file open between the two different pieces
    of code that write out the two different parts of .opt files.

    If --experiment5 is set, write out the parse tree of the .opt file
    to the .optx file, to enable comparison with the .opt file.

compiler/mercury_compile_middle_passes.m:
    If --experiment5 is set, write out the parse tree of the .trans_opt file
    to the .trans_optx file, to enable comparison with the .trans_opt file.

    Reset a memo table for structure_{sharing,reuse}.analysis.

compiler/structure_reuse.analysis.m:
compiler/structure_sharing.analysis.m:
    Don't take an I/O state pair as arguments, since we needed them *only*
    for that reset, and for progress messages.

    Give the main predicates more descriptive names.

compiler/trailing_analysis.m:
    Give the main predicate a more descriptive names.

compiler/closure_analysis.m:
    Don't take an I/O state pair as arguments, since we needed them *only*
    for progress messages.

compiler/add_pragma.m:
    Don't ignore an error, since one of the other changes in this diff
    could have fixed its cause.

compiler/convert_interface.m:
    Export utility functions needed by code added by this diff.

ompiler/lp_rational.m:
    Tighten the inst of an output argument for use by intermod.m.

    Bring programming style up to date.

compiler/parse_pragma.m:
    Don't put a maybe attributes field into item_pragma_infos.

    Include the varset in structure sharing and reuse pragmas.

    Use simplest_spec where possible.

compiler/parse_tree_out.m:
    Add predicates for writing out the new parse trees of .opt and
    .trans_opt files.

compiler/parse_tree_out_pragma.m:
    Add predicates needed by the new code in parse_tree_out.m.

compiler/add_mutable_aux_preds.m:
compiler/canonicalize_interface.m:
compiler/comp_unit_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/item_util.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.qualify_items.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2019-10-30 10:43:39 +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
a1ab0668a4 Allow foreign_enums for dummy types.
This fixes Mantis bug #485.

compiler/check_parse_tree_type_defns.m:
    Generalize the representation of du types in checked type definitions
    to give special representation to dummy types, as well as enum types.

    Allow foreign enum definitions for types whose du definitions are dummy,
    as well as those whose du definitions are enum.

compiler/prog_type.m:
    Have the predicate that tests whether a du type is an enum type
    to return the number of function symbols as well as the number of bits
    needed to represent them. This is the most direct differentiator between
    dummy types and enum types.

compiler/comp_unit_interface.m:
    Conform to the change in prog_type.m.

tests/valid/bug485.m:
    A regression test for the bug.

tests/valid/Mmakefile:
    Enable the new test case.
2019-09-29 12:16:30 +10:00
Zoltan Somogyi
9891677bf3 Carve convert_interface.m out of prog_item.m.
compiler/convert_interface.m:
compiler/prog_item.m:
    As above.

compiler/parse_tree.m:
    Include the new module.

compiler/comp_unit_interface.m:
compiler/parse_module.m:
    Import the new module.
2019-09-28 04:09:58 +10:00
Zoltan Somogyi
19ef98b66f Check the type definitions in a module for consistency ...
... when generating interface files.

compiler/check_parse_tree_type_defns.m:
    A new module for doing the checking.

compiler/parse_tree.m:
    Add the new module.

compiler/comp_unit_interface.m:
    When computing what should go into a .intN file, use the new module
    to check for inconsistencies in the source code of the module.

    Making the above possible requires retaining some information
    (such as contexts in foreign enum definitions, and the presence
    of definitions, as opposed to declarations, for some types)
    for longer than was needed until now.

    Give some predicates more descriptive names.

    Move the record_foreign_enum_spec predicate near where it is used.

compiler/write_module_interface_files.m:
    If comp_unit_interface.m reports any errors when generating the
    would-be contents of an interface file, do NOT create that
    interface file.

    The errors comp_unit_interface.m and check_parse_tree_type_defns.m
    now generate are the kinds of inconsistencies whose resolution requires
    everything depending on this module to be recompiled anyway,
    so stopping the compilation process *without* producing
    the would-be-erroneous interface file should be a net win
    almost all the time.

compiler/prog_item.m:
    Factor out some commonalities in data structures.

    When converting the generic parse_tree_int we get from reading
    in a .intN file to the parse tree type specific to that N,
    check the definitions we read in for consistency.

    As in comp_unit_interface, making the above possible requires
    retaining some information for longer than was needed until now.

    Never output two or more declarations of the same type_ctor
    in the same section of an interface file, since the code
    *reading* interface files now reports such redundancies
    (but see the change to options.m).

compiler/options.m:
    Disable the printing of error messages for problems found in
    interface files, since the new code in check_parse_tree_type_defns.m
    now finds problems in interface files generated by currently
    installed compilers. Specifically, many contain duplicate
    declarations for Mercury types. One declaration is written
    by the programmer, the other is the type's actual definition
    turned into the redundant declaration by the compiler.

compiler/parse_pragma.m:
    When parsing foreign enum pragmas, implicitly qualify the
    name of the type constructor they are for with the current module name.
    This is semantically sound, since foreign_enum pragmas *must* be
    for a type constructor defined in the same module. It is desirable
    because type_ctors in type definitions are module qualified.
    The code of check_parse_tree_type_defns.m needs to process
    the type definitions and foreign enums for a type_ctor at the
    same time, and doing so would be more needlessly complicated
    if the type ctor keys in the "type_ctor to type definitions"
    and "type_ctor to foreign enums" maps were incompatible due to
    the difference in qualification.

    The type_ctor in a foreign enum definition may still be manually
    module qualified by programmers; it just happens that any qualification
    other than the default is a semantic error.

compiler/module_qual.qual_errors.m:
    When printing error messages about undefined type_ctors in
    foreign enum definitions, do not print this implicitly
    added qualification, since it adds only clutter.

compiler/error_util.m:
    Provide a mechanism for printing type_ctors directly,
    i.e. without converting them to a sym_name/arity pair.

    Put a qual_ prefix in front of top_ctor_of_type, since it
    always prints module qualification. (This is to remind people
    who may use this component about that qualification.)

    Factor out some common code.

compiler/det_analysis.m:
    Conform to the change in error_util.m.

compiler/parse_module.m:
    Fix too-long lines.

compiler/Mercury.options:
    Require some of the modules above to have no dead predicates.

library/erlang_rtti_implementation.m:
library/io.m:
    Delete declarations of types that are unneeded because the types
    also have definitions.

tests/typeclasses/unqualified_method2.m:
    Move an import out of the interface, since we now print the warning
    generated for its improper location.
2019-09-28 02:57:00 +10:00
Zoltan Somogyi
8214456761 Delete the foreign_import_module_info type.
compiler/prog_data_foreign.m:
compiler/prog_item.m:
    Replace it with the fim_spec type, which contains the exact same information.

compiler/comp_unit_interface.m:
compiler/compile_target_code.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_top_gen.m:
compiler/mlds.m:
compiler/mlds_to_c_file.m:
compiler/module_imports.m:
compiler/parse_tree_out.m:
compiler/prog_foreign.m:
compiler/write_deps_file.m:
    Conform to the change above.
2019-09-13 14:28:03 +10:00
Zoltan Somogyi
2b04f7cc7b Handle item kinds in a standard order. 2019-09-12 05:42:55 +10:00