Skip to content

Commit 1b3c1e6

Browse files
committed
Add epsilon::gc_str for &str -> GcString
Symmetry with epsilon::gc_array and epsilon::gc
1 parent 6cd57b9 commit 1b3c1e6

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

src/epsilon.rs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,7 @@
1111
mod layout;
1212
mod alloc;
1313

14-
use crate::{
15-
CollectorId, internals::ConstCollectorId,
16-
GcContext, GcSafe, GcSimpleAlloc, GcSystem,
17-
GcVisitor, NullTrace, Trace, TraceImmutable,
18-
TrustedDrop
19-
};
14+
use crate::{CollectorId, GcContext, GcSafe, GcSimpleAlloc, GcSystem, GcVisitor, NullTrace, Trace, TraceImmutable, TrustedDrop, internals::ConstCollectorId};
2015
use std::ptr::NonNull;
2116
use std::alloc::Layout;
2217
use std::rc::Rc;
@@ -48,7 +43,7 @@ pub const fn gc<'gc, T: GcSafe<'gc, EpsilonCollectorId> + 'gc>(ptr: &'gc T) -> G
4843
/// Coerce a slice into a `GcArray`.
4944
///
5045
/// This is only supported on the epsilon collector.
51-
/// Because the epsilon collector never allocates,
46+
/// Because the epsilon collector never collects,
5247
/// it doesn't need to make a distinction between `GcArray<T>` and `&[T]`.
5348
///
5449
/// See also: [gc] for converting `&T` -> `Gc<T>`
@@ -64,6 +59,27 @@ pub const fn gc_array<'gc, T: GcSafe<'gc, EpsilonCollectorId> + 'gc>(slice: &'gc
6459
unsafe { std::mem::transmute::<&'gc [T], crate::GcArray<'gc, T, EpsilonCollectorId>>(slice) }
6560
}
6661

62+
/// Coerce a `&str` into a `GcString`
63+
///
64+
/// This is only supported on the epsilon collector,
65+
/// because the epsilon collector never collects.
66+
///
67+
/// See also [gc_array] for converting `&[T]` -> `GcArray<T>`
68+
#[inline]
69+
pub const fn gc_str<'gc>(s: &'gc str) -> GcString<'gc> {
70+
/*
71+
* SAFETY: Epsilon uses the 'fat' representation for GcArrays.
72+
* This means that repr(GcArray) == repr(&[T])
73+
*
74+
* Because we already know the string is UTF8 encoded,
75+
* we can take advantage of the fact that repr(str) == repr(&[u8])
76+
* and repr(GcArray) == repr(GcString).
77+
* Instead of going `str -> &[T] -> GcArray -> GcString`
78+
* we can just go directly from `str -> GcString`
79+
*/
80+
unsafe { std::mem::transmute::<&'gc str, crate::array::GcString<'gc, EpsilonCollectorId>>(s) }
81+
}
82+
6783
/// Allocate a [(fake) Gc](Gc) that points to the specified
6884
/// value and leak it.
6985
///
@@ -78,7 +94,7 @@ pub fn leaked<'gc, T: GcSafe<'gc, EpsilonCollectorId> + 'static>(value: T) -> Gc
7894
///
7995
/// **WARNING**: This never actually collects any garbage
8096
pub type Gc<'gc, T> = crate::Gc<'gc, T, EpsilonCollectorId>;
81-
/// A [garbage collected array](`crate::vec::GcArray`)
97+
/// A [garbage collected array](`crate::array::GcArray`)
8298
/// that uses the [epsilon collector](EpsilonSystem)
8399
///
84100
/// **WARNING**: This never actually collects any garbage.
@@ -88,6 +104,11 @@ pub type GcArray<'gc, T> = crate::array::GcArray<'gc, T, EpsilonCollectorId>;
88104
///
89105
/// **WARNING**: This never actually collects any garbage.
90106
pub type GcVec<'gc, T> = crate::vec::GcVec<'gc, T, EpsilonContext>;
107+
/// A [garbage collected string](`crate::array::GcString`)
108+
/// that uses the epsilon collector.
109+
///
110+
/// **WARNING**: This never actually collects any garbage
111+
pub type GcString<'gc> = crate::array::GcString<'gc, EpsilonCollectorId>;
91112

92113
/// A never-collecting garbage collector context.
93114
///

0 commit comments

Comments
 (0)