Skip to content

Rollup of 15 pull requests #33927

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

Merged
merged 25 commits into from
May 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
808e431
Propagate obligations through projection
soltanmm-google May 13, 2016
9e55748
Update error format for readability. Add spacing header<->snippet and…
May 23, 2016
4280992
Fix #33819 and update ui test
May 23, 2016
86a6256
panic.rs: fix docs (recover -> catch_unwind)
diwic May 24, 2016
9cc8deb
Move issue-26480 cfail to ui test. Fix #33763
May 24, 2016
00b78d0
Back to single line between errors. Add header space to secondary files
May 24, 2016
df87a78
Satisfy tidy
May 24, 2016
40285ca
Apply visit_path to import prefixes by default
petrochenkov Mar 6, 2016
c209d44
refactor autoderef to avoid registering obligations
May 24, 2016
33dfd0f
std: Use memalign, not posix_memalign, on Android
alexcrichton May 24, 2016
394c23b
Implement Error trait for fmt::Error type
GuillaumeGomez May 24, 2016
040fc94
catch attempts to leak obligations out of snapshots
arielb1 May 25, 2016
c30fa92
`EscapeUnicode` and `EscapeDefault` are `ExactSizeIterator`s
ranma42 Dec 30, 2015
baa9680
Implement `count` for `EscapeDefault` and `EscapeUnicode`
ranma42 Dec 30, 2015
da03950
Move length computation to `ExactSizeIterator` impls
ranma42 Jan 18, 2016
41950c6
Explain the order of the enumeration items
ranma42 May 26, 2016
6b5e86b
Extend the test for `EscapeUnicode`
ranma42 May 26, 2016
fe19b47
Rollup merge of #33820 - jonathandturner:format_readability_updates, …
Manishearth May 28, 2016
0ed494e
Rollup merge of #33822 - soltanmm:dot-vec-div-mag-square, r=nikomatsakis
Manishearth May 28, 2016
0a6bf37
Rollup merge of #33831 - diwic:patch-1, r=aturon
Manishearth May 28, 2016
320dd04
Rollup merge of #33832 - alexcrichton:android-memalign, r=luqmana
Manishearth May 28, 2016
6e897d7
Rollup merge of #33849 - ranma42:escape-iters-count, r=alexcrichton
Manishearth May 28, 2016
edd7d42
Rollup merge of #33852 - arielb1:autoderef-iterator, r=eddyb
Manishearth May 28, 2016
81aeb0c
Rollup merge of #33854 - petrochenkov:prefvis, r=eddyb
Manishearth May 28, 2016
fe9a915
Rollup merge of #33856 - GuillaumeGomez:fmt_error, r=alexcrichton
Manishearth May 28, 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
41 changes: 34 additions & 7 deletions src/liballoc_system/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,40 @@ mod imp {
if align <= MIN_ALIGN {
libc::malloc(size as libc::size_t) as *mut u8
} else {
let mut out = ptr::null_mut();
let ret = libc::posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
if ret != 0 {
ptr::null_mut()
} else {
out as *mut u8
}
aligned_malloc(size, align)
}
}

#[cfg(target_os = "android")]
unsafe fn aligned_malloc(size: usize, align: usize) -> *mut u8 {
// On android we currently target API level 9 which unfortunately
// doesn't have the `posix_memalign` API used below. Instead we use
// `memalign`, but this unfortunately has the property on some systems
// where the memory returned cannot be deallocated by `free`!
//
// Upon closer inspection, however, this appears to work just fine with
// Android, so for this platform we should be fine to call `memalign`
// (which is present in API level 9). Some helpful references could
// possibly be chromium using memalign [1], attempts at documenting that
// memalign + free is ok [2] [3], or the current source of chromium
// which still uses memalign on android [4].
//
// [1]: https://codereview.chromium.org/10796020/
// [2]: https://code.google.com/p/android/issues/detail?id=35391
// [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
// [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
// /memory/aligned_memory.cc
libc::memalign(align as libc::size_t, size as libc::size_t) as *mut u8
}

#[cfg(not(target_os = "android"))]
unsafe fn aligned_malloc(size: usize, align: usize) -> *mut u8 {
let mut out = ptr::null_mut();
let ret = libc::posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
if ret != 0 {
ptr::null_mut()
} else {
out as *mut u8
}
}

Expand Down
78 changes: 50 additions & 28 deletions src/libcore/char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,14 +411,17 @@ pub struct EscapeUnicode {
hex_digit_idx: usize,
}

// The enum values are ordered so that their representation is the
// same as the remaining length (besides the hexadecimal digits). This
// likely makes `len()` a single load from memory) and inline-worth.
#[derive(Clone, Debug)]
enum EscapeUnicodeState {
Backslash,
Type,
LeftBrace,
Value,
RightBrace,
Done,
RightBrace,
Value,
LeftBrace,
Type,
Backslash,
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -457,19 +460,17 @@ impl Iterator for EscapeUnicode {
}
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let n = match self.state {
EscapeUnicodeState::Backslash => 5,
EscapeUnicodeState::Type => 4,
EscapeUnicodeState::LeftBrace => 3,
EscapeUnicodeState::Value => 2,
EscapeUnicodeState::RightBrace => 1,
EscapeUnicodeState::Done => 0,
};
let n = n + self.hex_digit_idx;
let n = self.len();
(n, Some(n))
}

#[inline]
fn count(self) -> usize {
self.len()
}

fn last(self) -> Option<char> {
match self.state {
EscapeUnicodeState::Done => None,
Expand All @@ -483,6 +484,22 @@ impl Iterator for EscapeUnicode {
}
}

#[stable(feature = "exact_size_escape", since = "1.11.0")]
impl ExactSizeIterator for EscapeUnicode {
#[inline]
fn len(&self) -> usize {
// The match is a single memory access with no branching
self.hex_digit_idx + match self.state {
EscapeUnicodeState::Done => 0,
EscapeUnicodeState::RightBrace => 1,
EscapeUnicodeState::Value => 2,
EscapeUnicodeState::LeftBrace => 3,
EscapeUnicodeState::Type => 4,
EscapeUnicodeState::Backslash => 5,
}
}
}

/// An iterator that yields the literal escape code of a `char`.
///
/// This `struct` is created by the [`escape_default()`] method on [`char`]. See
Expand All @@ -498,9 +515,9 @@ pub struct EscapeDefault {

#[derive(Clone, Debug)]
enum EscapeDefaultState {
Backslash(char),
Char(char),
Done,
Char(char),
Backslash(char),
Unicode(EscapeUnicode),
}

Expand All @@ -523,22 +540,15 @@ impl Iterator for EscapeDefault {
}
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self.state {
EscapeDefaultState::Char(_) => (1, Some(1)),
EscapeDefaultState::Backslash(_) => (2, Some(2)),
EscapeDefaultState::Unicode(ref iter) => iter.size_hint(),
EscapeDefaultState::Done => (0, Some(0)),
}
let n = self.len();
(n, Some(n))
}

#[inline]
fn count(self) -> usize {
match self.state {
EscapeDefaultState::Char(_) => 1,
EscapeDefaultState::Unicode(iter) => iter.count(),
EscapeDefaultState::Done => 0,
EscapeDefaultState::Backslash(_) => 2,
}
self.len()
}

fn nth(&mut self, n: usize) -> Option<char> {
Expand Down Expand Up @@ -578,6 +588,18 @@ impl Iterator for EscapeDefault {
}
}

#[stable(feature = "exact_size_escape", since = "1.11.0")]
impl ExactSizeIterator for EscapeDefault {
fn len(&self) -> usize {
match self.state {
EscapeDefaultState::Done => 0,
EscapeDefaultState::Char(_) => 1,
EscapeDefaultState::Backslash(_) => 2,
EscapeDefaultState::Unicode(ref iter) => iter.len(),
}
}
}

/// An iterator over `u8` entries represending the UTF-8 encoding of a `char`
/// value.
///
Expand Down
6 changes: 6 additions & 0 deletions src/libcoretest/char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ fn eu_iterator_specializations() {
// Check last
assert_eq!(iter.clone().last(), Some('}'));

// Check len
assert_eq!(iter.len(), len - offset);

// Check size_hint (= len in ExactSizeIterator)
assert_eq!(iter.size_hint(), (iter.len(), Some(iter.len())));

// Check counting
assert_eq!(iter.clone().count(), len - offset);

Expand Down
15 changes: 4 additions & 11 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_path(path, item.id);
}
ViewPathList(ref prefix, ref list) => {
if !list.is_empty() {
for item in list {
visitor.visit_path_list_item(prefix, item)
}
} else {
visitor.visit_path(prefix, item.id);
visitor.visit_path(prefix, item.id);
for item in list {
visitor.visit_path_list_item(prefix, item)
}
}
}
Expand Down Expand Up @@ -419,12 +416,8 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
}

pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V,
prefix: &'v Path,
_prefix: &'v Path,
item: &'v PathListItem) {
for segment in &prefix.segments {
visitor.visit_path_segment(prefix.span, segment);
}

walk_opt_name(visitor, item.span, item.node.name());
walk_opt_name(visitor, item.span, item.node.rename());
}
Expand Down
33 changes: 28 additions & 5 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
// If the number of errors increases, that's also a sign (line
// `tained_by_errors`) to avoid reporting certain kinds of errors.
err_count_on_creation: usize,

// This flag is used for debugging, and is set to true if there are
// any obligations set during the current snapshot. In that case, the
// snapshot can't be rolled back.
pub obligations_in_snapshot: Cell<bool>,
}

/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
Expand Down Expand Up @@ -476,7 +481,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
normalize: false,
projection_mode: ProjectionMode::AnyFinal,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: self.sess.err_count()
err_count_on_creation: self.sess.err_count(),
obligations_in_snapshot: Cell::new(false),
}
}
}
Expand Down Expand Up @@ -515,7 +521,8 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
normalize: normalize,
projection_mode: projection_mode,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: tcx.sess.err_count()
err_count_on_creation: tcx.sess.err_count(),
obligations_in_snapshot: Cell::new(false),
}))
}
}
Expand All @@ -542,6 +549,7 @@ pub struct CombinedSnapshot {
int_snapshot: unify::Snapshot<ty::IntVid>,
float_snapshot: unify::Snapshot<ty::FloatVid>,
region_vars_snapshot: RegionSnapshot,
obligations_in_snapshot: bool,
}

/// Helper trait for shortening the lifetimes inside a
Expand Down Expand Up @@ -809,11 +817,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}

fn start_snapshot(&self) -> CombinedSnapshot {
let obligations_in_snapshot = self.obligations_in_snapshot.get();
self.obligations_in_snapshot.set(false);

CombinedSnapshot {
type_snapshot: self.type_variables.borrow_mut().snapshot(),
int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
region_vars_snapshot: self.region_vars.start_snapshot(),
obligations_in_snapshot: obligations_in_snapshot,
}
}

Expand All @@ -822,7 +834,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let CombinedSnapshot { type_snapshot,
int_snapshot,
float_snapshot,
region_vars_snapshot } = snapshot;
region_vars_snapshot,
obligations_in_snapshot } = snapshot;

assert!(!self.obligations_in_snapshot.get());
self.obligations_in_snapshot.set(obligations_in_snapshot);

self.type_variables
.borrow_mut()
Expand All @@ -842,7 +858,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let CombinedSnapshot { type_snapshot,
int_snapshot,
float_snapshot,
region_vars_snapshot } = snapshot;
region_vars_snapshot,
obligations_in_snapshot } = snapshot;

self.obligations_in_snapshot.set(obligations_in_snapshot);

self.type_variables
.borrow_mut()
Expand Down Expand Up @@ -904,12 +923,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let CombinedSnapshot { type_snapshot,
int_snapshot,
float_snapshot,
region_vars_snapshot } = self.start_snapshot();
region_vars_snapshot,
obligations_in_snapshot } = self.start_snapshot();

let r = self.commit_if_ok(|_| f());

debug!("commit_regions_if_ok: rolling back everything but regions");

assert!(!self.obligations_in_snapshot.get());
self.obligations_in_snapshot.set(obligations_in_snapshot);

// Roll back any non-region bindings - they should be resolved
// inside `f`, with, e.g. `resolve_type_vars_if_possible`.
self.type_variables
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
// debug output much nicer to read and so on.
let obligation = infcx.resolve_type_vars_if_possible(&obligation);

infcx.obligations_in_snapshot.set(true);

if infcx.tcx.fulfilled_predicates.borrow().check_duplicate(&obligation.predicate)
{
return
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub use self::coherence::overlapping_impls;
pub use self::coherence::OrphanCheckErr;
pub use self::fulfill::{FulfillmentContext, GlobalFulfilledPredicates, RegionObligation};
pub use self::project::{MismatchedProjectionTypes, ProjectionMode};
pub use self::project::{normalize, Normalized};
pub use self::project::{normalize, normalize_projection_type, Normalized};
pub use self::object_safety::ObjectSafetyViolation;
pub use self::object_safety::MethodViolationCode;
pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
Expand Down
Loading