A frame with no slots still has a body, and the note spoke for it

"every slot in it is one the compiler made up" is a claim about the body this
session holds, not about the frame, and it was answered before either body
check ran — so a zero-slot frame whose body had since been replaced by one with
slots got that note instead of the refusal. No values were misattributed, which
is why it is not the defect just fixed, but the reason given was untrue. The
count and fingerprint checks now run first and the note is the last arm.
This commit is contained in:
Joseph Ferano 2026-09-12 14:51:24 +07:00
parent b5d7a6e45f
commit 4e6b3f6183

View File

@ -783,13 +783,12 @@ let locals t ~frame =
(name
^ " is not a function this session holds; a lifted handler clause has no declaration of its own to read slot names from")
| Some fn ->
if nslots = 0 then
ok
[ ":frame " ^ Wire.quote name; ":locals ()"; ":refused ()";
":note "
^ Wire.quote
"that frame records no slots; every slot in it is one the compiler made up" ]
else if nslots <> Array.length fn.Tast.slots then
(* The two body checks come first, including for a frame
with no slots. "every slot in it is one the compiler made
up" is a claim about the body this session holds, and a
zero-slot frame whose body has since been replaced by one
with slots is a frame that claim is false about. *)
if nslots <> Array.length fn.Tast.slots then
error
(Printf.sprintf
"%s on the stack has %d slots and the %s this session holds has %d: the frame is running a body that has been redefined since, so every slot index here would be a guess"
@ -807,6 +806,12 @@ let locals t ~frame =
(Printf.sprintf
"%s on the stack was compiled from a different body than the %s this session holds: this frame's body was redefined since it was entered, so its names no longer describe its values"
name name)
else if nslots = 0 then
ok
[ ":frame " ^ Wire.quote name; ":locals ()"; ":refused ()";
":note "
^ Wire.quote
"that frame records no slots; every slot in it is one the compiler made up" ]
else
match bound_slots t ~frame with
| Error m -> error ("the program refused to say which slots are bound: " ^ m)