Files
mercury/tests/invalid/assert_in_interface.err_exp
Zoltan Somogyi 638551faaa Add missing code for parsing 'promise_ex's.
compiler/parse_item.m:
    Add previously missing code for parsing promise_ex declarations
    (promise_exclusive, promise_exhaustive, and promise_exclusive_exhaustive)
    of the form ":- all [vars] promise_ex... goal."

    Comment out the code for parsing another form of such declarations,
    ":- promise_ex... goal.", which also had missing code and thus
    never worked.

    Check whether the first argument of a "some" or "all" quantifier
    is a list of variables in just one place.

compiler/status.m:
    Fix a bug in code that already had an XXX. Without this fix,
    the new test case would get a spurious error from check_promise.m.

compiler/check_promise.m:
    Fix several instances of another bug uncovered by the fix in status.m.
    The problem was that the code that checked promises in the interface
    section to see whether they contained any inappropriate references
    to predicates or data constructors defined in the implementation section
    considered, due to the bug now fixed in status.m, predicates and data
    constructors imported from other modules to be defined in the
    implementation section of this module. In fact, it did not even consider
    the question of whether the predicate or data constructor was defined
    in the current module at all.

    Fixing this requires making a choice: may promises in the interface
    refer to predicates and data constructors defined in other modules,
    or not? The language manual does not answer this question, or any
    other, about promises, since (a) all its documentation of promise
    declarations is commented out, and (b) even the commented-out prose
    is silent on references to other modules in promises.

    The fix chosen by this diff is to let a promise refer to other modules
    only if it is in the implementation section. The reason for this is that
    I would find it strange to have module A rely on a promise made by
    module B about the properties of e.g. a predicate in module C.
    While having the code of module B itself rely on a promise that
    module B itself makes about module C is not ideal, at least if the
    promise is wrong, the effect of the wrong promise will be local.
    (In a review comment, Julien pointed out that having module B make promise
    about a predicate in module C may make sense if module C was provided
    by an external entity, which may make moving the promise itself
    to module C problematic in practice.)

    Make error messages clearer via additional punctuation.

compiler/intermod.m:
    Make the result of writing out a promise look better.

compiler/parse_tree_out.m:
    Make the code writing out promises add a parentheses, without which
    we could not read the promise back in.

tests/valid/promise_ex.m:
    Add a test case for whether we can parse a promise_ex declaration.

tests/valid/Mmakefile:
    Enable the new test case.

tests/invalid/assert_in_interface.err_exp:
    Expect the error message we now generate for cross-module promises
    in interface sections.

tests/invalid/tricky_assert1.err_exp:
    Expect additional punctuation in an error message.
2021-12-07 17:04:03 +11:00

8 lines
482 B
Plaintext

assert_in_interface.m:012: In interface for module `assert_in_interface':
assert_in_interface.m:012: error: exported promise refers to predicate
assert_in_interface.m:012: `list.last'/2, which is defined in another module,
assert_in_interface.m:012: `list'.
assert_in_interface.m:012: Either move the promise into the implementation
assert_in_interface.m:012: section, or move it to the `list' module. In most
assert_in_interface.m:012: cases, the latter is preferable.