It can be useful to do some computation in `assert!` format arguments, in order to get better error messages. For example:
```rust
assert!(
some_condition,
"The state is invalid. Details: {}",
expensive_call_to_get_debugging_info(),
);
```
It seems like `assert!` only evaluates the format arguments if the assertion fails, which is useful but doesn't appear to be documented anywhere. This PR documents the behavior and adds some tests.
The former `chain`+`chain`+`fold` implementation looked nice from a
functional-programming perspective, but it introduced unnecessary layers
of abstraction on every `flat_map`/`flatten` fold. It's straightforward
to just fold each part in turn, and this makes it look like a simplified
version of the existing `try_fold` implementation.
For the `iter::bench_flat_map*` benchmarks, I get a large improvement in
`bench_flat_map_chain_sum`, from 1,598,473 ns/iter to 499,889 ns/iter,
and the rest are unchanged.
This does not suggest adding such a function to the public API. This is
just for the purpose of avoiding duplicate code. Many array methods
already contained the same kind of code and there are still many array
related methods to come (e.g. `Iterator::{chunks, map_windows, next_n,
...}`) which all basically need this functionality. Writing custom
`unsafe` code for each of those seems not like a good idea.
The `may_have_side_effect` is an implementation detail of `TrustedRandomAccess`
trait. It describes if obtaining an iterator element may have side effects. It
is currently implemented as an associated function.
Turn `may_have_side_effect` into an associated constant. This makes the
value immediately available to the optimizer.
The use of module-level functions instead of associated functions
on `<*const T>` or `<*mut T>` follows the precedent of
`ptr::slice_from_raw_parts` and `ptr::slice_from_raw_parts_mut`.
Increment `self.index` before calling `Iterator::self.a.__iterator_ge…
…`t_unchecked` in `Zip` `TrustedRandomAccess` specialization
Otherwise if `Iterator::self.a.__iterator_get_unchecked` panics the
index would not have been incremented yet and another call to
`Iterator::next` would read from the same index again, which is not
allowed according to the API contract of `TrustedRandomAccess` for
`!Clone`.
Fixes https://github.com/rust-lang/rust/issues/81740
Only split doctest lang strings on `,`, ` `, and `\t`. Additionally, to
preserve backwards compatibility with pandoc-style langstrings, strip a
surrounding `{}`, and remove leading `.`s from each token.
Prior to this change, doctest lang strings were split on all
non-alphanumeric characters except `-` or `_`, which limited future
extensions to doctest lang string tokens, for example using `=` for
key-value tokens.
This is a breaking change, although it is not expected to be disruptive,
because lang strings using separators other than `,` and ` ` are not
very common
Bump stabilization version for const int methods
These methods missed the beta cutoff. See #80962 for details.
`@rustbot` modify labels to +A-const-fn, +A-intrinsics
r? `@m-ou-se`
Expand the docs for ops::ControlFlow a bit
Since I was writing some examples for an RFC anyway.
And I almost made the mistake of reordering the variants, so added a note and a test about that.
Stabilize remaining integer methods as `const fn`
This pull request stabilizes the following methods as `const fn`:
- `i*::checked_div`
- `i*::checked_div_euclid`
- `i*::checked_rem`
- `i*::checked_rem_euclid`
- `i*::div_euclid`
- `i*::overflowing_div`
- `i*::overflowing_div_euclid`
- `i*::overflowing_rem`
- `i*::overflowing_rem_euclid`
- `i*::rem_euclid`
- `i*::wrapping_div`
- `i*::wrapping_div_euclid`
- `i*::wrapping_rem`
- `i*::wrapping_rem_euclid`
- `u*::checked_div`
- `u*::checked_div_euclid`
- `u*::checked_rem`
- `u*::checked_rem_euclid`
- `u*::div_euclid`
- `u*::overflowing_div`
- `u*::overflowing_div_euclid`
- `u*::overflowing_rem`
- `u*::overflowing_rem_euclid`
- `u*::rem_euclid`
- `u*::wrapping_div`
- `u*::wrapping_div_euclid`
- `u*::wrapping_rem`
- `u*::wrapping_rem_euclid`
These can all be implemented on the current stable (1.49). There are two unstable details: const likely/unlikely and unchecked division/remainder. Both of these are for optimizations, and are in no way required to make the methods function; there is no exposure of these details publicly. Per comments below, it seems best practice is to stabilize the intrinsics. As such, `intrinsics::unchecked_div` and `intrinsics::unchecked_rem` have been stabilized as `const` as part of this pull request as well. The methods themselves remain unstable.
I believe part of the reason these were not stabilized previously was the behavior around division by 0 and modulo 0. After testing on nightly, the diagnostic for something like `const _: i8 = 5i8 % 0i8;` is similar to that of `const _: i8 = 5i8.rem_euclid(0i8);` (assuming the appropriate feature flag is enabled). As such, I believe these methods are ready to be stabilized as `const fn`.
This pull request represents the final methods mentioned in #53718. As such, this PR closes#53718.
`@rustbot` modify labels to +A-const-fn, +T-libs
expand/resolve: Turn `#[derive]` into a regular macro attribute
This PR turns `#[derive]` into a regular attribute macro declared in libcore and defined in `rustc_builtin_macros`, like it was previously done with other "active" attributes in https://github.com/rust-lang/rust/pull/62086, https://github.com/rust-lang/rust/pull/62735 and other PRs.
This PR is also a continuation of #65252, #69870 and other PRs linked from them, which layed the ground for converting `#[derive]` specifically.
`#[derive]` still asks `rustc_resolve` to resolve paths inside `derive(...)`, and `rustc_expand` gets those resolution results through some backdoor (which I'll try to address later), but otherwise `#[derive]` is treated as any other macro attributes, which simplifies the resolution-expansion infra pretty significantly.
The change has several observable effects on language and library.
Some of the language changes are **feature-gated** by [`feature(macro_attributes_in_derive_output)`](https://github.com/rust-lang/rust/issues/81119).
#### Library
- `derive` is now available through standard library as `{core,std}::prelude::v1::derive`.
#### Language
- `derive` now goes through name resolution, so it can now be renamed - `use derive as my_derive; #[my_derive(Debug)] struct S;`.
- `derive` now goes through name resolution, so this resolution can fail in corner cases. Crater found one such regression, where import `use foo as derive` goes into a cycle with `#[derive(Something)]`.
- **[feature-gated]** `#[derive]` is now expanded as any other attributes in left-to-right order. This allows to remove the restriction on other macro attributes following `#[derive]` (https://github.com/rust-lang/reference/issues/566). The following macro attributes become a part of the derive's input (this is not a change, non-macro attributes following `#[derive]` were treated in the same way previously).
- `#[derive]` is now expanded as any other attributes in left-to-right order. This means two derive attributes `#[derive(Foo)] #[derive(Bar)]` are now expanded separately rather than together. It doesn't generally make difference, except for esoteric cases. For example `#[derive(Foo)]` can now produce an import bringing `Bar` into scope, but previously both `Foo` and `Bar` were required to be resolved before expanding any of them.
- **[feature-gated]** `#[derive()]` (with empty list in parentheses) actually becomes useful. For historical reasons `#[derive]` *fully configures* its input, eagerly evaluating `cfg` everywhere in its target, for example on fields.
Expansion infra doesn't do that for other attributes, but now when macro attributes attributes are allowed to be written after `#[derive]`, it means that derive can *fully configure* items for them.
```rust
#[derive()]
#[my_attr]
struct S {
#[cfg(FALSE)] // this field in removed by `#[derive()]` and not observed by `#[my_attr]`
field: u8
}
```
- `#[derive]` on some non-item targets is now prohibited. This was accidentally allowed as noop in the past, but was warned about since early 2018 (#50092), despite that crater found a few such cases in unmaintained crates.
- Derive helper attributes used before their introduction are now reported with a deprecation lint. This change is long overdue (since macro modularization, https://github.com/rust-lang/rust/issues/52226#issuecomment-422605033), but it was hard to do without fixing expansion order for derives. The deprecation is tracked by #79202.
```rust
#[trait_helper] // warning: derive helper attribute is used before it is introduced
#[derive(Trait)]
struct S {}
```
Crater analysis: https://github.com/rust-lang/rust/pull/79078#issuecomment-731436821
Add a note about the correctness and the effect on unsafe code to the `ExactSizeIterator` docs
As it is a safe trait it does not provide any guarantee that the
returned length is correct and as such unsafe code must not rely on it.
That's why `TrustedLen` exists.
Fixes https://github.com/rust-lang/rust/issues/81739
Update LayoutError/LayoutErr stability attributes
`LayoutError` ended up not making it into 1.49.0, updating the stability attributes to reflect that.
I also pushed `LayoutErr` deprecation back a release to allow 2 releases before the deprecation comes into effect.
This change should be backported to beta.
Add lint for `panic!(123)` which is not accepted in Rust 2021.
This extends the `panic_fmt` lint to warn for all cases where the first argument cannot be interpreted as a format string, as will happen in Rust 2021.
It suggests to add `"{}",` to format the message as a string. In the case of `std::panic!()`, it also suggests the recently stabilized
`std::panic::panic_any()` function as an alternative.
It renames the lint to `non_fmt_panic` to match the lint naming guidelines.
![image](https://user-images.githubusercontent.com/783247/106520928-675ea680-64d5-11eb-81f7-d8fa48b93a0b.png)
This is part of #80162.
r? ```@estebank```
As it is a safe trait it does not provide any guarantee that the
returned length is correct and as such unsafe code must not rely on it.
That's why `TrustedLen` exists.
Fixes https://github.com/rust-lang/rust/issues/81739
Otherwise if `Iterator::self.a.__iterator_get_unchecked` panics the
index would not have been incremented yet and another call to
`Iterator::next` would read from the same index again, which is not
allowed according to the API contract of `TrustedRandomAccess` for
`!Clone`.
Fixes https://github.com/rust-lang/rust/issues/81740
Add some links to the cell docs.
This adds a few links to the cell module docs to make it a little easier to navigate to the types and functions it references.
Fix bug with assert!() calling the wrong edition of panic!().
The span of `panic!` produced by the `assert` macro did not carry the right edition. This changes `assert` to call the right version.
Also adds tests for the 2021 edition of panic and assert, that would've caught this.
Add doc aliases for "delete"
This patch adds doc aliases for "delete". The added aliases are supposed to reference usages `delete` in other programming languages.
- `HashMap::remove`, `BTreeMap::remove` -> `Map#delete` and `delete` keyword in JavaScript.
- `HashSet::remove`, `BTreeSet::remove` -> `Set#delete` in JavaScript.
- `mem::drop` -> `delete` keyword in C++.
- `fs::remove_file`, `fs::remove_dir`, `fs::remove_dir_all`-> `File#delete` in Java, `File#delete` and `Dir#delete` in Ruby.
Before this change, searching for "delete" in documentation returned no results.
Implement Rust 2021 panic
This implements the Rust 2021 versions of `panic!()`. See https://github.com/rust-lang/rust/issues/80162 and https://github.com/rust-lang/rfcs/pull/3007.
It does so by replacing `{std, core}::panic!()` by a bulitin macro that expands to either `$crate::panic::panic_2015!(..)` or `$crate::panic::panic_2021!(..)` depending on the edition of the caller.
This does not yet make std's panic an alias for core's panic on Rust 2021 as the RFC proposes. That will be a separate change: c5273bdfb2 That change is blocked on figuring out what to do with https://github.com/rust-lang/rust/issues/80846 first.