There was an incomplete version of the check in parsing and a second
version in AST validation. This meant that some, but not all, invalid
uses were allowed inside macros/disabled cfgs. It also means that later
passes have a hard time knowing when the let expression is in a valid
location, sometimes causing ICEs.
- Add a field to ExprKind::Let in AST/HIR to mark whether it's in a
valid location.
- Suppress later errors and MIR construction for invalid let
expressions.
Disentangle `Debug` and `Display` for `Ty`.
The `Debug` impl for `Ty` just calls the `Display` impl for `Ty`. This is surprising and annoying. In particular, it means `Debug` doesn't show as much information as `Debug` for `TyKind` does. And `Debug` is used in some user-facing error messages, which seems bad.
This commit changes the `Debug` impl for `Ty` to call the `Debug` impl for `TyKind`. It also does a number of follow-up changes to preserve existing output, many of which involve inserting
`with_no_trimmed_paths!` calls. It also adds `Display` impls for `UserType` and `Canonical`.
Some tests have changes to expected output:
- Those that use the `rustc_abi(debug)` attribute.
- Those that use the `rustc_layout(debug)` attribute.
- Those that use the `EMIT_MIR` annotation.
In each case the output is slightly uglier than before. This isn't ideal, but it's pretty weird (particularly for the attributes) that the output is using `Debug` in the first place. They're fairly obscure attributes (I hadn't heard of them) so I'm not worried by this.
For `async-is-unwindsafe.stderr`, there is one line that now lacks a full path. This is a consistency improvement, because all the other mentions of `Context` in this test lack a path.
The `Debug` impl for `Ty` just calls the `Display` impl for `Ty`. This
is surprising and annoying. In particular, it means `Debug` doesn't show
as much information as `Debug` for `TyKind` does. And `Debug` is used in
some user-facing error messages, which seems bad.
This commit changes the `Debug` impl for `Ty` to call the `Debug` impl
for `TyKind`. It also does a number of follow-up changes to preserve
existing output, many of which involve inserting
`with_no_trimmed_paths!` calls. It also adds `Display` impls for
`UserType` and `Canonical`.
Some tests have changes to expected output:
- Those that use the `rustc_abi(debug)` attribute.
- Those that use the `EMIT_MIR` annotation.
In each case the output is slightly uglier than before. This isn't
ideal, but it's pretty weird (particularly for the attribute) that the
output is using `Debug` in the first place. They're fairly obscure
attributes (I hadn't heard of them) so I'm not worried by this.
For `async-is-unwindsafe.stderr`, there is one line that now lacks a
full path. This is a consistency improvement, because all the other
mentions of `Context` in this test lack a path.
Encode only MIR reachable from other crates
Only reachable items might participate in the code generation in the
downstream crates. Omit redundant optimized MIR of unreachable items
from a crate metadata.
Additionally, include reachable closures in reachable set, so that
unreachable closures can be omitted on the same basis.
Only reachable items might participate in the code generation in the
downstream crates. Omit redundant optimized MIR of unreachable items
from a crate metadata.
Additionally, include reachable closures in reachable set, so that
unreachable closures can be omitted on the same basis.
The lint panicked for an input like 'extern "C" fn(Option<&<T as FooTrait>::FooType>)' because the type T therein cannot be normalized. The normalization failure caused SizeSkeleton::compute() to return an error and trigger a panic in the unwrap().
Fix sanitize/cfg.rs test
* Move needs-sanitizer conditions to specific revisions that require them (otherwise the conditions are mutually exclusive with needs-sanitizer-kcfi and test is always ignored).
* Add missing revisions
Improve "associated type not found" diagnostics
```rs
use core::ops::Deref;
fn foo<T>() where T: Deref<Output = u32> {}
```
Before:
```
error[E0220]: associated type `Output` not found for `Deref`
--> E0220.rs:5:28
|
5 | fn foo<T>() where T: Deref<Output = u32> {}
| ^^^^^^ associated type `Output` not found
```
After:
```
error[E0220]: associated type `Output` not found for `Deref`
--> E0220.rs:5:28
|
5 | fn foo<T>() where T: Deref<Output = u32> {}
| ^^^^^^ help: `Deref` has the following associated type: `Target`
```
---
`@rustbot` label +A-diagnostics +D-papercut
debuginfo: add compiler option to allow compressed debuginfo sections
LLVM already supports emitting compressed debuginfo. In debuginfo=full builds, the debug section is often a large amount of data, and it typically compresses very well (3x is not unreasonable.) We add a new knob to allow debuginfo to be compressed when the matching LLVM functionality is present. Like clang, if a known-but-disabled compression mechanism is requested, we disable compression and emit uncompressed debuginfo sections.
The API is different enough on older LLVMs we just pretend the support
is missing on LLVM older than 16.
Use the same DISubprogram for each instance of the same inlined function within a caller
# Issue Details:
The call to `panic` within a function like `Option::unwrap` is translated to LLVM as a `tail call` (as it will never return), when multiple calls to the same function like this are inlined LLVM will notice the common `tail call` block (i.e., loading the same panic string + location info and then calling `panic`) and merge them together.
When merging these instructions together, LLVM will also attempt to merge the debug locations as well, but this fails (i.e., debug info is dropped) as Rust emits a new `DISubprogram` at each inline site thus LLVM doesn't recognize that these are actually the same function and so thinks that there isn't a common debug location.
As an example of this, consider the following program:
```rust
#[no_mangle]
fn add_numbers(x: &Option<i32>, y: &Option<i32>) -> i32 {
let x1 = x.unwrap();
let y1 = y.unwrap();
x1 + y1
}
```
When building for x86_64 Windows using 1.72 it generates (note the lack of `.cv_loc` before the call to `panic`, thus it will be attributed to the same line at the `addq` instruction):
```llvm
.cv_loc 0 1 3 0 # src\lib.rs:3:0
addq $40, %rsp
retq
leaq .Lalloc_f570dea0a53168780ce9a91e67646421(%rip), %rcx
leaq .Lalloc_629ace53b7e5b76aaa810d549cc84ea3(%rip), %r8
movl $43, %edx
callq _ZN4core9panicking5panic17h12e60b9063f6dee8E
int3
```
# Fix Details:
Cache the `DISubprogram` emitted for each inlined function instance within a caller so that this can be reused if that instance is encountered again.
Ideally, we would also deduplicate child scopes and variables, however my attempt to do that with #114643 resulted in asserts when building for Linux (#115156) which would require some deep changes to Rust to fix (#115455).
Instead, when using an inlined function as a debug scope, we will also create a new child scope such that subsequent child scopes and variables do not collide (from LLVM's perspective).
After this change the above assembly now (with <https://reviews.llvm.org/D159226> as well) shows the `panic!` was inlined from `unwrap` in `option.rs` at line 935 into the current function in `lib.rs` at line 0 (line 0 is emitted since it is ambiguous which line to use as there were two inline sites that lead to this same code):
```llvm
.cv_loc 0 1 3 0 # src\lib.rs:3:0
addq $40, %rsp
retq
.cv_inline_site_id 6 within 0 inlined_at 1 0 0
.cv_loc 6 2 935 0 # library\core\src\option.rs:935:0
leaq .Lalloc_5f55955de67e57c79064b537689facea(%rip), %rcx
leaq .Lalloc_e741d4de8cb5801e1fd7a6c6795c1559(%rip), %r8
movl $43, %edx
callq _ZN4core9panicking5panic17hde1558f32d5b1c04E
int3
```
Using `ld.lld` may have been clever, but that was getting the /system/
ld.lld, not one we may have built as part of building llvm. By using the
warning message coming directly from rustc we now correctly skip the
zlib and zstd tests when the support is missing.
LLVM already supports emitting compressed debuginfo. In debuginfo=full
builds, the debug section is often a large amount of data, and it
typically compresses very well (3x is not unreasonable.) We add a new
knob to allow debuginfo to be compressed when the matching LLVM
functionality is present. Like clang, if a known-but-disabled
compression mechanism is requested, we disable compression and emit
uncompressed debuginfo sections.
The API is different enough on older LLVMs we just pretend the support
is missing on LLVM older than 16.
Rollup of 6 pull requests
Successful merges:
- #104299 (Clarify stability guarantee for lifetimes in enum discriminants)
- #115088 (Fix Step Skipping Caused by Using the `--exclude` Option)
- #115201 (rustdoc: list matching impls on type aliases)
- #115633 (Lint node for `PRIVATE_BOUNDS`/`PRIVATE_INTERFACES` is the item which names the private type)
- #115638 (`-Cllvm-args` usability improvement)
- #115643 (fix: return early when has tainted in mir-lint)
r? `@ghost`
`@rustbot` modify labels: rollup
* Move needs-sanitizer conditions to specific revisions that
require them (otherwise the conditions are mutually exclusive
with needs-sanitizer-kcfi and test is always ignored).
* Add missing revisions
fix: return early when has tainted in mir-lint
Fixes#115203
`a[..]` is of indeterminate size, it had been reported error during borrow check, therefore we skip the mir lint process.
Lint node for `PRIVATE_BOUNDS`/`PRIVATE_INTERFACES` is the item which names the private type
The HIR that the `PRIVATE_BOUNDS` lint should be attached to is the item that has the *bounds*, not the private type. This PR also aligns this behavior with the `EXPORTED_PRIVATE_DEPENDENCIES` lint, which also requires putting the `allow` on the item that names the private type.
Fixes#115475
r? petrochenkov
Add CL and CMD into to pdb debug info
Partial fix for https://github.com/rust-lang/rust/issues/96475
The Arg0 and CommandLineArgs of the MCTargetOptions cpp class are not set within bb548f9645/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp (L378)
This causes LLVM to not neither output any compiler path (cl) nor the arguments that were used when invoking it (cmd) in the PDB file.
This fix adds the missing information to the target machine so LLVM can use it.
diagnostics: add test case for trait bounds diagnostic
Closes#82038
It was fixed by https://github.com/rust-lang/rust/pull/89580, a wide-reaching obligation tracking improvement. This commit adds a test case.
Don't suggest dereferencing to unsized type
Rudimentary check that the self type is Sized. I don't really like any of this diagnostics code -- it's really messy and also really prone to false positives and negatives, but oh well.
Fixes#115569
Print the path of a return-position impl trait in trait when `return_type_notation` is enabled
When we're printing a return-position impl trait in trait, we usually just print it like an opaque. This is *usually* fine, but can be confusing when using `return_type_notation`. Print the path of the method from where the RPITIT originates when this feature gate is enabled.
rustdoc: Render private fields in tuple struct as `/* private fields */`
Reopening of https://github.com/rust-lang/rust/pull/110552. All that was missing was a test for the different cases so I added it into the second commit.
Description from the original PR:
> I've gotten some feedback that the current rustdoc rendering of...
>
> ```
> struct HasPrivateFields(_);
> ```
>
> ...is confusing, and I agree with that feedback, especially compared to the field struct case:
>
> ```
> struct HasPrivateFields { /* private fields */ }
> ```
>
> So this PR makes it so that when all of the fields of a tuple variant are private, just render it with the `/* private fields */` comment. We can't *always* render it like that, for example when there's a mix of private and public fields.
cc ````@jsha````
r? ````@notriddle````