Fix argument removal suggestion around macros
Fixes#112437.
Fixes#113866.
Helps with #114255.
The issue was that `span.find_ancestor_inside(outer)` could previously return a span with a different expansion context from `outer`.
This happens for example for the built-in macro `panic!`, which expands to another macro call of `panic_2021!` or `panic_2015!`. Because the call site of `panic_20xx!` has not associated source code, its span currently points to the call site of `panic!` instead.
Something similar also happens items that get desugared in AST->HIR lowering. For example, `for` loops get two spans: One "inner" span that has the `.desugaring_kind()` kind set to `DesugaringKind::ForLoop` and one "outer" span that does not. Similar to the macro situation, both of these spans point to the same source code, but have different expansion contexts.
This causes problems, because joining two spans with different expansion contexts will usually[^1] not actually join them together to avoid creating "spaghetti" spans that go from the macro definition to the macro call. For example, in the following snippet `full_span` might not actually contain the `adjusted_start` and `adjusted_end`. This caused the broken suggestion / debug ICE in the linked issues.
```rust
let adjusted_start = start.find_ancestor_inside(shared_ancestor);
let adjusted_end = end.find_ancestor_inside(shared_ancestor);
let full_span = adjusted_start.to(adjusted_end)
```
To fix the issue, this PR introduces a new method, `find_ancestor_inside_same_ctxt`, which combines the functionality of `find_ancestor_inside` and `find_ancestor_in_same_ctxt`: It finds an ancestor span that is contained within the parent *and* has the same syntax context, and is therefore safe to extend. This new method should probably be used everywhere, where the returned span is extended, but for now it is just used for the argument removal suggestion.
Additionally, this PR fixes a second issue where the function call itself is inside a macro but the arguments come from outside the macro. The test is added in the first commit to include stderr diff, so this is best reviewed commit by commit.
[^1]: If one expansion context is the root context and the other is not.
Rollup of 7 pull requests
Successful merges:
- #114721 (Optimizing the rest of bool's Ord implementation)
- #114746 (Don't add associated type bound for non-types)
- #114779 (Add check before suggest removing parens)
- #114859 (Add trait related queries to SMIR's rustc_internal)
- #114861 (fix typo: affect -> effect)
- #114867 ([nit] Fix a comment typo.)
- #114871 (Update the link in the docs of `std::intrinsics`)
r? `@ghost`
`@rustbot` modify labels: rollup
Don't add associated type bound for non-types
We had this fix for equality constraints (#99890), but for some reason not trait constraints 😅Fixes#114744
Optimizing the rest of bool's Ord implementation
After coming across issue #66780, I realized that the other functions provided by Ord (`min`, `max`, and `clamp`) were similarly inefficient for bool. This change provides implementations for them in terms of boolean operators, resulting in much simpler assembly and faster code.
Fixes issue #114653
[Comparison on Godbolt](https://rust.godbolt.org/z/5nb5P8e8j)
`max` assembly before:
```assembly
example::max:
mov eax, edi
mov ecx, eax
neg cl
mov edx, esi
not dl
cmp dl, cl
cmove eax, esi
ret
```
`max` assembly after:
```assembly
example::max:
mov eax, edi
or eax, esi
ret
```
`clamp` assembly before:
```assembly
example:🗜️
mov eax, esi
sub al, dl
inc al
cmp al, 2
jae .LBB1_1
mov eax, edi
sub al, sil
movzx ecx, dil
sub dil, dl
cmp dil, 1
movzx edx, dl
cmovne edx, ecx
cmp al, -1
movzx eax, sil
cmovne eax, edx
ret
.LBB1_1:
; identical assert! code
```
`clamp` assembly after:
```assembly
example:🗜️
test edx, edx
jne .LBB1_2
test sil, sil
jne .LBB1_3
.LBB1_2:
or dil, sil
and dil, dl
mov eax, edi
ret
.LBB1_3:
; identical assert! code
```
Cleaner assert_eq! & assert_ne! panic messages
This PR finishes refactoring of the assert messages per #94005. The panic message format change #112849 used to be part of this PR, but has been factored out and just merged. It might be better to keep both changes in the same release once FCP vote completes.
Modify panic message for `assert_eq!`, `assert_ne!`, the currently unstable `assert_matches!`, as well as the corresponding `debug_assert_*` macros.
```rust
assert_eq!(1 + 1, 3);
assert_eq!(1 + 1, 3, "my custom message value={}!", 42);
```
#### Old messages
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion failed: `(left == right)`
left: `2`,
right: `3`
```
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion failed: `(left == right)`
left: `2`,
right: `3`: my custom message value=42!
```
#### New messages
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion `left == right` failed
left: 2
right: 3
```
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion `left == right` failed: my custom message value=42!
left: 2
right: 3
```
History of fixing #94005
* #94016 was a lengthy PR that was abandoned
* #111030 was similar, but it stringified left and right arguments, and thus caused compile time performance issues, thus closed
* #112849 factored out the two-line formatting of all panic messages
Fixes#94005
r? `@m-ou-se`
Rollup of 8 pull requests
Successful merges:
- #114588 (Improve docs for impl Default for ExitStatus)
- #114619 (Fix pthread_attr_union layout on Wasi)
- #114644 (Point out expectation even if we have `TypeError::RegionsInsufficientlyPolymorphic`)
- #114668 (Deny `FnDef` in patterns)
- #114819 (Point at return type when it influences non-first `match` arm)
- #114826 (Fix typos)
- #114837 (add missing feature(error_in_core))
- #114853 (Migrate GUI colors test to original CSS color format)
r? `@ghost`
`@rustbot` modify labels: rollup
Modify panic message for `assert_eq!`, `assert_ne!`, the currently unstable `assert_matches!`, as well as the corresponding `debug_assert_*` macros.
```rust
assert_eq!(1 + 1, 3);
assert_eq!(1 + 1, 3, "my custom message value={}!", 42);
```
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion failed: `(left == right)`
left: `2`,
right: `3`
```
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion failed: `(left == right)`
left: `2`,
right: `3`: my custom message value=42!
```
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion `left == right` failed
left: 2
right: 3
```
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion `left == right` failed: my custom message value=42!
left: 2
right: 3
```
This PR is a simpler subset of the #111030, but it does NOT stringify the original left and right source code assert expressions, thus should be faster to compile.
Point at return type when it influences non-first `match` arm
When encountering code like
```rust
fn foo() -> i32 {
match 0 {
1 => return 0,
2 => "",
_ => 1,
}
}
```
Point at the return type and not at the prior arm, as that arm has type `!` which isn't influencing the arm corresponding to arm `2`.
Fix#78124.
Deny `FnDef` in patterns
We can only see these via `const { .. }` patterns, which are unstable.
cc #76001 (tracking issue for inline const pats)
Fixes#114658Fixes#114659
Point out expectation even if we have `TypeError::RegionsInsufficientlyPolymorphic`
just a minor tweak, since saying "one type is more general than the other" kinda sucks if we don't actually point out two types.
Improve docs for impl Default for ExitStatus
This addresses a review comment in #106425 (which is on the way to being merged I think).
Some of the other followup work is more complicated so I'm going to do individual MRs.
~~Note this branch is on top of #106425~~
Rollup of 10 pull requests
Successful merges:
- #114711 (Infer `Lld::No` linker hint when the linker stem is a generic compiler driver)
- #114772 (Add `{Local}ModDefId` to more strongly type DefIds`)
- #114800 (std: add some missing repr(transparent))
- #114820 (Add test for unknown_lints from another file.)
- #114825 (Upgrade std to gimli 0.28.0)
- #114827 (Only consider object candidates for object-safe dyn types in new solver)
- #114828 (Probe when assembling upcast candidates so they don't step on eachother's toes in new solver)
- #114829 (Separate `consider_unsize_to_dyn_candidate` from other unsize candidates)
- #114830 (Clean up some bad UI testing annotations)
- #114831 (Check projection args before substitution in new solver)
r? `@ghost`
`@rustbot` modify labels: rollup
Don't panic in ceil_char_boundary
Implementing the alternative mentioned in this comment: https://github.com/rust-lang/rust/issues/93743#issuecomment-1579935853
Since `floor_char_boundary` will always work (rounding down to the length of the string is possible), it feels best for `ceil_char_boundary` to not panic either. However, the semantics of "rounding up" past the length of the string aren't very great, which is why the method originally panicked in these cases.
Taking into account how people are using this method, it feels best to simply return the end of the string in these cases, so that the result is still a valid char boundary.
Separate `consider_unsize_to_dyn_candidate` from other unsize candidates
Move the unsize candidate assembly *just for* `T -> dyn Trait` out of `assemble_candidates_via_self_ty` so that we only consider it once, instead of for every normalization step of the self ty. This makes sure that we don't assemble several candidates that are equal modulo normalization when we really don't care about normalizing the self type of an `T: Unsize<dyn Trait>` goal anyways.
Fixesrust-lang/trait-system-refactor-initiative#57
r? lcnr
Probe when assembling upcast candidates so they don't step on eachother's toes in new solver
Lack of a probe causes one candidate to disqualify the other due to inference side-effects.
r? lcnr
Upgrade std to gimli 0.28.0
Gimli 0.28 removed its `From<EndianSlice> for &[u8]` that was the root cause of #113238.
This dependency update mirrors rust-lang/backtrace-rs#557, but since that doesn't require any code changes in `backtrace`, we can also apply that right away for our nested `std/backtrace` feature.
Add test for unknown_lints from another file.
This adds a test for #84936 which was incidentally fixed via #97266. It is a strange issue where `#![allow(unknown_lints)]` at the crate root was not applying to unknown lints that fired in a non-inline-module. I did not dig further into how #97266 fixed it, but I did verify it. I couldn't find any existing tests which did anything similar.
Closes#84936
std: add some missing repr(transparent)
For some types we don't want to stably guarantee this, so hide the `repr` from rustdoc. This nice approach was suggested by `@thomcc.`
Infer `Lld::No` linker hint when the linker stem is a generic compiler driver
This PR basically reverts the temporary solution in https://github.com/rust-lang/rust/pull/113631 to a more long-term solution.
r? ``@petrochenkov``
In [this comment](https://github.com/rust-lang/rust/pull/113631#issuecomment-1634598238), you had ideas about a long-term solution:
> I wonder what a good non-temporary solution for the inference would look like.
>
> * If the default is `(Cc::No, Lld::Yes)` (e.g. `rust-lld`)
>
> * and we switch to some specific platform compiler (e.g. `-C linker=arm-none-eabi-gcc`), should we change to `Lld::No`? Maybe yes?
> * and we switch to some non-default but generic compiler `-C linker=clang`? Then maybe not?
>
> * If the default is `(Cc::Yes, Lld::Yes)` (e.g. future x86_64 linux with default LLD)
>
> * and we switch to some specific platform compiler (e.g. `-C linker=arm-none-eabi-gcc`), should we change to `Lld::No`? Maybe yes?
> * and we switch to some non-default but generic compiler `-C linker=clang`? Then maybe not?
>
I believe that we should infer the `Lld::No` linker hint for any `-Clinker` override, and all the cases above:
- the linker drivers have their own defaults, so in my mind `-Clinker` is a signal to use its default linker / flavor, rather than ours or the target's. In the case of generic compilers, it's more likely than not going to be `Lld::No`. I would expect this to be the case in general, even when including platform-specific compilers.
- the guess will be wrong if the linker driver uses lld by default (and we also don't want to search for `-fuse-ld` link args), but will work in the more common cases. And the minority of other cases can fix the wrong guess by opting into the precise linker flavor.
- this also ensures backwards-compatibility: today, even on targets with an lld default and overriding the linker, rustc will not use lld. That includes `thumbv6m-none-eabi` where issue #113597 happened.
It looks like the simplest option, and the one with least churn: we maintain the current behavior in ambiguous cases.
I've tested that this works on #113597, as expected from the failure.
(I also have a no-std `run-make` test using a custom target json spec: basically simulating a future `x86_64-unknown-linux-gnu` using an lld flavor by default, to check that e.g. `-Clinker=clang` doesn't use lld. I could add that test to this PR, but IIUC such a custom target requires `cargo -Z build-std` and we have no tests depending on this cargo feature yet. Let me know if you want to add this test of the linker inference for such targets.)
What do you think ?
Use `unstable_target_features` when checking inline assembly
This is necessary to properly validate register classes even when the relevant target feature name is still unstable.