mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-21 04:13:46 +00:00
083d376e6598628362ee91c2da170febd83590f4
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c78c8b6a32 |
Update tests/invalid/invalid_int.err_exp
tests/invalid/invalid_int.err_exp:
Update expected error output for 32-bit machines.
|
||
|
|
810cb54ed0 |
Fix failing test case.
tests/invalid/invalid_int.err_exp:
Conform to changes in the way error messages are printed.
(This is the 32-bit version of this and presumably wasn't updated
when the 64-bit version was.)
|
||
|
|
253378fe21 |
Improve error messages for malformed lambda expressions.
Do this by insisting that terms whose top level(s) look like lambda
expressions should be parsed as lambda expressions, and return error
messages if that parsing attempt fails.
I did this is in several commits to modules in the parse_tree.m package
that translated terms to the parse tree, i.e. to goal_exprs. This diff
does the same thing for lambda expressions.
NEWS:
Document this change, as well as other, similar changes in the recent past.
compiler/superhomogeneous.m:
When translating a var-functor unification, which has the form
X = f(Y1, ..., Yn), to the HLDS, we parse the right hand side term,
looking for Mercury constructs such as lambda expressions and
field accesses. We used to do this by checking if the RHS was
a well-formed version of the construct we were looking for,
and falling back to parsing it as an ordinary term. That meant that
terms that the programmer *intended* to be lambda expressions,
but which contained a syntax error, were not diagnosed during the
construction of the HLDS, but during a later pass. Virtually always,
that later pass was typechecking. Since in such cases, the typechecker
is given terms whose function symbols were *intended* to be the "keywords"
of Mercury constructs (to the extent that Mercury *has* keywords),
not the names of data constructors or predicates, those error messages
were almost always confusing, and at best an *indirect* indication
of the actual problem with the code.
This diff changes things so that when the top function symbol on
the RHS of a unification is a Mercury "keyword" used only in lambda
expressions, we commit to parsing it as such. If the parsing fails,
we now generate an error message that describes the problem *directly*.
To make the task of generating good error messages easier, and to make it
possible to generate *consistent* error messages for the same error
in different contexts, unify the four separate pieces of code that
*used* to parse different kinds of lambda expressions. These four
pieces of code used to parse
- predicates defined using DCG notation;
- predicates defined using non-DCG notation;
- functions that used the default function mode and determinism; and
- functions that did not use the default function mode and determinism.
The unified code allows a function lambda expression to omit the
default argument modes *independently* of whether it omits the default
determinism, and vice versa. The old code did not do that: if you didn't
explicitly specify one, you couldn't explicitly specify the other either,
probably because it would have required two more pieces of code.
The language reference manual says, in section 8.1:
As with ‘:- func’ declarations, if the modes and determinism
of the function are omitted in a higher-order function term, then
the modes default to ‘in’ for the arguments, ‘out’ for
the function result, and the determinism defaults to ‘det’.
This text is vague on whether the modes and determinism are *allowed*
to be omitted independently. The old behavior was a strict reading
of this text. The new behavior follows the most liberal possible reading,
and thus allows all the behaviors that the old one did, and more.
Integrate the test for big integers that are too big to be represented
with the conversion of all ordinary functors into cons_ids, both to
simplify the code, and to speed it up. In the process, improve the
error message for too-big integers.
compiler/add_clause.m:
Don't try to generate warnings for singleton variables in a clause
if the clause had syntax errors. Part of the parser's recovery from
those syntax errors (e.g. when they occur in lambda expressions' clause
heads) may have included not translating parts of the original term
into the parsed clause body, so any such warnings could be misleading.
Such warnings could also be correct, but I expect most programmers
would prefer to miss some correct singleton warnings while the
syntax errors are present in their code, and get them only once
they have fixed those syntax errors, than to have to wade through
misleading errors messages for the initial syntax error to get to
the real ones.
compiler/field_access.m:
Clarify the text of an error message.
Delete a predicate that superhomogeneous.m no longer needs.
compiler/mercury_compile_front_end.m:
Don't proceed past typechecking if the parser found syntax errors,
since any errors we find later, e.g. as part of mode checking,
are quite likely to be avalanche errors caused by those syntax errors.
The reason why this wasn't a problem in the past is that when
the program contained malformed uses of builtin constructs such as
lambda expressions and field accesses, the parser used to simply
transform the terms containing the malformed constructs into the arguments
of call goals and unifications, and it was the typechecker that discovered
that these function symbols did not match any declared type.
The "type errors" generated for such problems told the compiler
not to run later compiler passes to prevent avalanche errors.
We now report syntax errors earlier, during the construction of the HLDS,
and it is entirely possible that the parser's recovery from those errors
leaves *no* type errors to be reported. This is why we need to make
the presence of syntax errors in a predicate block the invocation
of later passes.
compiler/typecheck.m:
Return whether the predicates we typechecked had syntax errors,
to make the change in mercury_compile_front_end.m possible.
compiler/state_var.m:
If a lambda expression has two or more arguments of the form !X,
we now print an error message for each, with each message naming the bad
state variable and giving the context of the argument. We used to
print only a single message saying that *some* argument misused
state variables this way. Similarly, we now print the correct context
for !X appearing as a function result, whether in a lambda expression
or at the top level of a clause.
The actual printing of those error messages takes place elsewhere,
but change the utility predicates exported by state_var.m to make
the change possible.
Change the error message we generate for !X appearing as a function
result, to avoid suggesting a possible repair that is virtually never
the right repair.
compiler/mode_util.m:
Delete a predicate that was used only by superhomogeneous.m; an updated
version of that predicate is now in superhomogeneous.m itself.
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
Instead of exporting predicates to module qualify the whole list of
argument modes of a lambda expression, export predicates that module
qualify only one such mode, since that is what superhomogeneous.m
now wants.
compiler/hlds_clauses.m:
Add access predicates for fields of the clauses_info type that previously
did not have them, including the one that records the presence of syntax
errors.
Put related fields of the clauses_info together.
Group both the declarations and the definitions of the access predicates
together, and put them in the same order as the fields themselves.
compiler/add_class.m:
compiler/add_pred.m:
compiler/add_pragma_type_spec.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/unify_proc.m:
Conform to the changes above.
tests/invalid/lambda_syntax_error.err_exp:
Print one error message for each of the four malformed lambda expressions
in this test case, instead of the 13 avalanche messages we used to get
from the typechecker, which tried to interpret the malformed lambda
expression heads as calls, unifications etc.
The motivation for this diff was a set of similar set of avalanche error
messages for a real-life syntax error in a lambda expression in a change
I worked on a while ago.
tests/benchmarks/deriv.{m,exp}:
This test case used to use "^" as a data constructor (to represent
raising X to the Nth power). Since the parser now insists on treating it
as a field access operator, replace "^" with "power". (This test has
the excuse of predating the addition of field access syntax to Mercury
by several years.)
tests/dppd/grammar_impl.m:
This test case used to define a type which contained "is" as a data
constructor. After this diff, this is no longer allowed (as part of
"is detism", it looks to the parser like the top constructor in a
lambda expression head, and therefore as the top constructor of
the lambda expression as a whole if it has no body), so add the type
name as a prefix to this data constructor. To future-proof the test case,
do the same with the several other data constructors that also duplicate
the names of Mercury keywords.
tests/hard_coded/pprint_test2.{m,exp}:
tests/hard_coded/write.{m,exp}:
tests/hard_coded/write_binary.{m,exp}:
These test cases used to define a type which contained ":-" as a data
constructor. After this diff, this is no longer allowed, so replace them
with "?-". (The tests check how io.m formats terms whose data constructor
is an operator, so the replacement needs to be an operator, and Mercury
syntax does not use "?-"; library/ops.m lists it as an operator only
because it is an operator in Prolog.)
Update write_binary.m to conform to our current style guide, and to avoid
using the recently-deprecated io.make_temp.
tests/invalid/invalid_int.err_exp:
Expect the updated text of the error message for a too-big
integer constant.
tests/invalid/record_syntax_error.err_exp:
Expect the updated text of the error message for a malformed field name.
tests/invalid/state_vars_test3.err_exp:
Expect the updated text of the error message for a !X appearing
as the result of a lambda function.
tests/invalid/state_vars_test4.err_exp:
Expect the error message for a !X lambda argument, but (since we now
stop after typechecking in the presence of such syntax errors),
don't expect the avalanche error messages we used to print from the
mode checker.
|
||
|
|
62ec97d443 |
Report imports shadowed by other imports.
If a module has two or more import_module or use_module declarations
for the same module, (typically, but not always, one being in its interface
and one in its implementation), generate an informational message about
each redundant declaration if --warn-unused-imports is enabled.
compiler/hlds_module.m:
We used to record the set of imported/used modules, and the set of
modules imported/used in the interface of the current module. However,
these sets
- did not record the distinction between imports and uses;
- did not allow distinction between single and multiple imports/uses;
- did not record the locations of the imports/uses.
The first distinction was needed only by module_qual.m, which *did*
pay attention to it; the other two were not needed at all.
To generate messages for imports/uses shadowing other imports/uses,
we need all three, so change the data structure storing such information
for *direct* imports to one that records all three of the above kinds
of information. (For imports made by read-in interface and optimization
files, the old set of modules approach is fine, and this diff leaves
the set of thus *indirectly* imported module names alone.)
compiler/unused_imports.m:
Use the extra information now available to generate a
severity_informational message about any import or use that is made
redundant by an earlier, more general import or use.
Fix two bugs in the code that generated warnings for just plain unused
modules.
(1) It did not consider that a use of the builtin type char justified
an import of char.m, but without that import, the type is not visible.
(2) It scanned cons_ids in goals in procedure bodies, but did not scan
cons_ids that have been put into the const_struct_db. (I did not update
the code here when I added the const_struct_db.)
Also, add a (hopefully temporary) workaround for a bug in
make_hlds_passes.m, which is noted below.
However, there are at least three problems that prevent us from enabling
--warn-unused-imports by default.
(1) In some places, the import of a module is used only by clauses for
a predicate that also has foreign procs. When compiled in a grade that
selects one of those foreign_procs as the implementation of the predicate,
the clauses are discarded *without* being added to the HLDS at all.
This leads unused_imports.m to generate an uncalled-for warning in such
cases. To fix this, we would need to preserve the Mercury clauses for
*all* predicates, even those with foreign procs, and do all the semantic
checks on them before throwing them away. (I tried to do this once, and
failed, but the task should be easier after the item list change.)
(2) We have two pieces of code to generate import warnings. The one in
unused_imports.m operates on the HLDS after type and mode checking,
while module_qual.m operates on the parse tree before the creation of
the HLDS. The former is more powerful, since it knows e.g. what types and
modes are used in the bodies of predicates, and hence can generate warnings
about an import being unused *anywhere* in a module, as opposed to just
unused in its interface.
If --warn-unused-imports is enabled, we will get two separate set of
reports about an interface import being unused in the interface,
*unless* we get a type or mode error, in which case unused_imports.m
won't be invoked. But in case we do get such errors, we don't want to
throw away the warnings from module_qual.m. We could store them and
throw them away only after we know we won't need them, or just get
the two modules to generate identical error_specs for each warning,
so that the sort_and_remove_dups of the error specs will do the
throwing away for us for free, if we get that far.
(3) The valid/bug100.m test case was added as a regression test for a bug
that was fixed in module_qual.m. However the bug is still present in
unused_imports.m.
compiler/make_hlds_passes.m:
Give hlds_module.m the extra information it now needs for each item_avail.
Add an XXX for a bug that cannot be fixed right now: the setting of
the status of abstract instances to abstract_imported. (The "abstract"
part is correct; the "imported" part may not be.)
compiler/intermod.m:
compiler/try_expand.m:
compiler/xml_documentation.m:
Conform to the change in hlds_module.m.
compiler/module_qual.m:
Update the documentation of the relationship of this module
with unused_imports.m.
compiler/hlds_data.m:
Document a problem with the status of instance definitions.
compiler/hlds_out_module.m:
Update the code that prints out the module_info to conform to the change
to hlds_module.m.
Print status information about instances, which was needed to diagnose
one of the bugs in unused_imports.m. Format the output for instances
nicer.
compiler/prog_item.m:
Add a convenience predicate.
compiler/prog_data.m:
Remove a type synonym that makes things harder to understand, not easier.
compiler/modules.m:
Delete an XXX that asks for the feature this diff implements.
Add another XXX about how that feature could be improved.
compiler/Mercury.options.m:
Add some more modules to the list of modules on which the compiler
should be invoked with --no-warn-unused-imports.
compiler/*.m:
library/*.m:
mdbcomp/*.m:
browser/*.m:
deep_profiler/*.m:
mfilterjavac/*.m:
Delete unneeded imports. Many of these shadow other imports, and some
are just plain unneeded, as shown by --warn-unused-imports. In a few
modules, there were a *lot* of unneeded imports, but most had just
one or two.
In a few cases, removing an import from a module, because it *itself*
does not need it, required adding that same import to those of its
submodules which *do* need it.
In a few cases, conform to other changes above.
tests/invalid/Mercury.options:
Test the generation of messages about import shadowing on the existing
import_in_parent.m test case (although it was also tested very thoroughly
when giving me the information needed for the deletion of all the
unneeded imports above).
tests/*/*.{m,*exp}:
Delete unneeded imports, and update any expected error messages
to expect the now-smaller line numbers.
|
||
|
|
6a267a8f07 |
Make base_string_to_int check overflow/underflow for all bases.
Make base_string_to_int check for overflow and underflow when converting from strings in all bases, not only base 10. Fixes bug #376. Previously it was stated that "numbers not in base 10 are assumed to denote bit patterns and are not checked for overflow." Though not a safe assumption in general, in Mercury source files it is useful to be able to write values with the high bit set, e.g. 0x80000000 on 32-bit machines, that would be greater than max_int if interpreted as a positive integer. The changed behaviour of base_string_to_int would reject such literals from Mercury sources, so additional changes are required to maintain that usage. However, unlike before, the compiler will report an error if some non-zero bits of the literal would be discarded. library/string.m: Enable overflow/underflow checking for base_string_to_int for any base. Update documentation. library/lexer.m: Allow `big_integer' token functor to represent non-base 10 literals as well. Add `integer_base' type. library/term.m: Add `big_integer' term functor. Add `integer_base' type. library/term_io.m: Add private helper functions `integer_base_int' and `integer_base_prefix'. Conform to changes. library/parser.m: Pass through `big_integer' tokens as `big_integer' terms. Conform to changes. compiler/prog_util.m: Add predicate to convert integer terms to ints with the aforementioned concession for bit patterns. `make_functor_cons_id' can now fail due to integer tokens exceeding the range of `int'. compiler/superhomogeneous.m: Make `unravel_var_functor_unification' convert `big_integer' tokens on the RHS to a simple `int' with the aforementioned concession for bit patterns, or add an error message if any significant bits would be discarded. compiler/fact_table.m: compiler/mercury_to_mercury.m: compiler/module_imports.m: compiler/prog_io_util.m: Conform to changes. compiler/make.util.m: Delete unused predicate. tests/general/test_string_to_int_overflow.m: tests/general/test_string_to_int_overflow.exp: tests/general/test_string_to_int_overflow.exp2: tests/general/test_string_to_int_overflow.exp3: Rewrite test case. tests/hard_coded/lexer_bigint.exp: tests/hard_coded/lexer_bigint.exp2: tests/hard_coded/read_min_int.exp: tests/hard_coded/read_min_int.exp2: Update expected outputs due to the lexer and term module changes. tests/invalid/Mmakefile: tests/invalid/invalid_int.err_exp: tests/invalid/invalid_int.err_exp2: tests/invalid/invalid_int.m: Add new test case. NEWS: Announce the changes. |