Commit Graph

10 Commits

Author SHA1 Message Date
Zoltan Somogyi
012751691c Rename some function symbols to avoid ambiguity.
compiler/module_qual.id_set.m:
    As above. Also give the affected type a better name.

compiler/module_qual.m:
compiler/module_qual.qual_errors.m:
compiler/module_qual.qualify_items.m:
    Conform to the change above.
2022-11-25 16:23:33 +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
814aae5bb7 Add a distinguishing prefix to recompilation items.
compiler/recompilation.m:
    Add a distinguishing prefix to the names of both types relating to
    recompilation items, and to the names of their function symbols,
    in order to avoid confusion between them and the items defined in
    prog_item.m.

    Update the names of the related functions.

compiler/add_pragma_type_spec.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/module_qual.id_set.m:
compiler/module_qual.qualify_items.m:
compiler/proc_requests.m:
compiler/prog_item.m:
compiler/qual_info.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
    Conform to the change above.
2022-04-05 07:48:01 +10:00
Zoltan Somogyi
1f328fe18b More recompilation type specializations.
compiler/recompilation.m:
    Introduce a new enum type, used_item_type, which has equivalents
    of those item_types for which we collect used item sets. This allows us
    to delete several calls to unexpected.

    Rename type_abstract_item to type_name_item and type_body_item to
    type_defn_item.

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

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

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

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

    In some cases, give some predicates and/or variables more meaningful names,
    or convert clause lists into explicit disjunctions. (In some cases,
    the latter revealed arguments that all clauses ignored.)
2021-08-29 00:41:14 +10:00
Zoltan Somogyi
f12968eee6 Replace item_id_set with several specialized types.
The old code used item_id_sets for representing several closely related
but nevertheless significantly different pieces of information. These had
different invariants, but these could not be expressed in the type.
Using a different type for each purpose allows encoding the applicable
invariants in the types.

Also, the original code was organized around higher order code
that (a) used an item_type key to get a field from an item_id_set,
(b) did something with that field, and then, in some cases
(c) put its updated version back into the item_id_set.
It often did this in a loop over some, but not all, item_type values.
This diff replaces such code with code that (a) deconstructs a value
in one of item_id_set's replacement types, (b) uses a separate call
to process each field that needs to be processed, and then maybe
(c) constructs a new value containing the updated field.

This new approach has several advantages.

- It is more direct and hence more understandable. Due to the extra code
  that used to be required by the higher order machinery, it can also be
  shorter.

- It made clear that two of the fields of item_id_set, the fields
  ostensibly containing information about mutables and foreign_procs,
  were *never actually used*.

- It also works when the fields are not all the same type. The old code
  stored information about instances separately from item_id_sets
  precisely because it would have required a field of a different type.

- This last point allows a future diff to further specialize the types
  of the fields. Some now store items; in the future, they could store
  either just one specific kind of item, or one of a small set of kinds
  of items; e.g. the fields for predicates and functions could store
  one of item_pred_decl_infos, item_mode_decl_infos or item_decl_pragma_infos.

- It is also more efficient. Some of the old traversals allocated a new
  item_id_set every time they updated a field, with their replacement
  traversals never constructing a new item_id_set (or rather a value
  of one of its replacement types) until the traversal is complete.

One minor aspect of the change is that this diff consistently puts insts
before modes in data structures and in the code that operates on them,
as we do in the rest of the compiler. Another is that it uses the name_arity
type to replace the type that the old code used, which was pair(string, int).

compiler/recompilation.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
    As above.

    Delete assignments to !:MaybeStoppingReason that assign it the value
    ("no") that !.MaybeStoppingReason already contains, as tested
    immediately above.

    Add XXX RECOMP where further changes are desirable.

compiler/module_qual.id_set.m:
    Put insts before modes in id_type.

library/cord.m:
    Add foldl versions with two and three accumulators.

NEWS:
    Announce the new predicates.

tests/recompilation/two_module_debug:
    Add this script, which can help debug problems with smart recompilation.

tests/recompilation/Mercury.options:
    Fix indentation.
2021-08-27 21:49:37 +10:00
Zoltan Somogyi
4b2a4a88b5 Fix handling "int used, imp imported" modules when making interface files.
This fixes the second incarnation of Mantis bug #401. (The first incarnation
was the handling of such modules when generating target code.)

compiler/grab_modules.m:
    Compute the set of modules that have a use_module declaration in the
    interface section and an import_module declaration in the implementation
    section, and set the status of the items imported from that module
    accordingly.

compiler/module_qual.id_set.m:
    If module A defines an entity (such as a type) that module B refers to
    without the required qualification (which can happen if B has a use_module,
    not import_module for A), then do NOT report A as unused in B; it IS used,
    just not properly.

tests/hard_coded/int_impl_imports.exp:
tests/hard_coded/int_impl_imports.m:
tests/hard_coded/int_impl_imports_2.m:
    A new test case to see whether we can compile a module that has
    "int used, imp imported" references to another module, and has
    unqualified references to an imported entity in the implementation.

tests/invalid/int_impl_imports.err_exp:
tests/invalid/int_impl_imports.m:
tests/invalid/int_impl_imports_2.m:
    A new test case to see whether we can generate the right error message
    for a module that has "int used, imp imported" references to another
    module, and has an unqualified references to an imported entity
    in the interface.

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

tests/valid_seq/int_impl_imports.m:
tests/valid_seq/int_impl_imports_2.m:
    Add vim mode lines.
2019-08-02 10:36:59 +02:00
Zoltan Somogyi
c1bdd2100b Delete unneeded $module args from aborts. 2019-04-16 04:13:35 +10:00
Zoltan Somogyi
5649f36c80 Handle "use_module in interface, import_module in implementation".
If a module m1 imports module m2 using a use_module declaration in its
interface section but also imports it using an import_module declaration
in its implementation section, then references to entities defined in m2
in the interface of m1 must be module qualified, but similar references
in the implementation of m1 need NOT be module qualified.

The Mercury compiler has long had a bug that allowed entities imported
in the implementation of module m1 to be used in the interface of m1,
against the rules of the language. When I fixed that bug on 2015 nov 11,
the compiler became unable to properly process the situation described
in the paragraph above, because it still had another bug, which was that
it had a single setting for module qualification requirements: either it
was required *everywhere* in m1, or it was required *nowhere* in m1.
This diff fixes that bug (mantis bug 401) by allowing different requirements
in this respect in the interface of m1 versus its implementation.

It also changes the de-facto meaning of what exactly a use_module declaration
requires. The reference manual says only:

    Uses of entities imported using @code{use_module} declarations
    @emph{must} be explicitly module qualified.

This WAS unambiguous when it was written in june 1997, a few months before
submodules were added to the language. With a flat module system, there were
no nested module names, so either the module name was present, or it wasn't.
In the presence of nested modules, though, it IS ambiguous: HOW MUCH of
the module name must be present? The reference manual is silent on this.

At the moment, in the presence of a use_module for module ma.mb.mc,
a predicate p1 in ma.mb.mc may of course be referred to as ma.mb.mc.p1,
but may also be referred to as mb.mc.p1, or even just mc.p1. The specification
of mc is always required, but exactly WHICH of the previous module name
components are required depends on whether e.g. ma or ma.mb were themselves
imported via use_module or import_module declarations. The code implementing
the check (find_matches_in_permissions_map in module_qual.id_set.m) is itself
not too clear.

This diff changes the rules so that all references to anything imported
via a use_module declarations have to be fully qualified. This is stricter
than the existing rule, but it is MUCH simpler, and it better matches
the original intent of use_module declarations, which is the avoidance
of ALL POSSIBILITY of ambiguity.

NEWS:
doc/reference_manual.texi:
    Document this change to the language.

compiler/prog_item.m:
    Change the representation of sections in .int* files. Previously,
    we recorded whether the interface file that the section was from
    was read for an `import_module' or a `use_module' declaration.
    We now allow the recording of the fact that it had both declarations,
    a use_module in the interface and an import_module in the implementation.

compiler/modules.m:
    Treat modules that have both a `use_module' declaration in interface
    and an `import_module' declaration in the implementation as being of this
    new internal section kind.

    Add some infrastructure for debugging similar problems in the future.

compiler/module_qual.id_set.m:
    Change the permissions system. Instead of recording *independently*
    whether (a) an entity may be used in the interface and (b) whether
    references to it must be qualified, record *separately* whether
    (a) it may be used in the interface, and if so with what qualification
    requirements, and (b) what its qualification requirements are in the
    implementation. Unlike the old permission setup, the new one allows us
    to express the "use_module in interface, import_module in implementation"
    situation.

    Implement the change to the language, by requiring full module
    qualification of entities imported via use_module declarations.
    This allows us to use a single parameterized piece of code to handle
    both unqualified and qualified references, whereas before we used
    separate pieces of code for them.

    Change the way we handle errors in module qualification. Instead of
    looking only for precise matches only, and looking for the possible causes
    of errors only if we find either no matches or two or more matches, we now
    return the near-miss matches as well, the ones that we need to decide
    on what error message we want to generate. While this is slightly slower,
    it is *much* simpler, since it allows us to avoid duplicating the search
    code: once for precise matches only, once for no-match errors, and once
    for multiple-match errors.

compiler/module_qual.collect_mq_info.m:
    Set permissions for symbol access according to the new permissions system.
    Code that previously triggered the bug will use the new interface file
    section kind, and can now have its permissions record correctly.

compiler/module_qual.qual_errors.m:
    Use a single predicate to generate error messages for all situations
    in which there is not a single precise match for a module qualification.
    This allows us to diagnose multiple potential problems with a single
    lookup.

    Change the wording of an existing error message to avoid a possibly-untrue
    implication.

compiler/hlds_data.m:
    Rename a field of the type_defn type to better document its meaning.

compiler/make_hlds.m:
    Document the meaning of the need_qualifier field in sec_infos.

compiler/add_type.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.m:
compiler/pred_table.m:
compiler/parse_tree_out.m:
compiler/prog_item_stats.m:
    Conform to the above changes.

mdbcomp/sym_name.m:
    Add a utility predicate for use in looking for near-miss matches
    in module qualification.

    Make the documentation of a related predicate more precise.

tests/invalid/bad_instance.m:
tests/submodules/class.m:
tests/submodules/nested.m:
tests/submodules/nested3.m:
tests/submodules/parent.m:
    Make names fully module qualified where the language rules now require it.

tests/submodules/deeply_nested.m:
    Comment out a part of the test that tested the partially qualified names,
    since these are now not allowed.

tests/invalid/errors.err_exp:
    Expect a now-improved error message.

tests/invalid/test_nested.err_exp:
tests/invalid/transitive_import.err_exp:
tests/invalid/undef_type.err_exp:
    Expect a now less-likely-to-mislead error message.

tests/valid_seq/int_impl_imports.m:
tests/valid_seq/int_impl_imports_2.m:
    The test case for mantis bug 401.

tests/valid_seq/Mmakefile:
    Enable the new test case.
2016-01-11 23:05:39 +11:00
Zoltan Somogyi
9fe11c2f8e Delete some redundant imports. 2015-11-16 19:23:11 +11:00
Zoltan Somogyi
df794c259a Break up module_qual.m into cohesive submodules.
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.id_set.m:
compiler/module_qual.qual_errors.m:
compiler/module_qual.qualify_items.m:
    The new submodules of module_qual.m.

compiler/module_qual.m:
    Delete the stuff moved to the new submodules.

compiler/notes/compiler_design.html:
    Document the new submodules.
2015-11-12 01:25:09 +11:00