Skip to content

Commit 6f00161

Browse files
committed
Remove GcRebrand + GcErase for GcVec
They are unsafe, because GcVec has an explicit reference to the owning context, which cant be meaningfully erased. Add GcVec::extend_from_slice
1 parent 010d592 commit 6f00161

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

src/vec.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ pub struct GcVec<'gc, T: GcSafe, Ctx: GcSimpleAlloc> {
7373
pub raw: GcRawVec<'gc, T, Ctx::Id>
7474
}
7575
impl<'gc, T: GcSafe, Ctx: GcSimpleAlloc> GcVec<'gc, T, Ctx> {
76+
/// Convert this vector into its underlying [GcRawVec]
77+
#[inline]
78+
pub fn into_raw(self) -> GcRawVec<'gc, T, Ctx::Id> {
79+
self.raw
80+
}
7681
/// Reserve enough capacity for the specified number of additional elements.
7782
#[inline]
7883
pub fn reserve(&mut self, amount: usize) {
@@ -81,6 +86,17 @@ impl<'gc, T: GcSafe, Ctx: GcSimpleAlloc> GcVec<'gc, T, Ctx> {
8186
self.grow(amount);
8287
}
8388
}
89+
/// Extend the vector with elements copied from the specified slice
90+
#[inline]
91+
pub fn extend_from_slice(&mut self, src: &[T])
92+
where T: Copy {
93+
self.reserve(src.len());
94+
// TODO: Write barriers?
95+
unsafe {
96+
(self.raw.as_repr_mut().ptr() as *mut T).add(self.len())
97+
.copy_from_nonoverlapping(src.as_ptr(), src.len())
98+
}
99+
}
84100
/// Push the specified value onto the vector
85101
#[inline]
86102
pub fn push(&mut self, val: T) {
@@ -116,17 +132,17 @@ unsafe_gc_impl!(
116132
params => ['gc, T: GcSafe, Ctx: GcSimpleAlloc],
117133
bounds => {
118134
TraceImmutable => never,
119-
GcRebrand => { where T: GcRebrand<'new_gc, Ctx::Id> },
120-
GcErase => { where T: GcErase<'min, Ctx::Id> },
135+
Trace => { where T: GcSafe },
136+
GcRebrand => never,
137+
GcErase => never,
121138
},
122-
branded_type => <T as GcRebrand<'new_gc, Ctx::Id>>::Branded,
123-
erased_type => <T as GcErase<'min, Ctx::Id>>::Erased,
124139
null_trace => never,
125140
NEEDS_TRACE => true,
126141
NEEDS_DROP => T::NEEDS_DROP /* if our inner type needs a drop */,
127142
trace_mut => |self, visitor| {
128143
unsafe { visitor.visit_vec::<T, _>(self.raw.as_repr_mut()) }
129144
},
145+
collector_id => Ctx::Id
130146
);
131147
impl<'gc, T: GcSafe, Ctx: GcSimpleAlloc> Deref for GcVec<'gc, T, Ctx> {
132148
type Target = GcRawVec<'gc, T, Ctx::Id>;
@@ -308,11 +324,17 @@ unsafe_gc_impl!(
308324
collector_id => Id,
309325
bounds => {
310326
TraceImmutable => never,
311-
GcRebrand => { where T: GcRebrand<'new_gc, Id> },
312-
GcErase => { where T: GcErase<'min, Id> },
327+
GcRebrand => {
328+
where T: GcSafe + GcRebrand<'new_gc, Id>,
329+
<T as GcRebrand<'new_gc, Id>>::Branded: GcSafe
330+
},
331+
GcErase => {
332+
where T: GcSafe + GcErase<'min, Id>,
333+
<T as GcErase<'min, Id>>::Erased: GcSafe
334+
},
313335
},
314-
branded_type => <T as GcRebrand<'new_gc, Id>>::Branded,
315-
erased_type => <T as GcErase<'min, Id>>::Erased,
336+
branded_type => GcRawVec<'new_gc, <T as GcRebrand<'new_gc, Id>>::Branded, Id>,
337+
erased_type => GcRawVec<'min, <T as GcErase<'min, Id>>::Erased, Id>,
316338
null_trace => never,
317339
NEEDS_TRACE => true,
318340
NEEDS_DROP => T::NEEDS_DROP /* if our inner type needs a drop */,

0 commit comments

Comments
 (0)