Repository navigation
Conversation
Lorenzobattistela
left a comment
There was a problem hiding this comment.
Thanks, the message is much clearer for a plain def written below its use. One case still gets the old message.
-
A law filled below its caller still says "an unfilled law is a dead claim", even though it has a body:
import Base def a(x: Nat) -> Nat: b(x) law b: for x: Nat Nat def b(x): 1n+x def main() -> Nat: a(1n)
On this branch,
--check-onlyprints "expected : a filled definition (an unfilled law is a dead claim: live code cannot use it) / observed : b". But b is filled, and moving it above a makes the file check. That's the confusion #1782 is about.tld.lsays that alawdeclared the name, not whether a body is coming later in the file. A law declared above its caller and filled below it gets the same message (as in forward_reference_scope / assert_fill_scope).Suggestion: book_valid already knows from
lastwhich names get a body later in the order, but drops that when it writes{ ...t, v: null }. If you mark those cleared copies, infer-ref can pick the message from that mark instead of fromtld.l. Then a def or law filled below its use gets the file-order message, and the law message stays for laws that are never filled. This also keeps the file-order message away from other entries that have no body and nol, such as an instance while it is checked in def_inst, which has no position in the file. -
tests/check/forward_reference.bend expects the law message for
later, which is filled below its use, and its comment ("a def below is a bodiless claim ... as an unfilled law") now contradicts this PR. Once 1 is fixed, it should expect the file-order message. A test for a law declared above its caller and filled below it would cover the other case. -
The comment on the infer-ref rule (bend.ts, just above the check) still explains a missing body only as an unfilled law. Please add the def-below-its-use case.
All gates are green on this branch merged onto main ed186a4 (repo 54/54, test 1682/1682, perf 124/124, ping 63/63, safe 0 false rejects).
infer-ref picked the message by tld.l, which says that a law declared the name, not whether its body comes later. A law filled below its caller still read "an unfilled law is a dead claim", though moving the fill above the caller makes the file check. book_valid knows from `last` which names get a body later in the order. It now marks those cleared copies (w), and infer-ref picks the file-order message from that mark. A law that is never filled keeps the law message, and so does any other bodiless entry, such as an instance while def_inst checks it. forward_reference, forward_reference_scope and assert_fill_scope call a law before its fill, declared below or above the caller, and now expect the file-order message. The axiom tests use a law that is never filled and keep the law message. The infer-ref and Valid comments name the def-below-its-use case.
|
Thanks, all three are done in 3292e72:
Rebased onto main at 10256a7 locally, it merges cleanly. There, |
Lorenzobattistela
left a comment
There was a problem hiding this comment.
Thanks, the w mark fixes my repro, and the copies never carry it outside book_valid, so nothing downstream sees it. Gates are green on this branch merged onto main 66ced68 (repo 54/54, test 1698/1698, ping 73/73, safe 0 false rejects; perf fails the same cells on main). 1 and 4 below must be fixed before approving; 2, 3 and 5 are optional.
-
(must fix) A law filled by an importing file now gets the file-order message inside the imported file, where no reordering can fix it:
# LAWS.bend import Base law foo: U32 law bar: U32 def bar(): foo
# PROOF.bend import Base import ./LAWS.bend as L def L.foo(): 0
bend PROOF.bend --check-onlyprints "expected : a def written above its use (defs are checked in file order) / observed : foo" at bar, in LAWS.bend. Butbend LAWS.bendprints the law message at the same spot. LAWS.bend is checked in full before PROOF.bend, so the prover can't move the fill above the use, and in this case the law message was the right one.wasks whether a body exists anywhere later in the book; it should ask whether it comes later in the same file (for example, by comparing the module of the fill with the module of the use). This is the LAWS/PROOF flow, so it's the case that matters most. -
(optional) Mutual recursion now says to reorder: with f calling g and g calling f, either order gives "a def written above its use". The law message on main was also wrong there, so this isn't a regression, but if there's a cheap way to tell (the caller is itself marked
w, say), "mutual recursion is not allowed" would be better. -
(optional) For a law declared above its use and filled below it (forward_reference_scope), "a def written above its use" reads as already true, since the
law foo:line is above. It's the fill that has to move. Something like "a def or law fill written above its use" would point at the right line. Wording only, your call. -
(must fix) The header comments of tests/comptime/later_def.bend ("a def below is a bodiless claim") and tests/check/assert_fill_scope.bend ("an assert declares a DEAD claim") still argue for the law message, but both tests now expect the file-order one.
-
(optional) A test for 1 (two files, law filled by the importer, expecting the law message) would pin the fix.
Fixes #1782.
What changes
book_validclears every def's body and restores the bodies in file order. So while a def is checked, a def or law filled below it hasv === null, as an unfilled law does, and infer-ref refused both with the law message. A reader with no law in sight went looking for a missing proof.book_validknows fromlastwhich names get a body later in the order. It now marks those cleared copies (w), and infer-ref picks the message by that mark:def_instchecks it): the law message, unchanged.The issue's
fwd.bendnow prints:The review's case, a law declared below
aand filled below it, now prints the same message, and so does a law declared above its caller and filled below it. The message says "its use", not "its caller", so it also reads right when the def below is passed as a~argument, as intests/comptime/later_def.bend. It names neither the caller nor@unsafe. In that test the caller is the instanceapp~0. And a template below is refused even in an@unsafecaller.The rule itself does not change. Only the message changes. The infer-ref and Valid comments now name the def-below-its-use case.
Tests
tests/check/unsafe_forward_safe.bendalready pins the issue's case: a safehcalls a plaingwritten below it. It now expects the new message, and its comment says so.tests/comptime/later_def.bend(a def below passed as a~argument) now expects the new message.Three tests call a law before its fill, and now expect the file-order message:
forward_reference: the law is declared below its caller;forward_reference_scopeandassert_fill_scope: it is declared above its caller.forward_reference's comment no longer calls a def below a bodiless claim, andforward_reference_scope's says the refusal names the file order.The five axiom tests (
axiom_use,axiom_whitelist,axiom_import_warn,axiom_runtime_capture,compile/axiom_runtime) use a law that is never filled, and keep the law message.Checks
On the branch rebased onto main at 10256a7 (it merges cleanly):
gates/test.ts, run locally: PASS 1690 / 1692. The two failures,gfx_clicksandgfx_window, expect "no display" and fail the same way on main here, because this Mac has a desktop session.bun gates/repo.ts: 54 / 54.bend.tsgoes from 43,767 to 43,857 tokens (cap 48,000).tsc -p bend2/pack/tsconfig.json(TypeScript 5.9.3): the same 11 errors as main, none on the changed lines.