Replace type_name with TypeId using typeid crate - #100
Conversation
| actual_type_name == core::any::type_name::<U>() | ||
| pub fn is<U: Trace + ?Sized>(&self) -> bool { | ||
| let actual_type_id = unsafe { (*self.ptr.as_ptr().as_ptr()).0.type_id }; | ||
| actual_type_id == core::any::TypeId::of::<U::StaticId>() |
There was a problem hiding this comment.
Huh, why can't we use TypeId::of::<U>() here?
There was a problem hiding this comment.
Replced StaticId with dtonlay's typeid crate, everything compiles, certainly an improvement on the earlier approach.
It gives us a TypeId equivalent that works without requiring 'static, so U no longer needs the StaticId proxy at all
788e873 to
f579642
Compare
f579642 to
40363d4
Compare
There was a problem hiding this comment.
Pull request overview
This PR replaces string-based runtime type checks (type_name) with TypeId-based checks (via the typeid crate) in the branded collectors, aiming to make Gc::is/downcasting safer and more compatible with #![no_std].
Changes:
- Store a runtime type identifier in
GcBoxand switchGc::isto compareTypeIds instead oftype_namestrings. - Update branded
Traceblanket impls and add/adjust safety documentation in the null collector’s global mutation context. - Introduce the
typeiddependency and update lockfile accordingly.
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| oscars/src/collectors/null_collector_branded/weak.rs | Adds comment about static proxy mapping for weak pointers. |
| oscars/src/collectors/null_collector_branded/trace.rs | Updates several Trace blanket impl bounds and comments; adds Trace for str. |
| oscars/src/collectors/null_collector_branded/mutation_ctx.rs | Expands safety documentation around MutationContext::global() TLS usage. |
| oscars/src/collectors/null_collector_branded/gc.rs | Switches Gc::is from string comparison to typeid::of. |
| oscars/src/collectors/null_collector_branded/gc_box.rs | Stores TypeId in GcBox and updates constructor bounds. |
| oscars/src/collectors/null_collector_branded/ephemeron.rs | Adds comment describing intended static proxy mapping. |
| oscars/src/collectors/null_collector_branded/cell.rs | Uses Clone trait for GcRef; adds comment about static mapping. |
| oscars/src/collectors/mark_sweep_branded/weak.rs | Minor simplification in is_upgradable; adds comment about static proxy mapping. |
| oscars/src/collectors/mark_sweep_branded/trace.rs | Updates several Trace blanket impl bounds/comments; adds Trace for str. |
| oscars/src/collectors/mark_sweep_branded/tests/uaf.rs | Adds comment describing intended static proxy mapping for test type. |
| oscars/src/collectors/mark_sweep_branded/tests/mod.rs | Adds comment on Trace impl for JsObject. |
| oscars/src/collectors/mark_sweep_branded/mod.rs | Adds Default impl for Collector. |
| oscars/src/collectors/mark_sweep_branded/gc.rs | Switches Gc::is to typeid::of; updates Trace impl signature. |
| oscars/src/collectors/mark_sweep_branded/gc_box.rs | Stores TypeId in GcBox and updates constructor bounds. |
| oscars/src/collectors/mark_sweep_branded/ephemeron.rs | Adds comment describing intended static proxy mapping. |
| oscars/src/collectors/mark_sweep_branded/cell.rs | Adds comment about branding/static mapping for GcRefCell. |
| oscars/Cargo.toml | Adds the typeid dependency. |
| Cargo.lock | Records the new typeid package in the lockfile. |
Suppressed comments (3)
oscars/src/collectors/mark_sweep_branded/trace.rs:272
PhantomData<T>is a marker and has no runtime data to trace, so requiringT: 'statichere is an unnecessary restriction. It also conflicts with the unbranded collector’sTrace for PhantomData<T>blanket impl (collectors/mark_sweep/trace.rs:398-401). Unless there is a concrete reason to restrict this, consider restoring the unrestricted impl.
unsafe impl Trace for core::any::TypeId {
#[inline]
unsafe fn trace(&self, _tracer: &mut Tracer) {}
}
oscars/src/collectors/null_collector_branded/trace.rs:194
PhantomData<T>is a marker and has no runtime data to trace, so requiringT: 'statichere is an unnecessary restriction (and inconsistent with the unbranded collector’s blanket impl incollectors/mark_sweep/trace.rs:398-401). Unless there is a concrete reason to restrict this, consider restoring the unrestricted impl.
unsafe impl<T: Trace + Default> Trace for Cell<T> {
unsafe fn trace(&self, tracer: &mut Tracer) {
let v = self.take();
v.trace(tracer);
oscars/src/collectors/mark_sweep_branded/trace.rs:426
- This comment says “Gc requires &mut self to trace”, but
Trace::tracetakes&selfandGcitself is traced via a shared reference. If the intent is to forbid branded GC pointers inBTreeSetby using theT: 'staticbound, the comment should state that instead to avoid spreading incorrect guidance.
use crate::collectors::mark_sweep_branded::{Trace, Tracer};
use icu_locale_core::{LanguageIdentifier, Locale};
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
typeid crate
Related to #98 (comment)
Replaced the string based
type_namemethod with the standardcore::any::TypeId. This makes downcasting safer and fully supports#![no_std]environments without cross thread memory bugs.Because
TypeIdrequires a'staticlifetime (and our GC pointers use a temporary'gclifetime), added aStaticIdproxy type to safely bridge the gaptype StaticIdto theTracetrait. Every GC type now links to a safe'staticversion of itself (for example,Gc<'gc, T>links toGc<'static, T::StaticId>)GcBoxusesTypeIdinstead of strings. WhenGc::is<U>()is called, it safely checks the type usingTypeId::of::<U::StaticId>()Vecas the static proxy for slices ([T]) andStringas the proxy forstrthread_local!requirement in the null collector to prevent cross thread uaf bugs and brings back full#![no_std]support.