[m-dev.] request for opinions about a change to switch detection

Julien Fischer jfischer at opturion.com
Fri Nov 14 14:56:14 AEDT 2025


On Fri, 14 Nov 2025 at 13:59, Zoltan Somogyi <zoltan.somogyi at runbox.com> wrote:
>
> On Fri, 14 Nov 2025 13:17:46 +1100, Peter Wang <novalazy at gmail.com> wrote:
> > > > The third "fix" is to simply declare that the warning is an appropriate
> > > > response to code like the above.
> > >
> > > It is not an appropriate response to such code.
> >
> > Why not? There is no description of how smart the compiler is supposed
> > to be to implement --warn-unknown-format-calls. I'm surprised the
> > compiler didn't warn about that code before. The fact that it didn't
> > in that particular case seems like an artefact of the implementation
> > more than by design.
>
> Agreed.
>
> > The compiler does produce the warning for this predicate:
> >
> >     p(List, Str) :-
> >       (
> >           List = [],
> >           Fmt = "empty %d"
> >       ;
> >           List = [_ | _],
> >           Fmt = "non-empty %d"
> >       ),
> >       string.format(Fmt, [i(1)], Str).
>
> A good point.

But not a good warning, since it is obviously spurious!

> > I'm not saying the third option is the best, but I shouldn't simply
> > reject it.
>
> I agree, which is why I mentioned it, though I added the quotes around
> "fix" because I agree with what I take to be Julien's main point, which is that
> we should avoid breaking existing user code if possible (and in this case,
> avoiding such breakage is possible).

Ideally, yes, we would avoid breaking existing code.

> How about a fourth fix, which goes like this. *If* the format_call
> pass generates a warning, *and* the inst of the variable it is warning
> about (in this case, Fmt) is a bound inst with two or more alternatives
> (as it would be in this case), *then*
>
> - we discard the results of the pass,
>
> - we perform a backwards traversal of the procedure body that looks for
>   calls to format predicates that are preceded by a disjunction or a switch
>   or if-then-else, and pushes all goals after the disjunction/switch/ite
>   up to and including the format call into each arm of the disjunction/switch/ite,
>
> - we fix up quantification, recompute instmap deltas and so on,
>
> - and we then redo the usual format call pass, but this time committing
>   to keeping its result, whatever it may be.
>
> This should have the minimal possible performance impact, since code
> like this very rare; a bootcheck found exactly one predicate where this
> redo of the pass would be needed. *And* it would have the effect that
> Peter's example code would be now accepted by the compiler, and the
> description of what programs would be accepted in this respect would
> be simplified. (You could describe it using text such as "if, for each path
> execution can take through the body of the clause, the format string
> is fixed, then ...")
>
> Opinions?

Presumably, by pushing the format calls back into the branched control
structure, that then makes them amenable to being optimised?  (I was going
to ask about that anyway after I saw Peter's example.)

Julien.


More information about the developers mailing list