about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/liballoc/collections/vec_deque.rs18
-rw-r--r--src/liballoc/tests/binary_heap.rs4
-rw-r--r--src/liballoc/tests/btree/map.rs4
-rw-r--r--src/liballoc/tests/str.rs2
-rw-r--r--src/liballoc/tests/vec_deque.rs8
-rw-r--r--src/libcore/ptr.rs30
-rw-r--r--src/libcore/slice/mod.rs3
-rw-r--r--src/librustc/hir/map/hir_id_validator.rs2
-rw-r--r--src/librustc/mir/mod.rs2
-rw-r--r--src/librustc/ty/context.rs8
-rw-r--r--src/librustc/ty/query/job.rs98
-rw-r--r--src/librustc/util/profiling.rs6
-rw-r--r--src/librustc_apfloat/ieee.rs4
-rw-r--r--src/librustc_driver/test.rs2
-rw-r--r--src/librustc_errors/emitter.rs6
-rw-r--r--src/librustc_incremental/persist/fs.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/values.rs2
-rw-r--r--src/librustc_mir/build/matches/mod.rs2
-rw-r--r--src/librustc_resolve/lib.rs2
-rw-r--r--src/librustc_target/spec/mod.rs2
-rw-r--r--src/librustc_target/spec/thumb_base.rs1
-rw-r--r--src/librustc_target/spec/thumbv8m_main_none_eabi.rs34
-rw-r--r--src/librustc_target/spec/thumbv8m_main_none_eabihf.rs40
-rw-r--r--src/librustdoc/html/render.rs2
-rw-r--r--src/libstd/collections/hash/map.rs8
-rw-r--r--src/libstd/io/buffered.rs2
-rw-r--r--src/libstd/io/mod.rs2
-rw-r--r--src/libstd/sys/windows/process.rs2
-rw-r--r--src/libsyntax/util/lev_distance.rs2
-rw-r--r--src/libsyntax_pos/lib.rs2
30 files changed, 225 insertions, 77 deletions
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index c8ee40f3d27..c0adeca4eb5 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -2795,7 +2795,7 @@ mod tests {
             // 0, 1, 2, .., len - 1
             let expected = (0..).take(len).collect::<VecDeque<_>>();
             for tail_pos in 0..cap {
-                for to_remove in 0..len + 1 {
+                for to_remove in 0..=len {
                     tester.tail = tail_pos;
                     tester.head = tail_pos;
                     for i in 0..len {
@@ -2821,10 +2821,10 @@ mod tests {
         let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
 
         let cap = tester.capacity();
-        for len in 0..cap + 1 {
-            for tail in 0..cap + 1 {
-                for drain_start in 0..len + 1 {
-                    for drain_end in drain_start..len + 1 {
+        for len in 0..=cap {
+            for tail in 0..=cap {
+                for drain_start in 0..=len {
+                    for drain_end in drain_start..=len {
                         tester.tail = tail;
                         tester.head = tail;
                         for i in 0..len {
@@ -2866,10 +2866,10 @@ mod tests {
         tester.reserve(63);
         let max_cap = tester.capacity();
 
-        for len in 0..cap + 1 {
+        for len in 0..=cap {
             // 0, 1, 2, .., len - 1
             let expected = (0..).take(len).collect::<VecDeque<_>>();
-            for tail_pos in 0..max_cap + 1 {
+            for tail_pos in 0..=max_cap {
                 tester.tail = tail_pos;
                 tester.head = tail_pos;
                 tester.reserve(63);
@@ -2899,7 +2899,7 @@ mod tests {
         // len is the length *before* splitting
         for len in 0..cap {
             // index to split at
-            for at in 0..len + 1 {
+            for at in 0..=len {
                 // 0, 1, 2, .., at - 1 (may be empty)
                 let expected_self = (0..).take(at).collect::<VecDeque<_>>();
                 // at, at + 1, .., len - 1 (may be empty)
@@ -2927,7 +2927,7 @@ mod tests {
     fn test_from_vec() {
         use vec::Vec;
         for cap in 0..35 {
-            for len in 0..cap + 1 {
+            for len in 0..=cap {
                 let mut vec = Vec::with_capacity(cap);
                 vec.extend(0..len);
 
diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs
index 8494463463c..b0d8fa6bd69 100644
--- a/src/liballoc/tests/binary_heap.rs
+++ b/src/liballoc/tests/binary_heap.rs
@@ -318,11 +318,11 @@ fn panic_safe() {
     const NTEST: usize = 10;
 
     // don't use 0 in the data -- we want to catch the zeroed-out case.
-    let data = (1..DATASZ + 1).collect::<Vec<_>>();
+    let data = (1..=DATASZ).collect::<Vec<_>>();
 
     // since it's a fuzzy test, run several tries.
     for _ in 0..NTEST {
-        for i in 1..DATASZ + 1 {
+        for i in 1..=DATASZ {
             DROP_COUNTER.store(0, Ordering::SeqCst);
 
             let mut panic_ords: Vec<_> = data.iter()
diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs
index 6ebdb86cc4a..33ef13ab811 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -302,7 +302,7 @@ fn test_range() {
     for i in 0..size {
         for j in i..size {
             let mut kvs = map.range((Included(&i), Included(&j))).map(|(&k, &v)| (k, v));
-            let mut pairs = (i..j + 1).map(|i| (i, i));
+            let mut pairs = (i..=j).map(|i| (i, i));
 
             for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
                 assert_eq!(kv, pair);
@@ -321,7 +321,7 @@ fn test_range_mut() {
     for i in 0..size {
         for j in i..size {
             let mut kvs = map.range_mut((Included(&i), Included(&j))).map(|(&k, &mut v)| (k, v));
-            let mut pairs = (i..j + 1).map(|i| (i, i));
+            let mut pairs = (i..=j).map(|i| (i, i));
 
             for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
                 assert_eq!(kv, pair);
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index a5fa7f0c4d9..494b36f8541 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -1378,7 +1378,7 @@ fn test_bool_from_str() {
 fn check_contains_all_substrings(s: &str) {
     assert!(s.contains(""));
     for i in 0..s.len() {
-        for j in i+1..s.len() + 1 {
+        for j in i+1..=s.len() {
             assert!(s.contains(&s[i..j]));
         }
     }
diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs
index 3ea6c87a651..1f2a7211c65 100644
--- a/src/liballoc/tests/vec_deque.rs
+++ b/src/liballoc/tests/vec_deque.rs
@@ -861,7 +861,7 @@ fn test_as_slices() {
         ring.push_back(i);
 
         let (left, right) = ring.as_slices();
-        let expected: Vec<_> = (0..i + 1).collect();
+        let expected: Vec<_> = (0..=i).collect();
         assert_eq!(left, &expected[..]);
         assert_eq!(right, []);
     }
@@ -869,7 +869,7 @@ fn test_as_slices() {
     for j in -last..0 {
         ring.push_front(j);
         let (left, right) = ring.as_slices();
-        let expected_left: Vec<_> = (-last..j + 1).rev().collect();
+        let expected_left: Vec<_> = (-last..=j).rev().collect();
         let expected_right: Vec<_> = (0..first).collect();
         assert_eq!(left, &expected_left[..]);
         assert_eq!(right, &expected_right[..]);
@@ -889,7 +889,7 @@ fn test_as_mut_slices() {
         ring.push_back(i);
 
         let (left, right) = ring.as_mut_slices();
-        let expected: Vec<_> = (0..i + 1).collect();
+        let expected: Vec<_> = (0..=i).collect();
         assert_eq!(left, &expected[..]);
         assert_eq!(right, []);
     }
@@ -897,7 +897,7 @@ fn test_as_mut_slices() {
     for j in -last..0 {
         ring.push_front(j);
         let (left, right) = ring.as_mut_slices();
-        let expected_left: Vec<_> = (-last..j + 1).rev().collect();
+        let expected_left: Vec<_> = (-last..=j).rev().collect();
         let expected_right: Vec<_> = (0..first).collect();
         assert_eq!(left, &expected_left[..]);
         assert_eq!(right, &expected_right[..]);
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 0387708033b..8630dd402ef 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -2516,6 +2516,36 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
     a == b
 }
 
+/// Hash the raw pointer address behind a reference, rather than the value
+/// it points to.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(ptr_hash)]
+/// use std::collections::hash_map::DefaultHasher;
+/// use std::hash::{Hash, Hasher};
+/// use std::ptr;
+///
+/// let five = 5;
+/// let five_ref = &five;
+///
+/// let mut hasher = DefaultHasher::new();
+/// ptr::hash(five_ref, &mut hasher);
+/// let actual = hasher.finish();
+///
+/// let mut hasher = DefaultHasher::new();
+/// (five_ref as *const i32).hash(&mut hasher);
+/// let expected = hasher.finish();
+///
+/// assert_eq!(actual, expected);
+/// ```
+#[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")]
+pub fn hash<T, S: hash::Hasher>(hashee: *const T, into: &mut S) {
+    use hash::Hash;
+    hashee.hash(into);
+}
+
 // Impls for function pointers
 macro_rules! fnptr_impls_safety_abi {
     ($FnTy: ty, $($Arg: ident),*) => {
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 8c55a16f3c8..5b57dcabb8d 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -702,8 +702,7 @@ impl<T> [T] {
     /// resulting code better than in the case of [`chunks`].
     ///
     /// See [`chunks`] for a variant of this iterator that also returns the remainder as a smaller
-    /// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice of
-    /// the slice.
+    /// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice.
     ///
     /// # Panics
     ///
diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs
index ac4119dc372..58d1a780f12 100644
--- a/src/librustc/hir/map/hir_id_validator.rs
+++ b/src/librustc/hir/map/hir_id_validator.rs
@@ -100,7 +100,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
 
         if max != self.hir_ids_seen.len() - 1 {
             // Collect the missing ItemLocalIds
-            let missing: Vec<_> = (0 .. max as u32 + 1)
+            let missing: Vec<_> = (0 ..= max as u32)
               .filter(|&i| !self.hir_ids_seen.contains_key(&ItemLocalId::from_u32(i)))
               .collect();
 
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 91663557409..7259bbfb780 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -339,7 +339,7 @@ impl<'tcx> Mir<'tcx> {
     #[inline]
     pub fn args_iter(&self) -> impl Iterator<Item = Local> {
         let arg_count = self.arg_count;
-        (1..arg_count + 1).map(Local::new)
+        (1..=arg_count).map(Local::new)
     }
 
     /// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index f0411924131..bd8b3e678d8 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1942,8 +1942,12 @@ pub mod tls {
     /// This is a callback from libsyntax as it cannot access the implicit state
     /// in librustc otherwise
     fn span_debug(span: syntax_pos::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        with(|tcx| {
-            write!(f, "{}", tcx.sess.source_map().span_to_string(span))
+        with_opt(|tcx| {
+            if let Some(tcx) = tcx {
+                write!(f, "{}", tcx.sess.source_map().span_to_string(span))
+            } else {
+                syntax_pos::default_span_debug(span, f)
+            }
         })
     }
 
diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs
index d588bc8c0cb..1439e41bb31 100644
--- a/src/librustc/ty/query/job.rs
+++ b/src/librustc/ty/query/job.rs
@@ -103,8 +103,11 @@ impl<'tcx> QueryJob<'tcx> {
                     condvar: Condvar::new(),
                 });
                 self.latch.await(&waiter);
-
-                match Lrc::get_mut(&mut waiter).unwrap().cycle.get_mut().take() {
+                // FIXME: Get rid of this lock. We have ownership of the QueryWaiter
+                // although another thread may still have a Lrc reference so we cannot
+                // use Lrc::get_mut
+                let mut cycle = waiter.cycle.lock();
+                match cycle.take() {
                     None => Ok(()),
                     Some(cycle) => Err(cycle)
                 }
@@ -326,19 +329,17 @@ fn connected_to_root<'tcx>(
     query: Lrc<QueryJob<'tcx>>,
     visited: &mut FxHashSet<*const QueryJob<'tcx>>
 ) -> bool {
-    // This query is connected to the root (it has no query parent), return true
-    if query.parent.is_none() {
-        return true;
-    }
-
     // We already visited this or we're deliberately ignoring it
     if visited.contains(&query.as_ptr()) {
         return false;
     }
 
-    visited.insert(query.as_ptr());
+    // This query is connected to the root (it has no query parent), return true
+    if query.parent.is_none() {
+        return true;
+    }
 
-    let mut connected = false;
+    visited.insert(query.as_ptr());
 
     visit_waiters(query, |_, successor| {
         if connected_to_root(successor, visited) {
@@ -349,6 +350,28 @@ fn connected_to_root<'tcx>(
     }).is_some()
 }
 
+// Deterministically pick an query from a list
+#[cfg(parallel_queries)]
+fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, Lrc<QueryJob<'tcx>>)>(
+    tcx: TyCtxt<'_, 'tcx, '_>,
+    queries: &'a [T],
+    f: F
+) -> &'a T {
+    // Deterministically pick an entry point
+    // FIXME: Sort this instead
+    let mut hcx = tcx.create_stable_hashing_context();
+    queries.iter().min_by_key(|v| {
+        let (span, query) = f(v);
+        let mut stable_hasher = StableHasher::<u64>::new();
+        query.info.query.hash_stable(&mut hcx, &mut stable_hasher);
+        // Prefer entry points which have valid spans for nicer error messages
+        // We add an integer to the tuple ensuring that entry points
+        // with valid spans are picked first
+        let span_cmp = if span == DUMMY_SP { 1 } else { 0 };
+        (span_cmp, stable_hasher.finish())
+    }).unwrap()
+}
+
 /// Looks for query cycles starting from the last query in `jobs`.
 /// If a cycle is found, all queries in the cycle is removed from `jobs` and
 /// the function return true.
@@ -388,41 +411,52 @@ fn remove_cycle<'tcx>(
 
         // Find the queries in the cycle which are
         // connected to queries outside the cycle
-        let entry_points = stack.iter().filter_map(|query| {
-            // Mark all the other queries in the cycle as already visited
-            let mut visited = FxHashSet::from_iter(stack.iter().filter_map(|q| {
-                if q.1.as_ptr() != query.1.as_ptr() {
-                    Some(q.1.as_ptr())
-                } else {
+        let entry_points: Vec<_> = stack.iter().filter_map(|(span, query)| {
+            if query.parent.is_none() {
+                // This query is connected to the root (it has no query parent)
+                Some((*span, query.clone(), None))
+            } else {
+                let mut waiters = Vec::new();
+                // Find all the direct waiters who lead to the root
+                visit_waiters(query.clone(), |span, waiter| {
+                    // Mark all the other queries in the cycle as already visited
+                    let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1.as_ptr()));
+
+                    if connected_to_root(waiter.clone(), &mut visited) {
+                        waiters.push((span, waiter));
+                    }
+
+                    None
+                });
+                if waiters.is_empty() {
                     None
+                } else {
+                    // Deterministically pick one of the waiters to show to the user
+                    let waiter = pick_query(tcx, &waiters, |s| s.clone()).clone();
+                    Some((*span, query.clone(), Some(waiter)))
                 }
-            }));
-
-            if connected_to_root(query.1.clone(), &mut visited) {
-                Some(query.1.clone())
-            } else {
-                None
             }
-        });
+        }).collect();
+
+        let entry_points: Vec<(Span, Lrc<QueryJob<'tcx>>, Option<(Span, Lrc<QueryJob<'tcx>>)>)>
+         = entry_points;
 
         // Deterministically pick an entry point
-        // FIXME: Sort this instead
-        let mut hcx = tcx.create_stable_hashing_context();
-        let entry_point = entry_points.min_by_key(|q| {
-            let mut stable_hasher = StableHasher::<u64>::new();
-            q.info.query.hash_stable(&mut hcx, &mut stable_hasher);
-            stable_hasher.finish()
-        }).unwrap().as_ptr();
+        let (_, entry_point, usage) = pick_query(tcx, &entry_points, |e| (e.0, e.1.clone()));
 
         // Shift the stack so that our entry point is first
-        let entry_point_pos = stack.iter().position(|(_, query)| query.as_ptr() == entry_point);
+        let entry_point_pos = stack.iter().position(|(_, query)| {
+            query.as_ptr() == entry_point.as_ptr()
+        });
         if let Some(pos) = entry_point_pos {
-            stack.rotate_right(pos);
+            stack.rotate_left(pos);
         }
 
+        let usage = usage.as_ref().map(|(span, query)| (*span, query.info.query.clone()));
+
         // Create the cycle error
         let mut error = CycleError {
-            usage: None,
+            usage,
             cycle: stack.iter().map(|&(s, ref q)| QueryInfo {
                 span: s,
                 query: q.info.query.clone(),
diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs
index bea3453b31a..1e648c45817 100644
--- a/src/librustc/util/profiling.rs
+++ b/src/librustc/util/profiling.rs
@@ -11,7 +11,7 @@
 use session::config::Options;
 
 use std::fs;
-use std::io::{self, StdoutLock, Write};
+use std::io::{self, StderrLock, Write};
 use std::time::{Duration, Instant};
 
 macro_rules! define_categories {
@@ -61,7 +61,7 @@ macro_rules! define_categories {
                 }
             }
 
-            fn print(&self, lock: &mut StdoutLock<'_>) {
+            fn print(&self, lock: &mut StderrLock<'_>) {
                 writeln!(lock, "| Phase            | Time (ms)      | Queries        | Hits (%) |")
                     .unwrap();
                 writeln!(lock, "| ---------------- | -------------- | -------------- | -------- |")
@@ -235,7 +235,7 @@ impl SelfProfiler {
             self.timer_stack.is_empty(),
             "there were timers running when print_results() was called");
 
-        let out = io::stdout();
+        let out = io::stderr();
         let mut lock = out.lock();
 
         let crate_name =
diff --git a/src/librustc_apfloat/ieee.rs b/src/librustc_apfloat/ieee.rs
index adcb9857ee3..2ad83fc93ef 100644
--- a/src/librustc_apfloat/ieee.rs
+++ b/src/librustc_apfloat/ieee.rs
@@ -571,7 +571,7 @@ impl<S: Semantics> fmt::Display for IeeeFloat<S> {
             }
             // Fill with zeros up to precision.
             if !truncate_zero && precision > digits - 1 {
-                for _ in 0..precision - digits + 1 {
+                for _ in 0..=precision - digits {
                     f.write_char('0')?;
                 }
             }
@@ -1969,7 +1969,7 @@ impl<S: Semantics> IeeeFloat<S> {
         // in a Limb. When this would overflow do we do a single
         // bignum multiplication, and then revert again to multiplication
         // in a Limb.
-        let mut chars = s[first_sig_digit..last_sig_digit + 1].chars();
+        let mut chars = s[first_sig_digit..=last_sig_digit].chars();
         loop {
             let mut val = 0;
             let mut multiplier = 1;
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index b8cd9bda7f0..2b6bb34b146 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -98,7 +98,7 @@ fn errors(msgs: &[&str]) -> (Box<dyn Emitter + sync::Send>, usize) {
 
 fn test_env<F>(source_string: &str, args: (Box<dyn Emitter + sync::Send>, usize), body: F)
 where
-    F: FnOnce(Env),
+    F: FnOnce(Env) + sync::Send,
 {
     syntax::with_globals(|| {
         let mut options = config::Options::default();
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index ab2ab25c91a..ae9f6a5e140 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -549,7 +549,7 @@ impl EmitterWriter {
         // 3 |
         // 4 |   }
         //   |
-        for pos in 0..line_len + 1 {
+        for pos in 0..=line_len {
             draw_col_separator(buffer, line_offset + pos + 1, width_offset - 2);
             buffer.putc(line_offset + pos + 1,
                         width_offset - 2,
@@ -617,7 +617,7 @@ impl EmitterWriter {
             let pos = pos + 1;
 
             if pos > 1 && (annotation.has_label() || annotation.takes_space()) {
-                for p in line_offset + 1..line_offset + pos + 1 {
+                for p in line_offset + 1..=line_offset + pos {
                     buffer.putc(p,
                                 code_offset + annotation.start_col,
                                 '|',
@@ -634,7 +634,7 @@ impl EmitterWriter {
                     }
                 }
                 AnnotationType::MultilineEnd(depth) => {
-                    for p in line_offset..line_offset + pos + 1 {
+                    for p in line_offset..=line_offset + pos {
                         buffer.putc(p,
                                     width_offset + depth - 1,
                                     '|',
diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs
index bc98798f772..11ce10fd4a7 100644
--- a/src/librustc_incremental/persist/fs.rs
+++ b/src/librustc_incremental/persist/fs.rs
@@ -354,7 +354,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
     }
 
     // State: "s-{timestamp}-{random-number}-"
-    let mut new_sub_dir_name = String::from(&old_sub_dir_name[.. dash_indices[2] + 1]);
+    let mut new_sub_dir_name = String::from(&old_sub_dir_name[..= dash_indices[2]]);
 
     // Append the svh
     base_n::push_str(svh.as_u64() as u128, INT_ENCODE_BASE, &mut new_sub_dir_name);
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs
index 69e2c896d33..c7512f4b67f 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs
@@ -48,7 +48,7 @@ impl RegionValueElements {
 
         let mut basic_blocks = IndexVec::with_capacity(num_points);
         for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
-            basic_blocks.extend((0..bb_data.statements.len() + 1).map(|_| bb));
+            basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb));
         }
 
         Self {
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 342aaf9039d..172ff95ed10 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -101,7 +101,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
         // create binding start block for link them by false edges
         let candidate_count = arms.iter().fold(0, |ac, c| ac + c.patterns.len());
-        let pre_binding_blocks: Vec<_> = (0..candidate_count + 1)
+        let pre_binding_blocks: Vec<_> = (0..=candidate_count)
             .map(|_| self.cfg.start_new_block())
             .collect();
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 4fa6dd7409f..389be3f758e 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3617,7 +3617,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             let res = self.smart_resolve_path_fragment(
                 id,
                 None,
-                &path[..qself.position + 1],
+                &path[..=qself.position],
                 span,
                 PathSource::TraitItem(ns),
                 CrateLint::QPathTrait {
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 5830fa00be8..a9aa721f5c3 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -400,6 +400,8 @@ supported_targets! {
     ("thumbv7em-none-eabi", thumbv7em_none_eabi),
     ("thumbv7em-none-eabihf", thumbv7em_none_eabihf),
     ("thumbv8m.base-none-eabi", thumbv8m_base_none_eabi),
+    ("thumbv8m.main-none-eabi", thumbv8m_main_none_eabi),
+    ("thumbv8m.main-none-eabihf", thumbv8m_main_none_eabihf),
 
     ("msp430-none-elf", msp430_none_elf),
 
diff --git a/src/librustc_target/spec/thumb_base.rs b/src/librustc_target/spec/thumb_base.rs
index 22e5f49fd59..a5c4b8925e2 100644
--- a/src/librustc_target/spec/thumb_base.rs
+++ b/src/librustc_target/spec/thumb_base.rs
@@ -18,6 +18,7 @@
 // - Cortex-M4(F)
 // - Cortex-M7(F)
 // - Cortex-M23
+// - Cortex-M33
 //
 // We have opted for these instead of one target per processor (e.g. `cortex-m0`, `cortex-m3`,
 // etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost
diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabi.rs b/src/librustc_target/spec/thumbv8m_main_none_eabi.rs
new file mode 100644
index 00000000000..6dc203e81bf
--- /dev/null
+++ b/src/librustc_target/spec/thumbv8m_main_none_eabi.rs
@@ -0,0 +1,34 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile),
+// without the Floating Point extension.
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "thumbv8m.main-none-eabi".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "none".to_string(),
+        target_env: String::new(),
+        target_vendor: String::new(),
+        linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
+
+        options: TargetOptions {
+            max_atomic_width: Some(32),
+            .. super::thumb_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs
new file mode 100644
index 00000000000..dc7728c2bd5
--- /dev/null
+++ b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs
@@ -0,0 +1,40 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile),
+// with the Floating Point extension.
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "thumbv8m.main-none-eabihf".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "none".to_string(),
+        target_env: String::new(),
+        target_vendor: String::new(),
+        linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
+
+        options: TargetOptions {
+            // If the Floating Point extension is implemented in the Cortex-M33
+            // processor, the Cortex-M33 Technical Reference Manual states that
+            // the FPU uses the FPv5 architecture, single-precision instructions
+            // and 16 D registers.
+            // These parameters map to the following LLVM features.
+            features: "+fp-armv8,+fp-only-sp,+d16".to_string(),
+            max_atomic_width: Some(32),
+            .. super::thumb_base::opts()
+        },
+    })
+}
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 6158815fb9a..30054f66e2f 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -4798,7 +4798,7 @@ impl<'a> fmt::Display for Source<'a> {
             tmp /= 10;
         }
         write!(fmt, "<pre class=\"line-numbers\">")?;
-        for i in 1..lines + 1 {
+        for i in 1..=lines {
             write!(fmt, "<span id=\"{0}\">{0:1$}</span>\n", i, cols)?;
         }
         write!(fmt, "</pre>")?;
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 536ce2e16a0..55a1a75d049 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -11,6 +11,7 @@
 use self::Entry::*;
 use self::VacantEntryState::*;
 
+use intrinsics::unlikely;
 use collections::CollectionAllocErr;
 use cell::Cell;
 use borrow::Borrow;
@@ -1992,6 +1993,9 @@ impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S>
     fn search<F>(self, hash: u64, is_match: F, compare_hashes: bool) -> Option<(&'a K, &'a V)>
         where F: FnMut(&K) -> bool
     {
+        if unsafe { unlikely(self.map.table.size() == 0) } {
+            return None;
+        }
         match search_hashed_nonempty(&self.map.table,
                                      SafeHash::new(hash),
                                      is_match,
@@ -3610,7 +3614,7 @@ mod test_map {
             for i in 1..1001 {
                 assert!(m.insert(i, i).is_none());
 
-                for j in 1..i + 1 {
+                for j in 1..=i {
                     let r = m.get(&j);
                     assert_eq!(r, Some(&j));
                 }
@@ -3629,7 +3633,7 @@ mod test_map {
             for i in 1..1001 {
                 assert!(m.remove(&i).is_some());
 
-                for j in 1..i + 1 {
+                for j in 1..=i {
                     assert!(!m.contains_key(&j));
                 }
 
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 476ee3f71ca..7ede050da6c 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -918,7 +918,7 @@ impl<W: Write> Write for LineWriter<W> {
         // some data then we *must* report that we wrote that data, so future
         // errors are ignored. We set our internal `need_flush` flag, though, in
         // case flushing fails and we need to try it first next time.
-        let n = self.inner.write(&buf[..i + 1])?;
+        let n = self.inner.write(&buf[..=i])?;
         self.need_flush = true;
         if self.flush().is_err() || n != i + 1 {
             return Ok(n)
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 076524e624a..dc97701d889 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -1261,7 +1261,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
             };
             match memchr::memchr(delim, available) {
                 Some(i) => {
-                    buf.extend_from_slice(&available[..i + 1]);
+                    buf.extend_from_slice(&available[..=i]);
                     (true, i + 1)
                 }
                 None => {
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index ff1ee0d26fe..03c1bb54af8 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -487,7 +487,7 @@ fn make_command_line(prog: &OsStr, args: &[OsString]) -> io::Result<Vec<u16>> {
             } else {
                 if x == '"' as u16 {
                     // Add n+1 backslashes to total 2n+1 before internal '"'.
-                    cmd.extend((0..(backslashes + 1)).map(|_| '\\' as u16));
+                    cmd.extend((0..=backslashes).map(|_| '\\' as u16));
                 }
                 backslashes = 0;
             }
diff --git a/src/libsyntax/util/lev_distance.rs b/src/libsyntax/util/lev_distance.rs
index fb281154be0..e6b81a59d86 100644
--- a/src/libsyntax/util/lev_distance.rs
+++ b/src/libsyntax/util/lev_distance.rs
@@ -20,7 +20,7 @@ pub fn lev_distance(a: &str, b: &str) -> usize {
         return a.chars().count();
     }
 
-    let mut dcol: Vec<_> = (0..b.len() + 1).collect();
+    let mut dcol: Vec<_> = (0..=b.len()).collect();
     let mut t_last = 0;
 
     for (i, sc) in a.chars().enumerate() {
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 4d42b85ea75..4e3d1e89a72 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -611,7 +611,7 @@ impl serialize::UseSpecializedDecodable for Span {
     }
 }
 
-fn default_span_debug(span: Span, f: &mut fmt::Formatter) -> fmt::Result {
+pub fn default_span_debug(span: Span, f: &mut fmt::Formatter) -> fmt::Result {
     f.debug_struct("Span")
         .field("lo", &span.lo())
         .field("hi", &span.hi())