about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-06-10 00:48:35 +0000
committerbors <bors@rust-lang.org>2020-06-10 00:48:35 +0000
commitbb8674837a9cc5225020e07fc3f164762bb4c11c (patch)
treef94c254be282b464db805e6fa9042266d66c47b9
parent283522400b5c13dfdf2b7e608e63a70ee8e3d7af (diff)
parent74380d712d76c8bf48493f751ffda745bf78ecbc (diff)
downloadrust-bb8674837a9cc5225020e07fc3f164762bb4c11c.tar.gz
rust-bb8674837a9cc5225020e07fc3f164762bb4c11c.zip
Auto merge of #73190 - Dylan-DPC:rollup-9wbyh4y, r=Dylan-DPC
Rollup of 8 pull requests

Successful merges:

 - #72417 (Remove `RawVec::reserve_in_place`.)
 - #73098 (Add Item::is_fake for rustdoc)
 - #73122 (Resolve E0584 conflict)
 - #73123 (Clean up E0647 explanation)
 - #73133 (Enforce unwind invariants)
 - #73148 (Fix a typo (size of the size))
 - #73149 (typo: awailable -> available)
 - #73161 (Add mailmap entry)

Failed merges:

r? @ghost
-rw-r--r--.mailmap1
-rw-r--r--src/doc/unstable-book/src/compiler-flags/report-time.md2
-rw-r--r--src/liballoc/raw_vec.rs122
-rw-r--r--src/liballoc/vec.rs8
-rw-r--r--src/libcore/slice/mod.rs4
-rw-r--r--src/librustc_arena/lib.rs86
-rw-r--r--src/librustc_error_codes/error_codes.rs1
-rw-r--r--src/librustc_error_codes/error_codes/E0583.md2
-rw-r--r--src/librustc_error_codes/error_codes/E0647.md3
-rw-r--r--src/librustc_error_codes/error_codes/E0761.md25
-rw-r--r--src/librustc_expand/module.rs2
-rw-r--r--src/librustc_mir/transform/validate.rs67
-rw-r--r--src/librustdoc/clean/types.rs11
-rw-r--r--src/libtest/cli.rs2
-rw-r--r--src/test/ui/mod/mod_file_disambig.stderr4
15 files changed, 172 insertions, 168 deletions
diff --git a/.mailmap b/.mailmap
index 9639c117496..15ca403456a 100644
--- a/.mailmap
+++ b/.mailmap
@@ -266,6 +266,7 @@ Tim Chevalier <chevalier@alum.wellesley.edu> <catamorphism@gmail.com>
 Tim JIANG <p90eri@gmail.com>
 Tim Joseph Dumol <tim@timdumol.com>
 Torsten Weber <TorstenWeber12@gmail.com> <torstenweber12@gmail.com>
+Trevor Spiteri <tspiteri@ieee.org> <trevor.spiteri@um.edu.mt>
 Ty Overby <ty@pre-alpha.com>
 Ulrik Sverdrup <bluss@users.noreply.github.com> bluss <bluss@users.noreply.github.com>
 Ulrik Sverdrup <bluss@users.noreply.github.com> bluss <bluss>
diff --git a/src/doc/unstable-book/src/compiler-flags/report-time.md b/src/doc/unstable-book/src/compiler-flags/report-time.md
index ed4e9c6b568..68265d8a9e8 100644
--- a/src/doc/unstable-book/src/compiler-flags/report-time.md
+++ b/src/doc/unstable-book/src/compiler-flags/report-time.md
@@ -22,7 +22,7 @@ Available options:
 
 ```sh
 --report-time [plain|colored]
-                Show execution time of each test. Awailable values:
+                Show execution time of each test. Available values:
                 plain = do not colorize the execution time (default);
                 colored = colorize output according to the `color`
                 parameter value;
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index 5b365f0387a..805dbfe2775 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -9,7 +9,7 @@ use core::ptr::{NonNull, Unique};
 use core::slice;
 
 use crate::alloc::{
-    handle_alloc_error, AllocErr,
+    handle_alloc_error,
     AllocInit::{self, *},
     AllocRef, Global, Layout,
     ReallocPlacement::{self, *},
@@ -235,13 +235,13 @@ impl<T, A: AllocRef> RawVec<T, A> {
         }
     }
 
-    /// Ensures that the buffer contains at least enough space to hold
-    /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have
-    /// enough capacity, will reallocate enough space plus comfortable slack
-    /// space to get amortized `O(1)` behavior. Will limit this behavior
-    /// if it would needlessly cause itself to panic.
+    /// Ensures that the buffer contains at least enough space to hold `len +
+    /// additional` elements. If it doesn't already have enough capacity, will
+    /// reallocate enough space plus comfortable slack space to get amortized
+    /// `O(1)` behavior. Will limit this behavior if it would needlessly cause
+    /// itself to panic.
     ///
-    /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate
+    /// If `len` exceeds `self.capacity()`, this may fail to actually allocate
     /// the requested space. This is not really unsafe, but the unsafe
     /// code *you* write that relies on the behavior of this function may break.
     ///
@@ -287,8 +287,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
     /// #   vector.push_all(&[1, 3, 5, 7, 9]);
     /// # }
     /// ```
-    pub fn reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
-        match self.try_reserve(used_capacity, needed_extra_capacity) {
+    pub fn reserve(&mut self, len: usize, additional: usize) {
+        match self.try_reserve(len, additional) {
             Err(CapacityOverflow) => capacity_overflow(),
             Err(AllocError { layout, .. }) => handle_alloc_error(layout),
             Ok(()) => { /* yay */ }
@@ -296,55 +296,23 @@ impl<T, A: AllocRef> RawVec<T, A> {
     }
 
     /// The same as `reserve`, but returns on errors instead of panicking or aborting.
-    pub fn try_reserve(
-        &mut self,
-        used_capacity: usize,
-        needed_extra_capacity: usize,
-    ) -> Result<(), TryReserveError> {
-        if self.needs_to_grow(used_capacity, needed_extra_capacity) {
-            self.grow_amortized(used_capacity, needed_extra_capacity, MayMove)
+    pub fn try_reserve(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
+        if self.needs_to_grow(len, additional) {
+            self.grow_amortized(len, additional)
         } else {
             Ok(())
         }
     }
 
-    /// Attempts to ensure that the buffer contains at least enough space to hold
-    /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have
-    /// enough capacity, will reallocate in place enough space plus comfortable slack
-    /// space to get amortized `O(1)` behavior. Will limit this behaviour
-    /// if it would needlessly cause itself to panic.
+    /// Ensures that the buffer contains at least enough space to hold `len +
+    /// additional` elements. If it doesn't already, will reallocate the
+    /// minimum possible amount of memory necessary. Generally this will be
+    /// exactly the amount of memory necessary, but in principle the allocator
+    /// is free to give back more than we asked for.
     ///
-    /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate
-    /// the requested space. This is not really unsafe, but the unsafe
-    /// code *you* write that relies on the behavior of this function may break.
-    ///
-    /// Returns `true` if the reallocation attempt has succeeded.
-    ///
-    /// # Panics
-    ///
-    /// * Panics if the requested capacity exceeds `usize::MAX` bytes.
-    /// * Panics on 32-bit platforms if the requested capacity exceeds
-    ///   `isize::MAX` bytes.
-    pub fn reserve_in_place(&mut self, used_capacity: usize, needed_extra_capacity: usize) -> bool {
-        // This is more readable than putting this in one line:
-        // `!self.needs_to_grow(...) || self.grow(...).is_ok()`
-        if self.needs_to_grow(used_capacity, needed_extra_capacity) {
-            self.grow_amortized(used_capacity, needed_extra_capacity, InPlace).is_ok()
-        } else {
-            true
-        }
-    }
-
-    /// Ensures that the buffer contains at least enough space to hold
-    /// `used_capacity + needed_extra_capacity` elements. If it doesn't already,
-    /// will reallocate the minimum possible amount of memory necessary.
-    /// Generally this will be exactly the amount of memory necessary,
-    /// but in principle the allocator is free to give back more than what
-    /// we asked for.
-    ///
-    /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate
-    /// the requested space. This is not really unsafe, but the unsafe
-    /// code *you* write that relies on the behavior of this function may break.
+    /// If `len` exceeds `self.capacity()`, this may fail to actually allocate
+    /// the requested space. This is not really unsafe, but the unsafe code
+    /// *you* write that relies on the behavior of this function may break.
     ///
     /// # Panics
     ///
@@ -355,8 +323,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
     /// # Aborts
     ///
     /// Aborts on OOM.
-    pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
-        match self.try_reserve_exact(used_capacity, needed_extra_capacity) {
+    pub fn reserve_exact(&mut self, len: usize, additional: usize) {
+        match self.try_reserve_exact(len, additional) {
             Err(CapacityOverflow) => capacity_overflow(),
             Err(AllocError { layout, .. }) => handle_alloc_error(layout),
             Ok(()) => { /* yay */ }
@@ -366,14 +334,10 @@ impl<T, A: AllocRef> RawVec<T, A> {
     /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting.
     pub fn try_reserve_exact(
         &mut self,
-        used_capacity: usize,
-        needed_extra_capacity: usize,
+        len: usize,
+        additional: usize,
     ) -> Result<(), TryReserveError> {
-        if self.needs_to_grow(used_capacity, needed_extra_capacity) {
-            self.grow_exact(used_capacity, needed_extra_capacity)
-        } else {
-            Ok(())
-        }
+        if self.needs_to_grow(len, additional) { self.grow_exact(len, additional) } else { Ok(()) }
     }
 
     /// Shrinks the allocation down to the specified amount. If the given amount
@@ -398,8 +362,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
 impl<T, A: AllocRef> RawVec<T, A> {
     /// Returns if the buffer needs to grow to fulfill the needed extra capacity.
     /// Mainly used to make inlining reserve-calls possible without inlining `grow`.
-    fn needs_to_grow(&self, used_capacity: usize, needed_extra_capacity: usize) -> bool {
-        needed_extra_capacity > self.capacity().wrapping_sub(used_capacity)
+    fn needs_to_grow(&self, len: usize, additional: usize) -> bool {
+        additional > self.capacity().wrapping_sub(len)
     }
 
     fn capacity_from_bytes(excess: usize) -> usize {
@@ -419,14 +383,9 @@ impl<T, A: AllocRef> RawVec<T, A> {
     // so that all of the code that depends on `T` is within it, while as much
     // of the code that doesn't depend on `T` as possible is in functions that
     // are non-generic over `T`.
-    fn grow_amortized(
-        &mut self,
-        used_capacity: usize,
-        needed_extra_capacity: usize,
-        placement: ReallocPlacement,
-    ) -> Result<(), TryReserveError> {
+    fn grow_amortized(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
         // This is ensured by the calling contexts.
-        debug_assert!(needed_extra_capacity > 0);
+        debug_assert!(additional > 0);
 
         if mem::size_of::<T>() == 0 {
             // Since we return a capacity of `usize::MAX` when `elem_size` is
@@ -435,8 +394,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
         }
 
         // Nothing we can really do about these checks, sadly.
-        let required_cap =
-            used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?;
+        let required_cap = len.checked_add(additional).ok_or(CapacityOverflow)?;
 
         // This guarantees exponential growth. The doubling cannot overflow
         // because `cap <= isize::MAX` and the type of `cap` is `usize`.
@@ -461,7 +419,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
         let new_layout = Layout::array::<T>(cap);
 
         // `finish_grow` is non-generic over `T`.
-        let memory = finish_grow(new_layout, placement, self.current_memory(), &mut self.alloc)?;
+        let memory = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
         self.set_memory(memory);
         Ok(())
     }
@@ -469,22 +427,18 @@ impl<T, A: AllocRef> RawVec<T, A> {
     // The constraints on this method are much the same as those on
     // `grow_amortized`, but this method is usually instantiated less often so
     // it's less critical.
-    fn grow_exact(
-        &mut self,
-        used_capacity: usize,
-        needed_extra_capacity: usize,
-    ) -> Result<(), TryReserveError> {
+    fn grow_exact(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
         if mem::size_of::<T>() == 0 {
             // Since we return a capacity of `usize::MAX` when the type size is
             // 0, getting to here necessarily means the `RawVec` is overfull.
             return Err(CapacityOverflow);
         }
 
-        let cap = used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?;
+        let cap = len.checked_add(additional).ok_or(CapacityOverflow)?;
         let new_layout = Layout::array::<T>(cap);
 
         // `finish_grow` is non-generic over `T`.
-        let memory = finish_grow(new_layout, MayMove, self.current_memory(), &mut self.alloc)?;
+        let memory = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
         self.set_memory(memory);
         Ok(())
     }
@@ -518,7 +472,6 @@ impl<T, A: AllocRef> RawVec<T, A> {
 // much smaller than the number of `T` types.)
 fn finish_grow<A>(
     new_layout: Result<Layout, LayoutErr>,
-    placement: ReallocPlacement,
     current_memory: Option<(NonNull<u8>, Layout)>,
     alloc: &mut A,
 ) -> Result<MemoryBlock, TryReserveError>
@@ -532,12 +485,9 @@ where
 
     let memory = if let Some((ptr, old_layout)) = current_memory {
         debug_assert_eq!(old_layout.align(), new_layout.align());
-        unsafe { alloc.grow(ptr, old_layout, new_layout.size(), placement, Uninitialized) }
+        unsafe { alloc.grow(ptr, old_layout, new_layout.size(), MayMove, Uninitialized) }
     } else {
-        match placement {
-            MayMove => alloc.alloc(new_layout, Uninitialized),
-            InPlace => Err(AllocErr),
-        }
+        alloc.alloc(new_layout, Uninitialized)
     }
     .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?;
 
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index af943ecfd48..2226737757b 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -2977,12 +2977,12 @@ impl<T> Drain<'_, T> {
     }
 
     /// Makes room for inserting more elements before the tail.
-    unsafe fn move_tail(&mut self, extra_capacity: usize) {
+    unsafe fn move_tail(&mut self, additional: usize) {
         let vec = self.vec.as_mut();
-        let used_capacity = self.tail_start + self.tail_len;
-        vec.buf.reserve(used_capacity, extra_capacity);
+        let len = self.tail_start + self.tail_len;
+        vec.buf.reserve(len, additional);
 
-        let new_tail_start = self.tail_start + extra_capacity;
+        let new_tail_start = self.tail_start + additional;
         let src = vec.as_ptr().add(self.tail_start);
         let dst = vec.as_mut_ptr().add(new_tail_start);
         ptr::copy(src, dst, self.tail_len);
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index ff333f77334..4efb1db7a1a 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -409,7 +409,7 @@ impl<T> [T] {
     /// The returned range is half-open, which means that the end pointer
     /// points *one past* the last element of the slice. This way, an empty
     /// slice is represented by two equal pointers, and the difference between
-    /// the two pointers represents the size of the size.
+    /// the two pointers represents the size of the slice.
     ///
     /// See [`as_ptr`] for warnings on using these pointers. The end pointer
     /// requires extra caution, as it does not point to a valid element in the
@@ -464,7 +464,7 @@ impl<T> [T] {
     /// The returned range is half-open, which means that the end pointer
     /// points *one past* the last element of the slice. This way, an empty
     /// slice is represented by two equal pointers, and the difference between
-    /// the two pointers represents the size of the size.
+    /// the two pointers represents the size of the slice.
     ///
     /// See [`as_mut_ptr`] for warnings on using these pointers. The end
     /// pointer requires extra caution, as it does not point to a valid element
diff --git a/src/librustc_arena/lib.rs b/src/librustc_arena/lib.rs
index bbe80c26dcb..4da336f8e28 100644
--- a/src/librustc_arena/lib.rs
+++ b/src/librustc_arena/lib.rs
@@ -146,18 +146,18 @@ impl<T> TypedArena<T> {
     }
 
     #[inline]
-    fn can_allocate(&self, len: usize) -> bool {
-        let available_capacity_bytes = self.end.get() as usize - self.ptr.get() as usize;
-        let at_least_bytes = len.checked_mul(mem::size_of::<T>()).unwrap();
-        available_capacity_bytes >= at_least_bytes
+    fn can_allocate(&self, additional: usize) -> bool {
+        let available_bytes = self.end.get() as usize - self.ptr.get() as usize;
+        let additional_bytes = additional.checked_mul(mem::size_of::<T>()).unwrap();
+        available_bytes >= additional_bytes
     }
 
     /// Ensures there's enough space in the current chunk to fit `len` objects.
     #[inline]
-    fn ensure_capacity(&self, len: usize) {
-        if !self.can_allocate(len) {
-            self.grow(len);
-            debug_assert!(self.can_allocate(len));
+    fn ensure_capacity(&self, additional: usize) {
+        if !self.can_allocate(additional) {
+            self.grow(additional);
+            debug_assert!(self.can_allocate(additional));
         }
     }
 
@@ -214,36 +214,31 @@ impl<T> TypedArena<T> {
     /// Grows the arena.
     #[inline(never)]
     #[cold]
-    fn grow(&self, n: usize) {
+    fn grow(&self, additional: usize) {
         unsafe {
-            // We need the element size in to convert chunk sizes (ranging from
+            // We need the element size to convert chunk sizes (ranging from
             // PAGE to HUGE_PAGE bytes) to element counts.
             let elem_size = cmp::max(1, mem::size_of::<T>());
             let mut chunks = self.chunks.borrow_mut();
-            let (chunk, mut new_capacity);
+            let mut new_cap;
             if let Some(last_chunk) = chunks.last_mut() {
                 let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
-                let currently_used_cap = used_bytes / mem::size_of::<T>();
-                last_chunk.entries = currently_used_cap;
-                if last_chunk.storage.reserve_in_place(currently_used_cap, n) {
-                    self.end.set(last_chunk.end());
-                    return;
-                } else {
-                    // If the previous chunk's capacity is less than HUGE_PAGE
-                    // bytes, then this chunk will be least double the previous
-                    // chunk's size.
-                    new_capacity = last_chunk.storage.capacity();
-                    if new_capacity < HUGE_PAGE / elem_size {
-                        new_capacity = new_capacity.checked_mul(2).unwrap();
-                    }
+                last_chunk.entries = used_bytes / mem::size_of::<T>();
+
+                // If the previous chunk's capacity is less than HUGE_PAGE
+                // bytes, then this chunk will be least double the previous
+                // chunk's size.
+                new_cap = last_chunk.storage.capacity();
+                if new_cap < HUGE_PAGE / elem_size {
+                    new_cap = new_cap.checked_mul(2).unwrap();
                 }
             } else {
-                new_capacity = PAGE / elem_size;
+                new_cap = PAGE / elem_size;
             }
-            // Also ensure that this chunk can fit `n`.
-            new_capacity = cmp::max(n, new_capacity);
+            // Also ensure that this chunk can fit `additional`.
+            new_cap = cmp::max(additional, new_cap);
 
-            chunk = TypedArenaChunk::<T>::new(new_capacity);
+            let chunk = TypedArenaChunk::<T>::new(new_cap);
             self.ptr.set(chunk.start());
             self.end.set(chunk.end());
             chunks.push(chunk);
@@ -347,31 +342,28 @@ impl DroplessArena {
 
     #[inline(never)]
     #[cold]
-    fn grow(&self, needed_bytes: usize) {
+    fn grow(&self, additional: usize) {
         unsafe {
             let mut chunks = self.chunks.borrow_mut();
-            let (chunk, mut new_capacity);
+            let mut new_cap;
             if let Some(last_chunk) = chunks.last_mut() {
-                let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
-                if last_chunk.storage.reserve_in_place(used_bytes, needed_bytes) {
-                    self.end.set(last_chunk.end());
-                    return;
-                } else {
-                    // If the previous chunk's capacity is less than HUGE_PAGE
-                    // bytes, then this chunk will be least double the previous
-                    // chunk's size.
-                    new_capacity = last_chunk.storage.capacity();
-                    if new_capacity < HUGE_PAGE {
-                        new_capacity = new_capacity.checked_mul(2).unwrap();
-                    }
+                // There is no need to update `last_chunk.entries` because that
+                // field isn't used by `DroplessArena`.
+
+                // If the previous chunk's capacity is less than HUGE_PAGE
+                // bytes, then this chunk will be least double the previous
+                // chunk's size.
+                new_cap = last_chunk.storage.capacity();
+                if new_cap < HUGE_PAGE {
+                    new_cap = new_cap.checked_mul(2).unwrap();
                 }
             } else {
-                new_capacity = PAGE;
+                new_cap = PAGE;
             }
-            // Also ensure that this chunk can fit `needed_bytes`.
-            new_capacity = cmp::max(needed_bytes, new_capacity);
+            // Also ensure that this chunk can fit `additional`.
+            new_cap = cmp::max(additional, new_cap);
 
-            chunk = TypedArenaChunk::<u8>::new(new_capacity);
+            let chunk = TypedArenaChunk::<u8>::new(new_cap);
             self.ptr.set(chunk.start());
             self.end.set(chunk.end());
             chunks.push(chunk);
@@ -386,7 +378,7 @@ impl DroplessArena {
             self.align(align);
 
             let future_end = intrinsics::arith_offset(self.ptr.get(), bytes as isize);
-            if (future_end as *mut u8) >= self.end.get() {
+            if (future_end as *mut u8) > self.end.get() {
                 self.grow(bytes);
             }
 
diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs
index 760b4d7ba00..ec5b3251e68 100644
--- a/src/librustc_error_codes/error_codes.rs
+++ b/src/librustc_error_codes/error_codes.rs
@@ -439,6 +439,7 @@ E0753: include_str!("./error_codes/E0753.md"),
 E0754: include_str!("./error_codes/E0754.md"),
 E0758: include_str!("./error_codes/E0758.md"),
 E0760: include_str!("./error_codes/E0760.md"),
+E0761: include_str!("./error_codes/E0761.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
diff --git a/src/librustc_error_codes/error_codes/E0583.md b/src/librustc_error_codes/error_codes/E0583.md
index 2dcbbf88556..701900bb0cd 100644
--- a/src/librustc_error_codes/error_codes/E0583.md
+++ b/src/librustc_error_codes/error_codes/E0583.md
@@ -2,7 +2,7 @@ A file wasn't found for an out-of-line module.
 
 Erroneous code example:
 
-```ignore (compile_fail not working here; see Issue #43707)
+```compile_fail,E0583
 mod file_that_doesnt_exist; // error: file not found for module
 
 fn main() {}
diff --git a/src/librustc_error_codes/error_codes/E0647.md b/src/librustc_error_codes/error_codes/E0647.md
index 131db38c00d..8ca6e777f30 100644
--- a/src/librustc_error_codes/error_codes/E0647.md
+++ b/src/librustc_error_codes/error_codes/E0647.md
@@ -1,4 +1,5 @@
-It is not possible to define `start` with a where clause.
+The `start` function was defined with a where clause.
+
 Erroneous code example:
 
 ```compile_fail,E0647
diff --git a/src/librustc_error_codes/error_codes/E0761.md b/src/librustc_error_codes/error_codes/E0761.md
new file mode 100644
index 00000000000..c01574e413c
--- /dev/null
+++ b/src/librustc_error_codes/error_codes/E0761.md
@@ -0,0 +1,25 @@
+Multiple candidate files were found for an out-of-line module.
+
+Erroneous code example:
+
+```rust
+// file: ambiguous_module/mod.rs
+
+fn foo() {}
+```
+
+```rust
+// file: ambiguous_module.rs
+
+fn foo() {}
+```
+
+```ignore (multiple source files required for compile_fail)
+mod ambiguous_module; // error: file for module `ambiguous_module`
+                      // found at both ambiguous_module.rs and
+                      // ambiguous_module.rs/mod.rs
+
+fn main() {}
+```
+
+Please remove this ambiguity by deleting/renaming one of the candidate files.
diff --git a/src/librustc_expand/module.rs b/src/librustc_expand/module.rs
index 82215c7297e..535c1dbad04 100644
--- a/src/librustc_expand/module.rs
+++ b/src/librustc_expand/module.rs
@@ -291,7 +291,7 @@ pub fn default_submod_path<'a>(
             let mut err = struct_span_err!(
                 sess.span_diagnostic,
                 span,
-                E0584,
+                E0761,
                 "file for module `{}` found at both {} and {}",
                 mod_name,
                 default_path_str,
diff --git a/src/librustc_mir/transform/validate.rs b/src/librustc_mir/transform/validate.rs
index 1433d39abfb..8150c328316 100644
--- a/src/librustc_mir/transform/validate.rs
+++ b/src/librustc_mir/transform/validate.rs
@@ -11,6 +11,12 @@ use rustc_middle::{
 };
 use rustc_span::def_id::DefId;
 
+#[derive(Copy, Clone, Debug)]
+enum EdgeKind {
+    Unwind,
+    Normal,
+}
+
 pub struct Validator {
     /// Describes at which point in the pipeline this validation is happening.
     pub when: String,
@@ -49,8 +55,31 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         );
     }
 
-    fn check_bb(&self, location: Location, bb: BasicBlock) {
-        if self.body.basic_blocks().get(bb).is_none() {
+    fn check_edge(&self, location: Location, bb: BasicBlock, edge_kind: EdgeKind) {
+        if let Some(bb) = self.body.basic_blocks().get(bb) {
+            let src = self.body.basic_blocks().get(location.block).unwrap();
+            match (src.is_cleanup, bb.is_cleanup, edge_kind) {
+                // Non-cleanup blocks can jump to non-cleanup blocks along non-unwind edges
+                (false, false, EdgeKind::Normal)
+                // Non-cleanup blocks can jump to cleanup blocks along unwind edges
+                | (false, true, EdgeKind::Unwind)
+                // Cleanup blocks can jump to cleanup blocks along non-unwind edges
+                | (true, true, EdgeKind::Normal) => {}
+                // All other jumps are invalid
+                _ => {
+                    self.fail(
+                        location,
+                        format!(
+                            "{:?} edge to {:?} violates unwind invariants (cleanup {:?} -> {:?})",
+                            edge_kind,
+                            bb,
+                            src.is_cleanup,
+                            bb.is_cleanup,
+                        )
+                    )
+                }
+            }
+        } else {
             self.fail(location, format!("encountered jump to invalid basic block {:?}", bb))
         }
     }
@@ -92,7 +121,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
     fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
         match &terminator.kind {
             TerminatorKind::Goto { target } => {
-                self.check_bb(location, *target);
+                self.check_edge(location, *target, EdgeKind::Normal);
             }
             TerminatorKind::SwitchInt { targets, values, .. } => {
                 if targets.len() != values.len() + 1 {
@@ -106,19 +135,19 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     );
                 }
                 for target in targets {
-                    self.check_bb(location, *target);
+                    self.check_edge(location, *target, EdgeKind::Normal);
                 }
             }
             TerminatorKind::Drop { target, unwind, .. } => {
-                self.check_bb(location, *target);
+                self.check_edge(location, *target, EdgeKind::Normal);
                 if let Some(unwind) = unwind {
-                    self.check_bb(location, *unwind);
+                    self.check_edge(location, *unwind, EdgeKind::Unwind);
                 }
             }
             TerminatorKind::DropAndReplace { target, unwind, .. } => {
-                self.check_bb(location, *target);
+                self.check_edge(location, *target, EdgeKind::Normal);
                 if let Some(unwind) = unwind {
-                    self.check_bb(location, *unwind);
+                    self.check_edge(location, *unwind, EdgeKind::Unwind);
                 }
             }
             TerminatorKind::Call { func, destination, cleanup, .. } => {
@@ -131,10 +160,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     ),
                 }
                 if let Some((_, target)) = destination {
-                    self.check_bb(location, *target);
+                    self.check_edge(location, *target, EdgeKind::Normal);
                 }
                 if let Some(cleanup) = cleanup {
-                    self.check_bb(location, *cleanup);
+                    self.check_edge(location, *cleanup, EdgeKind::Unwind);
                 }
             }
             TerminatorKind::Assert { cond, target, cleanup, .. } => {
@@ -148,30 +177,30 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         ),
                     );
                 }
-                self.check_bb(location, *target);
+                self.check_edge(location, *target, EdgeKind::Normal);
                 if let Some(cleanup) = cleanup {
-                    self.check_bb(location, *cleanup);
+                    self.check_edge(location, *cleanup, EdgeKind::Unwind);
                 }
             }
             TerminatorKind::Yield { resume, drop, .. } => {
-                self.check_bb(location, *resume);
+                self.check_edge(location, *resume, EdgeKind::Normal);
                 if let Some(drop) = drop {
-                    self.check_bb(location, *drop);
+                    self.check_edge(location, *drop, EdgeKind::Normal);
                 }
             }
             TerminatorKind::FalseEdge { real_target, imaginary_target } => {
-                self.check_bb(location, *real_target);
-                self.check_bb(location, *imaginary_target);
+                self.check_edge(location, *real_target, EdgeKind::Normal);
+                self.check_edge(location, *imaginary_target, EdgeKind::Normal);
             }
             TerminatorKind::FalseUnwind { real_target, unwind } => {
-                self.check_bb(location, *real_target);
+                self.check_edge(location, *real_target, EdgeKind::Normal);
                 if let Some(unwind) = unwind {
-                    self.check_bb(location, *unwind);
+                    self.check_edge(location, *unwind, EdgeKind::Unwind);
                 }
             }
             TerminatorKind::InlineAsm { destination, .. } => {
                 if let Some(destination) = destination {
-                    self.check_bb(location, *destination);
+                    self.check_edge(location, *destination, EdgeKind::Normal);
                 }
             }
             // Nothing to validate for these.
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 38123816527..5c76c840b1d 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -85,9 +85,7 @@ pub struct Item {
 
 impl fmt::Debug for Item {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let fake = MAX_DEF_ID.with(|m| {
-            m.borrow().get(&self.def_id.krate).map(|id| self.def_id >= *id).unwrap_or(false)
-        });
+        let fake = self.is_fake();
         let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id };
 
         fmt.debug_struct("Item")
@@ -238,6 +236,13 @@ impl Item {
             _ => false,
         }
     }
+
+    /// See comments on next_def_id
+    pub fn is_fake(&self) -> bool {
+        MAX_DEF_ID.with(|m| {
+            m.borrow().get(&self.def_id.krate).map(|id| self.def_id >= *id).unwrap_or(false)
+        })
+    }
 }
 
 #[derive(Clone, Debug)]
diff --git a/src/libtest/cli.rs b/src/libtest/cli.rs
index 0cec8050c27..97a659f22d7 100644
--- a/src/libtest/cli.rs
+++ b/src/libtest/cli.rs
@@ -115,7 +115,7 @@ fn optgroups() -> getopts::Options {
         .optflagopt(
             "",
             "report-time",
-            "Show execution time of each test. Awailable values:
+            "Show execution time of each test. Available values:
             plain   = do not colorize the execution time (default);
             colored = colorize output according to the `color` parameter value;
 
diff --git a/src/test/ui/mod/mod_file_disambig.stderr b/src/test/ui/mod/mod_file_disambig.stderr
index 490633a3fb0..2cb99b75142 100644
--- a/src/test/ui/mod/mod_file_disambig.stderr
+++ b/src/test/ui/mod/mod_file_disambig.stderr
@@ -1,4 +1,4 @@
-error[E0584]: file for module `mod_file_disambig_aux` found at both mod_file_disambig_aux.rs and mod_file_disambig_aux/mod.rs
+error[E0761]: file for module `mod_file_disambig_aux` found at both mod_file_disambig_aux.rs and mod_file_disambig_aux/mod.rs
   --> $DIR/mod_file_disambig.rs:1:1
    |
 LL | mod mod_file_disambig_aux;
@@ -14,5 +14,5 @@ LL |     assert_eq!(mod_file_aux::bar(), 10);
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0433, E0584.
+Some errors have detailed explanations: E0433, E0761.
 For more information about an error, try `rustc --explain E0433`.