Commit Graph

2 Commits

Author SHA1 Message Date
Zoltan Somogyi
7b6bace9ec Don't return dummy parse_trees for missing files.
The predicates that read a Mercury source, interface or optimization file
used to return four things:

- the name of the file (for callers who specified only a module name),
- the timestamp, if requested and available,
- a parse tree, and
- a representation of any errors (sets of error categories, and error_specs).

However, these four things were not independent. Some combinations of their
values were not allowed, but (a) there was no documentation of what these
combinations were, and (b) code that processed these four things had to be
prepared to handle illegal as well as legal combinations.

This diff makes these predicates return only one result, which contains

- all four of the above things, when the file could be opened, but
- only the file name and a representation of the error if the file
  could not be opened,
- only the file name and a representation of *no* errors, if the caller
  asked the predicate to read the file only if its timestamp did not match
  a specified value, and it does match that value.

We use a somewhat modified version of an existing type, have_read_module,
for this. It is modified both by including information that its users
now need that they did not need before, and shortening the names of its
function symbols, which now occur in many more places than before.

compiler/read_modules.m:
    Make the change to the output arguments described above.

    Making this change requires having the affected predicates deal with
    the case where we either cannot find or cannot open the relevant file.
    (The two are effectively the same thing in this module, since we search
    by attempting to open.) Passing that task off to parse_modules.m
    was always inelegant.

    Simplify the have_read_module_map type by making the key always
    be a module_name. We deleted the only use of have_read_module_maps
    with another kind of key a while ago.

    Delete some no-longer-needed predicates.

compiler/parse_module.m:
    Delete the code dealing with the absence of a file stream to parse.

    Replace code that used to construct dummy parse trees with code
    that simply returns *no* parse tree if the file could be opened
    but could not be read, or if its timestamp indicated that reading it
    would have been redundant.

    Delete some utility predicates moved to parse_error.m, so that
    read_modules.m could also use them.

    Fix comment rot.

compiler/parse_error.m:
    Add some utility predicates for use by read_modules.m and parse_module.m.

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

    Document the dubious effects of an old design decision.

    Fix a misleading predicate name.

    Fix comment rot.

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

    Some predicates used to return parse trees that could be dummies.
    Change them to return just the parts of the parse tree that the
    caller was interested in, which was usually a tiny part, and which
    can be constructed trivially even when we don't have a parse tree.

    Delete an unneeded type.

compiler/recompilation.check.m:
    Conform to the changes above.

    Represent the operations we need to test version numbers in interface files
    as a typeclass, and rewrite the checking operation in terms of that
    typeclass, with one instance for each kind of interface file.

    Move some repeated code into a predicate.

    Shorten some long names.

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

    Break up a large predicate.

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

compiler/prog_item.m:
    Delete the parse_tree_some_int type. The change in recompilation.check.m,
    deleted its last few uses there, and allowed the deletion of the last
    uses in read_modules.m.

tests/recompilation/two_module_debug:
    Extend this script to help deal with problems in all stages of the
    execution of a test case, since that was required while debugging
    this diff.

    Document which parts of this script correspond to which parts of
    two_module_test.

tests/recompilation/test_functions:
tests/recompilation/two_module_test:
    Simplify the logic of the main test function, by testing a condition
    once instead of three times.

    Specify whether a recompilation test is expected to succeed or fail
    directly, using alternatives that model a bespoke type, instead
    of alternatives that mimic a boolean answer to a question, which
    does not help readers who don't remember the question.

    Always put shell variable names in braces.

    Note a problem that makes one of the shell functions ineffective.

tests/recompilation/Mmakefile:
    Tell two_module_test what to do using its updated interface.
2022-04-30 14:37:22 +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