Skip to content

Commit

Permalink
Auto merge of rust-lang#48476 - Manishearth:rollup, r=Manishearth
Browse files Browse the repository at this point in the history
  • Loading branch information
bors committed Feb 24, 2018
2 parents b0a8620 + b26442a commit 6070d3e
Show file tree
Hide file tree
Showing 35 changed files with 1,035 additions and 313 deletions.
2 changes: 2 additions & 0 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/liballoc/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,8 +747,8 @@ impl<T> LinkedList<T> {
/// Creates an iterator which uses a closure to determine if an element should be removed.
///
/// If the closure returns true, then the element is removed and yielded.
/// If the closure returns false, it will try again, and call the closure on the next element,
/// seeing if it passes the test.
/// If the closure returns false, the element will remain in the list and will not be yielded
/// by the iterator.
///
/// Note that `drain_filter` lets you mutate every element in the filter closure, regardless of
/// whether you choose to keep or remove it.
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ impl String {
///
/// Given that the `String` is empty, this will not allocate any initial
/// buffer. While that means that this initial operation is very
/// inexpensive, but may cause excessive allocation later, when you add
/// inexpensive, it may cause excessive allocation later when you add
/// data. If you have an idea of how much data the `String` will hold,
/// consider the [`with_capacity`] method to prevent excessive
/// re-allocation.
Expand Down
4 changes: 2 additions & 2 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1966,8 +1966,8 @@ impl<T> Vec<T> {
/// Creates an iterator which uses a closure to determine if an element should be removed.
///
/// If the closure returns true, then the element is removed and yielded.
/// If the closure returns false, it will try again, and call the closure
/// on the next element, seeing if it passes the test.
/// If the closure returns false, the element will remain in the vector and will not be yielded
/// by the iterator.
///
/// Using this method is equivalent to the following code:
///
Expand Down
48 changes: 42 additions & 6 deletions src/libcore/iter/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1366,9 +1366,9 @@ pub trait Iterator {
///
/// In particular, try to have this call `try_fold()` on the internal parts
/// from which this iterator is composed. If multiple calls are needed,
/// the `?` operator be convenient for chaining the accumulator value along,
/// but beware any invariants that need to be upheld before those early
/// returns. This is a `&mut self` method, so iteration needs to be
/// the `?` operator may be convenient for chaining the accumulator value
/// along, but beware any invariants that need to be upheld before those
/// early returns. This is a `&mut self` method, so iteration needs to be
/// resumable after hitting an error here.
///
/// # Examples
Expand Down Expand Up @@ -1414,6 +1414,42 @@ pub trait Iterator {
Try::from_ok(accum)
}

/// An iterator method that applies a fallible function to each item in the
/// iterator, stopping at the first error and returning that error.
///
/// This can also be thought of as the fallible form of [`for_each()`]
/// or as the stateless version of [`try_fold()`].
///
/// [`for_each()`]: #method.for_each
/// [`try_fold()`]: #method.try_fold
///
/// # Examples
///
/// ```
/// #![feature(iterator_try_fold)]
/// use std::fs::rename;
/// use std::io::{stdout, Write};
/// use std::path::Path;
///
/// let data = ["no_tea.txt", "stale_bread.json", "torrential_rain.png"];
///
/// let res = data.iter().try_for_each(|x| writeln!(stdout(), "{}", x));
/// assert!(res.is_ok());
///
/// let mut it = data.iter().cloned();
/// let res = it.try_for_each(|x| rename(x, Path::new(x).with_extension("old")));
/// assert!(res.is_err());
/// // It short-circuited, so the remaining items are still in the iterator:
/// assert_eq!(it.next(), Some("stale_bread.json"));
/// ```
#[inline]
#[unstable(feature = "iterator_try_fold", issue = "45594")]
fn try_for_each<F, R>(&mut self, mut f: F) -> R where
Self: Sized, F: FnMut(Self::Item) -> R, R: Try<Ok=()>
{
self.try_fold((), move |(), x| f(x))
}

/// An iterator method that applies a function, producing a single, final value.
///
/// `fold()` takes two arguments: an initial value, and a closure with two
Expand Down Expand Up @@ -1532,7 +1568,7 @@ pub trait Iterator {
fn all<F>(&mut self, mut f: F) -> bool where
Self: Sized, F: FnMut(Self::Item) -> bool
{
self.try_fold((), move |(), x| {
self.try_for_each(move |x| {
if f(x) { LoopState::Continue(()) }
else { LoopState::Break(()) }
}) == LoopState::Continue(())
Expand Down Expand Up @@ -1581,7 +1617,7 @@ pub trait Iterator {
Self: Sized,
F: FnMut(Self::Item) -> bool
{
self.try_fold((), move |(), x| {
self.try_for_each(move |x| {
if f(x) { LoopState::Break(()) }
else { LoopState::Continue(()) }
}) == LoopState::Break(())
Expand Down Expand Up @@ -1635,7 +1671,7 @@ pub trait Iterator {
Self: Sized,
P: FnMut(&Self::Item) -> bool,
{
self.try_fold((), move |(), x| {
self.try_for_each(move |x| {
if predicate(&x) { LoopState::Break(x) }
else { LoopState::Continue(()) }
}).break_value()
Expand Down
6 changes: 6 additions & 0 deletions src/libproc_macro/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,12 @@ pub mod __internal {
})
}

pub fn in_sess() -> bool
{
let p = CURRENT_SESS.with(|p| p.get());
!p.0.is_null()
}

pub fn with_sess<F, R>(f: F) -> R
where F: FnOnce((&ParseSess, Mark)) -> R
{
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ bitflags = "1.0"
fmt_macros = { path = "../libfmt_macros" }
graphviz = { path = "../libgraphviz" }
jobserver = "0.1"
lazy_static = "1.0.0"
log = { version = "0.4", features = ["release_max_level_info", "std"] }
proc_macro = { path = "../libproc_macro" }
rustc_apfloat = { path = "../librustc_apfloat" }
rustc_back = { path = "../librustc_back" }
rustc_const_math = { path = "../librustc_const_math" }
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#![feature(never_type)]
#![feature(non_exhaustive)]
#![feature(nonzero)]
#![feature(proc_macro_internals)]
#![feature(quote)]
#![feature(refcell_replace_swap)]
#![feature(rustc_diagnostic_macros)]
Expand All @@ -81,6 +82,7 @@ extern crate core;
extern crate fmt_macros;
extern crate getopts;
extern crate graphviz;
#[macro_use] extern crate lazy_static;
#[cfg(windows)]
extern crate libc;
extern crate rustc_back;
Expand All @@ -92,6 +94,7 @@ extern crate rustc_errors as errors;
#[macro_use] extern crate syntax;
extern crate syntax_pos;
extern crate jobserver;
extern crate proc_macro;

extern crate serialize as rustc_serialize; // used by deriving

Expand Down
82 changes: 71 additions & 11 deletions src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,19 @@ enum Scope<'a> {
/// we should use for an early-bound region?
next_early_index: u32,

/// Whether or not this binder would serve as the parent
/// binder for abstract types introduced within. For example:
///
/// fn foo<'a>() -> impl for<'b> Trait<Item = impl Trait2<'a>>
///
/// Here, the abstract types we create for the `impl Trait`
/// and `impl Trait2` references will both have the `foo` item
/// as their parent. When we get to `impl Trait2`, we find
/// that it is nested within the `for<>` binder -- this flag
/// allows us to skip that when looking for the parent binder
/// of the resulting abstract type.
abstract_type_parent: bool,

s: ScopeRef<'a>,
},

Expand Down Expand Up @@ -498,6 +511,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
let scope = Scope::Binder {
lifetimes,
next_early_index,
abstract_type_parent: true,
s: ROOT_SCOPE,
};
self.with(scope, |old_scope, this| {
Expand Down Expand Up @@ -541,6 +555,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
.collect(),
s: self.scope,
next_early_index,
abstract_type_parent: false,
};
self.with(scope, |old_scope, this| {
// a bare fn has no bounds, so everything
Expand Down Expand Up @@ -614,7 +629,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
ref generics,
ref bounds,
} = *exist_ty;
let mut index = self.next_early_index();

// We want to start our early-bound indices at the end of the parent scope,
// not including any parent `impl Trait`s.
let mut index = self.next_early_index_for_abstract_type();
debug!("visit_ty: index = {}", index);

let mut elision = None;
Expand All @@ -638,7 +656,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
s: self.scope
};
self.with(scope, |_old_scope, this| {
let scope = Scope::Binder { lifetimes, next_early_index, s: this.scope };
let scope = Scope::Binder {
lifetimes,
next_early_index,
s: this.scope,
abstract_type_parent: false,
};
this.with(scope, |_old_scope, this| {
this.visit_generics(generics);
for bound in bounds {
Expand All @@ -647,7 +670,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
});
});
} else {
let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
let scope = Scope::Binder {
lifetimes,
next_early_index,
s: self.scope,
abstract_type_parent: false,
};
self.with(scope, |_old_scope, this| {
this.visit_generics(generics);
for bound in bounds {
Expand Down Expand Up @@ -681,7 +709,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
.collect();

let next_early_index = index + generics.ty_params().count() as u32;
let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
let scope = Scope::Binder {
lifetimes,
next_early_index,
s: self.scope,
abstract_type_parent: true,
};
self.with(scope, |_old_scope, this| {
this.visit_generics(generics);
for bound in bounds {
Expand Down Expand Up @@ -721,7 +754,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
.collect();

let next_early_index = index + generics.ty_params().count() as u32;
let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
let scope = Scope::Binder {
lifetimes,
next_early_index,
s: self.scope,
abstract_type_parent: true,
};
self.with(scope, |_old_scope, this| {
this.visit_generics(generics);
this.visit_ty(ty);
Expand Down Expand Up @@ -792,6 +830,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
.collect(),
s: self.scope,
next_early_index,
abstract_type_parent: false,
};
let result = self.with(scope, |old_scope, this| {
this.check_lifetime_params(old_scope, &bound_generic_params);
Expand Down Expand Up @@ -853,6 +892,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
.collect(),
s: self.scope,
next_early_index,
abstract_type_parent: false,
};
self.with(scope, |old_scope, this| {
this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
Expand Down Expand Up @@ -1046,6 +1086,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) {
ref lifetimes,
s,
next_early_index: _,
abstract_type_parent: _,
} => {
// FIXME (#24278): non-hygienic comparison
if let Some(def) = lifetimes.get(&hir::LifetimeName::Name(label)) {
Expand Down Expand Up @@ -1303,32 +1344,49 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
lifetimes,
next_early_index,
s: self.scope,
abstract_type_parent: true,
};
self.with(scope, move |old_scope, this| {
this.check_lifetime_params(old_scope, &generics.params);
this.hack(walk); // FIXME(#37666) workaround in place of `walk(this)`
});
}

/// Returns the next index one would use for an early-bound-region
/// if extending the current scope.
fn next_early_index(&self) -> u32 {
fn next_early_index_helper(&self, only_abstract_type_parent: bool) -> u32 {
let mut scope = self.scope;
loop {
match *scope {
Scope::Root => return 0,

Scope::Binder {
next_early_index, ..
} => return next_early_index,
next_early_index,
abstract_type_parent,
..
} if (!only_abstract_type_parent || abstract_type_parent)
=> return next_early_index,

Scope::Body { s, .. }
Scope::Binder { s, .. }
| Scope::Body { s, .. }
| Scope::Elision { s, .. }
| Scope::ObjectLifetimeDefault { s, .. } => scope = s,
}
}
}

/// Returns the next index one would use for an early-bound-region
/// if extending the current scope.
fn next_early_index(&self) -> u32 {
self.next_early_index_helper(true)
}

/// Returns the next index one would use for an `impl Trait` that
/// is being converted into an `abstract type`. This will be the
/// next early index from the enclosing item, for the most
/// part. See the `abstract_type_parent` field for more info.
fn next_early_index_for_abstract_type(&self) -> u32 {
self.next_early_index_helper(false)
}

fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
debug!("resolve_lifetime_ref(lifetime_ref={:?})", lifetime_ref);
// Walk up the scope chain, tracking the number of fn scopes
Expand All @@ -1353,6 +1411,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
ref lifetimes,
s,
next_early_index: _,
abstract_type_parent: _,
} => {
if let Some(&def) = lifetimes.get(&lifetime_ref.name) {
break Some(def.shifted(late_depth));
Expand Down Expand Up @@ -2102,6 +2161,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
ref lifetimes,
s,
next_early_index: _,
abstract_type_parent: _,
} => {
if let Some(&def) = lifetimes.get(&lifetime.name) {
let node_id = self.tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
Expand Down
Loading

0 comments on commit 6070d3e

Please sign in to comment.