Split `core::slice` to smaller mods
Unfortunately the `#[lang = "slice"]` is too big (3003 lines), I cannot split it further.
Note for reviewer:
* I split to multiple commits for easier reviewing, but I could git squash them all to one if requested.
* Recommend pulling this change locally and using advanced git diff viewer or this command:
```
git show --reverse --color-moved=dimmed-zebra master..
```
---
I split core/slice/mod.rs to these modules:
* `ascii`: For operations on `[u8]`.
* `cmp`: For comparison operations on `[T]`, like PartialEq and SliceContains impl.
* `index`: For indexing operations like Index/IndexMut and SliceIndex.
* `iter`: For Iterator definitions and implementation on `[T]`.
- `macros`: For iterator! and forward_iterator! macros.
* `raw`: For free function to create `&[T]` or `&mut [T]` from pointer + length or a reference.
The heapsort wrapper in mod.rs is removed in favor of reexport from `sort::heapsort`.
Refactor intra doc link code
I got tired of `fold_item` being 500 lines long.
This is best reviewed one commit at a time with whitespace changes hidden.
There are no logic changes other than the last commit making a parameter checked by the caller instead of the callee.
r? `@Manishearth`
Optimize behavior of vec.split_off(0) (take all)
Optimization improvement to `split_off()` so the performance meets the
intuitively expected behavior when `at == 0`, avoiding the current behavior
of copying the entire vector.
The change honors documented behavior that the original vector's
"previous capacity unchanged".
This improvement better supports the pattern for building and flushing a
buffer of elements, such as the following:
```rust
let mut vec = Vec::new();
loop {
vec.push(something);
if condition_is_met {
process(vec.split_off(0));
}
}
```
`Option` wrapping is the first alternative I thought of, but is much
less obvious and more verbose:
```rust
let mut capacity = 1;
let mut vec: Option<Vec<Stuff>> = None;
loop {
vec.get_or_insert_with(|| Vec::with_capacity(capacity)).push(something);
if condition_is_met {
capacity = vec.capacity();
process(vec.take().unwrap());
}
}
```
Directly using `mem::replace()` (instead of calling`split_off()`) could work,
but `mem::replace()` is a more advanced tool for Rust developers, and in
this case, I believe developers would assume the standard library should
be sufficient for the purpose described here.
The benefit of the approach to this change is it does not change the
existing API contract, but improves the peformance of `split_off(0)` for
`Vec`, `String` (which delegates `split_off()` to `Vec`), and any other
existing use cases.
This change adds tests to validate the behavior of `split_off()` with
regard to capacity, as originally documented, and confirm that behavior
still holds, when `at == 0`.
The change is an implementation detail, and does not require a
documentation change, but documenting the new behavior as part of its
API contract may benefit future users.
(Let me know if I should make that documentation update.)
Note, for future consideration:
I think it would be helpful to introduce an additional method to `Vec`
(if not also to `String`):
```
pub fn take_all(&mut self) -> Self {
self.split_off(0)
}
```
This would make it more clear how `Vec` supports the pattern, and make
it easier to find, since the behavior is similar to other `take()`
methods in the Rust standard library.
r? `@wesleywiser`
FYI: `@tmandry`
use sort_unstable to sort primitive types
It's not important to retain original order if we have &[1, 1, 2, 3] for example.
clippy::stable_sort_primitive
More structured suggestions for boxed trait objects instead of impl Trait on non-coerceable tail expressions
When encountering a `match` or `if` as a tail expression where the
different arms do not have the same type *and* the return type of that
`fn` is an `impl Trait`, check whether those arms can implement `Trait`
and if so, suggest using boxed trait objects.
Use structured suggestion for `impl T` to `Box<dyn T>`.
Fix https://github.com/rust-lang/rust/issues/69107
Stabilize doc_alias feature
Fixes#50146.
This PR intend to stabilize the `doc_alias` feature. The last remaining bits were missing checks on the attribute usage and on its arguments. Both have been added so I think we can now move to the next step.
r? `@ollie27`
cc `@rust-lang/rustdoc`
Ignore rustc_private items from std docs
By ignoring rustc_private items for non local impl block,
this may fix#74672 and fix#75588 .
This might suppress #76529 if it is simple enough for backport.
Auto-generate lint documentation.
This adds a tool which will generate the lint documentation in the rustc book automatically. This is motivated by keeping the documentation up-to-date, and consistently formatted. It also ensures the examples are correct and that they actually generate the expected lint. The lint groups table is also auto-generated. See https://github.com/rust-lang/compiler-team/issues/349 for the original proposal.
An outline of how this works:
- The `declare_lint!` macro now accepts a doc comment where the documentation is written. This is inspired by how clippy works.
- A new tool `src/tools/lint-docs` scrapes the documentation and adds it to the rustc book during the build.
- It runs each example and verifies its output and embeds the output in the book.
- It does a few formatting checks.
- It verifies that every lint is documented.
- Groups are collected from `rustc -W help`.
I updated the documentation for all the missing lints. I have also added an "Explanation" section to each lint providing a reason for the lint and suggestions on how to resolve it.
This can lead towards a future enhancement of possibly showing these docs via the `--explain` flag to make them easily accessible and discoverable.
allow concrete self types in consts
This is quite a bad hack to fix#75486. There might be a better way to check if the self type depends on generic parameters, but I wasn't able to come up with one.
r? `@varkor` cc `@petrochenkov`
inliner: Emit storage markers for introduced arg temporaries
When introducing argument temporaries during inlining, emit storage
marker statements just before the assignment and in the beginning of
the return block.
This ensures that such temporaries will not be considered live across
yield points after inlining inside a generator.
Fixes#71793.
Don't query stability data when `staged_api` is off
This data only needs to be encoded when `#![feature(staged_api)]` or `-Zforce-unstable-if-unmarked` is on. Running these queries takes measurable time on large crates with many items, so skip it when the unstable flags have not been enabled.
Rollup of 12 pull requests
Successful merges:
- #75559 (unions: test move behavior of non-Copy fields)
- #76441 (Note that parallel-compiler = true causes tests to fail)
- #76527 (Remove internal and unstable MaybeUninit::UNINIT.)
- #76629 (Simplify iter zip struct doc)
- #76640 (Simplify SyncOnceCell's `take` and `drop`.)
- #76646 (Add mailmap entry)
- #76651 (Remove Windows details from Unix and VmWorks symlink() docstrings)
- #76663 (Simplify iter chain struct doc)
- #76665 (slice::from_raw_parts: explicitly mention that data must be initialized)
- #76667 (Fix CI LLVM to work on NixOS out of the box)
- #76668 (Add visualization of rustc span in doc)
- #76677 (note that test_stable_pointers does not reflect a stable guarantee)
Failed merges:
r? `@ghost`
Optimization improvement to `split_off()` so the performance meets the
intuitively expected behavior when `at == 0`, avoiding the current
behavior of copying the entire vector.
The change honors documented behavior that the method leaves the
original vector's "previous capacity unchanged".
This improvement better supports the pattern for building and flushing a
buffer of elements, such as the following:
```rust
let mut vec = Vec::new();
loop {
vec.push(something);
if condition_is_met {
process(vec.split_off(0));
}
}
```
`Option` wrapping is the first alternative I thought of, but is much
less obvious and more verbose:
```rust
let mut capacity = 1;
let mut vec: Option<Vec<Stuff>> = None;
loop {
vec.get_or_insert_with(|| Vec::with_capacity(capacity)).push(something);
if condition_is_met {
capacity = vec.capacity();
process(vec.take().unwrap());
}
}
```
Directly applying `mem::replace()` could work, but `mem::` functions are
typically a last resort, when a developer is actively seeking better
performance than the standard library provides, for example.
The benefit of the approach to this change is it does not change the
existing API contract, but improves the peformance of `split_off(0)` for
`Vec`, `String` (which delegates `split_off()` to `Vec`), and any other
existing use cases.
This change adds tests to validate the behavior of `split_off()` with
regard to capacity, as originally documented, and confirm that behavior
still holds, when `at == 0`.
The change is an implementation detail, and does not require a
documentation change, but documenting the new behavior as part of its
API contract may benefit future users.
(Let me know if I should make that documentation update.)
Note, for future consideration:
I think it would be helpful to introduce an additional method to `Vec`
(if not also to `String`):
```
pub fn take_all(&mut self) -> Self {
self.split_off(0)
}
```
This would make it more clear how `Vec` supports the pattern, and make
it easier to find, since the behavior is similar to other `take()`
methods in the Rust standard library.
Previously, `resolve` would immediately check that `module_id` was
non-empty and give an error if not. This had two downsides:
- It introduced `Option`s everywhere, even if the calling function knew
it had a valid module, and
- It checked the module on each namespace, which is unnecessary: it only
needed to be checked once.
This makes the caller responsible for checking the module exists, making
the code a lot simpler.
Remove internal and unstable MaybeUninit::UNINIT.
Looks like it is no longer necessary, as `uninit_array()` can be used instead in the few cases where it was needed.
(I wanted to just add `#[doc(hidden)]` to remove clutter from the documentation, but looks like it can just be removed entirely.)