Remove InstanceKind::generates_cgu_internal_copy
This PR should not contain any behavior changes. Before this PR, the logic for selecting instantiation mode is spread across all of
* `instantiation_mode`
* `cross_crate_inlinable`
* `generates_cgu_internal_copy`
* `requires_inline`
The last two of those functions are not well-designed. The function that actually decides if we generate a CGU-internal copy is `instantiation_mode`, _not_ `generates_cgu_internal_copy`. The function `requires_inline` documents that it is about the LLVM `inline` attribute and that it is a hint. The LLVM attribute is called `inlinehint`, this function is also used by other codegen backends, and since it is part of instantiation mode selection it is *not* a hint.
The goal of this PR is to start cleaning up the logic into a sequence of checks that have a more logical flow and are easier to customize in the future (to do things like improve incrementality or improve optimizations without causing obscure linker errors because you forgot to update another part of the compiler).
Add a helper for building an owner id in ast lowering
Just some deduplication of owner-id creations. Will also help me later split up ast lowering into per-owner queries, as it won't be possible anymore to go from a NodeId to a DefId of an owner without doing extra work to check whether we have an owner id. So I'd just do that in the new `owner_id` function and keep the `local_def_id` function free of that logic
Fix/tweak some tests in new solver
Bunch of miscellaneous new solver tweaks that I found from the failing tests. Can split these out, but they all seemed small enough to not warrant separate PRs.
r? lcnr
The existing code produces `Some(kw::Empty)` for these invalid forms:
- a non-name-value, e.g. `#[rustc_allowed_through_unstable_modules]`
- a non-string arg, e.g. `#[rustc_allowed_through_unstable_modules = 3]`
The new code avoids the `kw::Empty` and is a little shorter. It will
produce `None` in those cases, which means E0789 won't be produced if
the `stable` attribute is missing for these invalid forms. This doesn't
matter, because these invalid forms will trigger an "malformed
`rustc_allowed_through_unstable_modules` attribute" anyway.
This way, `None` represents "crate root without a name" instead of
`kw::Empty`. This changes makes it impossible to forget to handle the
exceptional case.
Lower to a memset(undef) when Rvalue::Repeat repeats uninit
Fixes https://github.com/rust-lang/rust/issues/138625.
It is technically correct to just do nothing. But if we actually do nothing, we may miss that this is de-initializing something, so instead we just lower to a single memset that writes undef. This is still superior to the memcpy loop, in both quality of code we hand to the backend and LLVM's final output.
Lower BinOp::Cmp to llvm.{s,u}cmp.* intrinsics
Lowers `mir::BinOp::Cmp` (`three_way_compare` intrinsic) to the corresponding LLVM `llvm.{s,u}cmp.i8.*` intrinsics.
These are the intrinsics mentioned in https://github.com/rust-lang/rust/pull/118310, which are now available in LLVM 19.
I couldn't find any follow-up PRs/discussions about this, please let me know if I missed something.
r? `@scottmcm`
`with_scope` is only ever used for ast modules
Thus I renamed it to match other similar functions (`with_mod_rib`) and made it panic if used on non-modules
match lowering cleanup: remove unused unsizing logic from `non_scalar_compare`
Since array and slice constants are now translated to array and slice patterns, `non_scalar_compare` is only used for string comparisons. This specializes it to strings, renames it, and removes the unused array-unsizing logic.
This also updates the doc comments for `thir::PatKind::Constant` and `TestKind::Eq`, which referred to them being used for slice references.
r? ````@oli-obk````
I saw someone post a code sample that contained these two attributes,
which immediately made me suspicious.
My suspicions were confirmed when I did a small test and checked the
compiler source code to confirm that in these cases, `#[inline]` is
indeed ignored (because you can't exactly `LocalCopy`an unmangled symbol
since that would lead to duplicate symbols, and doing a mix of an
unmangled `GloballyShared` and mangled `LocalCopy` instantiation is too
complicated for our current instatiation mode logic, which I don't want
to change right now).
So instead, emit the usual unused attribute lint with a message saying
that the attribute is ignored in this position.
I think this is not 100% true, since I expect LLVM `inlinehint` to still
be applied to such a function, but that's not why people use this
attribute, they use it for the `LocalCopy` instantiation mode, where it
doesn't work.
This fixes two problems with the autofixes for the `unused_imports`
lint:
- `use std::collections::{HashMap, self as coll};` would suggest, when
`HashMap` is unused, the incorrect `use std::collections::self as coll;`
which does not compile.
- `use std::borrow::{self, Cow};` would suggest, when `self` is unused,
`use std::borrow::{Cow};`, which contains unnecessary brackets.
Optimize hash map operations in the query system
This optimizes hash map operations in the query system by explicitly passing hashes and using more optimal operations. `find_or_find_insert_slot` in particular saves a hash table lookup over `entry`. It's not yet available in a safe API, but will be in https://github.com/rust-lang/hashbrown/pull/466.
<table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check</td><td align="right">1.6189s</td><td align="right">1.6129s</td><td align="right"> -0.37%</td></tr><tr><td>🟣 <b>hyper</b>:check</td><td align="right">0.2353s</td><td align="right">0.2337s</td><td align="right"> -0.67%</td></tr><tr><td>🟣 <b>regex</b>:check</td><td align="right">0.9344s</td><td align="right">0.9289s</td><td align="right"> -0.59%</td></tr><tr><td>🟣 <b>syn</b>:check</td><td align="right">1.4693s</td><td align="right">1.4652s</td><td align="right"> -0.28%</td></tr><tr><td>🟣 <b>syntex_syntax</b>:check</td><td align="right">5.6606s</td><td align="right">5.6439s</td><td align="right"> -0.30%</td></tr><tr><td>Total</td><td align="right">9.9185s</td><td align="right">9.8846s</td><td align="right"> -0.34%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">0.9956s</td><td align="right"> -0.44%</td></tr></table>
r? `@cjgillot`
They're dodgy, covering all the keywords, including weak ones, and
edition-specific ones without considering the edition. They have a
single use in rustfmt. This commit changes that use to
`is_reserved_ident`, which is a much more widely used alternative and is
good enough, judging by the lack of effect on the test suite.