mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #154815 - JonathanBrouwer:rollup-sdqRx2J, r=JonathanBrouwer
Rollup of 8 pull requests Successful merges: - rust-lang/rust#149868 (rustc: Stop passing `--allow-undefined` on wasm targets) - rust-lang/rust#153555 (Clarified docs in std::sync::RwLock + added test to ensure that max reader count is respected) - rust-lang/rust#152851 (Fix SGX delayed host lookup via ToSocketAddr) - rust-lang/rust#154051 (use libm for acosh and asinh) - rust-lang/rust#154581 (More informative `Debug for vec::ExtractIf`) - rust-lang/rust#154461 (Edit the docs new_in() and with_capacity_in()) - rust-lang/rust#154526 (Panic/return false on overflow in no_threads read/try_read impl) - rust-lang/rust#154798 (rustdoc-search: match path components on words)
This commit is contained in:
@@ -28,16 +28,6 @@ macro_rules! args {
|
||||
// stack overflow will be guaranteed to trap as it underflows instead of
|
||||
// corrupting static data.
|
||||
concat!($prefix, "--stack-first"),
|
||||
// FIXME we probably shouldn't pass this but instead pass an explicit list
|
||||
// of symbols we'll allow to be undefined. We don't currently have a
|
||||
// mechanism of knowing, however, which symbols are intended to be imported
|
||||
// from the environment and which are intended to be imported from other
|
||||
// objects linked elsewhere. This is a coarse approximation but is sure to
|
||||
// hide some bugs and frustrate someone at some point, so we should ideally
|
||||
// work towards a world where we can explicitly list symbols that are
|
||||
// supposed to be imported and have all other symbols generate errors if
|
||||
// they remain undefined.
|
||||
concat!($prefix, "--allow-undefined"),
|
||||
// LLD only implements C++-like demangling, which doesn't match our own
|
||||
// mangling scheme. Tell LLD to not demangle anything and leave it up to
|
||||
// us to demangle these symbols later. Currently rustc does not perform
|
||||
|
||||
@@ -695,6 +695,15 @@ pub fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocE
|
||||
/// does the same as <code>[Box::into_pin]\([Box::new_in]\(x, alloc))</code>. Consider using
|
||||
/// [`into_pin`](Box::into_pin) if you already have a `Box<T, A>`, or if you want to
|
||||
/// construct a (pinned) `Box` in a different way than with [`Box::new_in`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(allocator_api)]
|
||||
/// use std::alloc::System;
|
||||
///
|
||||
/// let x = Box::pin_in(1, System);
|
||||
/// ```
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
#[must_use]
|
||||
|
||||
@@ -549,8 +549,8 @@ impl<T, A: Allocator> BinaryHeap<T, A> {
|
||||
///
|
||||
/// use std::alloc::System;
|
||||
/// use std::collections::BinaryHeap;
|
||||
/// let mut heap = BinaryHeap::new_in(System);
|
||||
/// heap.push(4);
|
||||
///
|
||||
/// let heap : BinaryHeap<i32, System> = BinaryHeap::new_in(System);
|
||||
/// ```
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
#[must_use]
|
||||
@@ -573,8 +573,8 @@ pub const fn new_in(alloc: A) -> BinaryHeap<T, A> {
|
||||
///
|
||||
/// use std::alloc::System;
|
||||
/// use std::collections::BinaryHeap;
|
||||
/// let mut heap = BinaryHeap::with_capacity_in(10, System);
|
||||
/// heap.push(4);
|
||||
///
|
||||
/// let heap: BinaryHeap<i32, System> = BinaryHeap::with_capacity_in(10, System);
|
||||
/// ```
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
#[must_use]
|
||||
|
||||
@@ -684,13 +684,11 @@ pub fn clear(&mut self) {
|
||||
/// ```
|
||||
/// # #![feature(allocator_api)]
|
||||
/// # #![feature(btreemap_alloc)]
|
||||
///
|
||||
/// use std::collections::BTreeMap;
|
||||
/// use std::alloc::Global;
|
||||
///
|
||||
/// let mut map = BTreeMap::new_in(Global);
|
||||
///
|
||||
/// // entries can now be inserted into the empty map
|
||||
/// map.insert(1, "a");
|
||||
/// let map: BTreeMap<i32, i32> = BTreeMap::new_in(Global);
|
||||
/// ```
|
||||
#[unstable(feature = "btreemap_alloc", issue = "32838")]
|
||||
#[must_use]
|
||||
|
||||
@@ -355,10 +355,11 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
|
||||
/// # #![allow(unused_mut)]
|
||||
/// # #![feature(allocator_api)]
|
||||
/// # #![feature(btreemap_alloc)]
|
||||
///
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::alloc::Global;
|
||||
///
|
||||
/// let mut set: BTreeSet<i32> = BTreeSet::new_in(Global);
|
||||
/// let set: BTreeSet<i32> = BTreeSet::new_in(Global);
|
||||
/// ```
|
||||
#[unstable(feature = "btreemap_alloc", issue = "32838")]
|
||||
#[must_use]
|
||||
|
||||
@@ -509,7 +509,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
|
||||
/// use std::alloc::System;
|
||||
/// use std::collections::LinkedList;
|
||||
///
|
||||
/// let list: LinkedList<u32, _> = LinkedList::new_in(System);
|
||||
/// let list: LinkedList<i32, System> = LinkedList::new_in(System);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
|
||||
@@ -790,7 +790,7 @@ pub const fn new() -> VecDeque<T> {
|
||||
/// ```
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
/// let deque: VecDeque<u32> = VecDeque::with_capacity(10);
|
||||
/// let deque: VecDeque<i32> = VecDeque::with_capacity(10);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@@ -830,9 +830,12 @@ impl<T, A: Allocator> VecDeque<T, A> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::VecDeque;
|
||||
/// # #![feature(allocator_api)]
|
||||
///
|
||||
/// let deque: VecDeque<u32> = VecDeque::new();
|
||||
/// use std::collections::VecDeque;
|
||||
/// use std::alloc::Global;
|
||||
///
|
||||
/// let deque: VecDeque<i32> = VecDeque::new_in(Global);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
@@ -845,9 +848,12 @@ pub const fn new_in(alloc: A) -> VecDeque<T, A> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::VecDeque;
|
||||
/// # #![feature(allocator_api)]
|
||||
///
|
||||
/// let deque: VecDeque<u32> = VecDeque::with_capacity(10);
|
||||
/// use std::collections::VecDeque;
|
||||
/// use std::alloc::Global;
|
||||
///
|
||||
/// let deque: VecDeque<i32> = VecDeque::with_capacity_in(10, Global);
|
||||
/// ```
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
pub fn with_capacity_in(capacity: usize, alloc: A) -> VecDeque<T, A> {
|
||||
|
||||
@@ -737,6 +737,7 @@ impl<T, A: Allocator> Rc<T, A> {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(allocator_api)]
|
||||
///
|
||||
/// use std::rc::Rc;
|
||||
/// use std::alloc::System;
|
||||
///
|
||||
|
||||
@@ -130,20 +130,25 @@ impl<T, F, A> fmt::Debug for ExtractIf<'_, T, F, A>
|
||||
A: Allocator,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let peek = if self.idx < self.end {
|
||||
// This has to use pointer arithmetic as `self.vec[self.idx]` or
|
||||
// `self.vec.get_unchecked(self.idx)` wouldn't work since we
|
||||
// temporarily set the length of `self.vec` to zero.
|
||||
//
|
||||
// SAFETY:
|
||||
// Since `self.idx` is smaller than `self.end` and `self.end` is
|
||||
// smaller than `self.old_len`, `idx` is valid for indexing the
|
||||
// buffer. Also, per the invariant of `self.idx`, this element
|
||||
// has not been inspected/moved out yet.
|
||||
Some(unsafe { &*self.vec.as_ptr().add(self.idx) })
|
||||
} else {
|
||||
None
|
||||
};
|
||||
f.debug_struct("ExtractIf").field("peek", &peek).finish_non_exhaustive()
|
||||
// We have to use pointer arithmetics here,
|
||||
// because the length of `self.vec` is temporarily set to 0.
|
||||
let start = self.vec.as_ptr();
|
||||
|
||||
// SAFETY: we always keep first `self.idx - self.del` elements valid.
|
||||
let retained = unsafe { slice::from_raw_parts(start, self.idx - self.del) };
|
||||
|
||||
// SAFETY: we have not yet touched elements starting at `self.idx`.
|
||||
let valid_tail =
|
||||
unsafe { slice::from_raw_parts(start.add(self.idx), self.old_len - self.idx) };
|
||||
|
||||
// SAFETY: `end - idx <= old_len - idx`, because `end <= old_len`. Also `idx <= end` by invariant.
|
||||
let (remainder, skipped_tail) =
|
||||
unsafe { valid_tail.split_at_unchecked(self.end - self.idx) };
|
||||
|
||||
f.debug_struct("ExtractIf")
|
||||
.field("retained", &retained)
|
||||
.field("remainder", &remainder)
|
||||
.field("skipped_tail", &skipped_tail)
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1062,8 +1062,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||
///
|
||||
/// use std::alloc::System;
|
||||
///
|
||||
/// # #[allow(unused_mut)]
|
||||
/// let mut vec: Vec<i32, _> = Vec::new_in(System);
|
||||
/// let vec: Vec<i32, System> = Vec::new_in(System);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
|
||||
@@ -1651,13 +1651,17 @@ fn extract_if_unconsumed() {
|
||||
|
||||
#[test]
|
||||
fn extract_if_debug() {
|
||||
let mut vec = vec![1, 2];
|
||||
let mut drain = vec.extract_if(.., |&mut x| x % 2 != 0);
|
||||
assert!(format!("{drain:?}").contains("Some(1)"));
|
||||
drain.next();
|
||||
assert!(format!("{drain:?}").contains("Some(2)"));
|
||||
drain.next();
|
||||
assert!(format!("{drain:?}").contains("None"));
|
||||
let mut vec = vec![1, 2, 3, 4, 5, 6, 7, 8];
|
||||
let mut drain = vec.extract_if(1..5, |&mut x| x % 2 != 0);
|
||||
assert_eq!(
|
||||
format!("{drain:?}"),
|
||||
"ExtractIf { retained: [1], remainder: [2, 3, 4, 5], skipped_tail: [6, 7, 8], .. }"
|
||||
);
|
||||
drain.next().unwrap();
|
||||
assert_eq!(
|
||||
format!("{drain:?}"),
|
||||
"ExtractIf { retained: [1, 2], remainder: [4, 5], skipped_tail: [6, 7, 8], .. }"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
use std::num::FpCategory as Fp;
|
||||
use std::ops::{Add, Div, Mul, Rem, Sub};
|
||||
|
||||
/// i586 has issues with floating point precision.
|
||||
const I586: bool = cfg!(target_arch = "x86") && cfg!(not(target_feature = "sse2"));
|
||||
|
||||
pub(crate) trait TestableFloat: Sized {
|
||||
const BITS: u32;
|
||||
/// Unsigned int with the same size, for converting to/from bits.
|
||||
@@ -59,6 +62,7 @@ pub(crate) trait TestableFloat: Sized {
|
||||
const NEG_MUL_ADD_RESULT: Self;
|
||||
/// Reciprocal of the maximum val
|
||||
const MAX_RECIP: Self;
|
||||
const ASINH_ACOSH_MAX: Self;
|
||||
}
|
||||
|
||||
impl TestableFloat for f16 {
|
||||
@@ -103,6 +107,7 @@ impl TestableFloat for f16 {
|
||||
const MUL_ADD_RESULT: Self = 62.031;
|
||||
const NEG_MUL_ADD_RESULT: Self = 48.625;
|
||||
const MAX_RECIP: Self = 1.526624e-5;
|
||||
const ASINH_ACOSH_MAX: Self = 11.781;
|
||||
}
|
||||
|
||||
impl TestableFloat for f32 {
|
||||
@@ -120,8 +125,20 @@ impl TestableFloat for f32 {
|
||||
const LOG_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX };
|
||||
const LOG2_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX };
|
||||
const LOG10_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX };
|
||||
const ASINH_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX };
|
||||
const ACOSH_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX };
|
||||
const ASINH_APPROX: Self = if cfg!(miri) {
|
||||
1e-3
|
||||
} else if I586 {
|
||||
1e-5
|
||||
} else {
|
||||
Self::APPROX
|
||||
};
|
||||
const ACOSH_APPROX: Self = if cfg!(miri) {
|
||||
1e-3
|
||||
} else if I586 {
|
||||
1e-5
|
||||
} else {
|
||||
Self::APPROX
|
||||
};
|
||||
const ATANH_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX };
|
||||
const GAMMA_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX };
|
||||
const GAMMA_APPROX_LOOSE: Self = if cfg!(miri) { 1e-2 } else { 1e-4 };
|
||||
@@ -149,6 +166,7 @@ impl TestableFloat for f32 {
|
||||
const MUL_ADD_RESULT: Self = 62.05;
|
||||
const NEG_MUL_ADD_RESULT: Self = 48.65;
|
||||
const MAX_RECIP: Self = 2.938736e-39;
|
||||
const ASINH_ACOSH_MAX: Self = 89.4159851;
|
||||
}
|
||||
|
||||
impl TestableFloat for f64 {
|
||||
@@ -180,6 +198,7 @@ impl TestableFloat for f64 {
|
||||
const MUL_ADD_RESULT: Self = 62.050000000000004;
|
||||
const NEG_MUL_ADD_RESULT: Self = 48.650000000000006;
|
||||
const MAX_RECIP: Self = 5.562684646268003e-309;
|
||||
const ASINH_ACOSH_MAX: Self = 710.47586007394398;
|
||||
}
|
||||
|
||||
impl TestableFloat for f128 {
|
||||
@@ -221,6 +240,7 @@ impl TestableFloat for f128 {
|
||||
const MUL_ADD_RESULT: Self = 62.0500000000000000000000000000000037;
|
||||
const NEG_MUL_ADD_RESULT: Self = 48.6500000000000000000000000000000049;
|
||||
const MAX_RECIP: Self = 8.40525785778023376565669454330438228902076605e-4933;
|
||||
const ASINH_ACOSH_MAX: Self = 11357.216553474703894801348310092223;
|
||||
}
|
||||
|
||||
/// Determine the tolerance for values of the argument type.
|
||||
@@ -1705,6 +1725,9 @@ fn s_nan() -> Float {
|
||||
|
||||
assert_approx_eq!(flt(-200.0).asinh(), -5.991470797049389, Float::ASINH_APPROX);
|
||||
|
||||
// issue 153878: large values were rounding to infinity
|
||||
assert_approx_eq!(Float::MAX.asinh(), Float::ASINH_ACOSH_MAX, Float::ASINH_APPROX);
|
||||
|
||||
#[allow(overflowing_literals)]
|
||||
if Float::MAX > flt(66000.0) {
|
||||
// regression test for the catastrophic cancellation fixed in 72486
|
||||
@@ -1733,6 +1756,9 @@ fn s_nan() -> Float {
|
||||
assert_approx_eq!(flt(2.0).acosh(), 1.31695789692481670862504634730796844, Float::ACOSH_APPROX);
|
||||
assert_approx_eq!(flt(3.0).acosh(), 1.76274717403908605046521864995958461, Float::ACOSH_APPROX);
|
||||
|
||||
// issue 153878: large values were rounding to infinity
|
||||
assert_approx_eq!(Float::MAX.acosh(), Float::ASINH_ACOSH_MAX, Float::ACOSH_APPROX);
|
||||
|
||||
#[allow(overflowing_literals)]
|
||||
if Float::MAX > flt(66000.0) {
|
||||
// test for low accuracy from issue 104548
|
||||
|
||||
@@ -301,8 +301,11 @@ impl<K, V, A: Allocator> HashMap<K, V, RandomState, A> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(allocator_api)]
|
||||
/// use std::collections::HashMap;
|
||||
/// let mut map: HashMap<&str, i32> = HashMap::new();
|
||||
/// use std::alloc::Global;
|
||||
///
|
||||
/// let map: HashMap<i32, i32> = HashMap::new_in(Global);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
@@ -321,8 +324,11 @@ pub fn new_in(alloc: A) -> Self {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(allocator_api)]
|
||||
/// use std::collections::HashMap;
|
||||
/// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10);
|
||||
/// use std::alloc::Global;
|
||||
///
|
||||
/// let map: HashMap<i32, i32> = HashMap::with_capacity_in(10, Global);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
@@ -410,6 +416,18 @@ impl<K, V, S, A: Allocator> HashMap<K, V, S, A> {
|
||||
///
|
||||
/// The `hash_builder` passed should implement the [`BuildHasher`] trait for
|
||||
/// the `HashMap` to be useful, see its documentation for details.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(allocator_api)]
|
||||
/// use std::alloc::Global;
|
||||
/// use std::collections::HashMap;
|
||||
/// use std::hash::RandomState;
|
||||
///
|
||||
/// let s = RandomState::new();
|
||||
/// let map: HashMap<i32, i32> = HashMap::with_hasher_in(s, Global);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
@@ -432,6 +450,17 @@ pub fn with_hasher_in(hash_builder: S, alloc: A) -> Self {
|
||||
/// The `hasher` passed should implement the [`BuildHasher`] trait for
|
||||
/// the `HashMap` to be useful, see its documentation for details.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(allocator_api)]
|
||||
/// use std::alloc::Global;
|
||||
/// use std::collections::HashMap;
|
||||
/// use std::hash::RandomState;
|
||||
///
|
||||
/// let s = RandomState::new();
|
||||
/// let map: HashMap<i32, i32> = HashMap::with_capacity_and_hasher_in(10, s, Global);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
|
||||
@@ -176,6 +176,15 @@ impl<T, A: Allocator> HashSet<T, RandomState, A> {
|
||||
///
|
||||
/// The hash set is initially created with a capacity of 0, so it will not allocate until it
|
||||
/// is first inserted into.
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(allocator_api)]
|
||||
/// use std::alloc::Global;
|
||||
/// use std::collections::HashSet;
|
||||
///
|
||||
/// let set: HashSet<i32> = HashSet::new_in(Global);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
@@ -192,9 +201,11 @@ pub fn new_in(alloc: A) -> HashSet<T, RandomState, A> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(allocator_api)]
|
||||
/// use std::collections::HashSet;
|
||||
/// let set: HashSet<i32> = HashSet::with_capacity(10);
|
||||
/// assert!(set.capacity() >= 10);
|
||||
/// use std::alloc::Global;
|
||||
///
|
||||
/// let set: HashSet<i32> = HashSet::with_capacity_in(10, Global);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
@@ -282,6 +293,18 @@ impl<T, S, A: Allocator> HashSet<T, S, A> {
|
||||
///
|
||||
/// The `hash_builder` passed should implement the [`BuildHasher`] trait for
|
||||
/// the `HashSet` to be useful, see its documentation for details.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(allocator_api)]
|
||||
/// use std::alloc::Global;
|
||||
/// use std::collections::HashSet;
|
||||
/// use std::hash::RandomState;
|
||||
///
|
||||
/// let s = RandomState::new();
|
||||
/// let set: HashSet<i32> = HashSet::with_hasher_in(s, Global);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
@@ -303,6 +326,18 @@ pub fn with_hasher_in(hasher: S, alloc: A) -> HashSet<T, S, A> {
|
||||
///
|
||||
/// The `hash_builder` passed should implement the [`BuildHasher`] trait for
|
||||
/// the `HashSet` to be useful, see its documentation for details.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(allocator_api)]
|
||||
/// use std::alloc::Global;
|
||||
/// use std::collections::HashSet;
|
||||
/// use std::hash::RandomState;
|
||||
///
|
||||
/// let s = RandomState::new();
|
||||
/// let set: HashSet<i32> = HashSet::with_capacity_and_hasher_in(10, s, Global);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
|
||||
@@ -189,11 +189,6 @@ fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lookup_host(host: &str, port: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
|
||||
let addrs = crate::sys::net::lookup_host(host, port)?;
|
||||
Ok(Vec::from_iter(addrs).into_iter())
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl ToSocketAddrs for (&str, u16) {
|
||||
type Iter = vec::IntoIter<SocketAddr>;
|
||||
@@ -207,7 +202,7 @@ fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
|
||||
}
|
||||
|
||||
// Otherwise, make the system look it up.
|
||||
lookup_host(host, port)
|
||||
crate::sys::net::lookup_host(host, port).map(|addrs| Vec::from_iter(addrs).into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,16 +224,8 @@ fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
|
||||
return Ok(vec![addr].into_iter());
|
||||
}
|
||||
|
||||
// Otherwise, split the string by ':' and convert the second part to u16...
|
||||
let Some((host, port_str)) = self.rsplit_once(':') else {
|
||||
return Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid socket address"));
|
||||
};
|
||||
let Ok(port) = port_str.parse::<u16>() else {
|
||||
return Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid port value"));
|
||||
};
|
||||
|
||||
// ... and make the system look up the host.
|
||||
lookup_host(host, port)
|
||||
// Otherwise, make the system look it up.
|
||||
crate::sys::net::lookup_host_string(self).map(|addrs| Vec::from_iter(addrs).into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -867,9 +867,7 @@ pub fn tanh(self) -> f128 {
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn asinh(self) -> f128 {
|
||||
let ax = self.abs();
|
||||
let ix = 1.0 / ax;
|
||||
(ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
|
||||
cmath::asinhf128(self)
|
||||
}
|
||||
|
||||
/// Inverse hyperbolic cosine function.
|
||||
@@ -900,11 +898,7 @@ pub fn asinh(self) -> f128 {
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn acosh(self) -> f128 {
|
||||
if self < 1.0 {
|
||||
Self::NAN
|
||||
} else {
|
||||
(self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
|
||||
}
|
||||
cmath::acoshf128(self)
|
||||
}
|
||||
|
||||
/// Inverse hyperbolic tangent function.
|
||||
|
||||
@@ -832,9 +832,7 @@ pub fn tanh(self) -> f16 {
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn asinh(self) -> f16 {
|
||||
let ax = self.abs();
|
||||
let ix = 1.0 / ax;
|
||||
(ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
|
||||
cmath::asinhf(self as f32) as f16
|
||||
}
|
||||
|
||||
/// Inverse hyperbolic cosine function.
|
||||
@@ -865,11 +863,7 @@ pub fn asinh(self) -> f16 {
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn acosh(self) -> f16 {
|
||||
if self < 1.0 {
|
||||
Self::NAN
|
||||
} else {
|
||||
(self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
|
||||
}
|
||||
cmath::acoshf(self as f32) as f16
|
||||
}
|
||||
|
||||
/// Inverse hyperbolic tangent function.
|
||||
|
||||
@@ -1091,9 +1091,7 @@ pub fn tanh(self) -> f32 {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn asinh(self) -> f32 {
|
||||
let ax = self.abs();
|
||||
let ix = 1.0 / ax;
|
||||
(ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
|
||||
cmath::asinhf(self)
|
||||
}
|
||||
|
||||
/// Inverse hyperbolic cosine function.
|
||||
@@ -1119,11 +1117,7 @@ pub fn asinh(self) -> f32 {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn acosh(self) -> f32 {
|
||||
if self < 1.0 {
|
||||
Self::NAN
|
||||
} else {
|
||||
(self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
|
||||
}
|
||||
cmath::acoshf(self)
|
||||
}
|
||||
|
||||
/// Inverse hyperbolic tangent function.
|
||||
|
||||
@@ -1091,9 +1091,7 @@ pub fn tanh(self) -> f64 {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn asinh(self) -> f64 {
|
||||
let ax = self.abs();
|
||||
let ix = 1.0 / ax;
|
||||
(ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
|
||||
cmath::asinh(self)
|
||||
}
|
||||
|
||||
/// Inverse hyperbolic cosine function.
|
||||
@@ -1119,11 +1117,7 @@ pub fn asinh(self) -> f64 {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn acosh(self) -> f64 {
|
||||
if self < 1.0 {
|
||||
Self::NAN
|
||||
} else {
|
||||
(self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
|
||||
}
|
||||
cmath::acosh(self)
|
||||
}
|
||||
|
||||
/// Inverse hyperbolic tangent function.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
///
|
||||
/// In comparison, a [`Mutex`] does not distinguish between readers or writers
|
||||
/// that acquire the lock, therefore blocking any threads waiting for the lock to
|
||||
/// become available. An `RwLock` will allow any number of readers to acquire the
|
||||
/// become available. An `RwLock` will allow multiple readers to acquire the
|
||||
/// lock as long as a writer is not holding the lock.
|
||||
///
|
||||
/// The priority policy of the lock is dependent on the underlying operating
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
// or by `compiler-builtins` on unsupported platforms.
|
||||
unsafe extern "C" {
|
||||
pub safe fn acos(n: f64) -> f64;
|
||||
pub safe fn acosh(n: f64) -> f64;
|
||||
pub safe fn asin(n: f64) -> f64;
|
||||
pub safe fn asinh(n: f64) -> f64;
|
||||
pub safe fn atan(n: f64) -> f64;
|
||||
pub safe fn atan2(a: f64, b: f64) -> f64;
|
||||
pub safe fn cosh(n: f64) -> f64;
|
||||
@@ -30,7 +32,9 @@
|
||||
pub safe fn erfcf(n: f32) -> f32;
|
||||
|
||||
pub safe fn acosf128(n: f128) -> f128;
|
||||
pub safe fn acoshf128(n: f128) -> f128;
|
||||
pub safe fn asinf128(n: f128) -> f128;
|
||||
pub safe fn asinhf128(n: f128) -> f128;
|
||||
pub safe fn atanf128(n: f128) -> f128;
|
||||
pub safe fn atan2f128(a: f128, b: f128) -> f128;
|
||||
pub safe fn cbrtf128(n: f128) -> f128;
|
||||
@@ -57,6 +61,16 @@ pub fn acosf(n: f32) -> f32 {
|
||||
f64::acos(n as f64) as f32
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn acoshf(n: f32) -> f32 {
|
||||
f64::acosh(n as f64) as f32
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn asinhf(n: f32) -> f32 {
|
||||
f64::asinh(n as f64) as f32
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn asinf(n: f32) -> f32 {
|
||||
f64::asin(n as f64) as f32
|
||||
@@ -95,7 +109,9 @@ pub fn tanhf(n: f32) -> f32 {
|
||||
_ => {
|
||||
unsafe extern "C" {
|
||||
pub safe fn acosf(n: f32) -> f32;
|
||||
pub safe fn acoshf(n: f32) -> f32;
|
||||
pub safe fn asinf(n: f32) -> f32;
|
||||
pub safe fn asinhf(n: f32) -> f32;
|
||||
pub safe fn atan2f(a: f32, b: f32) -> f32;
|
||||
pub safe fn atanf(n: f32) -> f32;
|
||||
pub safe fn coshf(n: f32) -> f32;
|
||||
|
||||
@@ -59,3 +59,22 @@ fn each_addr<A: crate::net::ToSocketAddrs, F, T>(addr: A, mut f: F) -> crate::io
|
||||
None => Err(Error::NO_ADDRESSES),
|
||||
}
|
||||
}
|
||||
|
||||
// Default implementation, may be overridden by platform-specific implementations.
|
||||
#[cfg(not(all(target_vendor = "fortanix", target_env = "sgx")))]
|
||||
pub(crate) fn lookup_host_string(
|
||||
addr: &str,
|
||||
) -> crate::io::Result<impl Iterator<Item = crate::net::SocketAddr>> {
|
||||
use crate::io;
|
||||
|
||||
// Split the string by ':' and convert the second part to u16...
|
||||
let Some((host, port_str)) = addr.rsplit_once(':') else {
|
||||
return Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid socket address"));
|
||||
};
|
||||
let Ok(port) = port_str.parse::<u16>() else {
|
||||
return Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid port value"));
|
||||
};
|
||||
|
||||
// ... and make the system look up the host.
|
||||
crate::sys::net::lookup_host(host, port)
|
||||
}
|
||||
|
||||
@@ -506,9 +506,23 @@ fn next(&mut self) -> Option<SocketAddr> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup_host(host: &str, port: u16) -> io::Result<LookupHost> {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Uncategorized,
|
||||
NonIpSockAddr { host: format!("{host}:{port}") },
|
||||
))
|
||||
pub(crate) fn lookup_host_string(addr: impl Into<String>) -> io::Result<LookupHost> {
|
||||
Err(io::Error::new(io::ErrorKind::Uncategorized, NonIpSockAddr { host: addr.into() }))
|
||||
}
|
||||
|
||||
pub fn lookup_host(host: &str, port: u16) -> io::Result<LookupHost> {
|
||||
lookup_host_string(format!("{host}:{port}"))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn unparseable_sockaddr() {
|
||||
let addr = "local";
|
||||
let error = addr.to_socket_addrs().unwrap_err();
|
||||
let non_ip_addr = error.downcast::<NonIpSockAddr>().unwrap();
|
||||
assert_eq!(addr, non_ip_addr.host);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ pub const fn new() -> RwLock {
|
||||
pub fn read(&self) {
|
||||
let m = self.mode.get();
|
||||
if m >= 0 {
|
||||
self.mode.set(m + 1);
|
||||
self.mode.set(m.checked_add(1).expect("rwlock overflowed read locks"));
|
||||
} else {
|
||||
rtabort!("rwlock locked for writing");
|
||||
}
|
||||
@@ -28,6 +28,9 @@ pub fn read(&self) {
|
||||
pub fn try_read(&self) -> bool {
|
||||
let m = self.mode.get();
|
||||
if m >= 0 {
|
||||
if m == isize::MAX {
|
||||
return false;
|
||||
}
|
||||
self.mode.set(m + 1);
|
||||
true
|
||||
} else {
|
||||
@@ -56,16 +59,19 @@ pub fn try_write(&self) -> bool {
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_unlock(&self) {
|
||||
self.mode.set(self.mode.get() - 1);
|
||||
assert!(
|
||||
self.mode.replace(self.mode.get() - 1) > 0,
|
||||
"rwlock has not been locked for reading"
|
||||
);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn write_unlock(&self) {
|
||||
assert_eq!(self.mode.replace(0), -1);
|
||||
assert_eq!(self.mode.replace(0), -1, "rwlock has not been locked for writing");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn downgrade(&self) {
|
||||
assert_eq!(self.mode.replace(1), -1);
|
||||
assert_eq!(self.mode.replace(1), -1, "rwlock has not been locked for writing");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
|
||||
TryLockError,
|
||||
};
|
||||
use std::{hint, mem, thread};
|
||||
use std::{hint, mem, thread, u32};
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
@@ -883,3 +883,66 @@ fn test_rwlock_with_mut() {
|
||||
assert_eq!(*rwlock.read(), 5);
|
||||
assert_eq!(result, 10);
|
||||
}
|
||||
|
||||
// To note: there are (currently) four different implementations of Rwlock:
|
||||
// - On Windows (but not Win 7), Linux, Android, FreeBSD, OpenBSD, DragonFly,
|
||||
// Fuchsia, WASM, Hermit, and Motor OSs, it relies on rwlock/futex.rs, which has
|
||||
// a max reader of 1 << 30 - 2 (or 1073741822). A "too many active reader" error
|
||||
// is displayed after it exceeds the max number of readers.
|
||||
// - On Unix, Win 7, Fortranix (target env of sgx), Xous, and TeeOS, it leans
|
||||
// on rwlock/queue.rs, which uses a linked list under the hood stored on the stack
|
||||
// to hold a queue of waiters. Assuming no stack overflow, the max number of readers
|
||||
// that can be queued up at one time is limited to usize::MAX - (1 << 4) as the first
|
||||
// four bits are reserved for LOCKED, QUEUED, QUEUE_LOCKED, and DOWNGRADED flags. Any
|
||||
// pending readers after that max count, parks the thread and tries to acquire a read lock
|
||||
// again when the thread wakes up.
|
||||
// - On SolidASP3, it leans on rwlock/solid.rs, which utilizes rwl_loc_rdl, so the max
|
||||
// number of readers depends on the internal implementation of rwl_loc_rdl.
|
||||
// - Every other platforms utilizes rwlock/no_threads.rs, which has a max reader of
|
||||
// isize::MAX. An arithmetic overflow error occurs if it exceeds the max reader count.
|
||||
#[test]
|
||||
fn test_rwlock_max_readers() {
|
||||
let mut read_lock_ctr: u32 = 0;
|
||||
let rwlock: RwLock<i32> = RwLock::new(0);
|
||||
|
||||
const MAX_READERS: u32 = cfg_select! {
|
||||
miri => 100,
|
||||
any(
|
||||
all(target_os = "windows", not(target_vendor = "win7")),
|
||||
target_os = "linux",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "fuchsia",
|
||||
all(target_family = "wasm", target_feature = "atomics"),
|
||||
target_os = "hermit",
|
||||
target_os = "motor",
|
||||
) => {
|
||||
(1 << 30) - 2
|
||||
},
|
||||
any(
|
||||
target_family = "unix",
|
||||
all(target_os = "windows", target_vendor = "win7"),
|
||||
all(target_vendor = "fortanix", target_env = "sgx"),
|
||||
target_os = "xous",
|
||||
target_os = "teeos",
|
||||
) => {
|
||||
u32::MAX
|
||||
},
|
||||
target_os = "solid_asp3" => {
|
||||
(1 << 30)
|
||||
},
|
||||
_ => {
|
||||
u32::MAX
|
||||
}
|
||||
};
|
||||
|
||||
while read_lock_ctr < MAX_READERS {
|
||||
let lock = rwlock.read();
|
||||
mem::forget(lock);
|
||||
read_lock_ctr += 1;
|
||||
}
|
||||
|
||||
assert_eq!(read_lock_ctr, MAX_READERS);
|
||||
}
|
||||
|
||||
@@ -2799,6 +2799,8 @@ class DocSearch {
|
||||
result_list.sort((aaa, bbb) => {
|
||||
const aai = aaa.item;
|
||||
const bbi = bbb.item;
|
||||
const ap = aai.modulePath !== undefined ? aai.modulePath : "";
|
||||
const bp = bbi.modulePath !== undefined ? bbi.modulePath : "";
|
||||
/** @type {number} */
|
||||
let a;
|
||||
/** @type {number} */
|
||||
@@ -2829,14 +2831,25 @@ class DocSearch {
|
||||
if (a !== b) {
|
||||
return a - b;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by distance in the path part, if specified
|
||||
// (less changes required to match means higher rankings)
|
||||
a = Number(aaa.path_dist);
|
||||
b = Number(bbb.path_dist);
|
||||
if (a !== b) {
|
||||
return a - b;
|
||||
if (parsedQuery.elems[0] &&
|
||||
parsedQuery.elems[0].pathWithoutLast.length !== 0
|
||||
) {
|
||||
// Sort by distance in the path part, if specified
|
||||
// (less changes required to match means higher rankings)
|
||||
a = Number(aaa.path_dist);
|
||||
b = Number(bbb.path_dist);
|
||||
if (a !== b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
// sort by path (longer goes later)
|
||||
a = ap.length + (aai.parent ? aai.parent.name.length + 2 : 0);
|
||||
b = bp.length + (bbi.parent ? bbi.parent.name.length + 2 : 0);
|
||||
if (a !== b) {
|
||||
return a - b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (later literal occurrence, if any, goes later)
|
||||
@@ -2890,8 +2903,8 @@ class DocSearch {
|
||||
}
|
||||
|
||||
// sort by item name (lexicographically larger goes later)
|
||||
let aw = aai.normalizedName;
|
||||
let bw = bbi.normalizedName;
|
||||
const aw = aai.normalizedName;
|
||||
const bw = bbi.normalizedName;
|
||||
if (aw !== bw) {
|
||||
return (aw > bw ? +1 : -1);
|
||||
}
|
||||
@@ -2914,12 +2927,8 @@ class DocSearch {
|
||||
}
|
||||
|
||||
// sort by path (lexicographically larger goes later)
|
||||
const ap = aai.modulePath;
|
||||
const bp = bbi.modulePath;
|
||||
aw = ap === undefined ? "" : ap;
|
||||
bw = bp === undefined ? "" : bp;
|
||||
if (aw !== bw) {
|
||||
return (aw > bw ? +1 : -1);
|
||||
if (ap !== bp) {
|
||||
return (ap > bp ? +1 : -1);
|
||||
}
|
||||
|
||||
// que sera, sera
|
||||
@@ -3848,13 +3857,19 @@ class DocSearch {
|
||||
let dist_total = 0;
|
||||
for (let x = 0; x < clength; ++x) {
|
||||
const [p, c] = [path[i + x], contains[x]];
|
||||
const indexOf = p.indexOf(c);
|
||||
if (parsedQuery.literalSearch && p !== c) {
|
||||
continue pathiter;
|
||||
} else if (Math.floor((p.length - c.length) / 3) <= maxPathEditDistance &&
|
||||
p.indexOf(c) !== -1
|
||||
) {
|
||||
} else if (indexOf !== -1) {
|
||||
// discount distance on substring match
|
||||
dist_total += Math.floor((p.length - c.length) / 3);
|
||||
// if component is surrounded by underscores or edges,
|
||||
// count the distance as zero
|
||||
if (
|
||||
(indexOf !== 0 && p[indexOf - 1] !== "_") ||
|
||||
(indexOf + c.length !== p.length && p[indexOf + c.length] !== "_")
|
||||
) {
|
||||
dist_total += Math.floor((p.length - c.length) / 3);
|
||||
}
|
||||
} else {
|
||||
const dist = editDistance(p, c, maxPathEditDistance);
|
||||
if (dist > maxPathEditDistance) {
|
||||
|
||||
@@ -30,6 +30,8 @@ fn emulate_foreign_item_inner(
|
||||
| "acosf"
|
||||
| "asinf"
|
||||
| "atanf"
|
||||
| "acoshf"
|
||||
| "asinhf"
|
||||
| "log1pf"
|
||||
| "expm1f"
|
||||
| "tgammaf"
|
||||
@@ -52,6 +54,8 @@ fn emulate_foreign_item_inner(
|
||||
"acosf" => f_host.acos(),
|
||||
"asinf" => f_host.asin(),
|
||||
"atanf" => f_host.atan(),
|
||||
"acoshf" => f_host.acosh(),
|
||||
"asinhf" => f_host.asinh(),
|
||||
"log1pf" => f_host.ln_1p(),
|
||||
"expm1f" => f_host.exp_m1(),
|
||||
"tgammaf" => f_host.gamma(),
|
||||
@@ -113,6 +117,8 @@ fn emulate_foreign_item_inner(
|
||||
| "acos"
|
||||
| "asin"
|
||||
| "atan"
|
||||
| "acosh"
|
||||
| "asinh"
|
||||
| "log1p"
|
||||
| "expm1"
|
||||
| "tgamma"
|
||||
@@ -135,6 +141,8 @@ fn emulate_foreign_item_inner(
|
||||
"acos" => f_host.acos(),
|
||||
"asin" => f_host.asin(),
|
||||
"atan" => f_host.atan(),
|
||||
"acosh" => f_host.acosh(),
|
||||
"asinh" => f_host.asinh(),
|
||||
"log1p" => f_host.ln_1p(),
|
||||
"expm1" => f_host.exp_m1(),
|
||||
"tgamma" => f_host.gamma(),
|
||||
|
||||
@@ -1611,9 +1611,9 @@ fn test_operations_f32(a: f32, b: f32) {
|
||||
check_nondet(|| 1.0f32.sinh());
|
||||
check_nondet(|| 1.0f32.cosh());
|
||||
check_nondet(|| 1.0f32.tanh());
|
||||
check_nondet(|| 1.0f32.asinh());
|
||||
check_nondet(|| 2.0f32.acosh());
|
||||
}
|
||||
check_nondet(|| 1.0f32.asinh());
|
||||
check_nondet(|| 2.0f32.acosh());
|
||||
check_nondet(|| 0.5f32.atanh());
|
||||
check_nondet(|| 5.0f32.gamma());
|
||||
check_nondet(|| 5.0f32.ln_gamma());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#![crate_type = "cdylib"]
|
||||
|
||||
#[link(wasm_import_module = "the-world")]
|
||||
extern "C" {
|
||||
fn observe(ptr: *const u8, len: usize);
|
||||
}
|
||||
@@ -7,6 +8,7 @@
|
||||
macro_rules! s {
|
||||
( $( $f:ident -> $t:ty );* $(;)* ) => {
|
||||
$(
|
||||
#[link(wasm_import_module = "the-world")]
|
||||
extern "C" {
|
||||
fn $f() -> $t;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,11 @@ unsafe fn __rust_alloc(_size: usize, _align: usize) -> *mut u8 {
|
||||
fn __rust_alloc_error_handler(size: usize, align: usize) -> !;
|
||||
}
|
||||
|
||||
#[rustc_std_internal_symbol]
|
||||
pub unsafe fn __rdl_alloc_error_handler(_size: usize, _align: usize) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[used]
|
||||
static mut BUF: [u8; 1024] = [0; 1024];
|
||||
|
||||
|
||||
@@ -10,15 +10,24 @@ const EXPECTED = [
|
||||
query: 'vec::iter',
|
||||
others: [
|
||||
// std::net::ToSocketAttrs::iter should not show up here
|
||||
{ 'path': 'std::collections::vec_deque', 'name': 'Iter' },
|
||||
{ 'path': 'std::collections::VecDeque', 'name': 'iter' },
|
||||
{ 'path': 'std::collections::vec_deque', 'name': 'IterMut' },
|
||||
{ 'path': 'std::collections::VecDeque', 'name': 'iter_mut' },
|
||||
{ 'path': 'std::vec::Vec', 'name': 'from_iter' },
|
||||
{ 'path': 'std::vec', 'name': 'IntoIter' },
|
||||
{ 'path': 'std::vec::Vec', 'name': 'from_iter' },
|
||||
{ 'path': 'std::vec::Vec', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::ExtractIf', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::Drain', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::IntoIter', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::Splice', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::IntoIter', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::ExtractIf', 'name': 'into_iter' },
|
||||
{ 'path': 'std::collections::vec_deque', 'name': 'IntoIter' },
|
||||
{ 'path': 'std::collections::vec_deque::Iter', 'name': 'into_iter' },
|
||||
{ 'path': 'std::collections::vec_deque::Drain', 'name': 'into_iter' },
|
||||
{ 'path': 'std::collections::vec_deque::Splice', 'name': 'into_iter' },
|
||||
{ 'path': 'std::collections::vec_deque::IterMut', 'name': 'into_iter' },
|
||||
{ 'path': 'std::collections::vec_deque::IntoIter', 'name': 'into_iter' },
|
||||
{ 'path': 'std::collections::vec_deque::ExtractIf', 'name': 'into_iter' },
|
||||
{ 'path': 'std::collections::VecDeque', 'name': 'from_iter' },
|
||||
{ 'path': 'std::collections::VecDeque', 'name': 'into_iter' },
|
||||
],
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
// exact-check
|
||||
// ignore-tidy-linelength
|
||||
const EXPECTED = [
|
||||
// should match (substring)
|
||||
{
|
||||
'query': 'struct:now::Country',
|
||||
'others': [
|
||||
{ 'path': 'x::now_is_the_time_for_all_good_men_to_come_to_the_aid_of_their', 'name': 'Country' },
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'struct:is::Country',
|
||||
'others': [
|
||||
{ 'path': 'x::now_is_the_time_for_all_good_men_to_come_to_the_aid_of_their', 'name': 'Country' },
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'struct:is_the::Country',
|
||||
'others': [
|
||||
{ 'path': 'x::now_is_the_time_for_all_good_men_to_come_to_the_aid_of_their', 'name': 'Country' },
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'struct:the::Country',
|
||||
'others': [
|
||||
{ 'path': 'x::now_is_the_time_for_all_good_men_to_come_to_the_aid_of_their', 'name': 'Country' },
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'struct:their::Country',
|
||||
'others': [
|
||||
{ 'path': 'x::now_is_the_time_for_all_good_men_to_come_to_the_aid_of_their', 'name': 'Country' },
|
||||
],
|
||||
},
|
||||
// should not match
|
||||
{
|
||||
'query': 'struct:ood::Country',
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': 'struct:goo::Country',
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': 'struct:he::Country',
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': 'struct:heir::Country',
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': 'struct:hei::Country',
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': 'struct:no::Country',
|
||||
'others': [],
|
||||
},
|
||||
// should match (edit distance)
|
||||
{
|
||||
'query': 'struct:nowisthetimeforallgoodmentocometotheaidoftheir::Country',
|
||||
'others': [
|
||||
{ 'path': 'x::nowisthetimeforallgoodmentocometotheaidoftheir', 'name': 'Country' },
|
||||
{ 'path': 'x::now_is_the_time_for_all_good_men_to_come_to_the_aid_of_their', 'name': 'Country' },
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'struct:now_is_the_time_for_all_good_men_to_come_to_the_aid_of_their::Country',
|
||||
'others': [
|
||||
{ 'path': 'x::now_is_the_time_for_all_good_men_to_come_to_the_aid_of_their', 'name': 'Country' },
|
||||
{ 'path': 'x::nowisthetimeforallgoodmentocometotheaidoftheir', 'name': 'Country' },
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,7 @@
|
||||
#![crate_name = "x"]
|
||||
pub mod now_is_the_time_for_all_good_men_to_come_to_the_aid_of_their {
|
||||
pub struct Country;
|
||||
}
|
||||
pub mod nowisthetimeforallgoodmentocometotheaidoftheir {
|
||||
pub struct Country;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
//@ run-pass
|
||||
//@ ignore-windows-gnu: only statics marked with used can be GC-ed on windows-gnu
|
||||
//@ ignore-wasm: wasm, for better or worse, exports all #[no_mangle]
|
||||
|
||||
// Regression test for <https://github.com/rust-lang/rust/issues/139744>.
|
||||
// Functions in the binary marked with no_mangle should be GC-ed if they
|
||||
|
||||
Reference in New Issue
Block a user