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.
Rollup of 9 pull requests
Successful merges:
- #99212 (introduce `implied_by` in `#[unstable]` attribute)
- #99352 (Use `typeck_results` to avoid duplicate `ast_ty_to_ty` call)
- #99355 (better error for bad depth parameter on macro metavar expr)
- #99480 (Diagnostic width span is not added when '0$' is used as width in format strings)
- #99488 (compiletest: Allow using revisions with debuginfo tests.)
- #99489 (rustdoc UI fixes)
- #99508 (Avoid `Symbol` to `String` conversions)
- #99510 (adapt assembly/static-relocation-model test for LLVM change)
- #99516 (Use new tracking issue for proc_macro::tracked_*.)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Diagnostic width span is not added when '0$' is used as width in format strings
When the following code is run rustc does not add diagnostic spans for the width argument. Such spans are necessary for a clippy lint that I am currently writing.
```rust
println!("Hello {1:0$}!", 5, "x");
// ^^
// Should have a span here
```
introduce `implied_by` in `#[unstable]` attribute
Requested by the library team [on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/better.20support.20for.20partial.20stabilizations/near/285581519).
If part of a feature is stabilized and a new feature is added for the remaining parts, then the `implied_by` meta-item can be added to `#[unstable]` to indicate which now-stable feature was used previously.
```diagnostic
error: the feature `foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `foobar`
--> $DIR/stability-attribute-implies-using-unstable.rs:3:12
|
LL | #![feature(foo)]
| ^^^
|
note: the lint level is defined here
--> $DIR/stability-attribute-implies-using-stable.rs:2:9
|
LL | #![deny(stable_features)]
| ^^^^^^^^^^^^^^^
help: if you are using features which are still unstable, change to using `foobar`
|
LL | #![feature(foobar)]
| ~~~~~~
help: if you are using features which are now stable, remove this line
|
LL - #![feature(foo)]
|
```
When a `#![feature(..)]` attribute still exists for the now-stable attribute, then there this has two effects:
- There will not be an stability error for uses of items from the implied feature which are still unstable (until the `#![feature(..)]` is removed or updated to the new feature).
- There will be an improved diagnostic for the remaining use of the feature attribute for the now-stable feature.
```rust
/// If part of a feature is stabilized and a new feature is added for the remaining parts,
/// then the `implied_by` attribute is used to indicate which now-stable feature previously
/// contained a item.
///
/// ```pseudo-Rust
/// #[unstable(feature = "foo", issue = "...")]
/// fn foo() {}
/// #[unstable(feature = "foo", issue = "...")]
/// fn foobar() {}
/// ```
///
/// ...becomes...
///
/// ```pseudo-Rust
/// #[stable(feature = "foo", since = "1.XX.X")]
/// fn foo() {}
/// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")]
/// fn foobar() {}
/// ```
```
In the Zulip discussion, this was envisioned as `implies` on `#[stable]` but I went with `implied_by` on `#[unstable]` because it means that only the unstable attribute needs to be changed in future, not the new stable attribute, which seems less error-prone. It also isn't particularly feasible for me to detect whether items from the implied feature are used and then only suggest updating _or_ removing the `#![feature(..)]` as appropriate, so I always do both.
There's some new information in the cross-crate metadata as a result of this change, that's a little unfortunate, but without requiring that the `#[unstable]` and `#[stable]` attributes both contain the implication information, it's necessary:
```rust
/// This mapping is necessary unless both the `#[stable]` and `#[unstable]` attributes should
/// specify their implications (both `implies` and `implied_by`). If only one of the two
/// attributes do (as in the current implementation, `implied_by` in `#[unstable]`), then this
/// mapping is necessary for diagnostics. When a "unnecessary feature attribute" error is
/// reported, only the `#[stable]` attribute information is available, so the map is necessary
/// to know that the feature implies another feature. If it were reversed, and the `#[stable]`
/// attribute had an `implies` meta item, then a map would be necessary when avoiding a "use of
/// unstable feature" error for a feature that was implied.
```
I also change some comments to documentation comments in the compiler, add a helper for going from a `Span` to a `Span` for the entire line, and fix a incorrect part of the pre-existing stability attribute diagnostics.
cc `@yaahc`
interpret: rename Tag/PointerTag to Prov/Provenance
We were pretty inconsistent with calling this the "tag" vs the "provenance" of the pointer; I think we should consistently call it "provenance".
r? `@oli-obk`
Improves the diagnostic when a feature attribute is specified
unnecessarily but the feature implies another (i.e. it was partially
stabilized) to refer to the implied feature.
Signed-off-by: David Wood <david.wood@huawei.com>
Adds a simple helper function to the `SourceMap` for extending a `Span`
to encompass the entire line it is on - useful for suggestions where
removing a line is the suggested action.
Signed-off-by: David Wood <david.wood@huawei.com>
If part of a feature is stabilized and a new feature is added for the
remaining parts, then the `implied_by` attribute can be used to indicate
which now-stable feature previously contained a item. If the now-stable
feature is still active (if the user has only just updated rustc, for
example) then there will not be an stability error for uses of the item
from the implied feature.
Signed-off-by: David Wood <david.wood@huawei.com>
Rollup of 7 pull requests
Successful merges:
- #98101 (stdlib support for Apple WatchOS)
- #99345 (Do not allow typeck children items to constrain outer RPITs)
- #99383 (Formalize defining_use_anchor)
- #99436 (Add flag to configure `noalias` on `Box<T>`)
- #99483 (Fix a numerical underflow in tuple wrap suggestion)
- #99485 (Stop injecting `#[allow(unused_qualifications)]` in generated `derive` implementations)
- #99486 (Refactor: remove a string comparison between types in `check_str_addition`)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Stop injecting `#[allow(unused_qualifications)]` in generated `derive` implementations
Currently, the `#[derive]` attribute always injects an `#[allow(unused_qualifications)]` attribute in the generated implementation. This results in an error when a derive is used in combination with `#![forbid(unused_qualifications)]`, because the `forbid` rule by definition cannot be overridden by `allow`.
It appears that the original issue that prompted the inclusion of `#[allow(unused_qualifications)]` (#19102) is no longer present in the current stable release, and the associated [test case](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-19102.rs) still passes, so the `allow` is simply removed here.
Fixes#71898.
Fix a numerical underflow in tuple wrap suggestion
Fixes#99482
I'm a clown, I rewrote the arg mismatch algo to use well-typed indices to avoid things like this, but then I added my own indexing bug, lol.
Add flag to configure `noalias` on `Box<T>`
The aliasing rules of `Box<T>` are still not decided, but currently, `Box<T>` is unique and gets `noalias`. To aid making an informed decision about the future of `Box<T>`, this PR adds a flag `-Zbox-noalias` to configure `noalias` for `Box<T>` (for example, for benchmarking). The same flag already exists for `&mut T` `noalias`, where it was added because it was the problem of various miscompilations in LLVM.
For more information, see rust-lang/unsafe-code-guidelines#326
Formalize defining_use_anchor
This tackles issue #57961
Introduces new enum called `DefiningAnchor` that replaces `Option<LocalDefId>` of `defining_use_anchor`. Now every use of it is explicit and exhaustively matched, catching errors like one in the linked issue. This is not a perfect fix but it's a step in the right direction.
r? `@oli-obk`
Do not allow typeck children items to constrain outer RPITs
Fixes#99073 in a simpler and more conservative way than #99079. Simply raise a mismatched types error if we try to constrain an RPIT in an item that isn't the RPIT's parent.
r? `@oli-obk`
When an unexpected meta item is provided to `#[stable]`, the diagnostic
lists "since" and "note" as expected meta-items, however the surrounding
code actually expects "feature" and "since".
Signed-off-by: David Wood <david.wood@huawei.com>
Rollup of 5 pull requests
Successful merges:
- #98784 (Suggest returning local on "expected `ty`, found `()`" due to expr-less block)
- #98916 (Windows: Use `FindFirstFileW` for getting the metadata of locked system files)
- #99433 (Erase regions before comparing signatures of foreign fns.)
- #99452 (int_macros was only using to_xe_bytes_doc and not from_xe_bytes_doc)
- #99481 (Add regression test for #71547)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Erase regions before comparing signatures of foreign fns.
Fixes https://github.com/rust-lang/rust/issues/99276
The version with explicit lifetimes is probably tracked in another bug, but I could not find it.
Suggest returning local on "expected `ty`, found `()`" due to expr-less block
Putting this up for _initial_ review. Notably, this doesn't consider if the value has possibly been moved, or whether the type is `Copy`. It also provides a structured suggestion if there's one "preferred" binding that matches the type (i.e. one binding in the block or its parent), otherwise it just points them out if there's fewer than 4 of them.
Fixes#98177
r? `@estebank`
Enable check-cfg in stage0
Now that the bootstrap cargo supports `rustc-check-cfg` we can now enable it with `-Zcheck-cfg=output` and use it in `rustc_llvm` to unblock `--check-cfg` support in stage0.
r? `@Mark-Simulacrum`
Let's avoid using two different terms for the same thing -- let's just call it "provenance" everywhere.
In Miri, provenance consists of an AllocId and an SbTag (Stacked Borrows tag), which made this even more confusing.
Improve the function pointer docs
This is #97842 but for function pointers instead of tuples. The concept is basically the same.
* Reduce duplicate impls; show `fn (T₁, T₂, …, Tₙ)` and include a sentence saying that there exists up to twelve of them.
* Show `Copy` and `Clone`.
* Show auto traits like `Send` and `Sync`, and blanket impls like `Any`.
https://notriddle.com/notriddle-rustdoc-test/std/primitive.fn.html
interpret: make some large types not Copy
Also remove some unused trait impls (mostly HashStable).
This didn't find any unnecessary copies that I managed to avoid, but it might still be better to require explicit clone for these types? Not sure.
r? `@oli-obk`
* Reduce duplicate impls; show only the `fn (T)` and include a sentence
saying that there exists up to twelve of them.
* Show `Copy` and `Clone`.
* Show auto traits like `Send` and `Sync`, and blanket impls like `Any`.
use `par_for_each_in` in `par_body_owners` and `collect_crate_mono_items`
Using `par_iter` in non-parallel mode will cause the entire process to abort when any iteration panics. So we can use `par_for_each_in` instead to make the error message consistent with parallel mode. This means that the compiler will output more error messages in some cases. This fixes the following ui tests when set `parallel-compiler = true`:
```
[ui] src/test\ui\privacy\privacy2.rs
[ui] src/test\ui\privacy\privacy3.rs
[ui] src/test\ui\type_length_limit.rs
```
This refers to #68171
Updates #75760
Revert "Stabilize $$ in Rust 1.63.0"
This mechanically reverts commit 9edaa76adc, the one commit from #95860.
https://github.com/rust-lang/rust/issues/99035; the behavior of `$$crate` is potentially unexpected and not ready to be stabilized. https://github.com/rust-lang/rust/pull/99193 attempts to forbid `$$crate` without also destabilizing `$$` more generally.
`@rustbot` modify labels +T-compiler +T-lang +P-medium +beta-nominated +relnotes
(applying the labels I think are accurate from the issue and alternative partial revert)
cc `@Mark-Simulacrum`
use body's param-env when checking if type needs drop
The type comes from the body, so we should be using the body's param-env, as opposed to the ADT's param env, because we know less in the latter compared to the former.
Fixes#99375
Add E0790 as more specific variant of E0283
Fixes#81701
I think this should be good to go, there are only two things where I am somewhat unsure:
- Is there a better way to get the fully-qualified path for the suggestion? I tried `self.tcx.def_path_str`, but that didn't seem to always give a correct path for the context.
- Should all this be extracted into it's own method or is it fine where it is?
r? `@estebank`
Update invalid atomic ordering lint
The restriction that success ordering must be at least as strong as its
failure ordering in compare-exchange operations was lifted in #98383.
Use span_bug for unexpected field projection type
Improves the compiler error backtrace information, as shown in #99363,
by using `span_bug` instead of `bug`.
New output:
```
build/aarch64-apple-darwin/stage1/bin/rustc /tmp/test.rs --edition=2021
error: internal compiler error: compiler/rustc_middle/src/ty/closure.rs:185:25: Unexpected type Opaque(DefId(0:5 ~ test[db0f]::main::T::{opaque#0}), []) for `Field` projection
--> /tmp/test.rs:11:27
|
11 | let Foo((a, b)) = foo;
| ^^^
thread 'rustc' panicked at 'Box<dyn Any>', /Users/jmq/src/forked/rust/compiler/rustc_errors/src/lib.rs:1331:9
stack backtrace:
```
(Remainder of output truncated.)
Mention first and last macro in backtrace
Slight improvement to diagnostic mentioning what macro an error originates from. Not sure if it's worthwhile.
wf-check generators
fixes#90409
We should not rely on generators being well formed by construction now that they can get used via type alias impl trait (and thus users can choose generic arguments that are invalid). This can cause surprising behaviour if (definitely unsound) transmutes are used, and it's generally saner to just check for well formedness.
proc_macro/bridge: stop using a remote object handle for proc_macro Ident and Literal
This is the fourth part of https://github.com/rust-lang/rust/pull/86822, split off as requested in https://github.com/rust-lang/rust/pull/86822#pullrequestreview-1008655452. This patch transforms the `Ident` and `Group` types into structs serialized over IPC rather than handles.
Symbol values are interned on both the client and server when deserializing, to avoid unnecessary string copies and keep the size of `TokenTree` down. To do the interning efficiently on the client, the proc-macro crate is given a vendored version of the fxhash hasher, as `SipHash` appeared to cause performance issues. This was done rather than depending on `rustc_hash` as it is unfortunately difficult to depend on crates from within `proc_macro` due to it being built at the same time as `std`.
In addition, a custom arena allocator and symbol store was also added, inspired by those in `rustc_arena` and `rustc_span`. To prevent symbol re-use across multiple invocations of a macro on the same thread, a new range of `Symbol` names are used for each invocation of the macro, and symbols from previous invocations are cleaned-up.
In order to keep `Ident` creation efficient, a special ASCII-only case was added to perform ident validation without using RPC for simple identifiers. Full identifier validation couldn't be easily added, as it would require depending on the `rustc_lexer` and `unicode-normalization` crates from within `proc_macro`. Unicode identifiers are validated and normalized using RPC.
See the individual commit messages for more details on trade-offs and design decisions behind these patches.
Currently `#![forbid(unused_qualifications)]` is incompatible with all
derive's because we add `#[allow(unused_qualifications)]` in all
generated impl's.
- Use `expr.hir_id.owner` instead of `self.tcx.parent_module(expr.hir_id)`
- Use `.type_at()` instead of `.first()` + `.expect_ty()`
- Use single `.find()` with `&&` condition
Co-authored-by: Michael Goulet <michael@errs.io>
Rollup of 7 pull requests
Successful merges:
- #98839 (Add assertion that `transmute_copy`'s U is not larger than T)
- #98998 (Remove branch target prologues from `#[naked] fn`)
- #99198 (add missing null ptr check in alloc example)
- #99344 (rustdoc: avoid inlining items with duplicate `(type, name)`)
- #99351 (Use `typeck_results` to get accurate qpath res for arg mismatch error)
- #99378 (interpret/visitor: add missing early return)
- #99394 (Add regression test for #95230)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup