зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1568446) for causing multiple failures
Backed out changeset 6e7267a5b743 (bug 1568446) Backed out changeset 4c30e18adac2 (bug 1568446)
This commit is contained in:
Родитель
98ddcb49bf
Коммит
dfed4107fc
|
@ -34,7 +34,7 @@ use nodrop::NoDrop;
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use stable_deref_trait::{CloneStableDeref, StableDeref};
|
use stable_deref_trait::{CloneStableDeref, StableDeref};
|
||||||
use std::alloc::{self, Layout};
|
use std::alloc::Layout;
|
||||||
use std::borrow;
|
use std::borrow;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
@ -52,6 +52,25 @@ use std::sync::atomic;
|
||||||
use std::sync::atomic::Ordering::{Acquire, Relaxed, Release};
|
use std::sync::atomic::Ordering::{Acquire, Relaxed, Release};
|
||||||
use std::{isize, usize};
|
use std::{isize, usize};
|
||||||
|
|
||||||
|
// Private macro to get the offset of a struct field in bytes from the address of the struct.
|
||||||
|
macro_rules! offset_of {
|
||||||
|
($container:path, $field:ident) => {{
|
||||||
|
// Make sure the field actually exists. This line ensures that a compile-time error is
|
||||||
|
// generated if $field is accessed through a Deref impl.
|
||||||
|
let $container { $field: _, .. };
|
||||||
|
|
||||||
|
// Create an (invalid) instance of the container and calculate the offset to its
|
||||||
|
// field. Using a null pointer might be UB if `&(*(0 as *const T)).field` is interpreted to
|
||||||
|
// be nullptr deref.
|
||||||
|
let invalid: $container = ::std::mem::uninitialized();
|
||||||
|
let offset = &invalid.$field as *const _ as usize - &invalid as *const _ as usize;
|
||||||
|
|
||||||
|
// Do not run destructors on the made up invalid instance.
|
||||||
|
::std::mem::forget(invalid);
|
||||||
|
offset as isize
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
/// A soft limit on the amount of references that may be made to an `Arc`.
|
/// A soft limit on the amount of references that may be made to an `Arc`.
|
||||||
///
|
///
|
||||||
/// Going above this limit will abort your program (although not
|
/// Going above this limit will abort your program (although not
|
||||||
|
@ -115,23 +134,6 @@ impl<T> UniqueArc<T> {
|
||||||
UniqueArc(Arc::new(data))
|
UniqueArc(Arc::new(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct an uninitialized arc
|
|
||||||
#[inline]
|
|
||||||
pub fn new_uninit() -> UniqueArc<mem::MaybeUninit<T>> {
|
|
||||||
unsafe {
|
|
||||||
let layout = Layout::new::<ArcInner<mem::MaybeUninit<T>>>();
|
|
||||||
let ptr = alloc::alloc(layout);
|
|
||||||
let mut p = ptr::NonNull::new(ptr)
|
|
||||||
.unwrap_or_else(|| alloc::handle_alloc_error(layout))
|
|
||||||
.cast::<ArcInner<mem::MaybeUninit<T>>>();
|
|
||||||
ptr::write(&mut p.as_mut().count, atomic::AtomicUsize::new(1));
|
|
||||||
UniqueArc(Arc {
|
|
||||||
p,
|
|
||||||
phantom: PhantomData,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Convert to a shareable Arc<T> once we're done mutating it
|
/// Convert to a shareable Arc<T> once we're done mutating it
|
||||||
pub fn shareable(self) -> Arc<T> {
|
pub fn shareable(self) -> Arc<T> {
|
||||||
|
@ -139,17 +141,6 @@ impl<T> UniqueArc<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> UniqueArc<mem::MaybeUninit<T>> {
|
|
||||||
/// Convert to an initialized Arc.
|
|
||||||
#[inline]
|
|
||||||
pub unsafe fn assume_init(this: Self) -> UniqueArc<T> {
|
|
||||||
UniqueArc(Arc {
|
|
||||||
p: this.0.p.cast(),
|
|
||||||
phantom: PhantomData,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Deref for UniqueArc<T> {
|
impl<T> Deref for UniqueArc<T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
|
@ -177,14 +168,6 @@ struct ArcInner<T: ?Sized> {
|
||||||
unsafe impl<T: ?Sized + Sync + Send> Send for ArcInner<T> {}
|
unsafe impl<T: ?Sized + Sync + Send> Send for ArcInner<T> {}
|
||||||
unsafe impl<T: ?Sized + Sync + Send> Sync for ArcInner<T> {}
|
unsafe impl<T: ?Sized + Sync + Send> Sync for ArcInner<T> {}
|
||||||
|
|
||||||
/// Computes the offset of the data field within ArcInner.
|
|
||||||
fn data_offset<T>() -> usize {
|
|
||||||
let size = size_of::<ArcInner<()>>();
|
|
||||||
let align = align_of::<T>();
|
|
||||||
// https://github.com/rust-lang/rust/blob/1.36.0/src/libcore/alloc.rs#L187-L207
|
|
||||||
size.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Arc<T> {
|
impl<T> Arc<T> {
|
||||||
/// Construct an `Arc<T>`
|
/// Construct an `Arc<T>`
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -240,7 +223,7 @@ impl<T> Arc<T> {
|
||||||
unsafe fn from_raw(ptr: *const T) -> Self {
|
unsafe fn from_raw(ptr: *const T) -> Self {
|
||||||
// To find the corresponding pointer to the `ArcInner` we need
|
// To find the corresponding pointer to the `ArcInner` we need
|
||||||
// to subtract the offset of the `data` field from the pointer.
|
// to subtract the offset of the `data` field from the pointer.
|
||||||
let ptr = (ptr as *const u8).sub(data_offset::<T>());
|
let ptr = (ptr as *const u8).offset(-offset_of!(ArcInner<T>, data));
|
||||||
Arc {
|
Arc {
|
||||||
p: ptr::NonNull::new_unchecked(ptr as *mut ArcInner<T>),
|
p: ptr::NonNull::new_unchecked(ptr as *mut ArcInner<T>),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
|
|
@ -29,15 +29,15 @@ impl<'a> AutoProfilerLabel<'a> {
|
||||||
/// stack.
|
/// stack.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn new(
|
pub unsafe fn new(
|
||||||
label: &mut std::mem::MaybeUninit<structs::AutoProfilerLabel>,
|
label: &mut structs::AutoProfilerLabel,
|
||||||
label_type: ProfilerLabel,
|
label_type: ProfilerLabel,
|
||||||
) -> AutoProfilerLabel {
|
) -> AutoProfilerLabel {
|
||||||
let category_pair = match label_type {
|
let category_pair = match label_type {
|
||||||
ProfilerLabel::Style => structs::JS::ProfilingCategoryPair_LAYOUT_StyleComputation,
|
ProfilerLabel::Style => structs::JS::ProfilingCategoryPair_LAYOUT_StyleComputation,
|
||||||
ProfilerLabel::Parse => structs::JS::ProfilingCategoryPair_LAYOUT_CSSParsing,
|
ProfilerLabel::Parse => structs::JS::ProfilingCategoryPair_LAYOUT_CSSParsing,
|
||||||
};
|
};
|
||||||
structs::Gecko_Construct_AutoProfilerLabel(label.as_mut_ptr(), category_pair);
|
structs::Gecko_Construct_AutoProfilerLabel(label, category_pair);
|
||||||
AutoProfilerLabel(&mut *label.as_mut_ptr())
|
AutoProfilerLabel(label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,8 +202,7 @@ impl WeakAtom {
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Output,
|
F: FnOnce(&str) -> Output,
|
||||||
{
|
{
|
||||||
let mut buffer = mem::MaybeUninit::<[u8; 64]>::uninit();
|
let mut buffer: [u8; 64] = unsafe { mem::uninitialized() };
|
||||||
let buffer = unsafe { &mut *buffer.as_mut_ptr() };
|
|
||||||
|
|
||||||
// The total string length in utf16 is going to be less than or equal
|
// The total string length in utf16 is going to be less than or equal
|
||||||
// the slice length (each utf16 character is going to take at least one
|
// the slice length (each utf16 character is going to take at least one
|
||||||
|
@ -272,8 +271,7 @@ impl WeakAtom {
|
||||||
}
|
}
|
||||||
|
|
||||||
let slice = self.as_slice();
|
let slice = self.as_slice();
|
||||||
let mut buffer = mem::MaybeUninit::<[u16; 64]>::uninit();
|
let mut buffer: [u16; 64] = unsafe { mem::uninitialized() };
|
||||||
let buffer = unsafe { &mut *buffer.as_mut_ptr() };
|
|
||||||
let mut vec;
|
let mut vec;
|
||||||
let mutable_slice = if let Some(buffer_prefix) = buffer.get_mut(..slice.len()) {
|
let mutable_slice = if let Some(buffer_prefix) = buffer.get_mut(..slice.len()) {
|
||||||
buffer_prefix.copy_from_slice(slice);
|
buffer_prefix.copy_from_slice(slice);
|
||||||
|
|
|
@ -112,8 +112,8 @@ macro_rules! define_keyword_type {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! profiler_label {
|
macro_rules! profiler_label {
|
||||||
($label_type:ident) => {
|
($label_type:ident) => {
|
||||||
let mut _profiler_label =
|
let mut _profiler_label: $crate::gecko_bindings::structs::AutoProfilerLabel =
|
||||||
::std::mem::MaybeUninit::<$crate::gecko_bindings::structs::AutoProfilerLabel>::uninit();
|
unsafe { ::std::mem::uninitialized() };
|
||||||
let _profiler_label = if $crate::gecko::profiler::profiler_is_active() {
|
let _profiler_label = if $crate::gecko::profiler::profiler_is_active() {
|
||||||
unsafe {
|
unsafe {
|
||||||
Some($crate::gecko::profiler::AutoProfilerLabel::new(
|
Some($crate::gecko::profiler::AutoProfilerLabel::new(
|
||||||
|
|
|
@ -44,9 +44,9 @@ use crate::properties::computed_value_flags::*;
|
||||||
use crate::properties::longhands;
|
use crate::properties::longhands;
|
||||||
use crate::rule_tree::StrongRuleNode;
|
use crate::rule_tree::StrongRuleNode;
|
||||||
use crate::selector_parser::PseudoElement;
|
use crate::selector_parser::PseudoElement;
|
||||||
use servo_arc::{Arc, RawOffsetArc, UniqueArc};
|
use servo_arc::{Arc, RawOffsetArc};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::{forget, zeroed, ManuallyDrop};
|
use std::mem::{forget, uninitialized, zeroed, ManuallyDrop};
|
||||||
use std::{cmp, ops, ptr};
|
use std::{cmp, ops, ptr};
|
||||||
use crate::values::{self, CustomIdent, Either, KeyframesName, None_};
|
use crate::values::{self, CustomIdent, Either, KeyframesName, None_};
|
||||||
use crate::values::computed::{Percentage, TransitionProperty};
|
use crate::values::computed::{Percentage, TransitionProperty};
|
||||||
|
@ -215,18 +215,19 @@ impl ComputedValuesInner {
|
||||||
Some(p) => p.pseudo_type(),
|
Some(p) => p.pseudo_type(),
|
||||||
None => structs::PseudoStyleType::NotPseudo,
|
None => structs::PseudoStyleType::NotPseudo,
|
||||||
};
|
};
|
||||||
unsafe {
|
let arc = unsafe {
|
||||||
let mut arc = UniqueArc::<ComputedValues>::new_uninit();
|
let arc: Arc<ComputedValues> = Arc::new(uninitialized());
|
||||||
bindings::Gecko_ComputedStyle_Init(
|
bindings::Gecko_ComputedStyle_Init(
|
||||||
&mut (*arc.as_mut_ptr()).0,
|
&arc.0 as *const _ as *mut _,
|
||||||
&self,
|
&self,
|
||||||
pseudo_ty,
|
pseudo_ty,
|
||||||
);
|
);
|
||||||
// We're simulating move semantics by having C++ do a memcpy and then forgetting
|
// We're simulating a move by having C++ do a memcpy and then forgetting
|
||||||
// it on this end.
|
// it on this end.
|
||||||
forget(self);
|
forget(self);
|
||||||
UniqueArc::assume_init(arc).shareable()
|
arc
|
||||||
}
|
};
|
||||||
|
arc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::properties::LonghandId;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::mem;
|
use std::mem::{self, ManuallyDrop};
|
||||||
use crate::hash::FxHashMap;
|
use crate::hash::FxHashMap;
|
||||||
use super::ComputedValues;
|
use super::ComputedValues;
|
||||||
use crate::values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
|
use crate::values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
|
||||||
|
@ -252,12 +252,12 @@ impl Clone for AnimationValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut out = mem::MaybeUninit::uninit();
|
let mut out = mem::uninitialized();
|
||||||
ptr::write(
|
ptr::write(
|
||||||
out.as_mut_ptr() as *mut CopyVariants,
|
&mut out as *mut _ as *mut CopyVariants,
|
||||||
*(self as *const _ as *const CopyVariants),
|
*(self as *const _ as *const CopyVariants),
|
||||||
);
|
);
|
||||||
return out.assume_init();
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,15 +269,15 @@ impl Clone for AnimationValue {
|
||||||
${props[0].camel_case}(value.clone())
|
${props[0].camel_case}(value.clone())
|
||||||
% else:
|
% else:
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut out = mem::MaybeUninit::uninit();
|
let mut out = ManuallyDrop::new(mem::uninitialized());
|
||||||
ptr::write(
|
ptr::write(
|
||||||
out.as_mut_ptr() as *mut AnimationValueVariantRepr<${ty}>,
|
&mut out as *mut _ as *mut AnimationValueVariantRepr<${ty}>,
|
||||||
AnimationValueVariantRepr {
|
AnimationValueVariantRepr {
|
||||||
tag: *(self as *const _ as *const u16),
|
tag: *(self as *const _ as *const u16),
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
out.assume_init()
|
ManuallyDrop::into_inner(out)
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
@ -356,15 +356,15 @@ impl AnimationValue {
|
||||||
PropertyDeclaration::${props[0].camel_case}(value)
|
PropertyDeclaration::${props[0].camel_case}(value)
|
||||||
% else:
|
% else:
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut out = mem::MaybeUninit::uninit();
|
let mut out = mem::uninitialized();
|
||||||
ptr::write(
|
ptr::write(
|
||||||
out.as_mut_ptr() as *mut PropertyDeclarationVariantRepr<${specified}>,
|
&mut out as *mut _ as *mut PropertyDeclarationVariantRepr<${specified}>,
|
||||||
PropertyDeclarationVariantRepr {
|
PropertyDeclarationVariantRepr {
|
||||||
tag: *(self as *const _ as *const u16),
|
tag: *(self as *const _ as *const u16),
|
||||||
value,
|
value,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
out.assume_init()
|
out
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
@ -424,15 +424,15 @@ impl AnimationValue {
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut out = mem::MaybeUninit::uninit();
|
let mut out = mem::uninitialized();
|
||||||
ptr::write(
|
ptr::write(
|
||||||
out.as_mut_ptr() as *mut AnimationValueVariantRepr<${ty}>,
|
&mut out as *mut _ as *mut AnimationValueVariantRepr<${ty}>,
|
||||||
AnimationValueVariantRepr {
|
AnimationValueVariantRepr {
|
||||||
tag: longhand_id.to_physical(context.builder.writing_mode) as u16,
|
tag: longhand_id.to_physical(context.builder.writing_mode) as u16,
|
||||||
value,
|
value,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
out.assume_init()
|
out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
|
@ -579,15 +579,15 @@ impl Animate for AnimationValue {
|
||||||
let value = this.animate(&other_repr.value, procedure)?;
|
let value = this.animate(&other_repr.value, procedure)?;
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
let mut out = mem::MaybeUninit::uninit();
|
let mut out = mem::uninitialized();
|
||||||
ptr::write(
|
ptr::write(
|
||||||
out.as_mut_ptr() as *mut AnimationValueVariantRepr<${ty}>,
|
&mut out as *mut _ as *mut AnimationValueVariantRepr<${ty}>,
|
||||||
AnimationValueVariantRepr {
|
AnimationValueVariantRepr {
|
||||||
tag: this_tag,
|
tag: this_tag,
|
||||||
value,
|
value,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
out.assume_init()
|
out
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
${" |\n".join("{}(void)".format(prop.camel_case) for prop in unanimated)} => {
|
${" |\n".join("{}(void)".format(prop.camel_case) for prop in unanimated)} => {
|
||||||
|
|
|
@ -367,16 +367,15 @@ ${helpers.predefined_type(
|
||||||
% endfor
|
% endfor
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut system = mem::MaybeUninit::<nsFont>::uninit();
|
let mut system: nsFont = unsafe { mem::uninitialized() };
|
||||||
let system = unsafe {
|
unsafe {
|
||||||
bindings::Gecko_nsFont_InitSystem(
|
bindings::Gecko_nsFont_InitSystem(
|
||||||
system.as_mut_ptr(),
|
&mut system,
|
||||||
id as i32,
|
id as i32,
|
||||||
cx.style().get_font().gecko(),
|
cx.style().get_font().gecko(),
|
||||||
cx.device().document()
|
cx.device().document()
|
||||||
);
|
)
|
||||||
&mut *system.as_mut_ptr()
|
}
|
||||||
};
|
|
||||||
let font_weight = longhands::font_weight::computed_value::T::from_gecko_weight(system.weight);
|
let font_weight = longhands::font_weight::computed_value::T::from_gecko_weight(system.weight);
|
||||||
let font_stretch = FontStretch(NonNegative(Percentage(unsafe {
|
let font_stretch = FontStretch(NonNegative(Percentage(unsafe {
|
||||||
bindings::Gecko_FontStretch_ToFloat(system.stretch)
|
bindings::Gecko_FontStretch_ToFloat(system.stretch)
|
||||||
|
@ -414,7 +413,7 @@ ${helpers.predefined_type(
|
||||||
system_font: *self,
|
system_font: *self,
|
||||||
default_font_type: system.fontlist.mDefaultFontType,
|
default_font_type: system.fontlist.mDefaultFontType,
|
||||||
};
|
};
|
||||||
unsafe { bindings::Gecko_nsFont_Destroy(system); }
|
unsafe { bindings::Gecko_nsFont_Destroy(&mut system); }
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ use servo_arc::{Arc, UniqueArc};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::{ops, ptr};
|
use std::{ops, ptr};
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use std::mem;
|
use std::mem::{self, ManuallyDrop};
|
||||||
|
|
||||||
use cssparser::{Parser, RGBA, TokenSerializationType};
|
use cssparser::{Parser, RGBA, TokenSerializationType};
|
||||||
use cssparser::ParserInput;
|
use cssparser::ParserInput;
|
||||||
|
@ -294,12 +294,12 @@ impl Clone for PropertyDeclaration {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut out = mem::MaybeUninit::uninit();
|
let mut out = mem::uninitialized();
|
||||||
ptr::write(
|
ptr::write(
|
||||||
out.as_mut_ptr() as *mut CopyVariants,
|
&mut out as *mut _ as *mut CopyVariants,
|
||||||
*(self as *const _ as *const CopyVariants),
|
*(self as *const _ as *const CopyVariants),
|
||||||
);
|
);
|
||||||
return out.assume_init();
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,15 +333,15 @@ impl Clone for PropertyDeclaration {
|
||||||
% else:
|
% else:
|
||||||
${" |\n".join("{}(ref value)".format(v["name"]) for v in vs)} => {
|
${" |\n".join("{}(ref value)".format(v["name"]) for v in vs)} => {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut out = mem::MaybeUninit::uninit();
|
let mut out = ManuallyDrop::new(mem::uninitialized());
|
||||||
ptr::write(
|
ptr::write(
|
||||||
out.as_mut_ptr() as *mut PropertyDeclarationVariantRepr<${ty}>,
|
&mut out as *mut _ as *mut PropertyDeclarationVariantRepr<${ty}>,
|
||||||
PropertyDeclarationVariantRepr {
|
PropertyDeclarationVariantRepr {
|
||||||
tag: *(self as *const _ as *const u16),
|
tag: *(self as *const _ as *const u16),
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
out.assume_init()
|
ManuallyDrop::into_inner(out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
|
|
@ -412,10 +412,9 @@ impl<T: ToShmem, A: Array<Item = T>> ToShmem for SmallVec<A> {
|
||||||
SmallVec::from_raw_parts(dest, self.len(), self.len())
|
SmallVec::from_raw_parts(dest, self.len(), self.len())
|
||||||
} else {
|
} else {
|
||||||
// Place the items inline.
|
// Place the items inline.
|
||||||
let mut s = SmallVec::new();
|
let mut inline: A = mem::uninitialized();
|
||||||
to_shmem_slice_ptr(self.iter(), s.as_mut_ptr(), builder);
|
to_shmem_slice_ptr(self.iter(), inline.ptr_mut(), builder);
|
||||||
s.set_len(self.len());
|
SmallVec::from_buf_and_len(inline, self.len())
|
||||||
s
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче