mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-27 07:14:20 +00:00
This consists of two main parts.
The first part is creating a single point in time in a compiler invocation
when this check can be done. This point in time has to be after typechecking,
because (in the presence of type inference) this is the earliest point
when type information is guaranteed to be available (in the absence of
type errors, of course). The logical time is therefore the post-typecheck pass.
The post-typecheck pass also does the closely related task of propagating type
information into insts, but only the insts inside predicates' mode
declarations. Before this diff, the task of propagating type information
into the insts in the modes in lambda expressions was left to be done
*during*, not *before*, mode checking. (I think the rationale was that
you want to have propagated types into an inst in a procedure signature before
you may see a call to that procedure. Mode checking may encounter a call
to procedure of a predicate before processing that procedure, but due to
mode reordering, it won't ever encounter a call to a lambda expression
before processing the unification whose right hand side contains that
lambda expression.) However, it is conceptually simpler if the post-typecheck
pass takes over the propagation of types into insts even in lambda expressions,
which is what this diff does.
The second part is cleaning up the code that does this propagation,
to allow that cleanup to be reviewed separately from its modification
to check for uses of user-defined insts for values of types other than
the types that they are declared to be for.
compiler/inst_mode_type_prop.m:
Give most predicates in this module more descriptive names
that also fit into a single naming scheme.
compiler/hlds_pred.m:
Add a predicate marker that allows typechecking to tell the
post-typecheck pass that a predicate contains one or more lambda
expressions.
compiler/typecheck_info.m:
Add a slot to the typecheck_info in which we can record the presence
of a lambda expression.
compiler/typecheck.m:
When processing lambdas, record this fact in the new typecheck_info slot.
When processing a predicate bodies causes this slot to be set,
add the new marker to the predicate.
compiler/post_typecheck.m:
For predicates for which the typechecking pass left this marker,
propagate types not just into the insts in the predicate's mode
declarations, but also into the insts in lambda expressions.
This is an extra traversal of the predicate body, but only
a relatively small minority of predicate bodies will need it done.
Rename a predicate to fit in with the new naming scheme in
inst_mode_type_prop.m.
Improve the wording of an error message.
compiler/modecheck_unify.m:
Do not propagate type info into the insts in lambda expressions,
since the post-typecheck will have already done that task.
compiler/add_special_pred.m:
compiler/inst_lookup.m:
compiler/inst_user.m:
compiler/intermod.m:
compiler/table_gen.m:
Conform to the changes above.
tests/invalid_nodepend/invalid_main.err_exp:
Expect the updated error message from post_typecheck.m..
12 lines
687 B
Plaintext
12 lines
687 B
Plaintext
invalid_main.m:006: Error: module `invalid_main' should start with either an
|
|
invalid_main.m:006: `:- interface' or an `:- implementation' declaration.
|
|
invalid_main.m:006: The following assumes that the missing declaration is an
|
|
invalid_main.m:006: `:- implementation' declaration.
|
|
invalid_main.m:009: Error: `main'/2 must be `det' or `cc_multi'.
|
|
invalid_main.m:009: Error: `main'/2 must have mode `(di, uo)'.
|
|
invalid_main.m:009: Error: both arguments of `main/2' must have type
|
|
invalid_main.m:009: `io.state'.
|
|
invalid_main.m:009: In `main'(di, out):
|
|
invalid_main.m:009: warning: determinism declaration could be tighter.
|
|
invalid_main.m:009: Declared `multi', inferred `det'.
|