- 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.
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`
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.
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?
libunwind fix and cleanup
Fix:
1. "system-llvm-libunwind" now only skip build-script for linux target
2. workaround from https://github.com/rust-lang/rust/pull/65972 is not needed, upstream fix it in 68c50708d1 ( LLVM 11 )
3. remove code for MSCV and Apple in `compile()`, as they are not used
4. fix https://github.com/rust-lang/rust/issues/69222 , compile c files and cpp files in different config
5. fix conditional compilation for musl target.
6. fix that x86_64-fortanix-unknown-sgx don't link libunwind built in build-script into rlib
Add inline attr to CString::into_inner so it can optimize out NonNull checks
It seems that currently if you convert any of the standard library's container to a pointer and then to a NonNull pointer, all will optimize out the NULL check except `CString`(https://godbolt.org/z/YPKW9G5xn),
because for some reason `CString::into_inner` isn't inlined even though it's a private function that should compile into a simple `mov` instruction.
Adding a simple `#[inline]` attribute solves this, code example:
```rust
use std::ffi::CString;
use std::ptr::NonNull;
pub fn cstring_nonull(mut n: CString) -> NonNull<i8> {
NonNull::new(CString::into_raw(n)).unwrap()
}
```
assembly before:
```asm
__ZN3wat14cstring_nonull17h371c755bcad76294E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
callq __ZN3std3ffi5c_str7CString10into_inner17h28ece07b276e2878E
testq %rax, %rax
je LBB0_2
popq %rbp
retq
LBB0_2:
leaq l___unnamed_1(%rip), %rdi
leaq l___unnamed_2(%rip), %rdx
movl $43, %esi
callq __ZN4core9panicking5panic17h92a83fa9085a8f73E
.cfi_endproc
.section __TEXT,__const
l___unnamed_1:
.ascii "called `Option::unwrap()` on a `None` value"
l___unnamed_3:
.ascii "wat.rs"
.section __DATA,__const
.p2align 3
l___unnamed_2:
.quad l___unnamed_3
.asciz "\006\000\000\000\000\000\000\000\006\000\000\000(\000\000"
```
Assembly after:
```asm
__ZN3wat14cstring_nonull17h9645eb9341fb25d7E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movq %rdi, %rax
popq %rbp
retq
.cfi_endproc
```
(Related discussion on zulip: https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/NonNull.20From.3CBox.3CT.3E.3E)
Remove Iterator #[rustc_on_unimplemented]s that no longer apply.
Now that `IntoIterator` is implemented for arrays, all the `rustc_on_unimplemented` for arrays of ranges (e.g. `for _ in [1..3] {}`) no longer apply, since they are now valid Rust.
Separated these from #85670, because we should discuss a potential new (clippy?) lint for these.
Until Rust 1.52, `for _ in [1..3] {}` produced:
```
error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator
--> src/main.rs:2:14
|
2 | for _ in [1..3] {}
| ^^^^^^ if you meant to iterate between two values, remove the square brackets
|
= help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]`
= note: `[start..end]` is an array of one `Range`; you might have meant to have a `Range` without the brackets: `start..end`
= note: required by `std::iter::IntoIterator::into_iter`
```
But in Rust 1.53 and later, it compiles fine. It iterates over the array by value, for one iteration with the element `1..3`.
This is probably a mistake, which is no longer caught. Should we have a lint for it? Should Clippy have a lint for it?
cc ```@estebank``` ```@flip1995```
cc https://github.com/rust-lang/rust/issues/84513
Update cc
Recent commits have improved `cc`'s finding of MSVC tools on Windows. In particular it should help to address these issues: #83043 and #43468
While stdlib implementations of the unchecked methods require unchecked
math, there is no reason to gate it behind this for external users. The
reasoning for a separate `step_trait_ext` feature is unclear, and as
such has been merged as well.
Add `TrustedRandomAccess` specialization for `Vec::extend()`
This should do roughly the same as the `TrustedLen` specialization but result in less IR by using `__iterator_get_unchecked`
instead of `Iterator::for_each`
Conflicting specializations are manually prioritized by grouping them under yet another helper trait.
Fix typo in core::array::IntoIter comment
Saw a small typo reading some internal comments and decided to just throw this up to fix it for future readers.
Remove num_as_ne_bytes feature
From the discussion in #76976, it is determined that eventual results of the safe transmute work as a more general mechanism will let these conversions happen in safe code without needing specialized methods.
Merging this PR closes#76976 and resolves#64464. Several T-libs members have raised their opinion that it doesn't pull its weight as a standalone method, and so we should not track it as a specific thing to add.
fix `matches!` and `assert_matches!` on edition 2021
Previously this code failed to compile on edition 2021. [(Playground)](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=53960f2f051f641777b9e458da747707)
```rust
fn main() {
matches!((), ());
}
```
```
Compiling playground v0.0.1 (/playground)
error: `$pattern:pat` may be followed by `|`, which is not allowed for `pat` fragments
|
= note: allowed there are: `=>`, `,`, `=`, `if` or `in`
error: aborting due to previous error
error: could not compile `playground`
To learn more, run the command again with --verbose.
```
Demote `ControlFlow::{from|into}_try` to `pub(crate)`
They have mediocre names and non-obvious semantics, so personally I don't think they're worth trying to stabilize, and thus might as well just be internal (they're used for convenience in iterator adapters), not something shown in the rustdocs.
I don't think anyone actually wanted to use them outside `core` -- they just got made public-but-unstable along with the whole type in https://github.com/rust-lang/rust/pull/76204 that promoted `LoopState` from an internal type to the exposed `ControlFlow` type.
cc https://github.com/rust-lang/rust/issues/75744, the tracking issue they mention.
cc https://github.com/rust-lang/rust/pull/85608, the PR where I'm proposing stabilizing the type.
Fix pointer provenance in <[T]>::copy_within
Previously the `self.as_mut_ptr()` invalidated the pointer created by the first `self.as_ptr()`. This also triggered miri when run with `-Zmiri-track-raw-pointers`
doc: clarify Mutex::try_lock, etc. errors
Clarify error returns from Mutex::try_lock, RwLock::try_read,
RwLock::try_write to make it more obvious that both poisoning
and the lock being already locked are possible errors.