Override `clone_from` for some types
Override `clone_from` method of the `Clone` trait for:
- `cell::RefCell`
- `cmp::Reverse`
- `io::Cursor`
- `mem::ManuallyDrop`
This can bring performance improvements.
This also checks the contents and not only the capacity in case IntoIter's clone implementation is changed to add capacity at the end. Extra capacity at the beginning would be needed to make InPlaceIterable work.
Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
The unsoundness is not in Peekable per se, it rather is due to the
interaction between Peekable being able to hold an extra item
and vec::IntoIter's clone implementation shortening the allocation.
An alternative solution would be to change IntoIter's clone implementation
to keep enough spare capacity available.
Implement the new desugaring from `try_trait_v2`
~~Currently blocked on https://github.com/rust-lang/rust/issues/84782, which has a PR in https://github.com/rust-lang/rust/pull/84811~~ Rebased atop that fix.
`try_trait_v2` tracking issue: https://github.com/rust-lang/rust/issues/84277
Unfortunately this is already touching a ton of things, so if you have suggestions for good ways to split it up, I'd be happy to hear them. (The combination between the use in the library, the compiler changes, the corresponding diagnostic differences, even MIR tests mean that I don't really have a great plan for it other than trying to have decently-readable commits.
r? `@ghost`
~~(This probably shouldn't go in during the last week before the fork anyway.)~~ Fork happened.
Issue #25088 has been part of `thread_local!` for quite some time now.
Historical attempts have been made to add `#[inline]` to `__getit`
in #43931, #50252, and #59720, but these attempts ended up not landing
at the time due to segfaults on Windows.
In the interim though with `const`-initialized thread locals AFAIK this
is the only remaining bug which is why you might want to use
`#[thread_local]` over `thread_local!`. As a result I figured it was
time to resubmit this and see how it fares on CI and if I can help
debugging any issues that crop up.
Closes#25088
Implement more Iterator methods on core::iter::Repeat
`core::iter::Repeat` always returns the same element, which means we can
do better than implementing most `Iterator` methods in terms of
`Iterator::next`.
Fixes#81292.
#81292 raises the question of whether these changes violate the contract of `core::iter::Repeat`, but as far as I can tell `core::iter::repeat` doesn't make any guarantees around how it calls `Clone::clone`.
Provide ExitStatusError
Closes#73125
In MR #81452 "Add #[must_use] to [...] process::ExitStatus" we concluded that the existing arrangements in are too awkward so adding that `#[must_use]` is blocked on improving the ergonomics.
I wrote a mini-RFC-style discusion of the approach in https://github.com/rust-lang/rust/issues/73125#issuecomment-771092741
# Stabilization report
## Summary
This stabilizes using macro expansion in key-value attributes, like so:
```rust
#[doc = include_str!("my_doc.md")]
struct S;
#[path = concat!(env!("OUT_DIR"), "/generated.rs")]
mod m;
```
See the changes to the reference for details on what macros are allowed;
see Petrochenkov's excellent blog post [on internals](https://internals.rust-lang.org/t/macro-expansion-points-in-attributes/11455)
for alternatives that were considered and rejected ("why accept no more
and no less?")
This has been available on nightly since 1.50 with no major issues.
## Notes
### Accepted syntax
The parser accepts arbitrary Rust expressions in this position, but any expression other than a macro invocation will ultimately lead to an error because it is not expected by the built-in expression forms (e.g., `#[doc]`). Note that decorators and the like may be able to observe other expression forms.
### Expansion ordering
Expansion of macro expressions in "inert" attributes occurs after decorators have executed, analogously to macro expressions appearing in the function body or other parts of decorator input.
There is currently no way for decorators to accept macros in key-value position if macro expansion must be performed before the decorator executes (if the macro can simply be copied into the output for later expansion, that can work).
## Test cases
- https://github.com/rust-lang/rust/blob/master/src/test/ui/attributes/key-value-expansion-on-mac.rs
- https://github.com/rust-lang/rust/blob/master/src/test/rustdoc/external-doc.rs
The feature has also been dogfooded extensively in the compiler and
standard library:
- https://github.com/rust-lang/rust/pull/83329
- https://github.com/rust-lang/rust/pull/83230
- https://github.com/rust-lang/rust/pull/82641
- https://github.com/rust-lang/rust/pull/80534
## Implementation history
- Initial proposal: https://github.com/rust-lang/rust/issues/55414#issuecomment-554005412
- Experiment to see how much code it would break: https://github.com/rust-lang/rust/pull/67121
- Preliminary work to restrict expansion that would conflict with this
feature: https://github.com/rust-lang/rust/pull/77271
- Initial implementation: https://github.com/rust-lang/rust/pull/78837
- Fix for an ICE: https://github.com/rust-lang/rust/pull/80563
## Unresolved Questions
~~https://github.com/rust-lang/rust/pull/83366#issuecomment-805180738 listed some concerns, but they have been resolved as of this final report.~~
## Additional Information
There are two workarounds that have a similar effect for `#[doc]`
attributes on nightly. One is to emulate this behavior by using a limited version of this feature that was stabilized for historical reasons:
```rust
macro_rules! forward_inner_docs {
($e:expr => $i:item) => {
#[doc = $e]
$i
};
}
forward_inner_docs!(include_str!("lib.rs") => struct S {});
```
This also works for other attributes (like `#[path = concat!(...)]`).
The other is to use `doc(include)`:
```rust
#![feature(external_doc)]
#[doc(include = "lib.rs")]
struct S {}
```
The first works, but is non-trivial for people to discover, and
difficult to read and maintain. The second is a strange special-case for
a particular use of the macro. This generalizes it to work for any use
case, not just including files.
I plan to remove `doc(include)` when this is stabilized. The
`forward_inner_docs` workaround will still compile without warnings, but
I expect it to be used less once it's no longer necessary.
Simplify `cfg(any(unix, target_os="redox"))` in example to just `cfg(unix)`
Update example for `OsString` that handled `redox` seperately from `unix`: Redox has been completely integrated under `target_family="unix"`, so `cfg(unix)` implies `target_os="redox"`
35dbef2350/compiler/rustc_target/src/spec/redox_base.rs (L26)
Expand WASI abbreviation in docs
I was pretty sure this was related to something for WebAssembly but wasn't 100% sure so I checked but even on these top-level docs I couldn't find the abbreviation expanded. I'm normally used to Rust docs being detailed and explanatory and writing abbreviations like this out in full at least once so I thought it was worth the change. Feel free to close this if it's too much.
This avoids a zero-length write_str call, which boils down to a zero-length
memmove and ultimately costs quite a few instructions on some workloads.
This is approximately a 0.33% instruction count win on diesel-check.
Do not allocate or unwind after fork
### Objective scenarios
* Make (simple) panics safe in `Command::pre_exec_hook`, including most `panic!` calls, `Option::unwrap`, and array bounds check failures.
* Make it possible to `libc::fork` and then safely panic in the child (needed for the above, but this requirement means exposing the new raw hook API which the `Command` implementation needs).
* In singlethreaded programs, where panic in `pre_exec_hook` is already memory-safe, prevent the double-unwinding malfunction #79740.
I think we want to make panic after fork safe even though the post-fork child environment is only experienced by users of `unsafe`, beause the subset of Rust in which any panic is UB is really far too hazardous and unnatural.
#### Approach
* Provide a way for a program to, at runtime, switch to having panics abort. This makes it possible to panic without making *any* heap allocations, which is needed because on some platforms malloc is UB in a child forked from a multithreaded program (see https://github.com/rust-lang/rust/pull/80263#issuecomment-774272370, and maybe also the SuS [spec](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)).
* Make that change in the child spawned by `Command`.
* Document the rules comprehensively enough that a programmer has a fighting chance of writing correct code.
* Test that this all works as expected (and in particular, that there aren't any heap allocations we missed)
Fixes#79740
#### Rejected (or previously attempted) approaches
* Change the panic machinery to be able to unwind without allocating, at least when the payload and message are both `'static`. This seems like it would be even more subtle. Also that is a potentially-hot path which I don't want to mess with.
* Change the existing panic hook mechanism to not convert the message to a `String` before calling the hook. This would be a surprising change for existing code and would not be detected by the type system.
* Provide a `raw_panic_hook` function to intercept panics in a way that doesn't allocate. (That was an earlier version of this MR.)
### History
This MR could be considered a v2 of #80263. Thanks to everyone who commented there. In particular, thanks to `@m-ou-se,` `@Mark-Simulacrum` and `@hyd-dev.` (Tagging you since I think you might be interested in this new MR.) Compared to #80263, this MR has very substantial changes and additions.
Additionally, I have recently (2021-04-20) completely revised this series following very helpful comments from `@m-ou-se.`
r? `@m-ou-se`
`core::iter::Repeat` always returns the same element, which means we can
do better than implementing most `Iterator` methods in terms of
`Iterator::next`.
Fixes#81292.
Some platforma (eg ARM64) apparently generate SIGTRAP for panic abort!
See eg
https://github.com/rust-lang/rust/pull/81858#issuecomment-840702765
This is probably a bug, but we don't want to entangle this MR with it.
When it's fixed, this commit should be reverted.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
add BITS associated constant to core::num::Wrapping
This keeps `Wrapping` synchronized with the primitives it wraps as for the #32463 `wrapping_int_impl` feature.
Remove rustc_args_required_const attribute
Now that stdarch no longer needs it (thanks `@Amanieu!),` we can kill the `rustc_args_required_const` attribute. This means that lifetime extension of references to temporaries is the only remaining job that promotion is performing. :-)
r? `@oli-obk`
Fixes https://github.com/rust-lang/rust/issues/69493
#[inline(always)] on basic pointer methods
Retryng #85201 with only inlining pointer methods. The goal is to make pointers behave just like pointers in O0, mainly to reduce overhead in debug builds.
cc `@scottmcm`
Add auto traits and clone trait migrations for RFC2229
This PR
- renames the existent RFC2229 migration `disjoint_capture_drop_reorder` to `disjoint_capture_migration`
- add additional migrations for auto traits and clone trait
Closesrust-lang/project-rfc-2229#29Closesrust-lang/project-rfc-2229#28
r? `@nikomatsakis`
It is unergnomic to have to say things like
bad.into_status().signal()
Implementing `ExitStatusExt` for `ExitStatusError` fixes this.
Unfortunately it does mean making a previously-infallible method
capable of panicing, although of course the existing impl remains
infallible.
The alternative would be a whole new `ExitStatusErrorExt` trait.
`<ExitStatus as ExitStatusExt>::into_raw()` is not particularly
ergonomic to call because of the often-required type annotation.
See for example the code in the test case in
library/std/src/sys/unix/process/process_unix/tests.rs
Perhaps we should provide equivalent free functions for `ExitStatus`
and `ExitStatusExt` in std::os::unix::process and maybe deprecate this
trait method. But I think that is for the future.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Closes#73125
This is in pursuance of
Issue #73127 Consider adding #[must_use] to std::process::ExitStatus
In
MR #81452 Add #[must_use] to [...] process::ExitStatus
we concluded that the existing arrangements in are too awkward
so adding that #[must_use] is blocked on improving the ergonomics.
I wrote a mini-RFC-style discusion of the approach in
https://github.com/rust-lang/rust/issues/73125#issuecomment-771092741
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
This PR implements span quoting, allowing proc-macros to produce spans
pointing *into their own crate*. This is used by the unstable
`proc_macro::quote!` macro, allowing us to get error messages like this:
```
error[E0412]: cannot find type `MissingType` in this scope
--> $DIR/auxiliary/span-from-proc-macro.rs:37:20
|
LL | pub fn error_from_attribute(_args: TokenStream, _input: TokenStream) -> TokenStream {
| ----------------------------------------------------------------------------------- in this expansion of procedural macro `#[error_from_attribute]`
...
LL | field: MissingType
| ^^^^^^^^^^^ not found in this scope
|
::: $DIR/span-from-proc-macro.rs:8:1
|
LL | #[error_from_attribute]
| ----------------------- in this macro invocation
```
Here, `MissingType` occurs inside the implementation of the proc-macro
`#[error_from_attribute]`. Previosuly, this would always result in a
span pointing at `#[error_from_attribute]`
This will make many proc-macro-related error message much more useful -
when a proc-macro generates code containing an error, users will get an
error message pointing directly at that code (within the macro
definition), instead of always getting a span pointing at the macro
invocation site.
This is implemented as follows:
* When a proc-macro crate is being *compiled*, it causes the `quote!`
macro to get run. This saves all of the sapns in the input to `quote!`
into the metadata of *the proc-macro-crate* (which we are currently
compiling). The `quote!` macro then expands to a call to
`proc_macro::Span::recover_proc_macro_span(id)`, where `id` is an
opaque identifier for the span in the crate metadata.
* When the same proc-macro crate is *run* (e.g. it is loaded from disk
and invoked by some consumer crate), the call to
`proc_macro::Span::recover_proc_macro_span` causes us to load the span
from the proc-macro crate's metadata. The proc-macro then produces a
`TokenStream` containing a `Span` pointing into the proc-macro crate
itself.
The recursive nature of 'quote!' can be difficult to understand at
first. The file `src/test/ui/proc-macro/quote-debug.stdout` shows
the output of the `quote!` macro, which should make this eaier to
understand.
This PR also supports custom quoting spans in custom quote macros (e.g.
the `quote` crate). All span quoting goes through the
`proc_macro::quote_span` method, which can be called by a custom quote
macro to perform span quoting. An example of this usage is provided in
`src/test/ui/proc-macro/auxiliary/custom-quote.rs`
Custom quoting currently has a few limitations:
In order to quote a span, we need to generate a call to
`proc_macro::Span::recover_proc_macro_span`. However, proc-macros
support renaming the `proc_macro` crate, so we can't simply hardcode
this path. Previously, the `quote_span` method used the path
`crate::Span` - however, this only works when it is called by the
builtin `quote!` macro in the same crate. To support being called from
arbitrary crates, we need access to the name of the `proc_macro` crate
to generate a path. This PR adds an additional argument to `quote_span`
to specify the name of the `proc_macro` crate. Howver, this feels kind
of hacky, and we may want to change this before stabilizing anything
quote-related.
Additionally, using `quote_span` currently requires enabling the
`proc_macro_internals` feature. The builtin `quote!` macro
has an `#[allow_internal_unstable]` attribute, but this won't work for
custom quote implementations. This will likely require some additional
tricks to apply `allow_internal_unstable` to the span of
`proc_macro::Span::recover_proc_macro_span`.
Change param name (k to key and v to value) in std::env module
1. When I was reading code the ide displayed `k` and `v`, so I
thought it would be better to show key and value?
2. I noticed var method already uses `key` instead of `k` so it
is more consistent to use `key` instead of `k`?
Thanks
BTree: no longer copy keys and values before dropping them
When dropping BTreeMap or BTreeSet instances, keys-value pairs are up to now each copied and then dropped, at least according to source code. This is because the code for dropping and for iterators is shared.
This PR postpones the treatment of doomed key-value pairs from the intermediate functions `deallocating_next`(`_back`) to the last minute, so the we can drop the keys and values in place. According to the library/alloc benchmarks, this does make a difference, (and a positive difference with an `#[inline]` on `drop_key_val`). It does not change anything for #81444 though.
r? `@Mark-Simulacrum`
Emit errors/warns on some wrong uses of rustdoc attributes
This PR adds a few diagnostics:
- error if conflicting `#[doc(inline)]`/`#[doc(no_inline)]` are found
- introduce the `invalid_doc_attributes` lint (warn-by-default) which triggers:
- if a crate-level attribute is used on a non-`crate` item
- if `#[doc(inline)]`/`#[doc(no_inline)]` is used on a non-`use` item
The code could probably be improved but I wanted to get feedback first. Also, some of those changes could be considered breaking changes, so I don't know what the procedure would be? ~~And finally, for the warnings, they are currently hard warnings, maybe it would be better to introduce a lint?~~ (EDIT: introduced the `invalid_doc_attributes` lint)
Closes#80275.
r? `@jyn514`
Provide io::Seek::rewind
Using `Seek::seek` is slightly clumsy because of the need to write (or import) `std::io::SeekFrom` to get at `SeekStart`. C already has `rewind` (although with broken error handling); we should have it too.
I'm motivated to do this because I've just found myself copy-pasting my 5-line extension trait between projects.
That the example ends up using `OpenOptions` makes this look like a niche use case, but it is very common to rewind temporary files. `tempfile` isn't available for use in this example or it would have looked shorter and more natural.
If this gets a positive reception I will open a tracking issue and update the feature gate.
Make unchecked_{add,sub,mul} inherent methods unstably const
The intrinsics are marked as being stably const (even though they're not stable by nature of being intrinsics), but the currently-unstable inherent versions are not marked as const. This fixes this inconsistency. Split out of #85017,
r? `@oli-obk`
Bump stdarch submodule
Major changes:
- More AVX-512 intrinsics.
- More ARM & AArch64 NEON intrinsics.
- Updated unstable WASM intrinsics to latest draft standards.
- Intrinsics that previously used `#[rustc_args_required_const]` now use const generics. See #83167 for more details.
- `std_detect` is now a separate crate instead of a submodule of `std`.
fork fails there. The failure message is confusing: so c.status()
returns an Err, the closure panics, and the test thinks the panic was
propagated from inside the child.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
Rearrange SGX split module files
In #75979 several inlined modules were split out into multiple files.
This PR keeps the multiple files but moves a few things around to
organize things in a coherent way.
Cleanup of `wasm`
Some more cleanup of `sys`, this time `wasm`
- Reuse `unsupported::args` (functionally equivalent implementation, just an empty iterator).
- Split out `atomics` implementation of `wasm::thread`, the non-`atomics` implementation is reused from `unsupported`.
- Move all of the `atomics` code to a separate directory `wasm/atomics`.
````@rustbot```` label: +T-libs-impl
r? ````@m-ou-se````
In #75979 several inlined modules were split out into multiple files.
This PR keeps the multiple files but moves a few things around to
organize things in a coherent way.
This tests that we can indeed safely panic after fork, both
a raw libc::fork and in a Command pre_exec hook.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
This is safe (does not involve heap allocation) but we don't yet have
a test to ensure that stays true. That will come in a moment.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
Unwinding after fork() in the child is UB on some platforms, because
on those (including musl) malloc can be UB in the child of a
multithreaded program, and unwinding must box for the payload.
Even if it's safe, unwinding past fork() in the child causes whatever
traps the unwind to return twice. This is very strange and clearly
not desirable. With the default behaviour of the thread library, this
can even result in a panic in the child being transformed into zero
exit status (ie, success) as seen in the parent!
Fixes#79740.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
We must change the atomic read on panic entry to `Acquire`, to pick up
a possible an `always_panic` on another thread.
We add `count` to the names of panic_count::get and ::is_zaero,
because now there is another reason why panic ought to maybe abort.
Renaming these ensures that we have checked every call site to ensure
that they don't need further adjustment.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
Disallows `#![feature(no_coverage)]` on stable and beta (using standard crate-level gating)
Fixes: #84836
Removes the function-level feature gating solution originally implemented, and solves the same problem using `allow_internal_unstable`, so normal crate-level feature gating mechanism can still be used (which disallows the feature on stable and beta).
I tested this, building the compiler with and without `CFG_DISABLE_UNSTABLE_FEATURES=1`
With unstable features disabled, I get the expected result as shown here:
```shell
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc src/test/run-make-fulldeps/coverage/no_cov_crate.rs
error[E0554]: `#![feature]` may not be used on the dev release channel
--> src/test/run-make-fulldeps/coverage/no_cov_crate.rs:2:1
|
2 | #![feature(no_coverage)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0554`.
```
r? ````@Mark-Simulacrum````
cc: ````@tmandry```` ````@wesleywiser````
Allow using `core::` in intra-doc links within core itself
I came up with this idea ages ago, but rustdoc used to ICE on it. Now it doesn't.
Helps with https://github.com/rust-lang/rust/issues/73445. Doesn't fix it completely since `extern crate self as std;` in std still gives strange errors.
Stablize {HashMap,BTreeMap}::into_{keys,values}
I would propose to stabilize `{HashMap,BTreeMap}::into_{keys,values}`( aka. `map_into_keys_values`).
Closes#75294.
For certain sorts of systems, programming, it's deemed essential that
all allocation failures be explicitly handled where they occur. For
example, see Linus Torvald's opinion in [1]. Merely not calling global
panic handlers, or always `try_reserving` first (for vectors), is not
deemed good enough, because the mere presence of the global OOM handlers
is burdens static analysis.
One option for these projects to use rust would just be to skip `alloc`,
rolling their own allocation abstractions. But this would, in my
opinion be a real shame. `alloc` has a few `try_*` methods already, and
we could easily have more. Features like custom allocator support also
demonstrate and existing to support diverse use-cases with the same
abstractions.
A natural way to add such a feature flag would a Cargo feature, but
there are currently uncertainties around how std library crate's Cargo
features may or not be stable, so to avoid any risk of stabilizing by
mistake we are going with a more low-level "raw cfg" token, which
cannot be interacted with via Cargo alone.
Note also that since there is no notion of "default cfg tokens" outside
of Cargo features, we have to invert the condition from
`global_oom_handling` to to `not(no_global_oom_handling)`. This breaks
the monotonicity that would be important for a Cargo feature (i.e.
turning on more features should never break compatibility), but it
doesn't matter for raw cfg tokens which are not intended to be
"constraint solved" by Cargo or anything else.
To support this use-case we create a new feature, "global-oom-handling",
on by default, and put the global OOM handler infra and everything else
it that depends on it behind it. By default, nothing is changed, but
users concerned about global handling can make sure it is disabled, and
be confident that all OOM handling is local and explicit.
For this first iteration, non-flat collections are outright disabled.
`Vec` and `String` don't yet have `try_*` allocation methods, but are
kept anyways since they can be oom-safely created "from parts", and we
hope to add those `try_` methods in the future.
[1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
Rollup of 11 pull requests
Successful merges:
- #83553 (Update `ptr` docs with regards to `ptr::addr_of!`)
- #84183 (Update RELEASES.md for 1.52.0)
- #84709 (Add doc alias for `chdir` to `std::env::set_current_dir`)
- #84803 (Reduce duplication in `impl_dep_tracking_hash` macros)
- #84808 (Account for unsatisfied bounds in E0599)
- #84843 (use else if in std library )
- #84865 (rustbuild: Pass a `threads` flag that works to windows-gnu lld)
- #84878 (Clarify documentation for `[T]::contains`)
- #84882 (platform-support: Center the contents of the `std` and `host` columns)
- #84903 (Remove `rustc_middle::mir::interpret::CheckInAllocMsg::NullPointerTest`)
- #84913 (Do not ICE on invalid const param)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Clarify documentation for `[T]::contains`
Change the documentation to correctly characterize when the suggested alternative to `contains` applies, and correctly explain why it works.
Fixes#84877
Add doc alias for `chdir` to `std::env::set_current_dir`
Searching for `chdir` in the Rust documentation produces no useful
results.
I wrote some code recently that called `libc::chdir` and manually
handled errors, because I didn't realize that the safe
`std::env::set_current_dir` existed. I searched for `chdir` and
`change_dir` and `change_directory` (the latter two based on the
precedent of unabbreviating set by `create_dir`), and I also read
through `std::fs` expecting to potentially find it there. Given that
none of those led to `std::env::set_current_dir`, I think that provides
sufficient justification to add this specific alias.
Update `ptr` docs with regards to `ptr::addr_of!`
This updates the documentation since `ptr::addr_of!` and `ptr::addr_of_mut!` are now stable. One might remove the distinction between the sections `# On packed structs` and `# Examples`, as the old section on packed structs was primarily to prevent users of doing undefined behavior, which is not necessary anymore.
Technically there is now wrong/outdated documentation on stable, but I don't think this is worth a point release 😉Fixes#83509.
``````````@rustbot`````````` modify labels: T-doc
using allow_internal_unstable (as recommended)
Fixes: #84836
```shell
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc src/test/run-make-fulldeps/coverage/no_cov_crate.rs
error[E0554]: `#![feature]` may not be used on the dev release channel
--> src/test/run-make-fulldeps/coverage/no_cov_crate.rs:2:1
|
2 | #![feature(no_coverage)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0554`.
```
Move all `sys::ext` modules to `os`
This PR moves all `sys::ext` modules to `os`, centralizing the location of all `os` code and simplifying the dependencies between `os` and `sys`.
Because this also removes all uses `cfg_if!` on publicly exported items, where after #81969 there were still a few left, this should properly work around https://github.com/rust-analyzer/rust-analyzer/issues/6038.
`@rustbot` label: +T-libs-impl
This updates the documentation since `ptr::addr_of!` and
`ptr::addr_of_mut!` are now stable. One might remove the distinction
between the sections `# On packed structs` and `# Examples`, as the old
section on packed structs was primarily to prevent users of doing unde-
fined behavior, which is not necessary anymore.
There is also a new section in "how to obtain a pointer", which referen-
ces the `ptr::addr_of!` macros.
This commit contains squashed commits from code review.
Co-authored-by: Joshua Nelson <joshua@yottadb.com>
Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
Co-authored-by: Soveu <marx.tomasz@gmail.com>
Co-authored-by: Ralf Jung <post@ralfj.de>
Replace 'NULL' with 'null'
This replaces occurrences of "NULL" with "null" in docs, comments, and compiler error/lint messages. This is for the sake of consistency, as the lowercase "null" is already the dominant form in Rust. The all-caps NULL looks like the C macro (or SQL keyword), which seems out of place in a Rust context, given that NULL does not exist in the Rust language or standard library (instead having [`ptr::null()`](https://doc.rust-lang.org/stable/std/ptr/fn.null.html)).
Rollup of 6 pull requests
Successful merges:
- #84072 (Allow setting `target_family` to multiple values, and implement `target_family="wasm"`)
- #84744 (Add ErrorKind::OutOfMemory)
- #84784 (Add help message to suggest const for unused type param)
- #84811 (RustDoc: Fix bounds linking trait.Foo instead of traitalias.Foo)
- #84818 (suggestion for unit enum variant when matched with a patern)
- #84832 (Do not print visibility in external traits)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
i8 and u8::to_string() specialisation (far less asm).
Take 2. Around 1/6th of the assembly to without specialisation.
https://godbolt.org/z/bzz8Mq
(partially fixes#73533 )
[Arm64] use isb instruction instead of yield in spin loops
On arm64 we have seen on several databases that ISB (instruction synchronization
barrier) is better to use than yield in a spin loop. The yield instruction is a
nop. The isb instruction puts the processor to sleep for some short time. isb
is a good equivalent to the pause instruction on x86.
Below is an experiment that shows the effects of yield and isb on Arm64 and the
time of a pause instruction on x86 Intel processors. The micro-benchmarks use
https://github.com/google/benchmark.git
```
$ cat a.cc
static void BM_scalar_increment(benchmark::State& state) {
int i = 0;
for (auto _ : state)
benchmark::DoNotOptimize(i++);
}
BENCHMARK(BM_scalar_increment);
static void BM_yield(benchmark::State& state) {
for (auto _ : state)
asm volatile("yield"::);
}
BENCHMARK(BM_yield);
static void BM_isb(benchmark::State& state) {
for (auto _ : state)
asm volatile("isb"::);
}
BENCHMARK(BM_isb);
BENCHMARK_MAIN();
$ g++ -o run a.cc -O2 -lbenchmark -lpthread
$ ./run
--------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------
AWS Graviton2 (Neoverse-N1) processor:
BM_scalar_increment 0.485 ns 0.485 ns 1000000000
BM_yield 0.400 ns 0.400 ns 1000000000
BM_isb 13.2 ns 13.2 ns 52993304
AWS Graviton (A-72) processor:
BM_scalar_increment 0.897 ns 0.874 ns 801558633
BM_yield 0.877 ns 0.875 ns 800002377
BM_isb 13.0 ns 12.7 ns 55169412
Apple Arm64 M1 processor:
BM_scalar_increment 0.315 ns 0.315 ns 1000000000
BM_yield 0.313 ns 0.313 ns 1000000000
BM_isb 9.06 ns 9.06 ns 77259282
```
```
static void BM_pause(benchmark::State& state) {
for (auto _ : state)
asm volatile("pause"::);
}
BENCHMARK(BM_pause);
Intel Skylake processor:
BM_scalar_increment 0.295 ns 0.295 ns 1000000000
BM_pause 41.7 ns 41.7 ns 16780553
```
Tested on Graviton2 aarch64-linux with `./x.py test`.
Be stricter about rejecting LLVM reserved registers in asm!
LLVM will silently produce incorrect code if these registers are used as operands.
cc `@rust-lang/wg-inline-asm`
Add std::os::unix::fs::chroot to change the root directory of the current process
This is a straightforward wrapper that uses the existing helpers for C
string handling and errno handling.
Having this available is convenient for UNIX utility programs written in
Rust, and avoids having to call the unsafe `libc::chroot` directly and
handle errors manually, in a program that may otherwise be entirely safe
code.
Reuse `sys::unix::cmath` on other platforms
Reuse `sys::unix::cmath` on all non-`windows` platforms.
`unix` is chosen as the canonical location instead of `unsupported` or `common` because `unsupported` doesn't make sense semantically and `common` is reserved for code that is supported on all platforms. Also `unix` is already the home of some non-`windows` code that is technically not exclusive to `unix` like `unix::path`.
This is a straightforward wrapper that uses the existing helpers for C
string handling and errno handling.
Having this available is convenient for UNIX utility programs written in
Rust, and avoids having to call the unsafe `libc::chroot` directly and
handle errors manually, in a program that may otherwise be entirely safe
code.
Drop alias `reduce` for `fold` - we have a `reduce` function
Searching for "reduce" currently puts the `reduce` alias for `fold`
above the actual `reduce` function. The `reduce` function already has a
cross-reference for `fold`, and vice versa.
Link between std::env::{var, var_os} and std::env::{vars, vars_os}
In #84551 I linked between `std::env::{args, args_os}` and this PR does the same but for `std::env::{var, var_os}` and `std::env::{vars, vars_os}`. Now all of `std::env::{var, var_os, vars, vars_os, args, args_os}` should each mention their `_os` or non-`_os` equivalent in the docs so that you can easily navigate between them.
Minor grammar tweaks for readability to btree internals
I was reading through the btree implementation and I noticed some grammar that could be improved in Node.rs so here is what I think would be a minor improvement.
Point out that behavior might be switched on 2015 and 2018 too one day
Reword documentation to make it clear that behaviour can be switched on older editions too, one day in the future. It doesn't *have* to be switched, but I think it's good to have it as an option and re-evaluate it a few months/years down the line when e.g. the crates that showed up in crater were broken by different changes in the language already.
cc #25725, #65819, #66145, #84147 , and https://github.com/rust-lang/rust/issues/84133#issuecomment-818005314
On arm64 we have seen on several databases that ISB (instruction synchronization
barrier) is better to use than yield in a spin loop. The yield instruction is a
nop. The isb instruction puts the processor to sleep for some short time. isb
is a good equivalent to the pause instruction on x86.
Below is an experiment that shows the effects of yield and isb on Arm64 and the
time of a pause instruction on x86 Intel processors. The micro-benchmarks use
https://github.com/google/benchmark.git
$ cat a.cc
static void BM_scalar_increment(benchmark::State& state) {
int i = 0;
for (auto _ : state)
benchmark::DoNotOptimize(i++);
}
BENCHMARK(BM_scalar_increment);
static void BM_yield(benchmark::State& state) {
for (auto _ : state)
asm volatile("yield"::);
}
BENCHMARK(BM_yield);
static void BM_isb(benchmark::State& state) {
for (auto _ : state)
asm volatile("isb"::);
}
BENCHMARK(BM_isb);
BENCHMARK_MAIN();
$ g++ -o run a.cc -O2 -lbenchmark -lpthread
$ ./run
--------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------
AWS Graviton2 (Neoverse-N1) processor:
BM_scalar_increment 0.485 ns 0.485 ns 1000000000
BM_yield 0.400 ns 0.400 ns 1000000000
BM_isb 13.2 ns 13.2 ns 52993304
AWS Graviton (A-72) processor:
BM_scalar_increment 0.897 ns 0.874 ns 801558633
BM_yield 0.877 ns 0.875 ns 800002377
BM_isb 13.0 ns 12.7 ns 55169412
Apple Arm64 M1 processor:
BM_scalar_increment 0.315 ns 0.315 ns 1000000000
BM_yield 0.313 ns 0.313 ns 1000000000
BM_isb 9.06 ns 9.06 ns 77259282
static void BM_pause(benchmark::State& state) {
for (auto _ : state)
asm volatile("pause"::);
}
BENCHMARK(BM_pause);
Intel Skylake processor:
BM_scalar_increment 0.295 ns 0.295 ns 1000000000
BM_pause 41.7 ns 41.7 ns 16780553
Tested on Graviton2 aarch64-linux with `./x.py test`.
Searching for "reduce" currently puts the `reduce` alias for `fold`
above the actual `reduce` function. The `reduce` function already has a
cross-reference for `fold`, and vice versa.
use correct feature flag for impl-block-level trait bounds on const fn
I am not sure what that special hack was needed for, but it doesn't seem needed any more...
This removes the last use of the `const_fn` feature flag -- Cc https://github.com/rust-lang/rust/issues/84510
r? `@oli-obk`
Remove `DropGuard` in `sys::windows::process` and use `StaticMutex` instead
`StaticMutex` is a mutex that when locked provides a guard that unlocks the mutex again when dropped, thus provides the exact same functionality as `DropGuard`. `StaticMutex` is used in more places, and is thus preferred over an ad-hoc construct like `DropGuard`.
````@rustbot```` label: +T-libs-impl
Simplify `Mutex::into_inner`
Thanks to #77147, `Mutex` do not implement `Drop` directly, so the old unsafe implementation of `into_inner` is not relevant anymore.
Adds feature-gated `#[no_coverage]` function attribute, to fix derived Eq `0` coverage issue #83601
Derived Eq no longer shows uncovered
The Eq trait has a special hidden function. MIR `InstrumentCoverage`
would add this function to the coverage map, but it is never called, so
the `Eq` trait would always appear uncovered.
Fixes: #83601
The fix required creating a new function attribute `no_coverage` to mark
functions that should be ignored by `InstrumentCoverage` and the
coverage `mapgen` (during codegen).
Adding a `no_coverage` feature gate with tracking issue #84605.
r? `@tmandry`
cc: `@wesleywiser`
The Eq trait has a special hidden function. MIR `InstrumentCoverage`
would add this function to the coverage map, but it is never called, so
the `Eq` trait would always appear uncovered.
Fixes: #83601
The fix required creating a new function attribute `no_coverage` to mark
functions that should be ignored by `InstrumentCoverage` and the
coverage `mapgen` (during codegen).
While testing, I also noticed two other issues:
* spanview debug file output ICEd on a function with no body. The
workaround for this is included in this PR.
* `assert_*!()` macro coverage can appear covered if followed by another
`assert_*!()` macro. Normally they appear uncovered. I submitted a new
Issue #84561, and added a coverage test to demonstrate this issue.
Reuse modules on `hermit`
Reuse the following modules on `hermit`:
- `unix::path` (contents identical)
- `unsupported::io` (contents identical)
- `unsupported::thread_local_key` (contents functionally identical, only changes are the panic error messages)
`@rustbot` label: +T-libs-impl
Add the `try_trait_v2` library basics
No compiler changes as part of this -- just new unstable traits and impls thereof.
The goal here is to add the things that aren't going to break anything, to keep the feature implementation simpler in the next PR.
(Draft since the FCP won't end until Saturday, but I was feeling optimistic today -- and had forgotten that FCP was 10 days, not 7 days.)
Unify the docs of std::env::{args_os, args} more
I noticed that `args_os` was missing some information and I thought it should mention `args` for when you want more safety just like how `args` mentions `args_os` if you don't want it to panic on invalid Unicode.
Stabilize Duration::MAX
Following the suggested direction from https://github.com/rust-lang/rust/issues/76416#issuecomment-817278338, this PR proposes that `Duration::MAX` should have been part of the `duration_saturating_ops` feature flag all along, having been
0. heavily referenced by that feature flag
1. an odd duck next to most of `duration_constants`, as I expressed in https://github.com/rust-lang/rust/issues/57391#issuecomment-717681193
2. introduced in #76114 which added `duration_saturating_ops`
and accordingly should be folded into `duration_saturating_ops` and therefore stabilized.
r? `@m-ou-se`
Remove slice diagnostic item
...because it is unusally placed on an impl and is redundant with a lang item.
Depends on rust-lang/rust-clippy#7074 (next clippy sync). ~I expect clippy tests to fail in the meantime.~ Nope tests passed...
CC `@flip1995`
Get rid of is_min_const_fn
This removes the last trace of the min_const_fn mechanism by making the unsafety checker agnostic about whether something is a min or "non-min" const fn. It seems this distinction was used to disallow some features inside `const fn`, but that is the responsibility of the const checker, not of the unsafety checker. No test seems to even notice this change in the unsafety checker so I guess we are good...
r? `@oli-obk`
Cc https://github.com/rust-lang/rust/issues/84510
Inline most raw socket, fd and handle conversions
Now that file descriptor types on Unix have niches, it is advantageous for user libraries which provide file descriptor wrappers (e.g. `Socket` from socket2) to store a `File` internally instead of a `RawFd`, so that the niche can be taken advantage of. However, doing so will currently result in worse performance as `IntoRawFd`, `FromRawFd` and `AsRawFd` are not inlined. This change adds `#[inline]` to those methods on std types that wrap file descriptors, handles or sockets.
move core::hint::black_box under its own feature gate
The `black_box` function had its own RFC and is tracked separately from the `test` feature at https://github.com/rust-lang/rust/issues/64102. Let's reflect this in the feature gate.
To avoid breaking all the benchmarks, libtest's `test::black_box` is a wrapping definition, not a reexport -- this means it is still under the `test` feature gate.
Cautiously add IntoIterator for arrays by value
Add the attribute described in #84133, `#[rustc_skip_array_during_method_dispatch]`, which effectively hides a trait from method dispatch when the receiver type is an array.
Then cherry-pick `IntoIterator for [T; N]` from #65819 and gate it with that attribute. Arrays can now be used as `IntoIterator` normally, but `array.into_iter()` has edition-dependent behavior, returning `slice::Iter` for 2015 and 2018 editions, or `array::IntoIter` for 2021 and later.
r? `@nikomatsakis`
cc `@LukasKalbertodt` `@rust-lang/libs`
Rework `init` and `cleanup`
This PR reworks the code in `std` that runs before and after `main` and centralizes this code respectively in the functions `init` and `cleanup` in both `sys_common` and `sys`. This makes is easy to see what code is executed during initialization and cleanup on each platform just by looking at e.g. `sys::windows::init`.
Full list of changes:
- new module `rt` in `sys_common` to contain `init` and `cleanup` and the runtime macros.
- `at_exit` and the mechanism to register exit handlers has been completely removed. In practice this was only used for closing sockets on windows and flushing stdout, which have been moved to `cleanup`.
- <s>On windows `alloc` and `net` initialization is now done in `init`, this saves a runtime check in every allocation and network use.</s>
Duration is used in std to represent a difference between two Instants.
As such, it has to at least contain that span of time in it. However,
Instant can vary by platform. Thus, we should explain the impl of
Duration::MAX is sensitive to these vagaries of the platform.
further split up const_fn feature flag
This continues the work on splitting up `const_fn` into separate feature flags:
* `const_fn_trait_bound` for `const fn` with trait bounds
* `const_fn_unsize` for unsizing coercions in `const fn` (looks like only `dyn` unsizing is still guarded here)
I don't know if there are even any things left that `const_fn` guards... at least libcore and liballoc do not need it any more.
`@oli-obk` are you currently able to do reviews?
Explicitly implement `!Send` and `!Sync` for `sys::{Args, Env}`
Remove the field `_dont_send_or_sync_me: PhantomData<*mut ()>` in favor of an explicit implementation of `!Send` and `!Sync`.
Mention FusedIterator case in Iterator::fuse doc
Using `fuse` on an iterator that incorrectly implements
`FusedIterator` does not fuse the iterator. This commit adds a
note about this in the documentation of this method to increase
awareness about this potential issue (esp. when relying on fuse
in unsafe code).
Closes#83969
implement `TrustedRandomAccess` for `Take` iterator adapter
`TrustedRandomAccess` requires the iterator length to fit within `usize`. `take(n)` only constrains the upper bound of an iterator. So if the inner is `TrustedRandomAccess` (which already implies a finite length) then so can be `Take`.
```````@rustbot``````` label T-libs-impl
Move `sys_common::poison` to `sync::poison`
`sys_common` should not contain publicly exported types, only platform-independent abstractions on top of `sys`, which `sys_common::poison` is not. There is thus no reason for the module to not live under `sync`.
Part of #84187.
Remove duplicated fn(Box<[T]>) -> Vec<T>
`<[T]>::into_vec()` does the same thing as `Vec::from::<Box<[T]>>()`, so they can be implemented in terms of each other. This was the previous implementation of `Vec::from()`, but was changed in #78461. I'm not sure what the rationale was for that change, but it seems preferable to maintain a single implementation.
Improve `Iterator::by_ref` example
I split the example into two: one that fails to compile, and one that
works. I also made them identical except for the addition of `by_ref`
so we don't confuse readers with random differences.
cc `@steveklabnik,` who is the one that added the previous version of this example
Using `fuse` on an iterator that incorrectly implements
`FusedIterator` does not fuse the iterator. This commit adds a
note about this in the documentation of this method to increase
awareness about this potential issue (esp. when relying on fuse
in unsafe code).
Added CharIndices::offset function
The CharIndices iterator has a field internally called front_offset, that I think would be very useful to have access to.
You can already do something like ``char_indices.next().map(|(offset, _)| offset)``, but that is wordy, in addition to not handling the case where the iterator has ended, where you'd want the offset to be equal to the length.
I'm very new to the open source world and the rust repository, so I'm sorry if I missed a step or did something weird.
Improve rebuilding behaviour of BinaryHeap::retain.
This changes `BinaryHeap::retain` such that it doesn't always fully rebuild the heap, but only rebuilds the parts for which that's necessary.
This makes use of the fact that retain gives out `&T`s and not `&mut T`s.
Retaining every element or removing only elements at the end results in no rebuilding at all. Retaining most elements results in only reordering the elements that got moved (those after the first removed element), using the same logic as was already used for `append`.
cc `@KodrAus` `@sfackler` - We briefly discussed this possibility in the meeting last week while we talked about stabilization of this function (#71503).
Rollup of 7 pull requests
Successful merges:
- #84343 (Remove `ScopeTree::closure_tree`)
- #84376 (Uses flex to fix formatting of h1 at any width)
- #84377 (Followup to #83944)
- #84396 (Update LLVM submodule)
- #84402 (Move `sys_common::rwlock::StaticRWLock` etc. to `sys::unix::rwlock`)
- #84404 (Check for intrinsics before coercing to a function pointer)
- #84413 (Remove `sys::args::Args::inner_debug` and use `Debug` instead)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Remove `sys::args::Args::inner_debug` and use `Debug` instead
This removes the method `sys::args::Args::inner_debug` on all platforms and implements `Debug` for `Args` instead.
I believe this creates a more natural API for the different platforms under `sys`: export a type `Args: Debug + Iterator + ...` vs. `Args: Iterator + ...` and with a method `inner_debug`.
Move `sys_common::rwlock::StaticRWLock` etc. to `sys::unix::rwlock`
This moves `sys_common::rwlock::StaticRwLock`, `RWLockReadGuard` and `RWLockWriteGuard` to `sys::unix::rwlock`. They are already `#[cfg(unix)]` and don't need to be in `sys_common`.
Implement indexing slices with pairs of core::ops::Bound<usize>
Closes#49976.
I am not sure about code duplication between `check_range` and `into_maybe_range`. Should be former implemented in terms of the latter? Also this PR doesn't address code duplication between `impl SliceIndex for Range*`.
Format `Struct { .. }` on one line even with `{:#?}`.
The result of `debug_struct("A").finish_non_exhaustive()` before this change:
```
A {
..
}
```
And after this change:
```
A { .. }
```
If there's any fields, the result stays unchanged:
```
A {
field: value,
..
}
fix 'const-stable since' for NonZeroU*::new_unchecked
For the unsigned `NonZero` types, `new_unchecked` was const-stable from the start with https://github.com/rust-lang/rust/pull/50808. Fix the docs to accurately reflect that.
I think this `since` is also incorrect:
```rust
#[stable(feature = "from_nonzero", since = "1.31.0")]
impl From<$Ty> for $Int {
```
The signed nonzero types were only stabilized in 1.34, so that `From` impl certainly didn't exist before. But I had enough of digging through git histories after I figured out when `new_unchecked` became const-stable...^^
Replace `Void` in `sys` with never type
This PR replaces several occurrences in `sys` of the type `enum Void {}` with the Rust never type (`!`).
The name `Void` is unfortunate because in other languages (C etc.) it refers to a unit type, not an uninhabited type.
Note that the previous stabilization of the never type was reverted, however all uses here are implementation details and not publicly visible.
Move `sys::vxworks` code to `sys::unix`
Follow-up to #77666, `sys::vxworks` is almost identical to `sys::unix`, the only differences are the `rand`, `thread_local_dtor`, and `process` implementation. Since `vxworks` is `target_family = unix` anyway, there is no reason for the code not to live inside of `sys::unix` like all the other unix-OSes.
e41f378f82/compiler/rustc_target/src/spec/vxworks_base.rs (L12)
``@rustbot`` label: +T-libs-impl
Replace all `fmt.pad` with `debug_struct`
This replaces any occurrence of:
- `f.pad("X")` with `f.debug_struct("X").finish()`
- `f.pad("X { .. }")` with `f.debug_struct("X").finish_non_exhaustive()`
This is in line with existing formatting code such as
1255053067/library/std/src/sync/mpsc/mod.rs (L1470-L1475)
Add `Unsupported` to `std::io::ErrorKind`
I noticed a significant portion of the uses of `ErrorKind::Other` in std is for unsupported operations.
The notion that a specific operation is not available on a target (and will thus never succeed) seems semantically distinct enough from just "an unspecified error occurred", which is why I am proposing to add the variant `Unsupported` to `std::io::ErrorKind`.
**Implementation**:
The following variant will be added to `std::io::ErrorKind`:
```rust
/// This operation is unsupported on this platform.
Unsupported
```
`std::io::ErrorKind::Unsupported` is an error returned when a given operation is not supported on a platform, and will thus never succeed; there is no way for the software to recover. It will be used instead of `Other` where appropriate, e.g. on wasm for file and network operations.
`decode_error_kind` will be updated to decode operating system errors to `Unsupported`:
- Unix and VxWorks: `libc::ENOSYS`
- Windows: `c::ERROR_CALL_NOT_IMPLEMENTED`
- WASI: `wasi::ERRNO_NOSYS`
**Stability**:
This changes the kind of error returned by some functions on some platforms, which I think is not covered by the stability guarantees of the std? User code could depend on this behavior, expecting `ErrorKind::Other`, however the docs already mention:
> Errors that are `Other` now may move to a different or a new `ErrorKind` variant in the future. It is not recommended to match an error against `Other` and to expect any additional characteristics, e.g., a specific `Error::raw_os_error` return value.
The most recent variant added to `ErrorKind` was `UnexpectedEof` in `1.6.0` (almost 5 years ago), but `ErrorKind` is marked as `#[non_exhaustive]` and the docs warn about exhaustively matching on it, so adding a new variant per se should not be a breaking change.
The variant `Unsupported` itself could be marked as `#[unstable]`, however, because this PR also immediately uses this new variant and changes the errors returned by functions I'm inclined to agree with the others in this thread that the variant should be insta-stabilized.
Deprecate the core::raw / std::raw module
It only contains the `TraitObject` struct which exposes components of wide pointer. Pointer metadata APIs are designed to replace this: https://github.com/rust-lang/rust/issues/81513
Add some #[inline(always)] to arithmetic methods of integers
I tried to add it only to methods which return results of intrinsics and don't have any branching.
Branching could made performance of debug builds (`-Copt-level=0`) worse.
Main goal of changes is allowing wider optimizations in `-Copt-level=1`.
Closes: https://github.com/rust-lang/rust/issues/75598
r? `@nagisa`
No compiler changes as part of this -- just new unstable traits and impls thereof.
The goal here is to add the things that aren't going to break anything, to keep the feature implementation simpler in the next PR.
std: Add a variant of thread locals with const init
This commit adds a variant of the `thread_local!` macro as a new
`thread_local_const_init!` macro which requires that the initialization
expression is constant (e.g. could be stuck into a `const` if so
desired). This form of thread local allows for a more efficient
implementation of `LocalKey::with` both if the value has a destructor
and if it doesn't. If the value doesn't have a destructor then `with`
should desugar to exactly as-if you use `#[thread_local]` given
sufficient inlining.
The purpose of this new form of thread locals is to precisely be
equivalent to `#[thread_local]` on platforms where possible for values
which fit the bill (those without destructors). This should help close
the gap in performance between `thread_local!`, which is safe, relative
to `#[thread_local]`, which is not easy to use in a portable fashion.
This commit adds a variant of the `thread_local!` macro as a new
`thread_local_const_init!` macro which requires that the initialization
expression is constant (e.g. could be stuck into a `const` if so
desired). This form of thread local allows for a more efficient
implementation of `LocalKey::with` both if the value has a destructor
and if it doesn't. If the value doesn't have a destructor then `with`
should desugar to exactly as-if you use `#[thread_local]` given
sufficient inlining.
The purpose of this new form of thread locals is to precisely be
equivalent to `#[thread_local]` on platforms where possible for values
which fit the bill (those without destructors). This should help close
the gap in performance between `thread_local!`, which is safe, relative
to `#[thread_local]`, which is not easy to use in a portable fashion.
Fix join_paths error display.
On unix, the error from `join_paths` looked like this:
```
path segment contains separator `58`
```
This PR changes it to look like this:
```
path segment contains separator `:`
```
Move `std::sys_common::alloc` to new module `std::sys::common`
6b56603e35/library/std/src/sys_common/mod.rs (L7-L13)
It was my impression that the goal for `std::sys` has changed from extracting it into a separate crate to making std work with features. However the fact remains that there is a lot of interdependence between `sys` and `sys_common`, this is because `sys_common` contains two types of code:
- abstractions over the different platform implementations in `std::sys` (for example [`std::sys_common::mutex`](https://github.com/rust-lang/rust/blob/master/library/std/src/sys_common/mutex.rs))
- code shared between platforms (for example [`std::sys_common::alloc`](https://github.com/rust-lang/rust/blob/master/library/std/src/sys_common/alloc.rs))
This PR attempts to address this by adding a new module `common` to `std::sys` which will contain code shared between platforms, `alloc.rs` in this case but more can be moved over in the future.
add lint deref_nullptr detecting when a null ptr is dereferenced
fixes#83856
changelog: add lint that detect code like
```rust
unsafe {
&*core::ptr::null::<i32>()
};
unsafe {
addr_of!(std::ptr::null::<i32>())
};
let x: i32 = unsafe {*core::ptr::null()};
let x: i32 = unsafe {*core::ptr::null_mut()};
unsafe {*(0 as *const i32)};
unsafe {*(core::ptr::null() as *const i32)};
```
```
warning: Dereferencing a null pointer causes undefined behavior
--> src\main.rs:5:26
|
5 | let x: i32 = unsafe {*core::ptr::null()};
| ^^^^^^^^^^^^^^^^^^
| |
| a null pointer is dereferenced
| this code causes undefined behavior when executed
|
= note: `#[warn(deref_nullptr)]` on by default
```
Limitation:
It does not detect code like
```rust
const ZERO: usize = 0;
unsafe {*(ZERO as *const i32)};
```
or code where `0` is not directly a literal
Optimize for the common case where the input write size is less than the
buffer size. This slightly increases the cost for pathological write
patterns that commonly fill the buffer exactly, but if a client is doing
that frequently, they're already paying the cost of frequent flushing,
etc., so the cost is of this optimization to them is relatively small.
We use a Vec as our internal, constant-sized buffer, but the overhead of
using methods like `extend_from_slice` can be enormous, likely because
they don't get inlined, because `Vec` has to repeat bounds checks that
we've already done, and because it makes considerations for things like
reallocating, even though they should never happen.
Ensure that `write` and `write_all` can be inlined and that their
commonly executed fast paths can be as short as possible.
`write_vectored` would likely benefit from the same optimization, but I
omitted it because its implementation is more complex, and I don't have
a benchmark on hand to guide its optimization.
Improve code example for length comparison
Small fix/improvement: it's much safer to check that you're under the length of an array rather than chacking that you're equal to it. It's even more true in case you update the length of the array while iterating.
Stabilize `bufreader_seek_relative`
This PR marks `BufReader::seek_relative` as stable - the associated issue, #31100, has passed the final comment period without any issues, and from what I understand, the only thing left to stabilize this is to submit a PR marking the method as stable.
Closes#31100.
Turn old edition lint (anonymous-parameters) into warn-by-default on 2015
This makes `anonymous_parameters` <s>and `keyword_idents` </s>warn-by-default on the 2015 edition. I would also like to do this for `absolute_paths_not_starting_with_crate`, but I feel that case is slightly less clear-cut.
Note that this only affects code on the 2015 edition, such code is illegal in future editions anyway.
This was spurred by https://github.com/dtolnay/syn/issues/972: old edition syntax breaks tooling (like syn), and while the tooling should be free to find its balance on how much to support prior editions, it does seem like we should be nudging such code towards the newer edition, and we can do that by turning this Allow lint into a Warn.
In general, I feel like migration lints from an old edition should be made Warn after a year or so, and idiom lints for the new edition should be made Warn after a couple months.
cc `@m-ou-se,` this is for stuff from the 2015-2018 migration but you might be interested.
Update stdarch submodule (to before it switched to const generics)
https://github.com/rust-lang/rust/pull/83278#issuecomment-812389823: This unblocks #82539.
Major changes:
- More AVX-512 intrinsics.
- More ARM & AArch64 NEON intrinsics.
- Updated unstable WASM intrinsics to latest draft standards.
- std_detect is now a separate crate instead of a submodule of std.
I double-checked and the first use of const generics looks like 8d5017861e, which isn't included in this PR.
r? `@Amanieu`
This also includes a cherry-pick of
ec1461905b
and https://github.com/rust-lang/stdarch/pull/1108 to fix a build
failure.
It also adds a re-export of various macros to the crate root of libstd -
previously they would show up automatically because std_detect was defined
in the same crate.
clean up example on read_to_string
This is the same thing, but simpler.
This came out of a comment from a user: https://news.ycombinator.com/item?id=25318117 but rather than hide the signature of main, I think a `use` plus not including the `'static` makes more sense.
Bump libc dependency of std to 0.2.93
Update `libc` dependency of `std` to the latest version. That allows to consume the https://github.com/rust-lang/libc/pull/2131 fix and fix build for the `mipsel-unknown-linux-uclibc` target.
r? `@JohnTitor`
I tried to add it only to methods which return results of intrinsics and don't have any branching.
Branching could made performance of debug builds (`-Copt-level=0`) worse.
Main goal of changes is allowing wider optimizations in `-Copt-level=1`.
Closes: https://github.com/rust-lang/rust/issues/75598
Add note about reverting a workaround in the future
The root cause was fixed upstream in LLVM main. This adds a reminder to revert the workaround once the LLVM rustc depends on is new enough. Since I'm not sure how such optimizations get routed to LLVM releases, I used the conservative assumption that it will only show up with LLVM 13.
fix incorrect Box::from_raw_in doctest
Now that Miri can run doctests, I ran it on liballoc, and found exactly one problem: this test creates a `Box<u8>` to deallocate a 4-byte allocation!
Introduced by https://github.com/rust-lang/rust/pull/80310 so r? `@Manishearth` `@kennytm`
The root cause was fixed upstream in LLVM main. This adds a reminder to revert the workaround once the LLVM rustc depends on is new enough. Since I'm not sure how such optimizations get routed to LLVM releases, I used the conservative assumption that it will only show up with LLVM 13.
Stabilize `peekable_peek_mut`
Resolves#78302. Also adds some documentation on `std::iter::Iterator::peekable()` regarding the new method.
The feature was added in #77491 in Nov' 20, which is recently, but the feature seems reasonably small. Never did a stabilization-pr, excuse my ignorance if there is a protocol I'm not aware of.
Improve links in inline code in `core::pin`.
## Context
So I recently opened #80720. That PR uses HTML-based `<code>foo</code>` syntax in place of `` `foo` `` for some inline code. It looks like usage of `<code>` tags in doc comments is without precedent in the standard library, but the HTML-based syntax has an important advantage:
You can write something like
```
<code>[Box]<[Option]\<T>></code>
```
which becomes: <code>[Box]<[Option]\<T>></code>, whereas with ordinary backtick syntax, you cannot create links for a substring of an inline code block.
## Problem
I recalled (from my own experience) that a way to partially work around this limitation is to do something like
```
[`Box`]`<`[`Option`]`<T>>`
```
which looks like this: [`Box`]`<`[`Option`]`<T>>` _(admitted, it looks even worse on GitHub than in `rustdoc`’s CSS)_.
[Box]: https://doc.rust-lang.org/std/boxed/struct.Box.html "Box"
[`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html "Box"
[Option]: https://doc.rust-lang.org/std/option/enum.Option.html "Option"
[`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html "Option"
[Pin]: https://doc.rust-lang.org/std/pin/struct.Pin.html "Pin"
[&mut]: https://doc.rust-lang.org/std/primitive.reference.html "mutable reference"
So I searched the standard library and found that e.g. the [std::pin](https://doc.rust-lang.org/std/pin/index.html) module documentation uses this hack/workaround quite a bit, with types like <code>[Pin]<[Box]\<T>></code> or <code>[Pin]<[&mut] T>></code>. Although the way they look like in this sentence is what I would like them to look like, not what they currently look.
### Status Quo
Here’s a screenshot of what it currently looks like:

With a few HTML-style code blocks, we can fix all the spacing issues in the above screenshot that are due usage of this hack/workaround of putting multiple code blocks right next to each other being used.
### after d3915c555e:

There’s still a problem of inconsistency. Especially in a sentence such as
> A [`Pin<P>`][Pin] where `P: Deref` should be considered as a "`P`-style pointer" to _[...]_
looks weird with the variable `P` having different colors (and `Deref` has a different color from before where it was a link, too). Or compare the difference of <code>[Pin]<[Box]\<T>></code> vs [`Box<T>`][Box] where one time the variable is part of the link and the other time it isn’t.
_Note: Color differences show even **more strongly** when the ayu theme is used, while they are a bit less prominent in the light theme than they are in the dark theme, which is the one used for these screenshots._
This is why I’ve added the next commit
### after ceaeb249a3

pulling all the type parameters out of their links, and also the last commit with clearly visible changes
### after 87ac118ba3

where more links are added, removing e.g. the inconsistency with `Deref`’s color in e.g. `P: Deref` that I already mentioned above.
## Discussion
I am aware that this PR may very well be overkill. If for now only the first commit (plus the fix for the `Drop` link in e65385fbfa, the link titles 684edf7a70 as far as they apply, and a few of the line-break changes) are wanted, I can reduce this PR to just those changes. I personally find the rendered result with all these changes very nice though. On the other hand, all these `<code>` tags are not very nice in the source code, I’ll admit.
Perhaps alternative solutions could be preferred, such as `rustdoc` support for merging subsequent inline code blocks so that all the cases that currently use workarounds rendered as [`Box`]`<`[`Option`]`<T>>` automatically become <code>[Box]<[Option]\<T>></code> without any need for further changes. Even in this case, having a properly formatted, better looking example in the standard library docs could help motivate such a change to `rustdoc` by prodiving an example of the expected results and also the already existing alternative (i.e. using `<code>`). On the other hand, `` [`Box`]`<`[`Option`]`<T>>` `` isn’t particularly nice-looking source code either. I’m not even sure if I wouldn’t actually find the version `<code>[Box]<[Option]\<T>></code>` cleaner to read.
`@rustbot` modify labels: T-doc, T-rustdoc
Add more info for common trait resolution and async/await errors
* Suggest `Pin::new`/`Box::new`/`Arc::new`/`Box::pin` in more cases
* Point at `impl` and type defs introducing requirements on E0277
Stabilize cmp_min_max_by
I would like to propose cmp::{min_by, min_by_key, max_by, max_by_key}
for stabilization.
These are relatively simple and seemingly uncontroversial functions and
have been unchanged in unstable for a while now.
Closes: #64460
I would like to propose cmp::{min_by, min_by_key, max_by, max_by_key}
for stabilization.
These are relatively simple and seemingly uncontroversial functions and
have been unchanged in unstable for a while now.
Add strong_count mutation methods to Rc
The corresponding methods were stabilized on `Arc` in #79285 (tracking: #71983). This patch implements and stabilizes identical methods on the `Rc` types as well.
Use `#[inline(always)]` on trivial UnsafeCell methods
UnsafeCell is the standard building block for shared mutable data
structures. UnsafeCell should add zero overhead compared to using raw
pointers directly.
Some reports suggest that debug builds, or even builds at opt-level 1,
may not always be inlining its methods. Mark the methods as
`#[inline(always)]`, since once inlined the methods should result in no
actual code other than field accesses.
Bump bootstrap to 1.52 beta
This includes the standard bump, but also a workaround for new cargo behavior around clearing out the doc directory when the rustdoc version changes.
core: disable `ptr::swap_nonoverlapping_one`'s block optimization on SPIR-V.
SPIR-V primarily supports what it calls the "Logical addressing model" (and AFAIK for graphical shaders it's the only option), and what that implies is that there is no "memory" to uniformly address at some byte/word level, and that you can't really talk about values having a "raw representation" in terms of sequences of bytes. Therefore, the "block"-wise swapping optimization employed by `ptr::swap_nonoverlapping_one` (where a "block" is 32 bytes, currently), is fundamentally incompatible with SPIR-V "memory".
As such, [Rust-GPU](https://github.com/EmbarkStudios/rust-gpu/)'s `rustc_codegen_spirv` backend cannot currently allow the use of `ptr::swap_nonoverlapping_one` - but that comes at a great price, since it's the building block of `mem::{swap,replace}`, and those in turn are used by e.g. `Option::take` and `Range`'s `Iterator` implementation (the latter blocking the use of `for i in 0..n` loops).
There's 4 options I can see in terms of supporting `ptr::swap_nonoverlapping_one` in `rustc_codegen_spirv`:
* legalize the block-wise swap loop back into swapping whole values, for SPIR-V
* this is made borderline impossible by the fact that the size of the state "on the stack" is a block, and has to be expanded back to the appropriate size of the value being swapped, so in practice this would have to effectively pattern-match on the exact shape of the block-wise swapping algorithm, as a roundabout way of "patching `core::ptr` on the fly"
* (**this PR**) disable the block-wise swap optimization altogether when `#[cfg(target_arch = "spirv")`
* I've tested it and it does in fact allow compiling `for i in 0..n` loops, which was my primary motivation
* main downside IMO is the fact that `core` now acknowledges an out-of-tree backend
* as a counterpoint, any attempt to compile Rust to SPIR-V would run into this problem, one way or another
* only enable the block-wise swap optimization on targets where it's been empirically proven to be an improvement
* would avoid any surprises in terms of potentially-broken/inefficient codegen, in general
* however, it may be universally applicable (thanks to caches), even if the optimal block size could differ
* move low-level swapping into an intrinsic, where the backend can choose any optimization approach it wants
* this also has an impact on MIR optimizations (cc ``@rust-lang/wg-mir-opt)`` - which currently cannot hope to make sense of e.g. `Option::take` despite it being effectively `_0 = *_1;` `*_1 = None;` `return;`
* long-term this is my preferred approach, and I can start working on it if that's desired, but I wanted to confirm that this swapping optimization is the final blocker for [Rust-GPU](https://github.com/EmbarkStudios/rust-gpu/) supporting e.g. range `for` loops
r? ``@nagisa`` cc ``@rust-lang/libs``
UnsafeCell is the standard building block for shared mutable data
structures. UnsafeCell should add zero overhead compared to using raw
pointers directly.
Some reports suggest that debug builds, or even builds at opt-level 1,
may not always be inlining its methods. Mark the methods as
`#[inline(always)]`, since once inlined the methods should result in no
actual code other than field accesses.
BTree: move blocks around in node.rs
Without changing any names or implementation, reorder some members:
- Move down the ones defined long ago on the demised `struct Root`, to below the definition of their current host `struct NodeRef`.
- Move up some defined on `struct NodeRef` that are interspersed with those defined on `struct Handle`.
- Move up the `correct_…` methods squeezed between the two flavours of `push`.
- Move the unchecked static downcasts (`cast_to_…`) after the upcasts (`forget_`) and the (weirdly named) dynamic downcasts (`force`).
r? ````@Mark-Simulacrum````
BTree: no longer search arrays twice to check Ord
A possible addition to / partial replacement of #83147: no longer linearly search the upper bound of a range in the initial portion of the keys we already know are below the lower bound.
- Should be faster: fewer key comparisons at the cost of some instructions dealing with offsets
- Makes code a little more complicated.
- No longer detects ill-defined `Ord` implementations, but that wasn't a publicised feature, and was quite incomplete, and was only done in the `range` and `range_mut` methods.
r? `@Mark-Simulacrum`
Document "standard" conventions for error messages
These are currently documented in the API guidelines:
https://rust-lang.github.io/api-guidelines/interoperability.html#error-types-are-meaningful-and-well-behaved-c-good-err
I think it makes sense to uplift this guideline (in a milder form) into
std docs. Printing and producing errors is something that even
non-expert users do frequently, so it is useful to give at least some
indication of what a typical error message looks like.
Fix stack overflow detection on FreeBSD 11.1+
Beginning with FreeBSD 10.4 and 11.1, there is one guard page by
default. And the stack autoresizes, so if Rust allocates its own guard
page, then FreeBSD's will simply move up one page. The best solution is
to just use the OS's guard page.
Fix double-drop in `Vec::from_iter(vec.into_iter())` specialization when items drop during panic
This fixes the double-drop but it leaves a behavioral difference compared to the default implementation intact: In the default implementation the source and the destination vec are separate objects, so they get dropped separately. Here they share an allocation and the latter only exists as a pointer into the former. So if dropping the former panics then this fix will leak more items than the default implementation would. Is this acceptable or should the specialization also mimic the default implementation's drops-during-panic behavior?
Fixes#83618
`@rustbot` label T-libs-impl
Rework `std::sys::windows::alloc`
I came across https://github.com/rust-lang/rust/pull/76676#discussion_r488729990, which points out that there was unsound code in the Windows alloc code, creating a &mut to possibly uninitialized memory. I reworked the code so that that particular issue does not occur anymore, and started adding more documentation and safety comments.
Full list of changes:
- moved and documented the relevant Windows Heap API functions
- refactor `allocate_with_flags` to `allocate` (and remove the other helper functions), which now takes just a `bool` if the memory should be zeroed
- add checks for if `GetProcessHeap` returned null
- add a test that checks if the size and alignment of a `Header` are indeed <= `MIN_ALIGN`
- add `#![deny(unsafe_op_in_unsafe_fn)]` and the necessary unsafe blocks with safety comments
I feel like I may have overdone the documenting, the unsoundness fix is the most important part; I could spit this PR up in separate parts.
Fix comment typo in once.rs
I believe I came across a minor typo in a comment. I am not particularly familiar with this part of the codebase, but I have read the surrounding code as well as the referenced `park` and `unpark` functions, and I believe my proposed change is true to the intended meaning of the comment.
I intentionally tried to keep the change as minimal as possible. If I have the maintainers' permission, I'd also love to add a comma to improve readability as follows: `Luckily ``park`` comes with the guarantee that if it got an ``unpark`` just before on an unparked thread, it does not park.`
Rename `#[doc(spotlight)]` to `#[doc(notable_trait)]`
Fixes#80936.
"spotlight" is not a very specific or self-explaining name.
Additionally, the dialog that it triggers is called "Notable traits".
So, "notable trait" is a better name.
* Rename `#[doc(spotlight)]` to `#[doc(notable_trait)]`
* Rename `#![feature(doc_spotlight)]` to `#![feature(doc_notable_trait)]`
* Update documentation
* Improve documentation
r? `@Manishearth`
Beginning with FreeBSD 10.4 and 11.1, there is one guard page by
default. And the stack autoresizes, so if Rust allocates its own guard
page, then FreeBSD's will simply move up one page. The best solution is
to just use the OS's guard page.
panic early when `TrustedLen` indicates a `length > usize::MAX`
Changes `TrustedLen` specializations to immediately panic when `size_hint().1 == None`.
As far as I can tell this is ~not a change~ a minimal change in observable behavior for anything except ZSTs because the fallback path would go through `extend_desugared()` which tries to `reserve(lower_bound)` which already is `usize::MAX` and that would also lead to a panic. Before it might have popped somewhere between zero and a few elements from the iterator before panicking while it now panics immediately.
Overall this should reduce codegen by eliminating the fallback paths.
While looking into the `with_capacity()` behavior I also noticed that its documentation didn't have a *Panics* section, so I added that.
Disallow octal format in Ipv4 string
In its original specification, leading zero in Ipv4 string is interpreted
as octal literals. So a IP address 0127.0.0.1 actually means 87.0.0.1.
This confusion can lead to many security vulnerabilities. Therefore, in
[IETF RFC 6943], it suggests to disallow octal/hexadecimal format in Ipv4
string all together.
Existing implementation already disallows hexadecimal numbers. This commit
makes Parser reject octal numbers.
Fixes#83648.
[IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1
Improve pointer arithmetic docs
* Add slightly more detailed definition of "allocated object" to the module docs, and link it from everywhere.
* Clarify the "remains attached" wording a bit (at least I hope this is clearer).
* Remove the sentence about using integer arithmetic; this seems to confuse people even if it is technically correct.
As usual, the edit needs to be done in a dozen places to remain consistent, I hope I got them all.
Clean up Vec's benchmarks
The Vec benchmarks need a lot of love. I sort of noticed this in https://github.com/rust-lang/rust/pull/83357 but the overall situation is much less awesome than I thought at the time. The first commit just removes a lot of asserts and does a touch of other cleanup.
A number of these benchmarks are poorly-named. For example, `bench_map_fast` is not in fact fast, `bench_rev_1` and `bench_rev_2` are vague, `bench_in_place_zip_iter_mut` doesn't call `zip`, `bench_in_place*` don't do anything in-place... Should I fix these, or is there tooling that depend on the names not changing?
I've also noticed that `bench_rev_1` and `bench_rev_2` are remarkably fragile. It looks like poking other code in `Vec` can cause the codegen of this benchmark to switch to a version that has almost exactly half its current throughput and I have absolutely no idea why.
Here's the fast version:
```asm
0.69 │110: movdqu -0x20(%rbx,%rdx,4),%xmm0
1.76 │ movdqu -0x10(%rbx,%rdx,4),%xmm1
0.71 │ pshufd $0x1b,%xmm1,%xmm1
0.60 │ pshufd $0x1b,%xmm0,%xmm0
3.68 │ movdqu %xmm1,-0x30(%rcx)
14.36 │ movdqu %xmm0,-0x20(%rcx)
13.88 │ movdqu -0x40(%rbx,%rdx,4),%xmm0
6.64 │ movdqu -0x30(%rbx,%rdx,4),%xmm1
0.76 │ pshufd $0x1b,%xmm1,%xmm1
0.77 │ pshufd $0x1b,%xmm0,%xmm0
1.87 │ movdqu %xmm1,-0x10(%rcx)
13.01 │ movdqu %xmm0,(%rcx)
38.81 │ add $0x40,%rcx
0.92 │ add $0xfffffffffffffff0,%rdx
1.22 │ ↑ jne 110
```
And the slow one:
```asm
0.42 │9a880: movdqa %xmm2,%xmm1
4.03 │9a884: movq -0x8(%rbx,%rsi,4),%xmm4
8.49 │9a88a: pshufd $0xe1,%xmm4,%xmm4
2.58 │9a88f: movq -0x10(%rbx,%rsi,4),%xmm5
7.02 │9a895: pshufd $0xe1,%xmm5,%xmm5
4.79 │9a89a: punpcklqdq %xmm5,%xmm4
5.77 │9a89e: movdqu %xmm4,-0x18(%rdx)
15.74 │9a8a3: movq -0x18(%rbx,%rsi,4),%xmm4
3.91 │9a8a9: pshufd $0xe1,%xmm4,%xmm4
5.04 │9a8ae: movq -0x20(%rbx,%rsi,4),%xmm5
5.29 │9a8b4: pshufd $0xe1,%xmm5,%xmm5
4.60 │9a8b9: punpcklqdq %xmm5,%xmm4
9.81 │9a8bd: movdqu %xmm4,-0x8(%rdx)
11.05 │9a8c2: paddq %xmm3,%xmm0
0.86 │9a8c6: paddq %xmm3,%xmm2
5.89 │9a8ca: add $0x20,%rdx
0.12 │9a8ce: add $0xfffffffffffffff8,%rsi
1.16 │9a8d2: add $0x2,%rdi
2.96 │9a8d6: → jne 9a880 <<alloc::vec::Vec<T,A> as core::iter::traits::collect::Extend<&T>>::extend+0xd0>
```
In its original specification, leading zero in Ipv4 string is interpreted
as octal literals. So a IP address 0127.0.0.1 actually means 87.0.0.1.
This confusion can lead to many security vulnerabilities. Therefore, in
[IETF RFC 6943], it suggests to disallow octal/hexadecimal format in Ipv4
string all together.
Existing implementation already disallows hexadecimal numbers. This commit
makes Parser reject octal numbers.
Fixes#83648.
[IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1
unix: Fix feature(unix_socket_ancillary_data) on macos and other BSDs
This adds support for CMSG handling on macOS and fixes it on OpenBSD and possibly other BSDs.
When traversing the CMSG list, the previous code had an exception for Android where the next element after the last pointer could point to the first pointer instead of NULL. This is actually not specific to Android: the `libc::CMSG_NXTHDR` implementation for Linux and emscripten have a special case to return NULL when the length of the previous element is zero; most other implementations simply return the previous element plus a zero offset in this case.
This MR makes the check non-optional which fixes CMSG handling and a possible endless loop on such systems; tested with file descriptor passing on OpenBSD, Linux, and macOS.
This MR additionally adds `SocketAncillary::is_empty` because clippy is right that it should be added.
This belongs to the `feature(unix_socket_ancillary_data)` tracking issue: https://github.com/rust-lang/rust/issues/76915
r? `@joshtriplett`
escape_ascii take 2
The previous PR, #73111 was closed for inactivity; since I've had trouble in the past reopening closed PRs, I'm just making a new one.
I'm still running the tests locally but figured I'd open the PR in the meantime. Will fix whatever errors show up so we don't have to wait again for this.
r? ``@m-ou-se``
alloc: Added `as_slice` method to `BinaryHeap` collection
I initially asked about whether it is useful addition on https://internals.rust-lang.org/t/should-i-add-as-slice-method-to-binaryheap/13816, and it seems there were no objections, so went ahead with this PR.
> There is [`BinaryHeap::into_vec`](https://doc.rust-lang.org/std/collections/struct.BinaryHeap.html#method.into_vec), but it consumes the value. I wonder if there is API design limitation that should be taken into account. Implementation-wise, the inner buffer is just a Vec, so it is trivial to expose as_slice from it.
Please, guide me through if I need to add tests or something else.
UPD: Tracking issue #83659
The `Unpin` bound was originally added in #56939 following the
recommendation of @withoutboats in
https://github.com/rust-lang/rust/issues/55766#issue-378417538
That comment does not give explicit justification for why the bound
should be added. The relevant context was:
> [ ] Remove `impl<P> Unpin for Pin<P>`
>
> This impl is not justified by our standard justification for unpin
> impls: there is no pointer direction between `Pin<P>` and `P`. Its
> usefulness is covered by the impls for pointers themselves.
>
> This futures impl (link to the impl changed in this PR) will need to
> change to add a `P: Unpin` bound.
The decision to remove the unconditional impl of `Unpin for Pin` is
sound (these days there is just an auto-impl for when `P: Unpin`). But,
I think the decision to also add the `Unpin` bound for `impl Future` may
have been unnecessary. Or if that's not the case, I'd be very interested
to have the argument for why written down somewhere. The bound _appears_
to not be needed, since the presence of a `Pin<P>` should indicate that
it's safe to project to `Pin<&mut P::Target>` just like for
`Pin::as_mut`.
may not -> might not
may not -> might not
"may not" has two possible meanings:
1. A command: "You may not stay up past your bedtime."
2. A fact that's only sometimes true: "Some cities may not have bike lanes."
In some cases, the meaning is ambiguous: "Some cars may not have snow
tires." (do the cars *happen* to not have snow tires, or is it
physically impossible for them to have snow tires?)
This changes places where the standard library uses the "description of
fact" meaning to say "might not" instead.
This is just `std::vec` for now - if you think this is a good idea I can
convert the rest of the standard library.
Adjust documentation links for slice::make_ascii_*case
The documentation for the functions `slice::to_ascii_lowercase` and `slice::to_ascii_uppercase` contain the suggestion
> To lowercase the value in-place, use `make_ascii_lowercase`
however the link to the suggested method takes you to the page for `u8`, rather than the method of that name on the same page.
Instruct LLVM that binary_search returns a valid index
This allows removing bound checks when the return value of `binary_search` is used to index into the slice it was call on. I also added a codegen test for this, not sure if it's the right thing to do (I didn't find anything on the dev guide), but it felt so.
"may not" has two possible meanings:
1. A command: "You may not stay up past your bedtime."
2. A fact that's only sometimes true: "Some cities may not have bike lanes."
In some cases, the meaning is ambiguous: "Some cars may not have snow
tires." (do the cars *happen* to not have snow tires, or is it
physically impossible for them to have snow tires?)
This changes places where the standard library uses the "description of
fact" meaning to say "might not" instead.
This is just `std::vec` for now - if you think this is a good idea I can
convert the rest of the standard library.
Improve fs error open_from unix
Consistency for #79399
Suggested by JohnTitor
r? `@JohnTitor`
Not user if the error is too long now, do we handle long errors well?
Add function core::iter::zip
This makes it a little easier to `zip` iterators:
```rust
for (x, y) in zip(xs, ys) {}
// vs.
for (x, y) in xs.into_iter().zip(ys) {}
```
You can `zip(&mut xs, &ys)` for the conventional `iter_mut()` and
`iter()`, respectively. This can also support arbitrary nesting, where
it's easier to see the item layout than with arbitrary `zip` chains:
```rust
for ((x, y), z) in zip(zip(xs, ys), zs) {}
for (x, (y, z)) in zip(xs, zip(ys, zs)) {}
// vs.
for ((x, y), z) in xs.into_iter().zip(ys).zip(xz) {}
for (x, (y, z)) in xs.into_iter().zip((ys.into_iter().zip(xz)) {}
```
It may also format more nicely, especially when the first iterator is a
longer chain of methods -- for example:
```rust
iter::zip(
trait_ref.substs.types().skip(1),
impl_trait_ref.substs.types().skip(1),
)
// vs.
trait_ref
.substs
.types()
.skip(1)
.zip(impl_trait_ref.substs.types().skip(1))
```
This replaces the tuple-pair `IntoIterator` in #78204.
There is prior art for the utility of this in [`itertools::zip`].
[`itertools::zip`]: https://docs.rs/itertools/0.10.0/itertools/fn.zip.html
update array missing `IntoIterator` msg
fixes#82602
r? ```@estebank``` do you know whether we can use the expr span in `rustc_on_unimplemented`? The label isn't too great rn
make unaligned_references future-incompat lint warn-by-default
and also remove the safe_packed_borrows lint that it replaces.
`std::ptr::addr_of!` has hit beta now and will hit stable in a month, so I propose we start fixing https://github.com/rust-lang/rust/issues/27060 for real: creating a reference to a field of a packed struct needs to eventually become a hard error; this PR makes it a warn-by-default future-incompat lint. (The lint already existed, this just raises its default level.) At the same time I removed the corresponding code from unsafety checking; really there's no reason an `unsafe` block should make any difference here.
For references to packed fields outside `unsafe` blocks, this means `unaligned_refereces` replaces the previous `safe_packed_borrows` warning with a link to https://github.com/rust-lang/rust/issues/82523 (and no more talk about unsafe blocks making any difference). So behavior barely changes, the warning is just worded differently. For references to packed fields inside `unsafe` blocks, this PR shows a new future-incompat warning.
Closes https://github.com/rust-lang/rust/issues/46043 because that lint no longer exists.
Improve Debug implementations of Mutex and RwLock.
This improves the Debug implementations of Mutex and RwLock.
They now show the poison flag and use debug_non_exhaustive. (See #67364.)
Derive Debug for io::Chain instead of manually implementing it.
This derives Debug for io::Chain instead of manually implementing it.
The manual implementation has the same bounds, so I don't think there's any reason for a manual implementation. The names used in the derive implementation are even nicer (`first`/`second`) than the manual implementation (`t`/`u`), and include the `done_first` field too.
Fix Debug implementation for RwLock{Read,Write}Guard.
This would attempt to print the Debug representation of the lock that the guard has locked, which will try to lock again, fail, and just print `"<locked>"` unhelpfully.
After this change, this just prints the contents of the mutex, like the other smart pointers (and MutexGuard) do.
MutexGuard had this problem too: https://github.com/rust-lang/rust/issues/57702
ExitStatus: print "exit status: {}" rather than "exit code: {}" on unix
Proper Unix terminology is "exit status" (vs "wait status"). "exit
code" is imprecise on Unix and therefore unclear. (As far as I can
tell, "exit code" is correct terminology on Windows.)
This new wording is unfortunately inconsistent with the identifier
names in the Rust stdlib.
It is the identifier names that are wrong, as discussed at length in eg
https://doc.rust-lang.org/nightly/std/process/struct.ExitStatus.htmlhttps://doc.rust-lang.org/nightly/std/os/unix/process/trait.ExitStatusExt.html
Unfortunately for API stability reasons it would be a lot of work, and
a lot of disruption, to change the names in the stdlib (eg to rename
`std::process::ExitStatus` to `std::process::ChildStatus` or
something), but we should fix the message output. Many (probably
most) readers of these messages about exit statuses will be users and
system administrators, not programmers, who won't even know that Rust
has this wrong terminology.
So I think the right thing is to fix the documentation (as I have
already done) and, now, the terminology in the implementation.
This is a user-visible change to the behaviour of all Rust programs
which run Unix subprocesses. Hopefully no-one is matching against the
exit status string, except perhaps in tests.
Generalize and inline slice::fill specializations
This makes the memset specialization applicable to more types. And since the code now lives in a generic method it is also eligible for cross-crate inlining which should fix#83235
The manual implementation has the same bounds, so I don't think there's
any reason for a manual implementation. The names used in the derive
implementation are even nicer (`first`/`second`) than the manual
implementation (`t`/`u`), and include the `done_first` field too.
This would attempt to print the Debug representation of the lock that
the guard has locked, which will try to lock again, fail, and just print
"<locked>" unhelpfully.
After this change, this just prints the contents of the mutex, like the
other smart pointers (and MutexGuard) do.
Add IEEE 754 compliant fmt/parse of -0, infinity, NaN
This pull request improves the Rust float formatting/parsing libraries to comply with IEEE 754's formatting expectations around certain special values, namely signed zero, the infinities, and NaN. It also adds IEEE 754 compliance tests that, while less stringent in certain places than many of the existing flt2dec/dec2flt capability tests, are intended to serve as the beginning of a roadmap to future compliance with the standard. Some relevant documentation is also adjusted with clarifying remarks.
This PR follows from discussion in https://github.com/rust-lang/rfcs/issues/1074, and closes#24623.
The most controversial change here is likely to be that -0 is now printed as -0. Allow me to explain: While there appears to be community support for an opt-in toggle of printing floats as if they exist in the naively expected domain of numbers, i.e. not the extended reals (where floats live), IEEE 754-2019 is clear that a float converted to a string should be capable of being transformed into the original floating point bit-pattern when it satisfies certain conditions (namely, when it is an actual numeric value i.e. not a NaN and the original and destination float width are the same). -0 is given special attention here as a value that should have its sign preserved. In addition, the vast majority of other programming languages not only output `-0` but output `-0.0` here.
While IEEE 754 offers a broad leeway in how to handle producing what it calls a "decimal character sequence", it is clear that the operations a language provides should be capable of round tripping, and it is confusing to advertise the f32 and f64 types as binary32 and binary64 yet have the most basic way of producing a string and then reading it back into a floating point number be non-conformant with the standard. Further, existing documentation suggested that e.g. -0 would be printed with -0 regardless of the presence of the `+` fmt character, but it prints "+0" instead if given such (which was what led to the opening of #24623).
There are other parsing and formatting issues for floating point numbers which prevent Rust from complying with the standard, as well as other well-documented challenges on the arithmetic level, but I hope that this can be the beginning of motion towards solving those challenges.
Document that the SocketAddr memory representation is not stable
Intended to help out with #78802. Work has been put into finding and fixing code that assumes the memory layout of `SocketAddrV4` and `SocketAddrV6`. But it turns out there are cases where new code continues to make the same assumption ([example](96927dc2b7 (diff-917db3d8ca6f862ebf42726b23c72a12b35e584e497ebdb24e474348d7c6ffb6R610-R621))).
The memory layout of a type in `std` is never part of the public API. Unless explicitly stated I guess. But since that is invalidly relied upon by a considerable amount of code for these particular types, it might make sense to explicitly document this. This can be temporary. Once #78802 lands it does not make sense to rely on the layout any longer, and this documentation can also be removed.
Make # pretty print format easier to discover
# Rationale:
I use (cargo cult?) three formats in rust: `{}`, debug `{:?}`, and pretty-print debug `{:#?}`. I discovered `{:#?}` in some blog post or guide when I started working in Rust. While `#` is documented I think it is hard to discover. So taking the good advice of ```@carols10cents``` I am trying to improve the docs with a PR
As a reminder "pretty print" means that where `{:?}` will print something like
```
foo: { b1: 1, b2: 2}
```
`{:#?}` will prints something like
```
foo {
b1: 1
b2: 3
}
```
# Changes
Add an example to `fmt` to try and make it easier to discover `#`
This adds support for CMSG handling on macOS and fixes it on OpenBSD
and other BSDs.
When traversing the CMSG list, the previous code had an exception for
Android where the next element after the last pointer could point to
the first pointer instead of NULL. This is actually not specific to
Android: the `libc::CMSG_NXTHDR` implementation for Linux and
emscripten have a special case to return NULL when the length of the
previous element is zero; most other implementations simply return the
previous element plus a zero offset in this case.
This MR additionally adds `SocketAncillary::is_empty` because clippy
is right that it should be added.
This makes it a little easier to `zip` iterators:
```rust
for (x, y) in zip(xs, ys) {}
// vs.
for (x, y) in xs.into_iter().zip(ys) {}
```
You can `zip(&mut xs, &ys)` for the conventional `iter_mut()` and
`iter()`, respectively. This can also support arbitrary nesting, where
it's easier to see the item layout than with arbitrary `zip` chains:
```rust
for ((x, y), z) in zip(zip(xs, ys), zs) {}
for (x, (y, z)) in zip(xs, zip(ys, zs)) {}
// vs.
for ((x, y), z) in xs.into_iter().zip(ys).zip(xz) {}
for (x, (y, z)) in xs.into_iter().zip((ys.into_iter().zip(xz)) {}
```
It may also format more nicely, especially when the first iterator is a
longer chain of methods -- for example:
```rust
iter::zip(
trait_ref.substs.types().skip(1),
impl_trait_ref.substs.types().skip(1),
)
// vs.
trait_ref
.substs
.types()
.skip(1)
.zip(impl_trait_ref.substs.types().skip(1))
```
This replaces the tuple-pair `IntoIterator` in rust-lang/rust#78204.
There is prior art for the utility of this in [`itertools::zip`].
[`itertools::zip`]: https://docs.rs/itertools/0.10.0/itertools/fn.zip.html
Fixes#83046
The program
fn main() {
println!("{:?}", '"');
println!("{:?}", "'");
}
would previously print
'\"'
"\'"
With this patch it now prints:
'"'
"'"
Proper Unix terminology is "exit status" (vs "wait status"). "exit
code" is imprecise on Unix and therefore unclear. (As far as I can
tell, "exit code" is correct terminology on Windows.)
This new wording is unfortunately inconsistent with the identifier
names in the Rust stdlib.
It is the identifier names that are wrong, as discussed at length in eg
https://doc.rust-lang.org/nightly/std/process/struct.ExitStatus.htmlhttps://doc.rust-lang.org/nightly/std/os/unix/process/trait.ExitStatusExt.html
Unfortunately for API stability reasons it would be a lot of work, and
a lot of disruption, to change the names in the stdlib (eg to rename
`std::process::ExitStatus` to `std::process::ChildStatus` or
something), but we should fix the message output. Many (probably
most) readers of these messages about exit statuses will be users and
system administrators, not programmers, who won't even know that Rust
has this wrong terminology.
So I think the right thing is to fix the documentation (as I have
already done) and, now, the terminology in the implementation.
This is a user-visible change to the behaviour of all Rust programs
which run Unix subprocesses. Hopefully no-one is matching against the
exit status string, except perhaps in tests.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Many of the Vec benchmarks assert what values should be produced by the
benchmarked code. In some cases, these asserts dominate the runtime of
the benchmarks they are in, causing the benchmarks to understate the
impact of an optimization or regression.
Add Result::into_err where the Ok variant is the never type
Equivalent of #66045 but for the inverse situation where `T: Into<!>` rather than `E: Into<!>`.
I'm using the same feature gate name. I can't see why one of these methods would be OK to stabilize but not the other.
Tracking issue: #61695
Remove Option::{unwrap_none, expect_none}.
This removes `Option::unwrap_none` and `Option::expect_none` since we're not going to stabilize them, see https://github.com/rust-lang/rust/issues/62633.
Closes#62633
stabilize debug_non_exhaustive
tracking issue: https://github.com/rust-lang/rust/issues/67364
but it is still an open question whether the other `Debug*` struct's should have a similar method. I would guess that would best be put underneath a new feature gate, as this one seems uncontroversial enough to stabilize as is
Expose str::SplitInclusive in alloc and therefore in std
This seems to have been omitted from the beginning when this feature was first introduced in 86bf96291d. Most users won't need to name this type which is probably why this wasn't noticed in the meantime.
See #83372 for a different but related bug.
### Notes for reviewers
I think I have got this right but TBH I am not very familiar with the relationship between core and std and so on. <strike>I also haven't don't any kind of test (not even a build) yet. I will do a local docs build to see that the type now appears in the std docs.</strike> I did a local docs build and it has made this type appear as `std::str::SplitInclusive` as expected
The linkification of the return value from `str::split_inclusive` teleports me to the online url for `core::str::SplitInclusive`. I think this may be a rustdoc anomaly (similar to #79630 maybe) but I am not sure. Perhaps it means I haven't done the `std` -> `core` referrence correctly.
I made this insta-stable since it seems like simply a bug. Please LMK if that is not right. *(edited to add:)* In particular, IDK how this ought to relate to the (?)current release process.
Add internal io::Error::new_const to avoid allocations.
This makes it possible to have a io::Error containing a message with zero allocations, and uses that everywhere to avoid the *three* allocations involved in `io::Error::new(kind, "message")`.
The function signature isn't perfect, because it needs a reference to the `&str`. So for now, this is just a `pub(crate)` function. Later, we'll be able to use `fn new_const<MSG: &'static str>(kind: ErrorKind)` to make that a bit better. (Then we'll also be able to use some ZST trickery if that would result in more efficient code.)
See https://github.com/rust-lang/rust/issues/83352
This seems to have been omitted from the beginning when this feature
was first introduced in 86bf96291d.
Most users won't need to name this type which is probably why this
wasn't noticed in the meantime.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Add `debug-refcell` feature to libcore
See https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Attaching.20backtraces.20to.20RefCell/near/226273614
for some background discussion
This PR adds a new off-by-default feature `debug-refcell` to libcore.
When enabled, this feature stores additional debugging information in
`RefCell`. This information is included in the panic message when
`borrow()` or `borrow_mut()` panics, to make it easier to track down the
source of the issue.
Currently, we store the caller location for the earliest active borrow.
This has a number of advantages:
* There is only a constant amount of overhead per `RefCell`
* We don't need any heap memory, so it can easily be implemented in core
* Since we are storing the *earliest* active borrow, we don't need any
extra logic in the `Drop` implementation for `Ref` and `RefMut`
Limitations:
* We only store the caller location, not a full `Backtrace`. Until
we get support for `Backtrace` in libcore, this is the best tha we can
do.
* The captured location is only displayed when `borrow()` or
`borrow_mut()` panics. If a crate calls `try_borrow().unwrap()`
or `try_borrow_mut().unwrap()`, this extra information will be lost.
To make testing easier, I've enabled the `debug-refcell` feature by
default. I'm not sure how to write a test for this feature - we would
need to rebuild core from the test framework, and create a separate
sysroot.
Since this feature will be off-by-default, users will need to use
`xargo` or `cargo -Z build-std` to enable this feature. For users using
a prebuilt standard library, this feature will be disabled with zero
overhead.
I've created a simple test program:
```rust
use std::cell::RefCell;
fn main() {
let _ = std::panic::catch_unwind(|| {
let val = RefCell::new(true);
let _first = val.borrow();
let _second = val.borrow();
let _third = val.borrow_mut();
});
let _ = std::panic::catch_unwind(|| {
let val = RefCell::new(true);
let first = val.borrow_mut();
drop(first);
let _second = val.borrow_mut();
let _thid = val.borrow();
});
}
```
which produces the following output:
```
thread 'main' panicked at 'already borrowed: BorrowMutError at refcell_test.rs:6:26', refcell_test.rs:8:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'already mutably borrowed: BorrowError at refcell_test.rs:16:27', refcell_test.rs:18:25
```
"semantic equivalence" is too strong a phrasing here, which is why
actually explaining what kind of circumstances might produce a -0
was chosen instead.
This commit removes the previous mechanism of differentiating
between "Debug" and "Display" formattings for the sign of -0 so as
to comply with the IEEE 754 standard's requirements on external
character sequences preserving various attributes of a floating
point representation.
In addition, numerous tests are fixed.
See https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Attaching.20backtraces.20to.20RefCell/near/226273614
for some background discussion
This PR adds a new off-by-default feature `debug-refcell` to libcore.
When enabled, this feature stores additional debugging information in
`RefCell`. This information is included in the panic message when
`borrow()` or `borrow_mut()` panics, to make it easier to track down the
source of the issue.
Currently, we store the caller location for the earliest active borrow.
This has a number of advantages:
* There is only a constant amount of overhead per `RefCell`
* We don't need any heap memory, so it can easily be implemented in core
* Since we are storing the *earliest* active borrow, we don't need any
extra logic in the `Drop` implementation for `Ref` and `RefMut`
Limitations:
* We only store the caller location, not a full `Backtrace`. Until
we get support for `Backtrace` in libcore, this is the best tha we can
do.
* The captured location is only displayed when `borrow()` or
`borrow_mut()` panics. If a crate calls `try_borrow().unwrap()`
or `try_borrow_mut().unwrap()`, this extra information will be lost.
To make testing easier, I've enabled the `debug-refcell` feature by
default. I'm not sure how to write a test for this feature - we would
need to rebuild core from the test framework, and create a separate
sysroot.
Since this feature will be off-by-default, users will need to use
`xargo` or `cargo -Z build-std` to enable this feature. For users using
a prebuilt standard library, this feature will be disabled with zero
overhead.
I've created a simple test program:
```rust
use std::cell::RefCell;
fn main() {
let _ = std::panic::catch_unwind(|| {
let val = RefCell::new(true);
let _first = val.borrow();
let _second = val.borrow();
let _third = val.borrow_mut();
});
let _ = std::panic::catch_unwind(|| {
let val = RefCell::new(true);
let first = val.borrow_mut();
drop(first);
let _second = val.borrow_mut();
let _thid = val.borrow();
});
}
```
which produces the following output:
```
thread 'main' panicked at 'already borrowed: BorrowMutError { location: Location { file: "refcell_test.rs", line: 6, col: 26 } }', refcell_test.rs:8:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'already mutably borrowed: BorrowError { location: Location { file: "refcell_test.rs", line: 16, col: 27 } }', refcell_test.rs:18:25
```
Clarify non-exact length in the Iterator::take documentation
There's an example which demonstrates incomplete length case, but it'd be best to explain it right from the start.
Document panicking cases for integer division and remainder
This PR documents the cases when integer division and remainder operations panic. These operations panic in two cases: division by zero and overflow.
It's surprising that these operations always panic on overflow, unlike most other arithmetic operations, which panic on overflow only when `debug_assertions` is enabled. The panic on overflow for the remainder is also surprising because a return value of `0` would be reasonable in this case. ("Overflow" occurs only for `MIN % -1`.) Since the panics on overflow are somewhat surprising, they should be documented.
I guess it's worth asking: is panic on overflow (even when `debug_assertions` is disabled) the intended behavior? If not, what's the best way forward?
Add license metadata for std dependencies
These five crates are in the dependency tree of `std` but lack license metadata:
- `alloc`
- `core`
- `panic_abort`
- `panic_unwind`
- `unwind`
Querying the dependency tree of `std` is a useful thing to be able to do, since these crates will typically be linked into Rust binaries. Tools show the license fields missing, as seen in https://github.com/rust-lang/rust/issues/67014#issuecomment-782704534. This PR adds the license field for the five crates, based on the license of the `std` package and this repo as a whole. I also added the `repository` and `descriptions` fields, since those seem useful. For `description`, I copied text from top-level comments for the respective modules - except for `unwind` which has none.
I also note that https://github.com/rust-lang/rust/pull/73530 attempted to add license metadata for all crates in this repo, but was rejected because there was question about some of them. I hope that this smaller change, focusing only on the runtime dependencies, will be easier to review.
cc `@Mark-Simulacrum` `@Lokathor`
Fix inequality in docs for div_euclid
This commit fixes the statement of the inequality that the Euclidean remainder satisfies. (The remainder is guaranteed to be less than abs(rhs), not rhs.) It also rewords the documentation to make it a little easier to read.
(You might wonder why I've written `abs(rhs)` instead of `rhs.abs()`. Two reasons: first, the `rem_euclid` docs use `abs(rhs)` instead of `rhs.abs()`, and second, the absolute value here is the mathematical absolute value, not the the `.abs()` operation which may overflow.)
Move `std::sys::unix::platform` to `std::sys::unix::ext`
This moves the operating system dependent alias `platform` (`std::os::{linux, android, ...}`) from `std::sys::unix` to `std::sys::unix::ext` (a.k.a. `std::os::unix`), removing the need for compatibility code in `unix_ext` when documenting on another platform.
This is also a step in making it possible to properly move `std::sys::unix::ext` to `std::os::unix`, as ideally `std::sys` should not depend on the rest of `std`.
Fix invalid slice access in String::retain
As noted in #78499, the previous fix was technically still unsound because it accessed elements of a slice outside its bounds (even though they were still inside the same allocation). This PR addresses that concern by switching to a dropguard approach.
Implement TrustedLen and TrustedRandomAccess for Range<integer>, array::IntoIter, VecDequeue's iterators
This should make some `FromIterator` and `.zip()` specializations applicable in a few more cases.
``@rustbot`` label libs-impl
Make NonNull::as_ref (and friends) return refs with unbound lifetimes
# Rationale:
1. The documentation for all of these functions claims that this is what the functions already do, as they all come with this comment:
> You must enforce Rust's aliasing rules, *since the returned lifetime 'a is arbitrarily chosen* and does not necessarily reflect the actual lifetime of the data...
So I think it's just a bug that they weren't this way already. Note that had it not been for this part, I wouldn't be making this PR, so if we decide we won't take this change, I'll follow it up with a docs PR to fix this.
2. This is how the equivalent raw pointer functions behave.
They also take `self` and not `&self`/`&mut self`, but that can't be changed compatibly at this point. This is the next best thing.
3. Without this fix, often code that uses these methods will find it has to expand the lifetime of the result.
(I can't speak for others but even in unsafe-heavy code, needing to do this unexpectedly is a huge red flag -- if Rust thinks something should have a specific lifetime, I assume it's for a reason)
### Can this cause existing code to be unsound?
I'm confident this can't cause new unsoundness since the reference exists for at most its lifetime, but you get a borrow checker error if you do something that would require/allow the reference to exist past its lifetime.
Additionally, the aliasing rules of a reference only applies while the reference exists.
This *must* be the case, as it is required by the rules used by safe code. (That said, the documentation in this file sort of contradicts it, but I think it's just ambiguity between the lifetime `'a` in `&'a T` and lifetime of the `&'a T` reference itself...)
We are increasing the lifetime of these references, but they should already have hard bounds on that lifetime, or they'd have borrow checker errors.
(CC ``@RalfJung`` because I have gone and done the mistake where I say something definitive about aliasing in Rust which is honestly outside the group of things I should make definitive comments about).
# Caveats
1. This is insta-stable (except for on the unstable functions ofc). I don't think there's any other alternative.
2. I don't believe this is a breaking change in practice. In theory someone could be assigning `NonNull::as_ref` to a function pointer of type `fn(&NonNull<T>) -> &T`. Now they'd need to use a slightly different function pointer type which is (probably) incompatible. This seems pathological, but I guess crater could be used if there are concerns.
3. This has no tests. The old version didn't either that I saw. I could add some stuff that fails to compile without it, if that would be useful.
4. Sometimes the NLL borrow checker gives up and decides lifetimes live till the end of the scope, as opposed to the range where they're used. If this change can cause this to happen more, then my soundness rationale is wrong, and it's likely breaking.
In practice this seems super unlikely.
Anyway. That was a lot of typing.
Fixes https://github.com/rust-lang/rust/issues/80183
This allows the optimizer to turn certain iterator pipelines such as
```rust
let vec = vec![0usize; 100];
vec.into_iter().map(|e| e as isize).collect::<Vec<_>>()
```
into a noop.
The optimization only applies when iterator sources are `T: Copy`
since `impl TrustedRandomAccess for IntoIter<T>`.
No such requirement applies to the output type (`Iterator::Item`).
Fix overflowing length in Vec<ZST> to VecDeque
`Vec` can hold up to `usize::MAX` ZST items, but `VecDeque` has a lower
limit to keep its raw capacity as a power of two, so we should check
that in `From<Vec<T>> for VecDeque<T>`. We can also simplify the
capacity check for the remaining non-ZST case.
Before this fix, the new test would fail on the length:
```
thread 'collections::vec_deque::tests::test_from_vec_zst_overflow' panicked at 'assertion failed: `(left == right)`
left: `0`,
right: `9223372036854775808`', library/alloc/src/collections/vec_deque/tests.rs:474:5
note: panic did not contain expected string
panic message: `"assertion failed: `(left == right)`\n left: `0`,\n right: `9223372036854775808`"`,
expected substring: `"capacity overflow"`
```
That was a result of `len()` using a mask `& (size - 1)` with the
improper length. Now we do get a "capacity overflow" panic as soon as
that `VecDeque::from(vec)` is attempted.
Fixes#80167.
Add `as_str` method for split whitespace str iterators
This PR adds `as_str` methods to `SplitWhitespace` and `SplitAsciiWhitespace`
str iterators. The methods return the remainder, similar to `as_str` methods on
`Chars` and other split iterators. This PR is a continuation of https://github.com/rust-lang/rust/pull/75265, which added `as_str` for all other str split iterators.
The feature gate for new methods is `#![feature(str_split_whitespace_as_str)]`.
`SplitWhitespace` and `SplitAsciiWhitespace` use iterators under the hood, so to implement `as_str` it's required to either
1. Make fields of some iterators `pub(crate)`
2. Add getter methods (like `into_inner`, `inner`, `inner_mut`...) to some (all) iterators
3. Completely rewrite `SplitWhitespace` and `SplitAsciiWhitespace`
This PR uses the 1. approach since it's easier to implement and requires fewer changes (and no changes to the public API). If you think that's not the right way, please, tell me.
r? `@m-ou-se`
Fix typo/inaccuracy in the documentation of Iterator::skip_while
One of the examples used to say “this leads to a possibly confusing situation, where the type of the closure is a double reference” while _actually_ referring to the type of the closure _argument_.
This PR just changes a single word in documentation.
`````@rustbot````` modify labels: A-iterators, T-doc, T-lang
Deprecate std::os::haiku::raw, which accidentally wasn't deprecated
In early 2016, all `std::os::*::raw` modules [were deprecated](aa23c98450) in accordance with [RFC 1415](https://github.com/rust-lang/rfcs/blob/master/text/1415-trim-std-os.md). However, at this same time support for Haiku was being added to libstd, landing shortly after the aforementioned commit, and due to some crossed wires a `std::os::haiku::raw` module was added and was not marked as deprecated.
I have been in correspondence with the author of the Haiku patch, ````@nielx,```` who has confirmed that this was simply an oversight and that the definitions from the libc crate should be preferred instead.
Clarify docs for Read::read's return value
Right now the docs for `Read::read`'s return value are phrased in a way that makes it easy for the reader to assume that the return value is never larger than the passed buffer. This PR clarifies that this is a requirement for implementations of the trait, but that callers have to expect a buggy yet safe implementation failing to do so, especially if unchecked accesses to the buffer are done afterwards.
I fell into this trap recently, and when I noticed, I looked at the docs again and had the feeling that I might not have been the first one to miss this.
The same issue of trusting the return value of `read` was also present in std itself for about 2.5 years and only fixed recently, see #80895.
I hope that clarifying the docs might help others to avoid this issue.
Reuse `std::sys::unsupported::pipe` on `hermit`
Pipes are not supported on `hermit` and `hermit/pipe.rs` is identical to `unsupported/pipe.rs`. This PR reduces duplication between the two by doing the following on `hermit`:
```rust
#[path = "../unsupported/pipe.rs"]
pub mod pipe;
```
Implement String::remove_matches
Closes#50206.
I lifted the function help from `@frewsxcv's` original PR (#50015), hope they don't mind.
I'm also wondering whether it would be useful for `remove_matches` to collect up the removed substrings into a `Vec` and return them, right now they're just overwritten by the copy and lost.
One of the examples used to say “this leads to a possibly confusing situation,
where the type of the closure is a double reference” while _actually_ referring to
the type of the closure _argument_.
Add more links between hash and btree collections
- Link from `core::hash` to `HashMap` and `HashSet`
- Link from HashMap and HashSet to the module-level documentation on
when to use the collection
- Link from several collections to Wikipedia articles on the general
concept
See also https://github.com/rust-lang/rust/pull/81989#issuecomment-783920840.
Vec::dedup_by optimization
Now `Vec::dedup_by` drops items in-place as it goes through them.
From my benchmarks, it is around 10% faster when T is small, with no major regression when otherwise.
I used `ptr::copy` instead of conditional `ptr::copy_nonoverlapping`, because the latter had some weird performance issues on my ryzen laptop (it was 50% slower on it than on intel/sandybridge laptop)
It would be good if someone was able to reproduce these results.
`Vec` can hold up to `usize::MAX` ZST items, but `VecDeque` has a lower
limit to keep its raw capacity as a power of two, so we should check
that in `From<Vec<T>> for VecDeque<T>`. We can also simplify the
capacity check for the remaining non-ZST case.
Before this fix, the new test would fail on the length:
```
thread 'collections::vec_deque::tests::test_from_vec_zst_overflow' panicked at 'assertion failed: `(left == right)`
left: `0`,
right: `9223372036854775808`', library/alloc/src/collections/vec_deque/tests.rs:474:5
note: panic did not contain expected string
panic message: `"assertion failed: `(left == right)`\n left: `0`,\n right: `9223372036854775808`"`,
expected substring: `"capacity overflow"`
```
That was a result of `len()` using a mask `& (size - 1)` with the
improper length. Now we do get a "capacity overflow" panic as soon as
that `VecDeque::from(vec)` is attempted.
Deprecate `intrinsics::drop_in_place` and `collections::Bound`, which accidentally weren't deprecated
Fixes#82080.
I've taken the liberty of updating the `since` values to 1.52, since an unobservable deprecation isn't much of a deprecation (even the detailed release notes never bothered to mention these deprecations).
As mentioned in the issue I'm *pretty* sure that using a type alias for `Bound` is semantically equivalent to the re-export; [the reference implies](https://doc.rust-lang.org/reference/items/type-aliases.html) that type aliases only observably differ from types when used on unit structs or tuple structs, whereas `Bound` is an enum.
Add a check for ASCII characters in to_upper and to_lower
This extra check has better performance. See discussion here:
https://internals.rust-lang.org/t/to-upper-speed/13896
Thanks to `@gilescope` for helping discover and test this.
Deprecate RustcEncodable and RustcDecodable.
We can't remove the `RustcEncodable` and `RustcDecodable` derive macros from the prelude, but we can deprecate them.
Added `try_exists()` method to `std::path::Path`
This method is similar to the existing `exists()` method, except it
doesn't silently ignore the errors, leading to less error-prone code.
This change intentionally does NOT touch the documentation of `exists()`
nor recommend people to use this method while it's unstable.
Such changes are reserved for stabilization to prevent confusing people.
Apart from that it avoids conflicts with #80979.
`@joshtriplett` requested this PR in [internals discussion](https://internals.rust-lang.org/t/the-api-of-path-exists-encourages-broken-code/13817/25?u=kixunil)
Add a `min_type_alias_impl_trait` feature gate
This new feature gate only permits type alias impl trait to be constrained by function and trait method return types. All other possible constraining sites like const/static types, closure return types and binding types are now forbidden and gated under the `type_alias_impl_trait` and `impl_trait_in_bindings` feature gates (which are both marked as incomplete, as they have various ways to ICE the compiler or cause query cycles where they shouldn't).
r? `@nikomatsakis`
This is best reviewed commit-by-commit
"spotlight" is not a very specific or self-explaining name.
Additionally, the dialog that it triggers is called "Notable traits".
So, "notable trait" is a better name.
* Rename `#[doc(spotlight)]` to `#[doc(notable_trait)]`
* Rename `#![feature(doc_spotlight)]` to `#![feature(doc_notable_trait)]`
* Update documentation
* Improve documentation
use RWlock when accessing os::env (take 2)
This reverts commit acdca316c3 (#82877) i.e. redoes #81850 since the invalid unlock attempts in the child process have been fixed in #82949
r? `@joshtriplett`
Add `reverse` search alias for Iterator::rev()
When searching for "reverse" in rustdoc you can't find the rev method on Iterator so here is a search alias for that.
Demonstrate best practice for feeding stdin of a child processes
Documentation change.
It's possible to create a deadlock with stdin/stdout I/O on a single thread:
* the child process may fill its stdout buffer, and have to wait for the parent process to read it,
* but the parent process may be waiting until its stdin write finishes before reading the stdout.
Therefore, the parent process should use separate threads for writing and reading.
These examples are not deadlocking in practice, because they use short strings, but I think it's better to demonstrate code that works even for long writes. The problem is non-obvious and tricky to debug (it seems that even libstd has a similar issue: #45572).
This also demonstrates how to use stdio with threads: it's not obvious that `.take()` can be used to avoid fighting with the borrow checker.
I've checked that the modified examples run fine.
std: Fix a bug on the wasm32-wasi target opening files
This commit fixes an issue pointed out in #82758 where LTO changed the
behavior of a program. It turns out that LTO was not at fault here, it
simply uncovered an existing bug. The bindings to
`__wasilibc_find_relpath` assumed that the relative portion of the path
returned was always contained within thee input `buf` we passed in. This
isn't actually the case, however, and sometimes the relative portion of
the path may reference a sub-portion of the input string itself.
The fix here is to use the relative path pointer coming out of
`__wasilibc_find_relpath` as the source of truth. The `buf` used for
local storage is discarded in this function and the relative path is
copied out unconditionally. We might be able to get away with some
`Cow`-like business or such to avoid the extra allocation, but for now
this is probably the easiest patch to fix the original issue.
Implement Extend and FromIterator for OsString
Add the following trait impls:
- `impl Extend<OsString> for OsString`
- `impl<'a> Extend<&'a OsStr> for OsString`
- `impl FromIterator<OsString> for OsString`
- `impl<'a> FromIterator<&'a OsStr> for OsString`
Because `OsString` is a platform string with no particular semantics, concatenating them together seems acceptable.
I came across a use case for these trait impls in https://github.com/artichoke/artichoke/pull/1089:
Artichoke is a Ruby interpreter. Its CLI accepts multiple `-e` switches for executing inline Ruby code, like:
```console
$ cargo -q run --bin artichoke -- -e '2.times {' -e 'puts "foo: #{__LINE__}"' -e '}'
foo: 2
foo: 2
```
I use `clap` for command line argument parsing, which collects these `-e` commands into a `Vec<OsString>`. To pass these commands to the interpreter for `Eval`, I need to join them together. Combining these impls with `Iterator::intersperse` https://github.com/rust-lang/rust/issues/79524 would enable me to build a single bit of Ruby code.
Currently, I'm doing something like:
```rust
let mut commands = commands.into_iter();
let mut buf = if let Some(command) = commands.next() {
command
} else {
return Ok(Ok(()));
};
for command in commands {
buf.push("\n");
buf.push(command);
}
```
If there's interest, I'd also like to add impls for `Cow<'a, OsStr>`, which would avoid allocating the `"\n"` `OsString` in the concatenate + intersperse use case.
Don't implement mem::replace with mem::swap.
`swap` is a complicated operation, so this changes the implementation of `replace` to use `read` and `write` instead.
See https://github.com/rust-lang/rust/pull/83019.
I wrote there:
> Implementing the simpler operation (replace) with the much more complicated operation (swap) doesn't make a whole lot of sense. `replace` is just read+write, and the primitive for moving out of a `&mut`. `swap` is for doing that to *two* `&mut` at the same time, which is both more niche and more complicated (as shown by `swap_nonoverlapping_bytes`).
This could be especially interesting for `Option<VeryLargeStruct>::take()`, since swapping such a large structure with `swap_nonoverlapping_bytes` is going to be much less efficient than `ptr::write()`'ing a `None`.
But also for small values where `swap` just reads/writes using temporary variable, this makes a `replace` or `take` operation simpler:

Rollup of 11 pull requests
Successful merges:
- #80385 (Clarify what `Cell::replace` returns)
- #82571 (Rustdoc Json: Add tests for Reexports, and improve jsondocck)
- #82860 (Add `-Z unpretty` flag for the THIR)
- #82950 (convert slice doc link to intra-doc links)
- #82965 (Add spirv extension handling in compiletest)
- #82966 (update MSYS2 link in README)
- #82979 (Fix "run" button position in error index)
- #83001 (Ignore Vim swap files)
- #83003 (rustdoc: tweak the search index format)
- #83013 (Adjust some `#[cfg]`s to take non-Unix non-Windows operating systems into account)
- #83018 (Reintroduce accidentally deleted assertions.)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
convert slice doc link to intra-doc links
Continuing where #80189 stopped, with `core::slice`.
I had an issue with two dead links in my doc when implementing `Deref<Target = [T]>` for one of my type. This means that [`binary_search_by_key`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.binary_search_by_key) was available, but not [`sort_by_key`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.sort_by_key) even though it was linked in it's doc (same issue with [`as_ptr`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_ptr) and [`as_mut_pbr`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_mut_ptr)). It becomes available if I implement `DerefMut`, as it needs an `&mut self`.
<details>
<summary>Code that will have dead links in its doc</summary>
```rust
pub struct A;
pub struct B;
impl std::ops::Deref for B{
type Target = [A];
fn deref(&self) -> &Self::Target {
&A
}
}
```
</details>
I removed the link to `sort_by_key` from `binary_search_by_key` doc as I didn't find a nice way to have a live link:
- `binary_search_by_key` is in `core`
- `sort_by_key` is in `alloc`
- intra-doc link `slice::sort_by_key` doesn't work, as `alloc` is not available when `core` is being build (the warning can't be ignored: ```error[E0710]: an unknown tool name found in scoped lint: `rustdoc::broken_intra_doc_links` ```)
- keeping the link as an anchor `#method.sort_by_key` meant a dead link
- an absolute link would work but doesn't feel right...
Fix io::copy specialization using copy_file_range when writer was opened with O_APPEND
fixes#82410
While `sendfile()` returns `EINVAL` when the output was opened with O_APPEND, `copy_file_range()` does not and returns `EBADF` instead, which – unlike other `EBADF` causes – is not fatal for this operation since a regular `write()` will likely succeed.
We now treat `EBADF` as a non-fatal error for `copy_file_range` and fall back to a read-write copy as we already did for several other errors.
Do not attempt to unlock envlock in child process after a fork.
This implements the first two points from https://github.com/rust-lang/rust/issues/64718#issuecomment-793030479
This is a breaking change for cases where the environment is accessed in a Command::pre_exec closure. Except for single-threaded programs these uses were not correct anyway since they aren't async-signal safe.
Note that we had a ui test that explicitly tried `env::set_var` in `pre_exec`. As expected it failed with these changes when I tested locally.
Edition-specific preludes
This changes `{std,core}::prelude` to export edition-specific preludes under `rust_2015`, `rust_2018` and `rust_2021`. (As suggested in https://github.com/rust-lang/rust/issues/51418#issuecomment-395630382.) For now they all just re-export `v1::*`, but this allows us to add things to the 2021edition prelude soon.
This also changes the compiler to make the automatically injected prelude import dependent on the selected edition.
cc `@rust-lang/libs` `@djc`
Add Option::get_or_default
Tracking issue: #82901
The original issue is #55042, which was closed, but for an invalid reason (see discussion there). Opening this to reconsider (I hope that's okay). It seems like the only gap for `Option` being "entry-like".
I ran into a need for this method where I had a `Vec<Option<MyData>>` and wanted to do `vec[n].get_or_default().my_data_method()`. Using an `Option` as an inner component of a data structure is probably where the need for this will normally arise.
Fixes to ExitStatus and its docs
* On Unix, properly display every possible wait status (and don't panic on weird values)
* In the documentation, be clear and consistent about "exit status" vs "wait status".
Stabilize `unsafe_op_in_unsafe_fn` lint
This makes it possible to override the level of the `unsafe_op_in_unsafe_fn`, as proposed in https://github.com/rust-lang/rust/issues/71668#issuecomment-729770896.
Tracking issue: #71668
r? ```@nikomatsakis``` cc ```@SimonSapin``` ```@RalfJung```
# Stabilization report
This is a stabilization report for `#![feature(unsafe_block_in_unsafe_fn)]`.
## Summary
Currently, the body of unsafe functions is an unsafe block, i.e. you can perform unsafe operations inside.
The `unsafe_op_in_unsafe_fn` lint, stabilized here, can be used to change this behavior, so performing unsafe operations in unsafe functions requires an unsafe block.
For now, the lint is allow-by-default, which means that this PR does not change anything without overriding the lint level.
For more information, see [RFC 2585](https://github.com/rust-lang/rfcs/blob/master/text/2585-unsafe-block-in-unsafe-fn.md)
### Example
```rust
// An `unsafe fn` for demonstration purposes.
// Calling this is an unsafe operation.
unsafe fn unsf() {}
// #[allow(unsafe_op_in_unsafe_fn)] by default,
// the behavior of `unsafe fn` is unchanged
unsafe fn allowed() {
// Here, no `unsafe` block is needed to
// perform unsafe operations...
unsf();
// ...and any `unsafe` block is considered
// unused and is warned on by the compiler.
unsafe {
unsf();
}
}
#[warn(unsafe_op_in_unsafe_fn)]
unsafe fn warned() {
// Removing this `unsafe` block will
// cause the compiler to emit a warning.
// (Also, no "unused unsafe" warning will be emitted here.)
unsafe {
unsf();
}
}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn denied() {
// Removing this `unsafe` block will
// cause a compilation error.
// (Also, no "unused unsafe" warning will be emitted here.)
unsafe {
unsf();
}
}
```
This is a breaking change for cases where the environment is
accessed in a Command::pre_exec closure. Except for
single-threaded programs these uses were not correct
anyway since they aren't async-signal safe.
It's possible to create a deadlock with stdin/stdout I/O on a single thread:
* the child process may fill its stdout buffer, and have to wait for the parent process to read it,
* but the parent process may be waiting until its stdin write finishes before reading the stdout.
Therefore, the parent process should use separate threads for writing and reading.
Bump libc dependency of std to 0.2.88.
This PR bumps the `libc` dependency of `std` to 0.2.88. This will fix `TcpListener::accept` for Android on x86 platforms (31a2777d8f).
This will really finally fix https://github.com/rust-lang/rust/issues/82400 for the main branch :)
r? ``@JohnTitor``
Added #[repr(transparent)] to core::cmp::Reverse
I found casting from an `&T` to an `&Reverse<T>` potentially useful, but found that `Reverse` was not `#[repr(transparent)]`, so after asking about it [on Reddit](https://www.reddit.com/r/rust/comments/le60uv/make_stdcmpreverse_reprtransparent_and_add_a/), I decided to go ahead and make a pull request which simply adds the attribute to the struct.
Improve sift_down performance in BinaryHeap
Replacing `child < end - 1` with `child <= end.saturating_sub(2)` in `BinaryHeap::sift_down_range` (surprisingly) results in a significant speedup of `BinaryHeap::into_sorted_vec`. The same substitution can be done for `BinaryHeap::sift_down_to_bottom`, which causes a slight but probably statistically insignificant speedup for `BinaryHeap::pop`. It's interesting that benchmarks aside from `bench_into_sorted_vec` are barely affected, even those that do use `sift_down_*` methods internally.
| Benchmark | Before (ns/iter) | After (ns/iter) | Speedup |
|--------------------------|------------------|-----------------|---------|
| bench_find_smallest_1000<sup>1</sup> | 392,617 | 385,200 | 1.02 |
| bench_from_vec<sup>1</sup> | 506,016 | 504,444 | 1.00 |
| bench_into_sorted_vec<sup>1</sup> | 476,869 | 384,458 | 1.24 |
| bench_peek_mut_deref_mut<sup>3</sup> | 518,753 | 519,792 | 1.00 |
| bench_pop<sup>2</sup> | 446,718 | 444,409 | 1.01 |
| bench_push<sup>3</sup> | 772,481 | 770,208 | 1.00 |
<sup>1</sup>: internally calls `sift_down_range`
<sup>2</sup>: internally calls `sift_down_to_bottom`
<sup>3</sup>: should not be affected
Revert switch of env locking to rwlock, to fix deadlock in process spawning
This reverts commit 354f19cf24, reversing changes made to 0cfba2fd09.
PR https://github.com/rust-lang/rust/pull/81850 switched the environment lock from a mutex to an rwlock. However, process spawning (when not able to use `posix_spawn`) locks the environment before forking, and unlocks it after forking (in both the parent and the child). With a mutex, this works (although probably not correct even with a mutex). With an rwlock, on at least some targets, unlocking in the child does not work correctly, resulting in a deadlock.
This has manifested as CI hangs on i686 Linux; that target doesn't use `posix_spawn` in the CI environment due to the age of the installed C library (currently glibc 2.23). (Switching to `posix_spawn` would just mask this issue, though, which would still arise in any case that can't use `posix_spawn`.)
Some additional cleanup of environment handling around process spawning may help, but for now, revert the PR and go back to a standard mutex.
Fixes#82221
Add note about the `#[doc(no-inline)]` usage
This is required to correctly build the documentation (including all submodules, that are only available in certain targets).
See the linked issue and #82861 for reference.
Generalize Write impl for Vec<u8> to Vec<u8, A>
As discussed in the [issue tracker for the wg-allocators working group][1], updating this impl for allocator support was most likely just forgotten previously. This PR fixes this.
r? `````@TimDiekmann`````
[1]: https://github.com/rust-lang/wg-allocators/issues/86
Implement built-in attribute macro `#[cfg_eval]` + some refactoring
This PR implements a built-in attribute macro `#[cfg_eval]` as it was suggested in https://github.com/rust-lang/rust/pull/79078 to avoid `#[derive()]` without arguments being abused as a way to configure input for other attributes.
The macro is used for eagerly expanding all `#[cfg]` and `#[cfg_attr]` attributes in its input ("fully configuring" the input).
The effect is identical to effect of `#[derive(Foo, Bar)]` which also fully configures its input before passing it to macros `Foo` and `Bar`, but unlike `#[derive]` `#[cfg_eval]` can be applied to any syntax nodes supporting macro attributes, not only certain items.
`cfg_eval` was the first name suggested in https://github.com/rust-lang/rust/pull/79078, but other alternatives are also possible, e.g. `cfg_expand`.
```rust
#[cfg_eval]
#[my_attr] // Receives `struct S {}` as input, the field is configured away by `#[cfg_eval]`
struct S {
#[cfg(FALSE)]
field: u8,
}
```
Tracking issue: https://github.com/rust-lang/rust/issues/82679
As discussed in the issue tracker for the wg-allocators working group[1], updating this implementation for allocator support was most likely just forgotten in the original PR.
[1]: https://github.com/rust-lang/wg-allocators/issues/86
improve offset_from docs
`@thomcc` pointed out that the current docs leave it kind of unclear how one can satisfy the "no wrapping around `isize` or the address space" requirement of `offset_from`, so make the docs clearer about that.
FWIW, I don't think I entirely agree with that second paragraph about large objects (that I left mostly unchanged here). LLVM, to my knowledge, fundamentally assumes that all allocations fit into an `isize::MAX`. So in that sense creating a larger allocation is simply UB. I would expect a guarantee that Rust heap allocation methods will never return allocations larger than `isize::MAX` (or rather, Rust heap allocation methods should require that the `Layout` is no larger than `isize::MAX`). However, I cannot find any such requirement documented currently. Large allocations are not mentioned at all in the allocator docs, which is quite surprising -- even if we say that such allocations are not insta-UB (which I think is incompatible with LLVM), they are still extremely footgunny since `ptr::offset`/`ptr::add` do not support offsetting by more than `isize::MAX` bytes.
Furthermore, the allocator docs don't even say anything about allocations wrapping around the address space. But that is certainly something allocators must ensure never happens; we cannot expect clients to defend against this.
Cc `@rust-lang/wg-allocators`
Improve transmute docs with further clarifications
Closes#82493.
Please let me know if any of the new wording sounds off, English is not my mother tongue.
Prevent specialized ZipImpl from calling `__iterator_get_unchecked` twice with the same index
Fixes#82291
It's open for review, but conflicts with #82289, wait before merging. The conflict involves only the new test, so it should be rather trivial to fix.
Make some Option, Result methods unstably const
The following methods are now unstably const:
- Option::transpose
- Option::flatten
- Result::flatten
While some methods for could likely be made `const` in the future, nearly all of them require something to be dropped at compile-time, which isn't currently supported. The functions listed above should have a trivial path to stabilization.
Change built-in kernel targets to be os = none throughout
Whether for Rust's own `target_os`, LLVM's triples, or GNU config's, the
OS-related have fields have been for code running *on* that OS, not code
hat is *part* of the OS.
The difference is huge, as syscall interfaces are nothing like
freestanding interfaces. Kernels are (hypervisors and other more exotic
situations aside) freestanding programs that use the interfaces provided
by the hardware. It's *those* interfaces, the ones external to the
program being built and its software dependencies, that are the content
of the target.
For the Linux Kernel in particular, `target_env: "gnu"` is removed for
the same reason: that `-gnu` refers to glibc or GNU/linux, neither of
which applies to the kernel itself.
Relates to #74247
Improve slice.binary_search_by()'s best-case performance to O(1)
This PR aimed to improve the [slice.binary_search_by()](https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search_by)'s best-case performance to O(1).
# Noticed
I don't know why the docs of `binary_search_by` said `"If there are multiple matches, then any one of the matches could be returned."`, but the implementation isn't the same thing. Actually, it returns the **last one** if multiple matches found.
Then we got two options:
## If returns the last one is the correct or desired result
Then I can rectify the docs and revert my changes.
## If the docs are correct or desired result
Then my changes can be merged after fully reviewed.
However, if my PR gets merged, another issue raised: this could be a **breaking change** since if multiple matches found, the returning order no longer the last one instead of it could be any one.
For example:
```rust
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 1;
let idx = s.binary_search(&num);
s.insert(idx, 2);
// Old implementations
assert_eq!(s, [0, 1, 1, 1, 1, 2, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
// New implementations
assert_eq!(s, [0, 1, 1, 1, 2, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
```
# Benchmarking
**Old implementations**
```sh
$ ./x.py bench --stage 1 library/libcore
test slice::binary_search_l1 ... bench: 59 ns/iter (+/- 4)
test slice::binary_search_l1_with_dups ... bench: 59 ns/iter (+/- 3)
test slice::binary_search_l2 ... bench: 76 ns/iter (+/- 5)
test slice::binary_search_l2_with_dups ... bench: 77 ns/iter (+/- 17)
test slice::binary_search_l3 ... bench: 183 ns/iter (+/- 23)
test slice::binary_search_l3_with_dups ... bench: 185 ns/iter (+/- 19)
```
**New implementations (1)**
Implemented by this PR.
```rust
if cmp == Equal {
return Ok(mid);
} else if cmp == Less {
base = mid
}
```
```sh
$ ./x.py bench --stage 1 library/libcore
test slice::binary_search_l1 ... bench: 58 ns/iter (+/- 2)
test slice::binary_search_l1_with_dups ... bench: 37 ns/iter (+/- 4)
test slice::binary_search_l2 ... bench: 76 ns/iter (+/- 3)
test slice::binary_search_l2_with_dups ... bench: 57 ns/iter (+/- 6)
test slice::binary_search_l3 ... bench: 200 ns/iter (+/- 30)
test slice::binary_search_l3_with_dups ... bench: 157 ns/iter (+/- 6)
$ ./x.py bench --stage 1 library/libcore
test slice::binary_search_l1 ... bench: 59 ns/iter (+/- 8)
test slice::binary_search_l1_with_dups ... bench: 37 ns/iter (+/- 2)
test slice::binary_search_l2 ... bench: 77 ns/iter (+/- 2)
test slice::binary_search_l2_with_dups ... bench: 57 ns/iter (+/- 2)
test slice::binary_search_l3 ... bench: 198 ns/iter (+/- 21)
test slice::binary_search_l3_with_dups ... bench: 158 ns/iter (+/- 11)
```
**New implementations (2)**
Suggested by `@nbdd0121` in [comment](https://github.com/rust-lang/rust/pull/74024#issuecomment-665430239).
```rust
base = if cmp == Greater { base } else { mid };
if cmp == Equal { break }
```
```sh
$ ./x.py bench --stage 1 library/libcore
test slice::binary_search_l1 ... bench: 59 ns/iter (+/- 7)
test slice::binary_search_l1_with_dups ... bench: 37 ns/iter (+/- 5)
test slice::binary_search_l2 ... bench: 75 ns/iter (+/- 3)
test slice::binary_search_l2_with_dups ... bench: 56 ns/iter (+/- 3)
test slice::binary_search_l3 ... bench: 195 ns/iter (+/- 15)
test slice::binary_search_l3_with_dups ... bench: 151 ns/iter (+/- 7)
$ ./x.py bench --stage 1 library/libcore
test slice::binary_search_l1 ... bench: 57 ns/iter (+/- 2)
test slice::binary_search_l1_with_dups ... bench: 38 ns/iter (+/- 2)
test slice::binary_search_l2 ... bench: 77 ns/iter (+/- 11)
test slice::binary_search_l2_with_dups ... bench: 57 ns/iter (+/- 4)
test slice::binary_search_l3 ... bench: 194 ns/iter (+/- 15)
test slice::binary_search_l3_with_dups ... bench: 151 ns/iter (+/- 18)
```
I run some benchmarking testings against on two implementations. The new implementation has a lot of improvement in duplicates cases, while in `binary_search_l3` case, it's a little bit slower than the old one.
This commit fixes an issue pointed out in #82758 where LTO changed the
behavior of a program. It turns out that LTO was not at fault here, it
simply uncovered an existing bug. The bindings to
`__wasilibc_find_relpath` assumed that the relative portion of the path
returned was always contained within thee input `buf` we passed in. This
isn't actually the case, however, and sometimes the relative portion of
the path may reference a sub-portion of the input string itself.
The fix here is to use the relative path pointer coming out of
`__wasilibc_find_relpath` as the source of truth. The `buf` used for
local storage is discarded in this function and the relative path is
copied out unconditionally. We might be able to get away with some
`Cow`-like business or such to avoid the extra allocation, but for now
this is probably the easiest patch to fix the original issue.
Add diagnostic item to `Default` trait
This PR adds diagnostic item to `Default` trait to be used by rust-lang/rust-clippy#6562 issue.
Also fixes the obsolete path to the `symbols.rs` file in the comment.
Add assert_matches macro.
This adds `assert_matches!(expression, pattern)`.
Unlike the other asserts, this one ~~consumes the expression~~ may consume the expression, to be able to match the pattern. (It could add a `&` implicitly, but that's noticable in the pattern, and will make a consuming guard impossible.)
See https://github.com/rust-lang/rust/issues/62633#issuecomment-790737853
This re-uses the same `left: .. right: ..` output as the `assert_eq` and `assert_ne` macros, but with the pattern as the right part:
assert_eq:
```
assertion failed: `(left == right)`
left: `Some("asdf")`,
right: `None`
```
assert_matches:
```
assertion failed: `(left matches right)`
left: `Ok("asdf")`,
right: `Err(_)`
```
cc ```@cuviper```
Add {BTreeMap,HashMap}::try_insert
`{BTreeMap,HashMap}::insert(key, new_val)` returns `Some(old_val)` if the key was already in the map. It's often useful to assert no duplicate values are inserted.
We experimented with `map.insert(key, val).unwrap_none()` (https://github.com/rust-lang/rust/issues/62633), but decided that that's not the kind of method we'd like to have on `Option`s.
`insert` always succeeds because it replaces the old value if it exists. One could argue that `insert()` is never the right method for panicking on duplicates, since already handles that case by replacing the value, only allowing you to panic after that already happened.
This PR adds a `try_insert` method that instead returns a `Result::Err` when the key already exists. This error contains both the `OccupiedEntry` and the value that was supposed to be inserted. This means that unwrapping that result gives more context:
```rust
map.insert(10, "world").unwrap_none();
// thread 'main' panicked at 'called `Option::unwrap_none()` on a `Some` value: "hello"', src/main.rs:8:29
```
```rust
map.try_insert(10, "world").unwrap();
// thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value:
// OccupiedError { key: 10, old_value: "hello", new_value: "world" }', src/main.rs:6:33
```
It also allows handling the failure in any other way, as you have full access to the `OccupiedEntry` and the value.
`try_insert` returns a reference to the value in case of success, making it an alternative to `.entry(key).or_insert(value)`.
r? ```@Amanieu```
Fixes https://github.com/rust-lang/rfcs/issues/3092
Avoid unnecessary Vec construction in BufReader
As mentioned in #80460, creating a `Vec` and calling `Vec::into_boxed_slice()` emits unnecessary calls to `realloc()` and `free()`. Updated the code to use `Box::new_uninit_slice()` to create a boxed slice directly. I think this also makes it more explicit that the initial contents of the buffer are uninitialized.
r? ``@m-ou-se``
Add suggestion `.collect()` for iterators in iterators
Closes#81584
```
error[E0515]: cannot return value referencing function parameter `y`
--> main3.rs:4:38
|
4 | ... .map(|y| y.iter().map(|x| x + 1))
| -^^^^^^^^^^^^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| `y` is borrowed here
| help: Maybe use `.collect()` to allocate the iterator
```
Added the suggestion: `help: Maybe use `.collect()` to allocate the iterator`
Improved IO Bytes Size Hint
After trying to implement better `size_hint()` return values for `File` in [this PR](https://github.com/rust-lang/rust/pull/81044) and changing to implementing it for `BufReader` in [this PR](https://github.com/rust-lang/rust/pull/81052), I have arrived at this implementation that provides tighter bounds for the `Bytes` iterator of various readers including `BufReader`, `Empty`, and `Chain`.
Unfortunately, for `BufReader`, the size_hint only improves after calling `fill_buffer` due to it using the contents of the buffer for the hint. Nevertheless, the the tighter bounds should result in better pre-allocation of space to handle the contents of the `Bytes` iterator.
Closes#81052
Implement NOOP_METHOD_CALL lint
Implements the beginnings of https://github.com/rust-lang/lang-team/issues/67 - a lint for detecting noop method calls (e.g, calling `<&T as Clone>::clone()` when `T: !Clone`).
This PR does not fully realize the vision and has a few limitations that need to be addressed either before merging or in subsequent PRs:
* [ ] No UFCS support
* [ ] The warning message is pretty plain
* [ ] Doesn't work for `ToOwned`
The implementation uses [`Instance::resolve`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/instance/struct.Instance.html#method.resolve) which is normally later in the compiler. It seems that there are some invariants that this function relies on that we try our best to respect. For instance, it expects substitutions to have happened, which haven't yet performed, but we check first for `needs_subst` to ensure we're dealing with a monomorphic type.
Thank you to ```@davidtwco,``` ```@Aaron1011,``` and ```@wesleywiser``` for helping me at various points through out this PR ❤️.
Upgrade to LLVM 12
This implements the necessary adjustments to make rustc work with LLVM 12. I didn't encounter any major issues so far.
r? `@cuviper`
Previously vec's len was updated only after full copy, making the method
leak if T::clone panic!s.
This commit makes `Vec::extend_from_within` (or, more accurately, it's
`T: Clone` specialization) update vec's len on every iteration, fixing
the issue.
`T: Copy` specialization was not affected by the issue b/c it doesn't
call user specified code (as, e.g. `T::clone`), and instead calls
`ptr::copy_nonoverlapping`.
If different unices have different bit patterns for WIFSTOPPED and
WIFCONTINUED then simply being glibc is probably not good enough for
this rather ad-hoc test to work. Do it on Linux only.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Revert `Vec::spare_capacity_mut` impl to prevent pointers invalidation
The implementation was changed in #79015.
Later it was [pointed out](https://github.com/rust-lang/rust/issues/81944#issuecomment-782849785) that the implementation invalidates pointers to the buffer (initialized elements) by creating a unique reference to the buffer. This PR reverts the implementation.
r? ```@RalfJung```
enable atomic_min/max tests in Miri
Thanks to `@henryboisdequin` and `@GregBowyer,` Miri now supports these intrinsics. :)
Also includes the necessary Miri update.
unix: Non-mutable bufs in send_vectored_with_ancillary_to
This is the same PR as [#79753](https://github.com/rust-lang/rust/pull/79753). It was closed because of inactivity. Therefore, I create a new one. ````@lukaslihotzki````
Add is_enclave_range/is_user_range overflow checks
Fixes#76343.
This adds overflow checking to `is_enclave_range` and `is_user_range` in `sgx::os::fortanix_sgx::mem` in order to mitigate possible security issues with enclave code. It also accounts for an edge case where the memory range provided ends exactly at the end of the address space, where calculating `p + len` would overflow back to zero despite the range potentially being valid.
Turn may_have_side_effect into an associated constant
The `may_have_side_effect` is an implementation detail of `TrustedRandomAccess`
trait. It describes if obtaining an iterator element may have side effects. It
is currently implemented as an associated function.
Turn `may_have_side_effect` into an associated constant. This makes the
value immediately available to the optimizer.
Convert primitives in the standard library to intra-doc links
Blocked on https://github.com/rust-lang/rust/pull/80181. I forgot that this needs to wait for the beta bump so the standard library can be documented with `doc --stage 0`.
Notably I didn't convert `core::slice` because it's like 50 links and I got scared 😨
- Rename `broken_intra_doc_links` to `rustdoc::broken_intra_doc_links`
- Ensure that the old lint names still work and give deprecation errors
- Register lints even when running doctests
Otherwise, all `rustdoc::` lints would be ignored.
- Register all existing lints as removed
This unfortunately doesn't work with `register_renamed` because tool
lints have not yet been registered when rustc is running. For similar
reasons, `check_backwards_compat` doesn't work either. Call
`register_removed` directly instead.
- Fix fallout
+ Rustdoc lints for compiler/
+ Rustdoc lints for library/
Note that this does *not* suggest `rustdoc::broken_intra_doc_links` for
`rustdoc::intra_doc_link_resolution_failure`, since there was no time
when the latter was valid.
Change twice used large const table to static
This table is used twice in core::num::dec2flt::algorithm::power_of_ten. According to the semantics of const, a separate huge definition of the table is inlined at both places.
5233edcf1c/library/core/src/num/dec2flt/algorithm.rs (L16-L22)
Theoretically this gets cleaned up by optimization passes, but in practice I am experiencing a miscompile from LTO on this code. Making the table a static, which would only be defined a single time and not require attention from LTO, eliminates the miscompile and seems semantically more appropriate anyway. A separate bug report on the LTO bug is forthcoming.
Original addition of `const` is from #27307.
The panic when the right operand is `0` is expected, but the
overflow-related panic (which occurs only for `MIN % -1`) is somewhat
surprising for two reasons: a return value of `0` would be reasonable
in this case, and, for most arithmetic operations, overflow results in
panic only when `debug_assertions` is enabled. As a result, it's
helpful to document this behavior.
The panic on division by zero is expected, but the panic on overflow
is somewhat surprising (since most arithmetic operations panic on
overflow only when `debug_assertions` is enabled). As a result, it's
helpful to document this behavior.
This commit fixes the statement of the inequality that the Euclidean
remainder satisfies. (The remainder is guaranteed to be less than
abs(rhs), not rhs.) It also rewords the documentation to make it a
little easier to read.
This table is used twice in core::num::dec2flt::algorithm::power_of_ten.
According to the semantics of const, a separate huge definition of the
table is inlined at both places.
fn power_of_ten(e: i16) -> Fp {
assert!(e >= table::MIN_E);
let i = e - table::MIN_E;
let sig = table::POWERS.0[i as usize];
let exp = table::POWERS.1[i as usize];
Fp { f: sig, e: exp }
}
Theoretically this gets cleaned up by optimization passes, but in
practice I am experiencing a miscompile from LTO on this code. Making
the table a static, which would only be defined a single time and not
require attention from LTO, eliminates the miscompile and seems
semantically more appropriate anyway. A separate bug report on the LTO
bug is forthcoming.
Whether for Rust's own `target_os`, LLVM's triples, or GNU config's, the
OS-related have fields have been for code running *on* that OS, not code
that is *part* of the OS.
The difference is huge, as syscall interfaces are nothing like
freestanding interfaces. Kernels are (hypervisors and other more exotic
situations aside) freestanding programs that use the interfaces provided
by the hardware. It's *those* interfaces, the ones external to the
program being built and its software dependencies, that are the content
of the target.
For the Linux Kernel in particular, `target_env: "gnu"` is removed for
the same reason: that `-gnu` refers to glibc or GNU/linux, neither of
which applies to the kernel itself.
Relates to #74247
Thanks @ojeda for catching some things.
Clarify that SyncOnceCell::set blocks.
Reading the discussion of this feature, I gained the mistaken impression that neither `set` nor `get` blocked, and thus calling `get` immediately after `set` was not guaranteed to succeed. It turns out that `set` *does* block, guaranteeing that the cell contains a value once `set` returns. This change updates the documentation to state that explicitly.
Happy to adjust the wording as desired.
Rollup of 10 pull requests
Successful merges:
- #82309 (Propagate RUSTDOCFLAGS in the environment when documenting)
- #82403 (rustbuild: print out env vars on verbose rustc invocations)
- #82507 (Rename the `tidy` binary to `rust-tidy`)
- #82531 (Add GUI tests)
- #82532 (Add `build.print_step_rusage` to config.toml)
- #82543 (fix env var name in CI)
- #82622 (Propagate `--test-args` for `x.py test src/tools/cargo`)
- #82628 (Try to clarify GlobalAlloc::realloc documentation comment.)
- #82630 (Fix a typo in the `find_anon_type` doc)
- #82643 (Add more proc-macro attribute tests)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Try to clarify GlobalAlloc::realloc documentation comment.
This PR tries to improve the documentation of [GlobalAlloc::realloc](https://doc.rust-lang.org/alloc/alloc/trait.GlobalAlloc.html#method.realloc) with two aspects:
1. Explicitly mention that `realloc` preserves the contents of the original memory block.
2. Explicitly mention which layout should be used to deallocate the reallocated block.
BTree: no longer define impossible casts
Casts to leaf to internal only make sense when the original has a chance of being the thing it's cast to.
r? `@Mark-Simulacrum`
BTreeMap: split up range_search into two stages
`range_search` expects the caller to pass the same root twice and starts searching a node for both bounds of a range. It's not very clear that in the early iterations, it searches twice in the same node. This PR splits that search up in an initial `find_leaf_edges_spanning_range` that postpones aliasing until the last second, and a second phase for continuing the search for the range in the each subtree independently (`find_lower_bound_edge` & `find_upper_bound_edge`), which greatly helps for use in #81075. It also moves those functions over to the search module.
r? `@Mark-Simulacrum`
Reading the discussion of this feature, I gained the mistaken impression that neither `set` nor `get` blocked, and thus calling `get` immediately after `set` was not guaranteed to succeed. It turns out that `set` *does* block, guaranteeing that the cell contains a value once `set` returns. This change updates the documentation to state that explicitly.
Add a chapter on the test harness.
There isn't really any online documentation on the test harness, so this adds a chapter to the rustc book which provides information on how the harness works and details on the command-line options.
Remove the x86_64-rumprun-netbsd target
Herein we remove the target from the compiler and the code from libstd intended to support the now-defunct rumprun project.
Closes#81514
clarify RW lock's priority gotcha
In particular, the following program works on Linux, but deadlocks on
mac:
```rust
use std::{
sync::{Arc, RwLock},
thread,
time::Duration,
};
fn main() {
let lock = Arc::new(RwLock::new(()));
let r1 = thread::spawn({
let lock = Arc::clone(&lock);
move || {
let _rg = lock.read();
eprintln!("r1/1");
sleep(1000);
let _rg = lock.read();
eprintln!("r1/2");
sleep(5000);
}
});
sleep(100);
let w = thread::spawn({
let lock = Arc::clone(&lock);
move || {
let _wg = lock.write();
eprintln!("w");
}
});
sleep(100);
let r2 = thread::spawn({
let lock = Arc::clone(&lock);
move || {
let _rg = lock.read();
eprintln!("r2");
sleep(2000);
}
});
r1.join().unwrap();
r2.join().unwrap();
w.join().unwrap();
}
fn sleep(ms: u64) {
std:🧵:sleep(Duration::from_millis(ms))
}
```
Context: I was completely mystified by a my CI deadlocking on mac ([here](https://github.com/matklad/xshell/pull/7)), until ``@azdavis`` debugged the issue. See a stand-alone reproduciton here: https://github.com/matklad/xshell/pull/15
Add missing "see its documentation for more" stdio
StdoutLock and StderrLock does not have example, it would be better
to leave "see its documentation for more" like iter docs.
In particular, the following program works on Linux, but deadlocks on
mac:
use std::{
sync::{Arc, RwLock},
thread,
time::Duration,
};
fn main() {
let lock = Arc::new(RwLock::new(()));
let r1 = thread::spawn({
let lock = Arc::clone(&lock);
move || {
let _rg = lock.read();
eprintln!("r1/1");
sleep(1000);
let _rg = lock.read();
eprintln!("r1/2");
sleep(5000);
}
});
sleep(100);
let w = thread::spawn({
let lock = Arc::clone(&lock);
move || {
let _wg = lock.write();
eprintln!("w");
}
});
sleep(100);
let r2 = thread::spawn({
let lock = Arc::clone(&lock);
move || {
let _rg = lock.read();
eprintln!("r2");
sleep(2000);
}
});
r1.join().unwrap();
r2.join().unwrap();
w.join().unwrap();
}
fn sleep(ms: u64) {
std:🧵:sleep(Duration::from_millis(ms))
}
Specialize slice::fill with Copy type and u8/i8/bool
I don't expect rustperf could measure any perf improvements with this changes
since `slice::fill` is newly added.
Godbolt link for this change: <https://rust.godbolt.org/z/r3fzee>.
r? `@matthewjasper` since this patch added new specialization.
Use libc::accept4 on Android instead of raw syscall.
This PR replaces the use of a raw `accept4` syscall with `libc::accept4`. This was originally added (by me) because `std` couldn't update to the latest `libc` with `accept4` support for android. By now, libc is already on 0.2.85, so the workaround can be removed.
`@rustbot` label +O-android +T-libs-impl
Add a `size()` function to WASI's `MetadataExt`.
WASI's `filestat` type includes a size field, so expose it in
`MetadataExt` via a `size()` function, similar to the corresponding Unix
function.
r? ``````@alexcrichton``````
Enable API documentation for `std::os::wasi`.
This adds API documentation support for `std::os::wasi` modeled after
how `std::os::unix` works, so that WASI can be documented [here] along
with the other platforms.
[here]: https://doc.rust-lang.org/stable/std/os/index.html
Two changes of particular interest:
- This changes the `AsRawFd` for `io::Stdin` for WASI to return
`libc::STDIN_FILENO` instead of `sys::stdio::Stdin.as_raw_fd()` (and
similar for `Stdout` and `Stderr`), which matches how the `unix`
version works. `STDIN_FILENO` etc. may not always be explicitly
reserved at the WASI level, but as long as we have Rust's `std` and
`libc`, I think it's reasonable to guarantee that we'll always use
`libc::STDIN_FILENO` for stdin.
- This duplicates the `osstr2str` utility function, rather than
trying to share it across all the configurations that need it.
r? ```@alexcrichton```
This commit adds `as_str` methods to `SplitWhitespace` and `SplitAsciiWhitespace`
str iterators. The methods return the remainder, similar to `as_str` methods on
`Chars` and other split iterators.
This commit also makes fields of some iterators `pub(crate)`.
[librustdoc] Only split lang string on `,`, ` `, and `\t`
Split markdown lang strings into tokens on `,`.
The previous behavior was to split lang strings into tokens on any
character that wasn't a `_`, `_`, or alphanumeric.
This is a potentially breaking change, so please scrutinize! See discussion in #78344.
I noticed some test cases that made me wonder if there might have been some reason for the original behavior:
```
t("{.no_run .example}", false, true, Ignore::None, true, false, false, false, v(), None);
t("{.sh .should_panic}", true, false, Ignore::None, false, false, false, false, v(), None);
t("{.example .rust}", false, false, Ignore::None, true, false, false, false, v(), None);
t("{.test_harness .rust}", false, false, Ignore::None, true, true, false, false, v(), None);
```
It seemed pretty peculiar to specifically test lang strings in braces, with all the tokens prefixed by `.`.
I did some digging, and it looks like the test cases were added way back in [this commit from 2014](https://github.com/rust-lang/rust/commit/3fef7a74ca9a) by `@skade.`
It looks like they were added just to make sure that the splitting was permissive, and aren't testing that those strings in particular are accepted.
Closes https://github.com/rust-lang/rust/issues/78344.
library: Normalize safety-for-unsafe-block comments
Almost all safety comments are of the form `// SAFETY:`,
so normalize the rest and fix a few of them that should
have been a `/// # Safety` section instead.
Furthermore, make `tidy` only allow the uppercase form. While
currently `tidy` only checks `core`, it is a good idea to prevent
`core` from drifting to non-uppercase comments, so that later
we can start checking `alloc` etc. too.
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Update outdated comment in unix Command.
The big comment in the `Command` struct has been incorrect for some time (at least since #46789 which removed `envp`). Rather than try to remove the allocations, this PR just updates the comment to reflect reality. There is an explanation for the reasoning at https://github.com/rust-lang/rust/pull/31409#issuecomment-182122895, discussing the potential of being able to call `Command::exec` after `libc::fork`. That can still be done in the future, but I think for now it would be good to just correct the comment.
Make char and u8 methods const
char methods `len_utf8`, `len_utf16`, `to_ascii_lowercase`, `eq_ignore_ascii_case` can be made const.
`u8` methods `to_ascii_lowercase`, `to_ascii_uppercase` are required to be const as well.
`u8::eq_ignore_ascii_case` was additionally made const.
Rebase of https://github.com/rust-lang/rust/pull/79549 originally authored by ``@YenForYang.`` Changes from that PR:
- Squashed all commits from #79549.
- rebased to latest upstream master.
- Removed const attributes for `char::escape_unicode` and `char::escape_default`.
- Updated `since` attributes for `const` stabilization to 1.52.0.
cc ``@m-ou-se.``
Make ptr::write const
~~The code in this PR as of right now is not much more than an experiment.~~
~~This should, if I am not mistaken, in theory compile and pass the tests once the bootstraping compiler is updated. Thus the PR is blocked on that which should happen some time after the February the 9th. Also we might want to wait for #79989 to avoid regressing performance due to using `mem::forget` over `intrinsics::forget`~~.
Add an impl of Error on `Arc<impl Error>`.
`Display` already exists so this should be a non-controversial change (famous last words).
Would have to be insta-stable.
Convert core/num/mod.rs to intra-doc links
Helps with #75080.
This can't convert the associated constants `MAX` and `MIN` until #74489 is merged.
r? `@poliorcetics`
rust_2015 and rust_2018 are just re-exports of v1.
rust_2021 is a module that for now just re-exports everything from v1,
such that we can add more things later.
Expand FlattenCompat folds
The former `chain`+`chain`+`fold` implementation looked nice from a
functional-programming perspective, but it introduced unnecessary layers
of abstraction on every `flat_map`/`flatten` fold. It's straightforward
to just fold each part in turn, and this makes it look like a simplified
version of the existing `try_fold` implementation.
For the `iter::bench_flat_map*` benchmarks, I get a large improvement in
`bench_flat_map_chain_sum`, from 1,598,473 ns/iter to 499,889 ns/iter,
and the rest are unchanged.
Almost all safety comments are of the form `// SAFETY:`,
so normalize the rest and fix a few of them that should
have been a `/// # Safety` section instead.
Furthermore, make `tidy` only allow the uppercase form. While
currently `tidy` only checks `core`, it is a good idea to prevent
`core` from drifting to non-uppercase comments, so that later
we can start checking `alloc` etc. too.
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
`escape_unicode`, `escape_default`, `len_utf8`, `len_utf16`, to_ascii_lowercase`, `eq_ignore_ascii_case`
`u8` methods `to_ascii_lowercase`, `to_ascii_uppercase` also must be made const
u8 methods made const
Update methods.rs
Update mod.rs
Update methods.rs
Fix `since` in rustc_const_stable to next stable
Fix `since` in rustc_const_stable to next stable
Update methods.rs
Update mod.rs
Improve non_fmt_panic lint.
This change:
- fixes the span used by this lint in the case the panic argument is a single macro expansion (e.g. `panic!(a!())`);
- adds a suggestion for `panic!(format!(..))` to remove `format!()` instead of adding `"{}", ` or using `panic_any` like it does now; and
- fixes the incorrect suggestion to replace `panic![123]` by `panic_any(123]`.
Fixes#82109.
Fixes#82110.
Fixes#82111.
Example output:
```
warning: panic message is not a string literal
--> src/main.rs:8:12
|
8 | panic!(format!("error: {}", "oh no"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(non_fmt_panic)]` on by default
= note: this is no longer accepted in Rust 2021
= note: the panic!() macro supports formatting, so there's no need for the format!() macro here
help: remove the `format!(..)` macro call
|
8 | panic!("error: {}", "oh no");
| -- --
```
r? `@estebank`
This adds API documentation support for `std::os::wasi` modeled after
how `std::os::unix` works, so that WASI can be documented [here] along
with the other platforms.
[here]: https://doc.rust-lang.org/stable/std/os/index.html
Two changes of particular interest:
- This changes the `AsRawFd` for `io::Stdin` for WASI to return
`libc::STDIN_FILENO` instead of `sys::stdio::Stdin.as_raw_fd()` (and
similar for `Stdout` and `Stderr`), which matches how the `unix`
version works. `STDIN_FILENO` etc. may not always be explicitly
reserved at the WASI level, but as long as we have Rust's `std` and
`libc`, I think it's reasonable to guarantee that we'll always use
`libc::STDIN_FILENO` for stdin.
- This duplicates the `osstr2str` utility function, rather than
trying to share it across all the configurations that need it.
Update the bootstrap compiler
This updates the bootstrap compiler, notably leaving out a change to enable semicolon in macro expressions lint, because stdarch still depends on the old behavior.
- Link from `core::hash` to `HashMap` and `HashSet`
- Link from HashMap and HashSet to the module-level documentation on
when to use the collection
- Link from several collections to Wikipedia articles on the general
concept
add diagnostic items for OsString/PathBuf/Owned as well as to_vec on slice
This is adding diagnostic items to be used by rust-lang/rust-clippy#6730, but my understanding is the clippy-side change does need to be done over there since I am adding a new clippy feature.
Add diagnostic items to the following types:
OsString (os_string_type)
PathBuf (path_buf_type)
Owned (to_owned_trait)
As well as the to_vec method on slice/[T]
Make WASI's `hard_link` behavior match other platforms.
Following #78026, `std::fs::hard_link` on most platforms does not follow
symlinks. Change the WASI implementation to also not follow symlinks.
r? ```@alexcrichton```
Avoid `cfg_if` in `std::os`
rust-analyzer cannot currently load the `cfg_if` crate, which means that rust-analyzer is unable to see `std::os::{unix, windows, linux}` here. This works around that by avoiding `cfg_if`; the `#[cfg]` expressions are simple enough to reasonably write by hand.
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/6038
Slight perf improvement on char::to_ascii_lowercase
`char::to_ascii_lowercase()` was checking if it was ascii and then if it was in the right range. Instead propose to check once (I think removing a compare and a shift in the process: [godbolt](https://godbolt.org/z/e5Tora) ).
before:
```
test char::methods::bench_to_ascii_lowercase ... bench: 11,196 ns/iter (+/- 632)
test char::methods::bench_to_ascii_uppercase ... bench: 11,656 ns/iter (+/- 671)
```
after:
```
test char::methods::bench_to_ascii_lowercase ... bench: 9,612 ns/iter (+/- 979)
test char::methods::bench_to_ascii_uppercase ... bench: 8,241 ns/iter (+/- 701)
```
(calling u8::to_ascii_lowercase and letting that flip the 5th bit is also an option, but it's more instructions. I'm thinking for things around ascii and char we want to be as efficient as possible.)
Improve design of `assert_len`
It was discussed in the [tracking issue](https://github.com/rust-lang/rust/issues/76393#issuecomment-761765448) that `assert_len`'s name and usage are confusing. This PR improves them based on a suggestion by ``@scottmcm`` in that issue.
I also improved the documentation to make it clearer when you might want to use this method.
Old example:
```rust
let range = range.assert_len(slice.len());
```
New example:
```rust
let range = range.ensure_subset_of(..slice.len());
```
Fixes#81157
The use of `ExitStatus` as the Rust type name for a Unix *wait
status*, not an *exit status*, is very confusing, but sadly probably
too late to change.
This area is confusing enough in Unix already (and many programmers
are already confuxed). We can at least document it.
I chose *not* to mention the way shells like to exit with signal
numbers, thus turning signal numbers into exit statuses. This is only
relevant for Rust programs using `std::process` if they run shells.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>