Auto merge of #70800 - Dylan-DPC:rollup-9jjoptp, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #70635 (rustc_target: Some cleanup to `no_default_libraries`) - #70748 (Do not disable field reordering on enums with big discriminant) - #70752 (Add slice::fill) - #70766 (use ManuallyDrop instead of forget inside collections) - #70768 (macro_rules: `NtLifetime` cannot start with an identifier) - #70783 (comment refers to removed type) Failed merges: r? @ghost
This commit is contained in:
commit
7b657d340d
@ -469,8 +469,8 @@ impl<T: ?Sized> Box<T> {
|
||||
#[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
|
||||
|
@ -4,9 +4,10 @@ use core::fmt::Debug;
|
||||
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::*};
|
||||
@ -190,9 +191,9 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
|
||||
// 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)
|
||||
};
|
||||
|
||||
@ -1515,15 +1516,14 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
|
||||
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()),
|
||||
|
@ -12,7 +12,7 @@ use core::cmp::{self, Ordering};
|
||||
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};
|
||||
@ -2898,12 +2898,12 @@ impl<T> From<Vec<T>> for VecDeque<T> {
|
||||
/// 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
|
||||
@ -2955,6 +2955,7 @@ impl<T> From<VecDeque<T>> for Vec<T> {
|
||||
other.make_contiguous();
|
||||
|
||||
unsafe {
|
||||
let other = ManuallyDrop::new(other);
|
||||
let buf = other.buf.ptr();
|
||||
let len = other.len();
|
||||
let cap = other.cap();
|
||||
@ -2962,9 +2963,7 @@ impl<T> From<VecDeque<T>> for Vec<T> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
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;
|
||||
@ -112,11 +112,10 @@ impl<T> RawVec<T, Global> {
|
||||
}
|
||||
|
||||
/// 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())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -579,11 +578,10 @@ impl<T> RawVec<T, Global> {
|
||||
"`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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ use core::hash::{self, Hash};
|
||||
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};
|
||||
@ -392,7 +392,7 @@ impl<T> Vec<T> {
|
||||
/// ```
|
||||
#[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())
|
||||
}
|
||||
|
||||
@ -678,9 +678,9 @@ impl<T> Vec<T> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
@ -1949,16 +1949,16 @@ impl<T> IntoIterator for Vec<T> {
|
||||
/// }
|
||||
/// ```
|
||||
#[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,
|
||||
@ -2081,9 +2081,8 @@ impl<T> SpecExtend<T, IntoIter<T>> for Vec<T> {
|
||||
// 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();
|
||||
|
@ -23,6 +23,7 @@
|
||||
// * 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;
|
||||
@ -2145,6 +2146,29 @@ impl<T> [T] {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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`.
|
||||
|
@ -136,7 +136,6 @@ pub fn diagnostics_registry() -> Registry {
|
||||
}
|
||||
|
||||
// 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],
|
||||
|
@ -768,7 +768,7 @@ fn may_begin_with(token: &Token, name: Name) -> bool {
|
||||
/// 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,
|
||||
}
|
||||
}
|
||||
|
@ -285,11 +285,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
|
||||
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() };
|
||||
@ -307,6 +303,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
});
|
||||
}
|
||||
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]));
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ pub fn opts() -> TargetOptions {
|
||||
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(),
|
||||
|
@ -15,7 +15,6 @@ pub fn opts() -> TargetOptions {
|
||||
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(),
|
||||
|
@ -77,7 +77,6 @@ pub fn opts() -> TargetOptions {
|
||||
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,
|
||||
|
@ -43,7 +43,6 @@ pub fn opts() -> TargetOptions {
|
||||
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,
|
||||
|
13
src/test/ui/macros/issue-70446.rs
Normal file
13
src/test/ui/macros/issue-70446.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// check-pass
|
||||
|
||||
macro_rules! foo {
|
||||
($(: $p:path)? $(: $l:lifetime)? ) => { bar! {$(: $p)? $(: $l)? } };
|
||||
}
|
||||
|
||||
macro_rules! bar {
|
||||
($(: $p:path)? $(: $l:lifetime)? ) => {};
|
||||
}
|
||||
|
||||
foo! {: 'a }
|
||||
|
||||
fn main() {}
|
@ -37,6 +37,29 @@ enum ReorderedEnum {
|
||||
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 {
|
||||
@ -104,6 +127,8 @@ pub fn main() {
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user