Skip to content

Commit

Permalink
Auto merge of rust-lang#128128 - matthiaskrgr:rollup-jz6w0ck, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

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
  • Loading branch information
bors committed Jul 24, 2024
2 parents 42103d6 + 1fe9726 commit f4831e6
Show file tree
Hide file tree
Showing 24 changed files with 438 additions and 333 deletions.
2 changes: 1 addition & 1 deletion library/alloc/src/collections/binary_heap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
/// heap.push(4);
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_binary_heap_new_in", issue = "112353")]
#[rustc_const_unstable(feature = "const_binary_heap_new_in", issue = "125961")]
#[must_use]
pub const fn new_in(alloc: A) -> BinaryHeap<T, A> {
BinaryHeap { data: Vec::new_in(alloc) }
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ impl str {
without modifying the original"]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
pub fn replace<P: Pattern>(&self, from: P, to: &str) -> String {
let mut result = String::new();
let mut last_end = 0;
for (start, part) in self.match_indices(from) {
Expand Down Expand Up @@ -309,7 +309,7 @@ impl str {
#[must_use = "this returns the replaced string as a new allocation, \
without modifying the original"]
#[stable(feature = "str_replacen", since = "1.16.0")]
pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String {
pub fn replacen<P: Pattern>(&self, pat: P, to: &str, count: usize) -> String {
// Hope to reduce the times of re-allocation
let mut result = String::with_capacity(32);
let mut last_end = 0;
Expand Down
27 changes: 15 additions & 12 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1497,10 +1497,7 @@ impl String {
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "string_remove_matches", reason = "new API", issue = "72826")]
pub fn remove_matches<'a, P>(&'a mut self, pat: P)
where
P: for<'x> Pattern<'x>,
{
pub fn remove_matches<P: Pattern>(&mut self, pat: P) {
use core::str::pattern::Searcher;

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

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

#[inline]
fn is_contained_in(self, haystack: &'a str) -> bool {
fn is_contained_in(self, haystack: &str) -> bool {
self[..].is_contained_in(haystack)
}

#[inline]
fn is_prefix_of(self, haystack: &'a str) -> bool {
fn is_prefix_of(self, haystack: &str) -> bool {
self[..].is_prefix_of(haystack)
}

#[inline]
fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
fn strip_prefix_of(self, haystack: &str) -> Option<&str> {
self[..].strip_prefix_of(haystack)
}

#[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool {
fn is_suffix_of<'a>(self, haystack: &'a str) -> bool
where
Self::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
{
self[..].is_suffix_of(haystack)
}

#[inline]
fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> {
fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&str>
where
Self::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
{
self[..].strip_suffix_of(haystack)
}
}
Expand Down
14 changes: 6 additions & 8 deletions library/alloc/tests/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1927,12 +1927,10 @@ mod pattern {
}
}

fn cmp_search_to_vec<'a>(
rev: bool,
pat: impl Pattern<'a, Searcher: ReverseSearcher<'a>>,
haystack: &'a str,
right: Vec<SearchStep>,
) {
fn cmp_search_to_vec<P>(rev: bool, pat: P, haystack: &str, right: Vec<SearchStep>)
where
P: for<'a> Pattern<Searcher<'a>: ReverseSearcher<'a>>,
{
let mut searcher = pat.into_searcher(haystack);
let mut v = vec![];
loop {
Expand Down Expand Up @@ -2191,9 +2189,9 @@ generate_iterator_test! {
fn different_str_pattern_forwarding_lifetimes() {
use std::str::pattern::Pattern;

fn foo<'a, P>(p: P)
fn foo<P>(p: P)
where
for<'b> &'b P: Pattern<'a>,
for<'b> &'b P: Pattern,
{
for _ in 0..3 {
"asdf".find(&p);
Expand Down
12 changes: 9 additions & 3 deletions library/core/src/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//! const SOME_PROPERTY: bool = true;
//! }
//!
//! # trait QueryId { const SOME_PROPERTY: core::primitive::bool; }
//! # trait QueryId { const SOME_PROPERTY: ::core::primitive::bool; }
//! ```
//!
//! Note that the `SOME_PROPERTY` associated constant would not compile, as its
Expand All @@ -25,11 +25,17 @@
//! pub struct bool;
//!
//! impl QueryId for bool {
//! const SOME_PROPERTY: core::primitive::bool = true;
//! const SOME_PROPERTY: ::core::primitive::bool = true;
//! }
//!
//! # trait QueryId { const SOME_PROPERTY: core::primitive::bool; }
//! # trait QueryId { const SOME_PROPERTY: ::core::primitive::bool; }
//! ```
//!
//! We also used `::core` instead of `core`, because `core` can be
//! shadowed, too. Paths, starting with `::`, are searched in
//! the [extern prelude] since Edition 2018.
//!
//! [extern prelude]: https://doc.rust-lang.org/nightly/reference/names/preludes.html#extern-prelude

#[stable(feature = "core_primitive", since = "1.43.0")]
pub use bool;
Expand Down
115 changes: 115 additions & 0 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4522,6 +4522,121 @@ impl<T> [T] {
// are disjunct and in bounds.
unsafe { Ok(self.get_many_unchecked_mut(indices)) }
}

/// Returns the index that an element reference points to.
///
/// Returns `None` if `element` does not point within the slice or if it points between elements.
///
/// This method is useful for extending slice iterators like [`slice::split`].
///
/// Note that this uses pointer arithmetic and **does not compare elements**.
/// To find the index of an element via comparison, use
/// [`.iter().position()`](crate::iter::Iterator::position) instead.
///
/// # Panics
/// Panics if `T` is zero-sized.
///
/// # Examples
/// Basic usage:
/// ```
/// #![feature(substr_range)]
///
/// let nums: &[u32] = &[1, 7, 1, 1];
/// let num = &nums[2];
///
/// assert_eq!(num, &1);
/// assert_eq!(nums.elem_offset(num), Some(2));
/// ```
/// Returning `None` with an in-between element:
/// ```
/// #![feature(substr_range)]
///
/// let arr: &[[u32; 2]] = &[[0, 1], [2, 3]];
/// let flat_arr: &[u32] = arr.as_flattened();
///
/// let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap();
/// let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap();
///
/// assert_eq!(ok_elm, &[0, 1]);
/// assert_eq!(weird_elm, &[1, 2]);
///
/// assert_eq!(arr.elem_offset(ok_elm), Some(0)); // Points to element 0
/// assert_eq!(arr.elem_offset(weird_elm), None); // Points between element 0 and 1
/// ```
#[must_use]
#[unstable(feature = "substr_range", issue = "126769")]
pub fn elem_offset(&self, element: &T) -> Option<usize> {
if T::IS_ZST {
panic!("elements are zero-sized");
}

let self_start = self.as_ptr() as usize;
let elem_start = element as *const T as usize;

let byte_offset = elem_start.wrapping_sub(self_start);

if byte_offset % mem::size_of::<T>() != 0 {
return None;
}

let offset = byte_offset / mem::size_of::<T>();

if offset < self.len() { Some(offset) } else { None }
}

/// Returns the range of indices that a subslice points to.
///
/// Returns `None` if `subslice` does not point within the slice or if it points between elements.
///
/// This method **does not compare elements**. Instead, this method finds the location in the slice that
/// `subslice` was obtained from. To find the index of a subslice via comparison, instead use
/// [`.windows()`](slice::windows)[`.position()`](crate::iter::Iterator::position).
///
/// This method is useful for extending slice iterators like [`slice::split`].
///
/// Note that this may return a false positive (either `Some(0..0)` or `Some(self.len()..self.len())`)
/// if `subslice` has a length of zero and points to the beginning or end of another, separate, slice.
///
/// # Panics
/// Panics if `T` is zero-sized.
///
/// # Examples
/// Basic usage:
/// ```
/// #![feature(substr_range)]
///
/// let nums = &[0, 5, 10, 0, 0, 5];
///
/// let mut iter = nums
/// .split(|t| *t == 0)
/// .map(|n| nums.subslice_range(n).unwrap());
///
/// assert_eq!(iter.next(), Some(0..0));
/// assert_eq!(iter.next(), Some(1..3));
/// assert_eq!(iter.next(), Some(4..4));
/// assert_eq!(iter.next(), Some(5..6));
/// ```
#[must_use]
#[unstable(feature = "substr_range", issue = "126769")]
pub fn subslice_range(&self, subslice: &[T]) -> Option<Range<usize>> {
if T::IS_ZST {
panic!("elements are zero-sized");
}

let self_start = self.as_ptr() as usize;
let subslice_start = subslice.as_ptr() as usize;

let byte_start = subslice_start.wrapping_sub(self_start);

if byte_start % core::mem::size_of::<T>() != 0 {
return None;
}

let start = byte_start / core::mem::size_of::<T>();
let end = start.wrapping_add(subslice.len());

if start <= self.len() && end <= self.len() { Some(start..end) } else { None }
}
}

impl<T, const N: usize> [[T; N]] {
Expand Down
Loading

0 comments on commit f4831e6

Please sign in to comment.