Skip to content

Commit

Permalink
Auto merge of rust-lang#71483 - Dylan-DPC:rollup-c2h9s8b, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - rust-lang#70633 (Confusing suggestion on incorrect closing `}`)
 - rust-lang#71404 (Don't fuse Chain in its second iterator)
 - rust-lang#71408 (Check code blocks tags)
 - rust-lang#71442 (Add a "by reference" adaptor for `AllocRef`)
 - rust-lang#71446 (Only use read_unaligned in transmute_copy if necessary)
 - rust-lang#71470 (Fix doc links)
 - rust-lang#71479 (add back Scalar::null_ptr)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Apr 23, 2020
2 parents 413a129 + b107eb5 commit 14b1552
Show file tree
Hide file tree
Showing 30 changed files with 939 additions and 73 deletions.
2 changes: 1 addition & 1 deletion src/liballoc/collections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub struct VecDeque<T> {
/// It produces the following sequence of matching slices:
///
/// ([0 1], [a b])
/// ([2], [c])
/// (\[2\], \[c\])
/// ([3 4], [d e])
///
/// and the uneven remainder of either A or B is skipped.
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ unsafe fn set_data_ptr<T: ?Sized, U>(mut ptr: *mut T, data: *mut U) -> *mut T {
}

impl<T> Rc<[T]> {
/// Copy elements from slice into newly allocated Rc<[T]>
/// Copy elements from slice into newly allocated Rc<\[T\]>
///
/// Unsafe because the caller must either take ownership or bind `T: Copy`
unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> {
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ unsafe fn set_data_ptr<T: ?Sized, U>(mut ptr: *mut T, data: *mut U) -> *mut T {
}

impl<T> Arc<[T]> {
/// Copy elements from slice into newly allocated Arc<[T]>
/// Copy elements from slice into newly allocated Arc<\[T\]>
///
/// Unsafe because the caller must either take ownership or bind `T: Copy`.
unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> {
Expand Down
47 changes: 47 additions & 0 deletions src/libcore/alloc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,51 @@ pub unsafe trait AllocRef {
}
}
}

/// Creates a "by reference" adaptor for this instance of `AllocRef`.
///
/// The returned adaptor also implements `AllocRef` and will simply borrow this.
#[inline(always)]
fn by_ref(&mut self) -> &mut Self {
self
}
}

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl<A> AllocRef for &mut A
where
A: AllocRef + ?Sized,
{
#[inline]
fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
(**self).alloc(layout, init)
}

#[inline]
unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
(**self).dealloc(ptr, layout)
}

#[inline]
unsafe fn grow(
&mut self,
ptr: NonNull<u8>,
layout: Layout,
new_size: usize,
placement: ReallocPlacement,
init: AllocInit,
) -> Result<MemoryBlock, AllocErr> {
(**self).grow(ptr, layout, new_size, placement, init)
}

#[inline]
unsafe fn shrink(
&mut self,
ptr: NonNull<u8>,
layout: Layout,
new_size: usize,
placement: ReallocPlacement,
) -> Result<MemoryBlock, AllocErr> {
(**self).shrink(ptr, layout, new_size, placement)
}
}
2 changes: 1 addition & 1 deletion src/libcore/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> {
mod sealed_trait {
/// Trait which whitelists the allowed types to be used with [VaList::arg]
///
/// [VaList::va_arg]: struct.VaList.html#method.arg
/// [VaList::arg]: ../struct.VaList.html#method.arg
#[unstable(
feature = "c_variadic",
reason = "the `c_variadic` feature has not been properly tested on \
Expand Down
32 changes: 22 additions & 10 deletions src/libcore/iter/adapters/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub struct Chain<A, B> {
// adapter because its specialization for `FusedIterator` unconditionally descends into the
// iterator, and that could be expensive to keep revisiting stuff like nested chains. It also
// hurts compiler performance to add more iterator layers to `Chain`.
//
// Only the "first" iterator is actually set `None` when exhausted, depending on whether you
// iterate forward or backward. If you mix directions, then both sides may be `None`.
a: Option<A>,
b: Option<B>,
}
Expand All @@ -43,6 +46,17 @@ macro_rules! fuse {
};
}

/// Try an iterator method without fusing,
/// like an inline `.as_mut().and_then(...)`
macro_rules! maybe {
($self:ident . $iter:ident . $($call:tt)+) => {
match $self.$iter {
Some(ref mut iter) => iter.$($call)+,
None => None,
}
};
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A, B> Iterator for Chain<A, B>
where
Expand All @@ -54,7 +68,7 @@ where
#[inline]
fn next(&mut self) -> Option<A::Item> {
match fuse!(self.a.next()) {
None => fuse!(self.b.next()),
None => maybe!(self.b.next()),
item => item,
}
}
Expand Down Expand Up @@ -85,7 +99,7 @@ where
}
if let Some(ref mut b) = self.b {
acc = b.try_fold(acc, f)?;
self.b = None;
// we don't fuse the second iterator
}
Try::from_ok(acc)
}
Expand Down Expand Up @@ -114,7 +128,7 @@ where
}
self.a = None;
}
fuse!(self.b.nth(n))
maybe!(self.b.nth(n))
}

#[inline]
Expand All @@ -123,7 +137,7 @@ where
P: FnMut(&Self::Item) -> bool,
{
match fuse!(self.a.find(&mut predicate)) {
None => fuse!(self.b.find(predicate)),
None => maybe!(self.b.find(predicate)),
item => item,
}
}
Expand Down Expand Up @@ -174,7 +188,7 @@ where
#[inline]
fn next_back(&mut self) -> Option<A::Item> {
match fuse!(self.b.next_back()) {
None => fuse!(self.a.next_back()),
None => maybe!(self.a.next_back()),
item => item,
}
}
Expand All @@ -190,7 +204,7 @@ where
}
self.b = None;
}
fuse!(self.a.nth_back(n))
maybe!(self.a.nth_back(n))
}

#[inline]
Expand All @@ -199,7 +213,7 @@ where
P: FnMut(&Self::Item) -> bool,
{
match fuse!(self.b.rfind(&mut predicate)) {
None => fuse!(self.a.rfind(predicate)),
None => maybe!(self.a.rfind(predicate)),
item => item,
}
}
Expand All @@ -216,7 +230,7 @@ where
}
if let Some(ref mut a) = self.a {
acc = a.try_rfold(acc, f)?;
self.a = None;
// we don't fuse the second iterator
}
Try::from_ok(acc)
}
Expand All @@ -236,8 +250,6 @@ where
}

// Note: *both* must be fused to handle double-ended iterators.
// Now that we "fuse" both sides, we *could* implement this unconditionally,
// but we should be cautious about committing to that in the public API.
#[stable(feature = "fused", since = "1.26.0")]
impl<A, B> FusedIterator for Chain<A, B>
where
Expand Down
7 changes: 6 additions & 1 deletion src/libcore/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,12 @@ pub fn drop<T>(_x: T) {}
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
ptr::read_unaligned(src as *const T as *const U)
// If U has a higher alignment requirement, src may not be suitably aligned.
if align_of::<U>() > align_of::<T>() {
ptr::read_unaligned(src as *const T as *const U)
} else {
ptr::read(src as *const T as *const U)
}
}

/// Opaque type representing the discriminant of an enum.
Expand Down
64 changes: 39 additions & 25 deletions src/libcore/tests/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,50 +207,64 @@ fn test_iterator_chain_find() {
assert_eq!(iter.next(), None);
}

#[test]
fn test_iterator_chain_size_hint() {
struct Iter {
is_empty: bool,
}
struct Toggle {
is_empty: bool,
}

impl Iterator for Iter {
type Item = ();
impl Iterator for Toggle {
type Item = ();

// alternates between `None` and `Some(())`
fn next(&mut self) -> Option<Self::Item> {
if self.is_empty {
self.is_empty = false;
None
} else {
self.is_empty = true;
Some(())
}
// alternates between `None` and `Some(())`
fn next(&mut self) -> Option<Self::Item> {
if self.is_empty {
self.is_empty = false;
None
} else {
self.is_empty = true;
Some(())
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
if self.is_empty { (0, Some(0)) } else { (1, Some(1)) }
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.is_empty { (0, Some(0)) } else { (1, Some(1)) }
}
}

impl DoubleEndedIterator for Iter {
fn next_back(&mut self) -> Option<Self::Item> {
self.next()
}
impl DoubleEndedIterator for Toggle {
fn next_back(&mut self) -> Option<Self::Item> {
self.next()
}
}

#[test]
fn test_iterator_chain_size_hint() {
// this chains an iterator of length 0 with an iterator of length 1,
// so after calling `.next()` once, the iterator is empty and the
// state is `ChainState::Back`. `.size_hint()` should now disregard
// the size hint of the left iterator
let mut iter = Iter { is_empty: true }.chain(once(()));
let mut iter = Toggle { is_empty: true }.chain(once(()));
assert_eq!(iter.next(), Some(()));
assert_eq!(iter.size_hint(), (0, Some(0)));

let mut iter = once(()).chain(Iter { is_empty: true });
let mut iter = once(()).chain(Toggle { is_empty: true });
assert_eq!(iter.next_back(), Some(()));
assert_eq!(iter.size_hint(), (0, Some(0)));
}

#[test]
fn test_iterator_chain_unfused() {
// Chain shouldn't be fused in its second iterator, depending on direction
let mut iter = NonFused::new(empty()).chain(Toggle { is_empty: true });
iter.next().unwrap_none();
iter.next().unwrap();
iter.next().unwrap_none();

let mut iter = Toggle { is_empty: true }.chain(NonFused::new(empty()));
iter.next_back().unwrap_none();
iter.next_back().unwrap();
iter.next_back().unwrap_none();
}

#[test]
fn test_zip_nth() {
let xs = [0, 1, 2, 4, 5];
Expand Down
1 change: 1 addition & 0 deletions src/libcore/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#![feature(unwrap_infallible)]
#![feature(leading_trailing_ones)]
#![feature(const_forget)]
#![feature(option_unwrap_none)]

extern crate test;

Expand Down
4 changes: 3 additions & 1 deletion src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::{
BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS,
INTRA_DOC_LINK_RESOLUTION_FAILURE, INVALID_CODEBLOCK_ATTRIBUTE, MISSING_DOC_CODE_EXAMPLES,
PRIVATE_DOC_TESTS,
};
use rustc_span::Span;

Expand Down Expand Up @@ -299,6 +300,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
add_lint_group!(
"rustdoc",
INTRA_DOC_LINK_RESOLUTION_FAILURE,
INVALID_CODEBLOCK_ATTRIBUTE,
MISSING_DOC_CODE_EXAMPLES,
PRIVATE_DOC_TESTS
);
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_middle/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ impl<'tcx, Tag> Scalar<Tag> {
}
}

#[inline]
pub fn null_ptr(cx: &impl HasDataLayout) -> Self {
Scalar::Raw { data: 0, size: cx.data_layout().pointer_size.bytes() as u8 }
}

#[inline]
pub fn zst() -> Self {
Scalar::Raw { data: 0, size: 0 }
Expand Down
Loading

0 comments on commit 14b1552

Please sign in to comment.