mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-19 19:17:31 +00:00
Auto merge of #141529 - jhpratt:rollup-8dle839, r=jhpratt
Rollup of 4 pull requests Successful merges: - rust-lang/rust#139831 (rustdoc: on mobile, make the sidebar full width and linewrap) - rust-lang/rust#140950 (More option optimization tests) - rust-lang/rust#141108 (Docs(lib): Fix `extract_if` docs) - rust-lang/rust#141361 (use `cfg_select!` to select the right `VaListImpl` definition) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
aa57e46e24
@ -1398,10 +1398,12 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an iterator that visits all elements (key-value pairs) in
|
/// Creates an iterator that visits all elements (key-value pairs) in
|
||||||
/// ascending key order and uses a closure to determine if an element should
|
/// ascending key order and uses a closure to determine if an element
|
||||||
/// be removed. If the closure returns `true`, the element is removed from
|
/// should be removed.
|
||||||
/// the map and yielded. If the closure returns `false`, or panics, the
|
///
|
||||||
/// element remains in the map and will not be yielded.
|
/// If the closure returns `true`, the element is removed from the map and
|
||||||
|
/// yielded. If the closure returns `false`, or panics, the element remains
|
||||||
|
/// in the map and will not be yielded.
|
||||||
///
|
///
|
||||||
/// The iterator also lets you mutate the value of each element in the
|
/// The iterator also lets you mutate the value of each element in the
|
||||||
/// closure, regardless of whether you choose to keep or remove it.
|
/// closure, regardless of whether you choose to keep or remove it.
|
||||||
|
@ -1124,20 +1124,20 @@ impl<T, A: Allocator> LinkedList<T, A> {
|
|||||||
|
|
||||||
/// Creates an iterator which uses a closure to determine if an element should be removed.
|
/// Creates an iterator which uses a closure to determine if an element should be removed.
|
||||||
///
|
///
|
||||||
/// If the closure returns true, then the element is removed and yielded.
|
/// If the closure returns `true`, the element is removed from the list and
|
||||||
/// If the closure returns false, the element will remain in the list and will not be yielded
|
/// yielded. If the closure returns `false`, or panics, the element remains
|
||||||
/// by the iterator.
|
/// in the list and will not be yielded.
|
||||||
///
|
///
|
||||||
/// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
|
/// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
|
||||||
/// or the iteration short-circuits, then the remaining elements will be retained.
|
/// or the iteration short-circuits, then the remaining elements will be retained.
|
||||||
/// Use `extract_if().for_each(drop)` if you do not need the returned iterator.
|
/// Use `extract_if().for_each(drop)` if you do not need the returned iterator.
|
||||||
///
|
///
|
||||||
/// Note that `extract_if` lets you mutate every element in the filter closure, regardless of
|
/// The iterator also lets you mutate the value of each element in the
|
||||||
/// whether you choose to keep or remove it.
|
/// closure, regardless of whether you choose to keep or remove it.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Splitting a list into evens and odds, reusing the original list:
|
/// Splitting a list into even and odd values, reusing the original list:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::collections::LinkedList;
|
/// use std::collections::LinkedList;
|
||||||
|
@ -3648,11 +3648,11 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
Splice { drain: self.drain(range), replace_with: replace_with.into_iter() }
|
Splice { drain: self.drain(range), replace_with: replace_with.into_iter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an iterator which uses a closure to determine if element in the range should be removed.
|
/// Creates an iterator which uses a closure to determine if an element in the range should be removed.
|
||||||
///
|
///
|
||||||
/// If the closure returns true, then the element is removed and yielded.
|
/// If the closure returns `true`, the element is removed from the vector
|
||||||
/// If the closure returns false, the element will remain in the vector and will not be yielded
|
/// and yielded. If the closure returns `false`, or panics, the element
|
||||||
/// by the iterator.
|
/// remains in the vector and will not be yielded.
|
||||||
///
|
///
|
||||||
/// Only elements that fall in the provided range are considered for extraction, but any elements
|
/// Only elements that fall in the provided range are considered for extraction, but any elements
|
||||||
/// after the range will still have to be moved if any element has been extracted.
|
/// after the range will still have to be moved if any element has been extracted.
|
||||||
@ -3692,8 +3692,8 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
/// But `extract_if` is easier to use. `extract_if` is also more efficient,
|
/// But `extract_if` is easier to use. `extract_if` is also more efficient,
|
||||||
/// because it can backshift the elements of the array in bulk.
|
/// because it can backshift the elements of the array in bulk.
|
||||||
///
|
///
|
||||||
/// Note that `extract_if` also lets you mutate the elements passed to the filter closure,
|
/// The iterator also lets you mutate the value of each element in the
|
||||||
/// regardless of whether you choose to keep or remove them.
|
/// closure, regardless of whether you choose to keep or remove it.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
@ -3701,7 +3701,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Splitting an array into evens and odds, reusing the original allocation:
|
/// Splitting a vector into even and odd values, reusing the original vector:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
|
/// let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
|
||||||
|
@ -5,148 +5,120 @@
|
|||||||
use crate::ffi::c_void;
|
use crate::ffi::c_void;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::{PhantomData, PhantomInvariantLifetime};
|
||||||
use crate::ops::{Deref, DerefMut};
|
use crate::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
/// Basic implementation of a `va_list`.
|
|
||||||
// The name is WIP, using `VaListImpl` for now.
|
// The name is WIP, using `VaListImpl` for now.
|
||||||
#[cfg(any(
|
//
|
||||||
|
// Most targets explicitly specify the layout of `va_list`, this layout is matched here.
|
||||||
|
crate::cfg_select! {
|
||||||
all(
|
all(
|
||||||
not(target_arch = "aarch64"),
|
|
||||||
not(target_arch = "powerpc"),
|
|
||||||
not(target_arch = "s390x"),
|
|
||||||
not(target_arch = "xtensa"),
|
|
||||||
not(target_arch = "x86_64")
|
|
||||||
),
|
|
||||||
all(target_arch = "aarch64", target_vendor = "apple"),
|
|
||||||
target_family = "wasm",
|
|
||||||
target_os = "uefi",
|
|
||||||
windows,
|
|
||||||
))]
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[lang = "va_list"]
|
|
||||||
pub struct VaListImpl<'f> {
|
|
||||||
ptr: *mut c_void,
|
|
||||||
|
|
||||||
// Invariant over `'f`, so each `VaListImpl<'f>` object is tied to
|
|
||||||
// the region of the function it's defined in
|
|
||||||
_marker: PhantomData<&'f mut &'f c_void>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(
|
|
||||||
all(
|
|
||||||
not(target_arch = "aarch64"),
|
|
||||||
not(target_arch = "powerpc"),
|
|
||||||
not(target_arch = "s390x"),
|
|
||||||
not(target_arch = "xtensa"),
|
|
||||||
not(target_arch = "x86_64")
|
|
||||||
),
|
|
||||||
all(target_arch = "aarch64", target_vendor = "apple"),
|
|
||||||
target_family = "wasm",
|
|
||||||
target_os = "uefi",
|
|
||||||
windows,
|
|
||||||
))]
|
|
||||||
impl<'f> fmt::Debug for VaListImpl<'f> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "va_list* {:p}", self.ptr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// AArch64 ABI implementation of a `va_list`. See the
|
|
||||||
/// [AArch64 Procedure Call Standard] for more details.
|
|
||||||
///
|
|
||||||
/// [AArch64 Procedure Call Standard]:
|
|
||||||
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
|
|
||||||
#[cfg(all(
|
|
||||||
target_arch = "aarch64",
|
target_arch = "aarch64",
|
||||||
not(target_vendor = "apple"),
|
not(target_vendor = "apple"),
|
||||||
not(target_os = "uefi"),
|
not(target_os = "uefi"),
|
||||||
not(windows),
|
not(windows),
|
||||||
))]
|
) => {
|
||||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
/// AArch64 ABI implementation of a `va_list`. See the
|
||||||
#[derive(Debug)]
|
/// [AArch64 Procedure Call Standard] for more details.
|
||||||
#[lang = "va_list"]
|
///
|
||||||
pub struct VaListImpl<'f> {
|
/// [AArch64 Procedure Call Standard]:
|
||||||
|
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
|
||||||
|
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[lang = "va_list"]
|
||||||
|
pub struct VaListImpl<'f> {
|
||||||
stack: *mut c_void,
|
stack: *mut c_void,
|
||||||
gr_top: *mut c_void,
|
gr_top: *mut c_void,
|
||||||
vr_top: *mut c_void,
|
vr_top: *mut c_void,
|
||||||
gr_offs: i32,
|
gr_offs: i32,
|
||||||
vr_offs: i32,
|
vr_offs: i32,
|
||||||
_marker: PhantomData<&'f mut &'f c_void>,
|
_marker: PhantomInvariantLifetime<'f>,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// PowerPC ABI implementation of a `va_list`.
|
all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)) => {
|
||||||
#[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))]
|
/// PowerPC ABI implementation of a `va_list`.
|
||||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[lang = "va_list"]
|
#[lang = "va_list"]
|
||||||
pub struct VaListImpl<'f> {
|
pub struct VaListImpl<'f> {
|
||||||
gpr: u8,
|
gpr: u8,
|
||||||
fpr: u8,
|
fpr: u8,
|
||||||
reserved: u16,
|
reserved: u16,
|
||||||
overflow_arg_area: *mut c_void,
|
overflow_arg_area: *mut c_void,
|
||||||
reg_save_area: *mut c_void,
|
reg_save_area: *mut c_void,
|
||||||
_marker: PhantomData<&'f mut &'f c_void>,
|
_marker: PhantomInvariantLifetime<'f>,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// s390x ABI implementation of a `va_list`.
|
target_arch = "s390x" => {
|
||||||
#[cfg(target_arch = "s390x")]
|
/// s390x ABI implementation of a `va_list`.
|
||||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[lang = "va_list"]
|
#[lang = "va_list"]
|
||||||
pub struct VaListImpl<'f> {
|
pub struct VaListImpl<'f> {
|
||||||
gpr: i64,
|
gpr: i64,
|
||||||
fpr: i64,
|
fpr: i64,
|
||||||
overflow_arg_area: *mut c_void,
|
overflow_arg_area: *mut c_void,
|
||||||
reg_save_area: *mut c_void,
|
reg_save_area: *mut c_void,
|
||||||
_marker: PhantomData<&'f mut &'f c_void>,
|
_marker: PhantomInvariantLifetime<'f>,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// x86_64 ABI implementation of a `va_list`.
|
all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)) => {
|
||||||
#[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))]
|
/// x86_64 ABI implementation of a `va_list`.
|
||||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[lang = "va_list"]
|
#[lang = "va_list"]
|
||||||
pub struct VaListImpl<'f> {
|
pub struct VaListImpl<'f> {
|
||||||
gp_offset: i32,
|
gp_offset: i32,
|
||||||
fp_offset: i32,
|
fp_offset: i32,
|
||||||
overflow_arg_area: *mut c_void,
|
overflow_arg_area: *mut c_void,
|
||||||
reg_save_area: *mut c_void,
|
reg_save_area: *mut c_void,
|
||||||
_marker: PhantomData<&'f mut &'f c_void>,
|
_marker: PhantomInvariantLifetime<'f>,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// Xtensa ABI implementation of a `va_list`.
|
target_arch = "xtensa" => {
|
||||||
#[cfg(target_arch = "xtensa")]
|
/// Xtensa ABI implementation of a `va_list`.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[lang = "va_list"]
|
#[lang = "va_list"]
|
||||||
pub struct VaListImpl<'f> {
|
pub struct VaListImpl<'f> {
|
||||||
stk: *mut i32,
|
stk: *mut i32,
|
||||||
reg: *mut i32,
|
reg: *mut i32,
|
||||||
ndx: i32,
|
ndx: i32,
|
||||||
_marker: PhantomData<&'f mut &'f c_void>,
|
_marker: PhantomInvariantLifetime<'f>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The fallback implementation, used for:
|
||||||
|
//
|
||||||
|
// - apple aarch64 (see https://github.com/rust-lang/rust/pull/56599)
|
||||||
|
// - windows
|
||||||
|
// - uefi
|
||||||
|
// - any other target for which we don't specify the `VaListImpl` above
|
||||||
|
//
|
||||||
|
// In this implementation the `va_list` type is just an alias for an opaque pointer.
|
||||||
|
// That pointer is probably just the next variadic argument on the caller's stack.
|
||||||
|
_ => {
|
||||||
|
/// Basic implementation of a `va_list`.
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[lang = "va_list"]
|
||||||
|
pub struct VaListImpl<'f> {
|
||||||
|
ptr: *mut c_void,
|
||||||
|
|
||||||
|
// Invariant over `'f`, so each `VaListImpl<'f>` object is tied to
|
||||||
|
// the region of the function it's defined in
|
||||||
|
_marker: PhantomInvariantLifetime<'f>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'f> fmt::Debug for VaListImpl<'f> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "va_list* {:p}", self.ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper for a `va_list`
|
crate::cfg_select! {
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct VaList<'a, 'f: 'a> {
|
|
||||||
#[cfg(any(
|
|
||||||
all(
|
all(
|
||||||
not(target_arch = "aarch64"),
|
|
||||||
not(target_arch = "powerpc"),
|
|
||||||
not(target_arch = "s390x"),
|
|
||||||
not(target_arch = "x86_64")
|
|
||||||
),
|
|
||||||
target_arch = "xtensa",
|
|
||||||
all(target_arch = "aarch64", target_vendor = "apple"),
|
|
||||||
target_family = "wasm",
|
|
||||||
target_os = "uefi",
|
|
||||||
windows,
|
|
||||||
))]
|
|
||||||
inner: VaListImpl<'f>,
|
|
||||||
|
|
||||||
#[cfg(all(
|
|
||||||
any(
|
any(
|
||||||
target_arch = "aarch64",
|
target_arch = "aarch64",
|
||||||
target_arch = "powerpc",
|
target_arch = "powerpc",
|
||||||
@ -158,52 +130,41 @@ pub struct VaList<'a, 'f: 'a> {
|
|||||||
not(target_family = "wasm"),
|
not(target_family = "wasm"),
|
||||||
not(target_os = "uefi"),
|
not(target_os = "uefi"),
|
||||||
not(windows),
|
not(windows),
|
||||||
))]
|
) => {
|
||||||
|
/// A wrapper for a `va_list`
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct VaList<'a, 'f: 'a> {
|
||||||
inner: &'a mut VaListImpl<'f>,
|
inner: &'a mut VaListImpl<'f>,
|
||||||
|
|
||||||
_marker: PhantomData<&'a mut VaListImpl<'f>>,
|
_marker: PhantomData<&'a mut VaListImpl<'f>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(
|
|
||||||
all(
|
impl<'f> VaListImpl<'f> {
|
||||||
not(target_arch = "aarch64"),
|
/// Converts a [`VaListImpl`] into a [`VaList`] that is binary-compatible with C's `va_list`.
|
||||||
not(target_arch = "powerpc"),
|
#[inline]
|
||||||
not(target_arch = "s390x"),
|
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
||||||
not(target_arch = "x86_64")
|
VaList { inner: self, _marker: PhantomData }
|
||||||
),
|
}
|
||||||
target_arch = "xtensa",
|
}
|
||||||
all(target_arch = "aarch64", target_vendor = "apple"),
|
}
|
||||||
target_family = "wasm",
|
|
||||||
target_os = "uefi",
|
_ => {
|
||||||
windows,
|
/// A wrapper for a `va_list`
|
||||||
))]
|
#[repr(transparent)]
|
||||||
impl<'f> VaListImpl<'f> {
|
#[derive(Debug)]
|
||||||
/// Converts a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
|
pub struct VaList<'a, 'f: 'a> {
|
||||||
|
inner: VaListImpl<'f>,
|
||||||
|
_marker: PhantomData<&'a mut VaListImpl<'f>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'f> VaListImpl<'f> {
|
||||||
|
/// Converts a [`VaListImpl`] into a [`VaList`] that is binary-compatible with C's `va_list`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
||||||
VaList { inner: VaListImpl { ..*self }, _marker: PhantomData }
|
VaList { inner: VaListImpl { ..*self }, _marker: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(
|
|
||||||
any(
|
|
||||||
target_arch = "aarch64",
|
|
||||||
target_arch = "powerpc",
|
|
||||||
target_arch = "s390x",
|
|
||||||
target_arch = "xtensa",
|
|
||||||
target_arch = "x86_64"
|
|
||||||
),
|
|
||||||
not(target_arch = "xtensa"),
|
|
||||||
any(not(target_arch = "aarch64"), not(target_vendor = "apple")),
|
|
||||||
not(target_family = "wasm"),
|
|
||||||
not(target_os = "uefi"),
|
|
||||||
not(windows),
|
|
||||||
))]
|
|
||||||
impl<'f> VaListImpl<'f> {
|
|
||||||
/// Converts a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
|
|
||||||
#[inline]
|
|
||||||
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
|
||||||
VaList { inner: self, _marker: PhantomData }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,14 +648,14 @@ impl<K, V, S> HashMap<K, V, S> {
|
|||||||
Drain { base: self.base.drain() }
|
Drain { base: self.base.drain() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an iterator which uses a closure to determine if an element should be removed.
|
/// Creates an iterator which uses a closure to determine if an element (key-value pair) should be removed.
|
||||||
///
|
///
|
||||||
/// If the closure returns true, the element is removed from the map and yielded.
|
/// If the closure returns `true`, the element is removed from the map and
|
||||||
/// If the closure returns false, or panics, the element remains in the map and will not be
|
/// yielded. If the closure returns `false`, or panics, the element remains
|
||||||
/// yielded.
|
/// in the map and will not be yielded.
|
||||||
///
|
///
|
||||||
/// Note that `extract_if` lets you mutate every value in the filter closure, regardless of
|
/// The iterator also lets you mutate the value of each element in the
|
||||||
/// whether you choose to keep or remove it.
|
/// closure, regardless of whether you choose to keep or remove it.
|
||||||
///
|
///
|
||||||
/// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
|
/// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
|
||||||
/// or the iteration short-circuits, then the remaining elements will be retained.
|
/// or the iteration short-circuits, then the remaining elements will be retained.
|
||||||
|
@ -276,11 +276,11 @@ impl<T, S> HashSet<T, S> {
|
|||||||
Drain { base: self.base.drain() }
|
Drain { base: self.base.drain() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an iterator which uses a closure to determine if a value should be removed.
|
/// Creates an iterator which uses a closure to determine if an element should be removed.
|
||||||
///
|
///
|
||||||
/// If the closure returns true, then the value is removed and yielded.
|
/// If the closure returns `true`, the element is removed from the set and
|
||||||
/// If the closure returns false, the value will remain in the list and will not be yielded
|
/// yielded. If the closure returns `false`, or panics, the element remains
|
||||||
/// by the iterator.
|
/// in the set and will not be yielded.
|
||||||
///
|
///
|
||||||
/// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
|
/// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
|
||||||
/// or the iteration short-circuits, then the remaining elements will be retained.
|
/// or the iteration short-circuits, then the remaining elements will be retained.
|
||||||
|
@ -2527,9 +2527,12 @@ in src-script.js and main.js
|
|||||||
z-index: 11;
|
z-index: 11;
|
||||||
/* Reduce height slightly to account for mobile topbar. */
|
/* Reduce height slightly to account for mobile topbar. */
|
||||||
height: calc(100vh - 45px);
|
height: calc(100vh - 45px);
|
||||||
width: 200px;
|
|
||||||
/* resize indicator: hide this when on touch or mobile */
|
/* resize indicator: hide this when on touch or mobile */
|
||||||
border-right: none;
|
border-right: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.sidebar-elems .block li a {
|
||||||
|
white-space: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The source view uses a different design for the sidebar toggle, and doesn't have a topbar,
|
/* The source view uses a different design for the sidebar toggle, and doesn't have a topbar,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//@ min-llvm-version: 20
|
||||||
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
|
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
@ -24,6 +25,18 @@ pub fn non_zero_signed_eq(l: Option<NonZero<i64>>, r: Option<NonZero<i64>>) -> b
|
|||||||
l == r
|
l == r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(#49892)
|
||||||
|
// This currently relies on a manual implementation of `PartialOrd`/`Ord` for `Option`
|
||||||
|
// Once LLVM is better able to optimize this pattern, we can return to using a derive.
|
||||||
|
// CHECK-LABEL: @non_zero_ord
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn non_zero_ord(a: Option<NonZero<u32>>, b: Option<NonZero<u32>>) -> bool {
|
||||||
|
// CHECK: start:
|
||||||
|
// CHECK-NEXT: icmp ult i32
|
||||||
|
// CHECK-NEXT: ret i1
|
||||||
|
a < b
|
||||||
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: @non_null_eq
|
// CHECK-LABEL: @non_null_eq
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn non_null_eq(l: Option<NonNull<u8>>, r: Option<NonNull<u8>>) -> bool {
|
pub fn non_null_eq(l: Option<NonNull<u8>>, r: Option<NonNull<u8>>) -> bool {
|
||||||
@ -61,13 +74,3 @@ pub fn niche_eq(l: Option<EnumWithNiche>, r: Option<EnumWithNiche>) -> bool {
|
|||||||
// CHECK-NEXT: ret i1
|
// CHECK-NEXT: ret i1
|
||||||
l == r
|
l == r
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This should work too
|
|
||||||
// // FIXME-CHECK-LABEL: @bool_eq
|
|
||||||
// #[no_mangle]
|
|
||||||
// pub fn bool_eq(l: Option<bool>, r: Option<bool>) -> bool {
|
|
||||||
// // FIXME-CHECK: start:
|
|
||||||
// // FIXME-CHECK-NEXT: icmp eq i8
|
|
||||||
// // FIXME-CHECK-NEXT: ret i1
|
|
||||||
// l == r
|
|
||||||
// }
|
|
||||||
|
15
tests/codegen/option-niche-unfixed/option-bool-eq.rs
Normal file
15
tests/codegen/option-niche-unfixed/option-bool-eq.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//@ should-fail
|
||||||
|
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
|
||||||
|
//! FIXME(#49892)
|
||||||
|
//! Tests that LLVM does not fully optimize comparisons of `Option<bool>`.
|
||||||
|
//! If this starts passing, it can be moved to `tests/codegen/option-niche-eq.rs`
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
// CHECK-LABEL: @bool_eq
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn bool_eq(l: Option<bool>, r: Option<bool>) -> bool {
|
||||||
|
// CHECK: start:
|
||||||
|
// CHECK-NEXT: icmp eq i8
|
||||||
|
// CHECK-NEXT: ret i1
|
||||||
|
l == r
|
||||||
|
}
|
24
tests/codegen/option-niche-unfixed/option-nonzero-eq.rs
Normal file
24
tests/codegen/option-niche-unfixed/option-nonzero-eq.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//@ should-fail
|
||||||
|
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
|
||||||
|
//! FIXME(#49892)
|
||||||
|
//! Test that the derived implementation of `PartialEq` for `Option` is not fully
|
||||||
|
//! optimized by LLVM. If this starts passing, the test and manual impl should
|
||||||
|
//! be removed.
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
use std::num::NonZero;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum Option<T> {
|
||||||
|
None,
|
||||||
|
Some(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @non_zero_eq
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn non_zero_eq(l: Option<NonZero<u32>>, r: Option<NonZero<u32>>) -> bool {
|
||||||
|
// CHECK: start:
|
||||||
|
// CHECK-NEXT: icmp eq i32
|
||||||
|
// CHECK-NEXT: ret i1
|
||||||
|
l == r
|
||||||
|
}
|
@ -244,10 +244,6 @@ click: ".sidebar-menu-toggle"
|
|||||||
assert: "//*[@class='sidebar shown']"
|
assert: "//*[@class='sidebar shown']"
|
||||||
assert-count: ("//*[@class='tooltip popover']", 0)
|
assert-count: ("//*[@class='tooltip popover']", 0)
|
||||||
assert-false: "#method\.create_an_iterator_from_read .tooltip:focus"
|
assert-false: "#method\.create_an_iterator_from_read .tooltip:focus"
|
||||||
// Clicking a notable trait tooltip popover should close the sidebar.
|
|
||||||
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']"
|
|
||||||
assert-count: ("//*[@class='tooltip popover']", 1)
|
|
||||||
assert-false: "//*[@class='sidebar shown']"
|
|
||||||
|
|
||||||
// Also check the focus handling for the settings button.
|
// Also check the focus handling for the settings button.
|
||||||
set-window-size: (1100, 600)
|
set-window-size: (1100, 600)
|
||||||
|
@ -68,16 +68,3 @@ assert-css: ("#settings-menu .popover", {"display": "block"})
|
|||||||
click: ".sidebar-menu-toggle"
|
click: ".sidebar-menu-toggle"
|
||||||
assert: "//*[@class='sidebar shown']"
|
assert: "//*[@class='sidebar shown']"
|
||||||
assert-css: ("#settings-menu .popover", {"display": "none"})
|
assert-css: ("#settings-menu .popover", {"display": "none"})
|
||||||
// Opening the settings popover should close the sidebar.
|
|
||||||
click: "#settings-menu a"
|
|
||||||
assert-css: ("#settings-menu .popover", {"display": "block"})
|
|
||||||
assert-false: "//*[@class='sidebar shown']"
|
|
||||||
|
|
||||||
// Opening the settings popover at start (which async loads stuff) should also close.
|
|
||||||
reload:
|
|
||||||
click: ".sidebar-menu-toggle"
|
|
||||||
assert: "//*[@class='sidebar shown']"
|
|
||||||
assert-false: "#settings-menu .popover"
|
|
||||||
click: "#settings-menu a"
|
|
||||||
assert-false: "//*[@class='sidebar shown']"
|
|
||||||
wait-for: "#settings-menu .popover"
|
|
||||||
|
@ -32,8 +32,8 @@ assert-css: (
|
|||||||
{"display": "block"}
|
{"display": "block"}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Click elsewhere.
|
// Click the toggle to close it
|
||||||
click: "body"
|
click: ".sidebar-menu-toggle"
|
||||||
assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
|
assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
|
||||||
|
|
||||||
// Open the sidebar menu, and make sure pressing Escape closes it.
|
// Open the sidebar menu, and make sure pressing Escape closes it.
|
||||||
@ -57,6 +57,8 @@ scroll-to: ".block.keyword li:nth-child(1)"
|
|||||||
compare-elements-position-near: (".block.keyword li:nth-child(1)", ".mobile-topbar", {"y": 544})
|
compare-elements-position-near: (".block.keyword li:nth-child(1)", ".mobile-topbar", {"y": 544})
|
||||||
|
|
||||||
// Now checking the background color of the sidebar.
|
// Now checking the background color of the sidebar.
|
||||||
|
// Close the sidebar menu.
|
||||||
|
press-key: "Escape"
|
||||||
show-text: true
|
show-text: true
|
||||||
|
|
||||||
define-function: (
|
define-function: (
|
||||||
@ -72,6 +74,10 @@ define-function: (
|
|||||||
"background-color": |background|,
|
"background-color": |background|,
|
||||||
"color": |color|,
|
"color": |color|,
|
||||||
})
|
})
|
||||||
|
// Make sure the sidebar is full width
|
||||||
|
compare-elements-size: (".sidebar", "body", ["width"])
|
||||||
|
// Close the sidebar menu.
|
||||||
|
press-key: "Escape"
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user