resolve: Replace `Macros20NormalizedIdent` with `IdentKey`
This is a continuation of https://github.com/rust-lang/rust/pull/150741 and https://github.com/rust-lang/rust/pull/150982 based on the ideas from https://github.com/rust-lang/rust/pull/151491#issuecomment-3784421866.
Before this PR `Macros20NormalizedIdent` was used as a key in various "identifier -> its resolution" maps in `rustc_resolve`.
`Macros20NormalizedIdent` is a newtype around `Ident` in which `SyntaxContext` (packed inside `Span`) is guaranteed to be normalized using `normalize_to_macros_2_0`.
This type is also used in a number of functions looking up identifiers in those maps.
`Macros20NormalizedIdent` still contains span locations, which are useless and ignored during hash map lookups and comparisons due to `Ident`'s special `PartialEq` and `Hash` impls.
This PR replaces `Macros20NormalizedIdent` with a new type called `IdentKey`, which contains only a symbol and a normalized unpacked syntax context. (E.g. `IdentKey` == `Macros20NormalizedIdent` minus span locations.)
So we avoid keeping additional data and doing some syntax context packing/unpacking.
Along with `IdentKey` you can often see `orig_ident_span: Span` being passed around.
This is an unnormalized span of the original `Ident` from which `IdentKey` was obtained.
It is not used in map keys, but it is used in a number of other scenarios:
- diagnostics
- edition checks
- `allow_unstable` checks
This is because `normalize_to_macros_2_0` normalization is lossy and the normalized spans / syntax contexts no longer contain parts of macro backtraces, while the original span contains everything.
Tweak `SlicePartialEq` to allow MIR-inlining the `compare_bytes` call
rust-lang/rust#150265 disabled this because it was a net perf win, but let's see if we can tweak the structure of this to allow more inlining on this side while still not MIR-inlining the loop when it's not just `memcmp` and thus hopefully preserving the perf win.
This should also allow MIR-inlining the length check, which was previously blocked, and thus might allow some obvious non-matches to optimize away as well.
Don't try to evaluate const blocks during constant promotion
As of https://github.com/rust-lang/rust/pull/138499, trying to evaluate a const block in anything depended on by borrow-checking will result in a query cycle. Since that could happen in constant promotion, this PR adds a check for const blocks there to stop them from being evaluated.
Admittedly, this is a hack. See https://github.com/rust-lang/rust/issues/124328 for discussion of a more principled fix: removing cases like this from constant promotion altogether. To simplify the conditions under which promotion can occur, we probably shouldn't be implicitly promoting division or array indexing at all if possible. That would likely require a FCW and migration period, so I figure we may as well patch up the cycle now and simplify later.
Fixesrust-lang/rust#150464
I'll also lang-nominate this for visibility. I'm not sure there's much to discuss about this PR specifically, but it does represent a change in semantics. In Rust 1.87, the code below compiled. In Rust 1.88, it became a query cycle error. After this PR, it fails to borrow-check because the temporaries can no longer be promoted.
```rust
let (x, y, z);
// We only promote array indexing if the index is known to be in-bounds.
x = &([0][const { 0 }] & 0);
// We only promote integer division if the divisor is known not to be zero.
y = &(1 / const { 1 });
// Furthermore, if the divisor is `-1`, we only promote if the dividend is
// known not to be `int::MIN`.
z = &(const { 1 } / -1);
// The borrowed temporaries can't be promoted, so they were dropped at the ends
// of their respective statements.
(x, y, z);
```