pub struct ListContext {
pub index: Mutex<usize>,
pub elements: Arc<[Arc<Thunk>]>,
pub iter_binding: Mutex<Option<(Arc<str>, Value)>>,
}Expand description
Iteration context for &prev / &next / &index references inside a list.
Serves two scenarios:
- Plain list-literal iteration (
&prev/&next/&index) — built byScope::with_list_context. Each element runs under its own child scope with a fixedindex;iter_bindingis alwaysNone. - Comprehension hot loop (
for x in xs) — built once byScope::with_iter_loop, then the body reuses the sameArc<Scope>across all iterations.Scope::set_iter_bindingrefreshesiter_binding+indexin place per element, eliminating theArc::new(Self {...})per element flagged by the P1-B diagnostic correction (48 MB / 200 K blocks).iter_bindingisMutex-wrapped soScopestaysSend + Syncwithout unsafe interior mutability.
P2-1: thunks shared via Arc<[Arc<Thunk>]> so Expr::List’s
per-element with_list_context(i, elements) only bumps an Arc
instead of cloning the whole Vec<Arc<Thunk>> (O(N²) → O(N)).
Fields§
§index: Mutex<usize>§elements: Arc<[Arc<Thunk>]>P2-1: Arc<[Arc<Thunk>]> lets with_list_context share the
thunks slice across every element’s scope via a refcount bump,
instead of Vec::clone’ing all N entries per element (the prior
shape paid O(N²) Arc bumps over an N-element list).
iter_binding: Mutex<Option<(Arc<str>, Value)>>Current named-iteration binding (name, value). None for plain
list iteration. Comprehension hot loops fill this in once per
element via a lock + write (no allocation, no frame rebuild).
Semantic invariant: when a Closure value is constructed inside a
loop body, the constructor MUST snapshot the current binding into
captured_env (see the Expr::Closure branch in eval.rs).
Otherwise a later iteration would mutate the binding the closure
was meant to capture, breaking lexical-snapshot semantics.
Implementations§
Source§impl ListContext
impl ListContext
Sourcepub fn fixed(index: usize, elements: Arc<[Arc<Thunk>]>) -> Self
pub fn fixed(index: usize, elements: Arc<[Arc<Thunk>]>) -> Self
Plain &prev / &next / &index scenario: fixed index, no
iter binding.
Sourcepub fn empty(elements: Arc<[Arc<Thunk>]>) -> Self
pub fn empty(elements: Arc<[Arc<Thunk>]>) -> Self
Comprehension hot loop entry: starts at index 0 with an empty
binding slot. Scope::set_iter_binding fills it per element.
Sourcepub fn current_index(&self) -> usize
pub fn current_index(&self) -> usize
Read the current iteration index — used by &index / &prev /
&next.
Auto Trait Implementations§
impl !Freeze for ListContext
impl RefUnwindSafe for ListContext
impl Send for ListContext
impl Sync for ListContext
impl Unpin for ListContext
impl UnsafeUnpin for ListContext
impl UnwindSafe for ListContext
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more