That is, change `diagnostic_outside_of_impl` and
`untranslatable_diagnostic` from `allow` to `deny`, because more than
half of the compiler has be converted to use translated diagnostics.
This commit removes more `deny` attributes than it adds `allow`
attributes, which proves that this change is warranted.
Stabilize `slice_first_last_chunk`
This PR does a few different things based around stabilizing `slice_first_last_chunk`. They are split up so this PR can be by-commit reviewed, I can move parts to a separate PR if desired.
This feature provides a very elegant API to extract arrays from either end of a slice, such as for parsing integers from binary data.
## Stabilize `slice_first_last_chunk`
ACP: https://github.com/rust-lang/libs-team/issues/69
Implementation: https://github.com/rust-lang/rust/issues/90091
Tracking issue: https://github.com/rust-lang/rust/issues/111774
This stabilizes the functionality from https://github.com/rust-lang/rust/issues/111774:
```rust
impl [T] {
pub const fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>;
pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>;
pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>;
pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>;
pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>;
pub fn split_first_chunk_mut<const N: usize>(&mut self) -> Option<(&mut [T; N], &mut [T])>;
pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>;
pub fn split_last_chunk_mut<const N: usize>(&mut self) -> Option<(&mut [T], &mut [T; N])>;
}
```
Const stabilization is included for all non-mut methods, which are blocked on `const_mut_refs`. This change includes marking the trivial function `slice_split_at_unchecked` const-stable for internal use (but not fully stable).
## Remove `split_array` slice methods
Tracking issue: https://github.com/rust-lang/rust/issues/90091
Implementation: https://github.com/rust-lang/rust/pull/83233#pullrequestreview-780315524
This PR also removes the following unstable methods from the `split_array` feature, https://github.com/rust-lang/rust/issues/90091:
```rust
impl<T> [T] {
pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T]);
pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T]);
pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N]);
pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N]);
}
```
This is done because discussion at #90091 and its implementation PR indicate a strong preference for nonpanicking APIs that return `Option`. The only difference between functions under the `split_array` and `slice_first_last_chunk` features is `Option` vs. panic, so remove the duplicates as part of this stabilization.
This does not affect the array methods from `split_array`. We will want to revisit these once `generic_const_exprs` is further along.
## Reverse order of return tuple for `split_last_chunk{,_mut}`
An unresolved question for #111774 is whether to return `(preceding_slice, last_chunk)` (`(&[T], &[T; N])`) or the reverse (`(&[T; N], &[T])`), from `split_last_chunk` and `split_last_chunk_mut`. It is currently implemented as `(last_chunk, preceding_slice)` which matches `split_last -> (&T, &[T])`. The first commit changes these to `(&[T], &[T; N])` for these reasons:
- More consistent with other splitting methods that return multiple values: `str::rsplit_once`, `slice::split_at{,_mut}`, `slice::align_to` all return tuples with the items in order
- More intuitive (arguably opinion, but it is consistent with other language elements like pattern matching `let [a, b, rest @ ..] ...`
- If we ever added a varidic way to obtain multiple chunks, it would likely return something in order: `.split_many_last::<(2, 4)>() -> (&[T], &[T; 2], &[T; 4])`
- It is the ordering used in the `rsplit_array` methods
I think the inconsistency with `split_last` could be acceptable in this case, since for `split_last` the scalar `&T` doesn't have any internal order to maintain with the other items.
## Unresolved questions
Do we want to reserve the same names on `[u8; N]` to avoid inference confusion? https://github.com/rust-lang/rust/pull/117561#issuecomment-1793388647
---
`slice_first_last_chunk` has only been around since early 2023, but `split_array` has been around since 2021.
`@rustbot` label -T-libs +T-libs-api -T-libs +needs-fcp
cc `@rust-lang/wg-const-eval,` `@scottmcm` who raised this topic, `@clarfonthey` implementer of `slice_first_last_chunk` `@jethrogb` implementer of `split_array`
Zulip discussion: https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Stabilizing.20array-from-slice.20*something*.3FFixes: #111774
This stabilizes all methods under `slice_first_last_chunk`.
Additionally, it const stabilizes the non-mut functions and moves the `_mut`
functions under `const_slice_first_last_chunk`. These are blocked on
`const_mut_refs`.
As part of this change, `slice_split_at_unchecked` was marked const-stable for
internal use (but not fully stable).
`serialize.rs` has the `Encodable`/`Decodable` impls for lots of basic
types, including `Vec`. `collection_impls` has it for lots of collection
types. The distinction isn't really meaningful, and it's simpler to have
them all in a single file.
On later stages, the feature is already stable.
Result of running:
rg -l "feature.let_else" compiler/ src/librustdoc/ library/ | xargs sed -s -i "s#\\[feature.let_else#\\[cfg_attr\\(bootstrap, feature\\(let_else\\)#"
The signed LEB128 decoding function used a hardcoded constant of 64
instead of the number of bits in the type of integer being decoded,
which resulted in incorrect results for some inputs. Fix this, make the
decoding more consistent with the unsigned version, and increase the
LEB128 encoding and decoding test coverage.
Reduce a large memory spike that happens during serialization by writing
the incr comp structures to file by way of a fixed-size buffer, rather
than an unbounded vector.
Effort was made to keep the instruction count close to that of the
previous implementation. However, buffered writing to a file inherently
has more overhead than writing to a vector, because each write may
result in a handleable error. To reduce this overhead, arrangements are
made so that each LEB128-encoded integer can be written to the buffer
with only one capacity and error check. Higher-level optimizations in
which entire composite structures can be written with one capacity and
error check are possible, but would require much more work.
The performance is mostly on par with the previous implementation, with
small to moderate instruction count regressions. The memory reduction is
significant, however, so it seems like a worth-while trade-off.