Update list of allowed aarch64 features
I recently added these features to std_detect for aarch64 linux, pending [review](https://github.com/rust-lang/stdarch/pull/1146).
I have commented any features not supported by LLVM 9, the current minimum version for Rust. Some (PAuth at least) were renamed between 9 & 12 and I've left them disabled. TME, however, is not in LLVM 9 but I've left it enabled.
See https://github.com/rust-lang/stdarch/issues/993
CTFE Machine: do not expose Allocation
`Memory` is careful now to not expose direct access to `Allocation`, but this one slipped through.
r? ``@oli-obk``
impl FromStr for proc_macro::Literal
Note that unlike `impl FromStr for proc_macro::TokenStream`, this impl does not permit whitespace or comments. The input string must consist of nothing but your literal.
- `"1".parse::<Literal>()` ⟶ ok
- `"1.0".parse::<Literal>()` ⟶ ok
- `"'a'".parse::<Literal>()` ⟶ ok
- `"\"\n\"".parse::<Literal>()` ⟶ ok
- `"0 1".parse::<Literal>()` ⟶ LexError
- `" 0".parse::<Literal>()` ⟶ LexError
- `"0 ".parse::<Literal>()` ⟶ LexError
- `"/* comment */0".parse::<Literal>()` ⟶ LexError
- `"0/* comment */".parse::<Literal>()` ⟶ LexError
- `"0// comment".parse::<Literal>()` ⟶ LexError
---
## Use case
```rust
let hex_int: Literal = format!("0x{:x}", int).parse().unwrap();
```
The only way this is expressible in the current API is significantly worse.
```rust
let hex_int = match format!("0x{:x}", int)
.parse::<TokenStream>()
.unwrap()
.into_iter()
.next()
.unwrap()
{
TokenTree::Literal(literal) => literal,
_ => unreachable!(),
};
```
CTFE core engine allocation & memory API improvemenets
This is a first step towards https://github.com/rust-lang/miri/issues/841.
- make `Allocation` API offset-based (no more making up `Pointer`s just to access an `Allocation`)
- make `Memory` API higher-level (combine checking for access and getting access into one operation)
The Miri-side PR is at https://github.com/rust-lang/miri/pull/1804.
r? `@oli-obk`
Set dso_local for more items
Related to https://github.com/rust-lang/rust/pull/83592. (cc `@nagisa)`
Noticed that on x86_64 with `relocation-model: static` `R_X86_64_GOTPCREL` relocations were still generated in some cases. (related: https://github.com/Rust-for-Linux/linux/issues/135; Rust-for-Linux needs these fixes to successfully build)
First time doing anything with LLVM so not sure whether this is correct but the following are some of the things I've tried to convince myself.
## C equivalent
Example from clang which also sets `dso_local` in these cases:
`clang-12 -fno-PIC -S -emit-llvm test.c`
```C
extern int A;
int* a() {
return &A;
}
int B;
int* b() {
return &B;
}
```
```
; ModuleID = 'test.c'
source_filename = "test.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
`@A` = external dso_local global i32, align 4
`@B` = dso_local global i32 0, align 4
; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32* `@a()` #0 {
ret i32* `@A`
}
; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32* `@b()` #0 {
ret i32* `@B`
}
attributes #0 = { noinline nounwind optnone uwtable "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project/ b978a93635b584db380274d7c8963c73989944a1)"}
```
`clang-12 -fno-PIC -c test.c`
`objdump test.o -r`:
```
test.o: file format elf64-x86-64
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000006 R_X86_64_64 A
0000000000000016 R_X86_64_64 B
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET TYPE VALUE
0000000000000020 R_X86_64_PC32 .text
0000000000000040 R_X86_64_PC32 .text+0x0000000000000010
```
## Comparison to pre-LLVM 12 output
`rustc --emit=obj,llvm-ir --target=x86_64-unknown-none-linuxkernel --crate-type rlib test.rs`
```Rust
#![feature(no_core, lang_items)]
#![no_core]
#[lang="sized"]
trait Sized {}
#[lang="sync"]
trait Sync {}
#[lang = "drop_in_place"]
pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}
impl Sync for i32 {}
pub static STATIC: i32 = 32;
extern {
pub static EXT_STATIC: i32;
}
pub fn a() -> &'static i32 {
&STATIC
}
pub fn b() -> &'static i32 {
unsafe {&EXT_STATIC}
}
```
`objdump test.o -r`
nightly-2021-02-20 (rustc target is `x86_64-linux-kernel`):
```
RELOCATION RECORDS FOR [.text._ZN4test1a17h1024ba65f3424175E]:
OFFSET TYPE VALUE
0000000000000007 R_X86_64_32S _ZN4test6STATIC17h3adc41a83746c9ffE
RELOCATION RECORDS FOR [.text._ZN4test1b17h86a6a80c1190ac8dE]:
OFFSET TYPE VALUE
0000000000000007 R_X86_64_32S EXT_STATIC
```
nightly-2021-05-10:
```
RELOCATION RECORDS FOR [.text._ZN4test1a17he846f03bf37b2d20E]:
OFFSET TYPE VALUE
0000000000000007 R_X86_64_GOTPCREL _ZN4test6STATIC17h5a059515bf3d4968E-0x0000000000000004
RELOCATION RECORDS FOR [.text._ZN4test1b17h7e0f7f80fbd91125E]:
OFFSET TYPE VALUE
0000000000000007 R_X86_64_GOTPCREL EXT_STATIC-0x0000000000000004
```
This PR:
```
RELOCATION RECORDS FOR [.text._ZN4test1a17he846f03bf37b2d20E]:
OFFSET TYPE VALUE
0000000000000007 R_X86_64_32S _ZN4test6STATIC17h5a059515bf3d4968E
RELOCATION RECORDS FOR [.text._ZN4test1b17h7e0f7f80fbd91125E]:
OFFSET TYPE VALUE
0000000000000007 R_X86_64_32S EXT_STATIC
```
Only pass --[no-]gc-sections if linker is GNU ld.
Fixes a regression from #84468 where linking now fails with solaris linkers. LinkerFlavor::Gcc does not always mean GNU ld specifically. And in the case of at least the solaris ld in illumos, that flag is unrecognized and will cause the linking step to fail.
Even though removing the `is_like_solaris` branch from `gc_sections` in #84468 made sense as `-z ignore/record` are more analogous to the `--[no-]-as-needed` flags, it inadvertently caused solaris linkers to be passed the `--gc-sections` flag. So let's just change it to be more explicit about when we pass those flags.
Implement the new desugaring from `try_trait_v2`
~~Currently blocked on https://github.com/rust-lang/rust/issues/84782, which has a PR in https://github.com/rust-lang/rust/pull/84811~~ Rebased atop that fix.
`try_trait_v2` tracking issue: https://github.com/rust-lang/rust/issues/84277
Unfortunately this is already touching a ton of things, so if you have suggestions for good ways to split it up, I'd be happy to hear them. (The combination between the use in the library, the compiler changes, the corresponding diagnostic differences, even MIR tests mean that I don't really have a great plan for it other than trying to have decently-readable commits.
r? `@ghost`
~~(This probably shouldn't go in during the last week before the fork anyway.)~~ Fork happened.
- make Allocation API offset-based (no more Pointer)
- make Memory API higher-level (combine checking for access and getting access into one operation)
Rollup of 7 pull requests
Successful merges:
- #84587 (rustdoc: Make "rust code block is empty" and "could not parse code block" warnings a lint (`INVALID_RUST_CODEBLOCKS`))
- #85280 (Toggle-wrap items differently than top-doc.)
- #85338 (Implement more Iterator methods on core::iter::Repeat)
- #85339 (Report an error if a lang item has the wrong number of generic arguments)
- #85369 (Suggest borrowing if a trait implementation is found for &/&mut <type>)
- #85393 (Suppress spurious errors inside `async fn`)
- #85415 (Clean up remnants of BorrowOfPackedField)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Suggest borrowing if a trait implementation is found for &/&mut <type>
This pull request fixes#84973 by suggesting to borrow if a trait is not implemented for some type `T`, but it is for `&T` or `&mut T`. For instance:
```rust
trait Ti {}
impl<T> Ti for &T {}
fn foo<T: Ti>(_: T) {}
trait Tm {}
impl<T> Tm for &mut T {}
fn bar<T: Tm>(_: T) {}
fn main() {
let a: i32 = 5;
foo(a);
let b: Box<i32> = Box::new(42);
bar(b);
}
```
gives, on current nightly:
```
error[E0277]: the trait bound `i32: Ti` is not satisfied
--> t2.rs:11:9
|
3 | fn foo<T: Ti>(_: T) {}
| -- required by this bound in `foo`
...
11 | foo(a);
| ^ the trait `Ti` is not implemented for `i32`
error[E0277]: the trait bound `Box<i32>: Tm` is not satisfied
--> t2.rs:14:9
|
7 | fn bar<T: Tm>(_: T) {}
| -- required by this bound in `bar`
...
14 | bar(b);
| ^ the trait `Tm` is not implemented for `Box<i32>`
error: aborting due to 2 previous errors
```
whereas with my changes, I get:
```
error[E0277]: the trait bound `i32: Ti` is not satisfied
--> t2.rs:11:9
|
3 | fn foo<T: Ti>(_: T) {}
| -- required by this bound in `foo`
...
11 | foo(a);
| ^
| |
| expected an implementor of trait `Ti`
| help: consider borrowing here: `&a`
error[E0277]: the trait bound `Box<i32>: Tm` is not satisfied
--> t2.rs:14:9
|
7 | fn bar<T: Tm>(_: T) {}
| -- required by this bound in `bar`
...
14 | bar(b);
| ^
| |
| expected an implementor of trait `Tm`
| help: consider borrowing mutably here: `&mut b`
error: aborting due to 2 previous errors
```
In my implementation, I have added a "blacklist" to make these suggestions flexible. In particular, suggesting to borrow can interfere with other suggestions, such as to add another trait bound to a generic argument. I have tried to configure this blacklist to cause the least amount of test case failures, i.e. to model the current behavior as closely as possible (I only had to change one existing test case, and this change was quite clearly an improvement).
Report an error if a lang item has the wrong number of generic arguments
This pull request fixes#83893. The issue is that the lang item code currently checks whether the lang item has the correct item kind (e.g. a `#[lang="add"]` has to be a trait), but not whether the item has the correct number of generic arguments.
This can lead to an "index out of bounds" ICE when the compiler tries to create more substitutions than there are suitable types available (if the lang item was declared with too many generic arguments).
For instance, here is a reduced ("reduced" in the sense that it does not trigger additional errors) version of the example given in #83893:
```rust
#![feature(lang_items,no_core)]
#![no_core]
#![crate_type="lib"]
#[lang = "sized"]
trait MySized {}
#[lang = "add"]
trait MyAdd<'a, T> {}
fn ice() {
let r = 5;
let a = 6;
r + a
}
```
On current nightly, this immediately causes an ICE without any warnings or errors emitted. With the changes in this PR, however, I get no ICE and two errors:
```
error[E0718]: `add` language item must be applied to a trait with 1 generic argument
--> pr-ex.rs:8:1
|
8 | #[lang = "add"]
| ^^^^^^^^^^^^^^^
9 | trait MyAdd<'a, T> {}
| ------- this trait has 2 generic arguments, not 1
error[E0369]: cannot add `{integer}` to `{integer}`
--> pr-ex.rs:14:7
|
14 | r + a
| - ^ - {integer}
| |
| {integer}
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0369, E0718.
For more information about an error, try `rustc --explain E0369`.
```
Unify Regions with RegionVids in UnificationTable
A few test output changes; might be able to revert those but figured I would open this for perf and comments.
r? `@nikomatsakis`
# Stabilization report
## Summary
This stabilizes using macro expansion in key-value attributes, like so:
```rust
#[doc = include_str!("my_doc.md")]
struct S;
#[path = concat!(env!("OUT_DIR"), "/generated.rs")]
mod m;
```
See the changes to the reference for details on what macros are allowed;
see Petrochenkov's excellent blog post [on internals](https://internals.rust-lang.org/t/macro-expansion-points-in-attributes/11455)
for alternatives that were considered and rejected ("why accept no more
and no less?")
This has been available on nightly since 1.50 with no major issues.
## Notes
### Accepted syntax
The parser accepts arbitrary Rust expressions in this position, but any expression other than a macro invocation will ultimately lead to an error because it is not expected by the built-in expression forms (e.g., `#[doc]`). Note that decorators and the like may be able to observe other expression forms.
### Expansion ordering
Expansion of macro expressions in "inert" attributes occurs after decorators have executed, analogously to macro expressions appearing in the function body or other parts of decorator input.
There is currently no way for decorators to accept macros in key-value position if macro expansion must be performed before the decorator executes (if the macro can simply be copied into the output for later expansion, that can work).
## Test cases
- https://github.com/rust-lang/rust/blob/master/src/test/ui/attributes/key-value-expansion-on-mac.rs
- https://github.com/rust-lang/rust/blob/master/src/test/rustdoc/external-doc.rs
The feature has also been dogfooded extensively in the compiler and
standard library:
- https://github.com/rust-lang/rust/pull/83329
- https://github.com/rust-lang/rust/pull/83230
- https://github.com/rust-lang/rust/pull/82641
- https://github.com/rust-lang/rust/pull/80534
## Implementation history
- Initial proposal: https://github.com/rust-lang/rust/issues/55414#issuecomment-554005412
- Experiment to see how much code it would break: https://github.com/rust-lang/rust/pull/67121
- Preliminary work to restrict expansion that would conflict with this
feature: https://github.com/rust-lang/rust/pull/77271
- Initial implementation: https://github.com/rust-lang/rust/pull/78837
- Fix for an ICE: https://github.com/rust-lang/rust/pull/80563
## Unresolved Questions
~~https://github.com/rust-lang/rust/pull/83366#issuecomment-805180738 listed some concerns, but they have been resolved as of this final report.~~
## Additional Information
There are two workarounds that have a similar effect for `#[doc]`
attributes on nightly. One is to emulate this behavior by using a limited version of this feature that was stabilized for historical reasons:
```rust
macro_rules! forward_inner_docs {
($e:expr => $i:item) => {
#[doc = $e]
$i
};
}
forward_inner_docs!(include_str!("lib.rs") => struct S {});
```
This also works for other attributes (like `#[path = concat!(...)]`).
The other is to use `doc(include)`:
```rust
#![feature(external_doc)]
#[doc(include = "lib.rs")]
struct S {}
```
The first works, but is non-trivial for people to discover, and
difficult to read and maintain. The second is a strange special-case for
a particular use of the macro. This generalizes it to work for any use
case, not just including files.
I plan to remove `doc(include)` when this is stabilized. The
`forward_inner_docs` workaround will still compile without warnings, but
I expect it to be used less once it's no longer necessary.
This adds a new lint to `rustc` that is used in rustdoc when a code
block is empty or cannot be parsed as valid Rust code.
Previously this was unconditionally a warning. As such some
documentation comments were (unknowingly) abusing this to pass despite
the `-Dwarnings` used when compiling `rustc`, this should not be the
case anymore.
In https://reviews.llvm.org/D102093 lots of things stopped taking the
DebugLogging boolean parameter. Mercifully we appear to always set
DebugPassManager to false, so I don't think we're losing anything by not
passing this parameter.
Parse unnamed fields of struct and union type
Added the `unnamed_fields` feature gate.
This is a prototype of [RFC 2102](https://github.com/rust-lang/rust/issues/49804), so any suggestions are greatly appreciated.
r? `@petrochenkov`
Remove CrateNum parameter for queries that only work on local crate
The pervasive `CrateNum` parameter is a remnant of the multi-crate rustc idea.
Using `()` as query key in those cases avoids having to worry about the validity of the query key.
rustc_codegen_ssa: only create backend `BasicBlock`s as-needed.
Instead of creating one backend (e.g. LLVM) block per MIR block ahead of time, and then deleting the ones that weren't visited, this PR moves to creating the blocks as they're needed (either reached via the RPO visit, or used as the target of a branch from a different block).
As deleting a block was the only `unsafe` builder method (generally we only *create* backend objects, not *remove* them), that's gone now and codegen is overall a bit safer.
The only change in output is the order of LLVM blocks (which AFAIK has no semantic meaning, other than the first block being the entry block). This happens because the blocks are now created due to control-flow edges, rather than MIR block order.
I'm making this a standalone PR because I keep getting wild perf results when I change *anything* in codegen, but if you want to read more about my plans in this area, see https://github.com/rust-lang/rust/pull/84771#issuecomment-830636256 (and https://github.com/rust-lang/rust/pull/84771#issue-628295651 - but that may be a bit outdated).
(You may notice some of the APIs in this PR, like `append_block`, don't help with the future plans - but I didn't want to include the necessary refactors that pass a build around everywhere, in this PR, so it's a small compromise)
r? `@nagisa` `@bjorn3`
Fix unused attributes on macro_rules.
The `unused_attributes` lint wasn't firing on attributes of `macro_rules` definitions. The consequence is that many attributes are silently ignored on `macro_rules`. The reason is that `unused_attributes` is a late-lint pass, and only has access to the HIR, which does not have macro_rules definitions.
My solution here is to change `non_exported_macro_attrs` to be `macro_attrs` (a list of all attributes used for `macro_rules`, instead of just those for `macro_export`), and then to check this list in the `unused_attributes` lint. There are a number of alternate approaches, but this seemed the most reliable and least invasive. I am open to completely different approaches, though.
One concern is that I don't fully understand the implications of extending `non_exported_macro_attrs` to include non-exported macros. That list was originally added in #62042 to handle stability attributes, so I suspect it was just an optimization since that was all that was needed. It was later extended to be included in SVH in #83901. #80641 also added a use to check for `invalid` attributes, which seems a little odd to me (it didn't validate non-exported macros, and seems highly specific).
Overall, there doesn't seem to be a clear story of when `unused_attributes` should be used versus an error like E0518. I considered alternatively using an "allow list" of built-in attributes that can be used on macro_rules (allow, warn, deny, forbid, cfg, cfg_attr, macro_export, deprecated, doc), but I feel like that could be a pain to maintain.
Some built-in attributes already present hard-errors when used with macro_rules. These are each hard-coded in various places:
- `derive`
- `test` and `bench`
- `proc_macro` and `proc_macro_derive`
- `inline`
- `global_allocator`
The primary motivation is that I sometimes see people use `#[macro_use]` in front of `macro_rules`, which indicates there is some confusion out there (evident that there was even a case of it in rustc).
Remove support for floating-point constants in asm!
Floating-point constants aren't very useful anyways and this simplifies
the code since the type check can now be done in typeck.
cc `@rust-lang/wg-inline-asm`
r? `@nagisa`
Reachable statics have reachable initializers
Static initializer can read other statics. Initializers are evaluated at
compile time, and so their content could become inlined into another
crate. Ensure that initializers of reachable statics are also reachable.
Previously, when an item incorrectly considered to be unreachable was
reached from another crate an attempt would be made to codegen it. The
attempt could fail with an ICE (in the case MIR wasn't available to do
so) in some circumstances the attempt could also succeed resulting in
a local codegen of non-local items, including static ones.
Fixes#84455.
rustc_codegen_ssa: generate MSVC cleanup pads on demand, like GNU landing pads.
This unblocks #84993 in terms of codegen tests, as it brings the MSVC-style (`cleanup_pad`) EH (LLVM) block order in line with the GNU-style (`landing_pad`) EH (LLVM) block order, by having both of them be on-demand (instead of MSVC-style being eager and GNU-style lazy/on-demand).
It also unifies the two implementations a bit, similar to #84699, but in the opposite direction (as that attempt made both kinds of EH pads eagerly built).
~~Opening as draft because I haven't done enough Windows testing just yet, of both this PR, and of #84993 rebased on it.~~ (**EDIT**: seems to be working as expected)
r? `@nagisa`
CTFE validation: handle pointers in str
I also finally learned how I can match *some* NOTEs in a ui test without matching all of them, and applied that to some const tests in the 2nd commit where I added NOTE because I did not know what I was doing. I can separate this into its own PR if you prefer.
Fixes https://github.com/rust-lang/rust/issues/83182
r? `@oli-obk`
Check for inline assembly in THIR unsafeck
#83129 was merged recently and added a THIR unsafe checker. This adds a check for inline assembly. (and this is 2x simpler than the MIR version, which has to check for `asm` and `llvm_asm` in two separate spots!)
see also rust-lang/project-thir-unsafeck#7
Remove some unncessary spaces from pretty-printed tokenstream output
In addition to making the output look nicer for all crates, this also
aligns the pretty-printing output with what the `rental` crate expects.
This will allow us to eventually disable a backwards-compat hack in a
follow-up PR.
See https://github.com/rust-lang/rust/issues/84428 for some background information about why we want to make this change. Note that this change would be desirable (but not particularly necessary) even if `rental` didn't exist, so we're not adding any crate-specific hacks into the compiler.
In addition to making the output look nicer for all crates, this also
aligns the pretty-printing output with what the `rental` crate expects.
This will allow us to eventually disable a backwards-compat hack in a
follow-up PR.
Warn about unused `pub` fields in non-`pub` structs
This pull request fixes#85255. The current implementation of dead code analysis is too prudent because it marks all `pub` fields of structs as live, even though they cannot be accessed from outside of the current crate if the struct itself only has restricted or private visibility.
I have changed this behavior to take the containing struct's visibility into account when looking at field visibility and liveness. This also makes dead code warnings more consistent; consider the example given in #85255:
```rust
struct Foo {
a: i32,
pub b: i32,
}
struct Bar;
impl Bar {
fn a(&self) -> i32 { 5 }
pub fn b(&self) -> i32 { 6 }
}
fn main() {
let _ = Foo { a: 1, b: 2 };
let _ = Bar;
}
```
Current nightly already warns about `Bar::b()`, even though it is `pub` (but `Bar` is not). It should therefore also warn about `Foo::b`, which it does with the changes in this PR.
swap function order for better read flow
I was reading this error message for the first time.
I was a little bit confused when reading that part:
```
foo.bar(); // we can now use this method since i32 implements the Foo trait
```
At the time I was reading `// we can now use this method` I wasn't sure why. It only made sense when reading on. So swapping these parts results in a better read flow.
coverage bug fixes and some refactoring
This replaces the relevant commits (2 and 3) from PR #85082, and also corrects an error querying for coverageinfo.
1. `coverageinfo` query needs to use the same MIR as codegen
I ran into an error trying to fix dead block coverage and realized the
`coverageinfo` query is getting a different MIR compared to the
codegenned MIR, which can sometimes be a problem during mapgen.
I changed that query to use the `InstandeDef` (which includes the
generic parameter substitutions, prosibly specific to const params)
instead of the `DefId` (without unknown/default const substitutions).
2. Simplified body_span and filtered span code
Some code cleanup extracted from future (but unfinished) commit to fix
coverage in attr macro functions.
3. Spanview needs the relevant body_span used for coverage
The coverage body_span doesn't always match the function body_span.
r? ```@tmandry```
Preserve `SyntaxContext` for invalid/dummy spans in crate metadata
Fixes#85197
We already preserved the `SyntaxContext` for invalid/dummy spans in the
incremental cache, but we weren't doing the same for crate metadata.
If an invalid (lo/hi from different files) span is written to the
incremental cache, we will decode it with a 'dummy' location, but keep
the original `SyntaxContext`. Since the crate metadata encoder was only
checking for `DUMMY_SP` (dummy location + root `SyntaxContext`),
the metadata encoder would treat it as a normal span, encoding the
`SyntaxContext`. As a result, the final span encoded to the metadata
would change across sessions, even if the crate itself was unchanged.
This could lead to an 'unstable fingerprint' ICE under the following conditions:
1. We compile a crate with an invalid span using incremental compilation. The metadata encoder discards the `SyntaxContext` since the span is invalid, while the incremental cache encoder preserves the `SyntaxContext`
2. From another crate, we execute a foreign query, decoding the invalid span from the metadata as `DUMMY_SP` (e.g. with `SyntaxContext::root()`). This span gets hashed into the query fingerprint. So far, this has always happened through the `optimized_mir` query.
3. We recompile the first crate using our populated incremental cache, without changing anything. We load the (previously) invalid span from our incremental cache - it gets converted to a span with a dummy (but valid) location, along with the original `SyntaxContext`. This span gets written out to the crate metadata - since it now has a valid location, we preserve its `SyntaxContext`.
4. We recompile the second crate, again using a populated incremental cache. We now re-run the foreign query `optimized_mir` - the foreign crate hash is unchanged, but we end up decoding a different span (it now ha a non-root `SyntaxContext`). This results in the fingerprint changing, resulting in an ICE.
This PR updates our encoding of spans in the crate metadata to mirror
the encoding of spans into the incremental cache. We now always encode a
`SyntaxContext`, and encode location information for spans with a
non-dummy location.
Use the object crate for metadata reading
This allows sharing the metadata reader between cg_llvm, cg_clif and other codegen backends.
This is not currently useful for rlib reading with cg_spirv ([rust-gpu](https://github.com/EmbarkStudios/rust-gpu/)) as it uses tar rather than ar as .rlib format, but it is useful for dylib reading required for loading proc macros. (cc `@eddyb)`
The object crate is already trusted as dependency of libstd through backtrace. As far as I know it supports reading all object file formats used by targets for which we support rust dylibs with crate metadata, but I am not certain. If this happens to not be the case, I could keep using LLVM for reading dylib metadata.
Marked as WIP for a perf run and as it is based on #83637.
Improve error message for non-exhaustive matches on non-exhaustive enums
This pull request fixes#85227. For an enum marked with `#[non_exhaustive]` and not defined in the current crate, the error message for non-exhaustive matches now mentions the fact that the enum is marked as non-exhaustive:
```
error[E0004]: non-exhaustive patterns: `_` not covered
--> main.rs:12:11
|
12 | match e {
| ^ pattern `_` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
= note: the matched value is of type `E`, which is marked as non-exhaustive
```