fix: #39 Adds a garbage collected deep copy test
All checks were successful
per-push tests / build (push) Successful in 53s
per-push tests / test-utility (push) Successful in 40s
per-push tests / test-frontend (push) Successful in 40s
per-push tests / test-backend (push) Successful in 40s
per-push tests / timed-decomposer-parse (push) Successful in 39s

Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2025-07-28 23:36:26 +00:00
parent 7579d81d7b
commit 63554191f8

View file

@ -127,7 +127,7 @@ impl<T: Clone> Gc<T> {
pub fn deep_copy(&self) -> Gc<T> { pub fn deep_copy(&self) -> Gc<T> {
Gc(unsafe { Gc(unsafe {
NonNull::new(Box::into_raw(Box::new(Rc::from( NonNull::new(Box::into_raw(Box::new(Rc::from(
(*(self.0.as_ptr())).clone())))) self.0.as_ref().clone()))))
.expect("GC obj deep copy nonnull ptr check") .expect("GC obj deep copy nonnull ptr check")
}) })
} }
@ -292,9 +292,9 @@ impl Index<usize> for Cons {
mod tests { mod tests {
use super::*; use super::*;
struct GcTester<'a>(&'a mut bool); #[derive(Debug)]
struct GcTester<'a>(pub &'a mut bool);
// clone implementation leaks memory... but its for test
impl Clone for GcTester<'_> { impl Clone for GcTester<'_> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
unsafe { unsafe {
@ -309,19 +309,29 @@ mod tests {
} }
} }
// in non test code Id have to get the box back
impl Drop for GcTester<'_> { impl Drop for GcTester<'_> {
fn drop(&mut self) { fn drop(&mut self) {
*self.0 = true; *self.0 = true;
} }
} }
impl PartialEq for GcTester<'_> {
fn eq(&self, other: &Self) -> bool {
*(self.0) == *(other.0)
}
fn ne(&self, other: &Self) -> bool {
*(self.0) != *(other.0)
}
}
#[test] #[test]
fn test_gc_basic_behavior() { fn test_gc_basic_behavior() {
let mut flag = false; let mut flag = false;
let a = Into::<Gc<GcTester>>::into(GcTester(&mut flag)); let a = Into::<Gc<GcTester>>::into(GcTester(&mut flag));
assert!(!*(*a).0);
drop(a); drop(a);
assert!(flag) assert!(flag);
} }
#[test] #[test]
@ -329,9 +339,21 @@ mod tests {
let mut flag = false; let mut flag = false;
let a = let a =
Into::<Gc<GcTester>>::into(GcTester(&mut flag)).clone(); Into::<Gc<GcTester>>::into(GcTester(&mut flag)).clone();
assert!(!*(*a).0);
drop(a); drop(a);
assert!(flag) assert!(flag);
} }
// TODO: test deep copy #[test]
fn test_gc_deep_copy() {
let mut flag = false;
let reference_holder =
Into::<Gc<GcTester>>::into(GcTester(&mut flag)).clone();
assert!(!*(*reference_holder).0);
let copied_data = reference_holder.deep_copy();
assert!(!*(*copied_data).0);
assert_eq!(*reference_holder, *copied_data);
drop(reference_holder);
assert!(!*(*copied_data).0);
}
} }