Improve error messages involving `derive` and `packed`.
There are two errors involving `derive` and `packed`.
```
`#[derive]` can't be derived on a `#[repr(packed)]` struct with type or const parameters
`#[derive]` can't be derived on a `#[repr(packed)]` struct that does not derive Copy
```
The second one overstates things. It is possible to use derive on a
repr(packed) struct that doesn't derive Copy in two cases.
- If all the fields within the struct meet the required alignment: 1 for
`repr(packed)`, or `N` for `repr(packed(N))`.
- If `Default` is the only trait derived.
This commit improves things in a few ways.
- Changes the errors to say `this trait can't be derived on this ...`.
This is more accurate, because it's just *this* trait and *this*
packed struct that are a problem, not *all* derived traits on *all*
packed structs.
- Adds more details to the "ERROR" lines in the test case, enough to
distinguish between the two error messages.
- Adds more cases to the test case that don't cause errors, e.g. `Default`
derives.
- Uses a wider variety of builtin traits in the test case, for better coverage.
r? `@estebank`
rmeta: avoid embedding `StabilityLevel::Unstable` reason multiple times into .rmeta\.rlib files
Avoids bloating size of some rmeta\rlib files by not placing default string for `StabilityLevel::Unstable` reason multiple times, affects only stdlib\rustc artifacts. For stdlib cuts about 3% (diff of total size for patched\unpatched *.rmeta files of stage1-std) of file size, depending on crates.
fixes#88180
There are two errors involving `derive` and `packed`.
```
`#[derive]` can't be derived on a `#[repr(packed)]` struct with type or const parameters
`#[derive]` can't be derived on a `#[repr(packed)]` struct that does not derive Copy
```
The second one overstates things. It is possible to use derive on a
repr(packed) struct that doesn't derive Copy in two cases.
- If all the fields within the struct meet the required alignment: 1 for
`repr(packed)`, or `N` for `repr(packed(N))`.
- If `Default` is the only trait derived.
This commit improves things in a few ways.
- Changes the errors to say `$TRAIT can't be derived on this ...`.
This is more accurate, because it's just $TRAIT and *this* packed
struct that are a problem, not *all* derived traits on *all* packed
structs.
- Adds more details to the "ERROR" lines in the test case, enough to
distinguish between the two error messages.
- Adds more cases to the test case that don't cause errors, e.g. `Default`
derives.
- Uses a wider variety of builtin traits in the test case, for better coverage.
Update doc comments that refer to config parameter
This commit updates the `source_file_to_parser` and the
`maybe_source_file_to_parse` function's doc comments which currently
refer to a `config` parameter. The doc comments have been updated to
refer to the `session` parameter similar to the doc comment for
`try_file_to_source_file`, which also takes a `&Session` parameter.
remove some provenance-related machine hooks that Miri no longer needs
Then we can make `scalar_to_ptr` a method on `Scalar`. :)
Fixes https://github.com/rust-lang/miri/issues/2188
r? `@oli-obk`
This commit updates the source_file_to_parser and the
maybe_source_file_to_parse function's doc comments which currently
refer to a config parameter. The doc comments have been updated to
refer to the 'session' parameter similar to the doc comment for
try_file_to_source_file, which also takes a &Session parameter.
Upgrade indexmap and thorin-dwp to use hashbrown 0.12
This removes the last dependencies on hashbrown 0.11.
This also upgrades to hashbrown 0.12.3 to fix a double-free (#99372).
Add fine-grained LLVM CFI support to the Rust compiler
This PR improves the LLVM Control Flow Integrity (CFI) support in the Rust compiler by providing forward-edge control flow protection for Rust-compiled code only by aggregating function pointers in groups identified by their return and parameter types.
Forward-edge control flow protection for C or C++ and Rust -compiled code "mixed binaries" (i.e., for when C or C++ and Rust -compiled code share the same virtual address space) will be provided in later work as part of this project by identifying C char and integer type uses at the time types are encoded (see Type metadata in the design document in the tracking issue https://github.com/rust-lang/rust/issues/89653).
LLVM CFI can be enabled with -Zsanitizer=cfi and requires LTO (i.e., -Clto).
Thank you again, `@eddyb,` `@nagisa,` `@pcc,` and `@tmiasko` for all the help!
Rollup of 6 pull requests
Successful merges:
- #99298 (Make `ui-fulldeps/gated-plugins` and `ui-fulldeps/multiple-plugins` tests stage 2 only)
- #99396 (Add some additional double-adjustment regression tests)
- #99449 (Do not resolve associated const when there is no provided value)
- #99595 (Mark atomics as unsupported on thumbv6m)
- #99627 (Lock stdout once when listing tests)
- #99638 (Remove Clean trait implementation for hir::Ty and middle::Ty)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Mark atomics as unsupported on thumbv6m
The thumbv6m target does not support atomics. Historically, LLVM
had a bug where atomic load/stores for this target were emitted
as plain load/stores rather than as libatomic calls. This was
fixed in https://reviews.llvm.org/D120026, which will be part of
LLVM 15. As we require that "atomic support" does not use libatomic,
we need to indicate that this target does not have native atomics.
Do not resolve associated const when there is no provided value
Fixes#98629, since now we just delay a bug when we're not able to evaluate a const item due to the value not actually being provided by anything. This means compilation proceeds forward to where the "missing item in impl" error is emitted.
----
The root issue here is that when we're looking for the defining `LeafDef` in `resolve_associated_item`, we end up getting the trait's AssocItem instead of the impl's AssocItem (which does not exist). This resolution "succeeds" even if the trait's item has no default value, and then since this item has no value to evaluate, it turns into a const eval error.
This root issue becomes problematic (as in #98629) when this const eval error happens in wfcheck (for example, due to normalizing the param-env of something that references this const). Since this happens sooner than the check that an impl actually provides all of the items that a trait requires (which happens during later typecheck), we end up aborting compilation early with only this un-informative message.
I'm not exactly sure _why_ this bug arises due to #96591 -- perhaps valtrees are evaluated more eagerly than in the old system?
r? ``@oli-obk`` or ``@lcnr`` since y'all are familiar with const eval and reviewed #96591, though feel free to reassign.
This is a regression from stable to beta, so I would be open to considering this for beta backport. It seems correct to me, especially given the improvements in the other UI tests this PR touches, but may have some side-effects that I'm unaware of...?
Add support for LLVM ShadowCallStack.
LLVMs ShadowCallStack provides backward edge control flow integrity protection by using a separate shadow stack to store and retrieve a function's return address.
LLVM currently only supports this for AArch64 targets. The x18 register is used to hold the pointer to the shadow stack, and therefore this only works on ABIs which reserve x18. Further details are available in the [LLVM ShadowCallStack](https://clang.llvm.org/docs/ShadowCallStack.html) docs.
# Usage
`-Zsanitizer=shadow-call-stack`
# Comments/Caveats
* Currently only enabled for the aarch64-linux-android target
* Requires the platform to define a runtime to initialize the shadow stack, see the [LLVM docs](https://clang.llvm.org/docs/ShadowCallStack.html) for more detail.
This commit improves the LLVM Control Flow Integrity (CFI) support in
the Rust compiler by providing forward-edge control flow protection for
Rust-compiled code only by aggregating function pointers in groups
identified by their return and parameter types.
Forward-edge control flow protection for C or C++ and Rust -compiled
code "mixed binaries" (i.e., for when C or C++ and Rust -compiled code
share the same virtual address space) will be provided in later work as
part of this project by identifying C char and integer type uses at the
time types are encoded (see Type metadata in the design document in the
tracking issue #89653).
LLVM CFI can be enabled with -Zsanitizer=cfi and requires LTO (i.e.,
-Clto).
Use span_bug in case of unexpected rib kind
Extremely minor QOL change to improve the ICE compiler output in case
this default match case is encountered (an unexpected rib kind).
I have limited experience in this area of the compiler; please let me know
if a span more precise than `param.ident.span` is more applicable.
Fix hack that remaps env constness.
WARNING: might have perf implications.
Are there any more problems with having a constness in the `ParamEnv` now? :)
r? `@oli-obk`
The thumbv6m target does not support atomics. Historically, LLVM
had a bug where atomic load/stores for this target were emitted
as plain load/stores rather than as libatomic calls. This was
fixed in https://reviews.llvm.org/D120026, which will be part of
LLVM 15. As we require that "atomic support" does not use libatomic,
we need to indicate that this target does not have native atomics.
Improve suggestions for returning binding
Fixes#99525
Also reworks the cause codes for match and if a bit, I think cleaning them up in a positive way.
We no longer need to call `could_remove_semicolon` in successful code, which might save a few cycles?
Fix unreachable coverage generation for inlined functions
To generate a function coverage we need at least one coverage counter,
so a coverage from unreachable blocks is retained only when some live
counters remain.
The previous implementation incorrectly retained unreachable coverage,
because it didn't account for the fact that those live counters can
belong to another function due to inlining.
Fixes#98833.
make vtable pointers entirely opaque
This implements the scheme discussed in https://github.com/rust-lang/unsafe-code-guidelines/issues/338: vtable pointers should be considered entirely opaque and not even readable by Rust code, similar to function pointers.
- We have a new kind of `GlobalAlloc` that symbolically refers to a vtable.
- Miri uses that kind of allocation when generating a vtable.
- The codegen backends, upon encountering such an allocation, call `vtable_allocation` to obtain an actually dataful allocation for this vtable.
- We need new intrinsics to obtain the size and align from a vtable (for some `ptr::metadata` APIs), since direct accesses are UB now.
I had to touch quite a bit of code that I am not very familiar with, so some of this might not make much sense...
r? `@oli-obk`
move `considering_regions` to the infcx
it seems weird to prove some obligations which constrain inference vars while ignoring regions in a context which considers regions. This is especially weird because even for a fulfillment context with ignored regions, we still added region outlives bounds when directly relating regions.
tbh our handling of regions is still very weird, but at least this is a step in the right direction imo.
r? rust-lang/types
Allow to disable thinLTO buffer to support lto-embed-bitcode lld feature
Hello
This change is to fix issue (https://github.com/rust-lang/rust/issues/84395) in which passing "-lto-embed-bitcode=optimized" to lld when linking rust code via linker-plugin-lto doesn't produce the expected result.
Instead of emitting a single unified module into a llvmbc section of the linked elf, it emits multiple submodules.
This is caused because rustc emits the BC modules after running llvm `createWriteThinLTOBitcodePass` pass.
Which in turn triggers a thinLTO linkage and causes the said issue.
This patch allows via compiler flag (-Cemit-thin-lto=<bool>) to select between running `createWriteThinLTOBitcodePass` and `createBitcodeWriterPass`.
Note this pattern of selecting between those 2 passes is common inside of LLVM code.
The default is to match the old behavior.
Only compile #[used] as llvm.compiler.used for ELF targets
This returns `#[used]` to how it worked prior to the LLVM 13 update. The intention is not that this is a stable promise.
I'll add tests later today. The tests will test things that we don't actually promise, though.
It's a deliberately small patch, mostly comments. And assuming it's reviewed and lands in time, IMO it should at least be considered for uplifting to beta (so that it can be in 1.59), as the change broke many crates in the ecosystem, even if they are relying on behavior that is not guaranteed.
# Background
LLVM has two ways of preventing removal of an unused variable: `llvm.compiler.used`, which must be present in object files, but allows the linker to remove the value, and `llvm.used` which is supposed to apply to the linker as well, if possible.
Prior to LLVM 13, `llvm.used` and `llvm.compiler.used` were the same on ELF targets, although they were different elsewhere. Prior to our update to LLVM 13, we compiled `#[used]` using `llvm.used` unconditionally, even though we only ever promised behavior like `llvm.compiler.used`.
In LLVM 13, ELF targets gained some support for preventing linker removal of `llvm.used` via the SHF_RETAIN section flag. This has some compatibility issues though: Concretely: some older versions `ld.gold` (specifically ones prior to v2.36, released in Jan 2021) had a bug where it would fail to place a `#[used] #[link_section = ".init_array"]` static in between `__init_array_start`/`__init_array_end`, leading to code that does this failing to run a static constructor. This is technically not a thing we guarantee will work, is a common use case, and is needed in `libstd` (for example, to get access to `std::env::args()` even if Rust does not control `main`, such as when in a `cdylib` crate).
As a result, when updating to LLVM 13, we unconditionally switched to using `llvm.compiler.used`, which mirror the guarantees we make for `#[used]` and doesn't require the latest ld.gold. Unfortunately, this happened to break quite a bit of things in the ecosystem, as non-ELF targets had come to rely on `#[used]` being slightly stronger. In particular, there are cases where it will even break static constructors on these targets[^initinit] (and in fact, breaks way more use cases, as Mach-O uses special sections as an interface to the OS/linker/loader in many places).
As a result, we only switch to `llvm.compiler.used` on ELF[^elfish] targets. The rationale here is:
1. It is (hopefully) identical to the semantics we used prior to the LLVM13 update as prior to that update we unconditionally used `llvm.used`, but on ELF `llvm.used` was the same as `llvm.compiler.used`.
2. It seems to be how Clang compiles this, and given that they have similar (but stronger) compatibility promises, that makes sense.
[^initinit]: For Mach-O targets: It is not always guaranteed that `__DATA,__mod_init_func` is a GC root if it does not have the `S_MOD_INIT_FUNC_POINTERS` flag which we cannot add. In most cases, when ld64 transformed this section into `__DATA_CONST,__mod_init_func` it gets applied, but it's not clear that that is intentional (let alone guaranteed), and the logic is complex enough that it probably happens sometimes, and people in the wild report it occurring.
[^elfish]: Actually, there's not a great way to tell if it's ELF, so I've approximated it.
This is pretty ad-hoc and hacky! We probably should have a firmer set of guarantees here, but this change should relax the pressure on coming up with that considerably, returning it to previous levels.
---
Unsure who should review so leaving it open, but for sure CC `@nikic`
Remove the unused StableSet and StableMap types from rustc_data_structures.
The current implementation is not "stable" in the same sense that `HashStable` and `StableHasher` are stable, i.e. across compilation sessions. So, in my opinion, it's better to remove those types (which are basically unused anyway) than to give the wrong impression that these are safe for incr. comp.
I plan to provide new "stable" collection types soon that can be used to replace `FxHashMap` and `FxHashSet` in query results (see [draft](69d03ac7a7)). It's unsound that `HashMap` and `HashSet` implement `HashStable` (see https://github.com/rust-lang/rust/issues/98890 for a recent P-critical bug caused by this) -- so we should make some progress there.