Skip to content

Commit

Permalink
Auto merge of #44678 - alexcrichton:rollup, r=alexcrichton
Browse files Browse the repository at this point in the history
Rollup of 11 pull requests

- Successful merges: #44364, #44466, #44537, #44548, #44640, #44651, #44657, #44661, #44668, #44671, #44675
- Failed merges:
  • Loading branch information
bors committed Sep 18, 2017
2 parents 3a7b960 + 929215d commit 0701b37
Show file tree
Hide file tree
Showing 74 changed files with 1,985 additions and 798 deletions.
11 changes: 5 additions & 6 deletions src/doc/unstable-book/src/library-features/splice.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# `splice`

The tracking issue for this feature is: [#32310]
The tracking issue for this feature is: [#44643]

[#32310]: https://github.com/rust-lang/rust/issues/32310
[#44643]: https://github.com/rust-lang/rust/issues/44643

------------------------

The `splice()` method on `Vec` and `String` allows you to replace a range
of values in a vector or string with another range of values, and returns
the replaced values.
The `splice()` method on `String` allows you to replace a range
of values in a string with another range of values.

A simple example:

Expand All @@ -20,4 +19,4 @@ let beta_offset = s.find('β').unwrap_or(s.len());
// Replace the range up until the β from the string
s.splice(..beta_offset, "Α is capital alpha; ");
assert_eq!(s, "Α is capital alpha; β is beta");
```
```
2 changes: 1 addition & 1 deletion src/liballoc/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,7 @@ impl String {
/// s.splice(..beta_offset, "Α is capital alpha; ");
/// assert_eq!(s, "Α is capital alpha; β is beta");
/// ```
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
#[unstable(feature = "splice", reason = "recently added", issue = "44643")]
pub fn splice<R>(&mut self, range: R, replace_with: &str)
where R: RangeArgument<usize>
{
Expand Down
13 changes: 6 additions & 7 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1943,15 +1943,14 @@ impl<T> Vec<T> {
/// # Examples
///
/// ```
/// #![feature(splice)]
/// let mut v = vec![1, 2, 3];
/// let new = [7, 8];
/// let u: Vec<_> = v.splice(..2, new.iter().cloned()).collect();
/// assert_eq!(v, &[7, 8, 3]);
/// assert_eq!(u, &[1, 2]);
/// ```
#[inline]
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
#[stable(feature = "vec_splice", since = "1.22.0")]
pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<I::IntoIter>
where R: RangeArgument<usize>, I: IntoIterator<Item=T>
{
Expand Down Expand Up @@ -2554,13 +2553,13 @@ impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
/// [`splice()`]: struct.Vec.html#method.splice
/// [`Vec`]: struct.Vec.html
#[derive(Debug)]
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
#[stable(feature = "vec_splice", since = "1.22.0")]
pub struct Splice<'a, I: Iterator + 'a> {
drain: Drain<'a, I::Item>,
replace_with: I,
}

#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
#[stable(feature = "vec_splice", since = "1.22.0")]
impl<'a, I: Iterator> Iterator for Splice<'a, I> {
type Item = I::Item;

Expand All @@ -2573,18 +2572,18 @@ impl<'a, I: Iterator> Iterator for Splice<'a, I> {
}
}

#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
#[stable(feature = "vec_splice", since = "1.22.0")]
impl<'a, I: Iterator> DoubleEndedIterator for Splice<'a, I> {
fn next_back(&mut self) -> Option<Self::Item> {
self.drain.next_back()
}
}

#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
#[stable(feature = "vec_splice", since = "1.22.0")]
impl<'a, I: Iterator> ExactSizeIterator for Splice<'a, I> {}


#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
#[stable(feature = "vec_splice", since = "1.22.0")]
impl<'a, I: Iterator> Drop for Splice<'a, I> {
fn drop(&mut self) {
// exhaust drain first
Expand Down
33 changes: 1 addition & 32 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1381,38 +1381,7 @@ extern "rust-intrinsic" {
}

#[cfg(stage0)]
/// Computes the byte offset that needs to be applied to `ptr` in order to
/// make it aligned to `align`.
/// If it is not possible to align `ptr`, the implementation returns
/// `usize::max_value()`.
///
/// There are no guarantees whatsover that offsetting the pointer will not
/// overflow or go beyond the allocation that `ptr` points into.
/// It is up to the caller to ensure that the returned offset is correct
/// in all terms other than alignment.
///
/// # Examples
///
/// Accessing adjacent `u8` as `u16`
///
/// ```
/// # #![feature(core_intrinsics)]
/// # fn foo(n: usize) {
/// # use std::intrinsics::align_offset;
/// # use std::mem::align_of;
/// # unsafe {
/// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
/// let ptr = &x[n] as *const u8;
/// let offset = align_offset(ptr as *const (), align_of::<u16>());
/// if offset < x.len() - n - 1 {
/// let u16_ptr = ptr.offset(offset as isize) as *const u16;
/// assert_ne!(*u16_ptr, 500);
/// } else {
/// // while the pointer can be aligned via `offset`, it would point
/// // outside the allocation
/// }
/// # } }
/// ```
/// remove me after the next release
pub unsafe fn align_offset(ptr: *const (), align: usize) -> usize {
let offset = ptr as usize % align;
if offset == 0 {
Expand Down
17 changes: 17 additions & 0 deletions src/libcore/iter/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,23 @@ pub trait FromIterator<A>: Sized {
/// assert_eq!(i as i32, n);
/// }
/// ```
///
/// It is common to use `IntoIterator` as a trait bound. This allows
/// the input collection type to change, so long as it is still an
/// iterator. Additional bounds can be specified by restricting on
/// `Item`:
///
/// ```rust
/// fn collect_as_strings<T>(collection: T) -> Vec<String>
/// where T: IntoIterator,
/// T::Item : std::fmt::Debug,
/// {
/// collection
/// .into_iter()
/// .map(|item| format!("{:?}", item))
/// .collect()
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait IntoIterator {
/// The type of the elements being iterated over.
Expand Down
75 changes: 74 additions & 1 deletion src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,43 @@ impl<T: ?Sized> *const T {
copy_nonoverlapping(self, dest, count)
}


/// Computes the byte offset that needs to be applied in order to
/// make the pointer aligned to `align`.
/// If it is not possible to align the pointer, the implementation returns
/// `usize::max_value()`.
///
/// There are no guarantees whatsover that offsetting the pointer will not
/// overflow or go beyond the allocation that the pointer points into.
/// It is up to the caller to ensure that the returned offset is correct
/// in all terms other than alignment.
///
/// # Examples
///
/// Accessing adjacent `u8` as `u16`
///
/// ```
/// # #![feature(align_offset)]
/// # fn foo(n: usize) {
/// # use std::mem::align_of;
/// # unsafe {
/// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
/// let ptr = &x[n] as *const u8;
/// let offset = ptr.align_offset(align_of::<u16>());
/// if offset < x.len() - n - 1 {
/// let u16_ptr = ptr.offset(offset as isize) as *const u16;
/// assert_ne!(*u16_ptr, 500);
/// } else {
/// // while the pointer can be aligned via `offset`, it would point
/// // outside the allocation
/// }
/// # } }
/// ```
#[unstable(feature = "align_offset", issue = "44488")]
pub fn align_offset(self, align: usize) -> usize {
unsafe {
intrinsics::align_offset(self as *const _, align)
}
}
}

#[lang = "mut_ptr"]
Expand Down Expand Up @@ -1284,6 +1320,43 @@ impl<T: ?Sized> *mut T {
}
}

/// Computes the byte offset that needs to be applied in order to
/// make the pointer aligned to `align`.
/// If it is not possible to align the pointer, the implementation returns
/// `usize::max_value()`.
///
/// There are no guarantees whatsover that offsetting the pointer will not
/// overflow or go beyond the allocation that the pointer points into.
/// It is up to the caller to ensure that the returned offset is correct
/// in all terms other than alignment.
///
/// # Examples
///
/// Accessing adjacent `u8` as `u16`
///
/// ```
/// # #![feature(align_offset)]
/// # fn foo(n: usize) {
/// # use std::mem::align_of;
/// # unsafe {
/// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
/// let ptr = &x[n] as *const u8;
/// let offset = ptr.align_offset(align_of::<u16>());
/// if offset < x.len() - n - 1 {
/// let u16_ptr = ptr.offset(offset as isize) as *const u16;
/// assert_ne!(*u16_ptr, 500);
/// } else {
/// // while the pointer can be aligned via `offset`, it would point
/// // outside the allocation
/// }
/// # } }
/// ```
#[unstable(feature = "align_offset", issue = "44488")]
pub fn align_offset(self, align: usize) -> usize {
unsafe {
intrinsics::align_offset(self as *const _, align)
}
}

/// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
///
Expand Down
11 changes: 5 additions & 6 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use fmt;
use iter::{Map, Cloned, FusedIterator};
use slice::{self, SliceIndex};
use mem;
use intrinsics::align_offset;

pub mod pattern;

Expand Down Expand Up @@ -404,7 +403,7 @@ unsafe fn from_raw_parts_mut<'a>(p: *mut u8, len: usize) -> &'a mut str {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
mem::transmute(v)
&*(v as *const [u8] as *const str)
}

/// Converts a slice of bytes to a string slice without checking
Expand All @@ -429,7 +428,7 @@ pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
#[inline]
#[stable(feature = "str_mut_extras", since = "1.20.0")]
pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
mem::transmute(v)
&mut *(v as *mut [u8] as *mut str)
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -1515,7 +1514,7 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
let ptr = v.as_ptr();
let align = unsafe {
// the offset is safe, because `index` is guaranteed inbounds
align_offset(ptr.offset(index as isize) as *const (), usize_bytes)
ptr.offset(index as isize).align_offset(usize_bytes)
};
if align == 0 {
while index < blocks_end {
Expand Down Expand Up @@ -2447,12 +2446,12 @@ impl StrExt for str {

#[inline]
fn as_bytes(&self) -> &[u8] {
unsafe { mem::transmute(self) }
unsafe { &*(self as *const str as *const [u8]) }
}

#[inline]
unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
mem::transmute(self)
&mut *(self as *mut str as *mut [u8])
}

fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
Expand Down
16 changes: 14 additions & 2 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,12 +603,12 @@ trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
}

impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T
where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + fmt::Debug
where T: HashStable<StableHashingContext<'gcx>> + fmt::Debug
{
default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;

default fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint {
let mut hcx = StableHashingContext::new(tcx);
let mut hcx = tcx.create_stable_hashing_context();
let mut hasher = StableHasher::new();

self.hash_stable(&mut hcx, &mut hasher);
Expand All @@ -633,6 +633,18 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId,) {
}
}

impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefIndex,) {
const CAN_RECONSTRUCT_QUERY_KEY: bool = true;

fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
tcx.hir.definitions().def_path_hash(self.0).0
}

fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
tcx.item_path_str(DefId::local(self.0))
}
}

impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, DefId) {
const CAN_RECONSTRUCT_QUERY_KEY: bool = false;

Expand Down
36 changes: 25 additions & 11 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
// except according to those terms.

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHashingContextProvider};
use session::config::OutputType;
use std::cell::{Ref, RefCell};
use std::rc::Rc;
use util::common::{ProfileQueriesMsg, profq_msg};

use ich::Fingerprint;

use super::dep_node::{DepNode, DepKind, WorkProductId};
use super::query::DepGraphQuery;
use super::raii;
Expand Down Expand Up @@ -71,10 +75,6 @@ impl DepGraph {
self.data.as_ref().map(|data| raii::IgnoreTask::new(&data.edges))
}

pub fn in_task<'graph>(&'graph self, key: DepNode) -> Option<raii::DepTask<'graph>> {
self.data.as_ref().map(|data| raii::DepTask::new(&data.edges, key))
}

pub fn with_ignore<OP,R>(&self, op: OP) -> R
where OP: FnOnce() -> R
{
Expand Down Expand Up @@ -109,24 +109,38 @@ impl DepGraph {
/// `arg` parameter.
///
/// [README]: README.md
pub fn with_task<C, A, R>(&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R)
-> (R, DepNodeIndex)
where C: DepGraphSafe
pub fn with_task<C, A, R, HCX>(&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R)
-> (R, DepNodeIndex)
where C: DepGraphSafe + StableHashingContextProvider<ContextType=HCX>,
R: HashStable<HCX>,
{
if let Some(ref data) = self.data {
data.edges.borrow_mut().push_task(key);
if cfg!(debug_assertions) {
profq_msg(ProfileQueriesMsg::TaskBegin(key.clone()))
};

// In incremental mode, hash the result of the task. We don't
// do anything with the hash yet, but we are computing it
// anyway so that
// - we make sure that the infrastructure works and
// - we can get an idea of the runtime cost.
let mut hcx = cx.create_stable_hashing_context();

let result = task(cx, arg);
if cfg!(debug_assertions) {
profq_msg(ProfileQueriesMsg::TaskEnd)
};
let dep_node_index = data.edges.borrow_mut().pop_task(key);

let mut stable_hasher = StableHasher::new();
result.hash_stable(&mut hcx, &mut stable_hasher);
let _: Fingerprint = stable_hasher.finish();

(result, dep_node_index)
} else {
(task(cx, arg), DepNodeIndex::INVALID)
Expand Down
Loading

0 comments on commit 0701b37

Please sign in to comment.