[m-rev.] for review: warn about unneeded initial and final state vars
Zoltan Somogyi
zoltan.somogyi at runbox.com
Tue May 20 17:13:42 AEST 2025
On Tue, 20 May 2025 13:01:11 +1000, Peter Wang <novalazy at gmail.com> wrote:
> I've had a chance to try this change on the Prince codebase now.
> A common pattern is a predicate that takes the I/O state as unique input
> in order to read the "global state", but the I/O state needs to be
> threaded through its caller (for whatever reason).
>
> For example:
>
> :- pred p(int::in, io::di, io::uo) is det.
>
> p(_, !IO) :-
> read_global_state(!.IO).
>
> :- pred read_global_state(io::ui) is det.
>
> read_global_state(IO) :- ...
>
> The unneeded final statevars warning suggests that !:IO could be deleted
> in p/3, but it cannot be written like so:
>
> p(_, IO, IO) :-
> read_global_state(IO).
>
> as the modechecker will complain that IO has instantiatedness `ground'.
>
> To avoid the warning, it is necessary to write out the unification
> previously implied by state variable notation:
>
> p(_, IO0, IO) :-
> read_global_state(IO0),
> IO = IO0.
>
> I guess, ideally, the compiler would recognise that a final statevar is
> not "unneeded" if the statevar occurs as a unique-input argument in a
> call (or some generalisation of that).
The code that generates warnings just about has to gather information
about state var usage during the parse tree to HLDS conversion process,
because state variables effectively become invisible in the result of the
translation, except for their effects on variable names. And the code
that looks at clause heads just about has to operate before mode analysis,
because the copy-clauses-to-procs pass that precedes mode analysis
effectively obsoletes clause information.
This means that this code cannot base its decisions on the answers
to questions such as "what is the mode of this argument"; it has to
fall back to questions "what are the *possible* modes of this argument".
In this case, I think that still works. We could add a heuristic that says
"do not generate an unneeded final statevar warning if either the initial
or the final inst of the argument represented by that final statevar,
in *any* of the declared modes of the predicate, involve either
uniqueness, or its converse, being clobbered".
Would that work to shut up the unwanted warnings for the cases
you have seen? And can you think of any other heuristic that would help
in other cases of false positives?
Note that this approach has the minor disadvantage that it works
only on declared modes, not inferred ones, since these are not available
when the warnings are generated. But since mode inference
does a lousy job on any code involving uniqueness, I don't think
that is a serious limitation.
Zoltan.
More information about the reviews
mailing list