Since android ndk version `r23-beta3`, `libgcc` has been replaced with
`libunwind`. This moves the linking of `libgcc`/`libunwind` into the
`unwind` crate where we check if the system compiler can find
`libunwind` and fall back to `libgcc` if needed.
Mention "null pointer optimization" in option docs.
I had seen people discuss "null pointer optimization," but when I tried to find official documentation (using Google), the `std::option` page didn't show up, because it doesn't use that term. Hopefully adding the term will help others find it in the future.
- Split `sys_common::RWLock` between `StaticRWLock` and `MovableRWLock`
- Unbox `RwLock` on some platforms (Windows, Wasm and unsupported)
- Simplify `RwLock::into_inner`
Remove `Ipv6Addr::is_unicast_link_local_strict`
Removes the unstable method `Ipv6Addr::is_unicast_link_local_strict` and keeps the behaviour of `Ipv6Addr::is_unicast_link_local`, see also #85604 where I have tried to summarize related discussion so far.
My intent is for `is_unicast_link_local`, `is_unicast_site_local` and `is_unicast_global` to have the semantics of checking if an address has Link-Local, Site-Local or Global scope, see also #85696 which changes the behaviour of `is_unicast_global` and renames these methods to `has_unicast_XXX_scope` to reflect this.
For checking Link-Local scope we currently have two methods: `is_unicast_link_local` and `is_unicast_link_local_strict`. This is because of what appears to be conflicting definitions in [IETF RFC 4291](https://datatracker.ietf.org/doc/html/rfc4291).
From [IETF RFC 4291 section 2.4](https://datatracker.ietf.org/doc/html/rfc4291#section-2.4): "Link-Local unicast" (`FE80::/10`)
```text
Address type Binary prefix IPv6 notation Section
------------ ------------- ------------- -------
Unspecified 00...0 (128 bits) ::/128 2.5.2
Loopback 00...1 (128 bits) ::1/128 2.5.3
Multicast 11111111 FF00::/8 2.7
Link-Local unicast 1111111010 FE80::/10 2.5.6
Global Unicast (everything else)
```
From [IETF RFC 4291 section 2.5.6](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.6): "Link-Local IPv6 Unicast Addresses" (`FE80::/64`)
```text
| 10 bits | 54 bits | 64 bits |
+----------+-------------------------+----------------------------+
|1111111010| 0 | interface ID |
+----------+-------------------------+----------------------------+
```
With `is_unicast_link_local` checking `FE80::/10` and `is_unicast_link_local_strict` checking `FE80::/64`.
There is also [IETF RFC 5156 section 2.4](https://datatracker.ietf.org/doc/html/rfc5156#section-2.4) which defines "Link-Scoped Unicast" as `FE80::/10`.
It has been pointed out that implementations in other languages and the linux kernel all use `FE80::/10` (https://github.com/rust-lang/rust/pull/76098#issuecomment-706916840, https://github.com/rust-lang/rust/pull/76098#issuecomment-705928605).
Given all of this I believe the correct interpretation to be the following: All addresses in `FE80::/10` are defined as having Link-Local scope, however currently only the block `FE80::/64` has been allocated for "Link-Local IPv6 Unicast Addresses". This might change in the future however; more addresses in `FE80::/10` could be allocated and those will have Link-Local scope. I therefore believe the current behaviour of `is_unicast_link_local` to be correct (if interpreting it to have the semantics of `has_unicast_link_local_scope`) and `is_unicast_link_local_strict` to be unnecessary, confusing and even a potential source of future bugs:
Currently there is no real difference in checking `FE80::/10` or `FE80::/64`, since any address in practice will be `FE80::/64`. However if an application uses `is_unicast_link_local_strict` to implement link-local (so non-global) behaviour, it will be incorrect in the future if addresses outside of `FE80::/64` are allocated.
r? `@joshtriplett` as reviewer of all the related PRs
Add `String::extend_from_within`
This PR adds `String::extend_from_within` function under the `string_extend_from_within` feature gate similar to the [`Vec::extend_from_within`] function.
```rust
// String
pub fn extend_from_within<R>(&mut self, src: R)
where
R: RangeBounds<usize>;
```
[`Vec::extend_from_within`]: https://github.com/rust-lang/rust/issues/81656
Revert "Auto merge of #83770 - the8472:tra-extend, r=Mark-Simulacrum"
Due to a performance regression that didn't show up in the original perf run
this reverts commit 9111b8ae97 (#83770), reversing
changes made to 9a700d2947.
Since since is expected to have the inverse impact it should probably be rollup=never.
r? `@Mark-Simulacrum`
Make `Step` trait safe to implement
This PR makes a few modifications to the `Step` trait that I believe better position it for stabilization in the short term. In particular,
1. `unsafe trait TrustedStep` is introduced, indicating that the implementation of `Step` for a given type upholds all stated invariants (which have remained unchanged). This is gated behind a new `trusted_step` feature, as stabilization is realistically blocked on min_specialization.
2. The `Step` trait is internally specialized on the `TrustedStep` trait, which avoids a serious performance regression.
3. `TrustedLen` is implemented for `T: TrustedStep` as the latter's invariants subsume the former's.
4. The `Step` trait is no longer `unsafe`, as the invariants must not be relied upon by unsafe code (unless the type implements `TrustedStep`).
5. `TrustedStep` is implemented for all types that implement `Step` in the standard library and compiler.
6. The `step_trait_ext` feature is merged into the `step_trait` feature. I was unable to find any reasoning for the features being split; the `_unchecked` methods need not necessarily be stabilized at the same time, but I think it is useful to have them under the same feature flag.
All existing implementations of `Step` will be broken, as it is not possible to `unsafe impl` a safe trait. Given this trait only exists on nightly, I feel this breakage is acceptable. The blanket `impl<T: Step> TrustedLen for T` will likely cause some minor breakage, but this should be covered by the equivalent impl for `TrustedStep`.
Hopefully these changes are sufficient to place `Step` in decent position for stabilization, which would allow user-defined types to be used with `a..b` syntax.
copy_from_slice generally falls back to memcpy/memmove, which is much more expensive
than we need to write a single element in.
This saves 0.26% instructions on the diesel benchmark.
To make way for a new IoSlice(Mut)::advance function that advances a
single slice.
Also changes the signature to accept a `&mut &mut [IoSlice]`, not
returning anything. This will better match the future IoSlice::advance
function.
This patch adds `String::extend_from_within` function under the
`string_extend_from_within` feature gate similar to the
`Vec::extend_from_within` function.
Add #[track_caller] to panic_any
Report the panic location from the user code.
```rust
use std::panic;
use std::panic::panic_any;
fn main() {
panic::set_hook(Box::new(|panic_info| {
if let Some(location) = panic_info.location() {
println!(
"panic occurred in file '{}' at line {}",
location.file(),
location.line(),
);
} else {
println!("panic occurred but can't get location information...");
}
}));
panic_any(42);
}
````
Before:
`panic occurred in file '/rustc/ff2c947c00f867b9f012e28ba88cecfbe556f904/library/std/src/panic.rs' at line 59`
After:
`panic occurred in file 'src/main.rs' at line 17`
In particular the `is_dir`, `is_file` and `exists` functions says that querying a file requires querying the directory. On Windows this is not normally true.
Mention workaround for floats in Iterator::{min, max}
`Iterator::{min, max}` can't be used with iterators of floats due to NaN issues. This suggests a workaround in the documentation of those functions.
Forwarding `clone_from` to the inner value changes the observable
behavior, as previously the inner value would *not* be dropped by the
default implementation.
Enable Vec's calloc optimization for Option<NonZero>
Someone on discord noticed that `vec![None::<NonZeroU32>; N]` wasn't getting the optimization, so here's a PR 🙃
We can certainly do this in the standard library because we know for sure this is ok, but I think it's also a necessary consequence of documented guarantees like those in https://doc.rust-lang.org/std/option/#representation and https://doc.rust-lang.org/core/num/struct.NonZeroU32.html
It feels weird to do this without adding a test, but I wasn't sure where that would belong. Is it worth adding codegen tests for these?