Add as_(mut_)ptr and as_(mut_)slice to raw array pointers
Hey, first time contributing to the standard libraries so not completely sure about the process.
These functions are complementary to the ones being added in #74265 . I found them missing on array pointers.
See also:
- ACP: https://github.com/rust-lang/libs-team/issues/321
- Tracking issue: #119834
Implement `Duration::as_millis_{f64,f32}`
Implementation of #122451.
Linked const-unstability to #72440, so the post there should probably be updated to mentions the 2 new methods when/if this PR is merged.
fix unsoundness in Step::forward_unchecked for signed integers
Fixes#122420
```rust
pub fn foo(a: i8, b: u8) -> i8 {
unsafe { a.checked_add_unsigned(b).unwrap_unchecked() }
}
```
still compiles down to a single arithmetic instruction ([godbolt](https://rust.godbolt.org/z/qsd3xYWfE)).
But we may be losing some loop optimizations if llvm can no longer easily derive that it's a finite counted loop from the no-wrapping flags.
Improve `Step` docs
It [came up on urlo](https://users.rust-lang.org/t/implement-trait-step-in-1-76-0/108204?u=cad97) that the unstable reason string isn't helpful, so just remove it; there's nothing meaningful to add here.
Also makes a couple drive-by improvements to the method docs -- removes incorrect references, changes `forward_checked`'s invariant formulation to match `backward_checked`'s, and adds a helpful corollary that `step_unchecked(a, 0)` is always safe.
Add CStr::bytes iterator
See rust-lang/libs-team#135 for an ACP.
Since rust-lang/libs-team#134 was also accepted, this type is now `core::ffi::c_str::Bytes` instead of `core::ffi::CStrBytes`.
Expose the Freeze trait again (unstably) and forbid implementing it manually
non-emoji version of https://github.com/rust-lang/rust/pull/121501
cc #60715
This trait is useful for generic constants (associated consts of generic traits). See the test (`tests/ui/associated-consts/freeze.rs`) added in this PR for a usage example. The builtin `Freeze` trait is the only way to do it, users cannot work around this issue.
It's also a useful trait for building some very specific abstrations, as shown by the usage by the `zerocopy` crate: https://github.com/google/zerocopy/issues/941
cc ```@RalfJung```
T-lang signed off on reexposing this unstably: https://github.com/rust-lang/rust/pull/121501#issuecomment-1969827742
Add slice::try_range
This adds a fallible version of the unstable `slice::range` (tracking: #76393) which is highly requested in the tracking issue.
Hoping this can slide by without an ACP (since the feature is already being tracked), but let me know otherwise.
BorrowedCursor docs clarification
If one reads the `BorrowedCursor` docs without having seen `BorrowedBuf` before, it is quite easy to assume that "unfilled" and "uninit" are synonyms.
Fix legacy numeric constant diag items
- missed syms for usize/isize
- missed diag items on unsigned integers
For rust-lang/rust-clippy#12312
r? ```@Nilstrieb```
Follow-up to #121272, #121361, #121667
This should be the last one 🤞 Sorry!
Distinguish between library and lang UB in assert_unsafe_precondition
As described in https://github.com/rust-lang/rust/pull/121583#issuecomment-1963168186, `assert_unsafe_precondition` now explicitly distinguishes between language UB (conditions we explicitly optimize on) and library UB (things we document you shouldn't do, and maybe some library internals assume you don't do).
`debug_assert_nounwind` was originally added to avoid the "only at runtime" aspect of `assert_unsafe_precondition`. Since then the difference between the macros has gotten muddied. This totally revamps the situation.
Now _all_ preconditions shall be checked with `assert_unsafe_precondition`. If you have a precondition that's only checkable at runtime, do a `const_eval_select` hack, as done in this PR.
r? RalfJung
align_offset, align_to: no longer allow implementations to spuriously fail to align
For a long time, we have allowed `align_offset` to fail to compute a properly aligned offset, and `align_to` to return a smaller-than-maximal "middle slice". This was done to cover the implementation of `align_offset` in const-eval and Miri. See https://github.com/rust-lang/rust/issues/62420 for more background. For about the same amount of time, this has caused confusion and surprise, where people didn't realize they have to write their code to be defensive against `align_offset` failures.
Another way to put this is: the specification is effectively non-deterministic, and non-determinism is hard to test for -- in particular if the implementation everyone uses to test always produces the same reliable result, and nobody expects it to be non-deterministic to begin with.
With https://github.com/rust-lang/rust/pull/117840, Miri has stopped making use of this liberty in the spec; it now always behaves like rustc. That only leaves const-eval as potential motivation for this behavior. I do not think this is sufficient motivation. Currently, none of the relevant functions are stably const: `align_offset` is unstably const, `align_to` is not const at all. I propose that if we ever want to make these const-stable, we just accept the fact that they can behave differently at compile-time vs at run-time. This is not the end of the world, and it seems to be much less surprising to programmers than unexpected non-determinism. (Related: https://github.com/rust-lang/rfcs/pull/3352.)
`@thomcc` has repeatedly made it clear that they strongly dislike the non-determinism in align_offset, so I expect they will support this. `@oli-obk,` what do you think? Also, whom else should we involve? The primary team responsible is clearly libs-api, so I will nominate this for them. However, allowing const-evaluated code to behave different from run-time code is t-lang territory. The thing is, this is not stabilizing anything t-lang-worthy immediately, but it still does make a decision we will be bound to: if we accept this change, then
- either `align_offset`/`align_to` can never be called in const fn,
- or we allow compile-time behavior to differ from run-time behavior.
So I will nominate for t-lang as well, with the question being: are you okay with accepting either of these outcomes (without committing to which one, just accepting that it has to be one of them)? This closes the door to "have `align_offset` and `align_to` at compile-time and also always have compile-time behavior match run-time behavior".
Closes https://github.com/rust-lang/rust/issues/62420
Specifically, when an override doesn't just forward to an inner type,
document the behavior and that it's preferred over simply assigning
a clone of source. Also, change instances where the second parameter is
"other" to "source".
Stabilize the `#[diagnostic]` namespace and `#[diagnostic::on_unimplemented]` attribute
This PR stabilizes the `#[diagnostic]` attribute namespace and a minimal option of the `#[diagnostic::on_unimplemented]` attribute.
The `#[diagnostic]` attribute namespace is meant to provide a home for attributes that allow users to influence error messages emitted by the compiler. The compiler is not guaranteed to use any of this hints, however it should accept any (non-)existing attribute in this namespace and potentially emit lint-warnings for unused attributes and options. This is meant to allow discarding certain attributes/options in the future to allow fundamental changes to the compiler without the need to keep then non-meaningful options working.
The `#[diagnostic::on_unimplemented]` attribute is allowed to appear on a trait definition. This allows crate authors to hint the compiler to emit a specific error message if a certain trait is not implemented. For the `#[diagnostic::on_unimplemented]` attribute the following options are implemented:
* `message` which provides the text for the top level error message
* `label` which provides the text for the label shown inline in the broken code in the error message
* `note` which provides additional notes.
The `note` option can appear several times, which results in several note messages being emitted. If any of the other options appears several times the first occurrence of the relevant option specifies the actually used value. Any other occurrence generates an lint warning. For any other non-existing option a lint-warning is generated.
All three options accept a text as argument. This text is allowed to contain format parameters referring to generic argument or `Self` by name via the `{Self}` or `{NameOfGenericArgument}` syntax. For any non-existing argument a lint warning is generated.
This allows to have a trait definition like:
```rust
#[diagnostic::on_unimplemented(
message = "My Message for `ImportantTrait<{A}>` is not implemented for `{Self}`",
label = "My Label",
note = "Note 1",
note = "Note 2"
)]
trait ImportantTrait<A> {}
```
which then generates for the following code
```rust
fn use_my_trait(_: impl ImportantTrait<i32>) {}
fn main() {
use_my_trait(String::new());
}
```
this error message:
```
error[E0277]: My Message for `ImportantTrait<i32>` is not implemented for `String`
--> src/main.rs:14:18
|
14 | use_my_trait(String::new());
| ------------ ^^^^^^^^^^^^^ My Label
| |
| required by a bound introduced by this call
|
= help: the trait `ImportantTrait<i32>` is not implemented for `String`
= note: Note 1
= note: Note 2
```
[Playground with the unstable feature](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=05133acce8e1d163d481e97631f17536)
Fixes#111996
Rollup of 9 pull requests
Successful merges:
- #121958 (Fix redundant import errors for preload extern crate)
- #121976 (Add an option to have an external download/bootstrap cache)
- #122022 (loongarch: add frecipe and relax target feature)
- #122026 (Do not try to format removed files)
- #122027 (Uplift some feeding out of `associated_type_for_impl_trait_in_impl` and into queries)
- #122063 (Make the lowering of `thir::ExprKind::If` easier to follow)
- #122074 (Add missing PartialOrd trait implementation doc for array)
- #122082 (remove outdated fixme comment)
- #122091 (Note why we're using a new thread in `test_get_os_named_thread`)
r? `@ghost`
`@rustbot` modify labels: rollup
const_eval_select: make it safe but be careful with what we expose on stable for now
As this is all still nightly-only I think `````@rust-lang/wg-const-eval````` can do that without involving t-lang.
r? `````@oli-obk`````
Cc `````@Nilstrieb````` -- the updated version of your RFC would basically say that we can remove these comments about not making behavior differences visible in stable `const fn`
Add basic i18n guidance for `Display`
I've tried to be relatively noncommittal here. The part I think is most important is to mention the concept of "display adapters" *somewhere* in the `std::fmt` documentation that has some chance of being discovered when people go looking for ways to provide context when `Display`ing their type.
Rendered:
> ### Internationalization
>
> Because a type can only have one `Display` implementation, it is often preferable to only implement `Display` when there is a single most "obvious" way that values can be formatted as text. This could mean formatting according to the "invariant" culture and "undefined" locale, or it could mean that the type display is designed for a specific culture/locale, such as developer logs.
>
> If not all values have a justifiably canonical textual format or if you want to support alternative formats not covered by the standard set of possible [formatting traits], the most flexible approach is display adapters: methods like [`str::escape_default`] or [`Path::display`] which create a wrapper implementing `Display` to output the specific display format.
>
> [formatting traits]: https://doc.rust-lang.org/nightly/std/fmt/index.html#formatting-traits
> [`str::escape_default`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.escape_default
> [`Path::display`]: https://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.display
The module docs do already have a [localization header](https://doc.rust-lang.org/nightly/std/fmt/index.html#localization), so maybe this header should be l10n instead of i18n, or maybe this information should live under that header? I'm not sure, but here on the `Display` trait at least isn't a *bad* spot to put it.
The other side of this that comes up a lot is `FromStr` compatibility, but that's for a different PR.
net: Don't use checked arithmetic when parsing numbers with known max digits
Add a branch to `Parser::read_number` that determines whether checked or regular arithmetic is used.
- If `max_digits.is_some()`, then we know we are parsing a `u8` or `u16` because `read_number` is only called with `Some(3)` or `Some(4)`. Both types fit within a `u32` without risk of overflow. Thus, we can use plain arithmetic to avoid extra instructions from `checked_mul` and `checked_add`.
Add benches for `IpAddr`, `Ipv4Addr`, `Ipv6Addr`, `SocketAddr`, `SocketAddrV4`, and `SocketAddrV6` parsing
Add ASCII fast-path for `char::is_grapheme_extended`
I discovered that `impl Debug for str` is quite slow because it ends up doing a `unicode_data::grapheme_extend::lookup` for each char, which ends up doing a binary search.
This introduces a fast-path for ASCII chars which do not have this property.
The `lookup` is thus completely gone from profiles.
---
As a followup, maybe it’s worth implementing this fast path directly in `unicode_data` so that it can check for the lower bound directly before going to a potentially expensive binary search.
Rollup of 10 pull requests
Successful merges:
- #121213 (Add an example to demonstrate how Rc::into_inner works)
- #121262 (Add vector time complexity)
- #121287 (Clarify/add `must_use` message for Rc/Arc/Weak::into_raw.)
- #121664 (Adjust error `yield`/`await` lowering)
- #121826 (Use root obligation on E0277 for some cases)
- #121838 (Use the correct logic for nested impl trait in assoc types)
- #121913 (Don't panic when waiting on poisoned queries)
- #121987 (pattern analysis: abort on arity mismatch)
- #121993 (Avoid using unnecessary queries when printing the query stack in panics)
- #121997 (interpret/cast: make more matches on FloatTy properly exhaustive)
r? `@ghost`
`@rustbot` modify labels: rollup
Use root obligation on E0277 for some cases
When encountering trait bound errors that satisfy some heuristics that tell us that the relevant trait for the user comes from the root obligation and not the current obligation, we use the root predicate for the main message.
This allows to talk about "X doesn't implement Pattern<'_>" over the most specific case that just happened to fail, like "char doesn't implement Fn(&mut char)" in
`tests/ui/traits/suggest-dereferences/root-obligation.rs`
The heuristics are:
- the type of the leaf predicate is (roughly) the same as the type from the root predicate, as a proxy for "we care about the root"
- the leaf trait and the root trait are different, so as to avoid talking about `&mut T: Trait` and instead remain talking about `T: Trait` instead
- the root trait is not `Unsize`, as to avoid talking about it in `tests/ui/coercion/coerce-issue-49593-box-never.rs`.
```
error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied
--> $DIR/root-obligation.rs:6:38
|
LL | .filter(|c| "aeiou".contains(c))
| -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>`
| |
| required by a bound introduced by this call
|
= note: required for `&char` to implement `FnOnce<(char,)>`
= note: required for `&char` to implement `Pattern<'_>`
note: required by a bound in `core::str::<impl str>::contains`
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
help: consider dereferencing here
|
LL | .filter(|c| "aeiou".contains(*c))
| +
```
Fix#79359, fix#119983, fix#118779, cc #118415 (the suggestion needs to change), cc #121398 (doesn't fix the underlying issue).
perf: improve write_fmt to handle simple strings
In case format string has no arguments, simplify its implementation with a direct call to `output.write_str(value)`. This builds on `@dtolnay` original [suggestion](https://github.com/serde-rs/serde/pull/2697#issuecomment-1940376414). This does not change any expectations because the original `fn write()` implementation calls `write_str` for parts of the format string.
```rust
write!(f, "text") -> f.write_str("text")
```
```diff
/// [`write!`]: crate::write!
+#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
+ if let Some(s) = args.as_str() { output.write_str(s) } else { write_internal(output, args) }
+}
+
+/// Actual implementation of the [`write`], but without the simple string optimization.
+fn write_internal(output: &mut dyn Write, args: Arguments<'_>) -> Result {
let mut formatter = Formatter::new(output);
let mut idx = 0;
```
* Hopefully it will improve the simple case for the https://github.com/rust-lang/rust/issues/99012
* Another related (original?) issues #10761
* Previous similar attempt to fix it by by `@Kobzol` #100700
CC: `@m-ou-se` as probably the biggest expert in everything `format!`
Add a scheme for moving away from `extern "rust-intrinsic"` entirely
All `rust-intrinsic`s can become free functions now, either with a fallback body, or with a dummy body and an attribute, requiring backends to actually implement the intrinsic.
This PR demonstrates the dummy-body scheme with the `vtable_size` intrinsic.
cc https://github.com/rust-lang/rust/issues/63585
follow-up to #120500
MCP at https://github.com/rust-lang/compiler-team/issues/720
arithmetic
If `max_digits.is_some()`, then we know we are parsing a `u8` or `u16`
because `read_number` is only called with `Some(3)` or `Some(4)`. Both
types fit well within a `u32` without risk of overflow. Thus, we can use
plain arithmetic to avoid extra instructions from `checked_mul` and
`checked_add`.
Doc: Fix incorrect reference to integer in Atomic{Ptr,Bool}::as_ptr.
I am assuming "resulting integer" is an error, since we are talking about pointers and booleans here. Seems like it was missed while copy & pasting the docs from the integer versions. I also checked the rest of the docs, and this was the only mention of integers.
Improve assert_matches! documentation
This new documentation tries to limit the impact of the conceptual pitfall, that the if guard relaxes the constraint, when really it tightens it. This is achieved by changing the text and examples. The previous documentation also chose a rather weird and non-representative example for the if guard, that made it needlessly complicated to understand.
```
error[E0599]: no method named `map` found for struct `Vec<bool>` in the current scope
--> $DIR/vec-on-unimplemented.rs:3:23
|
LL | vec![true, false].map(|v| !v).collect::<Vec<_>>();
| ^^^ `Vec<bool>` is not an iterator
|
help: call `.into_iter()` first
|
LL | vec![true, false].into_iter().map(|v| !v).collect::<Vec<_>>();
| ++++++++++++
```
We used to provide some help through `rustc_on_unimplemented` on non-`impl Trait` and non-type-params, but this lets us get rid of some otherwise unnecessary conditions in the annotation on `Iterator`.
When encountering trait bound errors that satisfy some heuristics that
tell us that the relevant trait for the user comes from the root
obligation and not the current obligation, we use the root predicate for
the main message.
This allows to talk about "X doesn't implement Pattern<'_>" over the
most specific case that just happened to fail, like "char doesn't
implement Fn(&mut char)" in
`tests/ui/traits/suggest-dereferences/root-obligation.rs`
The heuristics are:
- the type of the leaf predicate is (roughly) the same as the type
from the root predicate, as a proxy for "we care about the root"
- the leaf trait and the root trait are different, so as to avoid
talking about `&mut T: Trait` and instead remain talking about
`T: Trait` instead
- the root trait is not `Unsize`, as to avoid talking about it in
`tests/ui/coercion/coerce-issue-49593-box-never.rs`.
```
error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied
--> $DIR/root-obligation.rs:6:38
|
LL | .filter(|c| "aeiou".contains(c))
| -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>`
| |
| required by a bound introduced by this call
|
= note: required for `&char` to implement `FnOnce<(char,)>`
= note: required for `&char` to implement `Pattern<'_>`
note: required by a bound in `core::str::<impl str>::contains`
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
help: consider dereferencing here
|
LL | .filter(|c| "aeiou".contains(*c))
| +
```
Fix#79359, fix#119983, fix#118779, cc #118415 (the suggestion needs
to change).
The previous definition used the phrase "representation", which is ambiguous given the current state of memory model nomenclature in Rust. The new wording clarifies that size and bit validity are guaranteed to match the corresponding native integer type.
Clarify behavior of slice prefix/suffix operations in case of equality
Operations such as starts_with, ends_with, strip_prefix and strip_suffix can be either strict (do not consider a slice to be a prefix/suffix of itself) or not. In Rust's case, they are not strict. Add a few phrases to the documentation to clarify this.
Add proper cfg to keep only one AlignmentEnum definition for different target_pointer_widths
Detected by #121752
Only one AlignmentEnum would be used with a specified target_pointer_width
Safe Transmute: Revise safety analysis
This PR migrates `BikeshedIntrinsicFrom` to a simplified safety analysis (described [here](https://github.com/rust-lang/project-safe-transmute/issues/15)) that does not rely on analyzing the visibility of types and fields.
The revised analysis treats primitive types as safe, and user-defined types as potentially carrying safety invariants. If Rust gains explicit (un)safe fields, this PR is structured so that it will be fairly easy to thread support for those annotations into the analysis.
Notably, this PR removes the `Context` type parameter from `BikeshedIntrinsicFrom`. Most of the files changed by this PR are just UI tests tweaked to accommodate the removed parameter.
r? `@compiler-errors`
This new documentation tries to avoid to limit the impact of the
conceptual pitfall, that the if guard relaxes the constraint, when
really it tightens it. This is achieved by changing the text and
examples. The previous documentation also chose a rather weird and
non-representative example for the if guard, that made it needlessly
complicated to understand.
This PR stabilizes the `#[diagnostic]` attribute namespace and a minimal
option of the `#[diagnostic::on_unimplemented]` attribute.
The `#[diagnostic]` attribute namespace is meant to provide a home for
attributes that allow users to influence error messages emitted by the
compiler. The compiler is not guaranteed to use any of this hints,
however it should accept any (non-)existing attribute in this namespace
and potentially emit lint-warnings for unused attributes and options.
This is meant to allow discarding certain attributes/options in the
future to allow fundamental changes to the compiler without the need to
keep then non-meaningful options working.
The `#[diagnostic::on_unimplemented]` attribute is allowed to appear
on a trait definition. This allows crate authors to hint the compiler
to emit a specific error message if a certain trait is not implemented.
For the `#[diagnostic::on_unimplemented]` attribute the following
options are implemented:
* `message` which provides the text for the top level error message
* `label` which provides the text for the label shown inline in the
broken code in the error message
* `note` which provides additional notes.
The `note` option can appear several times, which results in several
note messages being emitted. If any of the other options appears several
times the first occurrence of the relevant option specifies the actually
used value. Any other occurrence generates an lint warning. For any
other non-existing option a lint-warning is generated.
All three options accept a text as argument. This text is allowed to
contain format parameters referring to generic argument or `Self` by
name via the `{Self}` or `{NameOfGenericArgument}` syntax. For any
non-existing argument a lint warning is generated.
Tracking issue: #111996
rename 'try' intrinsic to 'catch_unwind'
The intrinsic has nothing to do with `try` blocks, and corresponds to the stable `catch_unwind` function, so this makes a lot more sense IMO.
Also rename Miri's special function while we are at it, to reflect the level of abstraction it works on: it's an unwinding mechanism, on which Rust implements panics.
Operations such as starts_with, ends_with, strip_prefix and strip_suffix
can be either strict (do not consider a slice to be a prefix/suffix of
itself) or not. In Rust's case, they are not strict. Add a few phrases to
the documentation to clarify this.
Add `#[rustc_no_mir_inline]` for standard library UB checks
should help with #121110 and also with #120848
Because the MIR inliner cannot know whether the checks are enabled or not, so inlining is an unnecessary compile time pessimization when debug assertions are disabled. LLVM knows whether they are enabled or not, so it can optimize accordingly without wasting time.
r? `@saethlin`
Forbid use of `extern "C-unwind"` inside standard library
Those libraries are build with `-C panic=unwind` and is expected to be linkable to `-C panic=abort` library. To ensure unsoundness compiler needs to prevent a `C-unwind` call to exist, as doing so may leak foreign exceptions into `-C panic=abort`.
r? ``@RalfJung``
Add examples for some methods on slices
Adds some examples to some methods on slice.
`is_empty` didn't have an example for an empty slice, even though `str` and the collections all have one, so I added that in.
`first_mut` and `last_mut` didn't have an example for what happens when the slice is empty, whereas `first` and `last` do, so I added that too.
Those libraries are build with `-C panic=unwind` and is expected to
be linkable to `-C panic=abort` library. To ensure unsoundness
compiler needs to prevent a `C-unwind` call to exist, as doing so may leak
foreign exceptions into `-C panic=abort`.
Provide suggestions through `rustc_confusables` annotations
Help with common API confusion, like asking for `push` when the data structure really has `append`.
```
error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope
--> $DIR/rustc_confusables_std_cases.rs:17:7
|
LL | x.size();
| ^^^^
|
help: you might have meant to use `len`
|
LL | x.len();
| ~~~
help: there is a method with a similar name
|
LL | x.resize();
| ~~~~~~
```
Fix#59450 (we can open subsequent tickets for specific cases).
Fix#108437:
```
error[E0599]: `Option<{integer}>` is not an iterator
--> f101.rs:3:9
|
3 | opt.flat_map(|val| Some(val));
| ^^^^^^^^ `Option<{integer}>` is not an iterator
|
::: /home/gh-estebank/rust/library/core/src/option.rs:571:1
|
571 | pub enum Option<T> {
| ------------------ doesn't satisfy `Option<{integer}>: Iterator`
|
= note: the following trait bounds were not satisfied:
`Option<{integer}>: Iterator`
which is required by `&mut Option<{integer}>: Iterator`
help: you might have meant to use `and_then`
|
3 | opt.and_then(|val| Some(val));
| ~~~~~~~~
```
On type error of method call arguments, look at confusables for suggestion. Fix#87212:
```
error[E0308]: mismatched types
--> f101.rs:8:18
|
8 | stuff.append(Thing);
| ------ ^^^^^ expected `&mut Vec<Thing>`, found `Thing`
| |
| arguments to this method are incorrect
|
= note: expected mutable reference `&mut Vec<Thing>`
found struct `Thing`
note: method defined here
--> /home/gh-estebank/rust/library/alloc/src/vec/mod.rs:2025:12
|
2025 | pub fn append(&mut self, other: &mut Self) {
| ^^^^^^
help: you might have meant to use `push`
|
8 | stuff.push(Thing);
| ~~~~
```
Help with common API confusion, like asking for `push` when the data structure really has `append`.
```
error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope
--> $DIR/rustc_confusables_std_cases.rs:17:7
|
LL | x.size();
| ^^^^
|
help: you might have meant to use `len`
|
LL | x.len();
| ~~~
help: there is a method with a similar name
|
LL | x.resize();
| ~~~~~~
```
#59450
Make intrinsic fallback bodies cross-crate inlineable
This change was prompted by the stage1 compiler spending 4% of its time when compiling the polymorphic-recursion MIR opt test in `unlikely`.
Intrinsic fallback bodies like `unlikely` should always be inlined, it's very silly if they are not. To do this, we enable the fallback bodies to be cross-crate inlineable. Not that this matters for our workloads since the compiler never actually _uses_ the "fallback bodies", it just uses whatever was cfg(bootstrap)ped, so I've also added `#[inline]` to those.
See the comments for more information.
r? oli-obk
intrinsics::simd: add missing functions, avoid UB-triggering fast-math
Turns out stdarch declares a bunch more SIMD intrinsics that are still missing from libcore.
I hope I got the docs and in particular the safety requirements right for these "unordered" and "nanless" intrinsics.
Many of these are unused even in stdarch, but they are implemented in the codegen backend, so we may as well list them here.
r? `@Amanieu`
Cc `@calebzulawski` `@workingjubilee`
Add "algebraic" fast-math intrinsics, based on fast-math ops that cannot return poison
Setting all of LLVM's fast-math flags makes our fast-math intrinsics very dangerous, because some inputs are UB. This set of flags permits common algebraic transformations, but according to the [LangRef](https://llvm.org/docs/LangRef.html#fastmath), only the flags `nnan` (no nans) and `ninf` (no infs) can produce poison.
And this uses the algebraic float ops to fix https://github.com/rust-lang/rust/issues/120720
cc `@orlp`
Refactor trait implementations in `core::convert::num`.
Tracking issue: https://github.com/rust-lang/rust/issues/120257
Implement conversion traits using generic `NonZero` type, and refactor all macros to use a consistent format/order of parameters.
r? `@dtolnay`
Correct the simd_masked_{load,store} intrinsic docs
Explains the uniform pointer being used for these two operations and how elements are offset from it.
Always inline check in `assert_unsafe_precondition` with cfg(debug_assertions)
The current complexities in `assert_unsafe_precondition` are delicately balancing several concerns, among them compile times for the cases where there are no debug assertions. This comes at a large runtime cost when the assertions are enabled, making the debug assertion compiler a lot slower, which is very annoying.
To avoid this, we always inline the check when building with debug assertions.
Numbers (compiling stage1 library after touching core):
- master: 80s
- just adding `#[inline(always)]` to the `cfg(bootstrap)` `debug_assertions` (equivalent to a bootstrap bump (uhh, i just realized that i was on a slightly outdated master so this bump might have happened already), (#121112)): 67s
- this: 54s
So this seems like a good solution. I think we can still get the same run-time perf improvements for other users too by massaging this code further (see my other PR about adding `#[rustc_no_mir_inline]` #121114) but this is a simpler step that solves the imminent problem of "holy shit my rustc is sooo slow".
Funny consequence: This now means compiling the standard library with dbeug assertions makes it faster (than without, when using debug assertions downstream)!
r? ```@saethlin``` (or anyone else if someone wants to review this)
fixes#121110, supposedly
Use intrinsics::debug_assertions in debug_assert_nounwind
This is the first item in https://github.com/rust-lang/rust/issues/120848.
Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library.
The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: https://github.com/rust-lang/rust/pull/120863#issuecomment-1937423502
This change was prompted by the stage1 compiler spending 4% of its time
when compiling the polymorphic-recursion MIR opt test in `unlikely`.
Intrinsic fallback bodies like `unlikely` should always be inlined, it's
very silly if they are not. To do this, we enable the fallback bodies to
be cross-crate inlineable. Not that this matters for our workloads since
the compiler never actually _uses_ the "fallback bodies", it just uses
whatever was cfg(bootstrap)ped, so I've also added `#[inline]` to those.
The current complexities in `assert_unsafe_precondition` are delicately
balancing several concerns, among them compile times for the cases where
there are no debug assertions. This comes at a large runtime cost when
the assertions are enabled, making the debug assertion compiler a lot
slower, which is very annoying.
To avoid this, we always inline the check when building with debug
assertions.
Numbers (compiling stage1 library after touching core):
- master: 80s
- just adding `#[inline(always)]` to the `cfg(bootstrap)`
`debug_assertions`: 67s
- this: 54s
So this seems like a good solution. I think we can still get
the same run-time perf improvements for other users too by
massaging this code further (see my other PR about adding
`#[rustc_no_mir_inline]`) but this is a simpler step that
solves the imminent problem of "holy shit my rustc is sooo slow".
Funny consequence: This now means compiling the standard library with
dbeug assertions makes it faster (than without, when using debug
assertions downstream)!
Store core::str::CharSearcher::utf8_size as u8
This is already relied on being smaller than u8 due to the `safety invariant: utf8_size must be less than 5`, so this helps LLVM optimize and maybe improve copies due to padding instead of unused bytes.
Add examples to document the return type of quickselect functions
Currently, `select_nth_unstable`, `select_nth_unstable_by`, and `select_nth_unstable_by_key`'s examples do not show how to use the return values of the functions in an example, so this PR adds that in.
Note: I didn't know what to call the parameters, so I settled on lesser, median, greater because the example is used for median finding so I retained that naming for the pivot, but lesser and greater are poor names for the example that sorts in descending order, because lesser and greater are then flipped.
I think it's common to say "lo" and "hi" for low and high respectively, but that's also not great when the comparator flips the elements. Otherwise, "left" and "right" are also commonly used but I think that's poor naming because some languages read right to left so those names are also unintuitive.
Lesser and greater are also not that great but I found a test that used `less`, `equal`, `greater` so I took that: dfa88b328f/library/core/tests/slice.rs (L1962)
Make `io::BorrowedCursor::advance` safe
This also keeps the old `advance` method under `advance_unchecked` name.
This makes pattern like `std::io::default_read_buf` safe to write.
Rename MaybeUninit::write_slice
A step to push #79995 forward.
https://github.com/rust-lang/libs-team/issues/122 also suggested to make them inherent methods, but they can't be — they'd conflict with slice's regular methods.
Implement intrinsics with fallback bodies
fixes#93145 (though we can port many more intrinsics)
cc #63585
The way this works is that the backend logic for generating custom code for intrinsics has been made fallible. The only failure path is "this intrinsic is unknown". The `Instance` (that was `InstanceDef::Intrinsic`) then gets converted to `InstanceDef::Item`, which represents the fallback body. A regular function call to that body is then codegenned. This is currently implemented for
* codegen_ssa (so llvm and gcc)
* codegen_cranelift
other backends will need to adjust, but they can just keep doing what they were doing if they prefer (though adding new intrinsics to the compiler will then require them to implement them, instead of getting the fallback body).
cc `@scottmcm` `@WaffleLapkin`
### todo
* [ ] miri support
* [x] default intrinsic name to name of function instead of requiring it to be specified in attribute
* [x] make sure that the bodies are always available (must be collected for metadata)
doc: add note about panicking examples for strict_overflow_ops
The first commit adds a note before the panicking examples for strict_overflow_ops to make it clearer that the following examples should panic and why, without needing the reader to hover the mouse over the information icon.
The second commit adds panicking examples for division by zero operations for strict division operations on unsigned numbers. The signed numbers already have two panicking examples each: one for division by zero and one for overflowing division (`MIN/-1`); this commit includes the division by zero examples for the unsigned numbers.
Waker::will_wake: Compare vtable address instead of its content
Optimize will_wake implementation by comparing vtable address instead of its content.
The existing best practice to avoid false negatives from will_wake is to define a waker vtable as a static item. That approach continues to works with the new implementation.
While this potentially changes the observable behaviour, the function is documented to work on a best-effort basis. The PartialEq impl for RawWaker remains as it was.
I discovered that `impl Debug for str` is quite slow because it ends up doing a `unicode_data::grapheme_extend::lookup` for each char, which ends up doing a binary search.
This introduces a fast-path for ASCII chars which do not have this property.
The `lookup` is thus completely gone from profiles.
Clarified docs on non-atomic oprations on owned/mut refs to atomics
I originally misinterpreted the documentation to mean that the compiler can/will automatically optimise away atomic operations whenever the data is owned or mutably referenced.
On re-reading I think it is not technically incorrect, but specifically mentioning _how_ the atomic operations can be avoided also prevents this misunderstanding.
implement `Default` for `AsciiChar`
This implements `Default` for `AsciiChar` in order to match `char`'s implementation.
From all the different possible ways to do this I think the clearest one is to have both `char` and `AsciiChar` impls together.
I've also updated the doc-comment of the default variant since rustdoc doesn't seem to indicate it otherwise. Probably the text could be improved, though. I couldn't find any similar examples in the codebase and suggestions are welcomed.
r? `@scottmcm`
Clarify the lifetimes of allocations returned by the `Allocator` trait
The previous definition (accidentally) disallowed the implementation of stack-based allocators whose memory would become invalid once the lifetime of the allocator type ended.
This also ensures the validity of the following blanket implementation:
```rust
impl<A: Allocator> Allocator for &'_ A {}
```
Additional doc links and explanation of `Wake`.
This is intended to clarify:
* That `Wake` exists and can be used instead of `RawWaker`.
* How to construct a `Waker` when you are looking at `Wake` (which was previously only documented in the example).
The previous definition (accidentally) disallowed the implementation of
stack-based allocators whose memory would become invalid once the
lifetime of the allocator type ended.
This also ensures the validity of the following blanket implementation:
```rust
impl<A: Allocator> Allocator for &'_ A {}
```
assert_unsafe_precondition cleanup
I moved the polymorphic `is_nonoverlapping` into the `Cell` function that uses it and renamed `intrinsics::is_nonoverlapping_mono` to just `intrinsics::is_nonoverlapping`.
We now also have some docs for `intrinsics::debug_assertions`.
r? RalfJung
core: add Duration constructors
Add more `Duration` constructors.
Tracking issue: #120301.
These match similar convenience constructors available on both `chrono::Duration` and `time::Duration`.
What's the best ordering for these with respect to the existing constructors?
Suggest less bug-prone construction of Duration in docs
std::time::Duration has a well-known quirk: Duration::as_nanos() returns u128 [1], but Duration::from_nanos() takes u64 [2]. So these methods cannot easily roundtrip [3]. It is not possible to simply accept u128 in from_nanos [4], because it requires breaking other API [5].
It seems to me that callers have basically only two options:
1. `Duration::from_nanos(d.as_nanos() as u64)`, which is the "obvious" and buggy approach.
2. `Duration::new(d.as_secs(), d.subsecs_nanos())`, which only becomes apparent after reading and digesting the entire Duration struct documentation.
I suggest that the documentation of `from_nanos` is changed to make option 2 more easily discoverable.
There are two major usecases for this:
- "Weird math" operations that should not be supported directly by `Duration`, like squaring.
- "Disconnected roundtrips", where the u128 value is passed through various other stack frames, and perhaps reconstructed into a Duration on a different machine.
In both cases, it seems like a good idea to not tempt people into thinking "Eh, u64 is good enough, what could possibly go wrong!". That's why I want to add a note that points out the similarly-easy and *safe* way to reconstruct a Duration.
[1] https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.as_nanos
[2] https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_nanos
[3] https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=fa6bab2b6b72f20c14b5243610ea1dde
[4] https://github.com/rust-lang/rust/issues/103332
[5] https://github.com/rust-lang/rust/issues/51107#issuecomment-392353166
Remove an unneeded helper from the tuple library code
Thanks to https://github.com/rust-lang/rust/pull/107022, this is just what `==` does, so we don't need the helper here anymore.
This is intended to clarify:
* That `Wake` exists and can be used instead of `RawWaker`.
* How to construct a `Waker` when you are looking at `Wake`
(which was previously only documented in the example).
Clarify that atomic and regular integers can differ in alignment
The documentation for atomic integers says that they have the "same in-memory representation" as their underlying integers. This might be misconstrued as implying that they have the same layout. Therefore, clarify that atomic integers' alignment is equal to their size.
Harmonize `AsyncFn` implementations, make async closures conditionally impl `Fn*` traits
This PR implements several changes to the built-in and libcore-provided implementations of `Fn*` and `AsyncFn*` to address two problems:
1. async closures do not implement the `Fn*` family traits, leading to breakage: https://crater-reports.s3.amazonaws.com/pr-120361/index.html
2. *references* to async closures do not implement `AsyncFn*`, as a consequence of the existing blanket impls of the shape `AsyncFn for F where F: Fn, F::Output: Future`.
In order to fix (1.), we implement `Fn` traits appropriately for async closures. It turns out that async closures can:
* always implement `FnOnce`, meaning that they're drop-in compatible with `FnOnce`-bound combinators like `Option::map`.
* conditionally implement `Fn`/`FnMut` if they have no captures, which means that existing usages of async closures should *probably* work without breakage (crater checking this: https://github.com/rust-lang/rust/pull/120712#issuecomment-1930587805).
In order to fix (2.), we make all of the built-in callables implement `AsyncFn*` via built-in impls, and instead adjust the blanket impls for `AsyncFn*` provided by libcore to match the blanket impls for `Fn*`.
Improve `Option::inspect` docs
* Refer to the function as "a function" instead of "the provided closure" since it is not necessarily a closure.
* State that the original Option/Result is returned.
* Adjust the example for `Option::inspect` to use chaining.
core/time: avoid divisions in Duration::new
In our (decently large) code base, we use `SystemTime::UNIX_EPOCH.elapsed()` in a lot of places & often in a loop or in the hot path. On [Unix](https://github.com/rust-lang/rust/blob/1.75.0/library/std/src/sys/unix/time.rs#L153-L162) at least, it seems we do calculations before hand to ensure that nanos is within the valid range, yet `Duration::new()` still checks it again, using 2 divisions. It seems like adding a branch can make this function 33% faster on ARM64 in the cases where nanos is already in the valid range & seems to have no effect in the other case.
Benchmarks:
M1 Pro (14-inch base model):
```
duration/current/checked
time: [1.5945 ns 1.6167 ns 1.6407 ns]
Found 5 outliers among 100 measurements (5.00%)
2 (2.00%) high mild
3 (3.00%) high severe
duration/current/unchecked
time: [1.5941 ns 1.6051 ns 1.6179 ns]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
duration/branched/checked
time: [1.1997 ns 1.2048 ns 1.2104 ns]
Found 8 outliers among 100 measurements (8.00%)
4 (4.00%) high mild
4 (4.00%) high severe
duration/branched/unchecked
time: [1.5881 ns 1.5957 ns 1.6039 ns]
Found 6 outliers among 100 measurements (6.00%)
3 (3.00%) high mild
3 (3.00%) high severe
```
EC2 c7gd.16xlarge (Graviton 3):
```
duration/current/checked
time: [2.7996 ns 2.8000 ns 2.8003 ns]
Found 5 outliers among 100 measurements (5.00%)
2 (2.00%) low severe
3 (3.00%) low mild
duration/current/unchecked
time: [2.9922 ns 2.9925 ns 2.9928 ns]
Found 7 outliers among 100 measurements (7.00%)
4 (4.00%) low severe
1 (1.00%) low mild
2 (2.00%) high mild
duration/branched/checked
time: [2.0830 ns 2.0843 ns 2.0857 ns]
Found 3 outliers among 100 measurements (3.00%)
1 (1.00%) low severe
1 (1.00%) low mild
1 (1.00%) high mild
duration/branched/unchecked
time: [2.9879 ns 2.9886 ns 2.9893 ns]
Found 5 outliers among 100 measurements (5.00%)
3 (3.00%) low severe
2 (2.00%) low mild
```
EC2 r7iz.16xlarge (Intel Xeon Scalable-based (Sapphire Rapids)):
```
duration/current/checked
time: [980.60 ps 980.79 ps 980.99 ps]
Found 10 outliers among 100 measurements (10.00%)
4 (4.00%) low severe
2 (2.00%) low mild
3 (3.00%) high mild
1 (1.00%) high severe
duration/current/unchecked
time: [979.53 ps 979.74 ps 979.96 ps]
Found 6 outliers among 100 measurements (6.00%)
2 (2.00%) low severe
1 (1.00%) low mild
2 (2.00%) high mild
1 (1.00%) high severe
duration/branched/checked
time: [938.72 ps 938.96 ps 939.22 ps]
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) low mild
1 (1.00%) high mild
2 (2.00%) high severe
duration/branched/unchecked
time: [1.0103 ns 1.0110 ns 1.0118 ns]
Found 10 outliers among 100 measurements (10.00%)
2 (2.00%) low mild
7 (7.00%) high mild
1 (1.00%) high severe
```
Bench code (ran using stable 1.75.0 & criterion latest 0.5.1):
I couldn't find any benches for `Duration` in this repo, so I just copied the relevant types & recreated it.
```rust
use criterion::{black_box, criterion_group, criterion_main, Criterion};
pub fn duration_bench(c: &mut Criterion) {
const NANOS_PER_SEC: u32 = 1_000_000_000;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
struct Nanoseconds(u32);
impl Default for Nanoseconds {
#[inline]
fn default() -> Self {
// SAFETY: 0 is within the valid range
unsafe { Nanoseconds(0) }
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct Duration {
secs: u64,
nanos: Nanoseconds, // Always 0 <= nanos < NANOS_PER_SEC
}
impl Duration {
#[inline]
pub const fn new_current(secs: u64, nanos: u32) -> Duration {
let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
Some(secs) => secs,
None => panic!("overflow in Duration::new"),
};
let nanos = nanos % NANOS_PER_SEC;
// SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
}
#[inline]
pub const fn new_branched(secs: u64, nanos: u32) -> Duration {
if nanos < NANOS_PER_SEC {
// SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
} else {
let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
Some(secs) => secs,
None => panic!("overflow in Duration::new"),
};
let nanos = nanos % NANOS_PER_SEC;
// SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
}
}
}
let mut group = c.benchmark_group("duration/current");
group.bench_function("checked", |b| {
b.iter(|| black_box(Duration::new_current(black_box(1_000_000_000), black_box(1_000_000))));
});
group.bench_function("unchecked", |b| {
b.iter(|| {
black_box(Duration::new_current(black_box(1_000_000_000), black_box(2_000_000_000)))
});
});
drop(group);
let mut group = c.benchmark_group("duration/branched");
group.bench_function("checked", |b| {
b.iter(|| {
black_box(Duration::new_branched(black_box(1_000_000_000), black_box(1_000_000)))
});
});
group.bench_function("unchecked", |b| {
b.iter(|| {
black_box(Duration::new_branched(black_box(1_000_000_000), black_box(2_000_000_000)))
});
});
}
criterion_group!(duration_benches, duration_bench);
criterion_main!(duration_benches);
```
The documentation for atomic integers says that they have the "same
in-memory representation" as their underlying integers. This might be
misconstrued as implying that they have the same layout. Therefore,
clarify that atomic integers' alignment is equal to their size.
Stop bailing out from compilation just because there were incoherent traits
fixes#120343
but also has a lot of "type annotations needed" fallout. Some are fixed in the second commit.
Make `NonZero` constructors generic.
This makes `NonZero` constructors generic, so that `NonZero::new` can be used without turbofish syntax.
Tracking issue: https://github.com/rust-lang/rust/issues/120257
~~I cannot figure out how to make this work with `const` traits. Not sure if I'm using it wrong or whether there's a bug:~~
```rust
101 | if n == T::ZERO {
| ^^^^^^^^^^^^ expected `host`, found `true`
|
= note: expected constant `host`
found constant `true`
```
r? `@dtolnay`
Reconstify `Add`
r? project-const-traits
I'm not happy with the ui test changes (or failures because I did not bless them and include the diffs in this PR). There is at least some bugs I need to look and try fix:
1. A third duplicated diagnostic when a consumer crate that does not have `effects` enabled has a trait selection error for an upstream const_trait trait. See tests/ui/ufcs/ufcs-qpath-self-mismatch.rs.
2. For some reason, making `Add` a const trait would stop us from suggesting `T: Add` when we try to add two `T`s without that bound. See tests/ui/suggestions/issue-97677.rs
revert stabilization of const_intrinsic_copy
`@rust-lang/wg-const-eval` I don't know what we were thinking when we approved https://github.com/rust-lang/rust/pull/97276... const-eval isn't supposed to be able to mutate anything yet! It's also near impossible to actually call `copy` in const on stable since `&mut` expressions are generally unstable. However, there's one exception...
```rust
static mut INT: i32 = unsafe {
let val = &mut [1]; // `&mut` on arrays is allowed in `static mut`
(val as *mut [i32; 1]).copy_from(&[42], 1);
val[0]
};
fn main() { unsafe {
dbg!(INT);
} }
```
Inside `static mut`, we accept some `&mut` since ~forever, to make `static mut FOO: &mut [T] = &mut [...];` work. We reject any attempt to actually write to that mutable reference though... except for the `copy` functions.
I think we should revert stabilizing these functions that take `*mut`, and then re-stabilize them together with `ptr.write` once mutable references are stable.
(This will likely fail on PowerPC until https://github.com/rust-lang/stdarch/pull/1497 lands. But we'll need a crater run first anyway.)
PartialEq, PartialOrd: update and synchronize handling of transitive chains
It was brought up in https://internals.rust-lang.org/t/total-equality-relations-as-std-eq-rhs/19232 that we currently have a gap in our `PartialEq` rules, which this PR aims to close:
> For example, with PartialEq's conditions you may have a = b = c = d ≠ a (where a and c are of type A, b and d are of type B).
The second commit fixes https://github.com/rust-lang/rust/issues/87067 by updating PartialOrd to handle the requirements the same way PartialEq does.
Clarify ambiguity in select_nth_unstable docs
Original docs for `select_nth_unstable` family of functions were ambiguous as to whether "the element at `index`" was the element at `index` before the function reordered the elements or after the function reordered the elements.
The most helpful change in this PR is to change the given examples to make this absolutely clear. Before, "the element at `index`" was the same value before and after the reordering, so it didn't help disambiguate the meaning. I've changed the example for `select_nth_unstable` and `select_nth_unstable_by` so that "the element at `index`" is different before and after the reordering, which clears up the ambiguity. The function `select_nth_unstable_by_key` already had an example that was unambiguous.
In an attempt to clear up the ambiguity from the get-go, I've added a bit of redundancy to the text. Now the docs refer to "the element at `index` *after the reordering*".
raw pointer metadata API: data address -> data pointer
A pointer consists of [more than just an address](https://github.com/rust-lang/rfcs/pull/3559), so let's not equate "pointer" and "address" in these docs.
core: add `From<core::ascii::Char>` implementations
Introduce `From<core::ascii::Char>` implementations for all unsigned
numeric types and `char`. This matches the API of `char` type.
Issue: https://github.com/rust-lang/rust/issues/110998
Rename `pointer` field on `Pin`
A few days ago, I was helping another user create a self-referential type using `PhantomPinned`. However, I noticed an odd behavior when I tried to access one of the type's fields via `Pin`'s `Deref` impl:
```rust
use std::{marker::PhantomPinned, ptr};
struct Pinned {
data: i32,
pointer: *const i32,
_pin: PhantomPinned,
}
fn main() {
let mut b = Box::pin(Pinned {
data: 42,
pointer: ptr::null(),
_pin: PhantomPinned,
});
{
let pinned = unsafe { b.as_mut().get_unchecked_mut() };
pinned.pointer = &pinned.data;
}
println!("{}", unsafe { *b.pointer });
}
```
```rust
error[E0658]: use of unstable library feature 'unsafe_pin_internals'
--> <source>:19:30
|
19 | println!("{}", unsafe { *b.pointer });
| ^^^^^^^^^
error[E0277]: `Pinned` doesn't implement `std::fmt::Display`
--> <source>:19:20
|
19 | println!("{}", unsafe { *b.pointer });
| ^^^^^^^^^^^^^^^^^^^^^ `Pinned` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Pinned`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
```
Since the user named their field `pointer`, it conflicts with the `pointer` field on `Pin`, which is public but unstable since Rust 1.60.0 with #93176. On versions from 1.33.0 to 1.59.0, where the field on `Pin` is private, this program compiles and prints `42` as expected.
To avoid this confusing behavior, this PR renames `pointer` to `__pointer`, so that it's less likely to conflict with a `pointer` field on the underlying type, as accessed through the `Deref` impl. This is technically a breaking change for anyone who names their field `__pointer` on the inner type; if this is undesirable, it could be renamed to something more longwinded. It's also a nightly breaking change for any external users of `unsafe_pin_internals`.
stabilise array methods
Closes#76118
Stabilises the remaining array methods
FCP is yet to be carried out for this
There wasn't a clear consensus on the naming, but all the other alternatives had some flaws as discussed in the tracking issue and there was a silence on this issue for a year
Initial implementation of `str::from_raw_parts[_mut]`
ACP (accepted): rust-lang/libs-team#167
Tracking issue: #119206
Thanks to ``@Kixiron`` for previous work on this (#107207)
``@rustbot`` label +T-libs-api -T-libs
r? ``@thomcc``
Closes#107207.
remove StructuralEq trait
The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.
One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust https://github.com/rust-lang/rust/pull/115893 to check for `Eq`, and rule out float matching for good.
Fixes https://github.com/rust-lang/rust/issues/115881
Add `AsyncFn` family of traits
I'm proposing to add a new family of `async`hronous `Fn`-like traits to the standard library for experimentation purposes.
## Why do we need new traits?
On the user side, it is useful to be able to express `AsyncFn` trait bounds natively via the parenthesized sugar syntax, i.e. `x: impl AsyncFn(&str) -> String` when experimenting with async-closure code.
This also does not preclude `AsyncFn` becoming something else like a trait alias if a more fundamental desugaring (which can take many[^1] different[^2] forms) comes around. I think we should be able to play around with `AsyncFn` well before that, though.
I'm also not proposing stabilization of these trait names any time soon (we may even want to instead express them via new syntax, like `async Fn() -> ..`), but I also don't think we need to introduce an obtuse bikeshedding name, since `AsyncFn` just makes sense.
## The lending problem: why not add a more fundamental primitive of `LendingFn`/`LendingFnMut`?
Firstly, for `async` closures to be as flexible as possible, they must be allowed to return futures which borrow from the async closure's captures. This can be done by introducing `LendingFn`/`LendingFnMut` traits, or (equivalently) by adding a new generic associated type to `FnMut` which allows the return type to capture lifetimes from the `&mut self` argument of the trait. This was proposed in one of [Niko's blog posts](https://smallcultfollowing.com/babysteps/blog/2023/05/09/giving-lending-and-async-closures/).
Upon further experimentation, for the purposes of closure type- and borrow-checking, I've come to the conclusion that it's significantly harder to teach the compiler how to handle *general* lending closures which may borrow from their captures. This is, because unlike `Fn`/`FnMut`, the `LendingFn`/`LendingFnMut` traits don't form a simple "inheritance" hierarchy whose top trait is `FnOnce`.
```mermaid
flowchart LR
Fn
FnMut
FnOnce
LendingFn
LendingFnMut
Fn -- isa --> FnMut
FnMut -- isa --> FnOnce
LendingFn -- isa --> LendingFnMut
Fn -- isa --> LendingFn
FnMut -- isa --> LendingFnMut
```
For example:
```
fn main() {
let s = String::from("hello, world");
let f = move || &s;
let x = f(); // This borrows `f` for some lifetime `'1` and returns `&'1 String`.
```
That trait hierarchy means that in general for "lending" closures, like `f` above, there's not really a meaningful return type for `<typeof(f) as FnOnce>::Output` -- it can't return `&'static str`, for example.
### Special-casing this problem:
By splitting out these traits manually, and making sure that each trait has its own associated future type, we side-step the issue of having to answer the questions of a general `LendingFn`/`LendingFnMut` implementation, since the compiler knows how to generate built-in implementations for first-class constructs like async closures, including the required future types for the (by-move) `AsyncFnOnce` and (by-ref) `AsyncFnMut`/`AsyncFn` trait implementations.
[^1]: For example, with trait transformers, we may eventually be able to write: `trait AsyncFn = async Fn;`
[^2]: For example, via the introduction of a more fundamental "`LendingFn`" trait, plus a [special desugaring with augmented trait aliases](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Lending.20closures.20and.20Fn*.28.29.20-.3E.20impl.20Trait/near/408471480).
Replacement of #114390: Add new intrinsic `is_var_statically_known` and optimize pow for powers of two
This adds a new intrinsic `is_val_statically_known` that lowers to [``@llvm.is.constant.*`](https://llvm.org/docs/LangRef.html#llvm-is-constant-intrinsic).` It also applies the intrinsic in the int_pow methods to recognize and optimize the idiom `2isize.pow(x)`. See #114390 for more discussion.
While I have extended the scope of the power of two optimization from #114390, I haven't added any new uses for the intrinsic. That can be done in later pull requests.
Note: When testing or using the library, be sure to use `--stage 1` or higher. Otherwise, the intrinsic will be a noop and the doctests will be skipped. If you are trying out edits, you may be interested in [`--keep-stage 0`](https://rustc-dev-guide.rust-lang.org/building/suggested.html#faster-builds-with---keep-stage).
Fixes#47234Resolves#114390
`@Centri3`
Add `NonZero*::count_ones`
This PR adds the following APIs to the standard library:
```rust
impl NonZero* {
pub const fn count_ones(self) -> NonZeroU32;
}
```
This is potentially interesting, given that `count_ones` can't ever return 0.
r? libs-api
Rollup of 9 pull requests
Successful merges:
- #112806 (Small code improvements in `collect_intra_doc_links.rs`)
- #119766 (Split tait and impl trait in assoc items logic)
- #120139 (Do not normalize closure signature when building `FnOnce` shim)
- #120160 (Manually implement derived `NonZero` traits.)
- #120171 (Fix assume and assert in jump threading)
- #120183 (Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`)
- #120195 (add several resolution test cases)
- #120259 (Split Diagnostics for Uncommon Codepoints: Add List to Display Characters Involved)
- #120261 (Provide structured suggestion to use trait objects in some cases of `if` arm type divergence)
r? `@ghost`
`@rustbot` modify labels: rollup
Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`
These closures are an internal implementation detail of the `#[test]` and `#[bench]` attribute macros, so from a user perspective there is no reason to instrument them for coverage.
Skipping them makes coverage reports slightly cleaner, and will also allow other changes to span processing during coverage instrumentation, without having to worry about how they affect the `#[test]` macro.
The `#[coverage(off)]` attribute has no effect when `-Cinstrument-coverage` is not used.
Fixes#120046.
---
Note that this PR has no effect on the user-written function that has the `#[test]` attribute attached to it. That function will still be instrumented as normal.
Manually implement derived `NonZero` traits.
Step 3 as mentioned in https://github.com/rust-lang/rust/pull/100428#pullrequestreview-1767139731.
Manually implement the traits that would cause “borrow of layout constrained field with interior mutability” errors when switching to `NonZero<T>`.
r? ```@dtolnay```
Use `Self` in `NonZero*` implementations.
This slightly reduces the size of the eventual diff when making these generic, since this can be merged independently.
Use `assert_unchecked` instead of `assume` intrinsic in the standard library
Now that a public wrapper for the `assume` intrinsic exists, we can use it in the standard library.
CC #119131
Revert stabilization of trait_upcasting feature
Reverts #118133
This reverts commit 6d2b84b3ed, reversing changes made to 73bc12199e.
The feature has a soundness bug:
* #120222
It is unclear to me whether we'll actually want to destabilize, but I thought it was still prudent to open the PR for easy destabilization once we get there.
Consolidate logic around resolving built-in coroutine trait impls
Deduplicates a lot of code. Requires defining a new lang item for `Coroutine::resume` for consistency, but it seems not harmful at worst, and potentially later useful at best.
r? oli-obk
Rollup of 9 pull requests
Successful merges:
- #118714 ( Explanation that fields are being used when deriving `(Partial)Ord` on enums)
- #119710 (Improve `let_underscore_lock`)
- #119726 (Tweak Library Integer Division Docs)
- #119746 (rustdoc: hide modals when resizing the sidebar)
- #119986 (Fix error counting)
- #120194 (Shorten `#[must_use]` Diagnostic Message for `Option::is_none`)
- #120200 (Correct the anchor of an URL in an error message)
- #120203 (Replace `#!/bin/bash` with `#!/usr/bin/env bash` in rust-installer tests)
- #120212 (Give nnethercote more reviews)
r? `@ghost`
`@rustbot` modify labels: rollup
Shorten `#[must_use]` Diagnostic Message for `Option::is_none`
This shortens the `#[must_use]` diagnostics displayed, in light of the [review comment](https://github.com/rust-lang/rust/pull/62431/files#r300819839) on when this was originally added.
Tweak Library Integer Division Docs
Improved the documentation and diagnostics related to panicking in the division-like methods in std:
* For signed methods that can overflow, clarified "results in overflow" to "self is -1 and rhs is Self::MIN." This is more concise than saying "results in overflow" and then explaining how it could overflow.
* For floor/ceil_div, corrected the documentation and made it more like the documentation in other methods.
* For signed methods that can overflow, explicitly mention that they are not affected by compiler flags.
* Removed all unused rustc_inherit_overflow_checks attributes. The non-division-like operations will never overflow.
* Added track_caller attributes to all methods that can panic. The panic messages will always be correct. For example, division methods all have / before %.
* Edited the saturating_div documentation to be consistent with similar methods.
Explanation that fields are being used when deriving `(Partial)Ord` on enums
When deriving `std::cmp::Ord` or `std::cmp::PartialOrd` on enums, their fields are compared if the variants are equal.
This means that the last assertion in the following snipped panics.
```rust
use std::cmp::{PartialEq, Eq, PartialOrd, Ord};
#[derive(PartialEq, Eq, PartialOrd, Ord)]
enum Sizes {
Small(usize),
Big(usize),
}
fn main() {
let a = Sizes::Big(3);
let b = Sizes::Big(5);
let c = Sizes::Small(10);
assert!( c < a);
assert_eq!(a, c);
}
```
This is more often expected behavior than not, and can be easily circumvented, as discussed in [this thread](https://users.rust-lang.org/t/how-to-sort-enum-variants/52291/4).
But it is addressed nowhere in the documentation, yet.
So I stumbled across this, as I personally did not expect fields being used in `PartialOrd`.
I added the explanation to the documentation.
Add `#[track_caller]` to the "From implies Into" impl
This pr implements what was mentioned in https://github.com/rust-lang/rust/issues/77474#issuecomment-1074480790
This follows from my URLO https://users.rust-lang.org/t/104497
```rust
#![allow(warnings)]
fn main() {
// Gives a good location
let _: Result<(), Loc> = dbg!(Err::<(), _>(()).map_err(|e| e.into()));
// still doesn't work, gives location of `FnOnce::call_once()`
let _: Result<(), Loc> = dbg!(Err::<(), _>(()).map_err(Into::into));
}
#[derive(Debug)]
pub struct Loc {
pub l: &'static std::panic::Location<'static>,
}
impl From<()> for Loc {
#[track_caller]
fn from(_: ()) -> Self {
Loc {
l: std::panic::Location::caller(),
}
}
}
```
Implement iterator specialization traits on more adapters
This adds
* `TrustedLen` to `Skip` and `StepBy`
* `TrustedRandomAccess` to `Skip`
* `InPlaceIterable` and `SourceIter` to `Copied` and `Cloned`
The first two might improve performance in the compiler itself since `skip` is used in several places. Constellations that would exercise the last point are probably rare since it would require an owning iterator that has references as Items somewhere in its iterator pipeline.
Improvements for `Skip`:
```
# old
test iter::bench_skip_trusted_random_access ... bench: 8,335 ns/iter (+/- 90)
# new
test iter::bench_skip_trusted_random_access ... bench: 2,753 ns/iter (+/- 27)
```
Add Ipv6Addr::is_ipv4_mapped
This change consists of cherry-picking the content from the original PR[1], which got closed due to inactivity, and applying the following changes:
* Resolving merge conflicts (obviously)
* Linked to to_ipv4_mapped instead of to_ipv4 in the documentation (seems more appropriate)
* Added the must_use and rustc_const_unstable attributes the original didn't have
I think it's a reasonably useful method to have.
[1] https://github.com/rust-lang/rust/pull/86490
Use `bool` instead of `PartiolOrd` as return value of the comparison closure in `{slice,Iteraotr}::is_sorted_by`
Changes the function signature of the closure given to `{slice,Iteraotr}::is_sorted_by` to return a `bool` instead of a `PartiolOrd` as suggested by the libs-api team here: https://github.com/rust-lang/rust/issues/53485#issuecomment-1766411980.
This means these functions now return true if the closure returns true for all the pairs of values.
Implement strict integer operations that panic on overflow
This PR implements the first part of the ACP for adding panic on overflow style arithmetic operations (https://github.com/rust-lang/libs-team/issues/270), mentioned in #116064.
It adds the following operations on both signed and unsigned integers:
- `strict_add`
- `strict_sub`
- `strict_mul`
- `strict_div`
- `strict_div_euclid`
- `strict_rem`
- `strict_rem_euclid`
- `strict_neg`
- `strict_shl`
- `strict_shr`
- `strict_pow`
Additionally, signed integers have:
- `strict_add_unsigned`
- `strict_sub_unsigned`
- `strict_abs`
And unsigned integers have:
- `strict_add_signed`
The `div` and `rem` operations are the same as normal division and remainder but are added for completeness similar to the corresponding `wrapping_*` operations.
I'm not sure if I missed any operations, I basically found them from the `wrapping_*` and `checked_*` operations on both integer types.
Tweak the threshold for chunked swapping
Thanks to `@AngelicosPhosphoros` for the tests here, which I copied from #98892.
This is an experiment as a simple alternative to that PR that just tweaks the existing threshold, since that PR showed that 3×Align (like `String`) currently doesn't work as well as it could.
Introduce split_at_checked and split_at_mut_checked methods to slices
types (including str) which are non-panicking versions of split_at and
split_at_mut respectively. This is analogous to get method being
non-panicking version of indexing.
This also removes
* impl From<&Context> for ContextBuilder
* Context::try_waker()
The from implementation is removed because now that
wakers are always supported, there are less incentives
to override the current context. Before, the incentive
was to add Waker support to a reactor that didn't have
any.
Stabilize single-field offset_of
This PR stabilizes offset_of for a single field. There has been some further discussion at https://github.com/rust-lang/rust/issues/106655 about whether this is advisable; I'm opening the PR anyway so that the code is available.
Fix overflow check
Make MIRI choose the path randomly and rename the intrinsic
Add back test
Add miri test and make it operate on `ptr`
Define `llvm.is.constant` for primitives
Update MIRI comment and fix test in stage2
Add const eval test
Clarify that both branches must have the same side effects
guaranteed non guarantee
use immediate type instead
Co-Authored-By: Ralf Jung <post@ralfj.de>
Change return type of unstable `Waker::noop()` from `Waker` to `&Waker`.
The advantage of this is that it does not need to be assigned to a variable to be used in a `Context` creation, which is the most common thing to want to do with a noop waker. It also avoids unnecessarily executing the dynamically dispatched drop function when the noop waker is dropped.
If an owned noop waker is desired, it can be created by cloning, but the reverse is harder to do since it requires declaring a constant. Alternatively, both versions could be provided, like `futures::task::noop_waker()` and `futures::task::noop_waker_ref()`, but that seems to me to be API clutter for a very small benefit, whereas having the `&'static` reference available is a large reduction in boilerplate.
[Previous discussion on the tracking issue starting here](https://github.com/rust-lang/rust/issues/98286#issuecomment-1862159766)
Stabilize `slice_first_last_chunk`
This PR does a few different things based around stabilizing `slice_first_last_chunk`. They are split up so this PR can be by-commit reviewed, I can move parts to a separate PR if desired.
This feature provides a very elegant API to extract arrays from either end of a slice, such as for parsing integers from binary data.
## Stabilize `slice_first_last_chunk`
ACP: https://github.com/rust-lang/libs-team/issues/69
Implementation: https://github.com/rust-lang/rust/issues/90091
Tracking issue: https://github.com/rust-lang/rust/issues/111774
This stabilizes the functionality from https://github.com/rust-lang/rust/issues/111774:
```rust
impl [T] {
pub const fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>;
pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>;
pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>;
pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>;
pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>;
pub fn split_first_chunk_mut<const N: usize>(&mut self) -> Option<(&mut [T; N], &mut [T])>;
pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>;
pub fn split_last_chunk_mut<const N: usize>(&mut self) -> Option<(&mut [T], &mut [T; N])>;
}
```
Const stabilization is included for all non-mut methods, which are blocked on `const_mut_refs`. This change includes marking the trivial function `slice_split_at_unchecked` const-stable for internal use (but not fully stable).
## Remove `split_array` slice methods
Tracking issue: https://github.com/rust-lang/rust/issues/90091
Implementation: https://github.com/rust-lang/rust/pull/83233#pullrequestreview-780315524
This PR also removes the following unstable methods from the `split_array` feature, https://github.com/rust-lang/rust/issues/90091:
```rust
impl<T> [T] {
pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T]);
pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T]);
pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N]);
pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N]);
}
```
This is done because discussion at #90091 and its implementation PR indicate a strong preference for nonpanicking APIs that return `Option`. The only difference between functions under the `split_array` and `slice_first_last_chunk` features is `Option` vs. panic, so remove the duplicates as part of this stabilization.
This does not affect the array methods from `split_array`. We will want to revisit these once `generic_const_exprs` is further along.
## Reverse order of return tuple for `split_last_chunk{,_mut}`
An unresolved question for #111774 is whether to return `(preceding_slice, last_chunk)` (`(&[T], &[T; N])`) or the reverse (`(&[T; N], &[T])`), from `split_last_chunk` and `split_last_chunk_mut`. It is currently implemented as `(last_chunk, preceding_slice)` which matches `split_last -> (&T, &[T])`. The first commit changes these to `(&[T], &[T; N])` for these reasons:
- More consistent with other splitting methods that return multiple values: `str::rsplit_once`, `slice::split_at{,_mut}`, `slice::align_to` all return tuples with the items in order
- More intuitive (arguably opinion, but it is consistent with other language elements like pattern matching `let [a, b, rest @ ..] ...`
- If we ever added a varidic way to obtain multiple chunks, it would likely return something in order: `.split_many_last::<(2, 4)>() -> (&[T], &[T; 2], &[T; 4])`
- It is the ordering used in the `rsplit_array` methods
I think the inconsistency with `split_last` could be acceptable in this case, since for `split_last` the scalar `&T` doesn't have any internal order to maintain with the other items.
## Unresolved questions
Do we want to reserve the same names on `[u8; N]` to avoid inference confusion? https://github.com/rust-lang/rust/pull/117561#issuecomment-1793388647
---
`slice_first_last_chunk` has only been around since early 2023, but `split_array` has been around since 2021.
`@rustbot` label -T-libs +T-libs-api -T-libs +needs-fcp
cc `@rust-lang/wg-const-eval,` `@scottmcm` who raised this topic, `@clarfonthey` implementer of `slice_first_last_chunk` `@jethrogb` implementer of `split_array`
Zulip discussion: https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Stabilizing.20array-from-slice.20*something*.3FFixes: #111774
Update `fn()` trait implementation docs
Fixes#119903
This was FCP'd and approved for the 1.70.0 release, this is just a docs update to match that change.
Docs: Use non-SeqCst in module example of atomics
I done this for this reasons:
1. The example now shows that there is more Orderings than just SeqCst.
2. People who would copy from example would now have more suitable orderings for the job.
3. SeqCst is both much harder to reason about and not needed in most situations.
IMHO, we should encourage people to think and use memory orderings that is suitable to task instead of blindly defaulting to SeqCst.
r? `@m-ou-se`
Consolidate all associated items on the NonZero integer types into a single impl block per type
**Before:**
```rust
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
pub struct NonZeroI8(i8);
impl NonZeroI8 {
pub const fn new(n: i8) -> Option<Self> ...
pub const fn get(self) -> i8 ...
}
impl NonZeroI8 {
pub const fn leading_zeros(self) -> u32 ...
pub const fn trailing_zeros(self) -> u32 ...
}
impl NonZeroI8 {
pub const fn abs(self) -> NonZeroI8 ...
}
...
```
**After:**
```rust
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
pub struct NonZeroI8(i8);
impl NonZeroI8 {
pub const fn new(n: i8) -> Option<Self> ...
pub const fn get(self) -> i8 ...
pub const fn leading_zeros(self) -> u32 ...
pub const fn trailing_zeros(self) -> u32 ...
pub const fn abs(self) -> NonZeroI8 ...
...
}
```
Having 6-7 different impl blocks per type is not such a problem in today's implementation, but becomes awful upon the switch to a generic `NonZero<T>` type (context: https://github.com/rust-lang/rust/issues/82363#issuecomment-921513910).
In the implementation from https://github.com/rust-lang/rust/pull/100428, there end up being **67** impl blocks on that type.
<img src="https://github.com/rust-lang/rust/assets/1940490/5b68bd6f-8a36-4922-baa3-348e30dbfcc1" width="200"><img src="https://github.com/rust-lang/rust/assets/1940490/2cfec71e-c2cd-4361-a542-487f13f435d9" width="200"><img src="https://github.com/rust-lang/rust/assets/1940490/2fe00337-7307-405d-9036-6fe1e58b2627" width="200">
Without the refactor to a single impl block first, introducing `NonZero<T>` would be a usability regression compared to today's separate pages per type. With all those blocks expanded, Ctrl+F is obnoxious because you need to skip 12× past every match you don't care about. With all the blocks collapsed, Ctrl+F is useless. Getting to a state in which exactly one type's (e.g. `NonZero<u32>`) impl blocks are expanded while the rest are collapsed is annoying.
After this refactor to a single impl block, we can move forward with making `NonZero<T>` a generic struct whose docs all go on the same rustdoc page. The rustdoc will have 12 impl blocks, one per choice of `T` supported by the standard library. The reader can expand a single one of those impl blocks e.g. `NonZero<u32>` to understand the entire API of that type.
Note that moving the API into a generic `impl<T> NonZero<T> { ... }` is not going to be an option until after `NonZero<T>` has been stabilized, which may be months or years after its introduction. During the period while generic `NonZero` is unstable, it will be extra important to offer good documentation on all methods demonstrating the API being used through the stable aliases such as `NonZeroI8`.
This PR follows a `key = $value` syntax for the macros which is similar to the macros we already use for producing a single large impl block on the integer primitives.
1dd4db5062/library/core/src/num/mod.rs (L288-L309)
Best reviewed one commit at a time.
The advantage of this is that it does not need to be assigned to a
variable to be used in a `Context` creation, which is the most common
thing to want to do with a noop waker.
If an owned noop waker is desired, it can be created by cloning, but the
reverse is harder. Alternatively, both versions could be provided, like
`futures::task::noop_waker()` and `futures::task::noop_waker_ref()`, but
that seems to me to be API clutter for a very small benefit, whereas
having the `&'static` reference available is a large benefit.
Previous discussion on the tracking issue starting here:
https://github.com/rust-lang/rust/issues/98286#issuecomment-1862159766
The internal, unstable field of `Pin` can conflict with fields from the
inner type accessed via the `Deref` impl. Rename it from `pointer` to
`__pointer`, to make it less likely to conflict with anything else.
Add private `NonZero<T>` type alias.
According to step 2 suggested in https://github.com/rust-lang/rust/pull/100428#pullrequestreview-1767139731.
This adds a private type alias for `NonZero<T>` so that some parts of the code can already start using `NonZero<T>` syntax.
Using `NonZero<T>` for `convert` and other parts which implement `From` doesn't work while it is a type alias, since this results in conflicting implementations.
Tune the inlinability of `unwrap`
Fixes#115463
cc `@thomcc`
This tweaks `unwrap` on ~~`Option` &~~ `Result` to be two parts:
- `#[inline(always)]` for checking the discriminant
- `#[cold]` for actually panicking
The idea here is that checking the discriminant on a `Result` ~~or `Option`~~ should always be trivial enough to be worth inlining, even in `opt-level=z`, especially compared to passing it to a function.
As seen in the issue and codegen test, this will hopefully help particularly for things like `.try_into().unwrap()`s that are actually infallible, but in a way that's only visible with the inlining.
EDIT: I've restricted this to `Result` to avoid combining effects
Later in this stack, as the nonzero_integers macro is going to be
responsible for producing a larger fraction of the API for the NonZero
integer types, it will need to receive a number of additional arguments
beyond the ones currently seen here.
Additional arguments, especially named arguments across multiple lines,
will turn out clearer if everything in one macro call is for the same
NonZero type.
This commit adopts a similar arrangement to what we do for generating
the API of the integer primitives (`impl u8` etc), which also generate a
single type's API per top-level macro call, rather than generating all
12 impl blocks for the 12 types from one macro call.
This way all the other macros defined in this module, such as
nonzero_leading_trailing_zeros, are available to call within the expansion of
nonzero_integers.
(Macros defined by macro_rules cannot be called from the same module above the
location of the macro_rules.)
In this commit the ability to call things like nonzero_leading_trailing_zeros is
not immediately used, but later commits in this stack will be consolidating the
entire API of NonZeroT to be generated through nonzero_integers, and will need
to make use of some of the other macros to do that.
Add Benchmarks for int_pow Methods.
There is quite a bit of room for improvement in performance of the `int_pow` family of methods. I added benchmarks for those functions. In particular, there are benchmarks for small compile-time bases to measure the effect of #114390. ~~I added a lot (245), but all but 22 of them are marked with `#[ignore]`. There are a lot of macros, and I would appreciate feedback on how to simplify them.~~
~~To run benches relevant to #114390, use `./x bench core --stage 1 -- pow_base_const --include-ignored`.~~
Optimize will_wake implementation by comparing vtable address instead
of its content.
The existing best practice to avoid false negatives from will_wake is
to define a waker vtable as a static item. That approach continues to
works with the new implementation.
While this potentially changes the observable behaviour, the function is
documented to work on a best-effort basis. The PartialEq impl for
RawWaker remains as it was.
This stabilizes all methods under `slice_first_last_chunk`.
Additionally, it const stabilizes the non-mut functions and moves the `_mut`
functions under `const_slice_first_last_chunk`. These are blocked on
`const_mut_refs`.
As part of this change, `slice_split_at_unchecked` was marked const-stable for
internal use (but not fully stable).
A more efficient slice comparison implementation for T: !BytewiseEq
(This is a follow up PR on #113654)
This PR changes the implementation for `[T]` slice comparison when `T: !BytewiseEq`. The previous implementation using zip was not optimized properly by the compiler, which didn't leverage the fact that both length were equal. Performance improvements are for example 20% when testing that `[Some(0_u64); 4096].as_slice() == [Some(0_u64); 4096].as_slice()`.
Use `assert_unsafe_precondition` for `char::from_u32_unchecked`
Use `assert_unsafe_precondition` in `char::from_u32_unchecked` so that it can be stabilized as `const`.
Rewrite `pin` module documentation to clarify usage and invariants
The documentation of `pin` today does not give a complete treatment of pinning from first principles, nor does it adequately help build intuition and understanding for how the different elements of the pinning story fit together.
This rewrite attempts to address these in a way that makes the concept more approachable while also making the documentation more normative.
This PR picks up where `@mcy` left off in #88500 (thanks to him for the original work and `@Manishearth` for mentioning it such that I originally found it). I've directly incorporated much of the feedback left on the original PR and have rewritten and changed some of the main conceits of the prose to better adhere to the feedback from the reviewers on that PR or just explain something in (hopefully) a better way.