Let a ghost term name generic- and Self-typed variables - #232
Draft
coord-e wants to merge 1 commit into
Draft
Conversation
`ghost!` lifts its term into a free `#[thrust::formula_fn]`, which inherits neither
the enclosing function's generics nor `Self`, so a term could only name variables of
concrete type. `#[thrust_macros::context]` already threads that context into
`invariant!`; it now threads it into `ghost!` too:
#[thrust_macros::context]
impl Counter {
fn record(&mut self, x: i64) {
self.count += 1;
self.seen = thrust_macros::ghost!(
|self: &mut Self, x: i64| -> Seq<Int> { (*self).1.push(x) }
);
}
}
The context handling `invariant!` carried -- re-declaring the in-scope generics on the
formula function and instantiating them via turbofish, rewriting `Self` to the impl's
self type or to a synthetic type parameter in a trait, and renaming the receiver
`self` to `__thrust_self` -- moves to `formula_fn_lifting`, which both macros now
build their formula function with. On the analyzer side, the ghost path resolves
`__thrust_self` back to the receiver the way the invariant path already does.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJ6XNNsSBdPkAzrWHftvqV
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follows #220. Stacked on #231 — review that one first; this branch's own change is the second commit.
ghost!lifts its term into a free#[thrust::formula_fn], which inherits neither the enclosing function's generics norSelf, so a term could only name variables of concrete type — the last of #220's known gaps.#[thrust_macros::context]already threads that context intoinvariant!; it now threads it intoghost!too.How it works
The context handling
invariant!carried moves to a newformula_fn_liftingmodule, which both macros now build their formula function with:Selfis rewritten to theimpl's self type, or to a synthetic type parameter instantiated with the realSelfin a trait;selfis renamed to a__thrust_selfparameter.For
ghost!the introduced value is parameter0, so it passes through the same lifting as an ordinary parameter: a value type namingSelfor a generic is rewritten along with the rest, while the__ghost_marker::<_, T>turbofish keeps the type as written, since the marker call stays in the host's scope.On the analyzer side the ghost path resolves
__thrust_selfback to the receiver the way the invariant path already does; the shared rule isannot_fn::lifted_param_source_name.Tests
ghost_selfselfghost_genericEach as a
pass/failpair; in both, thefailfile differs only in which live variable the term names.Known gaps
Selfin a generic or traitimplis unsupported, unchanged frominvariant!— both now go through the sameTODO, so a fix covers them together.Generated by Claude Code