diff --git a/fix/src/downgrade.rs b/fix/src/downgrade.rs index c1e8998..5be19fc 100644 --- a/fix/src/downgrade.rs +++ b/fix/src/downgrade.rs @@ -195,23 +195,21 @@ impl<'id: 'ir, 'ir, Ctx: DowngradeContext<'id, 'ir>> Downgrade<'id, 'ir, Ctx> fo && matches!(normalized.first(), Some(ast::InterpolPart::Literal(_))); let bump = ctx.bump(); - let parts = normalized - .into_iter() - .map(|part| match part { - ast::InterpolPart::Literal(lit) => Ok(ctx.new_expr(Ir::Str(lit.box_in(bump)))), - ast::InterpolPart::Interpolation(interpol) => { - let inner = interpol - .expr() - .require(ctx, interpol.syntax().text_range())? - .downgrade(ctx)?; - Ok(ctx.maybe_thunk(inner)) - } - }) - .collect_in::>>(bump)?; + let mut parts = normalized.into_iter().map(|part| match part { + ast::InterpolPart::Literal(lit) => Ok(ctx.new_expr(Ir::Str(lit.box_in(bump)))), + ast::InterpolPart::Interpolation(interpol) => { + let inner = interpol + .expr() + .require(ctx, interpol.syntax().text_range())? + .downgrade(ctx)?; + Ok(ctx.maybe_thunk(inner)) + } + }); Ok(if is_single_literal { - parts.into_iter().next().expect("is_single_literal checked") + parts.next().expect("is_single_literal checked")? } else { + let parts = parts.collect_in::>(bump)?; ctx.new_expr(Ir::ConcatStrings { parts, force_string: true, diff --git a/fix/src/runtime/vm.rs b/fix/src/runtime/vm.rs index a44094c..5176912 100644 --- a/fix/src/runtime/vm.rs +++ b/fix/src/runtime/vm.rs @@ -8,7 +8,7 @@ use smallvec::SmallVec; use string_interner::{DefaultStringInterner, Symbol as _}; use super::Runtime; -use super::builtins::{BUILTINS, BuiltinId, PrimOpArgs, PrimOpStrictArgs}; +use super::builtins::{BUILTINS, BuiltinId}; use super::stack::Stack; use super::value::*; use crate::codegen::{ @@ -78,79 +78,6 @@ pub(super) fn new_gc_root<'gc>( } impl<'gc> GcRoot<'gc> { - fn init_builtins( - mc: &Mutation<'gc>, - strings: &mut DefaultStringInterner, - ) -> (Value<'gc>, HashMap) { - let mut builtin_lookup = HashMap::new(); - let mut entries = SmallVec::new(); - - for (id, &(name, arity)) in BUILTINS.iter().enumerate() { - let Some(sym) = strings.get(name) else { - continue; - }; - let sid = StringId(sym); - let primop = PrimOp { - id: BuiltinId::try_from_primitive(id as u8).expect("invalid BuiltinId??"), - arity, - }; - builtin_lookup.insert(sid, primop); - - // Regular primop - if arity != 0 { - entries.push((sid, Value::new_inline(primop))); - } - } - - // Add constant entries - macro_rules! add_const { - ($name:expr, $val:expr) => {{ - let sym = strings.get_or_intern($name); - entries.push((StringId(sym), $val)); - }}; - } - add_const!( - "currentSystem", - Value::new_gc(Gc::new(mc, NixString::new("x86_64-linux"))) - ); - add_const!("langVersion", Value::new_inline(6i32)); - add_const!( - "nixVersion", - Value::new_gc(Gc::new(mc, NixString::new("2.24.0"))) - ); - add_const!( - "storeDir", - Value::new_gc(Gc::new(mc, NixString::new("/nix/store"))) - ); - add_const!( - "nixPath", - Value::new_gc(Gc::new( - mc, - List { - inner: SmallVec::new() - } - )) - ); - add_const!("null", Value::new_inline(Null)); - add_const!("true", Value::new_inline(true)); - add_const!("false", Value::new_inline(false)); - - // Self-reference thunk for builtins.builtins - let self_ref_thunk: Gc<'gc, Thunk<'gc>> = Gc::new(mc, RefLock::new(ThunkState::Blackhole)); - let sym = strings.get_or_intern("builtins"); - entries.push((StringId(sym), Value::new_gc(self_ref_thunk))); - - entries.sort_by_key(|(k, _)| *k); - - let builtins_set = Gc::new(mc, unsafe { AttrSet::from_sorted_unchecked(entries) }); - let builtins_val = Value::new_gc(builtins_set); - - // Populate the self-reference - *self_ref_thunk.borrow_mut(mc) = ThunkState::Evaluated(builtins_val); - - (builtins_val, builtin_lookup) - } - #[inline(always)] fn env(&self) -> Gc<'gc, RefLock>> { self.current_env.expect("no current env") @@ -396,12 +323,12 @@ impl Runtime { LoadLocal => { let idx = self.read_u32() as usize; self.arena - .mutate_root(|mc, root| root.push_stack(root.env().borrow().locals[idx])) + .mutate_root(|_, root| root.push_stack(root.env().borrow().locals[idx])) } LoadOuter => { let layer = self.read_u8(); let idx = self.read_u32() as usize; - self.arena.mutate_root(|mc, root| { + self.arena.mutate_root(|_, root| { let mut cur = root.env(); for _ in 0..layer { let prev = cur.borrow().prev.expect("LoadOuter: env chain too short"); @@ -724,12 +651,11 @@ impl Runtime { let found = self.arena.mutate_root(|_, root| { let val = root.pop_stack(); - if let Some(attrset) = val.as_gc::>() { - if let Some(v) = attrset.lookup(key_sid) { + if let Some(attrset) = val.as_gc::>() + && let Some(v) = attrset.lookup(key_sid) { root.push_stack(v); return true; } - } // Not a set or key missing → use default false }); @@ -757,7 +683,7 @@ impl Runtime { } HasAttr => { let n = self.read_u16() as usize; - let keys = self.read_attr_keys(n); + let _keys = self.read_attr_keys(n); todo!("implement HasAttr (force + check)"); } @@ -846,8 +772,8 @@ impl Runtime { } Assert => { - let raw_idx = self.read_u32(); - let span_id = self.read_u32(); + let _raw_idx = self.read_u32(); + let _span_id = self.read_u32(); todo!("implement Assert (force TOS)"); } @@ -871,7 +797,7 @@ impl Runtime { root.with_scope = scope.prev; }), WithLookup => { - let name = self.read_string_id(); + let _name = self.read_string_id(); todo!("implement WithLookup (force with_scope)"); }