Commit Graph

10845 Commits

Author SHA1 Message Date
bors
516a6d3202 Auto merge of #109769 - JohnTitor:rollup-7n2bnpg, r=JohnTitor
Rollup of 7 pull requests

Successful merges:

 - #106985 (Enhanced doucmentation of binary search methods for `slice` and `VecDeque` for unsorted instances)
 - #109509 (compiletest: Don't allow tests with overlapping prefix names)
 - #109719 (RELEASES: Add "Only support Android NDK 25 or newer" to 1.68.0)
 - #109748 (Don't ICE on `DiscriminantKind` projection in new solver)
 - #109749 (Canonicalize float var as float in new solver)
 - #109761 (Drop binutils on powerpc-unknown-freebsd)
 - #109766 (Fix title for openharmony.md)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
2023-03-30 12:44:25 +00:00
Yuki Okushi
d6f27401f1
Rollup merge of #106985 - jofas:106746-fix, r=ChrisDenton
Enhanced doucmentation of binary search methods for `slice` and `VecDeque` for unsorted instances

Fixes #106746. Issue #106746 raises the concern that the binary search methods for slices and deques aren't explicit enough about the fact that they are only applicable to sorted slices/deques. I changed the explanation for these methods. I took the relatively harsh description of the behaviour of binary search on unsorted collections ("unspecified and meaningless") from the description of the [`partition_point`](https://doc.rust-lang.org/std/primitive.slice.html#method.partition_point) method:

> If this slice is not partitioned, the returned result is unspecified and meaningless, as this method performs a kind of binary search.
2023-03-30 21:06:59 +09:00
bors
8a7ca936e6 Auto merge of #105587 - tgross35:once-cell-min, r=m-ou-se
Partial stabilization of `once_cell`

This PR aims to stabilize a portion of the `once_cell` feature:

- `core::cell::OnceCell`
- `std::cell::OnceCell` (re-export of the above)
- `std::sync::OnceLock`

This will leave `LazyCell` and `LazyLock` unstabilized, which have been moved to the `lazy_cell` feature flag.

Tracking issue: https://github.com/rust-lang/rust/issues/74465 (does not fully close, but it may make sense to move to a new issue)

Future steps for separate PRs:
- ~~Add `#[inline]` to many methods~~ #105651
- Update cranelift usage of the `once_cell` crate
- Update rust-analyzer usage of the `once_cell` crate
- Update error messages discussing once_cell

## To be stabilized API summary

```rust
// core::cell (in core/cell/once.rs)

pub struct OnceCell<T> { .. }

impl<T> OnceCell<T> {
    pub const fn new() -> OnceCell<T>;
    pub fn get(&self) -> Option<&T>;
    pub fn get_mut(&mut self) -> Option<&mut T>;
    pub fn set(&self, value: T) -> Result<(), T>;
    pub fn get_or_init<F>(&self, f: F) -> &T where F: FnOnce() -> T;
    pub fn into_inner(self) -> Option<T>;
    pub fn take(&mut self) -> Option<T>;
}

impl<T: Clone> Clone for OnceCell<T>;
impl<T: Debug> Debug for OnceCell<T>
impl<T> Default for OnceCell<T>;
impl<T> From<T> for OnceCell<T>;
impl<T: PartialEq> PartialEq for OnceCell<T>;
impl<T: Eq> Eq for OnceCell<T>;
```

```rust
// std::sync (in std/sync/once_lock.rs)

impl<T> OnceLock<T> {
    pub const fn new() -> OnceLock<T>;
    pub fn get(&self) -> Option<&T>;
    pub fn get_mut(&mut self) -> Option<&mut T>;
    pub fn set(&self, value: T) -> Result<(), T>;
    pub fn get_or_init<F>(&self, f: F) -> &T where F: FnOnce() -> T;
    pub fn into_inner(self) -> Option<T>;
    pub fn take(&mut self) -> Option<T>;
}

impl<T: Clone> Clone for OnceLock<T>;
impl<T: Debug> Debug for OnceLock<T>;
impl<T> Default for OnceLock<T>;
impl<#[may_dangle] T> Drop for OnceLock<T>;
impl<T> From<T> for OnceLock<T>;
impl<T: PartialEq> PartialEq for OnceLock<T>
impl<T: Eq> Eq for OnceLock<T>;
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceLock<T>;
unsafe impl<T: Send> Send for OnceLock<T>;
unsafe impl<T: Sync + Send> Sync for OnceLock<T>;
impl<T: UnwindSafe> UnwindSafe for OnceLock<T>;
```

No longer planned as part of this PR, and moved to the `rust_cell_try` feature gate:

```rust
impl<T> OnceCell<T> {
    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result<T, E>;
}

impl<T> OnceLock<T> {
    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result<T, E>;
}
```

I am new to this process so would appreciate mentorship wherever needed.
2023-03-30 10:12:23 +00:00
jofas
b085007313 removed deprecated markdown links from documentation 2023-03-30 10:20:57 +02:00
bors
10338571cf Auto merge of #107221 - kleisauke:getentropy-emscripten, r=ChrisDenton
Use `getentropy()` instead of `/dev/urandom` on Emscripten

`/dev/urandom` is usually available on Emscripten, except when using
the special `NODERAWFS` filesystem backend, which replaces all normal
filesystem access with direct Node.js operations.

Since this filesystem backend directly access the filesystem on the
OS, it is not recommended to depend on `/dev/urandom`, especially
when trying to run the Wasm binary on OSes that are not Unix-based.

This can be considered a non-functional change, since Emscripten
implements `/dev/urandom` in the same way as `getentropy()` when not
linking with `-sNODERAWFS`.
2023-03-30 00:25:41 +00:00
Mara Bos
9b5122976e Em dashes are cooler than hyphens. 2023-03-29 18:04:44 -04:00
Trevor Gross
d1b28b75d2 Documentation updates to better share the purpose of OnceCell/OnceLock 2023-03-29 18:04:44 -04:00
Trevor Gross
dc4ba57566 Stabilize a portion of 'once_cell'
Move items not part of this stabilization to 'lazy_cell' or 'once_cell_try'
2023-03-29 18:04:44 -04:00
Matthias Krüger
c62bb46fb3
Rollup merge of #109693 - workingjubilee:maybe-unconstify-alloc, r=fee1-dead
Remove ~const from alloc

There is currently an effort underway to stop using `~const Trait`, temporarily, so as to refactor the logic underlying const traits with relative ease. This means it has to go from the standard library, as well.

I have taken the initial step of just removing these impls from alloc, as removing them from core is a much more tangled task. In addition, all of these implementations are one more-or-less logically-connected group, so reverting their deconstification as a group seems like it will also be sensible.

r? `@fee1-dead`
2023-03-29 21:19:50 +02:00
Matthias Krüger
57f1d114cd
Rollup merge of #107387 - joboet:hermit_random, r=ChrisDenton
Use random `HashMap` keys on Hermit

Initializing the keys with random data provided by the libOS avoids HashDOS attacks and similar issues.

CC `@stlankes`
2023-03-29 21:19:47 +02:00
bors
f98598c6cd Auto merge of #108089 - Zoxc:windows-tls, r=bjorn3
Support TLS access into dylibs on Windows

This allows access to `#[thread_local]`  in upstream dylibs on Windows by introducing a MIR shim to return the address of the thread local. Accesses that go into an upstream dylib will call the MIR shim to get the address of it.

`convert_tls_rvalues` is introduced in `rustc_codegen_ssa` which rewrites MIR TLS accesses to dummy calls which are replaced with calls to the MIR shims when the dummy calls are lowered to backend calls.

A new `dll_tls_export` target option enables this behavior with a `false` value which is set for Windows platforms.

This fixes https://github.com/rust-lang/rust/issues/84933.
2023-03-29 16:20:37 +00:00
jofas
37ed3cebbc enhanced documentation of binary search methods for slice and VecDeque for unsorted instances 2023-03-29 11:14:23 +02:00
joboet
f6bde0352b
std: use cvt to handle errors from read_entropy on Hermit 2023-03-29 10:52:48 +02:00
bors
f346fb0bc6 Auto merge of #108792 - Amanieu:ohos, r=petrochenkov
Add OpenHarmony targets

- `aarch64-unknown-linux-ohos`
- `armv7-unknown-linux-ohos`

Compiler team MCP: https://github.com/rust-lang/compiler-team/issues/568
2023-03-29 07:16:16 +00:00
John Kåre Alsaker
3019a341f3 Use #[inline] on Windows for thread local access 2023-03-29 08:55:25 +02:00
bors
cdbbce0a9e Auto merge of #108095 - soc:drop-contains, r=Amanieu
Drop unstable `Option::contains`, `Result::contains`, `Result::contains_err`

This is a proposal to drop the three functions `Option::contains`, `Result::contains` and `Result::contains_err`.

The discovery of `Option::is_some_with`/`Result::is_ok_with`/`Result::is_err_with` in https://github.com/rust-lang/rust/pull/93051 obviates the need for these methods (non-stabilization tracked in https://github.com/rust-lang/rust/issues/62358).

An additional benefit of change is that it avoids spurious error messages in IDEs, when `contains` is supplied by a third-party library:
![option-result-unstable](https://user-images.githubusercontent.com/42493/219127961-13cb559e-6ee8-4449-8dc9-d28d07270ad5.png)
2023-03-28 23:20:30 +00:00
Jubilee Young
e34ad76363 Remove ~const from alloc 2023-03-28 10:37:16 -07:00
bors
478cbb42b7 Auto merge of #109692 - Nilstrieb:rollup-hq65rps, r=Nilstrieb
Rollup of 8 pull requests

Successful merges:

 - #91793 (socket ancillary data implementation for FreeBSD (from 13 and above).)
 - #92284 (Change advance(_back)_by to return the remainder instead of the number of processed elements)
 - #102472 (stop special-casing `'static` in evaluation)
 - #108480 (Use Rayon's TLV directly)
 - #109321 (Erase impl regions when checking for impossible to eagerly monomorphize items)
 - #109470 (Correctly substitute GAT's type used in `normalize_param_env` in `check_type_bounds`)
 - #109562 (Update ar_archive_writer to 0.1.3)
 - #109629 (remove obsolete `givens` from regionck)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
2023-03-28 15:18:16 +00:00
Amanieu d'Antras
e3968be331 Add OpenHarmony targets
- `aarch64-unknown-linux-ohos`
- `armv7-unknown-linux-ohos`
2023-03-28 16:01:13 +01:00
bors
bf57e8ada6 Auto merge of #108080 - oli-obk:FnPtr-trait, r=lcnr
Add a builtin `FnPtr` trait that is implemented for all function pointers

r? `@ghost`

Rebased version of https://github.com/rust-lang/rust/pull/99531 (plus adjustments mentioned in the PR).

If perf is happy with this version, I would like to land it, even if the diagnostics fix in 9df8e1befb5031a5bf9d8dfe25170620642d3c59 only works for `FnPtr` specifically, and does not generally improve blanket impls.
2023-03-28 12:50:01 +00:00
nils
0883848882
Rollup merge of #92284 - the8472:simplify-advance-by, r=scottmcm
Change advance(_back)_by to return the remainder instead of the number of processed elements

When advance_by can't advance the iterator by the number of requested elements it now returns the amount by which it couldn't be advanced instead of the amount by which it did.

This simplifies adapters like chain, flatten or cycle because the remainder doesn't have to be calculated as the difference between requested steps and completed steps anymore.

Additionally switching from `Result<(), usize>` to `Result<(), NonZeroUsize>` reduces the size of the result and makes converting from/to a usize representing the number of remaining steps cheap.
2023-03-28 12:51:11 +02:00
nils
857b631616
Rollup merge of #91793 - devnexen:anc_data_fbsd, r=ChrisDenton
socket ancillary data implementation for FreeBSD (from 13 and above).

introducing new build config as well.
2023-03-28 12:51:10 +02:00
Matthias Krüger
a69496002c
Rollup merge of #109687 - joshtriplett:document-windows-isterminal-heuristics, r=BurntSushi
Document the heuristics IsTerminal uses on Windows

Suggested by `@BurntSushi.`
2023-03-28 07:01:12 +02:00
Matthias Krüger
90b6c715df
Rollup merge of #109682 - clubby789:c-str-inline, r=scottmcm
Add `#[inline]` to CStr trait implementations

Fixes #109674

I noticed other usages of traits on `CStr` weren't being inlined, so also added hints to the other implementations
2023-03-28 07:01:11 +02:00
Josh Triplett
b38732f25c Add "Platform-specific behavior" heading and link to changes disclaimer 2023-03-28 11:26:43 +09:00
Josh Triplett
1354a38afd Document the heuristics IsTerminal uses on Windows 2023-03-28 10:49:35 +09:00
clubby789
901f10899c Add #[inline] to CStr trait implementations 2023-03-28 01:09:31 +01:00
David CARLIER
ed5c0f66ac socket ancillary data implementation for FreeBSD (from 13 and above).
introducing new build config as well.
2023-03-27 16:48:41 +01:00
clubby789
3e16c56ffc
Fix ASCII case comment 2023-03-27 16:06:54 +01:00
The 8472
41807938d2 fix advance_by impl for vec_deque and add tests 2023-03-27 16:03:30 +02:00
The 8472
9cd9da2cd1 update documentation 2023-03-27 16:03:30 +02:00
The 8472
e29b27b4a4 replace advance_by returning usize with Result<(), NonZeroUsize> 2023-03-27 16:03:14 +02:00
Oli Scherer
5ae6caa0f0 Use the FnPtr trait to avoid implementing common traits via macros 2023-03-27 12:19:52 +00:00
lcnr
0c13565ca6 Add a builtin FnPtr trait 2023-03-27 12:16:54 +00:00
The 8472
69db91b8b2 Change advance(_back)_by to return usize instead of Result<(), usize>
A successful advance is now signalled by returning `0` and other values now represent the remaining number
of steps that couldn't be advanced as opposed to the amount of steps that have been advanced during a partial advance_by.

This simplifies adapters a bit, replacing some `match`/`if` with arithmetic. Whether this is beneficial overall depends
on whether `advance_by` is mostly used as a building-block for other iterator methods and adapters or whether
we also see uses by users where `Result` might be more useful.
2023-03-27 14:11:49 +02:00
Matthias Krüger
704991c959
Rollup merge of #102742 - bjorn3:cleanup_rust_start_panic, r=ChrisDenton
Remove unnecessary raw pointer in __rust_start_panic arg

It is no longer necessary as __rust_start_panic switched to the Rust abi.
2023-03-27 08:46:52 +02:00
Matthias Krüger
fe0b0428b8
Rollup merge of #98651 - mattfbacon:master, r=ChrisDenton
Follow C-RW-VALUE in std::io::Cursor example

rustc-dev-guide says to do this:

r? ``@steveklabnik``
2023-03-27 08:46:51 +02:00
Matthias Krüger
102bbbd940
Rollup merge of #97506 - JohnTitor:stabilize-nonnull-slice-from-raw-parts, r=m-ou-se,the8472
Stabilize `nonnull_slice_from_raw_parts`

FCP is done: https://github.com/rust-lang/rust/issues/71941#issuecomment-1100910416
Note that this doesn't const-stabilize `NonNull::slice_from_raw_parts` as `slice_from_raw_parts_mut` isn't const-stabilized yet. Given #67456 and #57349, it's not likely available soon, meanwhile, stabilizing only the feature makes some sense, I think.

Closes #71941
2023-03-27 08:46:50 +02:00
bors
db0cbc48d4 Auto merge of #109357 - saethlin:inline-as-deref, r=thomcc
Add #[inline] to as_deref

While working on https://github.com/rust-lang/rust/pull/109247 I found an `as_deref` call in the compiler that should have been inlined. This fixes the missing inlining (but doesn't address the perf issues I was chasing).

r? `@thomcc`
2023-03-26 18:32:17 +00:00
bjorn3
b874502a20 Remove unnecessary raw pointer in __rust_start_panic arg
It is no longer necessary as __rust_start_panic switched to the Rust abi.
2023-03-26 16:40:18 +00:00
Matthias Krüger
776a8f4eca
Rollup merge of #109620 - eievui5:patch-1, r=compiler-errors
Correct typo (`back_box` -> `black_box`)
2023-03-26 08:39:28 +02:00
bors
48ae1b335f Auto merge of #105096 - LegionMammal978:copied-allocators, r=Amanieu
Clarify that copied allocators must behave the same

Currently, the safety documentation for `Allocator` says that a cloned or moved allocator must behave the same as the original. However, it does not specify that a copied allocator must behave the same, and it's possible to construct an allocator that permits being moved or cloned, but sometimes produces a new allocator when copied.

<details>
<summary>Contrived example which results in a Miri error</summary>

```rust
#![feature(allocator_api, once_cell, strict_provenance)]
use std::{
    alloc::{AllocError, Allocator, Global, Layout},
    collections::HashMap,
    hint,
    marker::PhantomPinned,
    num::NonZeroUsize,
    pin::Pin,
    ptr::{addr_of, NonNull},
    sync::{LazyLock, Mutex},
};

mod source_allocator {
    use super::*;

    // `SourceAllocator` has 3 states:
    // - invalid value: is_cloned == false, source != self.addr()
    // - source value:  is_cloned == false, source == self.addr()
    // - cloned value:  is_cloned == true
    pub struct SourceAllocator {
        is_cloned: bool,
        source: usize,
        _pin: PhantomPinned,
    }

    impl SourceAllocator {
        // Returns a pinned source value (pointing to itself).
        pub fn new_source() -> Pin<Box<Self>> {
            let mut b = Box::new(Self {
                is_cloned: false,
                source: 0,
                _pin: PhantomPinned,
            });
            b.source = b.addr();
            Box::into_pin(b)
        }

        fn addr(&self) -> usize {
            addr_of!(*self).addr()
        }

        // Invalid values point to source 0.
        // Source values point to themselves.
        // Cloned values point to their corresponding source.
        fn source(&self) -> usize {
            if self.is_cloned || self.addr() == self.source {
                self.source
            } else {
                0
            }
        }
    }

    // Copying an invalid value produces an invalid value.
    // Copying a source value produces an invalid value.
    // Copying a cloned value produces a cloned value with the same source.
    impl Copy for SourceAllocator {}

    // Cloning an invalid value produces an invalid value.
    // Cloning a source value produces a cloned value with that source.
    // Cloning a cloned value produces a cloned value with the same source.
    impl Clone for SourceAllocator {
        fn clone(&self) -> Self {
            if self.is_cloned || self.addr() != self.source {
                *self
            } else {
                Self {
                    is_cloned: true,
                    source: self.source,
                    _pin: PhantomPinned,
                }
            }
        }
    }

    static SOURCE_MAP: LazyLock<Mutex<HashMap<NonZeroUsize, usize>>> =
        LazyLock::new(Default::default);

    // SAFETY: Wraps `Global`'s methods with additional tracking.
    // All invalid values share blocks with each other.
    // Each source value shares blocks with all cloned values pointing to it.
    // Cloning an allocator always produces a compatible allocator:
    // - Cloning an invalid value produces another invalid value.
    // - Cloning a source value produces a cloned value pointing to it.
    // - Cloning a cloned value produces another cloned value with the same source.
    // Moving an allocator always produces a compatible allocator:
    // - Invalid values remain invalid when moved.
    // - Source values cannot be moved, since they are always pinned to the heap.
    // - Cloned values keep the same source when moved.
    unsafe impl Allocator for SourceAllocator {
        fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
            let mut map = SOURCE_MAP.lock().unwrap();
            let block = Global.allocate(layout)?;
            let block_addr = block.cast::<u8>().addr();
            map.insert(block_addr, self.source());
            Ok(block)
        }

        unsafe fn deallocate(&self, block: NonNull<u8>, layout: Layout) {
            let mut map = SOURCE_MAP.lock().unwrap();
            let block_addr = block.addr();
            // SAFETY: `block` came from an allocator that shares blocks with this allocator.
            if map.remove(&block_addr) != Some(self.source()) {
                hint::unreachable_unchecked()
            }
            Global.deallocate(block, layout)
        }
    }
}
use source_allocator::SourceAllocator;

// SAFETY: `alloc1` and `alloc2` must share blocks.
unsafe fn test_same(alloc1: &SourceAllocator, alloc2: &SourceAllocator) {
    let ptr = alloc1.allocate(Layout:🆕:<i32>()).unwrap();
    alloc2.deallocate(ptr.cast(), Layout:🆕:<i32>());
}

fn main() {
    let orig = &*SourceAllocator::new_source();
    let orig_cloned1 = &orig.clone();
    let orig_cloned2 = &orig.clone();
    let copied = &{ *orig };
    let copied_cloned1 = &copied.clone();
    let copied_cloned2 = &copied.clone();
    unsafe {
        test_same(orig, orig_cloned1);
        test_same(orig_cloned1, orig_cloned2);
        test_same(copied, copied_cloned1);
        test_same(copied_cloned1, copied_cloned2);
        test_same(orig, copied); // error
    }
}
```
</details>

This could result in issues in the future for algorithms that specialize on `Copy` types. Right now, nothing in the standard library that depends on `Allocator + Clone` is susceptible to this issue, but I still think it would make sense to specify that copying an allocator is always as valid as cloning it.
2023-03-26 01:21:12 +00:00
Evie M
323551abb1
Correct typo (back_box -> black_box) 2023-03-25 19:57:46 -04:00
bors
9fa6b3c157 Auto merge of #99929 - the8472:default-iters, r=scottmcm
Implement Default for some alloc/core iterators

Add `Default` impls to the following collection iterators:

* slice::{Iter, IterMut}
* binary_heap::IntoIter
* btree::map::{Iter, IterMut, Keys, Values, Range, IntoIter, IntoKeys, IntoValues}
* btree::set::{Iter, IntoIter, Range}
* linked_list::IntoIter
* vec::IntoIter

and these adapters:

* adapters::{Chain, Cloned, Copied, Rev, Enumerate, Flatten, Fuse, Rev}

For iterators which are generic over allocators it only implements it for the global allocator because we can't conjure an allocator from nothing or would have to turn the allocator field into an `Option` just for this change.

These changes will be insta-stable.

ACP: https://github.com/rust-lang/libs-team/issues/77
2023-03-25 06:29:46 +00:00
bors
24a69af213 Auto merge of #109546 - saethlin:inline-into, r=scottmcm
Add #[inline] to the Into for From impl

I was skimming through the standard library MIR and I noticed a handful of very suspicious `Into::into` calls in `alloc`. ~Since this is a trivial wrapper function, `#[inline(always)]` seems appropriate.;~ `#[inline]` works too and is a lot less spooky.

r? `@thomcc`
2023-03-25 03:09:09 +00:00
Ben Kimock
badfb17d2f Add #[inline] to the Into for From impl 2023-03-24 15:06:31 -04:00
bors
f421586eed Auto merge of #109216 - martingms:unicode-case-lut-shrink, r=Mark-Simulacrum
Shrink unicode case-mapping LUTs by 24k

I was looking into the binary bloat of a small program using `str::to_lowercase` and `str::to_uppercase`, and noticed that the lookup tables used for case mapping had a lot of zero-bytes in them. The reason for this is that since some characters map to up to three other characters when lower or uppercased, the LUTs store a `[char; 3]` for each character. However, the vast majority of cases only map to a single new character, in other words most of the entries are e.g. `(lowerc, [upperc, '\0', '\0'])`.
This PR introduces a new encoding scheme for these tables.

The changes reduces the size of my test binary by about 24K.

I've also done some `#[bench]`marks on unicode-heavy test data, and found that the performance of both `str::to_lowercase` and `str::to_uppercase` improves by up to 20%. These measurements are obviously very dependent on the character distribution of the data.

Someone else will have to decide whether this more complex scheme is worth it or not, I was just goofing around a bit and here's what came out of it 🤷‍♂️ No hard feelings if this isn't wanted!
2023-03-24 10:33:42 +00:00
Matthias Krüger
936377a0aa
Rollup merge of #109406 - WaffleLapkin:🥛, r=cuviper
Remove outdated comments

What the title said
2023-03-24 07:13:04 +01:00
Matthias Krüger
cca2630bc9
Rollup merge of #109368 - hermitcore:typo, r=cuviper
fix typo in the creation of OpenOption for RustyHermit

Due to this typo we have to build a workaround for issue hermitcore/libhermit-rs#191.

RustyHermit is a tier 3 platform and backward compatibility does not have to be guaranteed.
2023-03-24 01:22:06 +01:00
Matthias Krüger
605a4fc7ab
Rollup merge of #109142 - the8472:mutex-block-docs, r=cuviper
Add block-based mutex unlocking example

This modifies the existing example in the Mutex docs to show both `drop()` and block based early unlocking.

Alternative to #81872, which is getting closed.
2023-03-24 01:22:05 +01:00