Add allow-by-default lint on implicit ABI in extern function pointers and items
This adds a new lint, missing_abi, which lints on omitted ABIs on extern blocks, function declarations, and function pointers.
It is currently not emitting the best possible diagnostics -- we need to track the span of "extern" at least or do some heuristic searching based on the available spans -- but seems good enough for an initial pass than can be expanded in future PRs.
This is a pretty large PR, but mostly due to updating a large number of tests to include ABIs; I can split that into a separate PR if it would be helpful, but test updates are already in dedicated commits.
Try to avoid locals when cloning into Box/Rc/Arc
For generic `T: Clone`, we can allocate an uninitialized box beforehand,
which gives the optimizer a chance to create the clone directly in the
heap. For `T: Copy`, we can go further and do a simple memory copy,
regardless of optimization level.
The same applies to `Rc`/`Arc::make_mut` when they must clone the data.
Stabilize split_inclusive
### Contents of this MR
This stabilises:
* `slice::split_inclusive`
* `slice::split_inclusive_mut`
* `str::split_inclusive`
Closes#72360.
### A possible concern
The proliferation of `split_*` methods is not particularly pretty. The existence of `split_inclusive` seems to invite the addition of `rsplit_inclusive`, `splitn_inclusive`, etc. We could instead have a more general API, along these kinds of lines maybe:
```
pub fn split_generic('a,P,H>(&'a self, pat: P, how: H) -> ...
where P: Pattern
where H: SplitHow;
pub fn split_generic_mut('a,P,H>(&'a mut self, pat: P, how: H) -> ...
where P: Pattern
where H: SplitHow;
trait SplitHow {
fn reverse(&self) -> bool;
fn inclusive -> bool;
fn limit(&self) -> Option<usize>;
}
pub struct SplitFwd;
...
pub struct SplitRevInclN(pub usize);
```
But maybe that is worse.
### Let us defer that? ###
This seems like a can of worms. I think we can defer opening it now; if and when we have something more general, these two methods can become convenience aliases. But I thought I would mention it so the lang API team can consider it and have an opinion.
use Once instead of Mutex to manage capture resolution
For #78299
This allows us to return borrows of the captured backtrace frames that are tied to a borrow of the Backtrace itself, instead of to some short-lived Mutex guard.
We could alternatively share `&Mutex<Capture>`s and lock on-demand, but then we could potentially forget to call `resolve()` before working with the capture. It also makes it semantically clearer what synchronization is needed on the capture.
cc `@seanchen1991` `@rust-lang/project-error-handling`
Add `MaybeUninit` method `array_assume_init`
When initialising an array element-by-element, the conversion to the initialised array is done through `mem::transmute`, which is both ugly and does not work with const generics (see #61956). This PR proposes the associated method `array_assume_init`, matching the style of `slice_assume_init_*`:
```rust
unsafe fn array_assume_init<T, const N: usize>(array: [MaybeUninit<T>; N]) -> [T; N];
```
Example:
```rust
let mut array: [MaybeUninit<i32>; 3] = MaybeUninit::uninit_array();
array[0].write(0);
array[1].write(1);
array[2].write(2);
// SAFETY: Now safe as we initialised all elements
let array: [i32; 3] = unsafe {
MaybeUninit::array_assume_init(array)
};
```
Things I'm unsure about:
* Should this be a method of array instead?
* Should the function be const?
As we did with `Box`, we can allocate an uninitialized `Rc` or `Arc`
beforehand, giving the optimizer a chance to skip the local value for
regular clones, or avoid any local altogether for `T: Copy`.
For generic `T: Clone`, we can allocate an uninitialized box beforehand,
which gives the optimizer a chance to create the clone directly in the
heap. For `T: Copy`, we can go further and do a simple memory copy,
regardless of optimization level.
std/core docs: fix wrong link in PartialEq
PartialEq doc was attempting to link to ``[`Eq`]`` but instead we got a link to `` `eq` ``. Disambiguate with `trait@Eq`.
You can see the bad link [here](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html) (Second sentence, "floating point types implement PartialEq but not Eq").
These methods work very similarly to `Option`'s methods `as_ref` and
`as_mut`. They are useful in several situation, particularly when
calling other array methods (like `map`) on the result. Unfortunately,
we can't easily call them `as_ref` and `as_mut` as that would shadow
those methods on slices, thus being a breaking change (that is likely
to affect a lot of code).
Don't build in-tree llvm-libunwind if system-llvm-libunwind is enable
When "system-llvm-libunwind" is enabled, some target eg. musl still build in-tree llvm-libunwind which is useless.
BTreeMap: tougher checking on most uses of copy_nonoverlapping
Miri checks pointer provenance and destination, but we can check it in debug builds already.
Also, we can let Miri confirm we don't mistake imprints of moved keys and values as genuine.
r? `@Mark-Simulacrum`
Fix safety comment
The size assertion in the comment was inverted compared to the code. After fixing that the implication that `(new_size >= old_size) => new_size != 0` still doesn't hold so explain why `old_size != 0` at this point.
Implement From<char> for u64 and u128.
With this PR you can write
```
let u = u64::from('👤');
let u = u128::from('👤');
```
Previously, you could already write `as` conversions ([Playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cee18febe28e69024357d099f07ca081)):
```
// Lossless conversions
dbg!('👤' as u32); // Prints 128100
dbg!('👤' as u64); // Prints 128100
dbg!('👤' as u128); // Prints 128100
// truncates, thus no `From` impls.
dbg!('👤' as u8); // Prints 100
dbg!('👤' as u16); // Prints 62564
// These `From` impls already exist.
dbg!(u32::from('👤')); // Prints 128100
dbg!(u64::from(u32::from('👤'))); // Prints 128100
```
The idea is from ``@gendx`` who opened [this Internals thread](https://internals.rust-lang.org/t/implement-from-char-for-u64/13454), and ``@withoutboats`` responded that someone should open a PR for it.
Some people mentioned `From<char>` impls for `f32` and `f64`, but that doesn't seem correct to me, so I didn't include them here.
I don't know what the feature should be named. Must it be registered somewhere, like unstable features?
r? ``@withoutboats``
Rustdoc: Fix macros 2.0 and built-in derives being shown at the wrong path
Fixes#74355
- ~~waiting on author + draft PR since my code ought to be cleaned up _w.r.t._ the way I avoid the `.unwrap()`s:~~
- ~~dummy items may avoid the first `?`,~~
- ~~but within the module traversal some tests did fail (hence the second `?`), meaning the crate did not possess the exact path of the containing module (`extern` / `impl` blocks maybe? I'll look into that).~~
r? `@jyn514`
Optimize away some path lookups in the generic `fs::copy` implementation
This also eliminates a use of a `Path` convenience function, in support
of #80741, refactoring `std::path` to focus on pure data structures and
algorithms.
Improve wording of parse doc
Change:
```
`parse` can parse any type that...
```
to:
```
`parse` can parse into any type that...
```
Word `into` added to be more precise and in coherence with other parts of the doc.
Stabilize slice::strip_prefix and slice::strip_suffix
These two methods are useful. The corresponding methods on `str` are already stable.
I believe that stablising these now would not get in the way of, in the future, extending these to take a richer pattern API a la `str`'s patterns.
Tracking PR: #73413. I also have an outstanding PR to improve the docs for these two functions and the corresponding ones on `str`: #75078
I have tried to follow the [instructions in the dev guide](https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr). The part to do with `compiler/rustc_feature` did not seem applicable. I assume that's because these are just library features, so there is no corresponding machinery in rustc.
The size assertion in the comment was inverted compared to the code. After fixing that the implication that `(new_size >= old_size) => new_size != 0` still doesn't hold so explain why `old_size != 0` at this point.
Change:
```
`parse` can parse any type that...
```
to:
```
`parse` can parse into any type that...
```
Word `into` added to be more precise and in coherence with other parts of the doc.
This also eliminates a use of a `Path` convenience function, in support
of #80741, refactoring `std::path` to focus on pure data structures and
algorithms.