Commit Graph

7756 Commits

Author SHA1 Message Date
Maybe Waffle
03d4569939 Fill-in tracking issues for features pointer_byte_offsets, const_pointer_byte_offsets and pointer_is_aligned 2022-05-12 12:54:21 +04:00
Maybe Waffle
5a5d62aeb2 Optimize ptr.is_aligned_to()
Apparently LLVM is unable to understand that if count_ones() == 1 then self != 0.
Adding `assume(align != 0)` helps generating better asm:
https://rust.godbolt.org/z/ja18YKq91
2022-05-12 12:54:21 +04:00
Maybe Waffle
6c1ebff59e Implement ptr.is_aligned() in terms of .is_aligned_to() 2022-05-12 12:54:21 +04:00
Maybe Waffle
a908eec438 Lift the Sized requirement from convenience ptr fns
Since they work on byte pointers (by `.cast::<u8>()`ing them), there is
no need to know the size of `T` and so there is no need for `T: Sized`.

The `is_aligned_to` is similar, though it doesn't need the _alignment_
of `T`.
2022-05-12 12:54:21 +04:00
Maybe Waffle
c8c91f757a Add convenience functions to pointers
The functions added:
- {*const T,*mut T}::{wrapping_,}byte_{offset,add,sub}
- {*const T,*mut T}::{byte_offset_from,is_aligned,is_aligned_to}
2022-05-12 12:54:16 +04:00
bors
1d2ea98cff Auto merge of #95837 - scottmcm:ptr-offset-from-unsigned, r=oli-obk
Add `sub_ptr` on pointers (the `usize` version of `offset_from`)

We have `add`/`sub` which are the `usize` versions of `offset`, this adds the `usize` equivalent of `offset_from`.  Like how `.add(d)` replaced a whole bunch of `.offset(d as isize)`, you can see from the changes here that it's fairly common that code actually knows the order between the pointers and *wants* a `usize`, not an `isize`.

As a bonus, this can do `sub nuw`+`udiv exact`, rather than `sub`+`sdiv exact`, which can be optimized slightly better because it doesn't have to worry about negatives.  That's why the slice iterators weren't using `offset_from`, though I haven't updated that code in this PR because slices are so perf-critical that I'll do it as its own change.

This is an intrinsic, like `offset_from`, so that it can eventually be allowed in CTFE.  It also allows checking the extra safety condition -- see the test confirming that CTFE catches it if you pass the pointers in the wrong order.
2022-05-12 02:49:00 +00:00
Scott McMurray
003b954a43 Apply CR suggestions; add real tracking issue 2022-05-11 17:16:25 -07:00
Scott McMurray
4bb15b3797 Add a debug check for ordering, and check for isize overflow in CTFE 2022-05-11 17:16:25 -07:00
Scott McMurray
e76b3f3b5b Rename unsigned_offset_from to sub_ptr 2022-05-11 17:16:25 -07:00
Scott McMurray
89a18cb600 Add unsigned_offset_from on pointers
Like we have `add`/`sub` which are the `usize` version of `offset`, this adds the `usize` equivalent of `offset_from`.  Like how `.add(d)` replaced a whole bunch of `.offset(d as isize)`, you can see from the changes here that it's fairly common that code actually knows the order between the pointers and *wants* a `usize`, not an `isize`.

As a bonus, this can do `sub nuw`+`udiv exact`, rather than `sub`+`sdiv exact`, which can be optimized slightly better because it doesn't have to worry about negatives.  That's why the slice iterators weren't using `offset_from`, though I haven't updated that code in this PR because slices are so perf-critical that I'll do it as its own change.

This is an intrinsic, like `offset_from`, so that it can eventually be allowed in CTFE.  It also allows checking the extra safety condition -- see the test confirming that CTFE catches it if you pass the pointers in the wrong order.
2022-05-11 17:16:25 -07:00
bors
0cd939e36c Auto merge of #96150 - est31:unused_macro_rules, r=petrochenkov
Implement a lint to warn about unused macro rules

This implements a new lint to warn about unused macro rules (arms/matchers), similar to the `unused_macros` lint added by #41907 that warns about entire macros.

```rust
macro_rules! unused_empty {
    (hello) => { println!("Hello, world!") };
    () => { println!("empty") }; //~ ERROR: 1st rule of macro `unused_empty` is never used
}

fn main() {
    unused_empty!(hello);
}
```

Builds upon #96149 and #96156.

Fixes #73576
2022-05-12 00:08:08 +00:00
bors
ecd44958e0 Auto merge of #96232 - sunfishcode:sunfishcode/io-safety-const-fns, r=joshtriplett
Make `BorrowedFd::borrow_raw` a const fn.

Making `BorrowedFd::borrow_raw` a const fn allows it to be used to
create a constant `BorrowedFd<'static>` holding constants such as
`AT_FDCWD`. This will allow [`rustix::fs::cwd`] to become a const fn.

For consistency, make similar changes to `BorrowedHandle::borrow_raw`
and `BorrowedSocket::borrow_raw`.

[`rustix::fs::cwd`]: https://docs.rs/rustix/latest/rustix/fs/fn.cwd.html

r? `@joshtriplett`
2022-05-10 21:19:19 +00:00
est31
493af0b54f Also allow unused macro rules in stdarch 2022-05-10 19:53:22 +02:00
Yuki Okushi
7274447c36
Rollup merge of #96861 - m-ou-se:std-use-prelude-2021, r=joshtriplett
Use Rust 2021 prelude in std itself.
2022-05-11 00:09:34 +09:00
Yuki Okushi
f689f6582c
Rollup merge of #96725 - nico-abram:win_tid, r=ChrisDenton
Expose process windows_process_extensions_main_thread_handle on Windows

~~I did not find any tests in 7d3e03666a/library/std/src/sys/windows/process/tests.rs that actually launch processes, so I haven't added tests for this.~~ I ran the following locally, to check that it works as expected:
```rs
#![feature(windows_process_extensions_main_thread_handle)]

fn main() {
    use std::os::windows::process::{ChildExt, CommandExt};
    const CREATE_SUSPENDED: u32 = 0x00000004;

    let proc = std::process::Command::new("cmd")
        .args(["/C", "echo hello"])
        .creation_flags(CREATE_SUSPENDED)
        .spawn()
        .unwrap();

    extern "system" {
        fn ResumeThread(_: *mut std::ffi::c_void) -> u32;
    }
    unsafe {
        ResumeThread(proc.main_thread_handle());
    }

    let output = proc.wait_with_output().unwrap();
    let str_output = std::str::from_utf8(&output.stdout[..]).unwrap();
    println!("{}", str_output);
}

```

Without the feature attribute it wouldn't compile, and commenting the `ResumeThread` line makes it hang forever, showing that it works.

Trakcing issue https://github.com/rust-lang/rust/issues/96723
2022-05-11 00:09:32 +09:00
Dylan DPC
c5c273b30e
Rollup merge of #96674 - bstrie:vardoc, r=thomcc
docs: add link explaining variance to NonNull docs
2022-05-10 08:24:02 +02:00
unknown
5368ea7d2e Expose process main_thread_handle on Windows 2022-05-10 02:41:19 -03:00
Matthias Krüger
f4bef2e41c
Rollup merge of #96841 - thomcc:revert-osstr-join, r=m-ou-se
Revert "Implement [OsStr]::join", which was merged without FCP.

This reverts commit 4fcbc53820, see https://github.com/rust-lang/rust/pull/96744. (I'm terribly sorry, and truly don't remember r+ing it, or even having seen it before yesterday, which is... genuinely very worrisome for me).

r? `@m-ou-se`
2022-05-09 18:45:37 +02:00
Matthias Krüger
6c8001b85c
Rollup merge of #96008 - fmease:warn-on-useless-doc-hidden-on-assoc-impl-items, r=lcnr
Warn on unused `#[doc(hidden)]` attributes on trait impl items

[Zulip conversation](https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/.E2.9C.94.20Validy.20checks.20for.20.60.23.5Bdoc.28hidden.29.5D.60).

Whether an associated item in a trait impl is shown or hidden in the documentation entirely depends on the corresponding item in the trait declaration. Rustdoc completely ignores `#[doc(hidden)]` attributes on impl items. No error or warning is emitted:

```rust
pub trait Tr { fn f(); }
pub struct Ty;
impl Tr for Ty { #[doc(hidden)] fn f() {} }
//               ^^^^^^^^^^^^^^ ignored by rustdoc and currently
//                              no error or warning issued
```

This may lead users to the wrong belief that the attribute has an effect. In fact, several such cases are found in the standard library (I've removed all of them in this PR).
There does not seem to exist any incentive to allow this in the future either: Impl'ing a trait for a type means the type *fully* conforms to its API. Users can add `#[doc(hidden)]` to the whole impl if they want to hide the implementation or add the attribute to the corresponding associated item in the trait declaration to hide the specific item. Hiding an implementation of an associated item does not make much sense: The associated item can still be found on the trait page.

This PR emits the warn-by-default lint `unused_attribute` for this case with a future-incompat warning.

`@rustbot` label T-compiler T-rustdoc A-lint
2022-05-09 18:45:36 +02:00
Matthias Krüger
28d800ce1c
Rollup merge of #95483 - golddranks:improve_float_docs, r=joshtriplett
Improve floating point documentation

This is my attempt to improve/solve https://github.com/rust-lang/rust/issues/95468 and https://github.com/rust-lang/rust/issues/73328 .

Added/refined explanations:
- Refine the "NaN as a special value" top level explanation of f32
- Refine `const NAN` docstring: add an explanation about there being multitude of NaN bitpatterns and disclaimer about the portability/stability guarantees.
- Refine `fn is_sign_positive` and `fn is_sign_negative` docstrings: add disclaimer about the sign bit of NaNs.
- Refine `fn min` and `fn max` docstrings: explain the semantics and their relationship to the standard and libm better.
- Refine `fn trunc` docstrings: explain the semantics slightly more.
- Refine `fn powi` docstrings: add disclaimer that the rounding behaviour might be different from `powf`.
- Refine `fn copysign` docstrings: add disclaimer about payloads of NaNs.
- Refine `minimum` and `maximum`: add disclaimer that "propagating NaN" doesn't mean that propagating the NaN bit patterns is guaranteed.
- Refine `max` and `min` docstrings: add "ignoring NaN" to bring the one-row explanation to parity with `minimum` and `maximum`.

Cosmetic changes:
- Reword `NaN` and `NAN` as plain "NaN", unless they refer to the specific `const NAN`.
- Reword "a number" to `self` in function docstrings to clarify.
- Remove "Returns NAN if the number is NAN" from `abs`, as this is told to be the default behavior in the top explanation.
2022-05-09 18:45:35 +02:00
Mara Bos
4f212f08cf Use Rust 2021 prelude in std itself. 2022-05-09 11:12:32 +02:00
bors
8a2fe75d0e Auto merge of #95960 - jhpratt:remove-rustc_deprecated, r=compiler-errors
Remove `#[rustc_deprecated]`

This removes `#[rustc_deprecated]` and introduces diagnostics to help users to the right direction (that being `#[deprecated]`). All uses of `#[rustc_deprecated]` have been converted. CI is expected to fail initially; this requires #95958, which includes converting `stdarch`.

I plan on following up in a short while (maybe a bootstrap cycle?) removing the diagnostics, as they're only intended to be short-term.
2022-05-09 04:47:30 +00:00
bors
db5b365fb0 Auto merge of #96802 - gimbles:windows_slice, r=thomcc
[feat] Make sys::windows::os_str::Slice repr(transparent)

Fixes #96577
2022-05-09 02:25:32 +00:00
bors
cb12198715 Auto merge of #96846 - matthiaskrgr:rollup-yxu9ot9, r=matthiaskrgr
Rollup of 5 pull requests

Successful merges:

 - #96617 (Fix incorrect syntax suggestion with `pub async fn`)
 - #96828 (Further elaborate the lack of guarantees from `Hasher`)
 - #96829 (Fix the `x.py clippy` command)
 - #96830 (Add and tweak const-generics tests)
 - #96835 (Add more eslint rules)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
2022-05-08 21:37:26 +00:00
León Orell Valerian Liehr
9d157ada35 Warn on unused doc(hidden) on trait impl items 2022-05-08 22:53:14 +02:00
Matthias Krüger
2c4d7a5463
Rollup merge of #96828 - scottmcm:clarify-hasher-write, r=Amanieu
Further elaborate the lack of guarantees from `Hasher`

I realized that I got too excited in #94598 by adding new methods, and forgot to do the documentation to really answer the core question in #94026.

This PR just has that doc update.

r? `@Amanieu`
2022-05-08 21:31:17 +02:00
bors
68461648bf Auto merge of #96302 - Serial-ATA:more-diagnostic-items, r=manishearth
Add more diagnostic items

This just adds a handful diagnostic items I noticed were missing.

Would it be worth doing this for all of the remaining types? I'm willing to do it if it'd be helpful.
2022-05-08 19:08:34 +00:00
Thom Chiovoloni
df446cb2af
Revert "Implement [OsStr]::join", which was merged without FCP
This reverts commit 4fcbc53820.
2022-05-08 09:37:36 -07:00
name1e5s
b87dd755ca fix panic in Path::strip_prefix 2022-05-08 22:15:26 +08:00
bors
4d1076c9f9 Auto merge of #94206 - PrestonFrom:significant_drop, r=flip1995
Create clippy lint against unexpectedly late drop for temporaries in match scrutinee expressions

A new clippy lint for issue 93883 (https://github.com/rust-lang/rust/issues/93883). Relies on a new trait in `marker` (called `SignificantDrop` to enable linting), which is why this PR is for the rust-lang repo and not the clippy repo.

changelog: new lint [`significant_drop_in_scrutinee`]
2022-05-08 00:57:08 +00:00
Scott McMurray
83f785bff9 Further elaborate the lack of guarantees from Hasher 2022-05-07 17:44:30 -07:00
Matthias Krüger
416d600a9a
Rollup merge of #96671 - mgeisler:current-exe-docstring, r=Mark-Simulacrum
Remove hard links from `env::current_exe` security example

The security example shows that `env::current_exe` will return the path used when the program was started. This is not really surprising considering how hard links work: after `ln foo bar`, the two files are _equivalent_. It is _not_ the case that `bar` is a “link” to `foo`, nor is `foo` a link to `bar`. They are simply two names for the same underlying data.

The security vulnerability linked to seems to be different: there an attacker would start a SUID binary from a directory under the control of the attacker. The binary would respawn itself by executing the program found at `/proc/self/exe` (which the attacker can control). This is a real problem. In my opinion, the example given here doesn’t really show the same problem, it just shows a misunderstanding of what hard links are.

I looked through the history a bit and found that the example was introduced in https://github.com/rust-lang/rust/pull/33526. That PR actually has two commits, and the first (8478d48dad) explains the race condition at the root of the linked security vulnerability. The second commit proceeds to replace the explanation with the example we have today.

This commit reverts most of the second commit from https://github.com/rust-lang/rust/pull/33526.
2022-05-07 22:44:39 +02:00
Matthias Krüger
eecc0469f5
Rollup merge of #96586 - ear7h:master, r=joshtriplett
Add aliases for std::fs::canonicalize

The aliases are `realpath` and `GetFinalPathNameByHandle` which are explicitly mentioned in `canonicalize`'s documentation.
2022-05-07 22:44:37 +02:00
Matthias Krüger
1386a02dc1
Rollup merge of #96336 - Nilstrieb:link-to-correct-as_mut-in-ptr-as_ref, r=JohnTitor
Link to correct `as_mut` in docs for `pointer::as_ref`

It previously linked to the unstable const-mut-cast method instead of
the `mut` counterpart for `as_ref`.

Closes #96327
2022-05-07 22:44:36 +02:00
bors
24a0eecf03 Auto merge of #96657 - cuviper:time64, r=joshtriplett
Use 64-bit time on 32-bit linux-gnu

The standard library suffered the [Year 2038 problem][Y2038] in two main places on targets with 32-bit `time_t`:

- In `std::time::SystemTime`, we stored a `timespec` that has `time_t` seconds. This is now changed to directly store 64-bit seconds and nanoseconds, and on 32-bit linux-gnu we try to use `__clock_gettime64` (glibc 2.34+) to get the larger timestamp.

- In `std::fs::Metadata`, we store a `stat64`, which has 64-bit `off_t` but still 32-bit `time_t`, and unfortunately that is baked in the API by the (deprecated) `MetadataExt::as_raw_stat()`. However, we can use `statx` for 64-bit `statx_timestamp` to store in addition to the `stat64`, as we already do to support creation time, and the rest of the `MetadataExt` methods can return those full values. Note that some filesystems may still be limited in their actual timestamp support, but that's not something Rust can change.

There remain a few places that need `timespec` for system call timeouts -- I leave that to future work.

[Y2038]: https://en.wikipedia.org/wiki/Year_2038_problem
2022-05-07 17:53:59 +00:00
Nikolaos Chatzikonstantinou
7c1d241f2b
Fix a minor typo in the description of Formatter 2022-05-07 19:32:54 +09:00
gimbles
3b5fe261fe [fix] remove pub(crate) visibility 2022-05-07 09:22:30 +05:30
Michael Goulet
102bbc9ad3
Rollup merge of #96701 - kraktus:alloc_example_2018_edition, r=Mark-Simulacrum
update `jemallocator` example to use 2018 edition import syntax
2022-05-06 20:49:31 -07:00
Preston From
bbb1c5b259 Mark locks in std lib with clippy::has_significant_drop 2022-05-06 21:48:17 -06:00
Josh Stone
f9675185a3 Share more unix SystemTime code 2022-05-06 11:45:59 -07:00
gimbles
0a80bb43e5 [feat] Make sys::windows::os_str::Slice repr(transparent) 2022-05-06 22:51:13 +05:30
Josh Stone
fec4818fdb Use statx's 64-bit times on 32-bit linux-gnu 2022-05-06 08:50:53 -07:00
Josh Stone
97b49a0cc5 Use __clock_gettime64 on 32-bit linux-gnu 2022-05-06 08:50:53 -07:00
Josh Stone
bee923f0df unix: always use 64-bit Timespec 2022-05-06 08:50:51 -07:00
bors
e209e85e39 Auto merge of #95183 - ibraheemdev:arc-count-acquire, r=Amanieu
Weaken needlessly restrictive orderings on `Arc::*_count`

There is no apparent reason for these to be `SeqCst`. For reference, [the Boost C++ implementation relies on acquire semantics](f2cc84a23c/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp (L137-L140)).
2022-05-06 14:53:24 +00:00
bors
8c4fc9d9a4 Auto merge of #94598 - scottmcm:prefix-free-hasher-methods, r=Amanieu
Add a dedicated length-prefixing method to `Hasher`

This accomplishes two main goals:
- Make it clear who is responsible for prefix-freedom, including how they should do it
- Make it feasible for a `Hasher` that *doesn't* care about Hash-DoS resistance to get better performance by not hashing lengths

This does not change rustc-hash, since that's in an external crate, but that could potentially use it in future.

Fixes #94026

r? rust-lang/libs

---

The core of this change is the following two new methods on `Hasher`:

```rust
pub trait Hasher {
    /// Writes a length prefix into this hasher, as part of being prefix-free.
    ///
    /// If you're implementing [`Hash`] for a custom collection, call this before
    /// writing its contents to this `Hasher`.  That way
    /// `(collection![1, 2, 3], collection![4, 5])` and
    /// `(collection![1, 2], collection![3, 4, 5])` will provide different
    /// sequences of values to the `Hasher`
    ///
    /// The `impl<T> Hash for [T]` includes a call to this method, so if you're
    /// hashing a slice (or array or vector) via its `Hash::hash` method,
    /// you should **not** call this yourself.
    ///
    /// This method is only for providing domain separation.  If you want to
    /// hash a `usize` that represents part of the *data*, then it's important
    /// that you pass it to [`Hasher::write_usize`] instead of to this method.
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(hasher_prefixfree_extras)]
    /// # // Stubs to make the `impl` below pass the compiler
    /// # struct MyCollection<T>(Option<T>);
    /// # impl<T> MyCollection<T> {
    /// #     fn len(&self) -> usize { todo!() }
    /// # }
    /// # impl<'a, T> IntoIterator for &'a MyCollection<T> {
    /// #     type Item = T;
    /// #     type IntoIter = std::iter::Empty<T>;
    /// #     fn into_iter(self) -> Self::IntoIter { todo!() }
    /// # }
    ///
    /// use std:#️⃣:{Hash, Hasher};
    /// impl<T: Hash> Hash for MyCollection<T> {
    ///     fn hash<H: Hasher>(&self, state: &mut H) {
    ///         state.write_length_prefix(self.len());
    ///         for elt in self {
    ///             elt.hash(state);
    ///         }
    ///     }
    /// }
    /// ```
    ///
    /// # Note to Implementers
    ///
    /// If you've decided that your `Hasher` is willing to be susceptible to
    /// Hash-DoS attacks, then you might consider skipping hashing some or all
    /// of the `len` provided in the name of increased performance.
    #[inline]
    #[unstable(feature = "hasher_prefixfree_extras", issue = "88888888")]
    fn write_length_prefix(&mut self, len: usize) {
        self.write_usize(len);
    }

    /// Writes a single `str` into this hasher.
    ///
    /// If you're implementing [`Hash`], you generally do not need to call this,
    /// as the `impl Hash for str` does, so you can just use that.
    ///
    /// This includes the domain separator for prefix-freedom, so you should
    /// **not** call `Self::write_length_prefix` before calling this.
    ///
    /// # Note to Implementers
    ///
    /// The default implementation of this method includes a call to
    /// [`Self::write_length_prefix`], so if your implementation of `Hasher`
    /// doesn't care about prefix-freedom and you've thus overridden
    /// that method to do nothing, there's no need to override this one.
    ///
    /// This method is available to be overridden separately from the others
    /// as `str` being UTF-8 means that it never contains `0xFF` bytes, which
    /// can be used to provide prefix-freedom cheaper than hashing a length.
    ///
    /// For example, if your `Hasher` works byte-by-byte (perhaps by accumulating
    /// them into a buffer), then you can hash the bytes of the `str` followed
    /// by a single `0xFF` byte.
    ///
    /// If your `Hasher` works in chunks, you can also do this by being careful
    /// about how you pad partial chunks.  If the chunks are padded with `0x00`
    /// bytes then just hashing an extra `0xFF` byte doesn't necessarily
    /// provide prefix-freedom, as `"ab"` and `"ab\u{0}"` would likely hash
    /// the same sequence of chunks.  But if you pad with `0xFF` bytes instead,
    /// ensuring at least one padding byte, then it can often provide
    /// prefix-freedom cheaper than hashing the length would.
    #[inline]
    #[unstable(feature = "hasher_prefixfree_extras", issue = "88888888")]
    fn write_str(&mut self, s: &str) {
        self.write_length_prefix(s.len());
        self.write(s.as_bytes());
    }
}
```

With updates to the `Hash` implementations for slices and containers to call `write_length_prefix` instead of `write_usize`.

`write_str` defaults to using `write_length_prefix` since, as was pointed out in the issue, the `write_u8(0xFF)` approach is insufficient for hashers that work in chunks, as those would hash `"a\u{0}"` and `"a"` to the same thing.  But since `SipHash` works byte-wise (there's an internal buffer to accumulate bytes until a full chunk is available) it overrides `write_str` to continue to use the add-non-UTF-8-byte approach.

---

Compatibility:

Because the default implementation of `write_length_prefix` calls `write_usize`, the changed hash implementation for slices will do the same thing the old one did on existing `Hasher`s.
2022-05-06 09:43:57 +00:00
bors
7f9e013ba6 Auto merge of #96510 - m-ou-se:futex-bsd, r=Amanieu
Use futex-based locks and thread parker on {Free, Open, DragonFly}BSD.

This switches *BSD to our futex-based locks and thread parker.

Tracking issue: https://github.com/rust-lang/rust/issues/93740

This is a draft, because this still needs a new version of the `libc` crate to be published that includes https://github.com/rust-lang/libc/pull/2770.

r? `@Amanieu`
2022-05-06 07:20:04 +00:00
Scott McMurray
ebdcb08abf For now, don't change the details of hashing a str
We might want to change the default before stabilizing (or maybe even after), but for getting in the new unstable methods, leave it as-is for now.  That way it won't break cargo and such.
2022-05-06 00:14:44 -07:00
Scott McMurray
98054377ee Add a dedicated length-prefixing method to Hasher
This accomplishes two main goals:
- Make it clear who is responsible for prefix-freedom, including how they should do it
- Make it feasible for a `Hasher` that *doesn't* care about Hash-DoS resistance to get better performance by not hashing lengths

This does not change rustc-hash, since that's in an external crate, but that could potentially use it in future.
2022-05-06 00:03:38 -07:00
Michael Goulet
8bcf4b0efc
Rollup merge of #96744 - est31:join_osstr, r=thomcc
Implement [OsStr]::join

Implements join for `OsStr` and `OsString` slices:

```Rust
    let strings = [OsStr::new("hello"), OsStr::new("dear"), OsStr::new("world")];
    assert_eq!("hello dear world", strings.join(OsStr::new(" ")));
````

This saves one from converting to strings and back, or from implementing it manually.
2022-05-05 19:34:26 -07:00