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
1use std::alloc::{GlobalAlloc, Layout};
1use std::borrow::Cow;2use std::borrow::Cow;
2use std::cell::RefCell;3use std::cell::RefCell;
3use std::ffi::{CStr, CString, c_char, c_int, c_uint, c_void};4use std::ffi::{CStr, CString, c_char, c_int, c_uint, c_void};
4use std::fmt;5use std::mem::forget;
5use std::ptr::null_mut;6use std::ptr::null_mut;
6use std::sync::LazyLock;7use std::sync::LazyLock;
7use std::{collections::HashMap, path::PathBuf};8use std::{collections::HashMap, path::PathBuf};
9use std::{fmt, slice};
810
9use anyhow::{Context, anyhow, bail};11use anyhow::{Context, anyhow, bail};
10use serde::Serialize;12use serde::Serialize;
11use serde::de::DeserializeOwned;13use serde::de::DeserializeOwned;
1214
13pub use anyhow::Result;15pub use anyhow::Result;
14use tracing::instrument;16use tracing::{info, instrument};
1517
16use self::logging::nix_logging_cxx;18use self::logging::nix_logging_cxx;
17use self::nix_cxx::set_fetcher_setting;19use self::nix_cxx::set_fetcher_setting;
18use self::nix_raw::{20use self::nix_raw::{
21 BindingsBuilder as c_bindings_builder, EvalState as c_eval_state, GC_SUCCESS,
22 GC_allow_register_threads, GC_free, GC_get_stack_base, GC_init, GC_malloc, GC_realloc,
23 GC_register_my_thread, GC_stack_base, GC_thread_is_registered, GC_unregister_my_thread,
19 alloc_value, c_context, c_context_create, err_code, err_info_msg, eval_state_build,24 Store as c_store, alloc_value, bindings_builder_free, bindings_builder_insert, c_context,
25 c_context_create, c_context_free, clear_err, err_code, err_info_msg, err_msg, eval_state_build,
20 eval_state_builder_new, expr_eval_from_string, fetchers_settings, fetchers_settings_free,26 eval_state_builder_load, eval_state_builder_new, eval_state_builder_set_eval_setting,
21 fetchers_settings_new, flake_lock, flake_lock_flags, flake_lock_flags_free,27 expr_eval_from_string, fetchers_settings, fetchers_settings_free, fetchers_settings_new,
22 flake_lock_flags_new, flake_reference_parse_flags, flake_reference_parse_flags_free,28 flake_lock, flake_lock_flags, flake_lock_flags_free, flake_lock_flags_new, flake_reference,
29 flake_reference_and_fragment_from_string, flake_reference_parse_flags,
23 flake_reference_parse_flags_new, flake_reference_parse_flags_set_base_directory,30 flake_reference_parse_flags_free, flake_reference_parse_flags_new,
24 flake_settings, flake_settings_free, flake_settings_new, get_string, init_bool, init_int,31 flake_reference_parse_flags_set_base_directory, flake_settings, flake_settings_free,
32 flake_settings_new, get_attr_byname, get_attr_name_byidx, get_attrs_size, get_list_byidx,
25 init_string, locked_flake_free, locked_flake_get_output_attrs, set_err_msg, setting_set,33 get_list_size, get_string, get_type, has_attr_byname, init_bool, init_int, init_string,
34 libexpr_init, libstore_init, libutil_init, locked_flake, locked_flake_free,
35 locked_flake_get_output_attrs, make_attrs, make_bindings_builder, realised_string,
36 realised_string_free, realised_string_get_buffer_size, realised_string_get_buffer_start,
37 realised_string_get_store_path, realised_string_get_store_path_count, set_err_msg, setting_set,
26 state_free, value_decref, value_incref,38 state_free, store_open, store_path_name, string_realise, value, value_call, value_decref,
39 value_incref,
27};40};
2841
117 }130 }
118}131}
132
133pub fn gc_now() {
134 unsafe { nix_raw::gc_now() };
135}
119136
120pub fn gc_register_my_thread() {137pub fn gc_register_my_thread() {
121 assert_eq!(unsafe { nix_raw::GC_thread_is_registered() }, 0);138 assert_eq!(unsafe { GC_thread_is_registered() }, 0);
122139
123 let mut sb = nix_raw::GC_stack_base {140 let mut sb = GC_stack_base {
124 mem_base: null_mut(),141 mem_base: null_mut(),
125 };142 };
126 let r = unsafe { nix_raw::GC_get_stack_base(&mut sb) };143 let r = unsafe { GC_get_stack_base(&mut sb) };
127 if r as u32 != nix_raw::GC_SUCCESS {144 if r as u32 != GC_SUCCESS {
128 panic!("failed to get thread stack base");145 panic!("failed to get thread stack base");
129 }146 }
130 unsafe { nix_raw::GC_register_my_thread(&sb) };147 unsafe { GC_register_my_thread(&sb) };
131}148}
132pub fn gc_unregister_my_thread() {149pub fn gc_unregister_my_thread() {
133 assert_eq!(unsafe { nix_raw::GC_thread_is_registered() }, 1);150 assert_eq!(unsafe { GC_thread_is_registered() }, 1);
134151
135 unsafe { nix_raw::GC_unregister_my_thread() };152 unsafe { GC_unregister_my_thread() };
136}153}
137154
138pub struct ThreadRegisterGuard {}155pub struct ThreadRegisterGuard {}
178195
179 // TODO: Can throw error (resulting in panic) if unable to retrieve error. Should be able to resolve by passing context as a first argument,196 // TODO: Can throw error (resulting in panic) if unable to retrieve error. Should be able to resolve by passing context as a first argument,
180 // but it looks ugly197 // but it looks ugly
181 let str = unsafe { nix_raw::err_msg(null_mut(), self.0, null_mut()) };198 let str = unsafe { err_msg(null_mut(), self.0, null_mut()) };
182 Some(unsafe { CStr::from_ptr(str) }.to_string_lossy())199 Some(unsafe { CStr::from_ptr(str) }.to_string_lossy())
183 }200 }
184 fn clean_err(&mut self) {201 fn clean_err(&mut self) {
185 unsafe {202 unsafe {
186 nix_raw::clear_err(self.0);203 clear_err(self.0);
187 }204 }
188 }205 }
189206
211impl Drop for NixContext {228impl Drop for NixContext {
212 fn drop(&mut self) {229 fn drop(&mut self) {
213 unsafe {230 unsafe {
214 nix_raw::c_context_free(self.0);231 c_context_free(self.0);
215 }232 }
216 }233 }
217}234}
225 fn new() -> Result<Self> {242 fn new() -> Result<Self> {
226 let mut ctx = NixContext::new();243 let mut ctx = NixContext::new();
227 let store = ctx244 let store = ctx
228 .run_in_context(|c| unsafe { nix_raw::store_open(c, c"auto".as_ptr(), null_mut()) })245 .run_in_context(|c| unsafe { store_open(c, c"auto".as_ptr(), null_mut()) })
229 .map(Store)?;246 .map(Store)?;
230247
231 let builder = ctx.run_in_context(|c| unsafe { eval_state_builder_new(c, store.0) })?;248 let builder = ctx.run_in_context(|c| unsafe { eval_state_builder_new(c, store.0) })?;
232 ctx.run_in_context(|c| {249 ctx.run_in_context(|c| unsafe { eval_state_builder_load(c, builder) })?;
233 unsafe { nix_raw::eval_state_builder_load(c, builder) }
234 // eval_s
235 })?;
236 ctx.run_in_context(|c| {250 ctx.run_in_context(|c| unsafe {
237 unsafe {
238 nix_raw::eval_state_builder_set_eval_setting(251 eval_state_builder_set_eval_setting(
239 c,252 c,
240 builder,253 builder,
241 c"lazy-trees".as_ptr(),254 c"lazy-trees".as_ptr(),
242 c"true".as_ptr(),255 c"true".as_ptr(),
243 )256 )
244 }257 })?;
245 // eval_s
246 })?;
247 ctx.run_in_context(|c| {258 ctx.run_in_context(|c| unsafe {
248 unsafe {
249 nix_raw::eval_state_builder_set_eval_setting(259 eval_state_builder_set_eval_setting(
250 c,260 c,
251 builder,261 builder,
252 c"lazy-locks".as_ptr(),262 c"lazy-locks".as_ptr(),
253 c"true".as_ptr(),263 c"true".as_ptr(),
254 )264 )
255 }265 })?;
256 // eval_s
257 })?;
258 let state = ctx266 let state = ctx
259 .run_in_context(|c| unsafe { eval_state_build(c, builder) })267 .run_in_context(|c| unsafe { eval_state_build(c, builder) })
260 .map(EvalState)?;268 .map(EvalState)?;
280thread_local! {288thread_local! {
281 static THREAD_STATE: RefCell<ThreadState> = RefCell::new(ThreadState::new().expect("thread state init shouldn't fail"));289 static THREAD_STATE: RefCell<ThreadState> = RefCell::new(ThreadState::new().expect("thread state init shouldn't fail"));
282}290}
283fn with_default_context<T>(291fn with_default_context<T>(f: impl FnOnce(*mut c_context, *mut c_eval_state) -> T) -> Result<T> {
284 f: impl FnOnce(*mut c_context, *mut nix_raw::EvalState) -> T,
285) -> Result<T> {
286 let global = &GLOBAL_STATE.state;292 let global = &GLOBAL_STATE.state;
287 let (ctx, state) = THREAD_STATE.with_borrow_mut(|w| (w.ctx.0, global.0));293 let (ctx, state) = THREAD_STATE.with_borrow_mut(|w| (w.ctx.0, global.0));
385}391}
386392
387unsafe extern "C" fn copy_nix_str(start: *const c_char, n: c_uint, user_data: *mut c_void) {393unsafe extern "C" fn copy_nix_str(start: *const c_char, n: c_uint, user_data: *mut c_void) {
388 let s = unsafe { std::slice::from_raw_parts(start.cast::<u8>(), n as usize) };394 let s = unsafe { slice::from_raw_parts(start.cast::<u8>(), n as usize) };
389 let s = std::str::from_utf8(s).expect("c string has invalid utf-8");395 let s = std::str::from_utf8(s).expect("c string has invalid utf-8");
390 unsafe { *user_data.cast::<String>() = s.to_owned() };396 unsafe { *user_data.cast::<String>() = s.to_owned() };
391}397}
392398
393struct Store(*mut nix_raw::Store);399struct Store(*mut c_store);
394unsafe impl Send for Store {}400unsafe impl Send for Store {}
395unsafe impl Sync for Store {}401unsafe impl Sync for Store {}
396402
397struct EvalState(*mut nix_raw::EvalState);403struct EvalState(*mut c_eval_state);
398unsafe impl Send for EvalState {}404unsafe impl Send for EvalState {}
399unsafe impl Sync for EvalState {}405unsafe impl Sync for EvalState {}
400406
406 }412 }
407}413}
408414
409pub struct FlakeReference(*mut nix_raw::flake_reference);415pub struct FlakeReference(*mut flake_reference);
410impl FlakeReference {416impl FlakeReference {
411 #[instrument(name = "new-flake-reference", skip(flake, parse, fetch))]417 #[instrument(name = "new-flake-reference", skip(flake, parse, fetch))]
412 pub fn new(418 pub fn new(
419 let mut fragment = String::new();425 let mut fragment = String::new();
420 // let fetch_settings = fetcher_settings;426 // let fetch_settings = fetcher_settings;
421 with_default_context(|c, _| unsafe {427 with_default_context(|c, _| unsafe {
422 nix_raw::flake_reference_and_fragment_from_string(428 flake_reference_and_fragment_from_string(
423 c,429 c,
424 fetch.0,430 fetch.0,
425 flake.0,431 flake.0,
449unsafe impl Send for FlakeReference {}455unsafe impl Send for FlakeReference {}
450unsafe impl Sync for FlakeReference {}456unsafe impl Sync for FlakeReference {}
451457
452pub struct LockedFlake(*mut nix_raw::locked_flake);458pub struct LockedFlake(*mut locked_flake);
453impl LockedFlake {459impl LockedFlake {
454 pub fn get_attrs(&self, settings: &mut FlakeSettings) -> Result<Value> {460 pub fn get_attrs(&self, settings: &mut FlakeSettings) -> Result<Value> {
455 with_default_context(|c, es| unsafe {461 with_default_context(|c, es| unsafe {
480 f486 f
481}487}
482488
483pub struct RealisedString(*mut nix_raw::realised_string);489pub struct RealisedString(*mut realised_string);
484impl fmt::Debug for RealisedString {490impl fmt::Debug for RealisedString {
485 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {491 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
486 self.as_str().fmt(f)492 self.as_str().fmt(f)
489495
490impl RealisedString {496impl RealisedString {
491 pub fn as_str(&self) -> &str {497 pub fn as_str(&self) -> &str {
492 let len = unsafe { nix_raw::realised_string_get_buffer_size(self.0) };498 let len = unsafe { realised_string_get_buffer_size(self.0) };
493 let data: *const u8 = unsafe { nix_raw::realised_string_get_buffer_start(self.0) }.cast();499 let data: *const u8 = unsafe { realised_string_get_buffer_start(self.0) }.cast();
494 let data = unsafe { std::slice::from_raw_parts(data, len) };500 let data = unsafe { slice::from_raw_parts(data, len) };
495 std::str::from_utf8(data).expect("non-utf8 strings not supported")501 std::str::from_utf8(data).expect("non-utf8 strings not supported")
496 }502 }
497 pub fn path_count(&self) -> usize {503 pub fn path_count(&self) -> usize {
498 unsafe { nix_raw::realised_string_get_store_path_count(self.0) }504 unsafe { realised_string_get_store_path_count(self.0) }
499 }505 }
500 pub fn path(&self, i: usize) -> String {506 pub fn path(&self, i: usize) -> String {
501 assert!(i < self.path_count());507 assert!(i < self.path_count());
502 let path = unsafe { nix_raw::realised_string_get_store_path(self.0, i) };508 let path = unsafe { realised_string_get_store_path(self.0, i) };
503 let mut err_out = String::new();509 let mut err_out = String::new();
504 unsafe { nix_raw::store_path_name(path, Some(copy_nix_str), (&raw mut err_out).cast()) };510 unsafe { store_path_name(path, Some(copy_nix_str), (&raw mut err_out).cast()) };
505 err_out511 err_out
506 }512 }
507}513}
508514
509unsafe impl Send for RealisedString {}515unsafe impl Send for RealisedString {}
510impl Drop for RealisedString {516impl Drop for RealisedString {
511 fn drop(&mut self) {517 fn drop(&mut self) {
512 unsafe { nix_raw::realised_string_free(self.0) }518 unsafe { realised_string_free(self.0) }
513 }519 }
514}520}
515521
516pub struct Value(*mut nix_raw::value);522pub struct Value(*mut value);
517523
518unsafe impl Send for Value {}524unsafe impl Send for Value {}
519unsafe impl Sync for Value {}525unsafe impl Sync for Value {}
544 }550 }
545}551}
546552
547struct AttrsBuilder(*mut nix_raw::BindingsBuilder);553struct AttrsBuilder(*mut c_bindings_builder);
548impl AttrsBuilder {554impl AttrsBuilder {
549 fn new(capacity: usize) -> Self {555 fn new(capacity: usize) -> Self {
550 with_default_context(|c, es| unsafe { nix_raw::make_bindings_builder(c, es, capacity) })556 with_default_context(|c, es| unsafe { make_bindings_builder(c, es, capacity) })
551 .map(Self)557 .map(Self)
552 .expect("alloc should not fail")558 .expect("alloc should not fail")
553 }559 }
554 fn insert(&mut self, k: &impl AsFieldName, v: Value) {560 fn insert(&mut self, k: &impl AsFieldName, v: Value) {
555 k.as_field_name(|name| {561 k.as_field_name(|name| {
556 with_default_context(|c, _| unsafe {562 with_default_context(|c, _| unsafe {
557 nix_raw::bindings_builder_insert(c, self.0, name.as_ptr().cast(), v.0)563 bindings_builder_insert(c, self.0, name.as_ptr().cast(), v.0);
564 // bindings_builder_insert doesn't do incref
558 })565 })
559 })566 })
560 .expect("builder insert shouldn't fail");567 .expect("builder insert shouldn't fail");
561 }568 }
562}569}
563impl Drop for AttrsBuilder {570impl Drop for AttrsBuilder {
564 fn drop(&mut self) {571 fn drop(&mut self) {
565 unsafe { nix_raw::bindings_builder_free(self.0) };572 unsafe { bindings_builder_free(self.0) };
566 }573 }
567}574}
568575
573 for (k, v) in v {580 for (k, v) in v {
574 b.insert(&k, v);581 b.insert(&k, v);
575 }582 }
576 with_default_context(|c, _| unsafe { nix_raw::make_attrs(c, out.0, b.0) })583 with_default_context(|c, _| unsafe { make_attrs(c, out.0, b.0) })
577 .expect("attrs initialization should not fail");584 .expect("attrs initialization should not fail");
585
578 out586 out
611 // Ok(())619 // Ok(())
612 // }620 // }
613 pub fn type_of(&self) -> NixType {621 pub fn type_of(&self) -> NixType {
614 let ty = with_default_context(|c, _| unsafe { nix_raw::get_type(c, self.0) })622 let ty = with_default_context(|c, _| unsafe { get_type(c, self.0) })
615 .expect("get_type should not fail");623 .expect("get_type should not fail");
616 NixType::from_int(ty)624 NixType::from_int(ty)
617 }625 }
628 Ok(str_out)636 Ok(str_out)
629 }637 }
630 pub fn to_realised_string(&self) -> Result<RealisedString> {638 pub fn to_realised_string(&self) -> Result<RealisedString> {
631 with_default_context(|c, es| unsafe { nix_raw::string_realise(c, es, self.0, false) })639 with_default_context(|c, es| unsafe { string_realise(c, es, self.0, false) })
632 .map(RealisedString)640 .map(RealisedString)
633641
634 // let store_paths = unsafe { nix_raw::realised_string_get_store_path_count(str) };642 // let store_paths = unsafe { nix_raw::realised_string_get_store_path_count(str) };
643 pub fn has_field(&self, field: &str) -> Result<bool> {651 pub fn has_field(&self, field: &str) -> Result<bool> {
644 let f = init_field_name(field);652 let f = init_field_name(field);
645 with_default_context(|c, es| unsafe {653 with_default_context(|c, es| unsafe { has_attr_byname(c, self.0, es, f.as_ptr().cast()) })
646 nix_raw::has_attr_byname(c, self.0, es, f.as_ptr().cast())
647 })
648 }654 }
649 // pub fn derivation_path(&self) {655 // pub fn derivation_path(&self) {
654 bail!("invalid type: expected attrs");660 bail!("invalid type: expected attrs");
655 }661 }
656662
657 let len = with_default_context(|c, _| unsafe { nix_raw::get_attrs_size(c, self.0) })?;663 let len = with_default_context(|c, _| unsafe { get_attrs_size(c, self.0) })?;
658 let mut out = Vec::with_capacity(len as usize);664 let mut out = Vec::with_capacity(len as usize);
659665
660 for i in 0..len {666 for i in 0..len {
661 let name = with_default_context(|c, es| unsafe {667 let name =
662 nix_raw::get_attr_name_byidx(c, self.0, es, i)668 with_default_context(|c, es| unsafe { get_attr_name_byidx(c, self.0, es, i) })?;
663 })?;
664 let c = unsafe { CStr::from_ptr(name) };669 let c = unsafe { CStr::from_ptr(name) };
665 out.push(c.to_str().expect("nix field names are utf-8").to_owned());670 out.push(c.to_str().expect("nix field names are utf-8").to_owned());
671 bail!("invalid type: expected list");676 bail!("invalid type: expected list");
672 }677 }
673 let len =678 let len = with_default_context(|c, _| unsafe { get_list_size(c, self.0) })? as usize;
674 with_default_context(|c, _| unsafe { nix_raw::get_list_size(c, self.0) })? as usize;
675 if v >= len {679 if v >= len {
676 bail!("oob list get: {v} >= {len}");680 bail!("oob list get: {v} >= {len}");
677 }681 }
678682
679 with_default_context(|c, es| unsafe { nix_raw::get_list_byidx(c, self.0, es, v as u32) })683 with_default_context(|c, es| unsafe { get_list_byidx(c, self.0, es, v as u32) }).map(Self)
680 .map(Self)
681 }684 }
682 pub fn attrs_update(self, other: Value) -> Result<Self> {685 pub fn attrs_update(self, other: Value) -> Result<Self> {
710713
711 name.as_field_name(|name| {714 name.as_field_name(|name| {
712 with_default_context(|c, es| unsafe {715 with_default_context(|c, es| unsafe {
713 nix_raw::get_attr_byname(c, self.0, es, name.as_ptr().cast())716 get_attr_byname(c, self.0, es, name.as_ptr().cast())
714 })717 })
715 .map(Self)718 .map(Self)
716 })719 })
736739
737 let out = Value::new_uninit();740 let out = Value::new_uninit();
738 with_default_context(|c, es| unsafe {741 with_default_context(|c, es| unsafe { value_call(c, es, function.0, v.0, out.0) })?;
739 nix_raw::value_call(c, es, function.0, v.0, out.0)
740 })?;
741742
742 Ok(out)743 Ok(out)
745 let s = CString::new(v).expect("expression shouldn't have internal NULs");746 let s = CString::new(v).expect("expression shouldn't have internal NULs");
746 let out = Self::new_uninit();747 let out = Self::new_uninit();
747 with_default_context(|c, es| unsafe {748 with_default_context(|c, es| unsafe {
748 expr_eval_from_string(c, es, s.as_ptr(), c"/homeless-shelter".as_ptr(), out.0)749 expr_eval_from_string(c, es, s.as_ptr(), c"/root".as_ptr(), out.0)
749 })?;750 })?;
750 Ok(out)751 Ok(out)
751 }752 }
764 self.clone()765 self.clone()
765 };766 };
766 // to_string here blocks until the path is built767 // to_string here blocks until the path is built
767 let drv_path =
768 tokio::task::spawn_blocking(move || v.builtin_to_string()?.to_realised_string())768 let s = v.builtin_to_string()?;
769 let rs = s.to_realised_string()?;
769 .await770 let drv_path = rs.as_str().to_owned();
770 .expect("spawn should not fail")?;
771 Ok(PathBuf::from(drv_path.as_str()))771 Ok(PathBuf::from(drv_path))
772 }772 }
773 pub fn as_json<T: DeserializeOwned>(&self) -> Result<T> {773 pub fn as_json<T: DeserializeOwned>(&self) -> Result<T> {
774 let to_json = Self::eval("builtins.toJSON")?;774 let to_json = Self::eval("builtins.toJSON")?;
848}848}
849849
850pub fn init_libraries() {850pub fn init_libraries() {
851 unsafe { nix_raw::GC_allow_register_threads() };851 unsafe { GC_allow_register_threads() };
852 unsafe {
853 nix_raw::GC_init();
854 };
855852
856 let mut ctx = NixContext::new();853 let mut ctx = NixContext::new();
857 ctx.run_in_context(|c| unsafe { nix_raw::libutil_init(c) })854 ctx.run_in_context(|c| unsafe { libutil_init(c) })
858 .expect("util init should not fail");855 .expect("util init should not fail");
859 ctx.run_in_context(|c| unsafe { nix_raw::libstore_init(c) })856 ctx.run_in_context(|c| unsafe { libstore_init(c) })
860 .expect("store init should not fail");857 .expect("store init should not fail");
861 ctx.run_in_context(|c| unsafe { nix_raw::libexpr_init(c) })858 ctx.run_in_context(|c| unsafe { libexpr_init(c) })
862 .expect("expr init should not fail");859 .expect("expr init should not fail");
863860
864 nix_logging_cxx::apply_tracing_logger();861 nix_logging_cxx::apply_tracing_logger();
872 fetch_settings.set(c"warn-dirty", c"false");869 fetch_settings.set(c"warn-dirty", c"false");
873870
874 let manifest = format!("{}/../../", env!("CARGO_MANIFEST_DIR"));871 let manifest = format!("{}/../../", env!("CARGO_MANIFEST_DIR"));
872 let flake = FlakeSettings::new()?;
873 let parse = FlakeReferenceParseFlags::new(&flake)?;
875 let (mut r, _) = FlakeReference::new(&manifest, &fetch_settings)?;874 let (mut r, _) = FlakeReference::new(&manifest, &flake, &parse, &fetch_settings)?;
875 let lock = FlakeLockFlags::new(&flake)?;
876 let locked = r.lock(&fetch_settings)?;876 let locked = r.lock(&fetch_settings, &flake, &lock)?;
877 let attrs = locked.get_attrs(&mut FlakeSettings::new()?)?;877 let attrs = locked.get_attrs(&mut FlakeSettings::new()?)?;
878878
879 let builtins = Value::eval("builtins")?;879 let builtins = Value::eval("builtins")?;
888 Ok(())888 Ok(())
889}889}
890
891// pub struct GcAlloc;
892// unsafe impl GlobalAlloc for GcAlloc {
893// unsafe fn alloc(&self, l: Layout) -> *mut u8 {
894// let ptr = unsafe { GC_malloc(l.size()) };
895// ptr.cast()
896// }
897// unsafe fn dealloc(&self, ptr: *mut u8, _: Layout) {
898// // unsafe { GC_free(ptr.cast()) };
899// }
900//
901// unsafe fn realloc(&self, ptr: *mut u8, _: Layout, new_size: usize) -> *mut u8 {
902// let ptr = unsafe { GC_realloc(ptr.cast(), new_size) };
903// ptr.cast()
904// }
905// }
906//
907// #[global_allocator]
908// static GC: GcAlloc = GcAlloc;
890909
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
--- a/crates/nixlike/Cargo.toml
+++ b/crates/nixlike/Cargo.toml
@@ -7,7 +7,6 @@
 [dependencies]
 thiserror.workspace = true
 
-alejandra = { git = "https://github.com/kamadorueda/alejandra" }
 linked-hash-map = "0.5.6"
 peg = "0.8.5"
 ron = "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