You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Introduce `thrust_macros::invariant!`, a Prusti-style loop invariant placed
inside the loop body:
fn f() {
while cond {
thrust_macros::invariant!(|x: i64, y: i64| x >= 1 && y >= 1);
...
}
}
`invariant!(|x: T, ...| pred)` expands to a `#[thrust::formula_fn]` over
`Model::Ty` parameters and a marker call (`thrust_models::__invariant_marker`)
referencing it, so invariants share the static semantics of
`requires`/`ensures`. The closure parameters name the live variables the
invariant constrains.
Generic- and `Self`-typed variables are out of scope here (the in-body macro
cannot see the enclosing generics, and `Self` cannot be named inside a nested
formula function); support for those will follow by extending
`#[thrust_macros::context]` to thread that context in.
Analyzer:
- Collect invariant markers, map each to its enclosing loop header, and turn
the formula function into that header's precondition by binding each named
formula parameter to the matching live basic-block parameter.
- Resolving a name to a live local errors when several distinct live locals
share it (e.g. shadowing) rather than silently picking one.
- The marker terminator is elaborated to a plain goto so it is not type-checked
as a real call.
https://claude.ai/code/session_01WB28auaD8dSQrckqBwJWBt
0 commit comments