From 7645587ef3fc7f1d85f838cd3c79e3318207825e Mon Sep 17 00:00:00 2001 From: shruti2522 Date: Sat, 11 Jul 2026 09:25:10 +0000 Subject: [PATCH] make Trace an unsafe trait for boa_engine compatibility --- .../src/collectors/mark_sweep_branded/cell.rs | 9 +- .../mark_sweep_branded/ephemeron.rs | 4 +- .../src/collectors/mark_sweep_branded/gc.rs | 4 +- .../mark_sweep_branded/tests/mod.rs | 4 +- .../mark_sweep_branded/tests/uaf.rs | 4 +- .../collectors/mark_sweep_branded/trace.rs | 112 +++++++------- .../src/collectors/mark_sweep_branded/weak.rs | 4 +- .../collectors/null_collector_branded/cell.rs | 11 +- .../null_collector_branded/ephemeron.rs | 4 +- .../collectors/null_collector_branded/gc.rs | 17 ++- .../null_collector_branded/trace.rs | 140 +++++++++++------- .../collectors/null_collector_branded/weak.rs | 9 +- 12 files changed, 187 insertions(+), 135 deletions(-) diff --git a/oscars/src/collectors/mark_sweep_branded/cell.rs b/oscars/src/collectors/mark_sweep_branded/cell.rs index ebc2fa4..50a6ebe 100644 --- a/oscars/src/collectors/mark_sweep_branded/cell.rs +++ b/oscars/src/collectors/mark_sweep_branded/cell.rs @@ -64,8 +64,11 @@ impl DerefMut for GcRefMut<'_, T> { impl Finalize for GcRefCell {} -impl Trace for GcRefCell { - fn trace(&mut self, tracer: &mut Tracer) { - self.inner.get_mut().trace(tracer); +unsafe impl Trace for GcRefCell { + unsafe fn trace(&self, tracer: &mut Tracer) { + let val = unsafe { &*self.inner.as_ptr() }; + unsafe { + val.trace(tracer); + } } } diff --git a/oscars/src/collectors/mark_sweep_branded/ephemeron.rs b/oscars/src/collectors/mark_sweep_branded/ephemeron.rs index 82e5887..bc3c4c9 100644 --- a/oscars/src/collectors/mark_sweep_branded/ephemeron.rs +++ b/oscars/src/collectors/mark_sweep_branded/ephemeron.rs @@ -54,6 +54,6 @@ impl<'id, K: Trace, V: Trace> Copy for Ephemeron<'id, K, V> {} impl<'id, K: Trace, V: Trace> Finalize for Ephemeron<'id, K, V> {} -impl<'id, K: Trace, V: Trace> Trace for Ephemeron<'id, K, V> { - fn trace(&mut self, _tracer: &mut Tracer) {} +unsafe impl<'id, K: Trace, V: Trace> Trace for Ephemeron<'id, K, V> { + unsafe fn trace(&self, _tracer: &mut Tracer) {} } diff --git a/oscars/src/collectors/mark_sweep_branded/gc.rs b/oscars/src/collectors/mark_sweep_branded/gc.rs index 2c1cf96..073e706 100644 --- a/oscars/src/collectors/mark_sweep_branded/gc.rs +++ b/oscars/src/collectors/mark_sweep_branded/gc.rs @@ -61,8 +61,8 @@ impl<'gc, T: Trace + 'gc> Deref for Gc<'gc, T> { } impl Finalize for Gc<'_, T> {} -impl Trace for Gc<'_, T> { - fn trace(&mut self, tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) { +unsafe impl Trace for Gc<'_, T> { + unsafe fn trace(&self, tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) { tracer.mark(self); } } diff --git a/oscars/src/collectors/mark_sweep_branded/tests/mod.rs b/oscars/src/collectors/mark_sweep_branded/tests/mod.rs index f766a73..cea7039 100644 --- a/oscars/src/collectors/mark_sweep_branded/tests/mod.rs +++ b/oscars/src/collectors/mark_sweep_branded/tests/mod.rs @@ -6,8 +6,8 @@ struct JsObject { value: i32, } -impl crate::collectors::mark_sweep_branded::Trace for JsObject { - fn trace(&mut self, _tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) {} +unsafe impl crate::collectors::mark_sweep_branded::Trace for JsObject { + unsafe fn trace(&self, _tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) {} } impl crate::collectors::mark_sweep_branded::Finalize for JsObject {} diff --git a/oscars/src/collectors/mark_sweep_branded/tests/uaf.rs b/oscars/src/collectors/mark_sweep_branded/tests/uaf.rs index 5eab874..921d148 100644 --- a/oscars/src/collectors/mark_sweep_branded/tests/uaf.rs +++ b/oscars/src/collectors/mark_sweep_branded/tests/uaf.rs @@ -5,8 +5,8 @@ use core::cell::Cell; struct DetectDrop<'a>(&'a Cell); -impl<'a> Trace for DetectDrop<'a> { - fn trace(&mut self, _tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) {} +unsafe impl<'a> Trace for DetectDrop<'a> { + unsafe fn trace(&self, _tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) {} } impl Finalize for DetectDrop<'_> {} diff --git a/oscars/src/collectors/mark_sweep_branded/trace.rs b/oscars/src/collectors/mark_sweep_branded/trace.rs index 214a94a..8b0118c 100644 --- a/oscars/src/collectors/mark_sweep_branded/trace.rs +++ b/oscars/src/collectors/mark_sweep_branded/trace.rs @@ -1,5 +1,7 @@ //! Trace and Finalize traits for the lifetime branded GC +#![allow(unsafe_op_in_unsafe_fn)] + use crate::{ alloc::mempool3::PoolItem, collectors::mark_sweep_branded::{gc::Gc, gc_box::GcColor}, @@ -20,9 +22,13 @@ pub use crate::collectors::common::Finalize; /// # Safety /// /// Use `Tracer::mark` for every reachable `Gc` pointer. -pub trait Trace { +pub unsafe trait Trace { /// Marks all `Gc` pointers reachable from `self`. - fn trace(&mut self, tracer: &mut Tracer); + /// + /// # Safety + /// + /// See `boa_gc::Trace` for safety contract details. + unsafe fn trace(&self, tracer: &mut Tracer); } pub(crate) type TraceFn = unsafe fn(core::ptr::NonNull, &mut Tracer<'_>); @@ -108,9 +114,9 @@ impl<'a> Tracer<'a> { } } -impl Trace for &T { +unsafe impl Trace for &T { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } // primitive + std-lib Trace impls @@ -118,9 +124,9 @@ impl Trace for &T { macro_rules! empty_trace { ($($T:ty),* $(,)?) => { $( - impl Trace for $T { + unsafe impl Trace for $T { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } )* }; @@ -159,30 +165,30 @@ empty_trace![ core::num::NonZeroU128, ]; -impl Trace for [T; N] { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.iter_mut() { +unsafe impl Trace for [T; N] { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { v.trace(tracer); } } } -impl Trace for Box { - fn trace(&mut self, tracer: &mut Tracer) { +unsafe impl Trace for Box { + unsafe fn trace(&self, tracer: &mut Tracer) { (**self).trace(tracer); } } -impl Trace for Option { - fn trace(&mut self, tracer: &mut Tracer) { +unsafe impl Trace for Option { + unsafe fn trace(&self, tracer: &mut Tracer) { if let Some(v) = self { v.trace(tracer); } } } -impl Trace for Result { - fn trace(&mut self, tracer: &mut Tracer) { +unsafe impl Trace for Result { + unsafe fn trace(&self, tracer: &mut Tracer) { match self { Ok(v) => v.trace(tracer), Err(e) => e.trace(tracer), @@ -190,91 +196,91 @@ impl Trace for Result { } } -impl Trace for Vec { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.iter_mut() { +unsafe impl Trace for Vec { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { v.trace(tracer); } } } -impl Trace for VecDeque { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.iter_mut() { +unsafe impl Trace for VecDeque { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { v.trace(tracer); } } } -impl Trace for LinkedList { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.iter_mut() { +unsafe impl Trace for LinkedList { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { v.trace(tracer); } } } -impl Trace for PhantomData { +unsafe impl Trace for PhantomData { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } // Cell> requires T: Copy to safely read the value via Cell::get(). // For non-Copy types, use GcRefCell instead. -impl Trace for Cell> { - fn trace(&mut self, tracer: &mut Tracer) { - if let Some(mut v) = self.get() { - v.trace(tracer); - } +unsafe impl Trace for Cell { + unsafe fn trace(&self, tracer: &mut Tracer) { + let v = self.take(); + v.trace(tracer); + self.set(v); } } -impl Trace for OnceCell { - fn trace(&mut self, tracer: &mut Tracer) { - if let Some(v) = self.get_mut() { +unsafe impl Trace for OnceCell { + unsafe fn trace(&self, tracer: &mut Tracer) { + if let Some(v) = self.get() { v.trace(tracer); } } } -impl Trace for Cow<'static, T> +unsafe impl Trace for Cow<'static, T> where T::Owned: Trace, { - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { if let Cow::Owned(v) = self { v.trace(tracer); } } } -impl Trace for (A,) { +unsafe impl Trace for (A,) { #[inline] - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { self.0.trace(tracer); } } -impl Trace for (A, B) { +unsafe impl Trace for (A, B) { #[inline] - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { self.0.trace(tracer); self.1.trace(tracer); } } -impl Trace for (A, B, C) { +unsafe impl Trace for (A, B, C) { #[inline] - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { self.0.trace(tracer); self.1.trace(tracer); self.2.trace(tracer); } } -impl Trace for (A, B, C, D) { +unsafe impl Trace for (A, B, C, D) { #[inline] - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { self.0.trace(tracer); self.1.trace(tracer); self.2.trace(tracer); @@ -285,27 +291,27 @@ impl Trace for (A, B, C, D) { // Rc and Arc do not contain Gc pointers (they use reference counting, not GC). // If you need to store Gc pointers inside Rc/Arc, wrap them in a GC-allocated // struct instead. -impl Trace for rust_alloc::rc::Rc { +unsafe impl Trace for rust_alloc::rc::Rc { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } -impl Trace for rust_alloc::sync::Arc { +unsafe impl Trace for rust_alloc::sync::Arc { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } -impl Trace for BTreeMap { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.values_mut() { +unsafe impl Trace for BTreeMap { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.values() { v.trace(tracer); } } } -impl Trace for BTreeSet { +unsafe impl Trace for BTreeSet { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) { + unsafe fn trace(&self, _tracer: &mut Tracer) { // BTreeSet keys are immutable and cannot contain Gc pointers // that need tracing (Gc requires &mut self to trace). } diff --git a/oscars/src/collectors/mark_sweep_branded/weak.rs b/oscars/src/collectors/mark_sweep_branded/weak.rs index 63e4a2c..1f9c62e 100644 --- a/oscars/src/collectors/mark_sweep_branded/weak.rs +++ b/oscars/src/collectors/mark_sweep_branded/weak.rs @@ -56,7 +56,7 @@ impl<'id, T: Trace + ?Sized> Clone for WeakGc<'id, T> { impl<'id, T: Trace + ?Sized> Copy for WeakGc<'id, T> {} impl<'id, T: Trace> Finalize for WeakGc<'id, T> {} -impl<'id, T: Trace> Trace for WeakGc<'id, T> { +unsafe impl<'id, T: Trace> Trace for WeakGc<'id, T> { // Weak references do not mark their target, upgrade() returning None after collection is the intended behaviour. - fn trace(&mut self, _tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) {} + unsafe fn trace(&self, _tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) {} } diff --git a/oscars/src/collectors/null_collector_branded/cell.rs b/oscars/src/collectors/null_collector_branded/cell.rs index 3490aa9..cdedb43 100644 --- a/oscars/src/collectors/null_collector_branded/cell.rs +++ b/oscars/src/collectors/null_collector_branded/cell.rs @@ -61,8 +61,13 @@ impl DerefMut for GcRefMut<'_, T> { impl Finalize for GcRefCell {} -impl Trace for GcRefCell { - fn trace(&mut self, tracer: &mut Tracer) { - self.inner.get_mut().trace(tracer); +unsafe impl Trace for GcRefCell { + unsafe fn trace(&self, tracer: &mut Tracer) { + // SAFETY: We only access the inner value for tracing and do not mutate it. + // The null collector's trace is a no-op, so this is safe. + let val = unsafe { &*self.inner.as_ptr() }; + unsafe { + val.trace(tracer); + } } } diff --git a/oscars/src/collectors/null_collector_branded/ephemeron.rs b/oscars/src/collectors/null_collector_branded/ephemeron.rs index b87591c..82bf7d1 100644 --- a/oscars/src/collectors/null_collector_branded/ephemeron.rs +++ b/oscars/src/collectors/null_collector_branded/ephemeron.rs @@ -48,6 +48,6 @@ impl<'id, K: Trace, V: Trace> Copy for Ephemeron<'id, K, V> {} impl<'id, K: Trace, V: Trace> Finalize for Ephemeron<'id, K, V> {} -impl<'id, K: Trace, V: Trace> Trace for Ephemeron<'id, K, V> { - fn trace(&mut self, _tracer: &mut Tracer) {} +unsafe impl<'id, K: Trace, V: Trace> Trace for Ephemeron<'id, K, V> { + unsafe fn trace(&self, _tracer: &mut Tracer) {} } diff --git a/oscars/src/collectors/null_collector_branded/gc.rs b/oscars/src/collectors/null_collector_branded/gc.rs index 63bd636..37d5cd4 100644 --- a/oscars/src/collectors/null_collector_branded/gc.rs +++ b/oscars/src/collectors/null_collector_branded/gc.rs @@ -35,31 +35,36 @@ impl<'gc, T: Trace + ?Sized + 'gc> Gc<'gc, T> { } } -impl<'gc, T: Trace + 'gc> Gc<'gc, T> { +impl<'gc, T: Trace + ?Sized + 'gc> Gc<'gc, T> { /// Returns a shared reference to the value. #[inline] pub fn get(&self) -> &T { // SAFETY: `ptr` is non-null and valid for `'gc` by construction. unsafe { &(*self.ptr.as_ptr().as_ptr()).0.value } } + + #[inline] + pub fn as_ptr(&self) -> *const T { + self.get() as *const T + } } -impl<'gc, T: Trace + fmt::Display + 'gc> fmt::Display for Gc<'gc, T> { +impl<'gc, T: Trace + ?Sized + fmt::Display + 'gc> fmt::Display for Gc<'gc, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self.get(), f) } } -impl<'gc, T: Trace + 'gc> Deref for Gc<'gc, T> { +impl<'gc, T: Trace + ?Sized + 'gc> Deref for Gc<'gc, T> { type Target = T; fn deref(&self) -> &T { self.get() } } -impl Finalize for Gc<'_, T> {} -impl Trace for Gc<'_, T> { - fn trace(&mut self, tracer: &mut crate::collectors::null_collector_branded::trace::Tracer) { +impl Finalize for Gc<'_, T> {} +unsafe impl Trace for Gc<'_, T> { + unsafe fn trace(&self, tracer: &mut crate::collectors::null_collector_branded::trace::Tracer) { tracer.mark(self); } } diff --git a/oscars/src/collectors/null_collector_branded/trace.rs b/oscars/src/collectors/null_collector_branded/trace.rs index 3dfa628..be4b7d9 100644 --- a/oscars/src/collectors/null_collector_branded/trace.rs +++ b/oscars/src/collectors/null_collector_branded/trace.rs @@ -1,4 +1,6 @@ //! Trace and Finalize traits for the lifetime branded GC + +#![allow(unsafe_op_in_unsafe_fn)] pub use crate::collectors::common::Finalize; use core::cell::{Cell, OnceCell}; @@ -12,9 +14,17 @@ use rust_alloc::vec::Vec; /// Trait for tracing garbage collected values. /// /// In the null collector, tracing is a no-op. -pub trait Trace { +/// +/// # Safety +/// +/// See `boa_gc::Trace` for safety contract details. +pub unsafe trait Trace { /// Marks all Gc pointers reachable from `self`. - fn trace(&mut self, tracer: &mut Tracer); + /// + /// # Safety + /// + /// See `boa_gc::Trace` for safety contract details. + unsafe fn trace(&self, tracer: &mut Tracer); } /// Dummy tracer for the null collector @@ -24,24 +34,24 @@ pub struct Tracer<'a> { impl<'a> Tracer<'a> { #[inline] - pub fn mark( + pub fn mark( &mut self, _gc: &crate::collectors::null_collector_branded::gc::Gc<'_, T>, ) { } } -impl Trace for &T { +unsafe impl Trace for &T { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } macro_rules! empty_trace { ($($T:ty),* $(,)?) => { $( - impl Trace for $T { + unsafe impl Trace for $T { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } )* }; @@ -66,6 +76,8 @@ empty_trace![ f64, char, String, + core::any::TypeId, + rustc_hash::FxBuildHasher, core::num::NonZeroIsize, core::num::NonZeroUsize, core::num::NonZeroI8, @@ -80,30 +92,50 @@ empty_trace![ core::num::NonZeroU128, ]; -impl Trace for [T; N] { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.iter_mut() { +unsafe impl Trace for [T; N] { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { + v.trace(tracer); + } + } +} + +unsafe impl Trace for [T] { + #[inline] + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { v.trace(tracer); } } } -impl Trace for Box { - fn trace(&mut self, tracer: &mut Tracer) { +unsafe impl Trace for Box { + #[inline] + unsafe fn trace(&self, tracer: &mut Tracer) { (**self).trace(tracer); } } -impl Trace for Option { - fn trace(&mut self, tracer: &mut Tracer) { +#[cfg(feature = "thin-vec")] +unsafe impl Trace for thin_vec::ThinVec { + #[inline] + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { + v.trace(tracer); + } + } +} + +unsafe impl Trace for Option { + unsafe fn trace(&self, tracer: &mut Tracer) { if let Some(v) = self { v.trace(tracer); } } } -impl Trace for Result { - fn trace(&mut self, tracer: &mut Tracer) { +unsafe impl Trace for Result { + unsafe fn trace(&self, tracer: &mut Tracer) { match self { Ok(v) => v.trace(tracer), Err(e) => e.trace(tracer), @@ -111,89 +143,89 @@ impl Trace for Result { } } -impl Trace for Vec { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.iter_mut() { +unsafe impl Trace for Vec { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { v.trace(tracer); } } } -impl Trace for VecDeque { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.iter_mut() { +unsafe impl Trace for VecDeque { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { v.trace(tracer); } } } -impl Trace for LinkedList { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.iter_mut() { +unsafe impl Trace for LinkedList { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.iter() { v.trace(tracer); } } } -impl Trace for PhantomData { +unsafe impl Trace for PhantomData { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } -impl Trace for Cell> { - fn trace(&mut self, tracer: &mut Tracer) { - if let Some(mut v) = self.get() { - v.trace(tracer); - } +unsafe impl Trace for Cell { + unsafe fn trace(&self, tracer: &mut Tracer) { + let v = self.take(); + v.trace(tracer); + self.set(v); } } -impl Trace for OnceCell { - fn trace(&mut self, tracer: &mut Tracer) { - if let Some(v) = self.get_mut() { +unsafe impl Trace for OnceCell { + unsafe fn trace(&self, tracer: &mut Tracer) { + if let Some(v) = self.get() { v.trace(tracer); } } } -impl Trace for Cow<'static, T> +unsafe impl Trace for Cow<'static, T> where T::Owned: Trace, { - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { if let Cow::Owned(v) = self { v.trace(tracer); } } } -impl Trace for (A,) { +unsafe impl Trace for (A,) { #[inline] - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { self.0.trace(tracer); } } -impl Trace for (A, B) { +unsafe impl Trace for (A, B) { #[inline] - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { self.0.trace(tracer); self.1.trace(tracer); } } -impl Trace for (A, B, C) { +unsafe impl Trace for (A, B, C) { #[inline] - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { self.0.trace(tracer); self.1.trace(tracer); self.2.trace(tracer); } } -impl Trace for (A, B, C, D) { +unsafe impl Trace for (A, B, C, D) { #[inline] - fn trace(&mut self, tracer: &mut Tracer) { + unsafe fn trace(&self, tracer: &mut Tracer) { self.0.trace(tracer); self.1.trace(tracer); self.2.trace(tracer); @@ -201,25 +233,25 @@ impl Trace for (A, B, C, D) { } } -impl Trace for rust_alloc::rc::Rc { +unsafe impl Trace for rust_alloc::rc::Rc { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } -impl Trace for rust_alloc::sync::Arc { +unsafe impl Trace for rust_alloc::sync::Arc { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } -impl Trace for BTreeMap { - fn trace(&mut self, tracer: &mut Tracer) { - for v in self.values_mut() { +unsafe impl Trace for BTreeMap { + unsafe fn trace(&self, tracer: &mut Tracer) { + for v in self.values() { v.trace(tracer); } } } -impl Trace for BTreeSet { +unsafe impl Trace for BTreeSet { #[inline] - fn trace(&mut self, _tracer: &mut Tracer) {} + unsafe fn trace(&self, _tracer: &mut Tracer) {} } diff --git a/oscars/src/collectors/null_collector_branded/weak.rs b/oscars/src/collectors/null_collector_branded/weak.rs index b9a8152..db5e56e 100644 --- a/oscars/src/collectors/null_collector_branded/weak.rs +++ b/oscars/src/collectors/null_collector_branded/weak.rs @@ -14,7 +14,7 @@ pub struct WeakGc<'id, T: Trace + ?Sized> { pub(crate) _marker: PhantomData<*mut &'id ()>, } -impl<'id, T: Trace> WeakGc<'id, T> { +impl<'id, T: Trace + ?Sized> WeakGc<'id, T> { pub(crate) fn with_pointer(ptr: PoolPointer<'static, GcBox>) -> Self { Self { ptr, @@ -40,7 +40,8 @@ impl<'id, T: Trace + ?Sized> Clone for WeakGc<'id, T> { impl<'id, T: Trace + ?Sized> Copy for WeakGc<'id, T> {} -impl<'id, T: Trace> Finalize for WeakGc<'id, T> {} -impl<'id, T: Trace> Trace for WeakGc<'id, T> { - fn trace(&mut self, _tracer: &mut crate::collectors::null_collector_branded::trace::Tracer) {} +impl<'id, T: Trace + ?Sized> Finalize for WeakGc<'id, T> {} +unsafe impl<'id, T: Trace + ?Sized> Trace for WeakGc<'id, T> { + unsafe fn trace(&self, _tracer: &mut crate::collectors::null_collector_branded::trace::Tracer) { + } }