My commit afe2887882 broke the ability
to run the test suite outside of a bootcheck by executing "mmake runtests"
in the tests directory. This diff fixes that.
tests/Mmake.common:
Don't define "TESTS_DIR = ..". While every single tests/*/Mmakefile
defined it as such, I overlooked the fact that tests/Mmakefile itself
defined it ".", referring to the same directory from a different starting
point. Document this easily-overlooked fact.
Rename the old runtests target, which after afe2887 runs the tests
in a single directory, as runtests_dir, to leave the target name
"runtests" itself free for tests/Mmakefile to use.
tests/Mmakefile:
Define "TESTS_DIR = .", and add a target "runtests" which invokes
"mmake runtests_dir" in each test directory.
tools/bootcheck:
Invoke "mmake runtests_dir" instead of "mmake runtests" in each
test directory.
Initialize a variable just before it is used.
tests/*/Mmakefile:
Add back the definition "TESTS_DIR = .."
tests/hard_coded/unsigned_lt_le.exp2:
Add an expected output for when int is 32-bit.
tests/hard_coded/unsigned_lt_le.m:
Document what the expected outputs are for.
library/string.parse_util.m:
When we find a mismatch between a format specifier char and the
corresponding polytype, list the specifier chars that are applicable
to the given polytype.
tests/invalid/string_format_bad.err_exp:
tests/invalid/string_format_unknown.err_exp:
Update the expected mismatch messages.
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.
library/private_builtin.m:
As above. The code recognizing them as builtins was added a few weeks ago.
configure.ac:
Require the installed compiled to contain that code.
compiler/options.m:
Provide a way to test whether the compiler has *this* diff.
library/int.m:
Delete int.unsigned_lt, and use private_builtin.unsigned_lt instead.
tests/hard_coded/unsigned_lt_le.{m,exp}:
A test case for the two operations.
tests/hard_coded/Mmakefile:
Enable the new test case.
Extend the operations that perform formatted conversion, such as
string.format/2, to be able to handle values of type uint directly. We have
always supported formatting values of type int as unsigned values, but
currently the only way to format uint values is by explicitly casting them to
an int. This addresses Mantis issue #502.
library/string.m:
Add a new alternative to the poly_type/0 type that wraps uint
values.
Update the documentation for string.format. uint values may
now be formatted using the u, x, X, o or p conversion specifiers.
library/string.format.m:
Add the necessary machinery for handling formatting of uint values.
library/string.parse_runtime.m:
library/string.parse_util.m:
Handle uint poly_types.
library/io.m:a
Handle uint values in the write_many predicates.
library/pprint.m:
Handle uint values in the poly/1 function.
compiler/format_call.m:
compiler/parse_string_format.m:
Conform to the above changes.
compiler/options.m:
Add a way to detect if a compiler supports this change.
NEWS:
Announce the above changes.
tests/hard_coded/stream_format.{m,exp}:
Extend this test to cover uints.
tests/invalid/string_format_bad.m:
tests/invalid/string_format_unknown.m:
Conform to the above changes.
tests/string_format/Mmakefile:
tests/string_format/string_format_uint_o.{m,exp,exp2}:
tests/string_format/string_format_uint_u.{m,exp,exp2}:
tests/string_format/string_format_uint_x.{m,exp,exp2}:
Add tests of string.format with uints.
tests/invalid/type_arity.{m,err_exp}:
A new test case that uses a type constructor with the wrong arity.
tests/invalid/Mmakefile:
Enable the new test case.
tests/valid_make_int/bug506.m:
tests/valid_make_int/bug506_sub.m:
The test case. bug506_sub.m defines a type whose name is a Mercury
operator; we test whether the compiler can read its .int3 file
when generating the .int file of bug506.m.
tests/valid_make_int/Mmakefile:
Enable the new case, after adding infrastructure for handling
multi-module programs.
The current source-to-source debugger transformation cannot handle the
predicates introduced by higher-order specialization. There are likely similar
issues with other HLDS->HLDS transformations.
The fix (for now) is to disable most HLDS->HLDS transformations in .ssdebug
grades.
compiler/handle_options.m:
Disable most HLDS->HLDS optimizations when the ss-trace level is
shallow or deep.
Add an XXX comment about a separate issue.
compiler/ssdebug.m:
Add an XXX comment about predicates produced by higher-order
specialization.
tests/WS_FLAGS.ws:
Add a missing include.
tests/valid/Mmakefile:
tests/valid/Mercury.options:
tests/valid/gh89.m:
Add the test case from github issue 89.
doc/reference_manual.texi:
Document the restrictions that the parse_type_defn.m implements
(or at least tries to).
Fix three bugs in one of the "supposed to be correct" examples,
as well as the formatting that previously made the bugs harder to see.
compiler/parse_type_defn.m:
Improve the wording of error messages for errors involving existentially
typed data constructors.
Simplify the structure of one of the predicates that generate such
messages.
compiler/parse_class.m:
Add a period to the end of an error message.
tests/invalid/bad_existential_data_type.{m,err_exp}:
A new test case for the updated error messages, most of which
weren't being tested before.
tests/invalid/Mmakefile:
Enable the new test case.
tests/invalid/fundeps_unbound_in_ctor.err_exp:
tests/invalid/type_vars.err_exp:
Update the expected wording of some error messages.
runtime/mercury_label.h:
Add a #include of mercury_conf.h before the #include of
mercury_conf_param.h.
We #include mercury_conf.h anyway, indirectly through mercury_types.h,
but this happens *after* mercury_conf_param.h. This was not a problem
in the usual case when a .c file #included mercury_label.h, since
its inclusion invariable came after inclusion of mercury_imp.h,
which itself includes mercury_conf.h. It was a problem only in one
very special case: when, as part of the namespace cleanliness check,
mercury_label.h was compiled as the only thing #included in
mercury_label.check.c, *and* the grade is the pregen grade.
The problem was that MR_LOW_TAG_BITS is *defined* in mercury_conf.h,
with a simple #define, but in the pregen grade, it is also *redefined*
in mercury_conf_param.h with a #undef/#define sequence. without
the fix, the compiler saw the sequence #undef/#define/#define, and
balked at the double #define. The fix restores the intended
#define/#undef/#define sequence. And the usual header guard macro
protects against the double processing of the body of mercury_conf.h.
runtime/mercury_label.c:
Delete a #include of mercury_conf.h, since it is (and was) redundant.
tests/EXPECT_FAIL_TESTS.hlc.gc.pregen:
Expect the hard_coded/constant_prop_p1 test case to fail in the pregen
grade, since one of the things it tests, arithmetic constant propagation,
is explicitly disabled in this grade.
library/thread.closeable_channel.m:
Rename the `empty' result of closeable_channel.try_take to
`would_block'.
tests/hard_coded/closeable_channel_test.exp:
tests/hard_coded/closeable_channel_test.m:
Update test case.
This is a plausible sequence of events leading to a failure in the
hard_coded/closeable_channel_test.m test case:
thread A thread B
-------- --------
close(Chan)
channel.take(Chan)
-> mvar.read(Head)
-> semaphore.wait(Full)
is_closed(Chan, IsClosed)
-> mvar.try_read(Hole)
-> semaphore.try_wait(Full)
Thread B tries to take the next item from the channel, during which time
it holds the Full semaphore of the mvar at the read end of the channel.
Thread A attempts to verify that the channel is really closed.
It tries to read from the mvar at the write end of the channel, which is
the same mvar as thread B is reading from (because the channel is empty).
Thread A cannot acquire the Full semaphore of the mvar as the semaphore
is being held by thread B, resulting in the call is_closed(Chan, IsClosed)
to return with IsClosed = no.
library/thread.closeable_channel.m:
Delete the is_closed predicate. It was of questionable utility
anyway.
tests/hard_coded/closeable_channel_test.m:
Delete call to is_closed in test case.
compiler/superhomogeneous.m:
Record a unification between X and f(Yi) as possibly leading to
an occurs check warning only if f is known to be a data constructor,
either user defined or the builtin tuple constructor.
compiler/hlds_cons.m:
Add a version of the search_cons_table predicate that does not construct
the list of hlds_cons_defns that match the given cons_id. The new code
in superhomogeneous.m needs to know whether a cons_id is a known data
constructor, but it does not need to know its matching definitions,
and constructing that list is reasonably expensive when it has to be
executed for every single function symbol in every clause.
Add some documentation of the existing predicates, and separate their
implementations from each other with lines.
tests/warnings/occurs.{m,exp}:
Extend this test case both with a unifications we should warn about
(a circular unification whose top level cons_id is a tuple constructor)
and one we should not warn about (when the cons_is is NOT a data
constructor of any kind).
compiler/implementation_defined_literals.m:
compiler/prog_data.m:
Clarify related documentation.
A long time ago, test directories such as hard_coded had subdirectories
such as hard_coded/typeclasses. These have since been flattened out
(e.g. hard_coded/typeclasses is now just typeclasses), but there were
still remnants of the old approach. This diff deletes those remnants.
tests/*/Mmakefile:
Delete the TESTS_DIR and the SUBDIRS mmake variables; TESTS_DIR
was always set to "..", and SUBDIRS to the empty string.
Delete any references to the make variable NOT_WORKING, since
it is never used.
tests/Mmake.common:
Document that Mmakefiles in test directories don't have to set
TESTS_DIR and SUBDIRS anymore. Fix the formatting of the documentation
of the make variables they do still have to set.
Delete the targets and actions for handling subdirectories of
test directories, since there aren't any.
tests/Mmakefile:
Simplify some code.
tests/Mmakefile:
tools/bootcheck:
Add invalid_make_int and valid_make_int as new test directories.
tests/invalid_make_int/missing_interface_import.m:
tests/invalid_make_int/missing_interface_import.int_err_exp:
tests/invalid_make_int/missing_interface_import.int_err_exp2:
Move this test case from invalid to invalid_make_int, since it was
*already* testing the error message we get from "mmc --make-interface".
tests/invalid_make_int/Mercury.options:
tests/invalid_make_int/Mmakefile:
Set up testing of whether we get the right error messages during
the process of making .int files.
tests/Mmake.common:
Provide a way for tests in invalid_make_int to compare a .int_err file
against several .int_err_exp* files.
tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
Delete references to the test case moved to invalid_make_int.
tests/valid_make_int/bug499.m:
Add the test case that motivated this change.
tests/valid_make_int/Mercury.options:
tests/valid_make_int/Mmakefile:
Set up testing of whether we can generate .int files for modules.
As we discussed, it has fallen into disuse. Its main purpose was to
pave the way for the .net backend and later for the java and csharp grades.
Now that the .net backend is ancient history and the java and csharp grades
are established, that purpose is gone, and for every other purpose,
hlc is better because it is simpler and faster.
compiler/options.m:
Delete the --high-level-data option. It is no longer needed,
bacause the data representation scheme is now a direct function
of the target language.
doc/user_guide.texi:
Delete references to the --high-level-data option.
NEWS:
Mention that --high-level-data is no longer supported.
compiler/compute_grade.m:
Delete references to the hl grade component, and conform
to the deletion of the --high-level-data option.
compiler/compile_target_code.m:
Give some predicates more meaningful names, and conform to the
deletion of the --high-level-data option.
compiler/const_struct.m:
compiler/du_type_layout.m:
compiler/globals.m:
compiler/handle_options.m:
compiler/lco.m:
compiler/mercury_compile_main.m:
compiler/ml_gen_info.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_c_util.m:
Conform to the deletion of the --high-level-data option.
grade_lib/grade_spec.m:
grade_lib/grade_vars.m:
Delete the datarep solver variable, since the data representation
is now a direct function of the target language.
Delete the requirements involving the deleted solver variable.
grade_lib/grade_structure.m:
Delete the datarep component of the representation of MLDS C grades,
since its value would now be fixed.
grade_lib/grade_solver.m:
grade_lib/grade_string.m:
grade_lib/try_all_grade_structs.m:
grade_lib/var_value_names.m:
Conform to the changes above.
grade_lib/Mmakefile:
Link the grade library's test programs statically, like we do
the executables in the other directories.
library/io.m:
library/robdd.m:
library/rtti_implementation.m:
runtime/mercury_conf_param.h:
runtime/mercury_grade.h:
runtime/mercury_hlc_types.h:
Remove references to MR_HIGHLEVEL_DATA, as well as any code
that was guarded by #ifdef MR_HIGHLEVEL_DATA.
scripts/Mmake.vars.in:
scripts/canonical_grade.sh-subr:
scripts/final_grade_options.sh-subr:
scripts/init_grade_options.sh-subr:
scripts/mgnuc.in:
scripts/mgnuc_file_opts.sh-subr:
scripts/mmake.in:
scripts/mmc.in:
scripts/mtc:
scripts/parse_grade_options.sh-subr:
scripts/parse_ml_options.sh-subr.in:
Remove references to --high-level-data options.
In canonical_grade.sh-subr, compute the base grade more directly.
Remove a few left-over references to the assembler backend.
Add or fix vim modelines where relevant.
Fix inconsistent indentation.
Add missing ;;s in case statements.
Switch to using ${var} references instead of just $var.
tests/invalid/Mercury.options:
Make the test_feature_set test case run in grade java instead of hl.gc.
tests/invalid/test_feature_set.err_exp:
Update the expected out for the grade change.
This implements Mantis feature request #497.
compiler/parse_goal.m:
compiler/parse_dcg_goal.m:
When we find that a disable_warnings scope contains an unrecognized
warning name, generate a warning for it, and return this warning
*alongside*, not *instead of*, the disable_warnings scope goal.
This requires passing around not a maybe1(goal), as we have been doing
till now, but a maybe2(goal, list(warning_spec)), so this change
affects both (1) most of these two modules, and (2) most of the
modules below.
compiler/error_util.m:
Provide warning_spec as a synonym for error_spec, to be used in
situations like this where the "error_spec" is intended contain
something with severity_warning.
compiler/maybe_error.m:
Provide some new utility predicates now needed in parse_goal.m
and elsewhere.
compiler/prog_item.m:
Provide room in the representation of clauses for the warnings
generated by parsing the clause body goal.
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/du_type_layout.m:
compiler/get_dependencies.m:
compiler/make_hlds_passes.m:
compiler/parse_item.m:
compiler/parse_tree_out_clause.m:
compiler/prog_item_stats.m:
compiler/superhomogeneous.m:
Conform to the changes above.
tests/valid/unknown_warning.m:
Add this test case that checks whether a source file with an unknown
warning name in a disable_warnings scope can have code generated for it.
tests/warnings/unknown_warning.{m,exp}:
Add the same source file to this directory as well, to check whether
we get the right set of warnings.
tests/valid/Mmakefile:
tests/valid/Mercury.options:
tests/warnings/Mmakefile:
Enable the two new test cases.
This fixes github issue #85.
A complication is that the compiler itself has code, in make.util.m,
in which a disjunct has no solutions in only one mode of a two mode
function, but in this case, the code works (though its programming style
is pretty bad), so to get this change to bootstrap, we also need
a way to disable the "this disjunct can't have solutions" warning
in a scope.
compiler/simplify_goal_disj.m:
When we generate a "this disjunct can't succeed" warning,
do not insist on all modes generating that warning.
We used to insist on that because in a multi-mode predicate,
such warnings can be inappropriate for other modes.
Instead, achieve the same objective of minimizing programmer
confusion by adding a codicil explicitly mentioninging
this possibility.
Make the generation of this warning conditional on a simplify task
that can be disabled by "disable_warnings" scope.
compiler/prog_data.m:
Add "no_solution_disjunct" as a warning kind that may be disabled.
compiler/parse_goal.m:
Parse the new kind of warning.
compiler/prog_out.m:
Output the new kind of warning.
Improve some adjacent though unrelated code.
compiler/make.util.m:
Add code disable this warning in the affected predicate.
Comment out this code until installed compilers know how
to parse it and understand it.
compiler/Mercury.options:
Don't turn warnings into errors for make.util.m until then.
compiler/simplify_goal_scope.m:
compiler/simplify_info.m:
compiler/simplify_tasks.m:
Provide the mechanism needed to make it possible to disable
warnings about no solution disjuncts.
doc/reference_manual.texi:
Document the new disable-able warning.
NEWS:
Document both the changed behavior of the old warning
and the new way to disable it.
tests/warnings/gh85.{m,exp}:
A regression test for the bug, based on the code in the
github issue. It also tests the way to disable the warning.
tests/warnings/Mmakefile:
Enable the new test case.
To enable argument packing, we need to ensure that all modules that use
a type (say T) agree on its representation. The design I am working to
implement designates the .int file of the module that defines the type
(call it M) as the single source of truth for this. Every module that
imports the definition of the type, even through intermodule optimization,
gets that definition from M.int. The only module that depends on the type
that does not get its definition from M.int is M itself.
Before I can add code that makes the compiler get the representation of
T from M.int even when generating for M itself, I have to make sure that
at the time of that compiler invocation, M.int will (a) exist, and (b)
be up-to-date. That is why this change makes M.int a prerequisite
for generating target language code for M both when using mmc --make
and when using mmake.
compiler/make.dependencies.m:
Add M.int to the list of dependencies for M's code generation.
compiler/write_deps_file.m:
Add M.int as an extra source for the mmake rule containing
code generation dependencies.
Add an XXX.
tests/invalid/Mercury.options:
Delete --compile-only from a test case's options. Since we now
generate an interface file for the test case, the --compile-only
would otherwise clash with the --make-interface option needed for that.
compiler/prog_data.m:
Delete the simple_call_id data type, since it is isomorphic
to the pf_sym_name_arity type, which more clearly specifies
what is stored inside it.
compiler/prog_out.m:
Rename (all three versions of) simple_call_id_to_string to
pf_sym_name_orig_arity_to_string, both to conform to the change
in the input data type, and to emphasize that the resulting string
will contain the *original* arity of functions (which does not include
the return value), which is one less than the arity in the
pf_sym_name_arity structure (which, in accordance with the
convention inside the compiler that the arity is the length
of the argument list, *does* include the return value).
Delete the provision inside simple_call_id_to_string, now
pf_sym_name_orig_arity_to_string, for special handling of the names
of the predicates we use to implement promises, because it seems that
*none* of the call sites to any of the three versions of this function
can actually pass to it the identity of such a predicate. These calls
refer to a predicate or mode declaration item (which promise predicates
do not have), to clause or foreign_proc items (which again, promise
predicates cannot have) or calls to the predicate (promise predicates
cannot be called).
Delete the exported predicate simple_call_id_to_sym_name_arity.
It was called from exactly one place, inside prog_out.m itself,
and this diff inlines that call.
Avoid unnecessary forwarding of work from prog_out.m to error_util.m.
Delete (all three versions of) write_simple_call_id. The changes
below replace all their (few) uses with calls to
pf_sym_name_orig_arity_to_string.
compiler/error_util.m:
Replace the simple_call() error piece with qual_pf_sym_name_orig_arity,
and add a new version unqual_pf_sym_name_orig_arity. Their names
explicitly say that they print the original arities of functions,
also say whether they strip away any module qualification on the
sym_name inside the pf_sym_name_arity. We prefer the unqual version
in situations where the module qualifier is implicit, which usually means
that it must be the same as the name of the module being compiled, because
it reduces visual clutter for readers of error messages.
Put {qual,unqual}_pf_sym_name_orig_arity next to their most closely
related function symbols, {qual,unqual}_sym_name_arity, in the
format_component type. (This yields a few inconsequential changes
in the order of error_specs when sorted.)
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/check_libgrades.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/goal_expr_to_goal.m:
compiler/hlds_data.m:
compiler/hlds_desc.m:
compiler/hlds_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/inst_util.m:
compiler/llds_out_instr.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make_hlds_error.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/ml_unify_gen_construct.m:
compiler/mlds_to_c_stmt.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/modecheck_util.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_type_repn.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/pre_quantification.m:
compiler/pred_table.m:
compiler/prog_item.m:
compiler/recompilation.version.m:
compiler/term_constr_build.m:
compiler/termination.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen_construct.m:
compiler/unused_imports.m:
Conform to the changes above. Where I am pretty sure that in an error
message, the module qualifier of a name must be the current module,
use unqual_pf_sym_name_orig_arity instead of qual_pf_sym_name_orig_arity.
Add some sanity checks where they seem appropriate.
Replace sequences of io.write_strings with uses of io.format where this
yields clearer code. (This is why there were no remaining calls to
write_simple_call_id.)
Shorten some too-long lines.
In add_pred.m, make the order of some predicate definitions match
the order of the calls to them.
tests/invalid/ambiguous_method.err_exp:
tests/invalid/ambiguous_method_2.err_exp:
tests/invalid/bad_pred_arity.err_exp:
tests/invalid/bad_sv_unify_msg.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/bug113.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/bug278.err_exp:
tests/invalid/bug410.err_exp:
tests/invalid/bug476.err_exp:
tests/invalid/bug487.err_exp:
tests/invalid/complex_constraint_err.err_exp:
tests/invalid/constrained_poly_insts.err_exp:
tests/invalid/errors.err_exp:
tests/invalid/errors1.err_exp:
tests/invalid/errors2.err_exp:
tests/invalid/exported_mode.err_exp:
tests/invalid/field_syntax_error.err_exp:
tests/invalid/foreign_singleton.err_exp:
tests/invalid/funcs_as_preds.err_exp:
tests/invalid/imported_mode.err_exp:
tests/invalid/invalid_binary_literal.err_exp:
tests/invalid/invalid_float_literal.err_exp:
tests/invalid/invalid_hex_literal.err_exp:
tests/invalid/invalid_octal_literal.err_exp:
tests/invalid/make_opt_error.err_exp:
tests/invalid/missing_det_decls.err_exp:
tests/invalid/multimode_syntax.err_exp:
tests/invalid/null_char.err_exp:
tests/invalid/occurs.err_exp:
tests/invalid/record_syntax_errors.err_exp:
tests/invalid/ref_to_implicit_pred.err_exp:
tests/invalid/require_tailrec_1.err_exp:
tests/invalid/require_tailrec_1.err_exp2:
tests/invalid/require_tailrec_2.err_exp:
tests/invalid/require_tailrec_2.err_exp2:
tests/invalid/require_tailrec_3.err_exp:
tests/invalid/require_tailrec_3.err_exp2:
tests/invalid/state_vars_test2.err_exp:
tests/invalid/state_vars_test3.err_exp:
tests/invalid/state_vars_test5.err_exp:
tests/invalid/type_inf_loop.err_exp:
tests/invalid/typeclass_constraint_extra_var.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_test_12.err_exp:
tests/invalid/typeclass_test_2.err_exp:
tests/invalid/typeclass_test_9.err_exp:
tests/invalid/types.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/unbound_type_vars.err_exp:
tests/invalid/with_type.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
tests/warnings/double_underscore.exp:
tests/warnings/pragma_source_file.exp:
tests/warnings/singleton_test.exp:
tests/warnings/singleton_test.exp2:
tests/warnings/singleton_test.exp3:
tests/warnings/singleton_test.exp4:
tests/warnings/singleton_test_state_var.exp:
tests/warnings/warn_return.exp:
tests/warnings/warn_return.exp2:
tests/warnings/warn_return.exp3:
tests/warnings/warn_succ_ind.exp:
tests/warnings/warn_succ_ind.exp2:
tests/warnings/warn_succ_ind.exp3:
tests/warnings/warn_succ_ind.exp4:
Update all these expected output files. Most changes are due to
predicate and function names no longer being module qualified when
the module qualification is obvious. A few changes are due to the
change in the relative ordering of the function symbols of the
format_component type.
For singleton_test, warn_return and warn_succ_ind in warnings,
the changes to the non-C .exp files were done by hand, so they
may have the wrong white space.
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.
Sometimes, when a test case fails in a workspace even though it has passed
before, it is not clear whether the cause of the failure is that the
updated code in the workspace is generating a different sequence of
mmc invocations, or whether the same invocations do something different.
The new option allows developers to answer that question by keeping the logs
from a bootcheck in an unchanged workspace, and comparing the logs
between the workspaces.
tools/bootcheck:
If given the --keep-success-log-files option, set an environment variable
that records this fact.
tests/run_one_test:
If this environment variable is set, then rename the .log files of
successful test cases as .kept_log files instead of deleting them.
Note that we cannot keep the .log files around under their original name,
because we currently interpret the presence of *any* .log file
in a test directory as meaning "some tests failed in this test directory".
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.
library/list.m:
Add a predicate version of map_corresponding3.
Move a predicate next to its only call site.
Use more meaningful variable names.
library/map.m:
library/tree234.m:
Add several predicates: foldl4_values, foldl5_values, filter_map_values
and filter_map_values_only.
library/multi_map.m:
Embed an implicit assertion in a call.
library/set_ordlist.m:
Give a predicate a better name.
library/NEWS:
Announce the new additions.
Put the list of updated library modules back into alphabetical order.
tests/hard_coded/test_map_filter.{m,exp}:
Test the one wholly new utility predicate.
library/hash_table.m:
Switch to using kv_lists to represent items in overflowing buckets.
This is both cleaner and more efficient.
Give many types, function symbols, predicates, functions and variables
more meaningful names.
Add XXXs to mark some significant potential problems.
When an operation has both function and predicate forms, make the
function form forward to the predicate form, as we do in the rest
of the standard library.
Make equality testing between a key in a hash bucket and a search key
explicit in all cases.
library/kv_list.m:
Add some functionality that hash_table.m now needs from kv_lists.
library/assoc_list.m:
Add some functionality that kv_list.m now has, to maintain parity
between the two modules.
NEWS:
Announce the changes to assoc_list.m. (The changes to kv_list are moot,
since it is a new module.)
tests/hard_coded/hash_table_test.{m,exp}:
Make the progress messages output by this test more meaningful,
and update its programming style.
Currently, the hash functions for (some of) the primitive types are defined in
three places:
1. The hash_table module.
2. The version_hash_table module (duplicates of the above).
3. Some (but not all) of the library modules for the primitive types.
This change makes the library module for a primitive type provide the hash
function for that type and deprecates the versions in the hash table modules.
Additionally, deprecate the "generic" has functions in the hash table modules.
library/hash_table.m:
library/version_hash_table.m:
As above.
library/char.m:
library/int.m:
library/uint.m:
Add hash/1 and hash/2.
library/float.m:
Add hash/2.
library/robdd.m:
Replace a call to the deprecated function.
NEWS:
Announce the above additions and deprecations.
tests/hard_coded/hash_table_delete.m:
tests/hard_coded/hash_table_test.m:
tests/hard_coded/version_hash_table_delete.m:
tests/hard_coded/version_hash_table_test.m:
Conform to the above change.
Common subexpression elimination (cse) declines to do its job of transforming
(
X = f(A1, ..., An),
goal A
;
X = f(B1, ..., Bn),
goal B
)
into
X = f(X1, ..., Xn),
(
A1 = X1, ..., An = Xn,
goal A
;
B1 = X1, ..., Bn = Xn,
goal B
)
when the insts of some of X's arguments are at least partially unique,
because mode analysis cannot track uniqueness through the extra unifications
that this transformation introduces. When this happens, and the procedure
this code is in does not match its declared determinism, generate a message
that gives this fact as a possible reason for that determinism mismatch.
This fixes Mantis bug #496 to the extent that we *can* fix it
without rewriting the whole of mode analysis.
compiler/hlds_pred.m:
Provide a slot in the proc_info for recording whether cse has declined
to pull a common unification out of a branched control structure because
of this concern, and if so, at what locations in the source code.
An unrelated change: move a slot used only by constraint-based mode
analysis, which is never enabled, from the proc_info to the proc_sub_info.
This should improve both speed and memory consumption, though very
slightly.
compiler/cse_detection.m:
Record each such location in this slot.
Doing this requires a change in approach. Previously, we did not try
to pull a unification out of any branch of a branched control structure
if it involved (partially or wholly) unique arguments. However, doing
this in just one branch cannot possibly affect the output of cse detection,
since it pulls a unification out of a branch only if can pull the same
unification out of all the other branches as well.
Our new approach is to transform branched control structures regardless
of uniqueness, and then *undo* the transformation (simply by discarding
its result) if it involves unique arguments. It is such undoing that we
record in the proc_info.
compiler/switch_detection.m:
Conform to the new approach.
compiler/hlds_out_pred.m:
Print the contents of the new slot in HLDS dumps.
compiler/det_report.m:
If the actual determinism of a procedure, as computed by determinism
analysis, does not match its declared determinism, *and* if the proc_info's
new slot says that cse declined to pull some common unifications
out of a branched control structure, then mention that fact, and
the usual fix, as a possible explanation of the determinism problem.
tests/invalid/bug496.{m,err_exp}:
The Mantis test case.
tests/invalid/Mmakefile:
Enable the new test case.
Delete some procedures that have been marked as obsolete since before the 14.01
release.
library/hash_table.m:
library/version_array.m:
As above.
NEWS:
Announce the deletions.
tests/hard_coded/hash_table_delete.m:
Replace a call to one of the deleted functions.
compiler/mode_errors.m:
Simplify the wording of the new error message component added yesterday.
Mention a possible reason for inst mismatches when the inst contains
a higher order component. Put this in the parentheses, because it is
*not* guaranteed to be the actual reason.
compiler/inst_util.m:
Add a utility predicate for the new code in mode_errors.m.
tests/invalid/any_passed_as_ground.err_exp:
tests/invalid/constrained_poly_insts2.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/try_detism.err_exp:
Expect the updated error messages.
compiler/mode_errors.m:
There are two improvements.
The first and much the more important is that when a call does not match
any of the declared modes of the called predicate or function, we now
print the names and insts of any arguments whose insts, by themselves,
do not match any of the callee's modes. Instead of reporting "here are
all the arguments, here are all their insts, find out for yourself
which one is wrong", the compiler now tells the programmer explicitly
which one is wrong in almost all cases. (Not all. If e.g. two args <A, B>
have insts <free, free>, but the callee has two modes, <in, out> and
<out, in>, then the compiler won't report either arg, since neither arg
is wrong by itself.)
The second improvement is that when the verbosity settings ask us
to print all possible reasons why we can't schedule a conjunction,
instead of our default approach of printing the only the first,
we now put a blank line between the different reasons, for visual
separation.
compiler/modecheck_call.m:
Preserve the extra information now needed by mode_errors.m.
compiler/modecheck_util.m:
Conform to the changes above.
tests/invalid/any_passed_as_ground.err_exp:
tests/invalid/anys_in_negated_contexts.err_exp:
tests/invalid/constrained_poly_insts2.err_exp:
tests/invalid/ho_default_func_1.err_exp:
tests/invalid/ho_default_func_3.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/modes_erroneous.err_exp:
tests/invalid/try_detism.err_exp:
Expect the updated error messages for these tests.
This fixes Mantis bug #493.
compiler/common.m:
Don't apply the common_struct optimization if doing so could possibly
invalidate the annotations generated by mark_static_terms.m, which the
MLDS code generator relies on.
Move the tests for the applicability of the common_struct optimization
for both construction and deconstruction unifications next to each other.
Add XXXs about possible problems this code may have when applied to code
that does region based memory allocation.
tests/valid/bug493.m:
A simplified version of the Mantis test case.
tests/valid/Mmakefile:
tests/valid/Mercury.options:
Enable the new test case, and specify the options that originally caused
the bug to manifest itself.
tests/mmc_make/Mmakefile:
tests/mmc_make/bug489.exp:
tests/mmc_make/bug489.m:
tests/mmc_make/bug489.other.m:
tests/mmc_make/lexer.m:
Add test where a separate sub-module is stored in a source file
with a name that could be confused for a standard library module.
Delete now-obsolete code to search for a module in files matching
partially qualified versions of the module name.
compiler/find_module.m:
As above.
compiler/read_modules.m:
compiler/write_deps_file.m:
Conform to changes.
tests/invalid/bad_module_name.err_exp
tests/invalid/bad_module_name.m
tests/invalid/bad_module_name_sub.m -> tests/invalid/bad_module_name.sub.m:
Rename sub-module and its source file so that the source file will
be found.
This should fix Mantis bug #489, which shows that without this,
the compiler can mistakenly believe that a file with a name such as lexer.m
contains a module of the standard library, rather than a submodule named
test.lexer.
compiler/parse_module.m:
Require that :- module declarations specify the expected name.
The name may be expected because it exactly matches the filename
(as above), or because mmc -f has recorded the actual name
as the expectation.
Factor report_module_has_unexpected_name out of
check_module_has_expected_name, since it is needed on its own.
Simplify its code.
Simplify the code for doing checks on :- end_module declarations.
doc/reference_manual.texi:
Document this change in the reference manual.texi.
Replace references to "the University of Melbourne Mercury implementation"
with just "the Melbourne Mercury implementation".
slice/Mmakefile:
Run mmc -f *.m before making dependencies, because the modules copied
from mdbcomp have non-fully-qualified filenames.
*/Mmakefile:
Delete inappropriate .PHONY directives from Mercury.modules targets.
Include Mercury.modules among the files to be deleted by clean_local
targets.
tests/submodules/ts.tsub.m:
Provide the full name of this module in its :- module declaration.
tests/submodules/initialise_parent.initialise_child.m:
Fix white space.
tests/submodules/*.*.m:
Move separate submodules to their fully qualified filenames.