previously field ordering was using the same seed for all instances of Foo,
now we pass seed values through the layout tree so that not only
the struct itself affects layout but also its fields
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.
Add `LayoutS::is_uninhabited` and use it
Use accessors for the things that accessors are good at: reducing everyone's need to be nosy and peek at the internals of every data structure.
For structs that cannot be unsized, the layout algorithm sometimes moves
unsized fields to the end of the struct, which circumvented the error
for unexpected unsized fields and returned an unsized layout anyway.
This commit makes it so that the unexpected unsized error is always
returned for structs that cannot be unsized, allowing us to remove an
old hack and fixing some old ICE.
Disable dead variant removal for `#[repr(C)]` enums.
This prevents removing dead branches from a `#[repr(C)]` enum (they now get discriminants allocated as if they were inhabited).
Implementation notes: ABI of something like
```rust
#[repr(C)]
enum Foo {
Foo(!),
}
```
is still `Uninhabited`, but its layout is now computed as if all the branches were inhabited.
This seemed to me like a proper way to do it, especially given that ABI sanity check explicitly asserts that type-level uninhabitedness implies ABI uninhabitedness.
This probably needs some sort of FCP (given that it changes `#[repr(C)]` layout, which is a stable guarantee), but I’m not sure how to call for one or which team is the most relevant.
See https://github.com/rust-lang/unsafe-code-guidelines/issues/500.
Represent `Result<usize, Box<T>>` as ScalarPair(i64, ptr)
This allows types like `Result<usize, std::io::Error>` (and integers of differing sign, e.g. `Result<u64, i64>`) to be passed in a pair of registers instead of through memory, like `Result<u64, u64>` or `Result<Box<T>, Box<U>>` are today.
Fixes#97540.
r? `@ghost`
From `impl Into<DiagnosticMessage>` to `impl Into<Cow<'static, str>>`.
Because these functions don't produce user-facing output and we don't
want their strings to be translated.
Unions cannot have unsized fields, and as such, layout computation for
unions asserts that each union field is sized (as this would normally
have halted compilation earlier).
However, if a generator ends up with an unsized local - a circumstance
in which an error will always have been emitted earlier, for example, if
attempting to dereference a `&str` - then the generator transform will
produce a union with an unsized field.
Since #110107, later passes will be run, such as constant propagation,
and can attempt layout computation on the generator, which will result
in layout computation of `str` in the context of it being a field of a
union - and so the aforementioned assertion would cause an ICE.
It didn't seem appropriate to try and detect this case in the MIR body
and skip this specific pass; tainting the MIR body or delaying a bug
from the generator transform (or elsewhere) wouldn't prevent this either
(as neither would prevent the later pass from running); and tainting when
the deref of `&str` is reported, if that's possible, would unnecessarily
prevent potential other errors from being reported later in compilation,
and is very tailored to this specific case of getting a unsized type in
a generator.
Given that this circumstance can only happen when an error should have
already been reported, the correct fix appears to be just changing the
assert to a delayed bug. This will still assert if there is some
circumstance where this occurs and no error has been reported, but it
won't crash the compiler in this instance.
Signed-off-by: David Wood <david@davidtw.co>