Skip to content

Commit c6536db

Browse files
committed
Define the diagnostic-flag invariant by what cannot force a rebuild
Section 4 justified rejecting warn-pedantic from stanc_options partly on the grounds that a supplied diagnostic evaporates the same way an injected one does: build once, warn once, and never warn again once the record matches. Read as a general rule that lands on --warn-uninitialized and every other supplied diagnostic, and taken that way it asks for stanc to be rerun on every construction of an up-to-date model. The two cases are not the same. A compared option cannot evaporate in the way that matters, because turning it on mismatches the record and rebuilds; only an option that cannot force a rebuild needs a mechanism of its own. So the invariant is narrower than "a diagnostic always re-emits": asking for something you did not have before never yields nothing. warn-pedantic satisfies it through section 8's rerun, warn-uninitialized through being compared. That leaves a real asymmetry on an identical repeat call, where pedantic warns and a supplied diagnostic does not. Named rather than defended as ideal. Buying it would mean cmdstanr knowing which stanc flags are diagnostic-only per CmdStan version, which is the per-option semantics canonicalization already declines, and a misclassification is silent in the unsafe direction: treat a codegen flag as diagnostic and a needed rebuild is skipped. It is also what a C compiler does with -W flags and an up-to-date object file. The warn-pedantic rejection now rests on the one-channel rule instead, where pedantic is the case in which two channels differ in kind rather than in spelling, one injected and uncompared and one supplied and compared.
1 parent 2c3c502 commit c6536db

1 file changed

Lines changed: 32 additions & 15 deletions

File tree

dev-notes/compilation-state.md

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -594,21 +594,38 @@ artifact while an old record's `_supplied` goes on matching, so nothing would
594594
rebuild. The bump is what forces it.
595595

596596
**An injected option still applies; not comparing it only means it cannot force a
597-
rebuild.** Where the option's whole purpose is to produce output — `--warn-pedantic`
598-
is the only current case — the operation still has to happen on a model that is
599-
already up to date, or the user's request silently evaporates (§5).
600-
601-
**Every `stanc_options` spelling of `--warn-pedantic` is therefore rejected**, with an
602-
error naming `pedantic = TRUE``list("warn-pedantic")`, `list("warn-pedantic" = TRUE)`
603-
and `list("warn-pedantic" = FALSE)` alike. The named `FALSE` is refused too because it
604-
emits nothing today (logical `FALSE` leaves a flag out, #1251) while `pedantic = TRUE`
605-
still injects, so it reads as a way to switch pedantic off and is not one.
606-
607-
Supplied rather than injected, the flag would be *compared*: the first build warns, the
608-
second construction matches the record, nothing rebuilds, and the warnings never appear
609-
againthe same evaporation through the door the rule above does not cover. One
610-
spelling that is already handled is cheaper than a second rule. `name` and
611-
`filename-in-msg` stay supplyable: neither has a dedicated argument, and
597+
rebuild.** The invariant this obliges is narrower than "a diagnostic always re-emits":
598+
*asking for something you did not have before never yields nothing.* A compared option
599+
satisfies it for free, since turning it on mismatches the record and rebuilds. An
600+
uncompared one cannot, and needs a mechanism of its ownfor `--warn-pedantic`, the
601+
only current case, §8 runs the check on a model that is already up to date.
602+
603+
That leaves an asymmetry, accepted rather than defended as ideal. `pedantic = TRUE` warns
604+
on every construction, including an identical repeat, because an uncompared option has no
605+
build to attach to and "every time" is the only alternative to "never". A supplied
606+
diagnostic such as `--warn-uninitialized` warns whenever a build happens and is quiet on
607+
an identical repeat. Warning there too would be better; it is not worth what buying it
608+
costs (below), and it is the behaviour of every C compiler with `-W` flags and an
609+
up-to-date object file, so it is not a surprise we are introducing. Both routes deliver
610+
the flag's effect the moment the caller asks for it; only the nothing-changed case
611+
differs.
612+
613+
**Extending warn-always to supplied options is refused.** It would need cmdstanr to know
614+
which stanc flags are diagnostic-only, per CmdStan version — the per-option semantics
615+
this section declines below for canonicalization, arrived at from the other direction. A
616+
misclassification is also silent and points the wrong way: treat a codegen flag as
617+
diagnostic and a needed rebuild is skipped.
618+
619+
**`--warn-pedantic` is rejected from `stanc_options`**, with an error naming
620+
`pedantic = TRUE`, matched on occurrence rather than by value (§3). This is the
621+
one-channel rule of §3 and §6, and pedantic is the case where two channels would differ
622+
in *kind* rather than in spelling: `pedantic = TRUE` is injected and not compared, the
623+
same flag through `stanc_options` is supplied and compared, so one warns on every call
624+
and the other only on a build. The named `FALSE` has a second reason of its own: it emits
625+
nothing today (logical `FALSE` leaves a flag out, #1251) while `pedantic = TRUE` still
626+
injects, so it reads as a way to switch pedantic off and is not one.
627+
628+
`name` and `filename-in-msg` stay supplyable: neither has a dedicated argument, and
612629
`filename-in-msg` is deliberately caller-overridable (§9). `allow-undefined` does not,
613630
being the flag `user_header` implies (§3).
614631

0 commit comments

Comments
 (0)