about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-12-11 10:37:52 +0000
committerbors <bors@rust-lang.org>2021-12-11 10:37:52 +0000
commitb9a37ad0d995c71518629b032f8e816e1efa8bca (patch)
tree57b8f04dfb65960fab67fea155d939ab6a8f8886
parent4a66a704b2c3d30ff07d89380ebb9ba3de3b3182 (diff)
parent5da73311be4c6cefc557c8615d39b0e44ef8de95 (diff)
downloadrust-b9a37ad0d995c71518629b032f8e816e1efa8bca.tar.gz
rust-b9a37ad0d995c71518629b032f8e816e1efa8bca.zip
Auto merge of #91776 - matthiaskrgr:rollup-tlb4bw1, r=matthiaskrgr
Rollup of 6 pull requests

Successful merges:

 - #91127 (Add `<*{const|mut} T>::{to|from}_bits`)
 - #91310 (Add --out-dir flag for rustdoc)
 - #91373 (Add needs-unwind to tests that depend on panicking)
 - #91426 (Make IdFunctor::try_map_id panic-safe)
 - #91515 (Add rsplit_array variants to slices and arrays)
 - #91553 (socket ancillary data implementation for dragonflybsd.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_data_structures/src/functor.rs53
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--library/core/src/array/mod.rs78
-rw-r--r--library/core/src/ptr/const_ptr.rs48
-rw-r--r--library/core/src/ptr/mut_ptr.rs49
-rw-r--r--library/core/src/slice/mod.rs78
-rw-r--r--library/core/tests/array.rs33
-rw-r--r--library/core/tests/slice.rs33
-rw-r--r--library/std/src/os/unix/net/ancillary.rs82
-rw-r--r--library/std/src/os/unix/net/datagram.rs14
-rw-r--r--library/std/src/sys/unix/net.rs4
-rw-r--r--src/doc/rustdoc/src/command-line-arguments.md4
-rw-r--r--src/librustdoc/config.rs14
-rw-r--r--src/librustdoc/lib.rs11
-rw-r--r--src/test/run-make/rustdoc-with-out-dir-option/Makefile8
-rw-r--r--src/test/run-make/rustdoc-with-out-dir-option/src/lib.rs2
-rw-r--r--src/test/run-make/rustdoc-with-output-option/Makefile8
-rw-r--r--src/test/run-make/rustdoc-with-output-option/src/lib.rs2
-rw-r--r--src/test/run-make/rustdoc-with-short-out-dir-option/Makefile8
-rw-r--r--src/test/run-make/rustdoc-with-short-out-dir-option/src/lib.rs2
-rw-r--r--src/test/rustdoc-ui/use_both_out_dir_and_output_options.rs1
-rw-r--r--src/test/rustdoc-ui/use_both_out_dir_and_output_options.stderr2
-rw-r--r--src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs1
-rw-r--r--src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs1
-rw-r--r--src/test/ui/array-slice-vec/nested-vec-3.rs1
-rw-r--r--src/test/ui/array-slice-vec/slice-panic-1.rs1
-rw-r--r--src/test/ui/array-slice-vec/slice-panic-2.rs1
-rw-r--r--src/test/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs1
-rw-r--r--src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs1
-rw-r--r--src/test/ui/builtin-clone-unwind.rs1
-rw-r--r--src/test/ui/catch-unwind-bang.rs1
-rw-r--r--src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs1
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed1
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs1
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr4
-rw-r--r--src/test/ui/drop/drop-trait-enum.rs1
-rw-r--r--src/test/ui/drop/dynamic-drop-async.rs1
-rw-r--r--src/test/ui/drop/dynamic-drop.rs1
-rw-r--r--src/test/ui/drop/terminate-in-initializer.rs1
-rw-r--r--src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs1
-rw-r--r--src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs1
-rw-r--r--src/test/ui/generator/generator-resume-after-panic.rs1
-rw-r--r--src/test/ui/generator/panic-drops-resume.rs1
-rw-r--r--src/test/ui/generator/panic-drops.rs1
-rw-r--r--src/test/ui/generator/panic-safe.rs1
-rw-r--r--src/test/ui/generator/resume-after-return.rs1
-rw-r--r--src/test/ui/intrinsics/panic-uninitialized-zeroed.rs1
-rw-r--r--src/test/ui/issues/issue-14875.rs1
-rw-r--r--src/test/ui/issues/issue-25089.rs1
-rw-r--r--src/test/ui/issues/issue-26655.rs1
-rw-r--r--src/test/ui/issues/issue-29485.rs1
-rw-r--r--src/test/ui/issues/issue-29948.rs1
-rw-r--r--src/test/ui/issues/issue-30018-panic.rs1
-rw-r--r--src/test/ui/issues/issue-43853.rs1
-rw-r--r--src/test/ui/issues/issue-46519.rs1
-rw-r--r--src/test/ui/iterators/iter-count-overflow-debug.rs1
-rw-r--r--src/test/ui/iterators/iter-position-overflow-debug.rs1
-rw-r--r--src/test/ui/iterators/iter-step-overflow-debug.rs1
-rw-r--r--src/test/ui/iterators/iter-sum-overflow-debug.rs1
-rw-r--r--src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs1
-rw-r--r--src/test/ui/macros/macro-comma-behavior-rpass.rs1
-rw-r--r--src/test/ui/mir/mir_calls_to_shims.rs1
-rw-r--r--src/test/ui/mir/mir_drop_order.rs1
-rw-r--r--src/test/ui/mir/mir_drop_panics.rs1
-rw-r--r--src/test/ui/mir/mir_dynamic_drops_3.rs1
-rw-r--r--src/test/ui/numbers-arithmetic/int-abs-overflow.rs1
-rw-r--r--src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs1
-rw-r--r--src/test/ui/panics/panic-handler-chain.rs1
-rw-r--r--src/test/ui/panics/panic-handler-flail-wildly.rs1
-rw-r--r--src/test/ui/panics/panic-handler-set-twice.rs1
-rw-r--r--src/test/ui/panics/panic-in-dtor-drops-fields.rs1
-rw-r--r--src/test/ui/panics/panic-recover-propagate.rs1
-rw-r--r--src/test/ui/privacy/reachable-unnameable-items.rs1
-rw-r--r--src/test/ui/proc-macro/expand-with-a-macro.rs1
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs1
-rw-r--r--src/test/ui/rfc-2091-track-caller/std-panic-locations.rs1
-rw-r--r--src/test/ui/rfcs/rfc1857-drop-order.rs1
-rw-r--r--src/test/ui/runtime/rt-explody-panic-payloads.rs1
-rw-r--r--src/test/ui/sepcomp/sepcomp-unwind.rs1
-rw-r--r--src/test/ui/structs-enums/unit-like-struct-drop-run.rs1
-rw-r--r--src/test/ui/test-attrs/test-should-fail-good-message.rs1
-rw-r--r--src/test/ui/threads-sendsync/task-stderr.rs1
-rw-r--r--src/test/ui/threads-sendsync/unwind-resource.rs1
-rw-r--r--src/test/ui/unwind-unique.rs1
84 files changed, 561 insertions, 39 deletions
diff --git a/compiler/rustc_data_structures/src/functor.rs b/compiler/rustc_data_structures/src/functor.rs
index 71ff762c714..a3d3f988344 100644
--- a/compiler/rustc_data_structures/src/functor.rs
+++ b/compiler/rustc_data_structures/src/functor.rs
@@ -34,38 +34,43 @@ impl<T> IdFunctor for Vec<T> {
     type Inner = T;
 
     #[inline]
-    fn try_map_id<F, E>(mut self, mut f: F) -> Result<Self, E>
+    fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E>
     where
         F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
     {
-        // FIXME: We don't really care about panics here and leak
-        // far more than we should, but that should be fine for now.
-        let len = self.len();
-        unsafe {
-            self.set_len(0);
-            let start = self.as_mut_ptr();
-            for i in 0..len {
-                let p = start.add(i);
-                match f(p.read()) {
-                    Ok(val) => p.write(val),
-                    Err(err) => {
-                        // drop all other elements in self
-                        // (current element was "moved" into the call to f)
-                        for j in (0..i).chain(i + 1..len) {
-                            start.add(j).drop_in_place();
-                        }
+        struct HoleVec<T> {
+            vec: Vec<mem::ManuallyDrop<T>>,
+            hole: Option<usize>,
+        }
 
-                        // returning will drop self, releasing the allocation
-                        // (len is 0 so elements will not be re-dropped)
-                        return Err(err);
+        impl<T> Drop for HoleVec<T> {
+            fn drop(&mut self) {
+                unsafe {
+                    for (index, slot) in self.vec.iter_mut().enumerate() {
+                        if self.hole != Some(index) {
+                            mem::ManuallyDrop::drop(slot);
+                        }
                     }
                 }
             }
-            // Even if we encountered an error, set the len back
-            // so we don't leak memory.
-            self.set_len(len);
         }
-        Ok(self)
+
+        unsafe {
+            let (ptr, length, capacity) = self.into_raw_parts();
+            let vec = Vec::from_raw_parts(ptr.cast(), length, capacity);
+            let mut hole_vec = HoleVec { vec, hole: None };
+
+            for (index, slot) in hole_vec.vec.iter_mut().enumerate() {
+                hole_vec.hole = Some(index);
+                let original = mem::ManuallyDrop::take(slot);
+                let mapped = f(original)?;
+                *slot = mem::ManuallyDrop::new(mapped);
+                hole_vec.hole = None;
+            }
+
+            mem::forget(hole_vec);
+            Ok(Vec::from_raw_parts(ptr, length, capacity))
+        }
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index e17724b72f8..181e5180d53 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -23,6 +23,7 @@
 #![feature(once_cell)]
 #![feature(test)]
 #![feature(thread_id_value)]
+#![feature(vec_into_raw_parts)]
 #![allow(rustc::default_hash_types)]
 #![deny(unaligned_references)]
 
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 23fd1453e54..5e295ffbff7 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -645,6 +645,84 @@ impl<T, const N: usize> [T; N] {
     pub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T]) {
         (&mut self[..]).split_array_mut::<M>()
     }
+
+    /// Divides one array reference into two at an index from the end.
+    ///
+    /// The first will contain all indices from `[0, N - M)` (excluding
+    /// the index `N - M` itself) and the second will contain all
+    /// indices from `[N - M, N)` (excluding the index `N` itself).
+    ///
+    /// # Panics
+    ///
+    /// Panics if `M > N`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(split_array)]
+    ///
+    /// let v = [1, 2, 3, 4, 5, 6];
+    ///
+    /// {
+    ///    let (left, right) = v.rsplit_array_ref::<0>();
+    ///    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+    ///    assert_eq!(right, &[]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = v.rsplit_array_ref::<2>();
+    ///     assert_eq!(left, &[1, 2, 3, 4]);
+    ///     assert_eq!(right, &[5, 6]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = v.rsplit_array_ref::<6>();
+    ///     assert_eq!(left, &[]);
+    ///     assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+    /// }
+    /// ```
+    #[unstable(
+        feature = "split_array",
+        reason = "return type should have array as 2nd element",
+        issue = "90091"
+    )]
+    #[inline]
+    pub fn rsplit_array_ref<const M: usize>(&self) -> (&[T], &[T; M]) {
+        (&self[..]).rsplit_array_ref::<M>()
+    }
+
+    /// Divides one mutable array reference into two at an index from the end.
+    ///
+    /// The first will contain all indices from `[0, N - M)` (excluding
+    /// the index `N - M` itself) and the second will contain all
+    /// indices from `[N - M, N)` (excluding the index `N` itself).
+    ///
+    /// # Panics
+    ///
+    /// Panics if `M > N`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(split_array)]
+    ///
+    /// let mut v = [1, 0, 3, 0, 5, 6];
+    /// let (left, right) = v.rsplit_array_mut::<4>();
+    /// assert_eq!(left, &mut [1, 0]);
+    /// assert_eq!(right, &mut [3, 0, 5, 6][..]);
+    /// left[1] = 2;
+    /// right[1] = 4;
+    /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+    /// ```
+    #[unstable(
+        feature = "split_array",
+        reason = "return type should have array as 2nd element",
+        issue = "90091"
+    )]
+    #[inline]
+    pub fn rsplit_array_mut<const M: usize>(&mut self) -> (&mut [T], &mut [T; M]) {
+        (&mut self[..]).rsplit_array_mut::<M>()
+    }
 }
 
 /// Pulls `N` items from `iter` and returns them as an array. If the iterator
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 344b483662a..3c716672113 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -48,6 +48,54 @@ impl<T: ?Sized> *const T {
         self as _
     }
 
+    /// Casts a pointer to its raw bits.
+    ///
+    /// This is equivalent to `as usize`, but is more specific to enhance readability.
+    /// The inverse method is [`from_bits`](#method.from_bits).
+    ///
+    /// In particular, `*p as usize` and `p as usize` will both compile for
+    /// pointers to numeric types but do very different things, so using this
+    /// helps emphasize that reading the bits was intentional.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ptr_to_from_bits)]
+    /// let array = [13, 42];
+    /// let p0: *const i32 = &array[0];
+    /// assert_eq!(<*const _>::from_bits(p0.to_bits()), p0);
+    /// let p1: *const i32 = &array[1];
+    /// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
+    /// ```
+    #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
+    pub fn to_bits(self) -> usize
+    where
+        T: Sized,
+    {
+        self as usize
+    }
+
+    /// Creates a pointer from its raw bits.
+    ///
+    /// This is equivalent to `as *const T`, but is more specific to enhance readability.
+    /// The inverse method is [`to_bits`](#method.to_bits).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ptr_to_from_bits)]
+    /// use std::ptr::NonNull;
+    /// let dangling: *const u8 = NonNull::dangling().as_ptr();
+    /// assert_eq!(<*const u8>::from_bits(1), dangling);
+    /// ```
+    #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
+    pub fn from_bits(bits: usize) -> Self
+    where
+        T: Sized,
+    {
+        bits as Self
+    }
+
     /// Decompose a (possibly wide) pointer into its address and metadata components.
     ///
     /// The pointer can be later reconstructed with [`from_raw_parts`].
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index f3b2bdfefe5..5d4e37641ee 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -47,6 +47,55 @@ impl<T: ?Sized> *mut T {
         self as _
     }
 
+    /// Casts a pointer to its raw bits.
+    ///
+    /// This is equivalent to `as usize`, but is more specific to enhance readability.
+    /// The inverse method is [`from_bits`](#method.from_bits-1).
+    ///
+    /// In particular, `*p as usize` and `p as usize` will both compile for
+    /// pointers to numeric types but do very different things, so using this
+    /// helps emphasize that reading the bits was intentional.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ptr_to_from_bits)]
+    /// let mut array = [13, 42];
+    /// let mut it = array.iter_mut();
+    /// let p0: *mut i32 = it.next().unwrap();
+    /// assert_eq!(<*mut _>::from_bits(p0.to_bits()), p0);
+    /// let p1: *mut i32 = it.next().unwrap();
+    /// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
+    /// ```
+    #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
+    pub fn to_bits(self) -> usize
+    where
+        T: Sized,
+    {
+        self as usize
+    }
+
+    /// Creates a pointer from its raw bits.
+    ///
+    /// This is equivalent to `as *mut T`, but is more specific to enhance readability.
+    /// The inverse method is [`to_bits`](#method.to_bits-1).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ptr_to_from_bits)]
+    /// use std::ptr::NonNull;
+    /// let dangling: *mut u8 = NonNull::dangling().as_ptr();
+    /// assert_eq!(<*mut u8>::from_bits(1), dangling);
+    /// ```
+    #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
+    pub fn from_bits(bits: usize) -> Self
+    where
+        T: Sized,
+    {
+        bits as Self
+    }
+
     /// Decompose a (possibly wide) pointer into its address and metadata components.
     ///
     /// The pointer can be later reconstructed with [`from_raw_parts_mut`].
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index a3f59d30759..f9ea99ea8aa 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1705,6 +1705,84 @@ impl<T> [T] {
         unsafe { (&mut *(a.as_mut_ptr() as *mut [T; N]), b) }
     }
 
+    /// Divides one slice into an array and a remainder slice at an index from
+    /// the end.
+    ///
+    /// The slice will contain all indices from `[0, len - N)` (excluding
+    /// the index `len - N` itself) and the array will contain all
+    /// indices from `[len - N, len)` (excluding the index `len` itself).
+    ///
+    /// # Panics
+    ///
+    /// Panics if `N > len`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(split_array)]
+    ///
+    /// let v = &[1, 2, 3, 4, 5, 6][..];
+    ///
+    /// {
+    ///    let (left, right) = v.rsplit_array_ref::<0>();
+    ///    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    ///    assert_eq!(right, &[]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = v.rsplit_array_ref::<2>();
+    ///     assert_eq!(left, [1, 2, 3, 4]);
+    ///     assert_eq!(right, &[5, 6]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = v.rsplit_array_ref::<6>();
+    ///     assert_eq!(left, []);
+    ///     assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+    /// }
+    /// ```
+    #[unstable(feature = "split_array", reason = "new API", issue = "90091")]
+    #[inline]
+    pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N]) {
+        assert!(N <= self.len());
+        let (a, b) = self.split_at(self.len() - N);
+        // SAFETY: b points to [T; N]? Yes it's [T] of length N (checked by split_at)
+        unsafe { (a, &*(b.as_ptr() as *const [T; N])) }
+    }
+
+    /// Divides one mutable slice into an array and a remainder slice at an
+    /// index from the end.
+    ///
+    /// The slice will contain all indices from `[0, len - N)` (excluding
+    /// the index `N` itself) and the array will contain all
+    /// indices from `[len - N, len)` (excluding the index `len` itself).
+    ///
+    /// # Panics
+    ///
+    /// Panics if `N > len`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(split_array)]
+    ///
+    /// let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+    /// let (left, right) = v.rsplit_array_mut::<4>();
+    /// assert_eq!(left, [1, 0]);
+    /// assert_eq!(right, &mut [3, 0, 5, 6]);
+    /// left[1] = 2;
+    /// right[1] = 4;
+    /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+    /// ```
+    #[unstable(feature = "split_array", reason = "new API", issue = "90091")]
+    #[inline]
+    pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N]) {
+        assert!(N <= self.len());
+        let (a, b) = self.split_at_mut(self.len() - N);
+        // SAFETY: b points to [T; N]? Yes it's [T] of length N (checked by split_at_mut)
+        unsafe { (a, &mut *(b.as_mut_ptr() as *mut [T; N])) }
+    }
+
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`. The matched element is not contained in the subslices.
     ///
diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs
index d212a3a3a05..8524a0bf8dd 100644
--- a/library/core/tests/array.rs
+++ b/library/core/tests/array.rs
@@ -459,6 +459,23 @@ fn array_split_array_mut() {
     }
 }
 
+#[test]
+fn array_rsplit_array_mut() {
+    let mut v = [1, 2, 3, 4, 5, 6];
+
+    {
+        let (left, right) = v.rsplit_array_mut::<0>();
+        assert_eq!(left, &mut [1, 2, 3, 4, 5, 6]);
+        assert_eq!(right, &mut []);
+    }
+
+    {
+        let (left, right) = v.rsplit_array_mut::<6>();
+        assert_eq!(left, &mut []);
+        assert_eq!(right, &mut [1, 2, 3, 4, 5, 6]);
+    }
+}
+
 #[should_panic]
 #[test]
 fn array_split_array_ref_out_of_bounds() {
@@ -475,6 +492,22 @@ fn array_split_array_mut_out_of_bounds() {
     v.split_array_mut::<7>();
 }
 
+#[should_panic]
+#[test]
+fn array_rsplit_array_ref_out_of_bounds() {
+    let v = [1, 2, 3, 4, 5, 6];
+
+    v.rsplit_array_ref::<7>();
+}
+
+#[should_panic]
+#[test]
+fn array_rsplit_array_mut_out_of_bounds() {
+    let mut v = [1, 2, 3, 4, 5, 6];
+
+    v.rsplit_array_mut::<7>();
+}
+
 #[test]
 fn array_intoiter_advance_by() {
     use std::cell::Cell;
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 281df8a1326..20e2d8d47c0 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -2219,6 +2219,23 @@ fn slice_split_array_mut() {
     }
 }
 
+#[test]
+fn slice_rsplit_array_mut() {
+    let v = &mut [1, 2, 3, 4, 5, 6][..];
+
+    {
+        let (left, right) = v.rsplit_array_mut::<0>();
+        assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+        assert_eq!(right, &mut []);
+    }
+
+    {
+        let (left, right) = v.rsplit_array_mut::<6>();
+        assert_eq!(left, []);
+        assert_eq!(right, &mut [1, 2, 3, 4, 5, 6]);
+    }
+}
+
 #[should_panic]
 #[test]
 fn slice_split_array_ref_out_of_bounds() {
@@ -2235,6 +2252,22 @@ fn slice_split_array_mut_out_of_bounds() {
     v.split_array_mut::<7>();
 }
 
+#[should_panic]
+#[test]
+fn slice_rsplit_array_ref_out_of_bounds() {
+    let v = &[1, 2, 3, 4, 5, 6][..];
+
+    v.rsplit_array_ref::<7>();
+}
+
+#[should_panic]
+#[test]
+fn slice_rsplit_array_mut_out_of_bounds() {
+    let v = &mut [1, 2, 3, 4, 5, 6][..];
+
+    v.rsplit_array_mut::<7>();
+}
+
 macro_rules! take_tests {
     (slice: &[], $($tts:tt)*) => {
         take_tests!(ty: &[()], slice: &[], $($tts)*);
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 6e6f5212b46..a29008140f7 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -16,6 +16,8 @@ mod libc {
     pub use libc::c_int;
     pub struct ucred;
     pub struct cmsghdr;
+    #[cfg(target_os = "dragonfly")]
+    pub struct cmsgcred;
     pub type pid_t = i32;
     pub type gid_t = u32;
     pub type uid_t = u32;
@@ -183,6 +185,11 @@ impl<'a, T> Iterator for AncillaryDataIter<'a, T> {
 #[derive(Clone)]
 pub struct SocketCred(libc::ucred);
 
+#[cfg(target_os = "dragonfly")]
+#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+#[derive(Clone)]
+pub struct SocketCred(libc::cmsgcred);
+
 #[cfg(any(doc, target_os = "android", target_os = "linux",))]
 impl SocketCred {
     /// Create a Unix credential struct.
@@ -234,6 +241,57 @@ impl SocketCred {
     }
 }
 
+#[cfg(target_os = "dragonfly")]
+impl SocketCred {
+    /// Create a Unix credential struct.
+    ///
+    /// PID, UID and GID is set to 0.
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    #[must_use]
+    pub fn new() -> SocketCred {
+        SocketCred(libc::cmsgcred { cmsgcred_pid: 0, cmsgcred_uid: 0, cmsgcred_gid: 0 })
+    }
+
+    /// Set the PID.
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn set_pid(&mut self, pid: libc::pid_t) {
+        self.0.cmsgcred_pid = pid;
+    }
+
+    /// Get the current PID.
+    #[must_use]
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn get_pid(&self) -> libc::pid_t {
+        self.0.cmsgcred_pid
+    }
+
+    /// Set the UID.
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn set_uid(&mut self, uid: libc::uid_t) {
+        self.0.cmsgcred_uid = uid;
+    }
+
+    /// Get the current UID.
+    #[must_use]
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn get_uid(&self) -> libc::uid_t {
+        self.0.cmsgcred_uid
+    }
+
+    /// Set the GID.
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn set_gid(&mut self, gid: libc::gid_t) {
+        self.0.cmsgcred_gid = gid;
+    }
+
+    /// Get the current GID.
+    #[must_use]
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn get_gid(&self) -> libc::gid_t {
+        self.0.cmsgcred_gid
+    }
+}
+
 /// This control message contains file descriptors.
 ///
 /// The level is equal to `SOL_SOCKET` and the type is equal to `SCM_RIGHTS`.
@@ -256,7 +314,11 @@ impl<'a> Iterator for ScmRights<'a> {
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::ucred>);
 
-#[cfg(any(doc, target_os = "android", target_os = "linux",))]
+#[cfg(target_os = "dragonfly")]
+#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::cmsgcred>);
+
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "dragonfly",))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 impl<'a> Iterator for ScmCredentials<'a> {
     type Item = SocketCred;
@@ -300,7 +362,7 @@ impl<'a> AncillaryData<'a> {
     /// # Safety
     ///
     /// `data` must contain a valid control message and the control message must be type of
-    /// `SOL_SOCKET` and level of `SCM_CREDENTIALS` or `SCM_CREDENTIALS`.
+    /// `SOL_SOCKET` and level of `SCM_CREDENTIALS` or `SCM_CREDS`.
     #[cfg(any(doc, target_os = "android", target_os = "linux",))]
     unsafe fn as_credentials(data: &'a [u8]) -> Self {
         let ancillary_data_iter = AncillaryDataIter::new(data);
@@ -320,6 +382,9 @@ impl<'a> AncillaryData<'a> {
                     libc::SCM_RIGHTS => Ok(AncillaryData::as_rights(data)),
                     #[cfg(any(target_os = "android", target_os = "linux",))]
                     libc::SCM_CREDENTIALS => Ok(AncillaryData::as_credentials(data)),
+                    #[cfg(target_os = "dragonfly")]
+                    libc::SCM_CREDS => Ok(AncillaryData::as_credentials(data)),
+
                     cmsg_type => {
                         Err(AncillaryError::Unknown { cmsg_level: libc::SOL_SOCKET, cmsg_type })
                     }
@@ -544,6 +609,19 @@ impl<'a> SocketAncillary<'a> {
         )
     }
 
+    #[cfg(target_os = "dragonfly")]
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn add_creds(&mut self, creds: &[SocketCred]) -> bool {
+        self.truncated = false;
+        add_to_ancillary_data(
+            &mut self.buffer,
+            &mut self.length,
+            creds,
+            libc::SOL_SOCKET,
+            libc::SCM_CREDS,
+        )
+    }
+
     /// Clears the ancillary data, removing all values.
     ///
     /// # Example
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index a2caccc7849..f23f8f94a24 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -854,8 +854,14 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "dragonfly"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "dragonfly")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::UnixDatagram;
     ///
@@ -865,7 +871,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux",))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "dragonfly",))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
         self.0.set_passcred(passcred)
@@ -877,7 +883,7 @@ impl UnixDatagram {
     /// Get the socket option `SO_PASSCRED`.
     ///
     /// [`set_passcred`]: UnixDatagram::set_passcred
-    #[cfg(any(doc, target_os = "android", target_os = "linux",))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "dragonfly",))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn passcred(&self) -> io::Result<bool> {
         self.0.passcred()
diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs
index a82a0172126..15d0dbe07fe 100644
--- a/library/std/src/sys/unix/net.rs
+++ b/library/std/src/sys/unix/net.rs
@@ -408,12 +408,12 @@ impl Socket {
         Ok(raw != 0)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "dragonfly",))]
     pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
         setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "dragonfly",))]
     pub fn passcred(&self) -> io::Result<bool> {
         let passcred: libc::c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)?;
         Ok(passcred != 0)
diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md
index d6948622662..9de2e733de7 100644
--- a/src/doc/rustdoc/src/command-line-arguments.md
+++ b/src/doc/rustdoc/src/command-line-arguments.md
@@ -57,13 +57,13 @@ release: 1.17.0
 LLVM version: 3.9
 ```
 
-## `-o`/`--output`: output path
+## `-o`/`--out-dir`: output directory path
 
 Using this flag looks like this:
 
 ```bash
 $ rustdoc src/lib.rs -o target/doc
-$ rustdoc src/lib.rs --output target/doc
+$ rustdoc src/lib.rs --out-dir target/doc
 ```
 
 By default, `rustdoc`'s output appears in a directory named `doc` in
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 04bcade156a..ee19567be10 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -504,8 +504,18 @@ impl Options {
             return Err(1);
         }
 
-        let output =
-            matches.opt_str("o").map(|s| PathBuf::from(&s)).unwrap_or_else(|| PathBuf::from("doc"));
+        let out_dir = matches.opt_str("out-dir").map(|s| PathBuf::from(&s));
+        let output = matches.opt_str("output").map(|s| PathBuf::from(&s));
+        let output = match (out_dir, output) {
+            (Some(_), Some(_)) => {
+                diag.struct_err("cannot use both 'out-dir' and 'output' at once").emit();
+                return Err(1);
+            }
+            (Some(out_dir), None) => out_dir,
+            (None, Some(output)) => output,
+            (None, None) => PathBuf::from("doc"),
+        };
+
         let cfgs = matches.opt_strs("cfg");
 
         let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s));
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index b6311abb5c3..8699ab20b19 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -278,7 +278,16 @@ fn opts() -> Vec<RustcOptGroup> {
             o.optopt("r", "input-format", "the input type of the specified file", "[rust]")
         }),
         stable("w", |o| o.optopt("w", "output-format", "the output type to write", "[html]")),
-        stable("o", |o| o.optopt("o", "output", "where to place the output", "PATH")),
+        stable("output", |o| {
+            o.optopt(
+                "",
+                "output",
+                "Which directory to place the output. \
+                 This option is deprecated, use --out-dir instead.",
+                "PATH",
+            )
+        }),
+        stable("o", |o| o.optopt("o", "out-dir", "which directory to place the output", "PATH")),
         stable("crate-name", |o| {
             o.optopt("", "crate-name", "specify the name of this crate", "NAME")
         }),
diff --git a/src/test/run-make/rustdoc-with-out-dir-option/Makefile b/src/test/run-make/rustdoc-with-out-dir-option/Makefile
new file mode 100644
index 00000000000..f79fce8eeea
--- /dev/null
+++ b/src/test/run-make/rustdoc-with-out-dir-option/Makefile
@@ -0,0 +1,8 @@
+-include ../../run-make-fulldeps/tools.mk
+
+OUTPUT_DIR := "$(TMPDIR)/rustdoc"
+
+all:
+	$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR)
+
+	$(HTMLDOCCK) $(OUTPUT_DIR) src/lib.rs
diff --git a/src/test/run-make/rustdoc-with-out-dir-option/src/lib.rs b/src/test/run-make/rustdoc-with-out-dir-option/src/lib.rs
new file mode 100644
index 00000000000..044bb6acb19
--- /dev/null
+++ b/src/test/run-make/rustdoc-with-out-dir-option/src/lib.rs
@@ -0,0 +1,2 @@
+// @has foobar/fn.ok.html
+pub fn ok() {}
diff --git a/src/test/run-make/rustdoc-with-output-option/Makefile b/src/test/run-make/rustdoc-with-output-option/Makefile
new file mode 100644
index 00000000000..654f9672588
--- /dev/null
+++ b/src/test/run-make/rustdoc-with-output-option/Makefile
@@ -0,0 +1,8 @@
+-include ../../run-make-fulldeps/tools.mk
+
+OUTPUT_DIR := "$(TMPDIR)/rustdoc"
+
+all:
+	$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --output $(OUTPUT_DIR)
+
+	$(HTMLDOCCK) $(OUTPUT_DIR) src/lib.rs
diff --git a/src/test/run-make/rustdoc-with-output-option/src/lib.rs b/src/test/run-make/rustdoc-with-output-option/src/lib.rs
new file mode 100644
index 00000000000..044bb6acb19
--- /dev/null
+++ b/src/test/run-make/rustdoc-with-output-option/src/lib.rs
@@ -0,0 +1,2 @@
+// @has foobar/fn.ok.html
+pub fn ok() {}
diff --git a/src/test/run-make/rustdoc-with-short-out-dir-option/Makefile b/src/test/run-make/rustdoc-with-short-out-dir-option/Makefile
new file mode 100644
index 00000000000..1e9ba71de26
--- /dev/null
+++ b/src/test/run-make/rustdoc-with-short-out-dir-option/Makefile
@@ -0,0 +1,8 @@
+-include ../../run-make-fulldeps/tools.mk
+
+OUTPUT_DIR := "$(TMPDIR)/rustdoc"
+
+all:
+	$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib -o $(OUTPUT_DIR)
+
+	$(HTMLDOCCK) $(OUTPUT_DIR) src/lib.rs
diff --git a/src/test/run-make/rustdoc-with-short-out-dir-option/src/lib.rs b/src/test/run-make/rustdoc-with-short-out-dir-option/src/lib.rs
new file mode 100644
index 00000000000..044bb6acb19
--- /dev/null
+++ b/src/test/run-make/rustdoc-with-short-out-dir-option/src/lib.rs
@@ -0,0 +1,2 @@
+// @has foobar/fn.ok.html
+pub fn ok() {}
diff --git a/src/test/rustdoc-ui/use_both_out_dir_and_output_options.rs b/src/test/rustdoc-ui/use_both_out_dir_and_output_options.rs
new file mode 100644
index 00000000000..5037043f19a
--- /dev/null
+++ b/src/test/rustdoc-ui/use_both_out_dir_and_output_options.rs
@@ -0,0 +1 @@
+// compile-flags: --output ./foo
diff --git a/src/test/rustdoc-ui/use_both_out_dir_and_output_options.stderr b/src/test/rustdoc-ui/use_both_out_dir_and_output_options.stderr
new file mode 100644
index 00000000000..96d2295ac3e
--- /dev/null
+++ b/src/test/rustdoc-ui/use_both_out_dir_and_output_options.stderr
@@ -0,0 +1,2 @@
+error: cannot use both 'out-dir' and 'output' at once
+
diff --git a/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs
index c8559d24728..2b3ece67b34 100644
--- a/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs
+++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 #![allow(overflowing_literals)]
 
 // Test that we cleanup a fixed size Box<[D; k]> properly when D has a
diff --git a/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs
index e75051caabc..c0ca4587507 100644
--- a/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs
+++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 #![allow(overflowing_literals)]
 
 // Test that we cleanup dynamic sized Box<[D]> properly when D has a
diff --git a/src/test/ui/array-slice-vec/nested-vec-3.rs b/src/test/ui/array-slice-vec/nested-vec-3.rs
index 96497a53d30..b3ae683a8a6 100644
--- a/src/test/ui/array-slice-vec/nested-vec-3.rs
+++ b/src/test/ui/array-slice-vec/nested-vec-3.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 #![allow(overflowing_literals)]
 
 // ignore-emscripten no threads support
diff --git a/src/test/ui/array-slice-vec/slice-panic-1.rs b/src/test/ui/array-slice-vec/slice-panic-1.rs
index 4134c623778..3829078aba5 100644
--- a/src/test/ui/array-slice-vec/slice-panic-1.rs
+++ b/src/test/ui/array-slice-vec/slice-panic-1.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 
 // ignore-emscripten no threads support
 
diff --git a/src/test/ui/array-slice-vec/slice-panic-2.rs b/src/test/ui/array-slice-vec/slice-panic-2.rs
index 2f7178fb3e1..d83c611d3bb 100644
--- a/src/test/ui/array-slice-vec/slice-panic-2.rs
+++ b/src/test/ui/array-slice-vec/slice-panic-2.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 
 // ignore-emscripten no threads support
 
diff --git a/src/test/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs b/src/test/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs
index f8caebcb876..5e71229beb5 100644
--- a/src/test/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs
+++ b/src/test/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs
@@ -2,6 +2,7 @@
 // be talking about `async fn`s instead. Should also test what happens when it panics.
 
 // run-fail
+// needs-unwind
 // error-pattern: thread 'main' panicked at '`async fn` resumed after panicking'
 // edition:2018
 // ignore-wasm no panic or subprocess support
diff --git a/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs b/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs
index ea4a9e5afa5..684172ca61c 100644
--- a/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs
+++ b/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // Check that partially moved from function parameters are dropped after the
 // named bindings that move from them.
 
diff --git a/src/test/ui/builtin-clone-unwind.rs b/src/test/ui/builtin-clone-unwind.rs
index 2caedb649a3..3623c4a4dd0 100644
--- a/src/test/ui/builtin-clone-unwind.rs
+++ b/src/test/ui/builtin-clone-unwind.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 
 #![allow(unused_variables)]
 #![allow(unused_imports)]
diff --git a/src/test/ui/catch-unwind-bang.rs b/src/test/ui/catch-unwind-bang.rs
index f181991713b..b31b5cab5b7 100644
--- a/src/test/ui/catch-unwind-bang.rs
+++ b/src/test/ui/catch-unwind-bang.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 
 fn worker() -> ! {
diff --git a/src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs b/src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs
index eadbe44a8e9..6cd3781b760 100644
--- a/src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs
+++ b/src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 
 #![allow(unused_must_use)]
 #![allow(dead_code)]
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
index 7df0dd76b44..89f3931418d 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+// needs-unwind
 
 #![deny(rust_2021_incompatible_closure_captures)]
 //~^ NOTE: the lint level is defined here
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
index d02fac7c669..6b0b1052174 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+// needs-unwind
 
 #![deny(rust_2021_incompatible_closure_captures)]
 //~^ NOTE: the lint level is defined here
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
index 74f85b6ebaa..6594ec31653 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
@@ -1,5 +1,5 @@
 error: changes to closure capture in Rust 2021 will affect which traits the closure implements
-  --> $DIR/mir_calls_to_shims.rs:20:38
+  --> $DIR/mir_calls_to_shims.rs:21:38
    |
 LL |     let result = panic::catch_unwind(move || {
    |                                      ^^^^^^^
@@ -11,7 +11,7 @@ LL |         f.0()
    |         --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.0`
    |
 note: the lint level is defined here
-  --> $DIR/mir_calls_to_shims.rs:3:9
+  --> $DIR/mir_calls_to_shims.rs:4:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/drop/drop-trait-enum.rs b/src/test/ui/drop/drop-trait-enum.rs
index 4ab8f733ad7..d2b77650a9d 100644
--- a/src/test/ui/drop/drop-trait-enum.rs
+++ b/src/test/ui/drop/drop-trait-enum.rs
@@ -3,6 +3,7 @@
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 // ignore-emscripten no threads support
+// needs-unwind
 
 use std::thread;
 use std::sync::mpsc::{channel, Sender};
diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs
index c0bf0bdf731..13bd71ecb33 100644
--- a/src/test/ui/drop/dynamic-drop-async.rs
+++ b/src/test/ui/drop/dynamic-drop-async.rs
@@ -4,6 +4,7 @@
 // * Dropping one of the values panics while dropping the future.
 
 // run-pass
+// needs-unwind
 // edition:2018
 // ignore-wasm32-bare compiled with panic=abort by default
 
diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs
index 7bb43d5b503..736123ed119 100644
--- a/src/test/ui/drop/dynamic-drop.rs
+++ b/src/test/ui/drop/dynamic-drop.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(generators, generator_trait)]
diff --git a/src/test/ui/drop/terminate-in-initializer.rs b/src/test/ui/drop/terminate-in-initializer.rs
index c9cb932e62a..66f267aa7c7 100644
--- a/src/test/ui/drop/terminate-in-initializer.rs
+++ b/src/test/ui/drop/terminate-in-initializer.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-emscripten no threads support
 
 // Issue #787
diff --git a/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs b/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
index 74c6e501c91..7a91cbdc2f5 100644
--- a/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
+++ b/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // ignore-emscripten no threads support
 
diff --git a/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs b/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
index bc15fcb0e39..e84ff41b344 100644
--- a/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
+++ b/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // ignore-emscripten no threads support
 
diff --git a/src/test/ui/generator/generator-resume-after-panic.rs b/src/test/ui/generator/generator-resume-after-panic.rs
index 55704f40e9f..f2e67f1f750 100644
--- a/src/test/ui/generator/generator-resume-after-panic.rs
+++ b/src/test/ui/generator/generator-resume-after-panic.rs
@@ -1,4 +1,5 @@
 // run-fail
+// needs-unwind
 // error-pattern:generator resumed after panicking
 // ignore-emscripten no processes
 
diff --git a/src/test/ui/generator/panic-drops-resume.rs b/src/test/ui/generator/panic-drops-resume.rs
index 29f4788b275..8d8eb6a97b1 100644
--- a/src/test/ui/generator/panic-drops-resume.rs
+++ b/src/test/ui/generator/panic-drops-resume.rs
@@ -1,6 +1,7 @@
 //! Tests that panics inside a generator will correctly drop the initial resume argument.
 
 // run-pass
+// needs-unwind
 // ignore-wasm       no unwind support
 // ignore-emscripten no unwind support
 
diff --git a/src/test/ui/generator/panic-drops.rs b/src/test/ui/generator/panic-drops.rs
index c9a201725ae..a9de4e7fc7d 100644
--- a/src/test/ui/generator/panic-drops.rs
+++ b/src/test/ui/generator/panic-drops.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 
 // ignore-wasm32-bare compiled with panic=abort by default
 
diff --git a/src/test/ui/generator/panic-safe.rs b/src/test/ui/generator/panic-safe.rs
index 500a3c9c295..14a0c8dbaf1 100644
--- a/src/test/ui/generator/panic-safe.rs
+++ b/src/test/ui/generator/panic-safe.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 
 // ignore-wasm32-bare compiled with panic=abort by default
 
diff --git a/src/test/ui/generator/resume-after-return.rs b/src/test/ui/generator/resume-after-return.rs
index efed08bd470..538609b981a 100644
--- a/src/test/ui/generator/resume-after-return.rs
+++ b/src/test/ui/generator/resume-after-return.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 
 // ignore-wasm32-bare compiled with panic=abort by default
 
diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
index 324bba15e43..a1cfee944c8 100644
--- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
+++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // revisions: mir thir
 // [thir]compile-flags: -Zthir-unsafeck
diff --git a/src/test/ui/issues/issue-14875.rs b/src/test/ui/issues/issue-14875.rs
index 0d95d168b3d..aaef2aab9fc 100644
--- a/src/test/ui/issues/issue-14875.rs
+++ b/src/test/ui/issues/issue-14875.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 
 // Check that values are not leaked when a dtor panics (#14875)
diff --git a/src/test/ui/issues/issue-25089.rs b/src/test/ui/issues/issue-25089.rs
index cf261d43c55..0f0f78623a2 100644
--- a/src/test/ui/issues/issue-25089.rs
+++ b/src/test/ui/issues/issue-25089.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-emscripten no threads support
 
 use std::thread;
diff --git a/src/test/ui/issues/issue-26655.rs b/src/test/ui/issues/issue-26655.rs
index 4c01183a440..cb386c908a4 100644
--- a/src/test/ui/issues/issue-26655.rs
+++ b/src/test/ui/issues/issue-26655.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-emscripten no threads support
 
 // Check that the destructors of simple enums are run on unwinding
diff --git a/src/test/ui/issues/issue-29485.rs b/src/test/ui/issues/issue-29485.rs
index 6b2fb7126e3..8d58ee6d92c 100644
--- a/src/test/ui/issues/issue-29485.rs
+++ b/src/test/ui/issues/issue-29485.rs
@@ -1,6 +1,7 @@
 // run-pass
 #![allow(unused_attributes)]
 // aux-build:issue-29485.rs
+// needs-unwind
 // ignore-emscripten no threads
 
 #[feature(recover)]
diff --git a/src/test/ui/issues/issue-29948.rs b/src/test/ui/issues/issue-29948.rs
index 8ede8143ea6..01c3ec64861 100644
--- a/src/test/ui/issues/issue-29948.rs
+++ b/src/test/ui/issues/issue-29948.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 
 use std::panic;
diff --git a/src/test/ui/issues/issue-30018-panic.rs b/src/test/ui/issues/issue-30018-panic.rs
index 50749b0c742..cba3055a221 100644
--- a/src/test/ui/issues/issue-30018-panic.rs
+++ b/src/test/ui/issues/issue-30018-panic.rs
@@ -4,6 +4,7 @@
 // spawned thread to isolate the expected error result from the
 // SIGTRAP injected by the drop-flag consistency checking.
 
+// needs-unwind
 // ignore-emscripten no threads support
 
 struct Foo;
diff --git a/src/test/ui/issues/issue-43853.rs b/src/test/ui/issues/issue-43853.rs
index 47c3ab59aa2..3162c091c87 100644
--- a/src/test/ui/issues/issue-43853.rs
+++ b/src/test/ui/issues/issue-43853.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 
 use std::panic;
diff --git a/src/test/ui/issues/issue-46519.rs b/src/test/ui/issues/issue-46519.rs
index cca0995d4ca..9bd3c094851 100644
--- a/src/test/ui/issues/issue-46519.rs
+++ b/src/test/ui/issues/issue-46519.rs
@@ -1,6 +1,7 @@
 // run-pass
 // compile-flags:--test -O
 
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #[test]
diff --git a/src/test/ui/iterators/iter-count-overflow-debug.rs b/src/test/ui/iterators/iter-count-overflow-debug.rs
index 5a0394ae760..15f25f1ca53 100644
--- a/src/test/ui/iterators/iter-count-overflow-debug.rs
+++ b/src/test/ui/iterators/iter-count-overflow-debug.rs
@@ -1,5 +1,6 @@
 // run-pass
 // only-32bit too impatient for 2⁶⁴ items
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C debug_assertions=yes -C opt-level=3
 
diff --git a/src/test/ui/iterators/iter-position-overflow-debug.rs b/src/test/ui/iterators/iter-position-overflow-debug.rs
index 733ee0c46cc..65124c28241 100644
--- a/src/test/ui/iterators/iter-position-overflow-debug.rs
+++ b/src/test/ui/iterators/iter-position-overflow-debug.rs
@@ -1,5 +1,6 @@
 // run-pass
 // only-32bit too impatient for 2⁶⁴ items
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C debug_assertions=yes -C opt-level=3
 
diff --git a/src/test/ui/iterators/iter-step-overflow-debug.rs b/src/test/ui/iterators/iter-step-overflow-debug.rs
index 67605d2fcc2..e16f984de79 100644
--- a/src/test/ui/iterators/iter-step-overflow-debug.rs
+++ b/src/test/ui/iterators/iter-step-overflow-debug.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C debug_assertions=yes
 
diff --git a/src/test/ui/iterators/iter-sum-overflow-debug.rs b/src/test/ui/iterators/iter-sum-overflow-debug.rs
index b7667d1bbf6..d8ce43848a7 100644
--- a/src/test/ui/iterators/iter-sum-overflow-debug.rs
+++ b/src/test/ui/iterators/iter-sum-overflow-debug.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C debug_assertions=yes
 
diff --git a/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs
index 04ca7f8a315..bc8dcbdbb0e 100644
--- a/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs
+++ b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C overflow-checks
 
diff --git a/src/test/ui/macros/macro-comma-behavior-rpass.rs b/src/test/ui/macros/macro-comma-behavior-rpass.rs
index 780e158fe0b..dfd58b25d08 100644
--- a/src/test/ui/macros/macro-comma-behavior-rpass.rs
+++ b/src/test/ui/macros/macro-comma-behavior-rpass.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 #![allow(unused_imports)]
 // Ideally, any macro call with a trailing comma should behave
 // identically to a call without the comma.
diff --git a/src/test/ui/mir/mir_calls_to_shims.rs b/src/test/ui/mir/mir_calls_to_shims.rs
index 6f13d5612ce..42eaab77da9 100644
--- a/src/test/ui/mir/mir_calls_to_shims.rs
+++ b/src/test/ui/mir/mir_calls_to_shims.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(fn_traits)]
diff --git a/src/test/ui/mir/mir_drop_order.rs b/src/test/ui/mir/mir_drop_order.rs
index 22c804abf5c..853efb0fed2 100644
--- a/src/test/ui/mir/mir_drop_order.rs
+++ b/src/test/ui/mir/mir_drop_order.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 
 use std::cell::RefCell;
diff --git a/src/test/ui/mir/mir_drop_panics.rs b/src/test/ui/mir/mir_drop_panics.rs
index bf269ee901b..b4093d70415 100644
--- a/src/test/ui/mir/mir_drop_panics.rs
+++ b/src/test/ui/mir/mir_drop_panics.rs
@@ -1,4 +1,5 @@
 // run-fail
+// needs-unwind
 // error-pattern:panic 1
 // error-pattern:drop 2
 // ignore-emscripten no processes
diff --git a/src/test/ui/mir/mir_dynamic_drops_3.rs b/src/test/ui/mir/mir_dynamic_drops_3.rs
index eb76fdff886..2bcd9fac55c 100644
--- a/src/test/ui/mir/mir_dynamic_drops_3.rs
+++ b/src/test/ui/mir/mir_dynamic_drops_3.rs
@@ -1,4 +1,5 @@
 // run-fail
+// needs-unwind
 // error-pattern:unwind happens
 // error-pattern:drop 3
 // error-pattern:drop 2
diff --git a/src/test/ui/numbers-arithmetic/int-abs-overflow.rs b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs
index 9c6dff7e1a6..d63ba8cb03e 100644
--- a/src/test/ui/numbers-arithmetic/int-abs-overflow.rs
+++ b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs
@@ -1,6 +1,7 @@
 // run-pass
 // compile-flags: -C overflow-checks=on
 // ignore-emscripten no threads support
+// needs-unwind
 
 use std::thread;
 
diff --git a/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs
index 101c5d50b20..f857d4f4c7f 100644
--- a/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs
+++ b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs
@@ -1,5 +1,6 @@
 // run-pass
 // compile-flags: -C debug_assertions=yes
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // ignore-emscripten dies with an LLVM error
 
diff --git a/src/test/ui/panics/panic-handler-chain.rs b/src/test/ui/panics/panic-handler-chain.rs
index 93044b5cb25..73d6e790dff 100644
--- a/src/test/ui/panics/panic-handler-chain.rs
+++ b/src/test/ui/panics/panic-handler-chain.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 #![allow(stable_features)]
 
 // ignore-emscripten no threads support
diff --git a/src/test/ui/panics/panic-handler-flail-wildly.rs b/src/test/ui/panics/panic-handler-flail-wildly.rs
index 6badd203842..679dc7de87a 100644
--- a/src/test/ui/panics/panic-handler-flail-wildly.rs
+++ b/src/test/ui/panics/panic-handler-flail-wildly.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 
 #![allow(stable_features)]
 #![allow(unused_must_use)]
diff --git a/src/test/ui/panics/panic-handler-set-twice.rs b/src/test/ui/panics/panic-handler-set-twice.rs
index 0312ed221ca..27445302090 100644
--- a/src/test/ui/panics/panic-handler-set-twice.rs
+++ b/src/test/ui/panics/panic-handler-set-twice.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 #![allow(unused_variables)]
 #![allow(stable_features)]
 
diff --git a/src/test/ui/panics/panic-in-dtor-drops-fields.rs b/src/test/ui/panics/panic-in-dtor-drops-fields.rs
index caddd942dc0..c0963aa3114 100644
--- a/src/test/ui/panics/panic-in-dtor-drops-fields.rs
+++ b/src/test/ui/panics/panic-in-dtor-drops-fields.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/panics/panic-recover-propagate.rs b/src/test/ui/panics/panic-recover-propagate.rs
index 7969336ca74..e110d94b656 100644
--- a/src/test/ui/panics/panic-recover-propagate.rs
+++ b/src/test/ui/panics/panic-recover-propagate.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-emscripten no threads support
 
 use std::sync::atomic::{AtomicUsize, Ordering};
diff --git a/src/test/ui/privacy/reachable-unnameable-items.rs b/src/test/ui/privacy/reachable-unnameable-items.rs
index f1e53a0d8b4..1c91541e642 100644
--- a/src/test/ui/privacy/reachable-unnameable-items.rs
+++ b/src/test/ui/privacy/reachable-unnameable-items.rs
@@ -1,5 +1,6 @@
 // run-pass
 // ignore-wasm32-bare compiled with panic=abort by default
+// needs-unwind
 // aux-build:reachable-unnameable-items.rs
 
 extern crate reachable_unnameable_items;
diff --git a/src/test/ui/proc-macro/expand-with-a-macro.rs b/src/test/ui/proc-macro/expand-with-a-macro.rs
index 418178d0f0e..21a4547d11e 100644
--- a/src/test/ui/proc-macro/expand-with-a-macro.rs
+++ b/src/test/ui/proc-macro/expand-with-a-macro.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // aux-build:expand-with-a-macro.rs
 
 // ignore-wasm32-bare compiled with panic=abort by default
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs
index 0bd7bf3d51a..cd57d9bca94 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs
@@ -1,5 +1,6 @@
 // compile-flags: --test
 // run-pass
+// needs-unwind
 
 // ignore-wasm32-bare compiled with panic=abort by default
 
diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
index f0850d5c1f1..b067994a5c6 100644
--- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
+++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // revisions: default mir-opt
 //[mir-opt] compile-flags: -Zmir-opt-level=4
diff --git a/src/test/ui/rfcs/rfc1857-drop-order.rs b/src/test/ui/rfcs/rfc1857-drop-order.rs
index 7923aa7c0e2..243b7fb6fad 100644
--- a/src/test/ui/rfcs/rfc1857-drop-order.rs
+++ b/src/test/ui/rfcs/rfc1857-drop-order.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![allow(dead_code, unreachable_code)]
diff --git a/src/test/ui/runtime/rt-explody-panic-payloads.rs b/src/test/ui/runtime/rt-explody-panic-payloads.rs
index dc193582c6a..eb5bf8f67a8 100644
--- a/src/test/ui/runtime/rt-explody-panic-payloads.rs
+++ b/src/test/ui/runtime/rt-explody-panic-payloads.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-emscripten no processes
 // ignore-sgx no processes
 // ignore-wasm32-bare no unwinding panic
diff --git a/src/test/ui/sepcomp/sepcomp-unwind.rs b/src/test/ui/sepcomp/sepcomp-unwind.rs
index 50a4e043943..a59e25a273e 100644
--- a/src/test/ui/sepcomp/sepcomp-unwind.rs
+++ b/src/test/ui/sepcomp/sepcomp-unwind.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 #![allow(dead_code)]
 // compile-flags: -C codegen-units=3
 // ignore-emscripten no threads support
diff --git a/src/test/ui/structs-enums/unit-like-struct-drop-run.rs b/src/test/ui/structs-enums/unit-like-struct-drop-run.rs
index 980fd97e2c6..1e9c269a4d3 100644
--- a/src/test/ui/structs-enums/unit-like-struct-drop-run.rs
+++ b/src/test/ui/structs-enums/unit-like-struct-drop-run.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-emscripten no threads support
 
 // Make sure the destructor is run for unit-like structs.
diff --git a/src/test/ui/test-attrs/test-should-fail-good-message.rs b/src/test/ui/test-attrs/test-should-fail-good-message.rs
index 9fa759f9eb4..3260b6938f0 100644
--- a/src/test/ui/test-attrs/test-should-fail-good-message.rs
+++ b/src/test/ui/test-attrs/test-should-fail-good-message.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: --test
 #[test]
diff --git a/src/test/ui/threads-sendsync/task-stderr.rs b/src/test/ui/threads-sendsync/task-stderr.rs
index 78145e337da..68d226ffbae 100644
--- a/src/test/ui/threads-sendsync/task-stderr.rs
+++ b/src/test/ui/threads-sendsync/task-stderr.rs
@@ -1,5 +1,6 @@
 // run-pass
 // ignore-emscripten no threads support
+// needs-unwind
 
 #![feature(internal_output_capture)]
 
diff --git a/src/test/ui/threads-sendsync/unwind-resource.rs b/src/test/ui/threads-sendsync/unwind-resource.rs
index a063bef0822..6950a9c40d2 100644
--- a/src/test/ui/threads-sendsync/unwind-resource.rs
+++ b/src/test/ui/threads-sendsync/unwind-resource.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 
 #![allow(non_camel_case_types)]
 // ignore-emscripten no threads support
diff --git a/src/test/ui/unwind-unique.rs b/src/test/ui/unwind-unique.rs
index 7ca53b664ac..50ecf751a86 100644
--- a/src/test/ui/unwind-unique.rs
+++ b/src/test/ui/unwind-unique.rs
@@ -1,4 +1,5 @@
 // run-pass
+// needs-unwind
 // ignore-emscripten no threads support
 
 use std::thread;