Auto merge of #45684 - bjorn3:runtime_choose_trans2, r=eddyb
Allow runtime switching between trans backends
The driver callback after_llvm has been removed as it doesnt work with multiple backends.
r? @eddyb
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 54c5073..70376c1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -301,12 +301,12 @@
[pull-requests]: #pull-requests
Pull requests are the primary mechanism we use to change Rust. GitHub itself
-has some [great documentation][pull-requests] on using the Pull Request feature.
+has some [great documentation][about-pull-requests] on using the Pull Request feature.
We use the "fork and pull" model [described here][development-models], where
contributors push changes to their personal fork and create pull requests to
bring those changes into the source repository.
-[pull-requests]: https://help.github.com/articles/about-pull-requests/
+[about-pull-requests]: https://help.github.com/articles/about-pull-requests/
[development-models]: https://help.github.com/articles/about-collaborative-development-models/
Please make pull requests against the `master` branch.
diff --git a/src/doc/index.md b/src/doc/index.md
index 3784cc3..3add277 100644
--- a/src/doc/index.md
+++ b/src/doc/index.md
@@ -28,6 +28,7 @@
nicknamed 'The Rust Bookshelf.'
* [The Rust Programming Language][book] teaches you how to program in Rust.
+* [Rust By Example][rbe] teaches you how to program in Rust using editable examples.
* [The Cargo Book][cargo-book] is a guide to Cargo, Rust's build tool and dependency manager.
* [The Unstable Book][unstable-book] has documentation for unstable features.
* [The Rustonomicon][nomicon] is your guidebook to the dark arts of unsafe Rust.
@@ -51,6 +52,7 @@
[refchecklist]: https://github.com/rust-lang-nursery/reference/issues/9
[err]: error-index.html
[book]: book/index.html
+[rbe]: rust-by-example/index.html
[nomicon]: nomicon/index.html
[unstable-book]: unstable-book/index.html
[rustdoc-book]: rustdoc/index.html
diff --git a/src/doc/nomicon b/src/doc/nomicon
index 2f7b05f..fec3182 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit 2f7b05fd5939aa49d52c4ab309b9a47776ba7bd8
+Subproject commit fec3182d0b0a3cf8122e192b3270064a5b19be5b
diff --git a/src/liballoc/allocator.rs b/src/liballoc/allocator.rs
index c2a8f5f..55e8c0b 100644
--- a/src/liballoc/allocator.rs
+++ b/src/liballoc/allocator.rs
@@ -19,7 +19,7 @@
use core::fmt;
use core::mem;
use core::usize;
-use core::ptr::{self, Unique};
+use core::ptr::{self, NonNull};
/// Represents the combination of a starting address and
/// a total capacity of the returned block.
@@ -895,12 +895,12 @@
/// Clients wishing to abort computation in response to an
/// allocation error are encouraged to call the allocator's `oom`
/// method, rather than directly invoking `panic!` or similar.
- fn alloc_one<T>(&mut self) -> Result<Unique<T>, AllocErr>
+ fn alloc_one<T>(&mut self) -> Result<NonNull<T>, AllocErr>
where Self: Sized
{
let k = Layout::new::<T>();
if k.size() > 0 {
- unsafe { self.alloc(k).map(|p| Unique::new_unchecked(p as *mut T)) }
+ unsafe { self.alloc(k).map(|p| NonNull::new_unchecked(p as *mut T)) }
} else {
Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one"))
}
@@ -923,7 +923,7 @@
/// * `ptr` must denote a block of memory currently allocated via this allocator
///
/// * the layout of `T` must *fit* that block of memory.
- unsafe fn dealloc_one<T>(&mut self, ptr: Unique<T>)
+ unsafe fn dealloc_one<T>(&mut self, ptr: NonNull<T>)
where Self: Sized
{
let raw_ptr = ptr.as_ptr() as *mut u8;
@@ -963,7 +963,7 @@
/// Clients wishing to abort computation in response to an
/// allocation error are encouraged to call the allocator's `oom`
/// method, rather than directly invoking `panic!` or similar.
- fn alloc_array<T>(&mut self, n: usize) -> Result<Unique<T>, AllocErr>
+ fn alloc_array<T>(&mut self, n: usize) -> Result<NonNull<T>, AllocErr>
where Self: Sized
{
match Layout::array::<T>(n) {
@@ -971,7 +971,7 @@
unsafe {
self.alloc(layout.clone())
.map(|p| {
- Unique::new_unchecked(p as *mut T)
+ NonNull::new_unchecked(p as *mut T)
})
}
}
@@ -1012,15 +1012,15 @@
/// reallocation error are encouraged to call the allocator's `oom`
/// method, rather than directly invoking `panic!` or similar.
unsafe fn realloc_array<T>(&mut self,
- ptr: Unique<T>,
+ ptr: NonNull<T>,
n_old: usize,
- n_new: usize) -> Result<Unique<T>, AllocErr>
+ n_new: usize) -> Result<NonNull<T>, AllocErr>
where Self: Sized
{
match (Layout::array::<T>(n_old), Layout::array::<T>(n_new), ptr.as_ptr()) {
(Some(ref k_old), Some(ref k_new), ptr) if k_old.size() > 0 && k_new.size() > 0 => {
self.realloc(ptr as *mut u8, k_old.clone(), k_new.clone())
- .map(|p|Unique::new_unchecked(p as *mut T))
+ .map(|p| NonNull::new_unchecked(p as *mut T))
}
_ => {
Err(AllocErr::invalid_input("invalid layout for realloc_array"))
@@ -1048,7 +1048,7 @@
/// constraints.
///
/// Always returns `Err` on arithmetic overflow.
- unsafe fn dealloc_array<T>(&mut self, ptr: Unique<T>, n: usize) -> Result<(), AllocErr>
+ unsafe fn dealloc_array<T>(&mut self, ptr: NonNull<T>, n: usize) -> Result<(), AllocErr>
where Self: Sized
{
let raw_ptr = ptr.as_ptr() as *mut u8;
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 185af88..6a77bf6 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -25,7 +25,7 @@
use core::mem::{self, align_of_val, size_of_val, uninitialized};
use core::ops::Deref;
use core::ops::CoerceUnsized;
-use core::ptr::{self, Shared};
+use core::ptr::{self, NonNull};
use core::marker::{Unsize, PhantomData};
use core::hash::{Hash, Hasher};
use core::{isize, usize};
@@ -197,7 +197,7 @@
/// [rc_examples]: ../../std/rc/index.html#examples
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Arc<T: ?Sized> {
- ptr: Shared<ArcInner<T>>,
+ ptr: NonNull<ArcInner<T>>,
phantom: PhantomData<T>,
}
@@ -234,7 +234,7 @@
/// [`None`]: ../../std/option/enum.Option.html#variant.None
#[stable(feature = "arc_weak", since = "1.4.0")]
pub struct Weak<T: ?Sized> {
- ptr: Shared<ArcInner<T>>,
+ ptr: NonNull<ArcInner<T>>,
}
#[stable(feature = "arc_weak", since = "1.4.0")]
@@ -286,7 +286,7 @@
weak: atomic::AtomicUsize::new(1),
data,
};
- Arc { ptr: Shared::from(Box::into_unique(x)), phantom: PhantomData }
+ Arc { ptr: Box::into_raw_non_null(x), phantom: PhantomData }
}
/// Returns the contained value, if the `Arc` has exactly one strong reference.
@@ -397,7 +397,7 @@
let arc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
Arc {
- ptr: Shared::new_unchecked(arc_ptr),
+ ptr: NonNull::new_unchecked(arc_ptr),
phantom: PhantomData,
}
}
@@ -582,7 +582,7 @@
// Free the allocation without dropping its contents
box_free(bptr);
- Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
+ Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
}
}
}
@@ -609,7 +609,7 @@
&mut (*ptr).data as *mut [T] as *mut T,
v.len());
- Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
+ Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
}
}
@@ -669,7 +669,7 @@
// All clear. Forget the guard so it doesn't free the new ArcInner.
mem::forget(guard);
- Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
+ Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
}
}
}
@@ -991,11 +991,11 @@
pub fn new() -> Weak<T> {
unsafe {
Weak {
- ptr: Shared::from(Box::into_unique(box ArcInner {
+ ptr: Box::into_raw_non_null(box ArcInner {
strong: atomic::AtomicUsize::new(0),
weak: atomic::AtomicUsize::new(1),
data: uninitialized(),
- })),
+ }),
}
}
}
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 6f125cd..bfe23dd 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -68,7 +68,7 @@
use core::mem;
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer};
-use core::ptr::{self, Unique};
+use core::ptr::{self, NonNull, Unique};
use core::convert::From;
use str::from_boxed_utf8_unchecked;
@@ -269,38 +269,7 @@
#[stable(feature = "box_raw", since = "1.4.0")]
#[inline]
pub unsafe fn from_raw(raw: *mut T) -> Self {
- Box::from_unique(Unique::new_unchecked(raw))
- }
-
- /// Constructs a `Box` from a `Unique<T>` pointer.
- ///
- /// After calling this function, the memory is owned by a `Box` and `T` can
- /// then be destroyed and released upon drop.
- ///
- /// # Safety
- ///
- /// A `Unique<T>` can be safely created via [`Unique::new`] and thus doesn't
- /// necessarily own the data pointed to nor is the data guaranteed to live
- /// as long as the pointer.
- ///
- /// [`Unique::new`]: ../../core/ptr/struct.Unique.html#method.new
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(unique)]
- ///
- /// fn main() {
- /// let x = Box::new(5);
- /// let ptr = Box::into_unique(x);
- /// let x = unsafe { Box::from_unique(ptr) };
- /// }
- /// ```
- #[unstable(feature = "unique", reason = "needs an RFC to flesh out design",
- issue = "27730")]
- #[inline]
- pub unsafe fn from_unique(u: Unique<T>) -> Self {
- Box(u)
+ Box(Unique::new_unchecked(raw))
}
/// Consumes the `Box`, returning the wrapped raw pointer.
@@ -326,40 +295,42 @@
#[stable(feature = "box_raw", since = "1.4.0")]
#[inline]
pub fn into_raw(b: Box<T>) -> *mut T {
- Box::into_unique(b).as_ptr()
+ Box::into_raw_non_null(b).as_ptr()
}
- /// Consumes the `Box`, returning the wrapped pointer as `Unique<T>`.
+ /// Consumes the `Box`, returning the wrapped pointer as `NonNull<T>`.
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `Box`. In particular, the
/// caller should properly destroy `T` and release the memory. The
- /// proper way to do so is to either convert the `Unique<T>` pointer:
- ///
- /// - Into a `Box` with the [`Box::from_unique`] function.
- ///
- /// - Into a raw pointer and back into a `Box` with the [`Box::from_raw`]
- /// function.
+ /// proper way to do so is to convert the `NonNull<T>` pointer
+ /// into a raw pointer and back into a `Box` with the [`Box::from_raw`]
+ /// function.
///
/// Note: this is an associated function, which means that you have
- /// to call it as `Box::into_unique(b)` instead of `b.into_unique()`. This
+ /// to call it as `Box::into_raw_non_null(b)`
+ /// instead of `b.into_raw_non_null()`. This
/// is so that there is no conflict with a method on the inner type.
///
- /// [`Box::from_unique`]: struct.Box.html#method.from_unique
/// [`Box::from_raw`]: struct.Box.html#method.from_raw
///
/// # Examples
///
/// ```
- /// #![feature(unique)]
+ /// #![feature(box_into_raw_non_null)]
///
/// fn main() {
/// let x = Box::new(5);
- /// let ptr = Box::into_unique(x);
+ /// let ptr = Box::into_raw_non_null(x);
/// }
/// ```
- #[unstable(feature = "unique", reason = "needs an RFC to flesh out design",
- issue = "27730")]
+ #[unstable(feature = "box_into_raw_non_null", issue = "47336")]
+ #[inline]
+ pub fn into_raw_non_null(b: Box<T>) -> NonNull<T> {
+ Box::into_unique(b).into()
+ }
+
+ #[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")]
#[inline]
pub fn into_unique(b: Box<T>) -> Unique<T> {
let unique = b.0;
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs
index b2bd9d7..37af9ea 100644
--- a/src/liballoc/heap.rs
+++ b/src/liballoc/heap.rs
@@ -232,7 +232,7 @@
///
/// This preserves the non-null invariant for types like `Box<T>`. The address
/// may overlap with non-zero-size memory allocations.
-#[rustc_deprecated(since = "1.19", reason = "Use Unique/Shared::empty() instead")]
+#[rustc_deprecated(since = "1.19", reason = "Use Unique/NonNull::empty() instead")]
#[unstable(feature = "heap_api", issue = "27700")]
pub const EMPTY: *mut () = 1 as *mut ();
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 6ee4f80..5139e54 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -84,6 +84,7 @@
#![cfg_attr(test, feature(rand, test))]
#![feature(allow_internal_unstable)]
#![feature(ascii_ctype)]
+#![feature(box_into_raw_non_null)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_target_has_atomic)]
@@ -109,8 +110,8 @@
#![feature(pattern)]
#![feature(placement_in_syntax)]
#![feature(placement_new_protocol)]
+#![feature(ptr_internals)]
#![feature(rustc_attrs)]
-#![feature(shared)]
#![feature(slice_get_slice)]
#![feature(slice_patterns)]
#![feature(slice_rsplit)]
@@ -120,7 +121,6 @@
#![feature(trusted_len)]
#![feature(unboxed_closures)]
#![feature(unicode)]
-#![feature(unique)]
#![feature(unsize)]
#![feature(allocator_internals)]
#![feature(on_unimplemented)]
diff --git a/src/liballoc/linked_list.rs b/src/liballoc/linked_list.rs
index 3ac5a85..3cc810a 100644
--- a/src/liballoc/linked_list.rs
+++ b/src/liballoc/linked_list.rs
@@ -29,7 +29,7 @@
use core::marker::PhantomData;
use core::mem;
use core::ops::{BoxPlace, InPlace, Place, Placer};
-use core::ptr::{self, Shared};
+use core::ptr::{self, NonNull};
use boxed::{Box, IntermediateBox};
use super::SpecExtend;
@@ -44,15 +44,15 @@
/// more memory efficient and make better use of CPU cache.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct LinkedList<T> {
- head: Option<Shared<Node<T>>>,
- tail: Option<Shared<Node<T>>>,
+ head: Option<NonNull<Node<T>>>,
+ tail: Option<NonNull<Node<T>>>,
len: usize,
marker: PhantomData<Box<Node<T>>>,
}
struct Node<T> {
- next: Option<Shared<Node<T>>>,
- prev: Option<Shared<Node<T>>>,
+ next: Option<NonNull<Node<T>>>,
+ prev: Option<NonNull<Node<T>>>,
element: T,
}
@@ -65,8 +65,8 @@
/// [`LinkedList`]: struct.LinkedList.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, T: 'a> {
- head: Option<Shared<Node<T>>>,
- tail: Option<Shared<Node<T>>>,
+ head: Option<NonNull<Node<T>>>,
+ tail: Option<NonNull<Node<T>>>,
len: usize,
marker: PhantomData<&'a Node<T>>,
}
@@ -98,8 +98,8 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, T: 'a> {
list: &'a mut LinkedList<T>,
- head: Option<Shared<Node<T>>>,
- tail: Option<Shared<Node<T>>>,
+ head: Option<NonNull<Node<T>>>,
+ tail: Option<NonNull<Node<T>>>,
len: usize,
}
@@ -157,7 +157,7 @@
unsafe {
node.next = self.head;
node.prev = None;
- let node = Some(Shared::from(Box::into_unique(node)));
+ let node = Some(Box::into_raw_non_null(node));
match self.head {
None => self.tail = node,
@@ -192,7 +192,7 @@
unsafe {
node.next = None;
node.prev = self.tail;
- let node = Some(Shared::from(Box::into_unique(node)));
+ let node = Some(Box::into_raw_non_null(node));
match self.tail {
None => self.head = node,
@@ -225,7 +225,7 @@
///
/// Warning: this will not check that the provided node belongs to the current list.
#[inline]
- unsafe fn unlink_node(&mut self, mut node: Shared<Node<T>>) {
+ unsafe fn unlink_node(&mut self, mut node: NonNull<Node<T>>) {
let node = node.as_mut();
match node.prev {
@@ -986,11 +986,11 @@
Some(prev) => prev,
};
- let node = Some(Shared::from(Box::into_unique(box Node {
+ let node = Some(Box::into_raw_non_null(box Node {
next: Some(head),
prev: Some(prev),
element,
- })));
+ }));
prev.as_mut().next = node;
head.as_mut().prev = node;
@@ -1038,7 +1038,7 @@
where F: FnMut(&mut T) -> bool,
{
list: &'a mut LinkedList<T>,
- it: Option<Shared<Node<T>>>,
+ it: Option<NonNull<Node<T>>>,
pred: F,
idx: usize,
old_len: usize,
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index dbf1fb1..621e190 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -322,7 +322,7 @@
// would cause overflow
let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 };
match self.a.alloc_array::<T>(new_cap) {
- Ok(ptr) => (new_cap, ptr),
+ Ok(ptr) => (new_cap, ptr.into()),
Err(e) => self.a.oom(e),
}
}
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 59079f9..1fa5d34 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -256,7 +256,7 @@
use core::mem::{self, align_of_val, forget, size_of_val, uninitialized};
use core::ops::Deref;
use core::ops::CoerceUnsized;
-use core::ptr::{self, Shared};
+use core::ptr::{self, NonNull};
use core::convert::From;
use heap::{Heap, Alloc, Layout, box_free};
@@ -282,7 +282,7 @@
/// [get_mut]: #method.get_mut
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Rc<T: ?Sized> {
- ptr: Shared<RcBox<T>>,
+ ptr: NonNull<RcBox<T>>,
phantom: PhantomData<T>,
}
@@ -311,11 +311,11 @@
// pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
- ptr: Shared::from(Box::into_unique(box RcBox {
+ ptr: Box::into_raw_non_null(box RcBox {
strong: Cell::new(1),
weak: Cell::new(1),
value,
- })),
+ }),
phantom: PhantomData,
}
}
@@ -428,7 +428,7 @@
let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
Rc {
- ptr: Shared::new_unchecked(rc_ptr),
+ ptr: NonNull::new_unchecked(rc_ptr),
phantom: PhantomData,
}
}
@@ -649,7 +649,7 @@
let raw: *const RcBox<Any> = self.ptr.as_ptr();
forget(self);
Ok(Rc {
- ptr: Shared::new_unchecked(raw as *const RcBox<T> as *mut _),
+ ptr: NonNull::new_unchecked(raw as *const RcBox<T> as *mut _),
phantom: PhantomData,
})
}
@@ -695,7 +695,7 @@
// Free the allocation without dropping its contents
box_free(bptr);
- Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
+ Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
}
}
}
@@ -722,7 +722,7 @@
&mut (*ptr).value as *mut [T] as *mut T,
v.len());
- Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
+ Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
}
}
@@ -781,7 +781,7 @@
// All clear. Forget the guard so it doesn't free the new RcBox.
forget(guard);
- Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
+ Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
}
}
}
@@ -1160,7 +1160,7 @@
/// [`None`]: ../../std/option/enum.Option.html#variant.None
#[stable(feature = "rc_weak", since = "1.4.0")]
pub struct Weak<T: ?Sized> {
- ptr: Shared<RcBox<T>>,
+ ptr: NonNull<RcBox<T>>,
}
#[stable(feature = "rc_weak", since = "1.4.0")]
@@ -1190,11 +1190,11 @@
pub fn new() -> Weak<T> {
unsafe {
Weak {
- ptr: Shared::from(Box::into_unique(box RcBox {
+ ptr: Box::into_raw_non_null(box RcBox {
strong: Cell::new(0),
weak: Cell::new(1),
value: uninitialized(),
- })),
+ }),
}
}
}
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 301e446..b14b9d7 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -78,7 +78,7 @@
use core::ops::{InPlace, Index, IndexMut, Place, Placer};
use core::ops;
use core::ptr;
-use core::ptr::Shared;
+use core::ptr::NonNull;
use core::slice;
use borrow::ToOwned;
@@ -1124,7 +1124,7 @@
tail_start: end,
tail_len: len - end,
iter: range_slice.iter(),
- vec: Shared::from(self),
+ vec: NonNull::from(self),
}
}
}
@@ -1745,7 +1745,7 @@
let cap = self.buf.cap();
mem::forget(self);
IntoIter {
- buf: Shared::new_unchecked(begin),
+ buf: NonNull::new_unchecked(begin),
phantom: PhantomData,
cap,
ptr: begin,
@@ -2267,7 +2267,7 @@
/// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> {
- buf: Shared<T>,
+ buf: NonNull<T>,
phantom: PhantomData<T>,
cap: usize,
ptr: *const T,
@@ -2442,7 +2442,7 @@
tail_len: usize,
/// Current remaining range to remove
iter: slice::Iter<'a, T>,
- vec: Shared<Vec<T>>,
+ vec: NonNull<Vec<T>>,
}
#[stable(feature = "collection_debug", since = "1.17.0")]
diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs
index f56aa23..69557fe 100644
--- a/src/liballoc/vec_deque.rs
+++ b/src/liballoc/vec_deque.rs
@@ -23,7 +23,7 @@
use core::mem;
use core::ops::{Index, IndexMut, Place, Placer, InPlace};
use core::ptr;
-use core::ptr::Shared;
+use core::ptr::NonNull;
use core::slice;
use core::hash::{Hash, Hasher};
@@ -895,7 +895,7 @@
self.head = drain_tail;
Drain {
- deque: Shared::from(&mut *self),
+ deque: NonNull::from(&mut *self),
after_tail: drain_head,
after_head: head,
iter: Iter {
@@ -2154,7 +2154,7 @@
after_tail: usize,
after_head: usize,
iter: Iter<'a, T>,
- deque: Shared<VecDeque<T>>,
+ deque: NonNull<VecDeque<T>>,
}
#[stable(feature = "collection_debug", since = "1.17.0")]
@@ -2480,7 +2480,7 @@
if other.is_contiguous() {
ptr::copy(buf.offset(tail as isize), buf, len);
} else {
- if (tail - head) >= cmp::min((cap - tail), head) {
+ if (tail - head) >= cmp::min(cap - tail, head) {
// There is enough free space in the centre for the shortest block so we can
// do this in at most three copy moves.
if (cap - tail) > head {
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 15181da..b8fe28d 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -881,6 +881,35 @@
}
}
+impl<T, E> Option<Result<T, E>> {
+ /// Transposes an `Option` of a `Result` into a `Result` of an `Option`.
+ ///
+ /// `None` will be mapped to `Ok(None)`.
+ /// `Some(Ok(_))` and `Some(Err(_))` will be mapped to `Ok(Some(_))` and `Err(_)`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(transpose_result)]
+ ///
+ /// #[derive(Debug, Eq, PartialEq)]
+ /// struct SomeErr;
+ ///
+ /// let x: Result<Option<i32>, SomeErr> = Ok(Some(5));
+ /// let y: Option<Result<i32, SomeErr>> = Some(Ok(5));
+ /// assert_eq!(x, y.transpose());
+ /// ```
+ #[inline]
+ #[unstable(feature = "transpose_result", issue = "47338")]
+ pub fn transpose(self) -> Result<Option<T>, E> {
+ match self {
+ Some(Ok(x)) => Ok(Some(x)),
+ Some(Err(e)) => Err(e),
+ None => Ok(None),
+ }
+ }
+}
+
// This is a separate function to reduce the code size of .expect() itself.
#[inline(never)]
#[cold]
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 7f7246d..fab5832 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -2321,7 +2321,7 @@
/// its owning Unique.
///
/// If you're uncertain of whether it's correct to use `Unique` for your purposes,
-/// consider using `Shared`, which has weaker semantics.
+/// consider using `NonNull`, which has weaker semantics.
///
/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
/// is never dereferenced. This is so that enums may use this forbidden value
@@ -2330,9 +2330,9 @@
///
/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
/// for any type which upholds Unique's aliasing requirements.
-#[allow(missing_debug_implementations)]
-#[unstable(feature = "unique", reason = "needs an RFC to flesh out design",
- issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0",
+ reason = "use NonNull instead and consider PhantomData<T> \
+ (if you also use #[may_dangle]), Send, and/or Sync")]
pub struct Unique<T: ?Sized> {
pointer: NonZero<*const T>,
// NOTE: this marker has no consequences for variance, but is necessary
@@ -2343,26 +2343,34 @@
_marker: PhantomData<T>,
}
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> fmt::Debug for Unique<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Pointer::fmt(&self.as_ptr(), f)
+ }
+}
+
/// `Unique` pointers are `Send` if `T` is `Send` because the data they
/// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
/// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: Sized> Unique<T> {
/// Creates a new `Unique` that is dangling, but well-aligned.
///
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
+ // FIXME: rename to dangling() to match NonNull?
pub fn empty() -> Self {
unsafe {
let ptr = mem::align_of::<T>() as *mut T;
@@ -2371,14 +2379,13 @@
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> Unique<T> {
/// Creates a new `Unique`.
///
/// # Safety
///
/// `ptr` must be non-null.
- #[unstable(feature = "unique", issue = "27730")]
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
}
@@ -2397,7 +2404,7 @@
///
/// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer
- /// (unbound) lifetime is needed, use `&*my_ptr.ptr()`.
+ /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
pub unsafe fn as_ref(&self) -> &T {
&*self.as_ptr()
}
@@ -2406,112 +2413,130 @@
///
/// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer
- /// (unbound) lifetime is needed, use `&mut *my_ptr.ptr()`.
+ /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
pub unsafe fn as_mut(&mut self) -> &mut T {
&mut *self.as_ptr()
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> Clone for Unique<T> {
fn clone(&self) -> Self {
*self
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> Copy for Unique<T> { }
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { }
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> fmt::Pointer for Unique<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.as_ptr(), f)
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
fn from(reference: &'a mut T) -> Self {
Unique { pointer: NonZero::from(reference), _marker: PhantomData }
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
fn from(reference: &'a T) -> Self {
Unique { pointer: NonZero::from(reference), _marker: PhantomData }
}
}
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
+ fn from(p: NonNull<T>) -> Self {
+ Unique { pointer: p.pointer, _marker: PhantomData }
+ }
+}
+
+/// Previous name of `NonNull`.
+#[rustc_deprecated(since = "1.24", reason = "renamed to `NonNull`")]
+#[unstable(feature = "shared", issue = "27730")]
+pub type Shared<T> = NonNull<T>;
+
/// `*mut T` but non-zero and covariant.
///
/// This is often the correct thing to use when building data structures using
/// raw pointers, but is ultimately more dangerous to use because of its additional
-/// properties. If you're not sure if you should use `Shared<T>`, just use `*mut T`!
+/// properties. If you're not sure if you should use `NonNull<T>`, just use `*mut T`!
///
/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
/// is never dereferenced. This is so that enums may use this forbidden value
-/// as a discriminant -- `Option<Shared<T>>` has the same size as `Shared<T>`.
+/// as a discriminant -- `Option<NonNull<T>>` has the same size as `NonNull<T>`.
/// However the pointer may still dangle if it isn't dereferenced.
///
-/// Unlike `*mut T`, `Shared<T>` is covariant over `T`. If this is incorrect
+/// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect
/// for your use case, you should include some PhantomData in your type to
/// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
/// Usually this won't be necessary; covariance is correct for most safe abstractions,
/// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they
/// provide a public API that follows the normal shared XOR mutable rules of Rust.
-#[allow(missing_debug_implementations)]
-#[unstable(feature = "shared", reason = "needs an RFC to flesh out design",
- issue = "27730")]
-pub struct Shared<T: ?Sized> {
+#[stable(feature = "nonnull", since = "1.24.0")]
+pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>,
}
-/// `Shared` pointers are not `Send` because the data they reference may be aliased.
-// NB: This impl is unnecessary, but should provide better error messages.
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> !Send for Shared<T> { }
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<T: ?Sized> fmt::Debug for NonNull<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Pointer::fmt(&self.as_ptr(), f)
+ }
+}
-/// `Shared` pointers are not `Sync` because the data they reference may be aliased.
+/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
// NB: This impl is unnecessary, but should provide better error messages.
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> !Sync for Shared<T> { }
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<T: ?Sized> !Send for NonNull<T> { }
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: Sized> Shared<T> {
- /// Creates a new `Shared` that is dangling, but well-aligned.
+/// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
+// NB: This impl is unnecessary, but should provide better error messages.
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<T: ?Sized> !Sync for NonNull<T> { }
+
+impl<T: Sized> NonNull<T> {
+ /// Creates a new `NonNull` that is dangling, but well-aligned.
///
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
- pub fn empty() -> Self {
+ #[stable(feature = "nonnull", since = "1.24.0")]
+ pub fn dangling() -> Self {
unsafe {
let ptr = mem::align_of::<T>() as *mut T;
- Shared::new_unchecked(ptr)
+ NonNull::new_unchecked(ptr)
}
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> Shared<T> {
- /// Creates a new `Shared`.
+impl<T: ?Sized> NonNull<T> {
+ /// Creates a new `NonNull`.
///
/// # Safety
///
/// `ptr` must be non-null.
- #[unstable(feature = "shared", issue = "27730")]
+ #[stable(feature = "nonnull", since = "1.24.0")]
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
- Shared { pointer: NonZero::new_unchecked(ptr) }
+ NonNull { pointer: NonZero::new_unchecked(ptr) }
}
- /// Creates a new `Shared` if `ptr` is non-null.
+ /// Creates a new `NonNull` if `ptr` is non-null.
+ #[stable(feature = "nonnull", since = "1.24.0")]
pub fn new(ptr: *mut T) -> Option<Self> {
- NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz })
+ NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz })
}
/// Acquires the underlying `*mut` pointer.
+ #[stable(feature = "nonnull", since = "1.24.0")]
pub fn as_ptr(self) -> *mut T {
self.pointer.get() as *mut T
}
@@ -2520,7 +2545,8 @@
///
/// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer
- /// (unbound) lifetime is needed, use `&*my_ptr.ptr()`.
+ /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
+ #[stable(feature = "nonnull", since = "1.24.0")]
pub unsafe fn as_ref(&self) -> &T {
&*self.as_ptr()
}
@@ -2529,56 +2555,50 @@
///
/// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer
- /// (unbound) lifetime is needed, use `&mut *my_ptr.ptr_mut()`.
+ /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
+ #[stable(feature = "nonnull", since = "1.24.0")]
pub unsafe fn as_mut(&mut self) -> &mut T {
&mut *self.as_ptr()
}
-
- /// Acquires the underlying pointer as a `*mut` pointer.
- #[rustc_deprecated(since = "1.19", reason = "renamed to `as_ptr` for ergonomics/consistency")]
- #[unstable(feature = "shared", issue = "27730")]
- pub unsafe fn as_mut_ptr(&self) -> *mut T {
- self.as_ptr()
- }
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> Clone for Shared<T> {
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<T: ?Sized> Clone for NonNull<T> {
fn clone(&self) -> Self {
*self
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> Copy for Shared<T> { }
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<T: ?Sized> Copy for NonNull<T> { }
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized, U: ?Sized> CoerceUnsized<Shared<U>> for Shared<T> where T: Unsize<U> { }
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> fmt::Pointer for Shared<T> {
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<T: ?Sized> fmt::Pointer for NonNull<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.as_ptr(), f)
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> From<Unique<T>> for Shared<T> {
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
fn from(unique: Unique<T>) -> Self {
- Shared { pointer: unique.pointer }
+ NonNull { pointer: unique.pointer }
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<'a, T: ?Sized> From<&'a mut T> for Shared<T> {
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
fn from(reference: &'a mut T) -> Self {
- Shared { pointer: NonZero::from(reference) }
+ NonNull { pointer: NonZero::from(reference) }
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<'a, T: ?Sized> From<&'a T> for Shared<T> {
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
fn from(reference: &'a T) -> Self {
- Shared { pointer: NonZero::from(reference) }
+ NonNull { pointer: NonZero::from(reference) }
}
}
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 2ace3d2..3801db9 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -909,6 +909,35 @@
}
}
+impl<T, E> Result<Option<T>, E> {
+ /// Transposes a `Result` of an `Option` into an `Option` of a `Result`.
+ ///
+ /// `Ok(None)` will be mapped to `None`.
+ /// `Ok(Some(_))` and `Err(_)` will be mapped to `Some(Ok(_))` and `Some(Err(_))`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(transpose_result)]
+ ///
+ /// #[derive(Debug, Eq, PartialEq)]
+ /// struct SomeErr;
+ ///
+ /// let x: Result<Option<i32>, SomeErr> = Ok(Some(5));
+ /// let y: Option<Result<i32, SomeErr>> = Some(Ok(5));
+ /// assert_eq!(x.transpose(), y);
+ /// ```
+ #[inline]
+ #[unstable(feature = "transpose_result", issue = "47338")]
+ pub fn transpose(self) -> Option<Result<T, E>> {
+ match self {
+ Ok(Some(x)) => Some(Ok(x)),
+ Ok(None) => None,
+ Err(e) => Some(Err(e)),
+ }
+ }
+}
+
// This is a separate function to reduce the code size of the methods
#[inline(never)]
#[cold]
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 2c00095..1c32452 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -41,7 +41,6 @@
#![feature(trusted_len)]
#![feature(try_from)]
#![feature(try_trait)]
-#![feature(unique)]
#![feature(exact_chunks)]
extern crate core;
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
index 98436f0..00f8733 100644
--- a/src/libcore/tests/ptr.rs
+++ b/src/libcore/tests/ptr.rs
@@ -249,9 +249,9 @@
}
#[test]
-fn test_unsized_unique() {
+fn test_unsized_nonnull() {
let xs: &[i32] = &[1, 2, 3];
- let ptr = unsafe { Unique::new_unchecked(xs as *const [i32] as *mut [i32]) };
+ let ptr = unsafe { NonNull::new_unchecked(xs as *const [i32] as *mut [i32]) };
let ys = unsafe { ptr.as_ref() };
let zs: &[i32] = &[1, 2, 3];
assert!(ys == zs);
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 1aca687..e649f1b 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -717,93 +717,40 @@
self.tcx.hir.span_if_local(did)
}).map(|sp| self.tcx.sess.codemap().def_span(sp)); // the sp could be an fn def
- let found_ty_count =
- match found_trait_ref.skip_binder().substs.type_at(1).sty {
- ty::TyTuple(ref tys, _) => tys.len(),
- _ => 1,
- };
- let (expected_tys, expected_ty_count) =
- match expected_trait_ref.skip_binder().substs.type_at(1).sty {
- ty::TyTuple(ref tys, _) =>
- (tys.iter().map(|t| &t.sty).collect(), tys.len()),
- ref sty => (vec![sty], 1),
- };
- if found_ty_count == expected_ty_count {
+ let found = match found_trait_ref.skip_binder().substs.type_at(1).sty {
+ ty::TyTuple(ref tys, _) => tys.iter()
+ .map(|_| ArgKind::empty()).collect::<Vec<_>>(),
+ _ => vec![ArgKind::empty()],
+ };
+ let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty {
+ ty::TyTuple(ref tys, _) => tys.iter()
+ .map(|t| match t.sty {
+ ty::TypeVariants::TyTuple(ref tys, _) => ArgKind::Tuple(
+ span,
+ tys.iter()
+ .map(|ty| ("_".to_owned(), format!("{}", ty.sty)))
+ .collect::<Vec<_>>()
+ ),
+ _ => ArgKind::Arg("_".to_owned(), format!("{}", t.sty)),
+ }).collect(),
+ ref sty => vec![ArgKind::Arg("_".to_owned(), format!("{}", sty))],
+ };
+ if found.len()== expected.len() {
self.report_closure_arg_mismatch(span,
found_span,
found_trait_ref,
expected_trait_ref)
} else {
- let expected_tuple = if expected_ty_count == 1 {
- expected_tys.first().and_then(|t| {
- if let &&ty::TyTuple(ref tuptys, _) = t {
- Some(tuptys.len())
- } else {
- None
- }
- })
- } else {
- None
- };
-
- // FIXME(#44150): Expand this to "N args expected but a N-tuple found."
- // Type of the 1st expected argument is somehow provided as type of a
- // found one in that case.
- //
- // ```
- // [1i32, 2, 3].sort_by(|(a, b)| ..)
- // // ^^^^^^^ --------
- // // expected_trait_ref: std::ops::FnMut<(&i32, &i32)>
- // // found_trait_ref: std::ops::FnMut<(&i32,)>
- // ```
-
- let (closure_span, closure_args) = found_did
+ let (closure_span, found) = found_did
.and_then(|did| self.tcx.hir.get_if_local(did))
- .and_then(|node| {
- if let hir::map::NodeExpr(
- &hir::Expr {
- node: hir::ExprClosure(_, ref decl, id, span, _),
- ..
- }) = node
- {
- let ty_snips = decl.inputs.iter()
- .map(|ty| {
- self.tcx.sess.codemap().span_to_snippet(ty.span).ok()
- .and_then(|snip| {
- // filter out dummy spans
- if snip == "," || snip == "|" {
- None
- } else {
- Some(snip)
- }
- })
- })
- .collect::<Vec<Option<String>>>();
+ .map(|node| self.get_fn_like_arguments(node))
+ .unwrap_or((found_span.unwrap(), found));
- let body = self.tcx.hir.body(id);
- let pat_snips = body.arguments.iter()
- .map(|arg|
- self.tcx.sess.codemap().span_to_snippet(arg.pat.span).ok())
- .collect::<Option<Vec<String>>>();
-
- Some((span, pat_snips, ty_snips))
- } else {
- None
- }
- })
- .map(|(span, pat, ty)| (Some(span), Some((pat, ty))))
- .unwrap_or((None, None));
- let closure_args = closure_args.and_then(|(pat, ty)| Some((pat?, ty)));
-
- self.report_arg_count_mismatch(
- span,
- closure_span.or(found_span),
- expected_ty_count,
- expected_tuple,
- found_ty_count,
- closure_args,
- found_trait_ty.is_closure()
- )
+ self.report_arg_count_mismatch(span,
+ closure_span,
+ expected,
+ found,
+ found_trait_ty.is_closure())
}
}
@@ -845,94 +792,135 @@
}
}
+ fn get_fn_like_arguments(&self, node: hir::map::Node) -> (Span, Vec<ArgKind>) {
+ if let hir::map::NodeExpr(&hir::Expr {
+ node: hir::ExprClosure(_, ref _decl, id, span, _),
+ ..
+ }) = node {
+ (self.tcx.sess.codemap().def_span(span), self.tcx.hir.body(id).arguments.iter()
+ .map(|arg| {
+ if let hir::Pat {
+ node: hir::PatKind::Tuple(args, _),
+ span,
+ ..
+ } = arg.pat.clone().into_inner() {
+ ArgKind::Tuple(
+ span,
+ args.iter().map(|pat| {
+ let snippet = self.tcx.sess.codemap()
+ .span_to_snippet(pat.span).unwrap();
+ (snippet, "_".to_owned())
+ }).collect::<Vec<_>>(),
+ )
+ } else {
+ let name = self.tcx.sess.codemap().span_to_snippet(arg.pat.span).unwrap();
+ ArgKind::Arg(name, "_".to_owned())
+ }
+ })
+ .collect::<Vec<ArgKind>>())
+ } else if let hir::map::NodeItem(&hir::Item {
+ span,
+ node: hir::ItemFn(ref decl, ..),
+ ..
+ }) = node {
+ (self.tcx.sess.codemap().def_span(span), decl.inputs.iter()
+ .map(|arg| match arg.clone().into_inner().node {
+ hir::TyTup(ref tys) => ArgKind::Tuple(
+ arg.span,
+ tys.iter()
+ .map(|_| ("_".to_owned(), "_".to_owned()))
+ .collect::<Vec<_>>(),
+ ),
+ _ => ArgKind::Arg("_".to_owned(), "_".to_owned())
+ }).collect::<Vec<ArgKind>>())
+ } else {
+ panic!("non-FnLike node found: {:?}", node);
+ }
+ }
+
fn report_arg_count_mismatch(
&self,
span: Span,
- found_span: Option<Span>,
- expected: usize,
- expected_tuple: Option<usize>,
- found: usize,
- closure_args: Option<(Vec<String>, Vec<Option<String>>)>,
- is_closure: bool
+ found_span: Span,
+ expected_args: Vec<ArgKind>,
+ found_args: Vec<ArgKind>,
+ is_closure: bool,
) -> DiagnosticBuilder<'tcx> {
- use std::borrow::Cow;
-
let kind = if is_closure { "closure" } else { "function" };
- let args_str = |n, distinct| format!(
- "{} {}argument{}",
- n,
- if distinct && n >= 2 { "distinct " } else { "" },
- if n == 1 { "" } else { "s" },
- );
-
- let expected_str = if let Some(n) = expected_tuple {
- assert!(expected == 1);
- if closure_args.as_ref().map(|&(ref pats, _)| pats.len()) == Some(n) {
- Cow::from("a single tuple as argument")
- } else {
- // be verbose when numbers differ
- Cow::from(format!("a single {}-tuple as argument", n))
+ let args_str = |arguments: &Vec<ArgKind>, other: &Vec<ArgKind>| {
+ let arg_length = arguments.len();
+ let distinct = match &other[..] {
+ &[ArgKind::Tuple(..)] => true,
+ _ => false,
+ };
+ match (arg_length, arguments.get(0)) {
+ (1, Some(&ArgKind::Tuple(_, ref fields))) => {
+ format!("a single {}-tuple as argument", fields.len())
+ }
+ _ => format!("{} {}argument{}",
+ arg_length,
+ if distinct && arg_length > 1 { "distinct " } else { "" },
+ if arg_length == 1 { "" } else { "s" }),
}
- } else {
- Cow::from(args_str(expected, false))
};
- let found_str = if expected_tuple.is_some() {
- args_str(found, true)
- } else {
- args_str(found, false)
- };
+ let expected_str = args_str(&expected_args, &found_args);
+ let found_str = args_str(&found_args, &expected_args);
-
- let mut err = struct_span_err!(self.tcx.sess, span, E0593,
+ let mut err = struct_span_err!(
+ self.tcx.sess,
+ span,
+ E0593,
"{} is expected to take {}, but it takes {}",
kind,
expected_str,
found_str,
);
- err.span_label(
- span,
- format!(
- "expected {} that takes {}",
- kind,
- expected_str,
- )
- );
+ err.span_label(span, format!( "expected {} that takes {}", kind, expected_str));
+ err.span_label(found_span, format!("takes {}", found_str));
- if let Some(span) = found_span {
- if let (Some(expected_tuple), Some((pats, tys))) = (expected_tuple, closure_args) {
- if expected_tuple != found || pats.len() != found {
- err.span_label(span, format!("takes {}", found_str));
- } else {
- let sugg = format!(
- "|({}){}|",
- pats.join(", "),
-
- // add type annotations if available
- if tys.iter().any(|ty| ty.is_some()) {
- Cow::from(format!(
- ": ({})",
- tys.into_iter().map(|ty| if let Some(ty) = ty {
- ty
- } else {
- "_".to_string()
- }).collect::<Vec<String>>().join(", ")
- ))
- } else {
- Cow::from("")
- },
- );
-
- err.span_suggestion(
- span,
- "consider changing the closure to accept a tuple",
- sugg
- );
- }
- } else {
- err.span_label(span, format!("takes {}", found_str));
+ if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] {
+ if fields.len() == expected_args.len() {
+ let sugg = fields.iter()
+ .map(|(name, _)| name.to_owned())
+ .collect::<Vec<String>>().join(", ");
+ err.span_suggestion(found_span,
+ "change the closure to take multiple arguments instead of \
+ a single tuple",
+ format!("|{}|", sugg));
+ }
+ }
+ if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
+ if fields.len() == found_args.len() && is_closure {
+ let sugg = format!(
+ "|({}){}|",
+ found_args.iter()
+ .map(|arg| match arg {
+ ArgKind::Arg(name, _) => name.to_owned(),
+ _ => "_".to_owned(),
+ })
+ .collect::<Vec<String>>()
+ .join(", "),
+ // add type annotations if available
+ if found_args.iter().any(|arg| match arg {
+ ArgKind::Arg(_, ty) => ty != "_",
+ _ => false,
+ }) {
+ format!(": ({})",
+ fields.iter()
+ .map(|(_, ty)| ty.to_owned())
+ .collect::<Vec<String>>()
+ .join(", "))
+ } else {
+ "".to_owned()
+ },
+ );
+ err.span_suggestion(found_span,
+ "change the closure to accept a tuple instead of individual \
+ arguments",
+ sugg);
}
}
@@ -1331,3 +1319,14 @@
suggested_limit));
}
}
+
+enum ArgKind {
+ Arg(String, String),
+ Tuple(Span, Vec<(String, String)>),
+}
+
+impl ArgKind {
+ fn empty() -> ArgKind {
+ ArgKind::Arg("_".to_owned(), "_".to_owned())
+ }
+}
diff --git a/src/librustc_apfloat/ieee.rs b/src/librustc_apfloat/ieee.rs
index 3e76b60..7abd02b 100644
--- a/src/librustc_apfloat/ieee.rs
+++ b/src/librustc_apfloat/ieee.rs
@@ -1434,7 +1434,7 @@
let max_change = S::MAX_EXP as i32 - (S::MIN_EXP as i32 - sig_bits) + 1;
// Clamp to one past the range ends to let normalize handle overflow.
- let exp_change = cmp::min(cmp::max(exp as i32, (-max_change - 1)), max_change);
+ let exp_change = cmp::min(cmp::max(exp as i32, -max_change - 1), max_change);
self.exp = self.exp.saturating_add(exp_change as ExpInt);
self = self.normalize(round, Loss::ExactlyZero).value;
if self.is_nan() {
diff --git a/src/librustc_back/target/aarch64_unknown_cloudabi.rs b/src/librustc_back/target/aarch64_unknown_cloudabi.rs
index d5e8194..59c82e0 100644
--- a/src/librustc_back/target/aarch64_unknown_cloudabi.rs
+++ b/src/librustc_back/target/aarch64_unknown_cloudabi.rs
@@ -15,6 +15,7 @@
let mut base = super::cloudabi_base::opts();
base.max_atomic_width = Some(128);
base.abi_blacklist = super::arm_base::abi_blacklist();
+ base.linker = "aarch64-unknown-cloudabi-cc".to_string();
Ok(Target {
llvm_target: "aarch64-unknown-cloudabi".to_string(),
diff --git a/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs b/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs
index 4dad8e1..faa2c4f 100644
--- a/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs
+++ b/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs
@@ -17,6 +17,7 @@
base.max_atomic_width = Some(64);
base.features = "+v7,+vfp3,+neon".to_string();
base.abi_blacklist = super::arm_base::abi_blacklist();
+ base.linker = "armv7-unknown-cloudabi-eabihf-cc".to_string();
Ok(Target {
llvm_target: "armv7-unknown-cloudabi-eabihf".to_string(),
diff --git a/src/librustc_back/target/i686_unknown_cloudabi.rs b/src/librustc_back/target/i686_unknown_cloudabi.rs
index b9aa617..e244f44 100644
--- a/src/librustc_back/target/i686_unknown_cloudabi.rs
+++ b/src/librustc_back/target/i686_unknown_cloudabi.rs
@@ -15,6 +15,7 @@
let mut base = super::cloudabi_base::opts();
base.cpu = "pentium4".to_string();
base.max_atomic_width = Some(64);
+ base.linker = "i686-unknown-cloudabi-cc".to_string();
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
base.stack_probes = true;
diff --git a/src/librustc_back/target/x86_64_unknown_cloudabi.rs b/src/librustc_back/target/x86_64_unknown_cloudabi.rs
index f9a5631..1ce3c64 100644
--- a/src/librustc_back/target/x86_64_unknown_cloudabi.rs
+++ b/src/librustc_back/target/x86_64_unknown_cloudabi.rs
@@ -15,6 +15,7 @@
let mut base = super::cloudabi_base::opts();
base.cpu = "x86-64".to_string();
base.max_atomic_width = Some(64);
+ base.linker = "x86_64-unknown-cloudabi-cc".to_string();
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
base.stack_probes = true;
diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs
index 57fc78e..511c407 100644
--- a/src/librustc_data_structures/array_vec.rs
+++ b/src/librustc_data_structures/array_vec.rs
@@ -12,7 +12,7 @@
use std::marker::Unsize;
use std::iter::Extend;
-use std::ptr::{self, drop_in_place, Shared};
+use std::ptr::{self, drop_in_place, NonNull};
use std::ops::{Deref, DerefMut, Range};
use std::hash::{Hash, Hasher};
use std::slice;
@@ -146,7 +146,7 @@
tail_start: end,
tail_len: len - end,
iter: range_slice.iter(),
- array_vec: Shared::from(self),
+ array_vec: NonNull::from(self),
}
}
}
@@ -232,7 +232,7 @@
tail_start: usize,
tail_len: usize,
iter: slice::Iter<'a, ManuallyDrop<A::Element>>,
- array_vec: Shared<ArrayVec<A>>,
+ array_vec: NonNull<ArrayVec<A>>,
}
impl<'a, A: Array> Iterator for Drain<'a, A> {
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 24048e6..a35ef2f 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -21,7 +21,6 @@
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![deny(warnings)]
-#![feature(shared)]
#![feature(collections_range)]
#![feature(nonzero)]
#![feature(unboxed_closures)]
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 4e066ec..ef6475f 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -302,6 +302,18 @@
Assign(_, ref value) => (value, "assigned value", false),
AssignOp(.., ref value) => (value, "assigned value", false),
InPlace(_, ref value) => (value, "emplacement value", false),
+ Call(_, ref args) => {
+ for arg in args {
+ self.check_unused_parens_core(cx, arg, "function argument", false)
+ }
+ return;
+ },
+ MethodCall(_, ref args) => {
+ for arg in &args[1..] { // first "argument" is self (which sometimes needs parens)
+ self.check_unused_parens_core(cx, arg, "method argument", false)
+ }
+ return;
+ }
_ => return,
};
self.check_unused_parens_core(cx, &value, msg, struct_lit_needs_parens);
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index 45604d5..7703235 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -584,13 +584,9 @@
DefiningTy::FnDef(_, substs) => substs,
- // When we encounter other sorts of constant
- // expressions, such as the `22` in `[foo; 22]`, we can
- // get the type `usize` here. For now, just return an
- // empty vector of substs in this case, since there are no
- // generics in scope in such expressions right now.
+ // When we encounter a constant body, just return whatever
+ // substitutions are in scope for that constant.
DefiningTy::Const(_) => {
- assert!(identity_substs.is_empty());
identity_substs
}
};
@@ -654,9 +650,8 @@
sig.inputs_and_output()
}
- // This happens on things like `[foo; 22]`. Hence, no
- // inputs, one output, but it seems like we need a more
- // general way to handle this category of MIR.
+ // For a constant body, there are no inputs, and one
+ // "output" (the type of the constant).
DefiningTy::Const(ty) => ty::Binder::dummy(tcx.mk_type_list(iter::once(ty))),
}
}
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index f76aea1..f543a33 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -131,7 +131,7 @@
}
impl ReserveOrActivateIndex {
- fn reserved(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new((i.index() * 2)) }
+ fn reserved(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new(i.index() * 2) }
fn active(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new((i.index() * 2) + 1) }
pub(crate) fn is_reservation(self) -> bool { self.index() % 2 == 0 }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 5b9b376..231a32c 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -963,7 +963,7 @@
unresolved_invocations: RefCell::new(FxHashSet()),
no_implicit_prelude: false,
glob_importers: RefCell::new(Vec::new()),
- globs: RefCell::new((Vec::new())),
+ globs: RefCell::new(Vec::new()),
traits: RefCell::new(None),
populated: Cell::new(normal_ancestor_id.is_local()),
span,
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 61de5f4..3a18c6b 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -94,20 +94,22 @@
<h2>Keyboard Shortcuts</h2>
<dl>
- <dt>?</dt>
+ <dt><kbd>?</kbd></dt>
<dd>Show this help dialog</dd>
- <dt>S</dt>
+ <dt><kbd>S</kbd></dt>
<dd>Focus the search field</dd>
- <dt>↑</dt>
+ <dt><kbd>↑</kbd></dt>
<dd>Move up in search results</dd>
- <dt>↓</dt>
+ <dt><kbd>↓</kbd></dt>
<dd>Move down in search results</dd>
- <dt>↹</dt>
+ <dt><kbd>↹</kbd></dt>
<dd>Switch tab</dd>
- <dt>⏎</dt>
+ <dt><kbd>⏎</kbd></dt>
<dd>Go to active search result</dd>
- <dt style="width:31px;">+ / -</dt>
- <dd>Collapse/expand all sections</dd>
+ <dt><kbd>+</kbd></dt>
+ <dd>Expand all sections</dd>
+ <dt><kbd>-</kbd></dt>
+ <dd>Collapse all sections</dd>
</dl>
</div>
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index b41874a..34b04de 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -585,18 +585,13 @@
flex: 0 0 auto;
box-shadow: 0 0 6px rgba(0,0,0,.2);
width: 550px;
- height: 354px;
+ height: auto;
border: 1px solid;
}
#help dt {
float: left;
- border-radius: 4px;
- border: 1px solid;
- width: 23px;
- text-align: center;
clear: left;
display: block;
- margin-top: -1px;
}
#help dd { margin: 5px 35px; }
#help .infos { padding-left: 0; }
@@ -1134,3 +1129,14 @@
left: -42px;
margin-top: 2px;
}
+
+kbd {
+ display: inline-block;
+ padding: 3px 5px;
+ font: 15px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ line-height: 10px;
+ vertical-align: middle;
+ border: solid 1px;
+ border-radius: 3px;
+ box-shadow: inset 0 -1px 0;
+}
diff --git a/src/librustdoc/html/static/styles/main.css b/src/librustdoc/html/static/styles/main.css
index c79413c..bd74056 100644
--- a/src/librustdoc/html/static/styles/main.css
+++ b/src/librustdoc/html/static/styles/main.css
@@ -194,11 +194,6 @@
border-color: #bfbfbf;
}
-#help dt {
- border-color: #bfbfbf;
- background: #fff;
-}
-
.since {
color: grey;
}
@@ -348,3 +343,11 @@
border-bottom-color: #e0e0e0;
}
}
+
+kbd {
+ color: #444d56;
+ background-color: #fafbfc;
+ border-color: #d1d5da;
+ border-bottom-color: #c6cbd1;
+ box-shadow-color: #c6cbd1;
+}
diff --git a/src/libserialize/leb128.rs b/src/libserialize/leb128.rs
index a963871..1786e29 100644
--- a/src/libserialize/leb128.rs
+++ b/src/libserialize/leb128.rs
@@ -9,7 +9,7 @@
// except according to those terms.
#[inline]
-fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) {
+pub fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) {
if position == vec.len() {
vec.push(byte);
} else {
@@ -17,57 +17,87 @@
}
}
-#[inline]
-/// encodes an integer using unsigned leb128 encoding and stores
-/// the result using a callback function.
-///
-/// The callback `write` is called once for each position
-/// that is to be written to with the byte to be encoded
-/// at that position.
-pub fn write_unsigned_leb128_to<W>(mut value: u128, mut write: W) -> usize
- where W: FnMut(usize, u8)
-{
- let mut position = 0;
- loop {
- let mut byte = (value & 0x7F) as u8;
- value >>= 7;
- if value != 0 {
- byte |= 0x80;
- }
+#[cfg(target_pointer_width = "32")]
+const USIZE_LEB128_SIZE: usize = 5;
+#[cfg(target_pointer_width = "64")]
+const USIZE_LEB128_SIZE: usize = 10;
- write(position, byte);
- position += 1;
-
- if value == 0 {
- break;
- }
- }
-
- position
+macro_rules! leb128_size {
+ (u16) => (3);
+ (u32) => (5);
+ (u64) => (10);
+ (u128) => (19);
+ (usize) => (USIZE_LEB128_SIZE);
}
-pub fn write_unsigned_leb128(out: &mut Vec<u8>, start_position: usize, value: u128) -> usize {
- write_unsigned_leb128_to(value, |i, v| write_to_vec(out, start_position+i, v))
-}
+macro_rules! impl_write_unsigned_leb128 {
+ ($fn_name:ident, $int_ty:ident) => (
+ #[inline]
+ pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) -> usize {
+ let mut position = start_position;
+ for _ in 0 .. leb128_size!($int_ty) {
+ let mut byte = (value & 0x7F) as u8;
+ value >>= 7;
+ if value != 0 {
+ byte |= 0x80;
+ }
-#[inline]
-pub fn read_unsigned_leb128(data: &[u8], start_position: usize) -> (u128, usize) {
- let mut result = 0;
- let mut shift = 0;
- let mut position = start_position;
- loop {
- let byte = data[position];
- position += 1;
- result |= ((byte & 0x7F) as u128) << shift;
- if (byte & 0x80) == 0 {
- break;
+ write_to_vec(out, position, byte);
+ position += 1;
+
+ if value == 0 {
+ break;
+ }
+ }
+
+ position - start_position
}
- shift += 7;
- }
-
- (result, position - start_position)
+ )
}
+impl_write_unsigned_leb128!(write_u16_leb128, u16);
+impl_write_unsigned_leb128!(write_u32_leb128, u32);
+impl_write_unsigned_leb128!(write_u64_leb128, u64);
+impl_write_unsigned_leb128!(write_u128_leb128, u128);
+impl_write_unsigned_leb128!(write_usize_leb128, usize);
+
+
+macro_rules! impl_read_unsigned_leb128 {
+ ($fn_name:ident, $int_ty:ident) => (
+ #[inline]
+ pub fn $fn_name(slice: &[u8]) -> ($int_ty, usize) {
+ let mut result: $int_ty = 0;
+ let mut shift = 0;
+ let mut position = 0;
+
+ for _ in 0 .. leb128_size!($int_ty) {
+ let byte = unsafe {
+ *slice.get_unchecked(position)
+ };
+ position += 1;
+ result |= ((byte & 0x7F) as $int_ty) << shift;
+ if (byte & 0x80) == 0 {
+ break;
+ }
+ shift += 7;
+ }
+
+ // Do a single bounds check at the end instead of for every byte.
+ assert!(position <= slice.len());
+
+ (result, position)
+ }
+ )
+}
+
+impl_read_unsigned_leb128!(read_u16_leb128, u16);
+impl_read_unsigned_leb128!(read_u32_leb128, u32);
+impl_read_unsigned_leb128!(read_u64_leb128, u64);
+impl_read_unsigned_leb128!(read_u128_leb128, u128);
+impl_read_unsigned_leb128!(read_usize_leb128, usize);
+
+
+
#[inline]
/// encodes an integer using signed leb128 encoding and stores
/// the result using a callback function.
@@ -130,26 +160,36 @@
(result, position - start_position)
}
-#[test]
-fn test_unsigned_leb128() {
- let mut stream = Vec::with_capacity(10000);
+macro_rules! impl_test_unsigned_leb128 {
+ ($test_name:ident, $write_fn_name:ident, $read_fn_name:ident, $int_ty:ident) => (
+ #[test]
+ fn $test_name() {
+ let mut stream = Vec::new();
- for x in 0..62 {
- let pos = stream.len();
- let bytes_written = write_unsigned_leb128(&mut stream, pos, 3 << x);
- assert_eq!(stream.len(), pos + bytes_written);
- }
+ for x in 0..62 {
+ let pos = stream.len();
+ let bytes_written = $write_fn_name(&mut stream, pos, (3u64 << x) as $int_ty);
+ assert_eq!(stream.len(), pos + bytes_written);
+ }
- let mut position = 0;
- for x in 0..62 {
- let expected = 3 << x;
- let (actual, bytes_read) = read_unsigned_leb128(&stream, position);
- assert_eq!(expected, actual);
- position += bytes_read;
- }
- assert_eq!(stream.len(), position);
+ let mut position = 0;
+ for x in 0..62 {
+ let expected = (3u64 << x) as $int_ty;
+ let (actual, bytes_read) = $read_fn_name(&stream[position ..]);
+ assert_eq!(expected, actual);
+ position += bytes_read;
+ }
+ assert_eq!(stream.len(), position);
+ }
+ )
}
+impl_test_unsigned_leb128!(test_u16_leb128, write_u16_leb128, read_u16_leb128, u16);
+impl_test_unsigned_leb128!(test_u32_leb128, write_u32_leb128, read_u32_leb128, u32);
+impl_test_unsigned_leb128!(test_u64_leb128, write_u64_leb128, read_u64_leb128, u64);
+impl_test_unsigned_leb128!(test_u128_leb128, write_u128_leb128, read_u128_leb128, u128);
+impl_test_unsigned_leb128!(test_usize_leb128, write_usize_leb128, read_usize_leb128, usize);
+
#[test]
fn test_signed_leb128() {
let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect();
diff --git a/src/libserialize/opaque.rs b/src/libserialize/opaque.rs
index 4093661..077efad 100644
--- a/src/libserialize/opaque.rs
+++ b/src/libserialize/opaque.rs
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use leb128::{read_signed_leb128, read_unsigned_leb128, write_signed_leb128, write_unsigned_leb128};
+use leb128::{self, read_signed_leb128, write_signed_leb128};
use std::borrow::Cow;
use std::io::{self, Write};
use serialize;
@@ -35,9 +35,9 @@
macro_rules! write_uleb128 {
- ($enc:expr, $value:expr) => {{
+ ($enc:expr, $value:expr, $fun:ident) => {{
let pos = $enc.cursor.position() as usize;
- let bytes_written = write_unsigned_leb128($enc.cursor.get_mut(), pos, $value as u128);
+ let bytes_written = leb128::$fun($enc.cursor.get_mut(), pos, $value);
$enc.cursor.set_position((pos + bytes_written) as u64);
Ok(())
}}
@@ -55,61 +55,76 @@
impl<'a> serialize::Encoder for Encoder<'a> {
type Error = io::Error;
+ #[inline]
fn emit_nil(&mut self) -> EncodeResult {
Ok(())
}
+ #[inline]
fn emit_usize(&mut self, v: usize) -> EncodeResult {
- write_uleb128!(self, v)
+ write_uleb128!(self, v, write_usize_leb128)
}
+ #[inline]
fn emit_u128(&mut self, v: u128) -> EncodeResult {
- write_uleb128!(self, v)
+ write_uleb128!(self, v, write_u128_leb128)
}
+ #[inline]
fn emit_u64(&mut self, v: u64) -> EncodeResult {
- write_uleb128!(self, v)
+ write_uleb128!(self, v, write_u64_leb128)
}
+ #[inline]
fn emit_u32(&mut self, v: u32) -> EncodeResult {
- write_uleb128!(self, v)
+ write_uleb128!(self, v, write_u32_leb128)
}
+ #[inline]
fn emit_u16(&mut self, v: u16) -> EncodeResult {
- write_uleb128!(self, v)
+ write_uleb128!(self, v, write_u16_leb128)
}
+ #[inline]
fn emit_u8(&mut self, v: u8) -> EncodeResult {
- let _ = self.cursor.write_all(&[v]);
+ let pos = self.cursor.position() as usize;
+ leb128::write_to_vec(self.cursor.get_mut(), pos, v);
+ self.cursor.set_position((pos + 1) as u64);
Ok(())
}
+ #[inline]
fn emit_isize(&mut self, v: isize) -> EncodeResult {
write_sleb128!(self, v)
}
+ #[inline]
fn emit_i128(&mut self, v: i128) -> EncodeResult {
write_sleb128!(self, v)
}
+ #[inline]
fn emit_i64(&mut self, v: i64) -> EncodeResult {
write_sleb128!(self, v)
}
+ #[inline]
fn emit_i32(&mut self, v: i32) -> EncodeResult {
write_sleb128!(self, v)
}
+ #[inline]
fn emit_i16(&mut self, v: i16) -> EncodeResult {
write_sleb128!(self, v)
}
+ #[inline]
fn emit_i8(&mut self, v: i8) -> EncodeResult {
let as_u8: u8 = unsafe { ::std::mem::transmute(v) };
- let _ = self.cursor.write_all(&[as_u8]);
- Ok(())
+ self.emit_u8(as_u8)
}
+ #[inline]
fn emit_bool(&mut self, v: bool) -> EncodeResult {
self.emit_u8(if v {
1
@@ -118,20 +133,24 @@
})
}
+ #[inline]
fn emit_f64(&mut self, v: f64) -> EncodeResult {
let as_u64: u64 = unsafe { ::std::mem::transmute(v) };
self.emit_u64(as_u64)
}
+ #[inline]
fn emit_f32(&mut self, v: f32) -> EncodeResult {
let as_u32: u32 = unsafe { ::std::mem::transmute(v) };
self.emit_u32(as_u32)
}
+ #[inline]
fn emit_char(&mut self, v: char) -> EncodeResult {
self.emit_u32(v as u32)
}
+ #[inline]
fn emit_str(&mut self, v: &str) -> EncodeResult {
self.emit_usize(v.len())?;
let _ = self.cursor.write_all(v.as_bytes());
@@ -140,6 +159,7 @@
}
impl<'a> Encoder<'a> {
+ #[inline]
pub fn position(&self) -> usize {
self.cursor.position() as usize
}
@@ -162,14 +182,17 @@
}
}
+ #[inline]
pub fn position(&self) -> usize {
self.position
}
+ #[inline]
pub fn set_position(&mut self, pos: usize) {
self.position = pos
}
+ #[inline]
pub fn advance(&mut self, bytes: usize) {
self.position += bytes;
}
@@ -187,10 +210,10 @@
}
macro_rules! read_uleb128 {
- ($dec:expr, $t:ty) => ({
- let (value, bytes_read) = read_unsigned_leb128($dec.data, $dec.position);
+ ($dec:expr, $t:ty, $fun:ident) => ({
+ let (value, bytes_read) = leb128::$fun(&$dec.data[$dec.position ..]);
$dec.position += bytes_read;
- Ok(value as $t)
+ Ok(value)
})
}
@@ -213,22 +236,22 @@
#[inline]
fn read_u128(&mut self) -> Result<u128, Self::Error> {
- read_uleb128!(self, u128)
+ read_uleb128!(self, u128, read_u128_leb128)
}
#[inline]
fn read_u64(&mut self) -> Result<u64, Self::Error> {
- read_uleb128!(self, u64)
+ read_uleb128!(self, u64, read_u64_leb128)
}
#[inline]
fn read_u32(&mut self) -> Result<u32, Self::Error> {
- read_uleb128!(self, u32)
+ read_uleb128!(self, u32, read_u32_leb128)
}
#[inline]
fn read_u16(&mut self) -> Result<u16, Self::Error> {
- read_uleb128!(self, u16)
+ read_uleb128!(self, u16, read_u16_leb128)
}
#[inline]
@@ -240,7 +263,7 @@
#[inline]
fn read_usize(&mut self) -> Result<usize, Self::Error> {
- read_uleb128!(self, usize)
+ read_uleb128!(self, usize, read_usize_leb128)
}
#[inline]
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 96f98ef..73bd574 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -16,7 +16,7 @@
use mem::{align_of, size_of, needs_drop};
use mem;
use ops::{Deref, DerefMut};
-use ptr::{self, Unique, Shared};
+use ptr::{self, Unique, NonNull};
use self::BucketState::*;
@@ -873,7 +873,7 @@
elems_left,
marker: marker::PhantomData,
},
- table: Shared::from(self),
+ table: NonNull::from(self),
marker: marker::PhantomData,
}
}
@@ -1020,7 +1020,7 @@
/// Iterator over the entries in a table, clearing the table.
pub struct Drain<'a, K: 'a, V: 'a> {
- table: Shared<RawTable<K, V>>,
+ table: NonNull<RawTable<K, V>>,
iter: RawBuckets<'static, K, V>,
marker: marker::PhantomData<&'a RawTable<K, V>>,
}
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index b8a6a66..e9a150f 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -64,11 +64,11 @@
//! * You want a map, with no extra functionality.
//!
//! ### Use a `BTreeMap` when:
+//! * You want a map sorted by its keys.
+//! * You want to be able to get a range of entries on-demand.
//! * You're interested in what the smallest or largest key-value pair is.
//! * You want to find the largest or smallest key that is smaller or larger
//! than something.
-//! * You want to be able to get all of the entries in order on-demand.
-//! * You want a map sorted by its keys.
//!
//! ### Use the `Set` variant of any of these `Map`s when:
//! * You just want to remember which keys you've seen.
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index bb38fc5..91cc6d2 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -293,11 +293,11 @@
#![feature(placement_in_syntax)]
#![feature(placement_new_protocol)]
#![feature(prelude_import)]
+#![feature(ptr_internals)]
#![feature(rand)]
#![feature(raw)]
#![feature(repr_align)]
#![feature(rustc_attrs)]
-#![feature(shared)]
#![feature(sip_hash_13)]
#![feature(slice_bytes)]
#![feature(slice_concat_ext)]
@@ -315,7 +315,6 @@
#![feature(try_from)]
#![feature(unboxed_closures)]
#![feature(unicode)]
-#![feature(unique)]
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
#![feature(vec_push_all)]
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index 1ca7e66..fa43093 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -12,7 +12,9 @@
use hash;
use io;
use mem;
-use net::{lookup_host, ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr};
+use net::{ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr};
+#[allow(deprecated)]
+use net::lookup_host;
use option;
use sys::net::netc as c;
use sys_common::{FromInner, AsInner, IntoInner};
@@ -845,6 +847,7 @@
}
}
+#[allow(deprecated)]
fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
let ips = lookup_host(s)?;
let v: Vec<_> = ips.map(|mut a| { a.set_port(p); a }).collect();
diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs
index 9fcb93e..eb0e2e1 100644
--- a/src/libstd/net/mod.rs
+++ b/src/libstd/net/mod.rs
@@ -134,12 +134,15 @@
iterator and returning socket \
addresses",
issue = "27705")]
+#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")]
pub struct LookupHost(net_imp::LookupHost);
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
iterator and returning socket \
addresses",
issue = "27705")]
+#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")]
+#[allow(deprecated)]
impl Iterator for LookupHost {
type Item = SocketAddr;
fn next(&mut self) -> Option<SocketAddr> { self.0.next() }
@@ -149,6 +152,8 @@
iterator and returning socket \
addresses",
issue = "27705")]
+#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")]
+#[allow(deprecated)]
impl fmt::Debug for LookupHost {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("LookupHost { .. }")
@@ -181,6 +186,8 @@
iterator and returning socket \
addresses",
issue = "27705")]
+#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")]
+#[allow(deprecated)]
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
net_imp::lookup_host(host).map(LookupHost)
}
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 53c2211..5608760 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -17,7 +17,7 @@
use fmt;
use ops::{Deref, DerefMut};
use panicking;
-use ptr::{Unique, Shared};
+use ptr::{Unique, NonNull};
use rc::Rc;
use sync::{Arc, Mutex, RwLock, atomic};
use thread::Result;
@@ -196,10 +196,10 @@
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Shared<T> {}
+#[stable(feature = "nonnull", since = "1.24.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> UnwindSafe for Mutex<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 7631a9a..ed102c2 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -1869,7 +1869,11 @@
///
/// let path = Path::new("/test/haha/foo.txt");
///
+ /// assert_eq!(path.strip_prefix("/"), Ok(Path::new("test/haha/foo.txt")));
/// assert_eq!(path.strip_prefix("/test"), Ok(Path::new("haha/foo.txt")));
+ /// assert_eq!(path.strip_prefix("/test/"), Ok(Path::new("haha/foo.txt")));
+ /// assert_eq!(path.strip_prefix("/test/haha/foo.txt"), Ok(Path::new("")));
+ /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new("")));
/// assert_eq!(path.strip_prefix("test").is_ok(), false);
/// assert_eq!(path.strip_prefix("/haha").is_ok(), false);
/// ```
@@ -1900,6 +1904,9 @@
/// let path = Path::new("/etc/passwd");
///
/// assert!(path.starts_with("/etc"));
+ /// assert!(path.starts_with("/etc/"));
+ /// assert!(path.starts_with("/etc/passwd"));
+ /// assert!(path.starts_with("/etc/passwd/"));
///
/// assert!(!path.starts_with("/e"));
/// ```
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index cb249af..525882c 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -311,8 +311,8 @@
#[cfg(target_os = "macos")]
pub unsafe fn current() -> Option<usize> {
- Some((libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize -
- libc::pthread_get_stacksize_np(libc::pthread_self())))
+ Some(libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize -
+ libc::pthread_get_stacksize_np(libc::pthread_self()))
}
#[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
diff --git a/src/test/compile-fail/lint-unnecessary-parens.rs b/src/test/compile-fail/lint-unnecessary-parens.rs
index b5eac73..7cd0a6b 100644
--- a/src/test/compile-fail/lint-unnecessary-parens.rs
+++ b/src/test/compile-fail/lint-unnecessary-parens.rs
@@ -13,19 +13,19 @@
#[derive(Eq, PartialEq)]
struct X { y: bool }
impl X {
- fn foo(&self) -> bool { self.y }
+ fn foo(&self, conjunct: bool) -> bool { self.y && conjunct }
}
fn foo() -> isize {
return (1); //~ ERROR unnecessary parentheses around `return` value
}
-fn bar() -> X {
- return (X { y: true }); //~ ERROR unnecessary parentheses around `return` value
+fn bar(y: bool) -> X {
+ return (X { y }); //~ ERROR unnecessary parentheses around `return` value
}
fn main() {
foo();
- bar();
+ bar((true)); //~ ERROR unnecessary parentheses around function argument
if (true) {} //~ ERROR unnecessary parentheses around `if` condition
while (true) {} //~ ERROR unnecessary parentheses around `while` condition
@@ -40,13 +40,15 @@
if (X { y: true } == v) {}
if (X { y: false }.y) {}
- while (X { y: false }.foo()) {}
+ while (X { y: false }.foo(true)) {}
while (true | X { y: false }.y) {}
match (X { y: false }) {
_ => {}
}
+ X { y: false }.foo((true)); //~ ERROR unnecessary parentheses around method argument
+
let mut _a = (0); //~ ERROR unnecessary parentheses around assigned value
_a = (0); //~ ERROR unnecessary parentheses around assigned value
_a += (1); //~ ERROR unnecessary parentheses around assigned value
diff --git a/src/test/run-pass/allocator-alloc-one.rs b/src/test/run-pass/allocator-alloc-one.rs
index 712fa2d..eaa5bc9 100644
--- a/src/test/run-pass/allocator-alloc-one.rs
+++ b/src/test/run-pass/allocator-alloc-one.rs
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(allocator_api, unique)]
+#![feature(allocator_api, nonnull)]
use std::heap::{Heap, Alloc};
diff --git a/src/test/run-pass/issue-23433.rs b/src/test/run-pass/issue-23433.rs
index aa13d6f..7af732f 100644
--- a/src/test/run-pass/issue-23433.rs
+++ b/src/test/run-pass/issue-23433.rs
@@ -10,13 +10,11 @@
// Don't fail if we encounter a NonZero<*T> where T is an unsized type
-#![feature(unique)]
-
-use std::ptr::Unique;
+use std::ptr::NonNull;
fn main() {
let mut a = [0u8; 5];
- let b: Option<Unique<[u8]>> = Some(Unique::from(&mut a));
+ let b: Option<NonNull<[u8]>> = Some(NonNull::from(&mut a));
match b {
Some(_) => println!("Got `Some`"),
None => panic!("Unexpected `None`"),
diff --git a/src/test/run-pass/nll/issue-47153-generic-const.rs b/src/test/run-pass/nll/issue-47153-generic-const.rs
new file mode 100644
index 0000000..9708ca1
--- /dev/null
+++ b/src/test/run-pass/nll/issue-47153-generic-const.rs
@@ -0,0 +1,27 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for #47153: constants in a generic context (such as
+// a trait) used to ICE.
+
+#![feature(nll)]
+#![allow(warnings)]
+
+trait Foo {
+ const B: bool = true;
+}
+
+struct Bar<T> { x: T }
+
+impl<T> Bar<T> {
+ const B: bool = true;
+}
+
+fn main() { }
diff --git a/src/test/run-pass/result-opt-conversions.rs b/src/test/run-pass/result-opt-conversions.rs
new file mode 100644
index 0000000..0f6da00
--- /dev/null
+++ b/src/test/run-pass/result-opt-conversions.rs
@@ -0,0 +1,57 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(transpose_result)]
+
+#[derive(Copy, Clone, Debug, PartialEq)]
+struct BadNumErr;
+
+fn try_num(x: i32) -> Result<i32, BadNumErr> {
+ if x <= 5 {
+ Ok(x + 1)
+ } else {
+ Err(BadNumErr)
+ }
+}
+
+type ResOpt = Result<Option<i32>, BadNumErr>;
+type OptRes = Option<Result<i32, BadNumErr>>;
+
+fn main() {
+ let mut x: ResOpt = Ok(Some(5));
+ let mut y: OptRes = Some(Ok(5));
+ assert_eq!(x, y.transpose());
+ assert_eq!(x.transpose(), y);
+
+ x = Ok(None);
+ y = None;
+ assert_eq!(x, y.transpose());
+ assert_eq!(x.transpose(), y);
+
+ x = Err(BadNumErr);
+ y = Some(Err(BadNumErr));
+ assert_eq!(x, y.transpose());
+ assert_eq!(x.transpose(), y);
+
+ let res: Result<Vec<i32>, BadNumErr> =
+ (0..10)
+ .map(|x| {
+ let y = try_num(x)?;
+ Ok(if y % 2 == 0 {
+ Some(y - 1)
+ } else {
+ None
+ })
+ })
+ .filter_map(Result::transpose)
+ .collect();
+
+ assert_eq!(res, Err(BadNumErr))
+}
diff --git a/src/test/rustdoc-js/from_u.js b/src/test/rustdoc-js/from_u.js
index 920620a..0296788 100644
--- a/src/test/rustdoc-js/from_u.js
+++ b/src/test/rustdoc-js/from_u.js
@@ -15,7 +15,6 @@
{ 'path': 'std::char', 'name': 'from_u32' },
{ 'path': 'std::str', 'name': 'from_utf8' },
{ 'path': 'std::string::String', 'name': 'from_utf8' },
- { 'path': 'std::boxed::Box', 'name': 'from_unique' },
{ 'path': 'std::i32', 'name': 'from_unsigned' },
{ 'path': 'std::i128', 'name': 'from_unsigned' },
],
diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs
index 1ee24e3..96e5201 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.rs
+++ b/src/test/ui/mismatched_types/closure-arg-count.rs
@@ -18,6 +18,8 @@
//~^ ERROR closure is expected to take
[1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
//~^ ERROR closure is expected to take
+ [1, 2, 3].sort_by(|(tuple, tuple2): (usize, _)| panic!());
+ //~^ ERROR closure is expected to take
f(|| panic!());
//~^ ERROR closure is expected to take
@@ -32,6 +34,9 @@
let bar = |i, x, y| i;
let _it = vec![1, 2, 3].into_iter().enumerate().map(bar);
//~^ ERROR closure is expected to take
+ let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
+ //~^ ERROR function is expected to take
}
fn foo() {}
+fn qux(x: usize, y: usize) {}
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index ba25d67..be00ee4 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -14,18 +14,34 @@
| |
| expected closure that takes 2 arguments
-error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument
+error[E0593]: closure is expected to take 2 distinct arguments, but it takes a single 2-tuple as argument
--> $DIR/closure-arg-count.rs:19:15
|
19 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
- | ^^^^^^^ ----------------- takes 1 argument
+ | ^^^^^^^ ----------------- takes a single 2-tuple as argument
| |
- | expected closure that takes 2 arguments
+ | expected closure that takes 2 distinct arguments
+help: change the closure to take multiple arguments instead of a single tuple
+ |
+19 | [1, 2, 3].sort_by(|tuple, tuple2| panic!());
+ | ^^^^^^^^^^^^^^^
+
+error[E0593]: closure is expected to take 2 distinct arguments, but it takes a single 2-tuple as argument
+ --> $DIR/closure-arg-count.rs:21:15
+ |
+21 | [1, 2, 3].sort_by(|(tuple, tuple2): (usize, _)| panic!());
+ | ^^^^^^^ ----------------------------- takes a single 2-tuple as argument
+ | |
+ | expected closure that takes 2 distinct arguments
+help: change the closure to take multiple arguments instead of a single tuple
+ |
+21 | [1, 2, 3].sort_by(|tuple, tuple2| panic!());
+ | ^^^^^^^^^^^^^^^
error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
- --> $DIR/closure-arg-count.rs:21:5
+ --> $DIR/closure-arg-count.rs:23:5
|
-21 | f(|| panic!());
+23 | f(|| panic!());
| ^ -- takes 0 arguments
| |
| expected closure that takes 1 argument
@@ -36,46 +52,63 @@
13 | fn f<F: Fn<usize>>(_: F) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments
- --> $DIR/closure-arg-count.rs:24:53
- |
-24 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i);
- | ^^^ ------ help: consider changing the closure to accept a tuple: `|(i, x)|`
- | |
- | expected closure that takes a single tuple as argument
-
-error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments
+error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
--> $DIR/closure-arg-count.rs:26:53
|
-26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i);
- | ^^^ ------------- help: consider changing the closure to accept a tuple: `|(i, x): (usize, _)|`
+26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i);
+ | ^^^ ------ takes 2 distinct arguments
| |
- | expected closure that takes a single tuple as argument
+ | expected closure that takes a single 2-tuple as argument
+help: change the closure to accept a tuple instead of individual arguments
+ |
+26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i);
+ | ^^^^^^^^
-error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments
+error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
--> $DIR/closure-arg-count.rs:28:53
|
-28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i);
+28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i);
+ | ^^^ ------------- takes 2 distinct arguments
+ | |
+ | expected closure that takes a single 2-tuple as argument
+help: change the closure to accept a tuple instead of individual arguments
+ |
+28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i);
+ | ^^^^^^^^
+
+error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments
+ --> $DIR/closure-arg-count.rs:30:53
+ |
+30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i);
| ^^^ --------- takes 3 distinct arguments
| |
| expected closure that takes a single 2-tuple as argument
error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments
- --> $DIR/closure-arg-count.rs:30:53
+ --> $DIR/closure-arg-count.rs:32:53
|
-30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
+32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
| ^^^ expected function that takes a single 2-tuple as argument
...
-37 | fn foo() {}
+41 | fn foo() {}
| -------- takes 0 arguments
error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments
- --> $DIR/closure-arg-count.rs:33:53
+ --> $DIR/closure-arg-count.rs:35:53
|
-32 | let bar = |i, x, y| i;
+34 | let bar = |i, x, y| i;
| --------- takes 3 distinct arguments
-33 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar);
+35 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar);
| ^^^ expected closure that takes a single 2-tuple as argument
-error: aborting due to 9 previous errors
+error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
+ --> $DIR/closure-arg-count.rs:37:53
+ |
+37 | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
+ | ^^^ expected function that takes a single 2-tuple as argument
+...
+42 | fn qux(x: usize, y: usize) {}
+ | -------------------------- takes 2 distinct arguments
+
+error: aborting due to 11 previous errors
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 61d7198..eee2902 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -69,6 +69,7 @@
"src/tools/miri",
"src/librustc/mir/interpret",
"src/librustc_mir/interpret",
+ "src/target",
];
skip.iter().any(|p| path.ends_with(p))
}