#[inline]
#[doc(hidden)]
pub fn into_unique(b: Box<T>) -> Unique<T> {
+ let b = mem::ManuallyDrop::new(b);
let mut unique = b.0;
- mem::forget(b);
// Box is kind-of a library type, but recognized as a "unique pointer" by
// Stacked Borrows. This function here corresponds to "reborrowing to
// a raw pointer", but there is no actual reborrow here -- so
use core::hash::{Hash, Hasher};
use core::iter::{FromIterator, FusedIterator, Peekable};
use core::marker::PhantomData;
+use core::mem::{self, ManuallyDrop};
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{Index, RangeBounds};
-use core::{fmt, mem, ptr};
+use core::{fmt, ptr};
use super::node::{self, marker, ForceResult::*, Handle, InsertResult::*, NodeRef};
use super::search::{self, SearchResult::*};
// We can't destructure subtree directly
// because BTreeMap implements Drop
let (subroot, sublength) = unsafe {
+ let subtree = ManuallyDrop::new(subtree);
let root = ptr::read(&subtree.root);
let length = subtree.length;
- mem::forget(subtree);
(root, length)
};
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> IntoIter<K, V> {
- if self.root.is_none() {
- mem::forget(self);
+ let me = ManuallyDrop::new(self);
+ if me.root.is_none() {
return IntoIter { front: None, back: None, length: 0 };
}
- let root1 = unsafe { unwrap_unchecked(ptr::read(&self.root)).into_ref() };
- let root2 = unsafe { unwrap_unchecked(ptr::read(&self.root)).into_ref() };
- let len = self.length;
- mem::forget(self);
+ let root1 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
+ let root2 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
+ let len = me.length;
IntoIter {
front: Some(root1.first_leaf_edge()),
use core::fmt;
use core::hash::{Hash, Hasher};
use core::iter::{once, repeat_with, FromIterator, FusedIterator};
-use core::mem::{self, replace};
+use core::mem::{self, replace, ManuallyDrop};
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{Index, IndexMut, RangeBounds, Try};
use core::ptr::{self, NonNull};
/// This avoids reallocating where possible, but the conditions for that are
/// strict, and subject to change, and so shouldn't be relied upon unless the
/// `Vec<T>` came from `From<VecDeque<T>>` and hasn't been reallocated.
- fn from(mut other: Vec<T>) -> Self {
+ fn from(other: Vec<T>) -> Self {
unsafe {
+ let mut other = ManuallyDrop::new(other);
let other_buf = other.as_mut_ptr();
let mut buf = RawVec::from_raw_parts(other_buf, other.capacity());
let len = other.len();
- mem::forget(other);
// We need to extend the buf if it's not a power of two, too small
// or doesn't have at least one free space
other.make_contiguous();
unsafe {
+ let other = ManuallyDrop::new(other);
let buf = other.buf.ptr();
let len = other.len();
let cap = other.cap();
if other.head != 0 {
ptr::copy(buf.add(other.tail), buf, len);
}
- let out = Vec::from_raw_parts(buf, len, cap);
- mem::forget(other);
- out
+ Vec::from_raw_parts(buf, len, cap)
}
}
}
use core::alloc::MemoryBlock;
use core::cmp;
-use core::mem::{self, MaybeUninit};
+use core::mem::{self, ManuallyDrop, MaybeUninit};
use core::ops::Drop;
use core::ptr::{NonNull, Unique};
use core::slice;
}
/// Converts a `Box<[T]>` into a `RawVec<T>`.
- pub fn from_box(mut slice: Box<[T]>) -> Self {
+ pub fn from_box(slice: Box<[T]>) -> Self {
unsafe {
- let result = RawVec::from_raw_parts(slice.as_mut_ptr(), slice.len());
- mem::forget(slice);
- result
+ let mut slice = ManuallyDrop::new(slice);
+ RawVec::from_raw_parts(slice.as_mut_ptr(), slice.len())
}
}
}
"`len` must be smaller than or equal to `self.capacity()`"
);
+ let me = ManuallyDrop::new(self);
// NOTE: not calling `capacity()` here; actually using the real `cap` field!
- let slice = slice::from_raw_parts_mut(self.ptr() as *mut MaybeUninit<T>, len);
- let output = Box::from_raw(slice);
- mem::forget(self);
- output
+ let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
+ Box::from_raw(slice)
}
}
use core::intrinsics::{arith_offset, assume};
use core::iter::{FromIterator, FusedIterator, TrustedLen};
use core::marker::PhantomData;
-use core::mem;
+use core::mem::{self, ManuallyDrop};
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{self, Index, IndexMut, RangeBounds};
use core::ptr::{self, NonNull};
/// ```
#[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
- let mut me = mem::ManuallyDrop::new(self);
+ let mut me = ManuallyDrop::new(self);
(me.as_mut_ptr(), me.len(), me.capacity())
}
pub fn into_boxed_slice(mut self) -> Box<[T]> {
unsafe {
self.shrink_to_fit();
- let buf = ptr::read(&self.buf);
- let len = self.len();
- mem::forget(self);
+ let me = ManuallyDrop::new(self);
+ let buf = ptr::read(&me.buf);
+ let len = me.len();
buf.into_box(len).assume_init()
}
}
/// }
/// ```
#[inline]
- fn into_iter(mut self) -> IntoIter<T> {
+ fn into_iter(self) -> IntoIter<T> {
unsafe {
- let begin = self.as_mut_ptr();
+ let mut me = ManuallyDrop::new(self);
+ let begin = me.as_mut_ptr();
let end = if mem::size_of::<T>() == 0 {
- arith_offset(begin as *const i8, self.len() as isize) as *const T
+ arith_offset(begin as *const i8, me.len() as isize) as *const T
} else {
- begin.add(self.len()) as *const T
+ begin.add(me.len()) as *const T
};
- let cap = self.buf.capacity();
- mem::forget(self);
+ let cap = me.buf.capacity();
IntoIter {
buf: NonNull::new_unchecked(begin),
phantom: PhantomData,
// has not been advanced at all.
if iterator.buf.as_ptr() as *const _ == iterator.ptr {
unsafe {
- let vec = Vec::from_raw_parts(iterator.buf.as_ptr(), iterator.len(), iterator.cap);
- mem::forget(iterator);
- vec
+ let it = ManuallyDrop::new(iterator);
+ Vec::from_raw_parts(it.buf.as_ptr(), it.len(), it.cap)
}
} else {
let mut vector = Vec::new();
// * The `raw` and `bytes` submodules.
// * Boilerplate trait implementations.
+use crate::borrow::Borrow;
use crate::cmp;
use crate::cmp::Ordering::{self, Equal, Greater, Less};
use crate::fmt;
}
}
+ /// Fills `self` with elements by cloning `value`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_fill)]
+ ///
+ /// let mut buf = vec![0; 10];
+ /// buf.fill(1);
+ /// assert_eq!(buf, vec![1; 10]);
+ /// ```
+ #[unstable(feature = "slice_fill", issue = "70758")]
+ pub fn fill<V>(&mut self, value: V)
+ where
+ V: Borrow<T>,
+ T: Clone,
+ {
+ let value = value.borrow();
+ for el in self {
+ el.clone_from(value)
+ }
+ }
+
/// Copies the elements from `src` into `self`.
///
/// The length of `src` must be the same as `self`.
}
// Parse args and run the compiler. This is the primary entry point for rustc.
-// See comments on CompilerCalls below for details about the callbacks argument.
// The FileLoader provides a way to load files from sources other than the file system.
pub fn run_compiler(
at_args: &[String],
/// Checks whether the non-terminal may contain a single (non-keyword) identifier.
fn may_be_ident(nt: &token::Nonterminal) -> bool {
match *nt {
- token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) => false,
+ token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => false,
_ => true,
}
}
let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
- let mut optimize = !repr.inhibit_struct_field_reordering_opt();
- if let StructKind::Prefixed(_, align) = kind {
- optimize &= align.bytes() == 1;
- }
-
+ let optimize = !repr.inhibit_struct_field_reordering_opt();
if optimize {
let end =
if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
});
}
StructKind::Prefixed(..) => {
+ // Sort in ascending alignment so that the layout stay optimal
+ // regardless of the prefix
optimizing.sort_by_key(|&x| field_align(&fields[x as usize]));
}
}
has_elf_tls: true,
linker_is_gnu: true,
pre_link_args,
- no_default_libraries: true,
panic_strategy: PanicStrategy::Abort,
position_independent_executables: true,
relocation_model: "static".to_string(),
has_elf_tls: true,
linker_is_gnu: true,
pre_link_args,
- no_default_libraries: true,
panic_strategy: PanicStrategy::Abort,
position_independent_executables: true,
relocation_model: "static".to_string(),
exe_suffix: ".exe".to_string(),
staticlib_prefix: String::new(),
staticlib_suffix: ".lib".to_string(),
- no_default_libraries: true,
target_family: Some("windows".to_string()),
is_like_windows: true,
allows_weak_linkage: false,
exe_suffix: ".exe".to_string(),
staticlib_prefix: "lib".to_string(),
staticlib_suffix: ".a".to_string(),
- no_default_libraries: true,
target_family: Some("windows".to_string()),
is_like_windows: true,
allows_weak_linkage: false,
--- /dev/null
+// check-pass
+
+macro_rules! foo {
+ ($(: $p:path)? $(: $l:lifetime)? ) => { bar! {$(: $p)? $(: $l)? } };
+}
+
+macro_rules! bar {
+ ($(: $p:path)? $(: $l:lifetime)? ) => {};
+}
+
+foo! {: 'a }
+
+fn main() {}
B(u8, u16, u8),
}
+enum ReorderedEnum2 {
+ A(u8, u32, u8),
+ B(u16, u8, u16, u8),
+
+ // 0x100 niche variants.
+ _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _0A, _0B, _0C, _0D, _0E, _0F,
+ _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1A, _1B, _1C, _1D, _1E, _1F,
+ _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2A, _2B, _2C, _2D, _2E, _2F,
+ _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3A, _3B, _3C, _3D, _3E, _3F,
+ _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4A, _4B, _4C, _4D, _4E, _4F,
+ _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5A, _5B, _5C, _5D, _5E, _5F,
+ _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6A, _6B, _6C, _6D, _6E, _6F,
+ _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7A, _7B, _7C, _7D, _7E, _7F,
+ _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8A, _8B, _8C, _8D, _8E, _8F,
+ _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9A, _9B, _9C, _9D, _9E, _9F,
+ _A0, _A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8, _A9, _AA, _AB, _AC, _AD, _AE, _AF,
+ _B0, _B1, _B2, _B3, _B4, _B5, _B6, _B7, _B8, _B9, _BA, _BB, _BC, _BD, _BE, _BF,
+ _C0, _C1, _C2, _C3, _C4, _C5, _C6, _C7, _C8, _C9, _CA, _CB, _CC, _CD, _CE, _CF,
+ _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7, _D8, _D9, _DA, _DB, _DC, _DD, _DE, _DF,
+ _E0, _E1, _E2, _E3, _E4, _E5, _E6, _E7, _E8, _E9, _EA, _EB, _EC, _ED, _EE, _EF,
+ _F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _FA, _FB, _FC, _FD, _FE, _FF,
+}
+
enum EnumEmpty {}
enum EnumSingle1 {
assert_eq!(size_of::<e3>(), 4 as usize);
assert_eq!(size_of::<ReorderedStruct>(), 4);
assert_eq!(size_of::<ReorderedEnum>(), 6);
+ assert_eq!(size_of::<ReorderedEnum2>(), 8);
+
assert_eq!(size_of::<EnumEmpty>(), 0);
assert_eq!(size_of::<EnumSingle1>(), 0);