Make some `usize`-typed masks definitions agnostic to the size of `usize`
Some masks where defined as
```rust
const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
```
where it was assumed that `usize` is never wider than 64, which is currently true.
To make those constants valid in a hypothetical 128-bit target, these constants have been redefined in an `usize`-width-agnostic way
```rust
const NONASCII_MASK: usize = usize::from_ne_bytes([0x80; size_of::<usize>()]);
```
There are already some cases where Rust anticipates the possibility of supporting 128-bit targets, such as not implementing `From<usize>` for `u64`.
docs: add link from zip to unzip
The docs for `Iterator::unzip` explain that it is kind of an inverse operation to `Iterator::zip` and guide the reader to the `zip` docs, but the `zip` docs don't let the user know that they can undo the `zip` operation with `unzip`. This change modifies the docs to help the user find `unzip`.
reference to taking `self` by value. This is consistent with the methods
of the same names on primitive pointers. The returned lifetime was
already previously unbounded.
Create (unstable) 2024 edition
[On Zulip](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Deprecating.20macro.20scoping.20shenanigans/near/272860652), there was a small aside regarding creating the 2024 edition now as opposed to later. There was a reasonable amount of support and no stated opposition.
This change creates the 2024 edition in the compiler and creates a prelude for the 2024 edition. There is no current difference between the 2021 and 2024 editions. Cargo and other tools will need to be updated separately, as it's not in the same repository. This change permits the vast majority of work towards the next edition to proceed _now_ instead of waiting until 2024.
For sanity purposes, I've merged the "hello" UI tests into a single file with multiple revisions. Otherwise we'd end up with a file per edition, despite them being essentially identical.
````@rustbot```` label +T-lang +S-waiting-on-review
Not sure on the relevant team, to be honest.
Stabilize `derive_default_enum`
This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](https://github.com/rust-lang/rfcs/pull/3107) and tracked in #87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility).
```````@rustbot``````` label +S-waiting-on-review +T-lang
Some masks where defined as
```rust
const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
```
where it was assumed that `usize` is never wider than 64, which is currently true.
To make those constants valid in a hypothetical 128-bit target, these constants have been redefined in an `usize`-width-agnostic way
```rust
const NONASCII_MASK: usize = usize::from_ne_bytes([0x80; size_of::<usize>()]);
```
There are already some cases where Rust anticipates the possibility of supporting 128-bit targets, such as not implementing `From<usize>` for `u64`.
The docs for `Iterator::unzip` explain that it is kind of an inverse operation to `Iterator::zip` and guide the reader to the `zip` docs, but the `zip` docs don't let the user know that they can undo the `zip` operation with `unzip`. This change modifies the docs to help the user find `unzip`.
Implement tuples using recursion
Because it is c00l3r™, requires less repetition and can be used as a reference for external people.
This change is non-essential and I am not sure about potential performance impacts so feel free to close this PR if desired.
r? `@petrochenkov`
Faster parsing for lower numbers for radix up to 16 (cont.)
( Continuation of https://github.com/rust-lang/rust/pull/83371 )
With LingMan's change I think this is potentially ready.
Clarify str::from_utf8_unchecked's invariants
Specifically, make it clear that it is immediately UB to pass ill-formed UTF-8 into the function. The previous wording left space to interpret that the UB only occurred when calling another function, which "assumes that `&str`s are valid UTF-8."
This does not change whether str being UTF-8 is a safety or a validity invariant. (As per previous discussion, it is a safety invariant, not a validity invariant.) It just makes it clear that valid UTF-8 is a precondition of str::from_utf8_unchecked, and that emitting an Abstract Machine fault (e.g. UB or a sanitizer error) on invalid UTF-8 is a valid thing to do.
If user code wants to create an unsafe `&str` pointing to ill-formed UTF-8, it must be done via transmutes. Also, just, don't.
Zulip discussion: https://rust-lang.zulipchat.com/#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/str.3A.3Afrom_utf8_unchecked.20Safety.20requirement
Update binary_search example to instead redirect to partition_point
Inspired by discussion in the tracking issue for `Result::into_ok_or_err`: https://github.com/rust-lang/rust/issues/82223#issuecomment-1067098167
People are surprised by us not providing a `Result<T, T> -> T` conversion, and the main culprit for this confusion seems to be the `binary_search` API. We should instead redirect people to the equivalent API that implicitly does that `Result<T, T> -> T` conversion internally which should obviate the need for the `into_ok_or_err` function and give us time to work towards a more general solution that applies to all enums rather than just `Result` such as making or_patterns usable for situations like this via postfix `match`.
I choose to duplicate the example rather than simply moving it from `binary_search` to partition point because most of the confusion seems to arise when people are looking at `binary_search`. It makes sense to me to have the example presented immediately rather than requiring people to click through to even realize there is an example. If I had to put it in only one place I'd leave it in `binary_search` and remove it from `partition_point` but it seems pretty obviously relevant to `partition_point` so I figured the best option would be to duplicate it.
Specifically, make it clear that it is immediately UB to pass ill-formed UTF-8 into the function. The previous wording left space to interpret that the UB only occurred when calling another function, which "assumes that `&str`s are valid UTF-8."
This does not change whether str being UTF-8 is a safety or a validity invariant. (As per previous discussion, it is a safety invariant, not a validity invariant.) It just makes it clear that valid UTF-8 is a precondition of str::from_utf8_unchecked, and that emitting an Abstract Machine fault (e.g. UB or a sanitizer error) on invalid UTF-8 is a valid thing to do.
If user code wants to create an unsafe `&str` pointing to ill-formed UTF-8, it must be done via transmutes. Also, just, don't.
Avoid duplication of doc comments in `std::char` constants and functions
For those consts and functions, only the summary is kept and a reference to the `char` associated const/method is included.
Additionaly, re-exported functions have been converted to function definitions that call the previously re-exported function. This makes it easier to add a deprecated attribute to these functions in the future.
Use bitwise XOR in to_ascii_uppercase
This saves an instruction compared to the previous approach, which
was to unset the fifth bit with bitwise OR.
Comparison of generated assembly on x86: https://godbolt.org/z/GdfvdGs39
This can also affect autovectorization, saving SIMD instructions as well: https://godbolt.org/z/cnPcz75T9
Not sure if `u8::to_ascii_lowercase` should also be changed, since using bitwise OR for that function does not require an extra bitwise negate since the code is setting a bit rather than unsetting a bit. `char::to_ascii_uppercase` already uses XOR, so no change seems to be required there.
Left overs of #95761
These are just nits. Feel free to close this PR if all modifications are not worth merging.
* `#![feature(decl_macro)]` is not needed anymore in `rustc_expand`
* `tuple_impls` does not require `$Tuple:ident`. I guess it is there to enhance readability?
r? ```@petrochenkov```
Make non-power-of-two alignments a validity error in `Layout`
Inspired by the zulip conversation about how `Layout` should better enforce `size <= isize::MAX as usize`, this uses an N-variant enum on N-bit platforms to require at the validity level that the existing invariant of "must be a power of two" is upheld.
This was MIRI can catch it, and means there's a more-specific type for `Layout` to store than just `NonZeroUsize`.
It's left as `pub(crate)` here; a future PR could consider giving it a tracking issue for non-internal usage.
Inspired by the zulip conversation about how `Layout` should better enforce `size < isize::MAX as usize`, this uses an N-variant enum on N-bit platforms to require at the validity level that the existing invariant of "must be a power of two" is upheld.
This was MIRI can catch it, and means there's a more-specific type for `Layout` to store than just `NonZeroUsize`.
Correct safety reasoning in `str::make_ascii_{lower,upper}case()`
I don't understand why the previous comment was used (it was inserted in #66564), but it doesn't explain why these functions are safe, only why `str::as_bytes{_mut}()` are safe.
If someone thinks they make perfect sense, I'm fine with closing this PR.
Bump bootstrap compiler to 1.61.0 beta
This PR bumps the bootstrap compiler to the 1.61.0 beta. The first commit changes the stage0 compiler, the second commit applies the "mechanical" changes and the third and fourth commits apply changes explained in the relevant comments.
r? `@Mark-Simulacrum`
Mention `std::env::var` in `env!`
When searching for how to read an environment variable, I first encountered the `env!` macro. It would have been useful to me if the documentation had included a link to `std::env::var`, which is what I was actually looking for.
When searching for how to read an environment variable, I first encountered the `env!` macro. It would have been useful to me if the documentation had included a link to `std::env::var`, which is what I was actually looking for.
caution against ptr-to-int transmutes
I don't know how strong of a statement we want to make here, but I am very concerned that the current docs could be interpreted as saying that ptr-to-int transmutes are just as okay as transmuting `*mut T` into an `&mut T`.
Examples [like this](https://github.com/rust-lang/unsafe-code-guidelines/issues/286#issuecomment-1085144431) show that ptr-to-int transmutes are deeply suspicious -- they are either UB, or they don't round-trip properly, or we have to basically say that `transmute` will actively look for pointers and do all the things a ptr-to-int cast does (which includes a global side-effect of marking the pointed-to allocation as 'exposed').
Another alternative might be to simply not talk about them... but we *do* want people to use casts rather than transmutes for this.
Cc `@rust-lang/lang`
Update panic docs to make it clearer when to use panic vs Result
This is based on a question that came up in one of my [error handling office hours](https://twitter.com/yaahc_/status/1506376624509374467?s=20&t=Sp-cEjrx5kpMdNsAGPOo9w) meetings. I had a user who was fairly familiar with error type design, thiserror and anyhow, and rust in general, but who was still confused about when to use panics vs when to use Result and `Error`.
This will also be cross referenced in an error handling FAQ that I will be creating in the https://github.com/rust-lang/project-error-handling repo shortly.
explicitly distinguish pointer::addr and pointer::expose_addr
``@bgeron`` pointed out that the current docs promise that `ptr.addr()` and `ptr as usize` are equivalent. I don't think that is a promise we want to make. (Conceptually, `ptr as usize` might 'escape' the provenance to enable future `usize as ptr` casts, but `ptr.addr()` dertainly does not do that.)
So I propose we word the docs a bit more carefully here. ``@Gankra`` what do you think?
Mention implementers of unsatisfied trait
When encountering an unsatisfied trait bound, if there are no other
suggestions, mention all the types that *do* implement that trait:
```
error[E0277]: the trait bound `f32: Foo` is not satisfied
--> $DIR/impl_wf.rs:22:6
|
LL | impl Baz<f32> for f32 { }
| ^^^^^^^^ the trait `Foo` is not implemented for `f32`
|
= help: the trait `Foo` is implemented for `i32`
note: required by a bound in `Baz`
--> $DIR/impl_wf.rs:18:31
|
LL | trait Baz<U: ?Sized> where U: Foo { }
| ^^^ required by this bound in `Baz`
```
```
error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:29:5
|
LL | f1(2u32, 4u32);
| ^^ the trait `Foo` is not implemented for `u32`
|
= help: the trait `Foo` is implemented for `i32`
note: required by a bound in `f1`
--> $DIR/associated-types-path-2.rs:13:14
|
LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
| ^^^ required by this bound in `f1`
```
Suggest dereferencing in more cases.
Fix#87437, fix#90970.
When encountering an unsatisfied trait bound, if there are no other
suggestions, mention all the types that *do* implement that trait:
```
error[E0277]: the trait bound `f32: Foo` is not satisfied
--> $DIR/impl_wf.rs:22:6
|
LL | impl Baz<f32> for f32 { }
| ^^^^^^^^ the trait `Foo` is not implemented for `f32`
|
= help: the following other types implement trait `Foo`:
Option<T>
i32
str
note: required by a bound in `Baz`
--> $DIR/impl_wf.rs:18:31
|
LL | trait Baz<U: ?Sized> where U: Foo { }
| ^^^ required by this bound in `Baz`
```
Mention implementers of traits in `ImplObligation`s.
Do not mention other `impl`s for closures, ranges and `?`.
Add SyncUnsafeCell.
This adds `SyncUnsafeCell`, which is just `UnsafeCell` except it implements `Sync`.
This was first proposed under the name `RacyUnsafeCell` here: https://github.com/rust-lang/rust/issues/53639#issuecomment-415515748 and here: https://github.com/rust-lang/rust/issues/53639#issuecomment-432741659 and here: https://github.com/rust-lang/rust/issues/53639#issuecomment-888435728
It allows you to create an UnsafeCell that is Sync without having to wrap it in a struct first (and then implement Sync for that struct).
E.g. `static X: SyncUnsafeCell<i32>`. Using a regular `UnsafeCell` as `static` is not possible, because it isn't `Sync`. We have a language workaround for it called `static mut`, but it's nice to be able to use the proper type for such unsafety instead.
It also makes implementing synchronization primitives based on unsafe cells slightly less verbose, because by using `SyncUnsafeCell` for `UnsafeCell`s that are shared between threads, you don't need a separate `impl<..> Sync for ..`. Using this type also clearly documents that the cell is expected to be accessed from multiple threads.
Mark Location::caller() as #[inline]
This function gets compiled to a single register move as it actually gets it's return value passed in as argument.
Fix &mut invalidation in ptr::swap doctest
Under Stacked Borrows with raw pointer tagging, the previous code was UB
because the code which creates the the second pointer borrows the array
through a tag in the borrow stacks below the Unique tag that our first
pointer is based on, thus invalidating the first pointer.
This is not definitely a bug and may never be real UB, but I desperately
want people to write code that conforms to SB with raw pointer tagging
so that I can write good diagnostics. The alternative aliasing models
aren't possible to diagnose well due to state space explosion.
Therefore, it would be super cool if the standard library nudged people
towards writing code that is valid with respect to SB with raw pointer
tagging.
The diagnostics that I want to write are implemented in a branch of Miri and the one for this case is below:
```
error: Undefined Behavior: attempting a read access using <2170> at alloc1068[0x0], but that tag does not exist in the borrow stack for this location
--> /home/ben/rust/library/core/src/intrinsics.rs:2103:14
|
2103 | unsafe { copy_nonoverlapping(src, dst, count) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| attempting a read access using <2170> at alloc1068[0x0], but that tag does not exist in the borrow stack for this location
| this error occurs as part of an access at alloc1068[0x0..0x8]
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <2170> was created due to a retag at offsets [0x0..0x10]
--> ../libcore/src/ptr/mod.rs:640:9
|
8 | let x = array[0..].as_mut_ptr() as *mut [u32; 2]; // this is `array[0..2]`
| ^^^^^^^^^^^^^^^^^^^^^^^
help: <2170> was later invalidated due to a retag at offsets [0x0..0x10]
--> ../libcore/src/ptr/mod.rs:641:9
|
9 | let y = array[2..].as_mut_ptr() as *mut [u32; 2]; // this is `array[2..4]`
| ^^^^^
= note: inside `std::intrinsics::copy_nonoverlapping::<[u32; 2]>` at /home/ben/rust/library/core/src/intrinsics.rs:2103:14
= note: inside `std::ptr::swap::<[u32; 2]>` at /home/ben/rust/library/core/src/ptr/mod.rs:685:9
note: inside `main::_doctest_main____libcore_src_ptr_mod_rs_635_0` at ../libcore/src/ptr/mod.rs:12:5
--> ../libcore/src/ptr/mod.rs:644:5
|
12 | ptr::swap(x, y);
| ^^^^^^^^^^^^^^^
note: inside `main` at ../libcore/src/ptr/mod.rs:15:3
--> ../libcore/src/ptr/mod.rs:647:3
|
15 | } _doctest_main____libcore_src_ptr_mod_rs_635_0() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to previous error
```
Under Stacked Borrows with raw pointer tagging, the previous code was UB
because the code which creates the the second pointer borrows the array
through a tag in the borrow stacks below the Unique tag that our first
pointer is based on, thus invalidating the first pointer.
This is not definitely a bug and may never be real UB, but I desperately
want people to write code that conforms to SB with raw pointer tagging
so that I can write good diagnostics. The alternative aliasing models
aren't possible to diagnose well due to state space explosion.
Therefore, it would be super cool if the standard library nudged people
towards writing code that is valid with respect to SB with raw pointer
tagging.
Improve doc example of DerefMut
It is more illustrative, after using `*x` to modify the field, to show
in the assertion that the field has indeed been modified.
Add debug assertions to some unsafe functions
As suggested by https://github.com/rust-lang/rust/issues/51713
~~Some similar code calls `abort()` instead of `panic!()` but aborting doesn't work in a `const fn`, and the intrinsic for doing dispatch based on whether execution is in a const is unstable.~~
This picked up some invalid uses of `get_unchecked` in the compiler, and fixes them.
I can confirm that they do in fact pick up invalid uses of `get_unchecked` in the wild, though the user experience is less-than-awesome:
```
Running unittests (target/x86_64-unknown-linux-gnu/debug/deps/rle_decode_fast-04b7918da2001b50)
running 6 tests
error: test failed, to rerun pass '--lib'
Caused by:
process didn't exit successfully: `/home/ben/rle-decode-helper/target/x86_64-unknown-linux-gnu/debug/deps/rle_decode_fast-04b7918da2001b50` (signal: 4, SIGILL: illegal instruction)
```
~~As best I can tell these changes produce a 6% regression in the runtime of `./x.py test` when `[rust] debug = true` is set.~~
Latest commit (6894d559bd) brings the additional overhead from this PR down to 0.5%, while also adding a few more assertions. I think this actually covers all the places in `core` that it is reasonable to check for safety requirements at runtime.
Thoughts?
`&mut [T]` implies validity which automatically makes `ptr::add` ok within its bounds.
But `*mut [T]` does not. Since we still want the benefits of in-bounds pointer arithmetic
`split_at_must` must require the caller to pass valid pointers and therefore it is `unsafe`.
Split out from #94247
This adds the following methods to raw slices that already exist on regular slices
* `*mut [T]::is_empty`
* `*mut [T]::split_at_mut`
* `*mut [T]::split_at_unchecked`
These methods reduce the amount of unsafe code needed to migrate ChunksMut and related iterators
to raw slices (#94247)
Co-authored-by:: The 8472 <git@infinite-source.de>
Implement provenance preserving methods on NonNull
### Description
Add the `addr`, `with_addr`, `map_addr` methods to the `NonNull` type, and map the address type to `NonZeroUsize`.
### Motivation
The `NonNull` type is useful for implementing pointer types which have the 0-niche. It is currently possible to implement these provenance preserving functions by calling `NonNull::as_ptr` and `new_unchecked`. The adding these methods makes it more ergonomic.
### Testing
Added a unit test of a non-null tagged pointer type. This is based on some real code I have elsewhere, that currently routes the pointer through a `NonZeroUsize` and back out to produce a usable pointer. I wanted to produce an ideal version of the same tagged pointer struct that preserved pointer provenance.
### Related
Extension of APIs proposed in #95228 . I can also split this out into a separate tracking issue if that is better (though I may need some pointers on how to do that).
Handle rustc_const_stable attribute in library feature collector
The library feature collector in [compiler/rustc_passes/src/lib_features.rs](551b4fa395/compiler/rustc_passes/src/lib_features.rs) has only been looking at `#[stable(…)]`, `#[unstable(…)]`, and `#[rustc_const_unstable(…)]` attributes, while ignoring `#[rustc_const_stable(…)]`. The consequences of this were:
- When any const feature got stabilized (changing one or more `rustc_const_unstable` to `rustc_const_stable`), users who had previously enabled that unstable feature using `#![feature(…)]` would get told "unknown feature", rather than rustc's nicer "the feature … has been stable since … and no longer requires an attribute to enable".
This can be seen in the way that https://github.com/rust-lang/rust/pull/93957#issuecomment-1079794660 failed after rebase:
```console
error[E0635]: unknown feature `const_ptr_offset`
--> $DIR/offset_from_ub.rs:1:35
|
LL | #![feature(const_ptr_offset_from, const_ptr_offset)]
| ^^^^^^^^^^^^^^^^
```
- We weren't enforcing that a particular feature is either stable everywhere or unstable everywhere, and that a feature that has been stabilized has the same stabilization version everywhere, both of which we enforce for the other stability attributes.
This PR updates the library feature collector to handle `rustc_const_stable`, and fixes places in the standard library and test suite where `rustc_const_stable` was being used in a way that does not meet the rules for a stability attribute.
For those consts and functions, only the summary is kept and a reference to the `char` associated const/method is included.
Additionaly, re-exported functions have been converted to function definitions that call the previously re-exported function. This makes it easier to add a deprecated attribute to these functions in the future.
add notes about alignment-altering reallocations to Allocator docs
As I said in https://github.com/rust-lang/wg-allocators/issues/97, the fact that calls to `grow`, `grow_zeroed`, and `shrink` may request altered alignments is surprising and may be a pitfall for implementors of `Allocator` if it's left implicit. This pull request adds a note to the "Safety" section of each function's docs making it explicit.
skip slow int_log tests in Miri
Iterating over i16::MAX many things takes a long time in Miri, let's not do that.
I added https://github.com/rust-lang/miri/pull/2044 on the Miri side to still give us some test coverage.
ptr_metadata test: avoid ptr-to-int transmutes
Pointers can have provenance, integers don't, so transmuting pointers to integers creates "non-standard" values and it is unclear how well those can be supported (https://github.com/rust-lang/unsafe-code-guidelines/issues/286).
So for this test let's take the safer option and use a pointer type instead. That also makes Miri happy. :)
**Description**
Add the `addr`, `with_addr, `map_addr` methods to the `NonNull` type,
and map the address type to `NonZeroUsize`.
**Motiviation**
The `NonNull` type is useful for implementing pointer types which have
the 0-niche. It is currently possible to implement these provenance
preserving functions by calling `NonNull::as_ptr` and `new_unchecked`.
The addition of these methods simply make it more ergonomic to use.
**Testing**
Added a unit test of a nonnull tagged pointer type. This is based on
some real code I have elsewhere, that currently routes the pointer
through a `NonZeroUsize` and back out to produce a usable pointer.
Update target_has_atomic documentation for stabilization
`cfg(target_has_atomic)` was stabilized in #93824, but this small note in the docs was not updated at the time.
- Refine the "NaN as a special value" top level explanation of f32
- Refine `const NAN` docstring.
- Refine `fn is_sign_positive` and `fn is_sign_negative` docstrings.
- Refine `fn min` and `fn max` docstrings.
- Refine `fn trunc` docstrings.
- Refine `fn powi` docstrings.
- Refine `fn copysign` docstrings.
- Reword `NaN` and `NAN` as plain "NaN", unless they refer to the specific `const NAN`.
- Reword "a number" to `self` in function docstrings to clarify.
- Remove "Returns NAN if the number is NAN" as this is told to be the default behavior in the top explanation.
- Remove "propagating NaNs", as full propagation (preservation of payloads) is not guaranteed.
allow arbitrary inherent impls for builtin types in core
Part of https://github.com/rust-lang/compiler-team/issues/487. Slightly adjusted after some talks with `@m-ou-se` about the requirements of `t-libs-api`.
This adds a crate attribute `#![rustc_coherence_is_core]` which allows arbitrary impls for builtin types in core.
For other library crates impls for builtin types should be avoided if possible. We do have to allow the existing stable impls however. To prevent us from accidentally adding more of these in the future, there is a second attribute `#[rustc_allow_incoherent_impl]` which has to be added to **all impl items**. This only supports impls for builtin types but can easily be extended to additional types in a future PR.
This implementation does not check for overlaps in these impls. Perfectly checking that requires us to check the coherence of these incoherent impls in every crate, as two distinct dependencies may add overlapping methods. It should be easy enough to detect if it goes wrong and the attribute is only intended for use inside of std.
The first two commits are mostly unrelated cleanups.
This patch series examines the question: how bad would it be if we adopted
an extremely strict pointer provenance model that completely banished all
int<->ptr casts.
The key insight to making this approach even *vaguely* pallatable is the
ptr.with_addr(addr) -> ptr
function, which takes a pointer and an address and creates a new pointer
with that address and the provenance of the input pointer. In this way
the "chain of custody" is completely and dynamically restored, making the
model suitable even for dynamic checkers like CHERI and Miri.
This is not a formal model, but lots of the docs discussing the model
have been updated to try to the *concept* of this design in the hopes
that it can be iterated on.
These debug assertions are all implemented only at runtime using
`const_eval_select`, and in the error path they execute
`intrinsics::abort` instead of being a normal debug assertion to
minimize the impact of these assertions on code size, when enabled.
Of all these changes, the bounds checks for unchecked indexing are
expected to be most impactful (case in point, they found a problem in
rustc).
Refactor set_ptr_value as with_metadata_of
Replaces `set_ptr_value` (#75091) with methods of reversed argument order:
```rust
impl<T: ?Sized> *mut T {
pub fn with_metadata_of<U: ?Sized>(self, val: *mut U) -> *mut U;
}
impl<T: ?Sized> *const T {
pub fn with_metadata_of<U: ?Sized>(self, val: *const U) -> *const U;
}
```
By reversing the arguments we achieve several clarifications:
- The function closely resembles `cast` with an argument to
initialize the metadata. This is easier to teach and answers a long
outstanding question that had restricted cast to `Sized` pointee
targets. See multiples reviews of
<https://github.com/rust-lang/rust/pull/47631>
- The 'object identity', in the form of provenance, is now preserved
from the receiver argument to the result. This helps explain the method as
a builder-style, instead of some kind of setter that would modify
something in-place. Ensuring that the result has the identity of the
`self` argument is also beneficial for an intuition of effects.
- An outstanding concern, 'Correct argument type', is avoided by not
committing to any specific argument type. This is consistent with cast
which does not require its receiver to be a 'raw address'.
Hopefully the usage examples in `sync/rc.rs` serve as sufficient examples of the style to convince the reader of the readability improvements of this style, when compared to the previous order of arguments.
I want to take the opportunity to motivate inclusion of this method _separate_ from metadata API, separate from `feature(ptr_metadata)`. It does _not_ involve the `Pointee` trait in any form. This may be regarded as a very, very light form that does not commit to any details of the pointee trait, or its associated metadata. There are several use cases for which this is already sufficient and no further inspection of metadata is necessary.
- Storing the coercion of `*mut T` into `*mut dyn Trait` as a way to dynamically cast some an arbitrary instance of the same type to a dyn trait instance. In particular, one can have a field of type `Option<*mut dyn io::Seek>` to memorize if a particular writer is seekable. Then a method `fn(self: &T) -> Option<&dyn Seek>` can be provided, which does _not_ involve the static trait bound `T: Seek`. This makes it possible to create an API that is capable of utilizing seekable streams and non-seekable streams (instead of a possible less efficient manner such as more buffering) through the same entry-point.
- Enabling more generic forms of unsizing for no-`std` smart pointers. Using the stable APIs only few concrete cases are available. One can unsize arrays to `[T]` by `ptr::slice_from_raw_parts` but unsizing a custom smart pointer to, e.g., `dyn Iterator`, `dyn Future`, `dyn Debug`, can't easily be done generically. Exposing `with_metadata_of` would allow smart pointers to offer their own `unsafe` escape hatch with similar parameters where the caller provides the unsized metadata. This is particularly interesting for embedded where `dyn`-trait usage can drastically reduce code size.
Clarify that ManuallyDrop<T> has same layout as T
This PR implements the documentation change under discussion in https://github.com/rust-lang/unsafe-code-guidelines/issues/302. It should not be approved or merged until the discussion there is resolved.
add diagnostic items for clippy's `trim_split_whitespace`
Adding the following diagnostic items:
* str_split_whitespace,
* str_trim,
* str_trim_start,
* str_trim_end
They are needed for https://github.com/rust-lang/rust-clippy/pull/8575
r? `@flip1995`
add module-level documentation for vec's in-place iteration
As requested in the last libs team meeting and during previous reviews.
Feel free to point out any gaps you encounter, after all non-obvious things may with hindsight seem obvious to me.
r? `@yaahc`
CC `@steffahn`
By reversing the arguments we achieve several clarifications:
- The function closely resembles `cast` but with an argument to
initialized the metadata. This is easier to teach and answers an long
outstanding question that had restricted cast to `Sized` targets
initially. See multiples reviews of
<https://github.com/rust-lang/rust/pull/47631>
- The 'object identity', in the form or provenance, is now preserved
from the call receiver to the result. This helps explain the method as
a builder-style, instead of some kind of setter that would modify
something in-place. Ensuring that the result has the identity of the
`self` argument is also beneficial for an intuition of effects.
- An outstanding concern, 'Correct argument type', is avoided by not
committing to any specific argument type. This is consistent with cast
which does not require its receiver to be a raw address.
Rename `~const Drop` to `~const Destruct`
r? `@oli-obk`
Completely switching to `~const Destructible` would be rather complicated, so it seems best to add it for now and wait for it to be backported to beta in the next release.
The rationale is to prevent complications such as #92149 and #94803 by introducing an entirely new trait. And `~const Destructible` reads a bit better than `~const Drop`. Name Bikesheddable.
Add u16::is_utf16_surrogate
Right now, there are methods in the standard library for encoding and decoding UTF-16, but at least for the moment, there aren't any methods specifically for `u16` to help work with UTF-16 data. Since the full logic already exists, this wouldn't really add any code, just expose what's already there.
This method in particular is useful for working with the data returned by Windows `OsStrExt::encode_wide`. Initially, I was planning to also offer a `TryFrom<u16> for char`, but decided against it for now. There is plenty of code in rustc that could be rewritten to use this method, but I only checked within the standard library to replace them.
I think that offering more UTF-16-related methods to u16 would be useful, but I think this one is a good start. For example, one useful method might be `u16::is_pattern_whitespace`, which would check if something is the Unicode `Pattern_Whitespace` category. We can get away with this because all of the `Pattern_Whitespace` characters are in the basic multilingual plane, and hence we don't need to check for surrogates.
Provide more useful documentation of conversion methods
I thought that the documentation for these methods needed to be a bit more explanatory for new users. For advanced users, the comments are relatively unnecessary. I think it would be useful to explain precisely what the method does. As a new user, when you see the `into` method, where the type is inferred, if you are new you don't even know what you convert to, because it is implicit. I believe this can help new users understand.
I thought that the documentation for these methods needed to be a bit more explanatory for new users. For advanced users, the comments are relatively unnecessary. I think it would be useful to explain precisely what the method does. As a new user, when you see the `into` method, where the type is inferred, if you are new you don't even know what you convert to, because it is implicit. I believe this can help new users understand.
Document that `Option<extern "abi" fn>` discriminant elision applies for any ABI
The current phrasing was not very clear on that aspect.
r? `@RalfJung`
`@rustbot` modify labels: A-docs A-ffi
Derive Eq for std::cmp::Ordering, instead of using manual impl.
This allows consts of type Ordering to be used in patterns, and with feature(adt_const_params) allows using `Ordering` as a const generic parameter.
Currently, `std::cmp::Ordering` implements `Eq` using a manually written `impl Eq for Ordering {}`, instead of `derive(Eq)`. This means that it does not implement `StructuralEq`.
This commit removes the manually written impl, and adds `derive(Eq)` to `Ordering`, so that it will implement `StructuralEq`.
Let `try_collect` take advantage of `try_fold` overrides
No public API changes.
With this change, `try_collect` (#94047) is no longer going through the `impl Iterator for &mut impl Iterator`, and thus will be able to use `try_fold` overrides instead of being forced through `next` for every element.
Here's the test added, to see that it fails before this PR (once a new enough nightly is out): https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=462f2896f2fed2c238ee63ca1a7e7c56
This might as well go to the same person as my last `try_process` PR (#93572), so
r? ``@yaahc``
Stabilize ADX target feature
This is a continuation of #60109, which noted that while the ADX intrinsics were stabilized, the corresponding target feature never was.
This PR follows the same general structure and stabilizes the ADX target feature.
See also https://github.com/rust-lang/rust/issues/44839 - tracking issue for target feature
Format core and std macro rules, removing needless surrounding blocks
Many of the asserting and printing macros in `core` and `std` are written with prehistoric-looking formatting, like this:
335ffbfa54/library/std/src/macros.rs (L96-L101)
In modern Rust style this would conventionally be written as follows instead, always using braces and a trailing semicolon on the macro arms:
af53809c87/library/std/src/macros.rs (L98-L105)
Getting rid of the unneeded braces inside the expansion reduces extraneous indentation in macro-expanded code. For example:
```rust
println!("repro {}", true);
```
```rust
// before:
{
::std::io::_print(
::core::fmt::Arguments::new_v1(
&["repro ", "\n"],
&[::core::fmt::ArgumentV1::new_display(&true)],
),
);
};
```
```rust
// after:
::std::io::_print(
::core::fmt::Arguments::new_v1(
&["repro ", "\n"],
&[::core::fmt::ArgumentV1::new_display(&true)],
),
);
```
This is a continuation of #60109, which noted that while the ADX
intrinsics were stabilized, the corresponding target feature never was.
This PR follows the same general structure and stabilizes the ADX target
feature.
Add `Atomic*::get_mut_slice`
This PR adds the inverse of `Atomic*::from_mut_slice` introduced in #94384 with the following API:
```rust
// core::sync::atomic
impl Atomic* {
fn get_mut_slice(this: &mut [Self]) -> &mut [*];
}
```
cc `@cuviper`
-----
For now I've used the same tracking issue as `Atomic*::from_mut_slice`, should I open a new one?
Enable conditional checking of values in the Rust codebase
This pull-request enable conditional checking of (well known) values in the Rust codebase.
Well known values were added in https://github.com/rust-lang/rust/pull/94362. All the `target_*` values are taken from all the built-in targets which is why some extra values were needed do be added as they are not (yet ?) defined in any built-in targets.
r? `@Mark-Simulacrum`
Make float parsing docs more comprehensive
I was working on some code with some specialized restrictions on float parsing. I noticed the doc comments for `f32::from_str` and `f64::from_str` were missing several cases of valid inputs that are otherwise difficult to discover without looking at source code.
I'm not sure if the doc comments were initially intended to contain a comprehensive description of valid inputs, but I figured it's useful to include these extra cases for reference.
Rename `IntoFuture::Future` to `IntoFuture::IntoFuture`
Ref: https://github.com/rust-lang/rust/issues/67644#issuecomment-1051401459
This renames `IntoFuture::Future` to `IntoFuture::IntoFuture`. This adds the `Into*` prefix to the associated type, similar to the [`IntoIterator::IntoIter`](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html#associatedtype.IntoIter) associated type. It's my mistake we didn't do so in the first place. This fixes that and brings the two closer together. Thanks!
### References
__`IntoIterator` trait def__
```rust
pub trait IntoIterator {
type Item;
type IntoIter: Iterator<Item = Self::Item>;
fn into_iter(self) -> Self::IntoIter;
}
```
__`IntoFuture` trait def__
```rust
pub trait IntoFuture {
type Output;
type IntoFuture: Future<Output = Self::Output>; // Prior to this PR: `type Future:`
fn into_future(self) -> Self::IntoFuture;
}
```
cc/ `@eholk` `@rust-lang/wg-async`
Remove unnecessary try_opt for operations that cannot fail
As indicated in the added comments, some operation cannot overflow, so using `try_opt!` for them is unnecessary.
Optimize ascii::escape_default
`ascii::escape_default` showed up as a hot function when compiling `deunicode-1.3.1` in `@nnethercote's` [analysis](https://hackmd.io/mxdn4U58Su-UQXwzOHpHag) of `@lqd's` [rustc-benchmarking-data](https://github.com/lqd/rustc-benchmarking-data).
After taking a look at the generated assembly it looked like a LUT-based approach could be faster for `hexify()`-ing ascii characters, so that's what this PR implements
The patch looks like it provides about a 1-2% improvement in instructions for that particular crate. This should definitely be verified with a perf run as I'm still getting used to the `rustc-perf` tooling and might easily have made an error!
Rename is_{some,ok,err}_with to is_{some,ok,err}_and.
This renames `is_{some,ok,err}_with` to `is_{some,ok,err}_and`. This was discussed on the [tracking issue](https://github.com/rust-lang/rust/issues/93050).
Use modern formatting for format! macros
This updates the standard library's documentation to use the new format_args syntax.
The documentation is worthwhile to update as it should be more idiomatic
(particularly for features like this, which are nice for users to get acquainted
with). The general codebase is likely more hassle than benefit to update: it'll
hurt git blame, and generally updates can be done by folks updating the code if
(and when) that makes things more readable with the new format.
A few places in the compiler and library code are updated (mostly just due to
already having been done when this commit was first authored).
`eprintln!("{}", e)` becomes `eprintln!("{e}")`, but `eprintln!("{}", e.kind())` remains untouched.
Document new recommended use of `FromIterator::from_iter`
#90107
Most of the added prose was paraphrased from the links provided in the issue. The suggested `VecDeque` example seemed to make the point well enough so I just used that.
This updates the standard library's documentation to use the new syntax. The
documentation is worthwhile to update as it should be more idiomatic
(particularly for features like this, which are nice for users to get acquainted
with). The general codebase is likely more hassle than benefit to update: it'll
hurt git blame, and generally updates can be done by folks updating the code if
(and when) that makes things more readable with the new format.
A few places in the compiler and library code are updated (mostly just due to
already having been done when this commit was first authored).
diagnostics: use rustc_on_unimplemented to recommend `[].iter()`
To make this work, the `#[rustc_on_unimplemented]` data needs to be used to
report method resolution errors, which is most of what this commit does.
Fixes#94581
Constify `Index{,Mut}` for `[T]`, `str`, and `[T; N]`
Several panic functions were rewired (via `const_eval_select`) to simpler implementations that do not require formatting for compile-time usage.
r? ```@oli-obk```
Merge `#[deprecated]` and `#[rustc_deprecated]`
The first commit makes "reason" an alias for "note" in `#[rustc_deprecated]`, while still prohibiting it in `#[deprecated]`.
The second commit changes "suggestion" to not just be a feature of `#[rustc_deprecated]`. This is placed behind the new `deprecated_suggestion` feature. This needs a tracking issue; let me know if this PR will be approved and I can create one.
The third commit is what permits `#[deprecated]` to be used when `#![feature(staged_api)]` is enabled. This isn't yet used in stdlib (only tests), as it would require duplicating all deprecation attributes until a bootstrap occurs. I intend to submit a follow-up PR that replaces all uses and removes the remaining `#[rustc_deprecated]` code after the next bootstrap.
`@rustbot` label +T-libs-api +C-feature-request +A-attributes +S-waiting-on-review
Add Iterator::collect_into
This PR adds `Iterator::collect_into` as proposed by ``@cormacrelf`` in #48597 (see https://github.com/rust-lang/rust/pull/48597#issuecomment-842083688).
Followup of #92982.
This adds the following method to the Iterator trait:
```rust
fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
```
Mention intent of `From` trait in its docs
This pr is a docs modification to add to the documentation of the `From` trait a note about its intent as a perfect conversion. This is already stated in the `TryFrom` docs so this is simply adding that information in a more visible way.
Based on @paolobarbolini's tip that the unsafe block was unnecessary in
this case.
Not much left of `hexify()` after this, so seemed clearer to just inline
it.
To make this work, the `#[rustc_on_unimplemented]` data needs to be used to
report method resolution errors, which is most of what this commit does.
Fixes#94581
Add core::hint::must_use
The example code in this documentation is minimized from a real-world situation in the `anyhow` crate where this function would have been valuable.
Having this provided by the standard library is especially useful for proc macros, even more than for macro_rules. That's because proc macro crates aren't allowed to export anything other than macros, so they couldn't make their own `must_use` function for their macro-generated code to call.
<br>
## Rendered documentation
> An identity function that causes an `unused_must_use` warning to be triggered if the given value is not used (returned, stored in a variable, etc) by the caller.
>
> This is primarily intended for use in macro-generated code, in which a [`#[must_use]` attribute][must_use] either on a type or a function would not be convenient.
>
> [must_use]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
>
> ### Example
>
> ```rust
> #![feature(hint_must_use)]
>
> use core::fmt;
>
> pub struct Error(/* ... */);
>
> #[macro_export]
> macro_rules! make_error {
> ($($args:expr),*) => {
> core::hint::must_use({
> let error = $crate::make_error(core::format_args!($($args),*));
> error
> })
> };
> }
>
> // Implementation detail of make_error! macro.
> #[doc(hidden)]
> pub fn make_error(args: fmt::Arguments<'_>) -> Error {
> Error(/* ... */)
> }
>
> fn demo() -> Option<Error> {
> if true {
> // Oops, meant to write `return Some(make_error!("..."));`
> Some(make_error!("..."));
> }
> None
> }
> ```
>
> In the above example, we'd like an `unused_must_use` lint to apply to the value created by `make_error!`. However, neither `#[must_use]` on a struct nor `#[must_use]` on a function is appropriate here, so the macro expands using `core::hint::must_use` instead.
>
> - We wouldn't want `#[must_use]` on the `struct Error` because that would make the following unproblematic code trigger a warning:
>
> ```rust
> fn f(arg: &str) -> Result<(), Error>
>
> #[test]
> fn t() {
> // Assert that `f` returns error if passed an empty string.
> // A value of type `Error` is unused here but that's not a problem.
> f("").unwrap_err();
> }
> ```
>
> - Using `#[must_use]` on `fn make_error` can't help because the return value *is* used, as the right-hand side of a `let` statement. The `let` statement looks useless but is in fact necessary for ensuring that temporaries within the `format_args` expansion are not kept alive past the creation of the `Error`, as keeping them alive past that point can cause autotrait issues in async code:
>
> ```rust
> async fn f() {
> // Using `let` inside the make_error expansion causes temporaries like
> // `unsync()` to drop at the semicolon of that `let` statement, which
> // is prior to the await point. They would otherwise stay around until
> // the semicolon on *this* statement, which is after the await point,
> // and the enclosing Future would not implement Send.
> log(make_error!("look: {:p}", unsync())).await;
> }
>
> async fn log(error: Error) {/* ... */}
>
> // Returns something without a Sync impl.
> fn unsync() -> *const () {
> 0 as *const ()
> }
> ```