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.
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 ()
> }
> ```
Remove argument from closure in thread::Scope::spawn.
This implements ```@danielhenrymantilla's``` [suggestion](https://github.com/rust-lang/rust/issues/93203#issuecomment-1040798286) for improving the scoped threads interface.
Summary:
The `Scope` type gets an extra lifetime argument, which represents basically its own lifetime that will be used in `&'scope Scope<'scope, 'env>`:
```diff
- pub struct Scope<'env> { .. };
+ pub struct Scope<'scope, 'env: 'scope> { .. }
pub fn scope<'env, F, T>(f: F) -> T
where
- F: FnOnce(&Scope<'env>) -> T;
+ F: for<'scope> FnOnce(&'scope Scope<'scope, 'env>) -> T;
```
This simplifies the `spawn` function, which now no longer passes an argument to the closure you give it, and now uses the `'scope` lifetime for everything:
```diff
- pub fn spawn<'scope, F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T>
+ pub fn spawn<F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T>
where
- F: FnOnce(&Scope<'env>) -> T + Send + 'env,
+ F: FnOnce() -> T + Send + 'scope,
- T: Send + 'env;
+ T: Send + 'scope;
```
The only difference the user will notice, is that their closure now takes no arguments anymore, even when spawning threads from spawned threads:
```diff
thread::scope(|s| {
- s.spawn(|_| {
+ s.spawn(|| {
...
});
- s.spawn(|s| {
+ s.spawn(|| {
...
- s.spawn(|_| ...);
+ s.spawn(|| ...);
});
});
```
<details><summary>And, as a bonus, errors get <em>slightly</em> better because now any lifetime issues point to the outermost <code>s</code> (since there is only one <code>s</code>), rather than the innermost <code>s</code>, making it clear that the lifetime lasts for the entire <code>thread::scope</code>.
</summary>
```diff
error[E0373]: closure may outlive the current function, but it borrows `a`, which is owned by the current function
--> src/main.rs:9:21
|
- 7 | s.spawn(|s| {
- | - has type `&Scope<'1>`
+ 6 | thread::scope(|s| {
+ | - lifetime `'1` appears in the type of `s`
9 | s.spawn(|| println!("{:?}", a)); // might run after `a` is dropped
| ^^ - `a` is borrowed here
| |
| may outlive borrowed value `a`
|
note: function requires argument type to outlive `'1`
--> src/main.rs:9:13
|
9 | s.spawn(|| println!("{:?}", a)); // might run after `a` is dropped
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword
|
9 | s.spawn(move || println!("{:?}", a)); // might run after `a` is dropped
| ++++
"
```
</details>
The downside is that the signature of `scope` and `Scope` gets slightly more complex, but in most cases the user wouldn't need to write those, as they just use the argument provided by `thread::scope` without having to name its type.
Another downside is that this does not work nicely in Rust 2015 and Rust 2018, since in those editions, `s` would be captured by reference and not by copy. In those editions, the user would need to use `move ||` to capture `s` by copy. (Which is what the compiler suggests in the error.)
Add Result::{ok, err, and, or, unwrap_or} as const
Already opened tracking issue #92384.
I don't think that this should actually cause any issues as long as the constness is unstable, but we may want to double-check that this doesn't get interpreted as a weird `Drop` bound even for non-const usages.
Rollup of 5 pull requests
Successful merges:
- #94362 (Add well known values to `--check-cfg` implementation)
- #94577 (only disable SIMD for doctests in Miri (not for the stdlib build itself))
- #94595 (Fix invalid `unresolved imports` errors for a single-segment import)
- #94596 (Delay bug in expr adjustment when check_expr is called multiple times)
- #94618 (Don't round stack size up for created threads in Windows)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
only disable SIMD for doctests in Miri (not for the stdlib build itself)
Also we can enable library/core/tests/simd.rs now, Miri supports enough SIMD for that.
Miri/CTFE: properly treat overflow in (signed) division/rem as UB
To my surprise, it looks like LLVM treats overflow of signed div/rem as UB. From what I can tell, MIR `Div`/`Rem` directly lowers to the corresponding LLVM operation, so to make that correct we also have to consider these overflows UB in the CTFE/Miri interpreter engine.
r? `@oli-obk`
When CStr moves to core with an alias in std, this can link to
`crate::ffi::CStr`. However, linking in the reverse direction (from core
to std) requires a relative path, and that path can't work from both
core::ffi and std::os::raw (different number of `../` traversals
required).
The ability to interoperate with C code via FFI is not limited to crates
using std; this allows using these types without std.
The existing types in `std::os::raw` become type aliases for the ones in
`core::ffi`. This uses type aliases rather than re-exports, to allow the
std types to remain stable while the core types are unstable.
This also moves the currently unstable `NonZero_` variants and
`c_size_t`/`c_ssize_t`/`c_ptrdiff_t` types to `core::ffi`, while leaving
them unstable.
core can't depend on external crates the way std can. Rather than revert
usage of cfg_if, add a copy of it to core. This does not export our
copy, even unstably; such a change could occur in a later commit.
Add Atomic*::from_mut_slice
Tracking issue #76314 for `from_mut` has a question about the possibility of `from_mut_slice`, and I found a real case for it. A user in the forum had a parallelism problem that could be solved by open-indexing updates to a vector of atomics, but they didn't want to affect the other code using that vector. Using `from_mut_slice`, they could borrow that data as atomics just long enough for their parallel loop.
ref: https://users.rust-lang.org/t/sharing-vector-with-rayon-par-iter-correctly/72022