Skip to content

Commit f4831e6

Browse files
committed
Auto merge of rust-lang#128128 - matthiaskrgr:rollup-jz6w0ck, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#125962 (Update tracking issue for `const_binary_heap_new_in`) - rust-lang#126770 (Add elem_offset and related methods) - rust-lang#127481 (Remove generic lifetime parameter of trait `Pattern`) - rust-lang#128043 (Docs for core::primitive: mention that "core" can be shadowed, too, so we should write "::core") - rust-lang#128092 (Remove wrapper functions from c.rs) - rust-lang#128100 (Allow to pass a full path for `run-make` tests) - rust-lang#128106 (Fix return type of FileAttr methods on AIX target) - rust-lang#128108 (ensure std step before preparing sysroot) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 42103d6 + 1fe9726 commit f4831e6

File tree

24 files changed

+438
-333
lines changed

24 files changed

+438
-333
lines changed

library/alloc/src/collections/binary_heap/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
484484
/// heap.push(4);
485485
/// ```
486486
#[unstable(feature = "allocator_api", issue = "32838")]
487-
#[rustc_const_unstable(feature = "const_binary_heap_new_in", issue = "112353")]
487+
#[rustc_const_unstable(feature = "const_binary_heap_new_in", issue = "125961")]
488488
#[must_use]
489489
pub const fn new_in(alloc: A) -> BinaryHeap<T, A> {
490490
BinaryHeap { data: Vec::new_in(alloc) }

library/alloc/src/str.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl str {
269269
without modifying the original"]
270270
#[stable(feature = "rust1", since = "1.0.0")]
271271
#[inline]
272-
pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
272+
pub fn replace<P: Pattern>(&self, from: P, to: &str) -> String {
273273
let mut result = String::new();
274274
let mut last_end = 0;
275275
for (start, part) in self.match_indices(from) {
@@ -309,7 +309,7 @@ impl str {
309309
#[must_use = "this returns the replaced string as a new allocation, \
310310
without modifying the original"]
311311
#[stable(feature = "str_replacen", since = "1.16.0")]
312-
pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String {
312+
pub fn replacen<P: Pattern>(&self, pat: P, to: &str, count: usize) -> String {
313313
// Hope to reduce the times of re-allocation
314314
let mut result = String::with_capacity(32);
315315
let mut last_end = 0;

library/alloc/src/string.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -1497,10 +1497,7 @@ impl String {
14971497
/// ```
14981498
#[cfg(not(no_global_oom_handling))]
14991499
#[unstable(feature = "string_remove_matches", reason = "new API", issue = "72826")]
1500-
pub fn remove_matches<'a, P>(&'a mut self, pat: P)
1501-
where
1502-
P: for<'x> Pattern<'x>,
1503-
{
1500+
pub fn remove_matches<P: Pattern>(&mut self, pat: P) {
15041501
use core::str::pattern::Searcher;
15051502

15061503
let rejections = {
@@ -2288,35 +2285,41 @@ impl<'a> Extend<Cow<'a, str>> for String {
22882285
reason = "API not fully fleshed out and ready to be stabilized",
22892286
issue = "27721"
22902287
)]
2291-
impl<'a, 'b> Pattern<'a> for &'b String {
2292-
type Searcher = <&'b str as Pattern<'a>>::Searcher;
2288+
impl<'b> Pattern for &'b String {
2289+
type Searcher<'a> = <&'b str as Pattern>::Searcher<'a>;
22932290

2294-
fn into_searcher(self, haystack: &'a str) -> <&'b str as Pattern<'a>>::Searcher {
2291+
fn into_searcher(self, haystack: &str) -> <&'b str as Pattern>::Searcher<'_> {
22952292
self[..].into_searcher(haystack)
22962293
}
22972294

22982295
#[inline]
2299-
fn is_contained_in(self, haystack: &'a str) -> bool {
2296+
fn is_contained_in(self, haystack: &str) -> bool {
23002297
self[..].is_contained_in(haystack)
23012298
}
23022299

23032300
#[inline]
2304-
fn is_prefix_of(self, haystack: &'a str) -> bool {
2301+
fn is_prefix_of(self, haystack: &str) -> bool {
23052302
self[..].is_prefix_of(haystack)
23062303
}
23072304

23082305
#[inline]
2309-
fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
2306+
fn strip_prefix_of(self, haystack: &str) -> Option<&str> {
23102307
self[..].strip_prefix_of(haystack)
23112308
}
23122309

23132310
#[inline]
2314-
fn is_suffix_of(self, haystack: &'a str) -> bool {
2311+
fn is_suffix_of<'a>(self, haystack: &'a str) -> bool
2312+
where
2313+
Self::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
2314+
{
23152315
self[..].is_suffix_of(haystack)
23162316
}
23172317

23182318
#[inline]
2319-
fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> {
2319+
fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&str>
2320+
where
2321+
Self::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
2322+
{
23202323
self[..].strip_suffix_of(haystack)
23212324
}
23222325
}

library/alloc/tests/str.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -1927,12 +1927,10 @@ mod pattern {
19271927
}
19281928
}
19291929

1930-
fn cmp_search_to_vec<'a>(
1931-
rev: bool,
1932-
pat: impl Pattern<'a, Searcher: ReverseSearcher<'a>>,
1933-
haystack: &'a str,
1934-
right: Vec<SearchStep>,
1935-
) {
1930+
fn cmp_search_to_vec<P>(rev: bool, pat: P, haystack: &str, right: Vec<SearchStep>)
1931+
where
1932+
P: for<'a> Pattern<Searcher<'a>: ReverseSearcher<'a>>,
1933+
{
19361934
let mut searcher = pat.into_searcher(haystack);
19371935
let mut v = vec![];
19381936
loop {
@@ -2191,9 +2189,9 @@ generate_iterator_test! {
21912189
fn different_str_pattern_forwarding_lifetimes() {
21922190
use std::str::pattern::Pattern;
21932191

2194-
fn foo<'a, P>(p: P)
2192+
fn foo<P>(p: P)
21952193
where
2196-
for<'b> &'b P: Pattern<'a>,
2194+
for<'b> &'b P: Pattern,
21972195
{
21982196
for _ in 0..3 {
21992197
"asdf".find(&p);

library/core/src/primitive.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//! const SOME_PROPERTY: bool = true;
1313
//! }
1414
//!
15-
//! # trait QueryId { const SOME_PROPERTY: core::primitive::bool; }
15+
//! # trait QueryId { const SOME_PROPERTY: ::core::primitive::bool; }
1616
//! ```
1717
//!
1818
//! Note that the `SOME_PROPERTY` associated constant would not compile, as its
@@ -25,11 +25,17 @@
2525
//! pub struct bool;
2626
//!
2727
//! impl QueryId for bool {
28-
//! const SOME_PROPERTY: core::primitive::bool = true;
28+
//! const SOME_PROPERTY: ::core::primitive::bool = true;
2929
//! }
3030
//!
31-
//! # trait QueryId { const SOME_PROPERTY: core::primitive::bool; }
31+
//! # trait QueryId { const SOME_PROPERTY: ::core::primitive::bool; }
3232
//! ```
33+
//!
34+
//! We also used `::core` instead of `core`, because `core` can be
35+
//! shadowed, too. Paths, starting with `::`, are searched in
36+
//! the [extern prelude] since Edition 2018.
37+
//!
38+
//! [extern prelude]: https://doc.rust-lang.org/nightly/reference/names/preludes.html#extern-prelude
3339
3440
#[stable(feature = "core_primitive", since = "1.43.0")]
3541
pub use bool;

library/core/src/slice/mod.rs

+115
Original file line numberDiff line numberDiff line change
@@ -4522,6 +4522,121 @@ impl<T> [T] {
45224522
// are disjunct and in bounds.
45234523
unsafe { Ok(self.get_many_unchecked_mut(indices)) }
45244524
}
4525+
4526+
/// Returns the index that an element reference points to.
4527+
///
4528+
/// Returns `None` if `element` does not point within the slice or if it points between elements.
4529+
///
4530+
/// This method is useful for extending slice iterators like [`slice::split`].
4531+
///
4532+
/// Note that this uses pointer arithmetic and **does not compare elements**.
4533+
/// To find the index of an element via comparison, use
4534+
/// [`.iter().position()`](crate::iter::Iterator::position) instead.
4535+
///
4536+
/// # Panics
4537+
/// Panics if `T` is zero-sized.
4538+
///
4539+
/// # Examples
4540+
/// Basic usage:
4541+
/// ```
4542+
/// #![feature(substr_range)]
4543+
///
4544+
/// let nums: &[u32] = &[1, 7, 1, 1];
4545+
/// let num = &nums[2];
4546+
///
4547+
/// assert_eq!(num, &1);
4548+
/// assert_eq!(nums.elem_offset(num), Some(2));
4549+
/// ```
4550+
/// Returning `None` with an in-between element:
4551+
/// ```
4552+
/// #![feature(substr_range)]
4553+
///
4554+
/// let arr: &[[u32; 2]] = &[[0, 1], [2, 3]];
4555+
/// let flat_arr: &[u32] = arr.as_flattened();
4556+
///
4557+
/// let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap();
4558+
/// let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap();
4559+
///
4560+
/// assert_eq!(ok_elm, &[0, 1]);
4561+
/// assert_eq!(weird_elm, &[1, 2]);
4562+
///
4563+
/// assert_eq!(arr.elem_offset(ok_elm), Some(0)); // Points to element 0
4564+
/// assert_eq!(arr.elem_offset(weird_elm), None); // Points between element 0 and 1
4565+
/// ```
4566+
#[must_use]
4567+
#[unstable(feature = "substr_range", issue = "126769")]
4568+
pub fn elem_offset(&self, element: &T) -> Option<usize> {
4569+
if T::IS_ZST {
4570+
panic!("elements are zero-sized");
4571+
}
4572+
4573+
let self_start = self.as_ptr() as usize;
4574+
let elem_start = element as *const T as usize;
4575+
4576+
let byte_offset = elem_start.wrapping_sub(self_start);
4577+
4578+
if byte_offset % mem::size_of::<T>() != 0 {
4579+
return None;
4580+
}
4581+
4582+
let offset = byte_offset / mem::size_of::<T>();
4583+
4584+
if offset < self.len() { Some(offset) } else { None }
4585+
}
4586+
4587+
/// Returns the range of indices that a subslice points to.
4588+
///
4589+
/// Returns `None` if `subslice` does not point within the slice or if it points between elements.
4590+
///
4591+
/// This method **does not compare elements**. Instead, this method finds the location in the slice that
4592+
/// `subslice` was obtained from. To find the index of a subslice via comparison, instead use
4593+
/// [`.windows()`](slice::windows)[`.position()`](crate::iter::Iterator::position).
4594+
///
4595+
/// This method is useful for extending slice iterators like [`slice::split`].
4596+
///
4597+
/// Note that this may return a false positive (either `Some(0..0)` or `Some(self.len()..self.len())`)
4598+
/// if `subslice` has a length of zero and points to the beginning or end of another, separate, slice.
4599+
///
4600+
/// # Panics
4601+
/// Panics if `T` is zero-sized.
4602+
///
4603+
/// # Examples
4604+
/// Basic usage:
4605+
/// ```
4606+
/// #![feature(substr_range)]
4607+
///
4608+
/// let nums = &[0, 5, 10, 0, 0, 5];
4609+
///
4610+
/// let mut iter = nums
4611+
/// .split(|t| *t == 0)
4612+
/// .map(|n| nums.subslice_range(n).unwrap());
4613+
///
4614+
/// assert_eq!(iter.next(), Some(0..0));
4615+
/// assert_eq!(iter.next(), Some(1..3));
4616+
/// assert_eq!(iter.next(), Some(4..4));
4617+
/// assert_eq!(iter.next(), Some(5..6));
4618+
/// ```
4619+
#[must_use]
4620+
#[unstable(feature = "substr_range", issue = "126769")]
4621+
pub fn subslice_range(&self, subslice: &[T]) -> Option<Range<usize>> {
4622+
if T::IS_ZST {
4623+
panic!("elements are zero-sized");
4624+
}
4625+
4626+
let self_start = self.as_ptr() as usize;
4627+
let subslice_start = subslice.as_ptr() as usize;
4628+
4629+
let byte_start = subslice_start.wrapping_sub(self_start);
4630+
4631+
if byte_start % core::mem::size_of::<T>() != 0 {
4632+
return None;
4633+
}
4634+
4635+
let start = byte_start / core::mem::size_of::<T>();
4636+
let end = start.wrapping_add(subslice.len());
4637+
4638+
if start <= self.len() && end <= self.len() { Some(start..end) } else { None }
4639+
}
45254640
}
45264641

45274642
impl<T, const N: usize> [[T; N]] {

0 commit comments

Comments
 (0)