Clean up the lowering of AST items
This PR simplifies and improves `rustc_ast_lowering::item` in various minor ways. The reasons for the changes should mostly be self evident, though I'm happy to specifically explain anything if needed.
These changes used to be part of #88019, but I removed them after it was pointed out that some of my other changes to `rustc_ast_lowering` were unnecessary. It felt like a bad idea to clean up code which I didn't even need to touch anymore.
r? `@cjgillot`
Add carrying_add, borrowing_sub, widening_mul, carrying_mul methods to integers
This comes in part from my own attempts to make (crude) big integer implementations, and also due to the stalled discussion in [RFC 2417](https://github.com/rust-lang/rfcs/pull/2417). My understanding is that changes like these are best offered directly as code and then an RFC can be opened if there needs to be more discussion before stabilisation. Since all of these methods are unstable from the start, I figured I might as well offer them now.
I tried looking into intrinsics, messed around with a few different implementations, and ultimately concluded that these are "good enough" implementations for now to at least put up some code and maybe start bikeshedding on a proper API for these.
For the `carrying_add` and `borrowing_sub`, I tried looking into potential architecture-specific code and realised that even using the LLVM intrinsics for `addcarry` and `subborrow` on x86 specifically, I was getting exactly the same assembly as the naive implementation using `overflowing_add` and `overflowing_sub`, although the LLVM IR did differ because of the architecture-specific code. Longer-term I think that they would be best suited to specific intrinsics as that would make optimisations easier (instructions like add-carry tend to use implicit flags, and thus can only be optimised if they're done one-after-another, and thus it would make the most sense to have compact intrinsics that can be merged together easily).
For `widening_mul` and `carrying_mul`, for now at least, I simply cast to the larger type and perform arithmetic that way, since we currently have no intrinsic that would work better for 128-bit integers. In the future, I also think that some form of intrinsic would work best to cover that case, but for now at least, I think that they're "good enough" for now.
The main reasoning for offering these directly to the standard library even though they're relatively niche optimisations is to help ensure that the code generated for them is optimal. Plus, these operations alone aren't enough to create big integer implementations, although they could help simplify the code required to do so and make it a bit more accessible for the average implementor.
That said, I 100% understand if any or all of these methods are not desired simply because of how niche they are. Up to you. 🤷🏻
Warn when [T; N].into_iter() is ambiguous in the new edition.
Fixes https://github.com/rust-lang/rust/issues/88475
In https://github.com/rust-lang/rust/issues/88475, a situation was found where `[T; N].into_iter()` becomes *ambiguous* in the new edition. This is different than the case where `(&[T; N]).into_iter()` resolves differently, which was the only case handled by the `array_into_iter` lint. This is almost identical to the new-traits-in-the-prelude problem. Effectively, due to the array-into-iter hack disappearing in Rust 2021, we effectively added `IntoIterator` to the 'prelude' in Rust 2021 specifically for arrays.
This modifies the prelude collisions lint to detect that case and emit a `array_into_iter` lint in that case.
Document `std::env::current_exe` possible rename behaviour
It might not be obvious that the "path of the current running executable" may (or may not) imply "at the time it was loaded".
This came up recently in chat so I thought it might be worth documenting.
Don't use `guess_head_span` in `predicates_of` for foreign span
Previously, the result of `predicates_of` for a foreign trait
would depend on the *current* state of the corresponding source
file in the foreign crate. This could lead to ICEs during incremental
compilation, since the on-disk contents of the upstream source file
could potentially change without the upstream crate being recompiled.
Additionally, this ensure that that the metadata we produce for a crate
only depends on its *compiled* upstream dependencies (e.g an rlib or
rmeta file), *not* the current on-disk state of the upstream crate
source files.