First of all, note that `Map` has three different relevant meanings.
- The `intravisit::Map` trait.
- The `map::Map` struct.
- The `NestedFilter::Map` associated type.
The `intravisit::Map` trait is impl'd twice.
- For `!`, where the methods are all unreachable.
- For `map::Map`, which gets HIR stuff from the `TyCtxt`.
As part of getting rid of `map::Map`, this commit changes `impl
intravisit::Map for map::Map` to `impl intravisit::Map for TyCtxt`. It's
fairly straightforward except various things are renamed, because the
existing names would no longer have made sense.
- `trait intravisit::Map` becomes `trait intravisit::HirTyCtxt`, so named
because it gets some HIR stuff from a `TyCtxt`.
- `NestedFilter::Map` assoc type becomes `NestedFilter::MaybeTyCtxt`,
because it's always `!` or `TyCtxt`.
- `Visitor::nested_visit_map` becomes `Visitor::maybe_tcx`.
I deliberately made the new trait and associated type names different to
avoid the old `type Map: Map` situation, which I found confusing. We now
have `type MaybeTyCtxt: HirTyCtxt`.
The end goal is to eliminate `Map` altogether.
I added a `hir_` prefix to all of them, that seemed simplest. The
exceptions are `module_items` which became `hir_module_free_items` because
there was already a `hir_module_items`, and `items` which became
`hir_free_items` for consistency with `hir_module_free_items`.
compiler: die immediately instead of handling unknown target codegen
We cannot produce anything useful if asked to compile unknown targets. We should handle the error immediately at the point of discovery instead of propagating it upward, and preferably in the simplest way: Die.
This allows cleaning up our "error-handling" spread across 5 crates.
We cannot produce anything useful if asked to compile unknown targets.
We should handle the error immediately at the point of discovery instead
of propagating it upward, and preferably in the simplest way: Die.
This allows cleaning up our "error-handling" spread across 5 crates.
Update bootstrap compiler and rustfmt
The rustfmt version we previously used formats things differently from what the latest nightly rustfmt does. This causes issues for subtrees that get formatted both in-tree and in their own repo. Updating the rustfmt used in-tree solves those issues. Also bumped the bootstrap compiler as the stage0 update command always updates both at the same
time.
It's a function that prints numbers with underscores inserted for
readability (e.g. "1_234_567"), used by `-Zmeta-stats` and
`-Zinput-stats`. It's the only thing in `rustc_middle::util::common`,
which is a bizarre location for it.
This commit:
- moves it to `rustc_data_structures`, a more logical crate for it;
- puts it in a module `thousands`, like the similar crates.io crate;
- renames it `format_with_underscores`, which is a clearer name;
- rewrites it to be more concise;
- slightly improves the testing.
```
error[E0271]: expected `{closure@fallback-closure-wrap.rs:18:40}` to be a closure that returns `()`, but it returns `!`
--> $DIR/fallback-closure-wrap.rs:19:9
|
LL | let error = Closure::wrap(Box::new(move || {
| -------
LL | panic!("Can't connect to server.");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `!`
|
= note: expected unit type `()`
found type `!`
= note: required for the cast from `Box<{closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47}>` to `Box<dyn FnMut()>`
```
```
error[E0271]: expected `{closure@dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10}` to be a closure that returns `bool`, but it returns `Option<()>`
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:6:16
|
LL | call(|| -> Option<()> {
| ---- ------^^^^^^^^^^
| | |
| | expected `bool`, found `Option<()>`
| required by a bound introduced by this call
|
= note: expected type `bool`
found enum `Option<()>`
note: required by a bound in `call`
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:3:25
|
LL | fn call(_: impl Fn() -> bool) {}
| ^^^^ required by this bound in `call`
```
```
error[E0271]: expected `{closure@f670.rs:28:13}` to be a closure that returns `Result<(), _>`, but it returns `!`
--> f670.rs:28:20
|
28 | let c = |e| -> ! {
| -------^
| |
| expected `Result<(), _>`, found `!`
...
32 | f().or_else(c);
| ------- required by a bound introduced by this call
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs:1433:28
|
= note: expected enum `Result<(), _>`
found type `!`
note: required by a bound in `Result::<T, E>::or_else`
--> /home/gh-estebank/rust/library/core/src/result.rs:1406:39
|
1406 | pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> {
| ^^^^^^^^^^^^ required by this bound in `Result::<T, E>::or_else`
```
Account for mutable borrow in argument suggestion
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
|
LL | object = &mut object2;
| ^^^^^^
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object3(object: &mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|
```
instead of
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
|
LL | object = &mut object2;
| ^^^^^^
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object3(object: &mut mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|
```
Fix#136028.
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
|
LL | object = &mut object2;
| ^^^^^^
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object3(object: &mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|
```
instead of
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
|
LL | object = &mut object2;
| ^^^^^^
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object3(object: &mut mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|
```
Fix#136028.
remove support for the (unstable) #[start] attribute
As explained by `@Noratrieb:`
`#[start]` should be deleted. It's nothing but an accidentally leaked implementation detail that's a not very useful mix between "portable" entrypoint logic and bad abstraction.
I think the way the stable user-facing entrypoint should work (and works today on stable) is pretty simple:
- `std`-using cross-platform programs should use `fn main()`. the compiler, together with `std`, will then ensure that code ends up at `main` (by having a platform-specific entrypoint that gets directed through `lang_start` in `std` to `main` - but that's just an implementation detail)
- `no_std` platform-specific programs should use `#![no_main]` and define their own platform-specific entrypoint symbol with `#[no_mangle]`, like `main`, `_start`, `WinMain` or `my_embedded_platform_wants_to_start_here`. most of them only support a single platform anyways, and need cfg for the different platform's ways of passing arguments or other things *anyways*
`#[start]` is in a super weird position of being neither of those two. It tries to pretend that it's cross-platform, but its signature is a total lie. Those arguments are just stubbed out to zero on ~~Windows~~ wasm, for example. It also only handles the platform-specific entrypoints for a few platforms that are supported by `std`, like Windows or Unix-likes. `my_embedded_platform_wants_to_start_here` can't use it, and neither could a libc-less Linux program.
So we have an attribute that only works in some cases anyways, that has a signature that's a total lie (and a signature that, as I might want to add, has changed recently, and that I definitely would not be comfortable giving *any* stability guarantees on), and where there's a pretty easy way to get things working without it in the first place.
Note that this feature has **not** been RFCed in the first place.
*This comment was posted [in May](https://github.com/rust-lang/rust/issues/29633#issuecomment-2088596042) and so far nobody spoke up in that issue with a usecase that would require keeping the attribute.*
Closes https://github.com/rust-lang/rust/issues/29633
try-job: x86_64-gnu-nopt
try-job: x86_64-msvc-1
try-job: x86_64-msvc-2
try-job: test-various
deprecate `std::intrinsics::transmute` etc, use `std::mem::*` instead
The `rustc_allowed_through_unstable_modules` attribute lets users call `std::mem::transmute` as `std::intrinsics::transmute`. The former is a reexport of the latter, and for a long time we didn't properly check stability for reexports, so making this a hard error now would be a breaking change for little gain. But at the same time, `std::intrinsics::transmute` is not the intended path for this function, so I think it is a good idea to show a deprecation warning when that path is used. This PR implements that, for all the functions in `std::intrinsics` that carry the attribute.
I assume this will need ``@rust-lang/libs-api`` FCP.
Exclude dependencies of `std` for diagnostics
Currently crates in the sysroot can show up in diagnostic suggestions, such as in https://github.com/rust-lang/rust/issues/135232. To prevent this, duplicate `all_traits` into `visible_traits` which only shows traits in non-private crates.
Setting `#![feature(rustc_private)]` overrides this and makes items in private crates visible as well, since `rustc_private` enables use of `std`'s private dependencies.
This may be reviewed per-commit.
Fixes: https://github.com/rust-lang/rust/issues/135232
Add an alternative to `tcx.all_traits()` that only shows traits that the
user might be able to use, for diagnostic purposes. With this available,
make use of it for diagnostics including associated type errors, which
is part of the problem with [1].
Includes a few comment updates for related API.
[1]: https://github.com/rust-lang/rust/issues/135232
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:11:5
|
LL | object = &object2;
| ^^^^^^
|
note: the lint level is defined here
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:1:9
|
LL | #![deny(unused_assignments, unused_variables)]
| ^^^^^^^^^^^^^^^^^^
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object2(object: &mut Object) {
LL | let object2 = Object;
LL ~ *object = object2;
|
```
This might be the first thing someone tries to write to mutate the value *behind* an argument, trying to avoid an E0308.
Adds `#[rustc_force_inline]` which is similar to always inlining but
reports an error if the inlining was not possible, and which always
attempts to inline annotated items, regardless of optimisation levels.
It can only be applied to free functions to guarantee that the MIR
inliner will be able to resolve calls.
Add support for wasm exception handling to Emscripten target
This is a draft because we need some additional setting for the Emscripten target to select between the old exception handling and the new exception handling. I don't know how to add a setting like that, would appreciate advice from Rust folks. We could maybe choose to use the new exception handling if `Ctarget-feature=+exception-handling` is passed? I tried this but I get errors from llvm so I'm not doing it right.
Restrict `#[non_exaustive]` on structs with default field values
Do not allow users to apply `#[non_exaustive]` to a struct when they have also used default field values.
This commit splits the `#[rustc_deny_explicit_impl(implement_via_object = ...)]` attribute
into two attributes `#[rustc_deny_explicit_impl]` and `#[rustc_do_not_implement_via_object]`.
This allows us to have special traits that can have user-defined impls but do not have the
automatic trait impl for trait objects (`impl Trait for dyn Trait`).
`rustc_span::symbol` defines some things that are re-exported from
`rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some
closely related things such as `Ident` and `kw`. So you can do `use
rustc_span::{Symbol, sym}` but you have to do `use
rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good
reason.
This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`,
and changes many `rustc_span::symbol::` qualifiers in `compiler/` to
`rustc_span::`. This is a 200+ net line of code reduction, mostly
because many files with two `use rustc_span` items can be reduced to
one.
Split up attribute parsing code and move data types to `rustc_attr_data_structures`
This change renames `rustc_attr` to `rustc_attr_parsing`, and splits up the parsing code. At the same time, all the data types used move to `rustc_attr_data_structures`. This is in preparation of also having a third crate: `rustc_attr_validation`
I initially envisioned this as two separate PRs, but I think doing it in one go reduces the number of ways others would have to rebase their changes on this. However, I can still split them.
r? `@oli-obk` (we already discussed how this is a first step in a larger plan)
For a more detailed plan on how attributes are going to change, see https://github.com/rust-lang/rust/issues/131229
Edit: this looks like a giant PR, but the changes are actually rather trivial. Each commit is reviewable on its own, and mostly moves code around. No new logic is added.
In #129533 the main hash function changed and the order of `-Z
input-stats` output changed, which showed that it is dependent on the
hash function, even though it is sorted. That's because entries with the
same cumulative size are ordered in a way that depends on the hash
function.
This commit fixes that by using the entry label as the secondary
ordering key.
`CheckAttrVisitor::check_doc_keyword` checks `#[doc(keyword = "..")]`
attributes to ensure they are on an empty module, and that the value is
a non-empty identifier.
The `rustc::existing_doc_keyword` lint checks these attributes to ensure
that the value is the name of a keyword.
It's silly to have two different checking mechanisms for these
attributes. This commit does the following.
- Changes `check_doc_keyword` to check that the value is the name of a
keyword (avoiding the need for the identifier check, which removes a
dependency on `rustc_lexer`).
- Removes the lint.
- Updates tests accordingly.
There is one hack: the `SelfTy` FIXME case used to used to be handled by
disabling the lint, but now is handled with a special case in
`is_doc_keyword`. That hack will go away if/when the FIXME is fixed.
Co-Authored-By: Guillaume Gomez <guillaume1.gomez@gmail.com>
Add some convenience helper methods on `hir::Safety`
Makes a lot of call sites simpler and should make any refactorings needed for https://github.com/rust-lang/rust/pull/134090#issuecomment-2541332415 simpler, as fewer sites have to be touched in case we end up storing some information in the variants of `hir::Safety`
Initial implementation of `#[feature(default_field_values]`, proposed in https://github.com/rust-lang/rfcs/pull/3681.
Support default fields in enum struct variant
Allow default values in an enum struct variant definition:
```rust
pub enum Bar {
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Allow using `..` without a base on an enum struct variant
```rust
Bar::Foo { .. }
```
`#[derive(Default)]` doesn't account for these as it is still gating `#[default]` only being allowed on unit variants.
Support `#[derive(Default)]` on enum struct variants with all defaulted fields
```rust
pub enum Bar {
#[default]
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Check for missing fields in typeck instead of mir_build.
Expand test with `const` param case (needs `generic_const_exprs` enabled).
Properly instantiate MIR const
The following works:
```rust
struct S<A> {
a: Vec<A> = Vec::new(),
}
S::<i32> { .. }
```
Add lint for default fields that will always fail const-eval
We *allow* this to happen for API writers that might want to rely on users'
getting a compile error when using the default field, different to the error
that they would get when the field isn't default. We could change this to
*always* error instead of being a lint, if we wanted.
This will *not* catch errors for partially evaluated consts, like when the
expression relies on a const parameter.
Suggestions when encountering `Foo { .. }` without `#[feature(default_field_values)]`:
- Suggest adding a base expression if there are missing fields.
- Suggest enabling the feature if all the missing fields have optional values.
- Suggest removing `..` if there are no missing fields.
Also this generates an error when `repr` is used on a trait method and
the `fn_align` feature is not enabled. Looks like that was missed here:
https://github.com/rust-lang/rust/pull/110313/files
Which first enables the align attribute on trait methods.
Get rid of HIR const checker
As far as I can tell, the HIR const checker was implemented in https://github.com/rust-lang/rust/pull/66170 because we were not able to issue useful const error messages in the MIR const checker.
This seems to have changed in the last 5 years, probably due to work like #90532. I've tweaked the diagnostics slightly and think the error messages have gotten *better* in fact.
Thus I think the HIR const checker has reached the end of its usefulness, and we can retire it.
cc `@RalfJung`
Minimally constify `Add`
* This PR removes the requirement for `impl const` to have a const stability attribute. cc ``@RalfJung`` I believe you mentioned that it would make much more sense to require `const_trait`s to have const stability instead. I agree with that sentiment but I don't think that is _required_ for a small scale experimentation like this PR. https://github.com/rust-lang/project-const-traits/issues/16 should definitely be prioritized in the future, but removing the impl check should be good for now as all callers need `const_trait_impl` enabled for any const impl to work.
* This PR is intentionally minimal as constifying other traits can become more complicated (`PartialEq`, for example, would run into requiring implementing it for `str` as that is used in matches, which runs into the implementation for slice equality which uses specialization)
Per the reasons above, anyone who is interested in making traits `const` in the standard library are **strongly encouraged** to reach out to us on the [Zulip channel](https://rust-lang.zulipchat.com/#narrow/channel/419616-t-compiler.2Fproject-const-traits) before proceeding with the work.
cc ``@rust-lang/project-const-traits``
I believe there is prior approval from libs that we can experiment, so
r? project-const-traits
Allow disabling ASan instrumentation for globals
AddressSanitizer adds instrumentation to global variables unless the [`no_sanitize_address`](https://llvm.org/docs/LangRef.html#global-attributes) attribute is set on them.
This commit extends the existing `#[no_sanitize(address)]` attribute to set this; previously it only had the desired effect on functions.
(cc https://github.com/rust-lang/rust/issues/39699)
Use attributes for `dangling_pointers_from_temporaries` lint
Checking for dangling pointers by function name isn't ideal, and leaves out certain pointer-returning methods that don't follow the `as_ptr` naming convention. Using an attribute for this lint cleans things up and allows more thorough coverage of other methods, such as `UnsafeCell::get()`.
Merge `-Zhir-stats` into `-Zinput-stats`
Currently `-Z hir-stats` prints the size and count of various kinds of nodes, and the total size of all the nodes it counted, but not the total count of nodes. So, before this PR:
```
$ git clone https://github.com/BurntSushi/ripgrep
$ cd ripgrep
$ cargo +nightly rustc -- -Z hir-stats
ast-stats-1 PRE EXPANSION AST STATS
ast-stats-1 Name Accumulated Size Count Item Size
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 ...
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total 93_576
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 ...
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total 2_430_648
ast-stats-2
hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size
hir-stats ----------------------------------------------------------------
hir-stats ...
hir-stats ----------------------------------------------------------------
hir-stats Total 3_678_512
hir-stats
```
For consistency, this PR adds a total for the count as well:
```
$ cargo +stage1 rustc -- -Z hir-stats
ast-stats-1 PRE EXPANSION AST STATS
ast-stats-1 Name Accumulated Size Count Item Size
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 ...
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total 93_576 1_877
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 ...
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total 2_430_648 48_625
ast-stats-2
hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size
hir-stats ----------------------------------------------------------------
hir-stats ...
hir-stats ----------------------------------------------------------------
hir-stats Total 3_678_512 73_418
hir-stats
```
I wasn't sure if I was supposed to update `tests/ui/stats/hir-stats.stderr` to reflect this. I ran it locally, thinking it would fail, but it didn't:
```
$ ./x test tests/ui/stats
...
running 2 tests
i.
test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 17949 filtered out
```
Also: is there a reason `-Z hir-stats` and `-Z input-stats` both exist? The former seems like it should completely supercede the latter. But strangely, the two give very different numbers for node counts:
```
$ cargo +nightly rustc -- -Z input-stats
...
Lines of code: 483
Pre-expansion node count: 2386
Post-expansion node count: 63844
```
That's a 30% difference in this case. Is it intentional that these numbers are so different? I see comments for both saying that they are merely approximations and should not be expected to be correct:
bd0826a452/compiler/rustc_ast_passes/src/node_count.rs (L1)bd0826a452/compiler/rustc_passes/src/hir_stats.rs (L1-L3)
the behavior of the type system not only depends on the current
assumptions, but also the currentnphase of the compiler. This is
mostly necessary as we need to decide whether and how to reveal
opaque types. We track this via the `TypingMode`.
Proper support for cross-crate recursive const stability checks
~~Stacked on top of https://github.com/rust-lang/rust/pull/132492; only the last three commits are new.~~
In a crate without `staged_api` but with `-Zforce-unstable-if-unmarked`, we now subject all functions marked with `#[rustc_const_stable_indirect]` to recursive const stability checks. We require an opt-in so that by default, a crate can be built with `-Zforce-unstable-if-unmarked` and use nightly features as usual. This property is recorded in the crate metadata so when a `staged_api` crate calls such a function, it sees the `#[rustc_const_stable_indirect]` and allows it to be exposed on stable. This, finally, will let us expose `const fn` from hashbrown on stable.
The second commit makes const stability more like regular stability: via `check_missing_const_stability`, we ensure that all publicly reachable functions have a const stability attribute -- both in `staged_api` crates and `-Zforce-unstable-if-unmarked` crates. To achieve this, we move around the stability computation so that const stability is computed after regular stability is done. This lets us access the final result of the regular stability computation, which we use so that `const fn` can inherit the regular stability (but only if that is "unstable"). Fortunately, this lets us get rid of an `Option` in `ConstStability`.
This is the last PR that I have planned in this series.
r? `@compiler-errors`
AddressSanitizer adds instrumentation to global variables unless the
[`no_sanitize_address`](https://llvm.org/docs/LangRef.html#global-attributes)
attribute is set on them.
This commit extends the existing `#[no_sanitize(address)]` attribute to
set this; previously it only had the desired effect on functions.
Rename `rustc_abi::Abi` to `BackendRepr`
Remove the confabulation of `rustc_abi::Abi` with what "ABI" actually means by renaming it to `BackendRepr`, and rename `Abi::Aggregate` to `BackendRepr::Memory`. The type never actually represented how things are passed, as that has to have `PassMode` considered, at minimum, but rather it just is how we represented some things to the backend. This conflation arose because LLVM, the primary backend at the time, would lower certain IR forms using certain ABIs. Even that only somewhat was true, as it broke down when one ventured significantly afield of what is described by the System V AMD64 ABI either by using different architectures, ABI-modifying IR annotations, the same architecture **with different ISA extensions enabled**, or other... unexpected delights.
Unfortunately both names are still somewhat of a misnomer right now, as people have written code for years based on this misunderstanding. Still, their original names are even moreso, and for better or worse, this backend code hasn't received as much maintenance as the rest of the compiler, lately. Actually arriving at a correct end-state will simply require us to disentangle a lot of code in order to fix, much of it pointlessly repeated in several places. Thus this is not an "actual fix", just a way to deflect further misunderstandings.
The initial naming of "Abi" was an awful mistake, conveying wrong ideas
about how psABIs worked and even more about what the enum meant.
It was only meant to represent the way the value would be described to
a codegen backend as it was lowered to that intermediate representation.
It was never meant to mean anything about the actual psABI handling!
The conflation is because LLVM typically will associate a certain form
with a certain ABI, but even that does not hold when the special cases
that actually exist arise, plus the IR annotations that modify the ABI.
Reframe `rustc_abi::Abi` as the `BackendRepr` of the type, and rename
`BackendRepr::Aggregate` as `BackendRepr::Memory`. Unfortunately, due to
the persistent misunderstandings, this too is now incorrect:
- Scattered ABI-relevant code is entangled with BackendRepr
- We do not always pre-compute a correct BackendRepr that reflects how
we "actually" want this value to be handled, so we leave the backend
interface to also inject various special-cases here
- In some cases `BackendRepr::Memory` is a "real" aggregate, but in
others it is in fact using memory, and in some cases it is a scalar!
Our rustc-to-backend lowering code handles this sort of thing right now.
That will eventually be addressed by lifting duplicated lowering code
to either rustc_codegen_ssa or rustc_target as appropriate.