This PR provides support for (non-recursive) function definitions nested within a Pulse statement block.
e.g.,
ghost
fn yields_idem (p:vprop)
requires emp
ensures p @==> p
{
ghost fn intro_stick_aux (u:unit)
requires emp ** p
ensures p
{ () };
Pulse.Lib.Stick.intro_stick _ _ _ intro_stick_aux;
fold (p @==> p);
}
Adding this involved a few steps:
A refactoring of the Pulse syntax extension
Adding a new Pulse typing rule T_BindFn, which is similar to T_TotBind, except the head of T_BindFn is an st_term with a C_Tot type, whereas the T_TotBind expects a head to be term.
Along the way I enhanced a few things related to the handling of post_hints and post_hint typing. This uncovered a two instances of the same bug in WithLocal and WithLocalArray where the postcondition was admitted to be typechecked in a context with the wrong type for the locally bound variable.
This PR provides support for (non-recursive) function definitions nested within a Pulse statement block.
e.g.,
Adding this involved a few steps:
A refactoring of the Pulse syntax extension
Adding a new Pulse typing rule T_BindFn, which is similar to T_TotBind, except the head of
T_BindFn
is an st_term with a C_Tot type, whereas the T_TotBind expects a head to be term.Along the way I enhanced a few things related to the handling of post_hints and post_hint typing. This uncovered a two instances of the same bug in WithLocal and WithLocalArray where the postcondition was admitted to be typechecked in a context with the wrong type for the locally bound variable.