Commit db34e5e
committed
Separate what the record stores from what the verdict compares
Round-five removed include_paths from the rebuild triggers but left section 6
re-resolving includes with the paths held in the record. With the comparison
gone, that made changing include_paths a no-op: stanc would be pointed at the
old directories, find the old files, report matching hashes, and reuse a binary
the caller did not ask for. Re-resolution now uses the effective paths of the
current call; the recorded ones are for replay and provenance.
The user header needs the opposite treatment and now matches on normalised path
as well as content. CmdStan feeds it in as -include, and a quoted include inside
it resolves relative to that header's own directory, so two byte-identical
headers in different directories are different translation units. A worked
example is in section 6: the same top-level hash, implementations returning
0.3261 and -1.0000, and every compared field matching. This is not an exception
to content identity but the same rule where our information is incomplete -- a
Stan program's include closure is fully visible through stanc, a C++ header's is
not, so the directory stands in for the part we cannot hash. Section 6 already
does this once, for make/local.
Both of those were derived wrongly at least once because the record's rules were
spread across three sections and never written down as rules. Section 4 now
carries a per-field recorded/compared table and is the authority on both; prose
elsewhere refers to it rather than restating it. Recorded-but-not-compared turns
out to be the ordinary case, not a list of exceptions, and that reframing settles
the injected stanc options: cmdstanr's own additions are recorded and never
compared, so toggling pedantic does not force a recompile. Checking for rules
stated twice immediately found two stale ones in section 3.
Includes are compared as an ordered sequence rather than a set. That is exact
where a set is not, and it is also the simpler implementation, since position
gives the error message its file name without a second pass.
Also here: variables() must be captured at construction, since parsing on first
call makes the answer depend on whether anyone asked before an edit; the
standalone family all take include_paths, without which format_stan_file() could
not format any program containing an include; filename-in-msg precedence is
settled rather than left open; stan_build_info() reports built_from and whether
it still exists, because it receives only an executable and cannot resolve a
current location; and the .libPaths() example is gone, since instantiate derives
the executable from the source it just found.
The 30-90 second compile figure was never measured. Replaced with 6.7s and 13.8s
for bernoulli.stan with and without precompiled headers, stated as a floor, and
the one argument that leaned on the number re-grounded on the caller not having
asked to build at all.1 parent 9ece4c3 commit db34e5e
1 file changed
Lines changed: 353 additions & 71 deletions
0 commit comments