pub struct Env(/* private fields */);Expand description
Evaluation environment — flattened binding map with structural sharing.
Internally an Rc<EnvInner>, so cloning is always O(1) (refcount
bump). child() clones the FxHashMap (O(1) structural
sharing) instead of building a parent chain. bind() uses
Rc::make_mut for copy-on-write: if the Rc is shared, only then
does it clone the inner data.
Implementations§
Source§impl Env
impl Env
Sourcepub fn child(&self) -> Self
pub fn child(&self) -> Self
Create a child environment that inherits from this one.
O(1) — the FxHashMap clone is structural sharing (refcount
bump on internal tree nodes), not a deep copy.
Sourcepub fn with_scope(self, value: Value) -> Self
pub fn with_scope(self, value: Value) -> Self
Attach a with scope to this environment.
If the value is a thunk that’s ALREADY evaluated (OnceCell cache hit),
pre-populate the with-scope cache immediately. This avoids creating
deferred WithIdent thunks when the fixpoint is already resolved —
critical for the overlay chain where multiple stages access the same
fixpoint through different with self; scopes.
Sourcepub fn bind(&mut self, name: String, value: Value)
pub fn bind(&mut self, name: String, value: Value)
Bind a name to a value in this environment’s own scope.
Uses copy-on-write: if the inner Rc is shared, clones the
inner data before mutating.
Sourcepub fn bind_many(&mut self, pairs: impl IntoIterator<Item = (String, Value)>)
pub fn bind_many(&mut self, pairs: impl IntoIterator<Item = (String, Value)>)
Bind many names in ONE copy-on-write step: a single Rc::make_mut on the
inner env, then N inserts on the owned map — instead of N successive
bind() calls each re-borrowing + re-make_mut-ing self.0.
Byte-identical to calling bind once per pair in the same
order (same intern, same insert sequence, same final HAMT) — a byte-SAFE
RedundantWrite-class optimization: it removes intermediate re-borrows,
not any observable value. Consumed by pattern-lambda binding (bind_param),
where an N-formal pattern otherwise pays N make_mut refcount checks.
Sourcepub fn set_eval_file(&mut self, file: Option<PathBuf>)
pub fn set_eval_file(&mut self, file: Option<PathBuf>)
Set the eval_file for this environment.
Sourcepub fn source_id(&self) -> u32
pub fn source_id(&self) -> u32
The source_id of the parse tree this env belongs to (0 = top level).
Sourcepub fn set_source_id(&mut self, id: u32)
pub fn set_source_id(&mut self, id: u32)
Set the source_id for this environment (called by eval_with_file
for an imported parse tree).
Sourcepub fn binding_count(&self) -> usize
pub fn binding_count(&self) -> usize
Number of direct bindings in this environment (debug).
Sourcepub fn binding_names_preview(&self, n: usize) -> Vec<String>
pub fn binding_names_preview(&self, n: usize) -> Vec<String>
First N binding names (debug).
Sourcepub fn with_scope_count(&self) -> usize
pub fn with_scope_count(&self) -> usize
Number of with scopes (debug).
Sourcepub fn lookup_lexical(&self, name: &str) -> Option<Value>
pub fn lookup_lexical(&self, name: &str) -> Option<Value>
Lookup in LEXICAL scope only (no with-scopes). Used by maybe_thunk to avoid forcing with-scope fixpoints during attrset construction.
Sourcepub fn lookup_lexical_sym(&self, sym: Symbol) -> Option<Value>
pub fn lookup_lexical_sym(&self, sym: Symbol) -> Option<Value>
Lookup in LEXICAL scope only, by pre-interned Symbol — the
Symbol-keyed sibling of lookup_lexical.
Probes ONLY the lexical bindings map (the first thing
lookup_fast does, by the same Symbol) — never
the with-chain. The ENV-RESOLVE M0 fast path uses this: a
Resolution::Lexical{sym} reference probes here directly with its
precomputed Symbol; on a hit the returned value is byte-identical to
lookup_fast’s (same map, same Symbol); on a miss the caller falls
back to today’s exact runtime path.
Sourcepub fn lookup_with_cache_only(&self, name: &str) -> Option<Value>
pub fn lookup_with_cache_only(&self, name: &str) -> Option<Value>
Look up a name using ONLY with-scope caches (no forcing). Returns Some if the name is in a cached with-scope, None otherwise. Used by maybe_thunk to resolve with-scope idents without forcing fixpoints.
Sourcepub fn innermost_with_scope(
&self,
) -> Option<(Rc<RefCell<Option<NixAttrs>>>, Value)>
pub fn innermost_with_scope( &self, ) -> Option<(Rc<RefCell<Option<NixAttrs>>>, Value)>
Get the innermost with-scope’s cache and value for creating WithIdent thunks. Returns None if there are no with-scopes.
Sourcepub fn lookup(&self, name: &str) -> Option<Value>
pub fn lookup(&self, name: &str) -> Option<Value>
Lookup matching Nix semantics:
- Probe the flattened binding map (single O(log32 n) lookup).
Any explicit
let/rec/function-arg binding wins over everywithscope. - If no lexical binding matched, iterate
with_scopesin reverse order (innermost first). Sowith X; with Y; xfindsxin Y if Y has it, otherwise in X.
Sourcepub fn lookup_fresh(&self, name: &str) -> Option<Value>
pub fn lookup_fresh(&self, name: &str) -> Option<Value>
Cache-BYPASSING with-scope lookup: force each with-scope value FRESH
(through the full thunk chain) and check for name, refreshing the
per-scope cache on the way. A force that errors (a mid-fixpoint blackhole
or a with (throw …); … namespace) is caught and the scope skipped.
This exists ONLY for the last-ditch retry on the about-to-throw
UndefinedVar path (see the WithIdent force): the normal cache-first
[lookup_fast] can trust a stale mid-fixpoint PARTIAL cached for a scope
(e.g. f self before makeScope merged callPackage into self) and skip
it; a fresh force sees the now-completed scope. Never call this on a hot
path — it re-forces every scope.
Sourcepub fn lookup_fast(&self, sym: Symbol, name: &str) -> Option<Value>
pub fn lookup_fast(&self, sym: Symbol, name: &str) -> Option<Value>
Lookup by pre-interned Symbol + string name. Avoids re-interning.
Sourcepub fn lookup_sym(&self, sym: Symbol) -> Option<Value>
pub fn lookup_sym(&self, sym: Symbol) -> Option<Value>
Look up a binding by pre-interned Symbol.
Same semantics as lookup but skips the
intern() call — for use when the caller has already cached
the symbol (e.g. via intern_cached).
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Env
impl !Send for Env
impl !Sync for Env
impl !UnwindSafe for Env
impl Freeze for Env
impl Unpin for Env
impl UnsafeUnpin for Env
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.