git.delta.rocks / jrsonnet / refs/commits / 79b689b0a354

difftreelog

build enable gc debugging

lnksvourYaroslav Bolyukin2025-09-07parent: #cd7c759.patch.diff
in: trunk

9 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -126,17 +126,6 @@
 ]
 
 [[package]]
-name = "alejandra"
-version = "4.0.0"
-source = "git+https://github.com/kamadorueda/alejandra#c68bef57c1db3add865493d9cb741a14618bdc28"
-dependencies = [
- "mimalloc",
- "rnix",
- "rowan",
- "serde",
-]
-
-[[package]]
 name = "android-tzdata"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -673,12 +662,6 @@
 version = "0.8.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
-
-[[package]]
-name = "countme"
-version = "3.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
 
 [[package]]
 name = "cpufeatures"
@@ -1352,12 +1335,6 @@
 version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hashbrown"
-version = "0.14.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
 
 [[package]]
 name = "hashbrown"
@@ -1793,16 +1770,6 @@
 version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
-
-[[package]]
-name = "libmimalloc-sys"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "667f4fec20f29dfc6bc7357c582d91796c169ad7e2fce709468aefeb2c099870"
-dependencies = [
- "cc",
- "libc",
-]
 
 [[package]]
 name = "link-cplusplus"
@@ -1873,24 +1840,6 @@
 version = "2.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
-
-[[package]]
-name = "memoffset"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "mimalloc"
-version = "0.1.48"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1ee66a4b64c74f4ef288bcbb9192ad9c3feaad75193129ac8509af543894fd8"
-dependencies = [
- "libmimalloc-sys",
-]
 
 [[package]]
 name = "mime"
@@ -1969,7 +1918,6 @@
 name = "nixlike"
 version = "0.1.0"
 dependencies = [
- "alejandra",
  "linked-hash-map",
  "peg",
  "ron",
@@ -2569,15 +2517,6 @@
  "byteorder",
  "rmp",
  "serde",
-]
-
-[[package]]
-name = "rnix"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f15e00b0ab43abd70d50b6f8cd021290028f9b7fdd7cdfa6c35997173bc1ba9"
-dependencies = [
- "rowan",
 ]
 
 [[package]]
@@ -2591,19 +2530,6 @@
  "serde",
  "serde_derive",
  "unicode-ident",
-]
-
-[[package]]
-name = "rowan"
-version = "0.15.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4f1e4a001f863f41ea8d0e6a0c34b356d5b733db50dadab3efef640bafb779b"
-dependencies = [
- "countme",
- "hashbrown 0.14.5",
- "memoffset",
- "rustc-hash 1.1.0",
- "text-size",
 ]
 
 [[package]]
@@ -3155,12 +3081,6 @@
 dependencies = [
  "unicode-width 0.2.1",
 ]
-
-[[package]]
-name = "text-size"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
 
 [[package]]
 name = "tf-provider"
modifiedcmds/fleet/src/main.rsdiffbeforeafterboth
--- a/cmds/fleet/src/main.rs
+++ b/cmds/fleet/src/main.rs
@@ -27,7 +27,7 @@
 use tracing::{Instrument, error, info, info_span};
 #[cfg(feature = "indicatif")]
 use tracing_indicatif::IndicatifLayer;
-use tracing_subscriber::{EnvFilter, prelude::*};
+use tracing_subscriber::{fmt::format::Format, prelude::*, EnvFilter};
 
 #[derive(Parser)]
 struct Prefetch {}
modifiedcrates/fleet-base/src/opts.rsdiffbeforeafterboth
--- a/crates/fleet-base/src/opts.rs
+++ b/crates/fleet-base/src/opts.rs
@@ -9,7 +9,7 @@
 use anyhow::{Context, Result, bail};
 use nix_eval::{
 	FetchSettings, FlakeLockFlags, FlakeReference, FlakeReferenceParseFlags, FlakeSettings, Value,
-	nix_go, util::assert_warn,
+	gc_now, nix_go, util::assert_warn,
 };
 use nom::{
 	Parser,
@@ -260,6 +260,10 @@
 			system: self.local_system.clone(),
 		}));
 
+		if cfg!(debug_assertions) {
+			gc_now();
+		}
+
 		Ok(Config(Arc::new(FleetConfigInternals {
 			directory,
 			data,
modifiedcrates/nix-eval/src/lib.rsdiffbeforeafterboth
--- a/crates/nix-eval/src/lib.rs
+++ b/crates/nix-eval/src/lib.rs
@@ -1,29 +1,42 @@
+use std::alloc::{GlobalAlloc, Layout};
 use std::borrow::Cow;
 use std::cell::RefCell;
 use std::ffi::{CStr, CString, c_char, c_int, c_uint, c_void};
-use std::fmt;
+use std::mem::forget;
 use std::ptr::null_mut;
 use std::sync::LazyLock;
 use std::{collections::HashMap, path::PathBuf};
+use std::{fmt, slice};
 
 use anyhow::{Context, anyhow, bail};
 use serde::Serialize;
 use serde::de::DeserializeOwned;
 
 pub use anyhow::Result;
-use tracing::instrument;
+use tracing::{info, instrument};
 
 use self::logging::nix_logging_cxx;
 use self::nix_cxx::set_fetcher_setting;
 use self::nix_raw::{
-	alloc_value, c_context, c_context_create, err_code, err_info_msg, eval_state_build,
-	eval_state_builder_new, expr_eval_from_string, fetchers_settings, fetchers_settings_free,
-	fetchers_settings_new, flake_lock, flake_lock_flags, flake_lock_flags_free,
-	flake_lock_flags_new, flake_reference_parse_flags, flake_reference_parse_flags_free,
-	flake_reference_parse_flags_new, flake_reference_parse_flags_set_base_directory,
-	flake_settings, flake_settings_free, flake_settings_new, get_string, init_bool, init_int,
-	init_string, locked_flake_free, locked_flake_get_output_attrs, set_err_msg, setting_set,
-	state_free, value_decref, value_incref,
+	BindingsBuilder as c_bindings_builder, EvalState as c_eval_state, GC_SUCCESS,
+	GC_allow_register_threads, GC_free, GC_get_stack_base, GC_init, GC_malloc, GC_realloc,
+	GC_register_my_thread, GC_stack_base, GC_thread_is_registered, GC_unregister_my_thread,
+	Store as c_store, alloc_value, bindings_builder_free, bindings_builder_insert, c_context,
+	c_context_create, c_context_free, clear_err, err_code, err_info_msg, err_msg, eval_state_build,
+	eval_state_builder_load, eval_state_builder_new, eval_state_builder_set_eval_setting,
+	expr_eval_from_string, fetchers_settings, fetchers_settings_free, fetchers_settings_new,
+	flake_lock, flake_lock_flags, flake_lock_flags_free, flake_lock_flags_new, flake_reference,
+	flake_reference_and_fragment_from_string, flake_reference_parse_flags,
+	flake_reference_parse_flags_free, flake_reference_parse_flags_new,
+	flake_reference_parse_flags_set_base_directory, flake_settings, flake_settings_free,
+	flake_settings_new, get_attr_byname, get_attr_name_byidx, get_attrs_size, get_list_byidx,
+	get_list_size, get_string, get_type, has_attr_byname, init_bool, init_int, init_string,
+	libexpr_init, libstore_init, libutil_init, locked_flake, locked_flake_free,
+	locked_flake_get_output_attrs, make_attrs, make_bindings_builder, realised_string,
+	realised_string_free, realised_string_get_buffer_size, realised_string_get_buffer_start,
+	realised_string_get_store_path, realised_string_get_store_path_count, set_err_msg, setting_set,
+	state_free, store_open, store_path_name, string_realise, value, value_call, value_decref,
+	value_incref,
 };
 
 // Contains macros helpers
@@ -117,22 +130,26 @@
 	}
 }
 
+pub fn gc_now() {
+	unsafe { nix_raw::gc_now() };
+}
+
 pub fn gc_register_my_thread() {
-	assert_eq!(unsafe { nix_raw::GC_thread_is_registered() }, 0);
+	assert_eq!(unsafe { GC_thread_is_registered() }, 0);
 
-	let mut sb = nix_raw::GC_stack_base {
+	let mut sb = GC_stack_base {
 		mem_base: null_mut(),
 	};
-	let r = unsafe { nix_raw::GC_get_stack_base(&mut sb) };
-	if r as u32 != nix_raw::GC_SUCCESS {
+	let r = unsafe { GC_get_stack_base(&mut sb) };
+	if r as u32 != GC_SUCCESS {
 		panic!("failed to get thread stack base");
 	}
-	unsafe { nix_raw::GC_register_my_thread(&sb) };
+	unsafe { GC_register_my_thread(&sb) };
 }
 pub fn gc_unregister_my_thread() {
-	assert_eq!(unsafe { nix_raw::GC_thread_is_registered() }, 1);
+	assert_eq!(unsafe { GC_thread_is_registered() }, 1);
 
-	unsafe { nix_raw::GC_unregister_my_thread() };
+	unsafe { GC_unregister_my_thread() };
 }
 
 pub struct ThreadRegisterGuard {}
@@ -178,12 +195,12 @@
 
 		// TODO: Can throw error (resulting in panic) if unable to retrieve error. Should be able to resolve by passing context as a first argument,
 		// but it looks ugly
-		let str = unsafe { nix_raw::err_msg(null_mut(), self.0, null_mut()) };
+		let str = unsafe { err_msg(null_mut(), self.0, null_mut()) };
 		Some(unsafe { CStr::from_ptr(str) }.to_string_lossy())
 	}
 	fn clean_err(&mut self) {
 		unsafe {
-			nix_raw::clear_err(self.0);
+			clear_err(self.0);
 		}
 	}
 
@@ -211,7 +228,7 @@
 impl Drop for NixContext {
 	fn drop(&mut self) {
 		unsafe {
-			nix_raw::c_context_free(self.0);
+			c_context_free(self.0);
 		}
 	}
 }
@@ -225,35 +242,26 @@
 	fn new() -> Result<Self> {
 		let mut ctx = NixContext::new();
 		let store = ctx
-			.run_in_context(|c| unsafe { nix_raw::store_open(c, c"auto".as_ptr(), null_mut()) })
+			.run_in_context(|c| unsafe { store_open(c, c"auto".as_ptr(), null_mut()) })
 			.map(Store)?;
 
 		let builder = ctx.run_in_context(|c| unsafe { eval_state_builder_new(c, store.0) })?;
-		ctx.run_in_context(|c| {
-			unsafe { nix_raw::eval_state_builder_load(c, builder) }
-			// eval_s
-		})?;
-		ctx.run_in_context(|c| {
-			unsafe {
-				nix_raw::eval_state_builder_set_eval_setting(
-					c,
-					builder,
-					c"lazy-trees".as_ptr(),
-					c"true".as_ptr(),
-				)
-			}
-			// eval_s
+		ctx.run_in_context(|c| unsafe { eval_state_builder_load(c, builder) })?;
+		ctx.run_in_context(|c| unsafe {
+			eval_state_builder_set_eval_setting(
+				c,
+				builder,
+				c"lazy-trees".as_ptr(),
+				c"true".as_ptr(),
+			)
 		})?;
-		ctx.run_in_context(|c| {
-			unsafe {
-				nix_raw::eval_state_builder_set_eval_setting(
-					c,
-					builder,
-					c"lazy-locks".as_ptr(),
-					c"true".as_ptr(),
-				)
-			}
-			// eval_s
+		ctx.run_in_context(|c| unsafe {
+			eval_state_builder_set_eval_setting(
+				c,
+				builder,
+				c"lazy-locks".as_ptr(),
+				c"true".as_ptr(),
+			)
 		})?;
 		let state = ctx
 			.run_in_context(|c| unsafe { eval_state_build(c, builder) })
@@ -280,9 +288,7 @@
 thread_local! {
 	static THREAD_STATE: RefCell<ThreadState> = RefCell::new(ThreadState::new().expect("thread state init shouldn't fail"));
 }
-fn with_default_context<T>(
-	f: impl FnOnce(*mut c_context, *mut nix_raw::EvalState) -> T,
-) -> Result<T> {
+fn with_default_context<T>(f: impl FnOnce(*mut c_context, *mut c_eval_state) -> T) -> Result<T> {
 	let global = &GLOBAL_STATE.state;
 	let (ctx, state) = THREAD_STATE.with_borrow_mut(|w| (w.ctx.0, global.0));
 	let mut ctx = NixContext(ctx);
@@ -385,16 +391,16 @@
 }
 
 unsafe extern "C" fn copy_nix_str(start: *const c_char, n: c_uint, user_data: *mut c_void) {
-	let s = unsafe { std::slice::from_raw_parts(start.cast::<u8>(), n as usize) };
+	let s = unsafe { slice::from_raw_parts(start.cast::<u8>(), n as usize) };
 	let s = std::str::from_utf8(s).expect("c string has invalid utf-8");
 	unsafe { *user_data.cast::<String>() = s.to_owned() };
 }
 
-struct Store(*mut nix_raw::Store);
+struct Store(*mut c_store);
 unsafe impl Send for Store {}
 unsafe impl Sync for Store {}
 
-struct EvalState(*mut nix_raw::EvalState);
+struct EvalState(*mut c_eval_state);
 unsafe impl Send for EvalState {}
 unsafe impl Sync for EvalState {}
 
@@ -406,7 +412,7 @@
 	}
 }
 
-pub struct FlakeReference(*mut nix_raw::flake_reference);
+pub struct FlakeReference(*mut flake_reference);
 impl FlakeReference {
 	#[instrument(name = "new-flake-reference", skip(flake, parse, fetch))]
 	pub fn new(
@@ -419,7 +425,7 @@
 		let mut fragment = String::new();
 		// let fetch_settings = fetcher_settings;
 		with_default_context(|c, _| unsafe {
-			nix_raw::flake_reference_and_fragment_from_string(
+			flake_reference_and_fragment_from_string(
 				c,
 				fetch.0,
 				flake.0,
@@ -449,7 +455,7 @@
 unsafe impl Send for FlakeReference {}
 unsafe impl Sync for FlakeReference {}
 
-pub struct LockedFlake(*mut nix_raw::locked_flake);
+pub struct LockedFlake(*mut locked_flake);
 impl LockedFlake {
 	pub fn get_attrs(&self, settings: &mut FlakeSettings) -> Result<Value> {
 		with_default_context(|c, es| unsafe {
@@ -480,7 +486,7 @@
 	f
 }
 
-pub struct RealisedString(*mut nix_raw::realised_string);
+pub struct RealisedString(*mut realised_string);
 impl fmt::Debug for RealisedString {
 	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 		self.as_str().fmt(f)
@@ -489,19 +495,19 @@
 
 impl RealisedString {
 	pub fn as_str(&self) -> &str {
-		let len = unsafe { nix_raw::realised_string_get_buffer_size(self.0) };
-		let data: *const u8 = unsafe { nix_raw::realised_string_get_buffer_start(self.0) }.cast();
-		let data = unsafe { std::slice::from_raw_parts(data, len) };
+		let len = unsafe { realised_string_get_buffer_size(self.0) };
+		let data: *const u8 = unsafe { realised_string_get_buffer_start(self.0) }.cast();
+		let data = unsafe { slice::from_raw_parts(data, len) };
 		std::str::from_utf8(data).expect("non-utf8 strings not supported")
 	}
 	pub fn path_count(&self) -> usize {
-		unsafe { nix_raw::realised_string_get_store_path_count(self.0) }
+		unsafe { realised_string_get_store_path_count(self.0) }
 	}
 	pub fn path(&self, i: usize) -> String {
 		assert!(i < self.path_count());
-		let path = unsafe { nix_raw::realised_string_get_store_path(self.0, i) };
+		let path = unsafe { realised_string_get_store_path(self.0, i) };
 		let mut err_out = String::new();
-		unsafe { nix_raw::store_path_name(path, Some(copy_nix_str), (&raw mut err_out).cast()) };
+		unsafe { store_path_name(path, Some(copy_nix_str), (&raw mut err_out).cast()) };
 		err_out
 	}
 }
@@ -509,11 +515,11 @@
 unsafe impl Send for RealisedString {}
 impl Drop for RealisedString {
 	fn drop(&mut self) {
-		unsafe { nix_raw::realised_string_free(self.0) }
+		unsafe { realised_string_free(self.0) }
 	}
 }
 
-pub struct Value(*mut nix_raw::value);
+pub struct Value(*mut value);
 
 unsafe impl Send for Value {}
 unsafe impl Sync for Value {}
@@ -544,17 +550,18 @@
 	}
 }
 
-struct AttrsBuilder(*mut nix_raw::BindingsBuilder);
+struct AttrsBuilder(*mut c_bindings_builder);
 impl AttrsBuilder {
 	fn new(capacity: usize) -> Self {
-		with_default_context(|c, es| unsafe { nix_raw::make_bindings_builder(c, es, capacity) })
+		with_default_context(|c, es| unsafe { make_bindings_builder(c, es, capacity) })
 			.map(Self)
 			.expect("alloc should not fail")
 	}
 	fn insert(&mut self, k: &impl AsFieldName, v: Value) {
 		k.as_field_name(|name| {
 			with_default_context(|c, _| unsafe {
-				nix_raw::bindings_builder_insert(c, self.0, name.as_ptr().cast(), v.0)
+				bindings_builder_insert(c, self.0, name.as_ptr().cast(), v.0);
+				// bindings_builder_insert doesn't do incref
 			})
 		})
 		.expect("builder insert shouldn't fail");
@@ -562,7 +569,7 @@
 }
 impl Drop for AttrsBuilder {
 	fn drop(&mut self) {
-		unsafe { nix_raw::bindings_builder_free(self.0) };
+		unsafe { bindings_builder_free(self.0) };
 	}
 }
 
@@ -573,8 +580,9 @@
 		for (k, v) in v {
 			b.insert(&k, v);
 		}
-		with_default_context(|c, _| unsafe { nix_raw::make_attrs(c, out.0, b.0) })
+		with_default_context(|c, _| unsafe { make_attrs(c, out.0, b.0) })
 			.expect("attrs initialization should not fail");
+
 		out
 	}
 	fn new_list<T: Into<Self>>(v: Vec<T>) -> Self {
@@ -611,7 +619,7 @@
 	// 	Ok(())
 	// }
 	pub fn type_of(&self) -> NixType {
-		let ty = with_default_context(|c, _| unsafe { nix_raw::get_type(c, self.0) })
+		let ty = with_default_context(|c, _| unsafe { get_type(c, self.0) })
 			.expect("get_type should not fail");
 		NixType::from_int(ty)
 	}
@@ -628,7 +636,7 @@
 		Ok(str_out)
 	}
 	pub fn to_realised_string(&self) -> Result<RealisedString> {
-		with_default_context(|c, es| unsafe { nix_raw::string_realise(c, es, self.0, false) })
+		with_default_context(|c, es| unsafe { string_realise(c, es, self.0, false) })
 			.map(RealisedString)
 
 		// let store_paths = unsafe { nix_raw::realised_string_get_store_path_count(str) };
@@ -642,9 +650,7 @@
 
 	pub fn has_field(&self, field: &str) -> Result<bool> {
 		let f = init_field_name(field);
-		with_default_context(|c, es| unsafe {
-			nix_raw::has_attr_byname(c, self.0, es, f.as_ptr().cast())
-		})
+		with_default_context(|c, es| unsafe { has_attr_byname(c, self.0, es, f.as_ptr().cast()) })
 	}
 	// pub fn derivation_path(&self) {
 	// 	nix_raw::real
@@ -654,13 +660,12 @@
 			bail!("invalid type: expected attrs");
 		}
 
-		let len = with_default_context(|c, _| unsafe { nix_raw::get_attrs_size(c, self.0) })?;
+		let len = with_default_context(|c, _| unsafe { get_attrs_size(c, self.0) })?;
 		let mut out = Vec::with_capacity(len as usize);
 
 		for i in 0..len {
-			let name = with_default_context(|c, es| unsafe {
-				nix_raw::get_attr_name_byidx(c, self.0, es, i)
-			})?;
+			let name =
+				with_default_context(|c, es| unsafe { get_attr_name_byidx(c, self.0, es, i) })?;
 			let c = unsafe { CStr::from_ptr(name) };
 			out.push(c.to_str().expect("nix field names are utf-8").to_owned());
 		}
@@ -670,14 +675,12 @@
 		if !matches!(self.type_of(), NixType::List) {
 			bail!("invalid type: expected list");
 		}
-		let len =
-			with_default_context(|c, _| unsafe { nix_raw::get_list_size(c, self.0) })? as usize;
+		let len = with_default_context(|c, _| unsafe { get_list_size(c, self.0) })? as usize;
 		if v >= len {
 			bail!("oob list get: {v} >= {len}");
 		}
 
-		with_default_context(|c, es| unsafe { nix_raw::get_list_byidx(c, self.0, es, v as u32) })
-			.map(Self)
+		with_default_context(|c, es| unsafe { get_list_byidx(c, self.0, es, v as u32) }).map(Self)
 	}
 	pub fn attrs_update(self, other: Value) -> Result<Self> {
 		let a_fields = self.list_fields()?;
@@ -710,7 +713,7 @@
 
 		name.as_field_name(|name| {
 			with_default_context(|c, es| unsafe {
-				nix_raw::get_attr_byname(c, self.0, es, name.as_ptr().cast())
+				get_attr_byname(c, self.0, es, name.as_ptr().cast())
 			})
 			.map(Self)
 		})
@@ -735,9 +738,7 @@
 		};
 
 		let out = Value::new_uninit();
-		with_default_context(|c, es| unsafe {
-			nix_raw::value_call(c, es, function.0, v.0, out.0)
-		})?;
+		with_default_context(|c, es| unsafe { value_call(c, es, function.0, v.0, out.0) })?;
 
 		Ok(out)
 	}
@@ -745,7 +746,7 @@
 		let s = CString::new(v).expect("expression shouldn't have internal NULs");
 		let out = Self::new_uninit();
 		with_default_context(|c, es| unsafe {
-			expr_eval_from_string(c, es, s.as_ptr(), c"/homeless-shelter".as_ptr(), out.0)
+			expr_eval_from_string(c, es, s.as_ptr(), c"/root".as_ptr(), out.0)
 		})?;
 		Ok(out)
 	}
@@ -764,11 +765,10 @@
 			self.clone()
 		};
 		// to_string here blocks until the path is built
-		let drv_path =
-			tokio::task::spawn_blocking(move || v.builtin_to_string()?.to_realised_string())
-				.await
-				.expect("spawn should not fail")?;
-		Ok(PathBuf::from(drv_path.as_str()))
+		let s = v.builtin_to_string()?;
+		let rs = s.to_realised_string()?;
+		let drv_path = rs.as_str().to_owned();
+		Ok(PathBuf::from(drv_path))
 	}
 	pub fn as_json<T: DeserializeOwned>(&self) -> Result<T> {
 		let to_json = Self::eval("builtins.toJSON")?;
@@ -848,17 +848,14 @@
 }
 
 pub fn init_libraries() {
-	unsafe { nix_raw::GC_allow_register_threads() };
-	unsafe {
-		nix_raw::GC_init();
-	};
+	unsafe { GC_allow_register_threads() };
 
 	let mut ctx = NixContext::new();
-	ctx.run_in_context(|c| unsafe { nix_raw::libutil_init(c) })
+	ctx.run_in_context(|c| unsafe { libutil_init(c) })
 		.expect("util init should not fail");
-	ctx.run_in_context(|c| unsafe { nix_raw::libstore_init(c) })
+	ctx.run_in_context(|c| unsafe { libstore_init(c) })
 		.expect("store init should not fail");
-	ctx.run_in_context(|c| unsafe { nix_raw::libexpr_init(c) })
+	ctx.run_in_context(|c| unsafe { libexpr_init(c) })
 		.expect("expr init should not fail");
 
 	nix_logging_cxx::apply_tracing_logger();
@@ -872,8 +869,11 @@
 	fetch_settings.set(c"warn-dirty", c"false");
 
 	let manifest = format!("{}/../../", env!("CARGO_MANIFEST_DIR"));
-	let (mut r, _) = FlakeReference::new(&manifest, &fetch_settings)?;
-	let locked = r.lock(&fetch_settings)?;
+	let flake = FlakeSettings::new()?;
+	let parse = FlakeReferenceParseFlags::new(&flake)?;
+	let (mut r, _) = FlakeReference::new(&manifest, &flake, &parse, &fetch_settings)?;
+	let lock = FlakeLockFlags::new(&flake)?;
+	let locked = r.lock(&fetch_settings, &flake, &lock)?;
 	let attrs = locked.get_attrs(&mut FlakeSettings::new()?)?;
 
 	let builtins = Value::eval("builtins")?;
@@ -887,3 +887,22 @@
 
 	Ok(())
 }
+
+// pub struct GcAlloc;
+// unsafe impl GlobalAlloc for GcAlloc {
+// 	unsafe fn alloc(&self, l: Layout) -> *mut u8 {
+// 		let ptr = unsafe { GC_malloc(l.size()) };
+// 		ptr.cast()
+// 	}
+// 	unsafe fn dealloc(&self, ptr: *mut u8, _: Layout) {
+// 		// unsafe { GC_free(ptr.cast()) };
+// 	}
+//
+// 	unsafe fn realloc(&self, ptr: *mut u8, _: Layout, new_size: usize) -> *mut u8 {
+// 		let ptr = unsafe { GC_realloc(ptr.cast(), new_size) };
+// 		ptr.cast()
+// 	}
+// }
+//
+// #[global_allocator]
+// static GC: GcAlloc = GcAlloc;
modifiedcrates/nix-eval/src/logging.rsdiffbeforeafterboth
--- a/crates/nix-eval/src/logging.rs
+++ b/crates/nix-eval/src/logging.rs
@@ -504,7 +504,7 @@
 			// Only plain colors are enabled, everything other might corrupt the output
 			return;
 		}
-		self.output.push_str("IDK\x1b[");
+		self.output.push_str("\x1b[");
 		for (i, par) in params.iter().enumerate() {
 			if i != 0 {
 				let _ = write!(self.output, ";");
modifiedcrates/nixlike/Cargo.tomldiffbeforeafterboth
7[dependencies]7[dependencies]
8thiserror.workspace = true8thiserror.workspace = true
99
10alejandra = { git = "https://github.com/kamadorueda/alejandra" }
11linked-hash-map = "0.5.6"10linked-hash-map = "0.5.6"
12peg = "0.8.5"11peg = "0.8.5"
13ron = "0.11.0"12ron = "0.11.0"
modifiedcrates/nixlike/src/lib.rsdiffbeforeafterboth
--- a/crates/nixlike/src/lib.rs
+++ b/crates/nixlike/src/lib.rs
@@ -5,7 +5,6 @@
 //! expressions and expect it to work, only basic primitives are supported, and there is no
 //! variables/recursive records, interpolation, e.t.c.
 
-use alejandra::config::Indentation;
 use linked_hash_map::LinkedHashMap;
 use peg::str::LineCol;
 use se_impl::MySerialize;
@@ -197,14 +196,8 @@
 	assert_eq!(serialize("Hello\nworld").unwrap(), "\"Hello\\nworld\"\n");
 }
 pub fn format_nix(value: &String) -> String {
-	let (_, out) = alejandra::format::in_memory(
-		"".to_owned(),
-		value.to_owned(),
-		alejandra::config::Config {
-			indentation: Indentation::TwoSpaces,
-		},
-	);
-	out
+	// TODO
+	value.to_owned()
 }
 
 #[test]
modifiedcrates/nixlike/src/to_string.rsdiffbeforeafterboth
--- a/crates/nixlike/src/to_string.rs
+++ b/crates/nixlike/src/to_string.rs
@@ -1,5 +1,3 @@
-use alejandra::config::Indentation;
-
 use crate::Value;
 
 pub fn write_identifier(k: &str, out: &mut String) {
@@ -100,12 +98,5 @@
 pub fn write_nix(value: &Value) -> String {
 	let mut out = String::new();
 	write_nix_buf(value, &mut out);
-	let (_, out) = alejandra::format::in_memory(
-		"".to_owned(),
-		out,
-		alejandra::config::Config {
-			indentation: Indentation::TwoSpaces,
-		},
-	);
 	out
 }
modifiedflake.nixdiffbeforeafterboth
--- a/flake.nix
+++ b/flake.nix
@@ -114,7 +114,13 @@
           {
             _module.args.pkgs = import inputs.nixpkgs {
               inherit system;
-              overlays = [ (inputs.rust-overlay.overlays.default) ];
+              overlays = [ (inputs.rust-overlay.overlays.default) (final: prev: {
+                boehmgc = prev.boehmgc.overrideAttrs (prevAttrs: {
+                  configureFlags = prevAttrs.configureFlags ++ [
+                    "--enable-gc-assertions"
+                  ];
+                });
+              }) ];
             };
             # Reference fleet package should be built with nightly rust, specified in rust-toolchain.toml.
             packages = lib.mkIf deployerSystem (
@@ -157,7 +163,6 @@
               factory = craneLib.devShell;
               packages = with pkgs; [
                 rust
-                alejandra
                 cargo-edit
                 cargo-udeps
                 cargo-fuzz