Skip to content

Commit f1776fe

Browse files
committedMay 28, 2016
Auto merge of #33927 - Manishearth:rollup, r=Manishearth
Rollup of 15 pull requests - Successful merges: #33820, #33821, #33822, #33824, #33825, #33831, #33832, #33848, #33849, #33852, #33854, #33856, #33859, #33860, #33861 - Failed merges:
2 parents 7d68b3d + fe9a915 commit f1776fe

36 files changed

+787
-612
lines changed
 

‎src/liballoc_system/lib.rs

+34-7
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,40 @@ mod imp {
8080
if align <= MIN_ALIGN {
8181
libc::malloc(size as libc::size_t) as *mut u8
8282
} else {
83-
let mut out = ptr::null_mut();
84-
let ret = libc::posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
85-
if ret != 0 {
86-
ptr::null_mut()
87-
} else {
88-
out as *mut u8
89-
}
83+
aligned_malloc(size, align)
84+
}
85+
}
86+
87+
#[cfg(target_os = "android")]
88+
unsafe fn aligned_malloc(size: usize, align: usize) -> *mut u8 {
89+
// On android we currently target API level 9 which unfortunately
90+
// doesn't have the `posix_memalign` API used below. Instead we use
91+
// `memalign`, but this unfortunately has the property on some systems
92+
// where the memory returned cannot be deallocated by `free`!
93+
//
94+
// Upon closer inspection, however, this appears to work just fine with
95+
// Android, so for this platform we should be fine to call `memalign`
96+
// (which is present in API level 9). Some helpful references could
97+
// possibly be chromium using memalign [1], attempts at documenting that
98+
// memalign + free is ok [2] [3], or the current source of chromium
99+
// which still uses memalign on android [4].
100+
//
101+
// [1]: https://codereview.chromium.org/10796020/
102+
// [2]: https://code.google.com/p/android/issues/detail?id=35391
103+
// [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
104+
// [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
105+
// /memory/aligned_memory.cc
106+
libc::memalign(align as libc::size_t, size as libc::size_t) as *mut u8
107+
}
108+
109+
#[cfg(not(target_os = "android"))]
110+
unsafe fn aligned_malloc(size: usize, align: usize) -> *mut u8 {
111+
let mut out = ptr::null_mut();
112+
let ret = libc::posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
113+
if ret != 0 {
114+
ptr::null_mut()
115+
} else {
116+
out as *mut u8
90117
}
91118
}
92119

‎src/libcore/char.rs

+50-28
Original file line numberDiff line numberDiff line change
@@ -411,14 +411,17 @@ pub struct EscapeUnicode {
411411
hex_digit_idx: usize,
412412
}
413413

414+
// The enum values are ordered so that their representation is the
415+
// same as the remaining length (besides the hexadecimal digits). This
416+
// likely makes `len()` a single load from memory) and inline-worth.
414417
#[derive(Clone, Debug)]
415418
enum EscapeUnicodeState {
416-
Backslash,
417-
Type,
418-
LeftBrace,
419-
Value,
420-
RightBrace,
421419
Done,
420+
RightBrace,
421+
Value,
422+
LeftBrace,
423+
Type,
424+
Backslash,
422425
}
423426

424427
#[stable(feature = "rust1", since = "1.0.0")]
@@ -457,19 +460,17 @@ impl Iterator for EscapeUnicode {
457460
}
458461
}
459462

463+
#[inline]
460464
fn size_hint(&self) -> (usize, Option<usize>) {
461-
let n = match self.state {
462-
EscapeUnicodeState::Backslash => 5,
463-
EscapeUnicodeState::Type => 4,
464-
EscapeUnicodeState::LeftBrace => 3,
465-
EscapeUnicodeState::Value => 2,
466-
EscapeUnicodeState::RightBrace => 1,
467-
EscapeUnicodeState::Done => 0,
468-
};
469-
let n = n + self.hex_digit_idx;
465+
let n = self.len();
470466
(n, Some(n))
471467
}
472468

469+
#[inline]
470+
fn count(self) -> usize {
471+
self.len()
472+
}
473+
473474
fn last(self) -> Option<char> {
474475
match self.state {
475476
EscapeUnicodeState::Done => None,
@@ -483,6 +484,22 @@ impl Iterator for EscapeUnicode {
483484
}
484485
}
485486

487+
#[stable(feature = "exact_size_escape", since = "1.11.0")]
488+
impl ExactSizeIterator for EscapeUnicode {
489+
#[inline]
490+
fn len(&self) -> usize {
491+
// The match is a single memory access with no branching
492+
self.hex_digit_idx + match self.state {
493+
EscapeUnicodeState::Done => 0,
494+
EscapeUnicodeState::RightBrace => 1,
495+
EscapeUnicodeState::Value => 2,
496+
EscapeUnicodeState::LeftBrace => 3,
497+
EscapeUnicodeState::Type => 4,
498+
EscapeUnicodeState::Backslash => 5,
499+
}
500+
}
501+
}
502+
486503
/// An iterator that yields the literal escape code of a `char`.
487504
///
488505
/// This `struct` is created by the [`escape_default()`] method on [`char`]. See
@@ -498,9 +515,9 @@ pub struct EscapeDefault {
498515

499516
#[derive(Clone, Debug)]
500517
enum EscapeDefaultState {
501-
Backslash(char),
502-
Char(char),
503518
Done,
519+
Char(char),
520+
Backslash(char),
504521
Unicode(EscapeUnicode),
505522
}
506523

@@ -523,22 +540,15 @@ impl Iterator for EscapeDefault {
523540
}
524541
}
525542

543+
#[inline]
526544
fn size_hint(&self) -> (usize, Option<usize>) {
527-
match self.state {
528-
EscapeDefaultState::Char(_) => (1, Some(1)),
529-
EscapeDefaultState::Backslash(_) => (2, Some(2)),
530-
EscapeDefaultState::Unicode(ref iter) => iter.size_hint(),
531-
EscapeDefaultState::Done => (0, Some(0)),
532-
}
545+
let n = self.len();
546+
(n, Some(n))
533547
}
534548

549+
#[inline]
535550
fn count(self) -> usize {
536-
match self.state {
537-
EscapeDefaultState::Char(_) => 1,
538-
EscapeDefaultState::Unicode(iter) => iter.count(),
539-
EscapeDefaultState::Done => 0,
540-
EscapeDefaultState::Backslash(_) => 2,
541-
}
551+
self.len()
542552
}
543553

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

591+
#[stable(feature = "exact_size_escape", since = "1.11.0")]
592+
impl ExactSizeIterator for EscapeDefault {
593+
fn len(&self) -> usize {
594+
match self.state {
595+
EscapeDefaultState::Done => 0,
596+
EscapeDefaultState::Char(_) => 1,
597+
EscapeDefaultState::Backslash(_) => 2,
598+
EscapeDefaultState::Unicode(ref iter) => iter.len(),
599+
}
600+
}
601+
}
602+
581603
/// An iterator over `u8` entries represending the UTF-8 encoding of a `char`
582604
/// value.
583605
///

‎src/libcoretest/char.rs

+6
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,12 @@ fn eu_iterator_specializations() {
276276
// Check last
277277
assert_eq!(iter.clone().last(), Some('}'));
278278

279+
// Check len
280+
assert_eq!(iter.len(), len - offset);
281+
282+
// Check size_hint (= len in ExactSizeIterator)
283+
assert_eq!(iter.size_hint(), (iter.len(), Some(iter.len())));
284+
279285
// Check counting
280286
assert_eq!(iter.clone().count(), len - offset);
281287

‎src/librustc/hir/intravisit.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
280280
visitor.visit_path(path, item.id);
281281
}
282282
ViewPathList(ref prefix, ref list) => {
283-
if !list.is_empty() {
284-
for item in list {
285-
visitor.visit_path_list_item(prefix, item)
286-
}
287-
} else {
288-
visitor.visit_path(prefix, item.id);
283+
visitor.visit_path(prefix, item.id);
284+
for item in list {
285+
visitor.visit_path_list_item(prefix, item)
289286
}
290287
}
291288
}
@@ -419,12 +416,8 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
419416
}
420417

421418
pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V,
422-
prefix: &'v Path,
419+
_prefix: &'v Path,
423420
item: &'v PathListItem) {
424-
for segment in &prefix.segments {
425-
visitor.visit_path_segment(prefix.span, segment);
426-
}
427-
428421
walk_opt_name(visitor, item.span, item.node.name());
429422
walk_opt_name(visitor, item.span, item.node.rename());
430423
}

‎src/librustc/infer/mod.rs

+28-5
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
163163
// If the number of errors increases, that's also a sign (line
164164
// `tained_by_errors`) to avoid reporting certain kinds of errors.
165165
err_count_on_creation: usize,
166+
167+
// This flag is used for debugging, and is set to true if there are
168+
// any obligations set during the current snapshot. In that case, the
169+
// snapshot can't be rolled back.
170+
pub obligations_in_snapshot: Cell<bool>,
166171
}
167172

168173
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
@@ -476,7 +481,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
476481
normalize: false,
477482
projection_mode: ProjectionMode::AnyFinal,
478483
tainted_by_errors_flag: Cell::new(false),
479-
err_count_on_creation: self.sess.err_count()
484+
err_count_on_creation: self.sess.err_count(),
485+
obligations_in_snapshot: Cell::new(false),
480486
}
481487
}
482488
}
@@ -515,7 +521,8 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
515521
normalize: normalize,
516522
projection_mode: projection_mode,
517523
tainted_by_errors_flag: Cell::new(false),
518-
err_count_on_creation: tcx.sess.err_count()
524+
err_count_on_creation: tcx.sess.err_count(),
525+
obligations_in_snapshot: Cell::new(false),
519526
}))
520527
}
521528
}
@@ -542,6 +549,7 @@ pub struct CombinedSnapshot {
542549
int_snapshot: unify::Snapshot<ty::IntVid>,
543550
float_snapshot: unify::Snapshot<ty::FloatVid>,
544551
region_vars_snapshot: RegionSnapshot,
552+
obligations_in_snapshot: bool,
545553
}
546554

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

811819
fn start_snapshot(&self) -> CombinedSnapshot {
820+
let obligations_in_snapshot = self.obligations_in_snapshot.get();
821+
self.obligations_in_snapshot.set(false);
822+
812823
CombinedSnapshot {
813824
type_snapshot: self.type_variables.borrow_mut().snapshot(),
814825
int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
815826
float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
816827
region_vars_snapshot: self.region_vars.start_snapshot(),
828+
obligations_in_snapshot: obligations_in_snapshot,
817829
}
818830
}
819831

@@ -822,7 +834,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
822834
let CombinedSnapshot { type_snapshot,
823835
int_snapshot,
824836
float_snapshot,
825-
region_vars_snapshot } = snapshot;
837+
region_vars_snapshot,
838+
obligations_in_snapshot } = snapshot;
839+
840+
assert!(!self.obligations_in_snapshot.get());
841+
self.obligations_in_snapshot.set(obligations_in_snapshot);
826842

827843
self.type_variables
828844
.borrow_mut()
@@ -842,7 +858,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
842858
let CombinedSnapshot { type_snapshot,
843859
int_snapshot,
844860
float_snapshot,
845-
region_vars_snapshot } = snapshot;
861+
region_vars_snapshot,
862+
obligations_in_snapshot } = snapshot;
863+
864+
self.obligations_in_snapshot.set(obligations_in_snapshot);
846865

847866
self.type_variables
848867
.borrow_mut()
@@ -904,12 +923,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
904923
let CombinedSnapshot { type_snapshot,
905924
int_snapshot,
906925
float_snapshot,
907-
region_vars_snapshot } = self.start_snapshot();
926+
region_vars_snapshot,
927+
obligations_in_snapshot } = self.start_snapshot();
908928

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

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

933+
assert!(!self.obligations_in_snapshot.get());
934+
self.obligations_in_snapshot.set(obligations_in_snapshot);
935+
913936
// Roll back any non-region bindings - they should be resolved
914937
// inside `f`, with, e.g. `resolve_type_vars_if_possible`.
915938
self.type_variables

‎src/librustc/traits/fulfill.rs

+2
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
171171
// debug output much nicer to read and so on.
172172
let obligation = infcx.resolve_type_vars_if_possible(&obligation);
173173

174+
infcx.obligations_in_snapshot.set(true);
175+
174176
if infcx.tcx.fulfilled_predicates.borrow().check_duplicate(&obligation.predicate)
175177
{
176178
return

‎src/librustc/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub use self::coherence::overlapping_impls;
3131
pub use self::coherence::OrphanCheckErr;
3232
pub use self::fulfill::{FulfillmentContext, GlobalFulfilledPredicates, RegionObligation};
3333
pub use self::project::{MismatchedProjectionTypes, ProjectionMode};
34-
pub use self::project::{normalize, Normalized};
34+
pub use self::project::{normalize, normalize_projection_type, Normalized};
3535
pub use self::object_safety::ObjectSafetyViolation;
3636
pub use self::object_safety::MethodViolationCode;
3737
pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};

0 commit comments

Comments
 (0)
Please sign in to comment.