Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 11 pull requests #37416

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
88b031e
save-analysis: dump data only if get_path_data doesn't fail to resolv…
eulerdisk Oct 13, 2016
4a93648
Support `use *;` and `use ::*;`.
jseyfried Oct 23, 2016
592d7bf
Add support for kernel randomness for Fuchsia
raphlinus Oct 24, 2016
c4651db
Support for aarch64 architecture on Fuchsia
raphlinus Oct 24, 2016
4bb6d4e
rustc_typeck: Allow reification from fn item to unsafe ptr
cramertj Oct 25, 2016
ab6119a
Fix coercin -> coercion typo
cramertj Oct 25, 2016
0a16a11
Use `SmallVector` for the stack in `macro_parser::parse`.
nnethercote Oct 21, 2016
3fd90d8
Use `SmallVector` for `TtReader::stack`.
nnethercote Oct 21, 2016
c440a7a
Don't use `Rc` in `TokenTreeOrTokenTreeVec`.
nnethercote Oct 21, 2016
15a9586
Special case .fold() for VecDeque's iterators
bluss Oct 25, 2016
780acda
iter: Implement .fold() for .cloned() and .map()
bluss Oct 25, 2016
b3e8c4c
Print out the error when HeapFree failures do occur
retep998 Oct 25, 2016
892a05d
run rustfmt on librustc_metadata folder
srinivasreddy Oct 22, 2016
09227b1
Vec docs: fix broken links and make quoting consistent
Oct 25, 2016
82d4200
Prohibit patterns in trait methods without bodies
petrochenkov Oct 22, 2016
a16626f
iter: Implement .fold() for .chain()
bluss Oct 25, 2016
1802610
Rollup merge of #37144 - eulerdisk:fix_37126, r=nrc
Manishearth Oct 26, 2016
e2bee0f
Rollup merge of #37315 - bluss:fold-more, r=alexcrichton
Manishearth Oct 26, 2016
5bc5647
Rollup merge of #37350 - srinivasreddy:meta_2, r=nrc
Manishearth Oct 26, 2016
9de7de8
Rollup merge of #37367 - jseyfried:import_crate_root, r=nrc
Manishearth Oct 26, 2016
f3882b0
Rollup merge of #37373 - nnethercote:html5ever-more-more, r=nrc
Manishearth Oct 26, 2016
f8d0a1f
Rollup merge of #37378 - petrochenkov:nopat, r=eddyb
Manishearth Oct 26, 2016
8b212e3
Rollup merge of #37385 - raphlinus:fuchsia_random, r=alexcrichton
Manishearth Oct 26, 2016
3fbfde5
Rollup merge of #37387 - raphlinus:fuchsia_aarch64, r=alexcrichton
Manishearth Oct 26, 2016
43a3a56
Rollup merge of #37389 - cramertj:cramertj/fn-item-to-unsafe-ptr, r=e…
Manishearth Oct 26, 2016
960f73b
Rollup merge of #37391 - vtduncan:vec-docs, r=GuillaumeGomez
Manishearth Oct 26, 2016
366d139
Rollup merge of #37399 - retep998:heap-of-trouble, r=alexcrichton
Manishearth Oct 26, 2016
d230a7e
Remove duplicate error code (fixup #37378)
Manishearth Oct 26, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mk/cfg/aarch64-unknown-fuchsia.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# rustbuild-only target
6 changes: 3 additions & 3 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -4023,9 +4023,9 @@ Methods that take either `self` or `Box<Self>` can optionally place them in a
mutable variable by prefixing them with `mut` (similar to regular arguments):

```
trait Changer {
fn change(mut self) -> Self;
fn modify(mut self: Box<Self>) -> Box<Self>;
trait Changer: Sized {
fn change(mut self) {}
fn modify(mut self: Box<Self>) {}
}
```

Expand Down
5 changes: 3 additions & 2 deletions src/liballoc_system/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ mod imp {
fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
fn GetLastError() -> DWORD;
}

#[repr(C)]
Expand Down Expand Up @@ -230,11 +231,11 @@ mod imp {
pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {
if align <= MIN_ALIGN {
let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
debug_assert!(err != 0);
debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError());
} else {
let header = get_header(ptr);
let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
debug_assert!(err != 0);
debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError());
}
}

Expand Down
44 changes: 22 additions & 22 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ use super::range::RangeArgument;
/// # Slicing
///
/// A `Vec` can be mutable. Slices, on the other hand, are read-only objects.
/// To get a slice, use "&". Example:
/// To get a slice, use `&`. Example:
///
/// ```
/// fn read_slice(slice: &[usize]) {
Expand Down Expand Up @@ -203,33 +203,33 @@ use super::range::RangeArgument;
///
/// # Guarantees
///
/// Due to its incredibly fundamental nature, Vec makes a lot of guarantees
/// Due to its incredibly fundamental nature, `Vec` makes a lot of guarantees
/// about its design. This ensures that it's as low-overhead as possible in
/// the general case, and can be correctly manipulated in primitive ways
/// by unsafe code. Note that these guarantees refer to an unqualified `Vec<T>`.
/// If additional type parameters are added (e.g. to support custom allocators),
/// overriding their defaults may change the behavior.
///
/// Most fundamentally, Vec is and always will be a (pointer, capacity, length)
/// Most fundamentally, `Vec` is and always will be a (pointer, capacity, length)
/// triplet. No more, no less. The order of these fields is completely
/// unspecified, and you should use the appropriate methods to modify these.
/// The pointer will never be null, so this type is null-pointer-optimized.
///
/// However, the pointer may not actually point to allocated memory. In particular,
/// if you construct a Vec with capacity 0 via [`Vec::new()`], [`vec![]`][`vec!`],
/// if you construct a `Vec` with capacity 0 via [`Vec::new()`], [`vec![]`][`vec!`],
/// [`Vec::with_capacity(0)`][`Vec::with_capacity`], or by calling [`shrink_to_fit()`]
/// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized
/// types inside a `Vec`, it will not allocate space for them. *Note that in this case
/// the `Vec` may not report a [`capacity()`] of 0*. Vec will allocate if and only
/// the `Vec` may not report a [`capacity()`] of 0*. `Vec` will allocate if and only
/// if [`mem::size_of::<T>()`]` * capacity() > 0`. In general, `Vec`'s allocation
/// details are subtle enough that it is strongly recommended that you only
/// free memory allocated by a Vec by creating a new Vec and dropping it.
/// free memory allocated by a `Vec` by creating a new `Vec` and dropping it.
///
/// If a `Vec` *has* allocated memory, then the memory it points to is on the heap
/// (as defined by the allocator Rust is configured to use by default), and its
/// pointer points to [`len()`] initialized elements in order (what you would see
/// if you coerced it to a slice), followed by `[capacity()][`capacity()`] -
/// [len()][`len()`]` logically uninitialized elements.
/// if you coerced it to a slice), followed by [`capacity()`]` - `[`len()`]
/// logically uninitialized elements.
///
/// `Vec` will never perform a "small optimization" where elements are actually
/// stored on the stack for two reasons:
Expand All @@ -249,8 +249,8 @@ use super::range::RangeArgument;
/// [`shrink_to_fit`][`shrink_to_fit()`].
///
/// [`push`] and [`insert`] will never (re)allocate if the reported capacity is
/// sufficient. [`push`] and [`insert`] *will* (re)allocate if `[len()][`len()`]
/// == [capacity()][`capacity()`]`. That is, the reported capacity is completely
/// sufficient. [`push`] and [`insert`] *will* (re)allocate if
/// [`len()`]` == `[`capacity()`]. That is, the reported capacity is completely
/// accurate, and can be relied on. It can even be used to manually free the memory
/// allocated by a `Vec` if desired. Bulk insertion methods *may* reallocate, even
/// when not necessary.
Expand All @@ -261,11 +261,10 @@ use super::range::RangeArgument;
/// strategy is used will of course guarantee `O(1)` amortized [`push`].
///
/// `vec![x; n]`, `vec![a, b, c, d]`, and
/// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all
/// produce a `Vec` with exactly the requested capacity. If `[len()][`len()`] ==
/// [capacity()][`capacity()`]`, (as is the case for the [`vec!`] macro), then a
/// `Vec<T>` can be converted to and from a [`Box<[T]>`] without reallocating or
/// moving the elements.
/// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all produce a `Vec`
/// with exactly the requested capacity. If [`len()`]` == `[`capacity()`],
/// (as is the case for the [`vec!`] macro), then a `Vec<T>` can be converted to
/// and from a [`Box<[T]>`][owned slice] without reallocating or moving the elements.
///
/// `Vec` will not specifically overwrite any data that is removed from it,
/// but also won't specifically preserve it. Its uninitialized memory is
Expand All @@ -292,7 +291,7 @@ use super::range::RangeArgument;
/// [`push`]: ../../std/vec/struct.Vec.html#method.push
/// [`insert`]: ../../std/vec/struct.Vec.html#method.insert
/// [`reserve`]: ../../std/vec/struct.Vec.html#method.reserve
/// [`Box<[T]>`]: ../../std/boxed/struct.Box.html
/// [owned slice]: ../../std/boxed/struct.Box.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Vec<T> {
buf: RawVec<T>,
Expand Down Expand Up @@ -329,9 +328,10 @@ impl<T> Vec<T> {
/// reallocating. If `capacity` is 0, the vector will not allocate.
///
/// It is important to note that this function does not specify the *length*
/// of the returned vector, but only the *capacity*. (For an explanation of
/// the difference between length and capacity, see the main `Vec<T>` docs
/// above, 'Capacity and reallocation'.)
/// of the returned vector, but only the *capacity*. For an explanation of
/// the difference between length and capacity, see *[Capacity and reallocation]*.
///
/// [Capacity and reallocation]: #capacity-and-reallocation
///
/// # Examples
///
Expand Down Expand Up @@ -497,13 +497,13 @@ impl<T> Vec<T> {
self.buf.shrink_to_fit(self.len);
}

/// Converts the vector into [`Box<[T]>`].
/// Converts the vector into [`Box<[T]>`][owned slice].
///
/// Note that this will drop any excess capacity. Calling this and
/// converting back to a vector with [`into_vec()`] is equivalent to calling
/// [`shrink_to_fit()`].
///
/// [`Box<[T]>`]: ../../std/boxed/struct.Box.html
/// [owned slice]: ../../std/boxed/struct.Box.html
/// [`into_vec()`]: ../../std/primitive.slice.html#method.into_vec
/// [`shrink_to_fit()`]: #method.shrink_to_fit
///
Expand Down Expand Up @@ -779,7 +779,7 @@ impl<T> Vec<T> {

/// Retains only the elements specified by the predicate.
///
/// In other words, remove all elements `e` such that `f(&e)` returns false.
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
/// This method operates in place and preserves the order of the retained
/// elements.
///
Expand Down
74 changes: 54 additions & 20 deletions src/libcollections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -743,16 +743,8 @@ impl<T> VecDeque<T> {
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn as_slices(&self) -> (&[T], &[T]) {
unsafe {
let contiguous = self.is_contiguous();
let buf = self.buffer_as_slice();
if contiguous {
let (empty, buf) = buf.split_at(0);
(&buf[self.tail..self.head], empty)
} else {
let (mid, right) = buf.split_at(self.tail);
let (left, _) = mid.split_at(self.head);
(right, left)
}
RingSlices::ring_slices(buf, self.head, self.tail)
}
}

Expand Down Expand Up @@ -780,20 +772,10 @@ impl<T> VecDeque<T> {
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
unsafe {
let contiguous = self.is_contiguous();
let head = self.head;
let tail = self.tail;
let buf = self.buffer_as_mut_slice();

if contiguous {
let (empty, buf) = buf.split_at_mut(0);
(&mut buf[tail..head], empty)
} else {
let (mid, right) = buf.split_at_mut(tail);
let (left, _) = mid.split_at_mut(head);

(right, left)
}
RingSlices::ring_slices(buf, head, tail)
}
}

Expand Down Expand Up @@ -1829,6 +1811,42 @@ fn wrap_index(index: usize, size: usize) -> usize {
index & (size - 1)
}

/// Returns the two slices that cover the VecDeque's valid range
trait RingSlices : Sized {
fn slice(self, from: usize, to: usize) -> Self;
fn split_at(self, i: usize) -> (Self, Self);

fn ring_slices(buf: Self, head: usize, tail: usize) -> (Self, Self) {
let contiguous = tail <= head;
if contiguous {
let (empty, buf) = buf.split_at(0);
(buf.slice(tail, head), empty)
} else {
let (mid, right) = buf.split_at(tail);
let (left, _) = mid.split_at(head);
(right, left)
}
}
}

impl<'a, T> RingSlices for &'a [T] {
fn slice(self, from: usize, to: usize) -> Self {
&self[from..to]
}
fn split_at(self, i: usize) -> (Self, Self) {
(*self).split_at(i)
}
}

impl<'a, T> RingSlices for &'a mut [T] {
fn slice(self, from: usize, to: usize) -> Self {
&mut self[from..to]
}
fn split_at(self, i: usize) -> (Self, Self) {
(*self).split_at_mut(i)
}
}

/// Calculate the number of elements left to be read in the buffer
#[inline]
fn count(tail: usize, head: usize, size: usize) -> usize {
Expand Down Expand Up @@ -1875,6 +1893,14 @@ impl<'a, T> Iterator for Iter<'a, T> {
let len = count(self.tail, self.head, self.ring.len());
(len, Some(len))
}

fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
where F: FnMut(Acc, Self::Item) -> Acc,
{
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
accum = front.iter().fold(accum, &mut f);
back.iter().fold(accum, &mut f)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -1927,6 +1953,14 @@ impl<'a, T> Iterator for IterMut<'a, T> {
let len = count(self.tail, self.head, self.ring.len());
(len, Some(len))
}

fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
where F: FnMut(Acc, Self::Item) -> Acc,
{
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
accum = front.iter_mut().fold(accum, &mut f);
back.iter_mut().fold(accum, &mut f)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
32 changes: 32 additions & 0 deletions src/libcore/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,12 @@ impl<'a, I, T: 'a> Iterator for Cloned<I>
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}

fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
where F: FnMut(Acc, Self::Item) -> Acc,
{
self.it.fold(init, move |acc, elt| f(acc, elt.clone()))
}
}

#[stable(feature = "iter_cloned", since = "1.1.0")]
Expand Down Expand Up @@ -544,6 +550,25 @@ impl<A, B> Iterator for Chain<A, B> where
}
}

fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
where F: FnMut(Acc, Self::Item) -> Acc,
{
let mut accum = init;
match self.state {
ChainState::Both | ChainState::Front => {
accum = self.a.fold(accum, &mut f);
}
_ => { }
}
match self.state {
ChainState::Both | ChainState::Back => {
accum = self.b.fold(accum, &mut f);
}
_ => { }
}
accum
}

#[inline]
fn nth(&mut self, mut n: usize) -> Option<A::Item> {
match self.state {
Expand Down Expand Up @@ -939,6 +964,13 @@ impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}

fn fold<Acc, G>(self, init: Acc, mut g: G) -> Acc
where G: FnMut(Acc, Self::Item) -> Acc,
{
let mut f = self.f;
self.iter.fold(init, move |acc, elt| g(acc, f(elt)))
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
12 changes: 12 additions & 0 deletions src/libcoretest/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,18 @@ fn test_empty() {
assert_eq!(it.next(), None);
}

#[test]
fn test_chain_fold() {
let xs = [1, 2, 3];
let ys = [1, 2, 0];

let mut iter = xs.iter().chain(&ys);
iter.next();
let mut result = Vec::new();
iter.fold((), |(), &elt| result.push(elt));
assert_eq!(&[2, 3, 1, 2, 0], &result[..]);
}

#[bench]
fn bench_rposition(b: &mut Bencher) {
let it: Vec<usize> = (0..300).collect();
Expand Down
2 changes: 1 addition & 1 deletion src/liblibc
9 changes: 8 additions & 1 deletion src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ declare_lint! {
"safe access to extern statics was erroneously allowed"
}

declare_lint! {
pub PATTERNS_IN_FNS_WITHOUT_BODY,
Warn,
"patterns in functions without body were erroneously allowed"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
Expand Down Expand Up @@ -228,7 +234,8 @@ impl LintPass for HardwiredLints {
SUPER_OR_SELF_IN_GLOBAL_PATH,
HR_LIFETIME_IN_ASSOC_TYPE,
LIFETIME_UNDERSCORE,
SAFE_EXTERN_STATICS
SAFE_EXTERN_STATICS,
PATTERNS_IN_FNS_WITHOUT_BODY
)
}
}
Expand Down
Loading