mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-18 02:43:40 +00:00
Github issue #118 reports a compiler abort that happens when table_gen.m attempts to perform that transformation that implements the tabling of I/O actions for declarative debugging, and a sanity check finds that the procedure's determinism is not model_det. We could change table_gen.m to not transform the affected predicate in such cases. This change could fix *this specific* compiler abort, but it is better to fix the root cause, which is that our semantic analysis passes have not detected and reported a violation of our semantic rules, and have allowed the affected predicate to flow through to the middle end to be processed. compiler/det_analysis.m: compiler/det_report.m: We used to check whether predicates with I/O state arguments have one of the permitted model_det determinisms as part of det_infer_proc. Github issue #118 arose because det_infer_proc processes only predicates defined in the current module. It was also strange that some properties of mode declarations were checked by det_infer_proc in det_analysis.m (which can be invoked on a procedure more than once during mode inference), while others were checked by check_determinism_of_procs in det_report.m (which is only ever invoked on a procedure once, at the end of determinism analysis). Move the checks on mode declarations all to det_report.m. Partly this is to fix the above code smell, but mainly so that we can add check_determinism_of_imported_procs, which performs the part of the job of check_determinism_of_procs that is appropriate for imported procedures. Make the error message for invalid mode declarations more specific by listing the given invalid determinism as well as the possible valid determinisms. To make the above possible without doing unnecessary checks on compiler-constructed procedures that are "born correct", separate out imported procedures from born-correct procedures. Previously, they were lumped together as "no inference needed" procedures. tests/invalid/ho_unique_error.err_exp: tests/invalid/mostly_uniq1.err_exp: tests/invalid/mostly_uniq2.err_exp: Expect the extra detail in error messages. tests/invalid/io_in_ite_cond.err_exp: tests/invalid/magicbox.err_exp: tests/invalid/try_detism.err_exp: Expect an error message about the invalid determinism of a procedure with I/O state args. Previously, we did not generate an error message for these issues.
16 lines
989 B
Plaintext
16 lines
989 B
Plaintext
mostly_uniq1.m:009: In `my_main'(di, uo):
|
|
mostly_uniq1.m:009: error: `multi' is not a valid determinism for a predicate
|
|
mostly_uniq1.m:009: that has I/O state arguments. The valid determinisms for
|
|
mostly_uniq1.m:009: such predicates are `det', `cc_multi' and `erroneous',
|
|
mostly_uniq1.m:009: since the I/O state can be neither duplicated nor
|
|
mostly_uniq1.m:009: destroyed.
|
|
mostly_uniq1.m:023: In clause for `my_main(di, uo)':
|
|
mostly_uniq1.m:023: in argument 2 of call to predicate `io.write_int'/3:
|
|
mostly_uniq1.m:023: mode error: variable `STATE_VARIABLE_IO_0' has
|
|
mostly_uniq1.m:023: instantiatedness `mostly_unique',
|
|
mostly_uniq1.m:023: expected instantiatedness was `unique'.
|
|
mostly_uniq1.m:023: This kind of uniqueness mismatch is usually caused by
|
|
mostly_uniq1.m:023: doing input/output or some other kind of destructive
|
|
mostly_uniq1.m:023: update in a context where it can be backtracked over,
|
|
mostly_uniq1.m:023: such as the condition of an if-then-else.
|