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
This commit is contained in:
bors 2021-12-11 10:37:52 +00:00
commit b9a37ad0d9
84 changed files with 561 additions and 39 deletions

View File

@ -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))
}
}
}

View File

@ -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)]

View File

@ -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

View File

@ -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`].

View File

@ -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`].

View File

@ -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.
///

View File

@ -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;

View File

@ -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)*);

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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));

View File

@ -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")
}),

View File

@ -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

View File

@ -0,0 +1,2 @@
// @has foobar/fn.ok.html
pub fn ok() {}

View File

@ -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

View File

@ -0,0 +1,2 @@
// @has foobar/fn.ok.html
pub fn ok() {}

View File

@ -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

View File

@ -0,0 +1,2 @@
// @has foobar/fn.ok.html
pub fn ok() {}

View File

@ -0,0 +1 @@
// compile-flags: --output ./foo

View File

@ -0,0 +1,2 @@
error: cannot use both 'out-dir' and 'output' at once

View File

@ -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

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(overflowing_literals)]
// Test that we cleanup dynamic sized Box<[D]> properly when D has a

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(overflowing_literals)]
// ignore-emscripten no threads support

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-emscripten no threads support

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-emscripten no threads support

View File

@ -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

View File

@ -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.

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(unused_variables)]
#![allow(unused_imports)]

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
fn worker() -> ! {

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(unused_must_use)]
#![allow(dead_code)]

View File

@ -1,4 +1,5 @@
// run-rustfix
// needs-unwind
#![deny(rust_2021_incompatible_closure_captures)]
//~^ NOTE: the lint level is defined here

View File

@ -1,4 +1,5 @@
// run-rustfix
// needs-unwind
#![deny(rust_2021_incompatible_closure_captures)]
//~^ NOTE: the lint level is defined here

View File

@ -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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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};

View File

@ -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

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
#![feature(generators, generator_trait)]

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-emscripten no threads support
// Issue #787

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
// ignore-emscripten no threads support

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
// ignore-emscripten no threads support

View File

@ -1,4 +1,5 @@
// run-fail
// needs-unwind
// error-pattern:generator resumed after panicking
// ignore-emscripten no processes

View File

@ -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

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default

View File

@ -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

View File

@ -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)

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-emscripten no threads support
use std::thread;

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-emscripten no threads support
// Check that the destructors of simple enums are run on unwinding

View File

@ -1,6 +1,7 @@
// run-pass
#![allow(unused_attributes)]
// aux-build:issue-29485.rs
// needs-unwind
// ignore-emscripten no threads
#[feature(recover)]

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
use std::panic;

View File

@ -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;

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
use std::panic;

View File

@ -1,6 +1,7 @@
// run-pass
// compile-flags:--test -O
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
#[test]

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
// compile-flags: -C debug_assertions=yes

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
// compile-flags: -C debug_assertions=yes

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
// compile-flags: -C overflow-checks

View File

@ -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.

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
#![feature(fn_traits)]

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
use std::cell::RefCell;

View File

@ -1,4 +1,5 @@
// run-fail
// needs-unwind
// error-pattern:panic 1
// error-pattern:drop 2
// ignore-emscripten no processes

View File

@ -1,4 +1,5 @@
// run-fail
// needs-unwind
// error-pattern:unwind happens
// error-pattern:drop 3
// error-pattern:drop 2

View File

@ -1,6 +1,7 @@
// run-pass
// compile-flags: -C overflow-checks=on
// ignore-emscripten no threads support
// needs-unwind
use std::thread;

View File

@ -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

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(stable_features)]
// ignore-emscripten no threads support

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(stable_features)]
#![allow(unused_must_use)]

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(unused_variables)]
#![allow(stable_features)]

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(dead_code)]
#![allow(non_upper_case_globals)]

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-emscripten no threads support
use std::sync::atomic::{AtomicUsize, Ordering};

View File

@ -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;

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// aux-build:expand-with-a-macro.rs
// ignore-wasm32-bare compiled with panic=abort by default

View File

@ -1,5 +1,6 @@
// compile-flags: --test
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default

View File

@ -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

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
#![allow(dead_code, unreachable_code)]

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-emscripten no processes
// ignore-sgx no processes
// ignore-wasm32-bare no unwinding panic

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(dead_code)]
// compile-flags: -C codegen-units=3
// ignore-emscripten no threads support

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-emscripten no threads support
// Make sure the destructor is run for unit-like structs.

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare compiled with panic=abort by default
// compile-flags: --test
#[test]

View File

@ -1,5 +1,6 @@
// run-pass
// ignore-emscripten no threads support
// needs-unwind
#![feature(internal_output_capture)]

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
#![allow(non_camel_case_types)]
// ignore-emscripten no threads support

View File

@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-emscripten no threads support
use std::thread;