borrowck diagnostics: suggest borrowing function inputs in generic positions
# Summary
This generalizes borrowck's existing suggestions to borrow instead of moving when passing by-value to a function that's generic in that input. Previously, this was special-cased to `AsRef`/`Borrow`-like traits and `Fn`-like traits. This PR changes it to test if, for a moved place with type `T`, that the callee's signature and clauses don't break if you substitute in `&T` or `&mut T`. For instance, it now works with `Read`/`Write`-like traits.
Fixes https://github.com/rust-lang/rust/issues/131413
# Incidental changes
- No longer spuriously suggests mutable borrows of closures in some situations (see e.g. the tests in [tests/ui/closures/2229_closure_analysis/](https://github.com/rust-lang/rust/compare/master...dianne:rust:suggest-borrow-generic?expand=1#diff-8dfb200c559f0995d0f2ffa2f23bc6f8041b263e264e5c329a1f4171769787c0)).
- No longer suggests cloning closures that implement `Fn`, since they can be borrowed (see e.g. [tests/ui/moves/borrow-closures-instead-of-move.stderr](https://github.com/rust-lang/rust/compare/master...dianne:rust:suggest-borrow-generic?expand=1#diff-5db268aac405eec56d099a72d8b58ac46dab523cf013e29008104840168577fb)).
This keeps the behavior to suppress suggestions of `fn_once.clone()()`. I think it might make sense to suggest it with a "but this might not be your desired behavior" caveat, as is done when something is used after being consumed as the receiver for a method call. That's probably out of the scope of this PR though.
# Limitations and possible improvements
- This doesn't work for receivers of method calls. This is a small change, and I have it implemented locally, but I'm not sure it's useful on its own. In most cases I've found borrowing the receiver would change the call's output type (see below). In other cases (e.g. `Iterator::sum`), borrowing the receiver isn't useful since it's consumed.
- This doesn't work when it would change the call's output type. In general, I figure inserting references into the output type is an unwanted change. However, this also means it doesn't work in cases where the new output type would be effectively the same as the old one. For example, from the rand crate, the iterator returned by [`Rng::sample_iter`](https://docs.rs/rand/latest/rand/trait.Rng.html#method.sample_iter) is effectively the same (modulo regions) whether you borrow or consume the receiver `Rng`, so common usage involves borrowing it. I'm not sure whether the best approach is to add a more complex check of approximate equivalence, to forego checking the call's output type and give spurious suggestions, or to leave it as-is.
- This doesn't work when it would change the call's other input types. Instead, it could suggest borrowing any others that have the same parameter type (but only when suggesting shared borrows). I think this would be a pretty easy change, but I don't think it's very useful so long as the normalized output type can't change.
I'm happy to implement any of these (or other potential improvements to this), but I'm not sure which are common enough patterns to justify the added complexity. Please let me know if any sound worthwhile.
PassWrapper: disable UseOdrIndicator for Asan Win32
As described in https://reviews.llvm.org/D137227 UseOdrIndicator should be disabled on Windows since link.exe does not support duplicate weak definitions.
Fixes https://github.com/rust-lang/rust/issues/124390.
Credits also belong to `@1c3t3a` who worked with me on this.
We are currently testing this on a Windows machine.
compiletest: add `max-llvm-major-version` directive
To complement existing `min-llvm-version` so contributors don't have to use `ignore-llvm-version: 20 - 99` to emulate `max-llvm-major-version: 19`.
Closes#132305.
cc `@workingjubilee` who suggested this.
### Implementation steps
- [x] 1. Implement the directive (this PR)
- [x] 2. Open an accompanying dev-guide PR to describe the directive (https://github.com/rust-lang/rustc-dev-guide/pull/2129)
r? bootstrap
Handle infer vars in anon consts on stable
Fixes#132955
Diagnostics will sometimes try to replace generic parameters with inference variables in failing goals. This means that if we have some failing goal with an array repeat expr count anon const in it, we will wind up with some `ty::ConstKind::Unevaluated(anon_const_def, [?x])` during diagnostics which will then ICE if we do not handle inference variables correctly on stable when normalizing type system consts.
r? ```@compiler-errors```
This subsumes the suggestions to borrow arguments with `AsRef`/`Borrow` bounds and those to borrow
arguments with `Fn` and `FnMut` bounds. It works for other traits implemented on references as well,
such as `std::io::Read`, `std::io::Write`, and `core::fmt::Write`.
Incidentally, by making the logic for suggesting borrowing closures general, this removes some
spurious suggestions to mutably borrow `FnMut` closures in assignments, as well as an unhelpful
suggestion to add a `Clone` constraint to an `impl Fn` argument.
This is setup for unifing the logic for suggestions to borrow arguments in generic positions.
As of this commit, it's still special cases for `AsRef`/`Borrow`-like traits and `Fn`-like traits.
This also downgrades its applicability to MaybeIncorrect. Its suggestion can result in ill-typed
code when the type parameter it suggests providing a different generic argument for appears
elsewhere in the callee's signature or predicates.
As described here UseOdrIndicator should be disabled on Windows
since link.exe does not support duplicate weak definitions
(https://reviews.llvm.org/D137227).
Co-Authored-By: Bastian Kersting <bkersting@google.com>
[rustdoc] Fix duplicated footnote IDs
Fixes https://github.com/rust-lang/rust/issues/131901.
Footnote IDs were increased locally (ie, on the docblock) and not globally (ie, on the whole item page).
cc `@aDotInTheVoid`
r? `@notriddle`
compiletest: Add ``exact-llvm-major-version`` directive
Now contributors don't need to use `min-llvm-version: X` + `ignore-llvm-version: X+1 - 99`, so they can simply use `exact-llvm-major-version: X`
To be honest, I didn't find any usages of that hack other than the one mentioned in the issue. ( `tests/codegen/try_question_mark_nop.rs`)
Closes#132348.
rustc-dev-guide PR for `//@ exact-llvm-major-version`: https://github.com/rust-lang/rustc-dev-guide/pull/2135
r? jieyouxu
rustdoc: Treat declarative macros more like other item kinds
Apparently at some time in the past we were unable to generate an href for the module path inside the visibility of decl macros 2.0 (`pub(in ...)`). As a result of this, a whole separate function was introduced specifically for printing the visibility of decl macros that didn't attempt to generate any links. The description of PR https://github.com/rust-lang/rust/pull/84074 states:
> This fixes the overly-complex invariant mentioned in https://github.com/rust-lang/rust/pull/83237#issuecomment-815346570, where the macro source can't have any links in it only because the cache hasn't been populated yet.
I can no longer reproduce the original issue. Reusing the existing visibility rendering logic *seems* to work just fine (I couldn't come up with any counterexamples, though I invite you to prove me wrong).
* Fixes#83000
* Fixes the visibility showing up "twice" in rustdoc-JSON output: Once as the `visibility` field, once baked into the source[^1]
* Fixes `#[doc(hidden)]` not getting rendered on doc(hidden) decl macros 2.0 under `--document-hiden-items` (for decl macros 1.2 the issue remains; I will address this separately when fixing #132304).
---
<details><summary>Outdated Section</summary>
NOTE: The current version of this PR is committing a UI crime, I'd like to receive feedback on that. Maybe you have a satisfactory solution for how to remedy it. Namely, as you know we have two different ways of / modes for highlighting code with color:
1. Only highlighting links / item paths and avoiding to highlight tokens by kind like keywords (to reduce visual noise and maybe also artifact size). Used for item declarations(\*).
2. Highlighting tokens by kind. Used for code blocks written by the user.
(\*): With the notable exception being macro declarations! Well, since this PR reuses the same function for rendering the item visibility (which only makes sense), we have a clash of modes: We now use both ways of highlighting code for decl macros: №1 for the visibility, №2 for the rest. This awkward. See for yourself:
* On master: ![Screenshot 2024-10-29 at 03-37-48 by_example_vis_named in decl_macro a b c - Rust](https://github.com/user-attachments/assets/22f0ab6e-9ba9-4c4e-8fb0-0741c91d360b)
* On this branch: ![Screenshot 2024-10-29 at 03-36-41 by_example_vis_named in decl_macro a b c - Rust](https://github.com/user-attachments/assets/b11d81a3-3e2e-43cb-a5b8-6773a3048732)
</details>
Furthermore, we now no longer syntax-highlight declarative macros (be it `macro_rules!` or `macro`) since that was inconsistent with the way we render all other item kinds. See (collapsed) *Outdated Section* above. See also https://github.com/rust-lang/rust/pull/132302#discussion_r1821310783.
| On master | On this branch |
|---|---|
| ![Screenshot 2024-11-13 at 16-12-46 by_example_vis_named in decl_macro a b c - Rust](https://github.com/user-attachments/assets/cb3aeb42-a56d-4ced-80d9-f2694f369af1) | ![Screenshot 2024-11-13 at 16-13-22 by_example_vis_named in decl_macro a b c - Rust](https://github.com/user-attachments/assets/b73bee50-1b85-4862-afba-5ad471443ccc) |
[^1]: E.g., `"visibility":{"restricted":{"parent":1,"path":"::a"}},/*OMITTED*/,"inner":{"macro":"pub(in a) macro by_example_vis_named($foo:expr) {\n ...\n}"}`
CFI: Append debug location to CFI blocks
Currently we're not appending debug locations to the inserted CFI blocks. This shows up in #132615 and #100783. This change fixes that by passing down the debug location to the CFI type-test generation and appending it to the blocks.
Credits also belong to `@jakos-sec` who worked with me on this.
Make precise capturing suggestion machine-applicable only if it has no APITs
cc https://github.com/rust-lang/rust/issues/132932
The only case where this suggestion is not machine-applicable is when we suggest turning arg-position impl trait into type parameters, which may expose type parameters that were not turbofishable before.
Proper support for cross-crate recursive const stability checks
~~Stacked on top of https://github.com/rust-lang/rust/pull/132492; only the last three commits are new.~~
In a crate without `staged_api` but with `-Zforce-unstable-if-unmarked`, we now subject all functions marked with `#[rustc_const_stable_indirect]` to recursive const stability checks. We require an opt-in so that by default, a crate can be built with `-Zforce-unstable-if-unmarked` and use nightly features as usual. This property is recorded in the crate metadata so when a `staged_api` crate calls such a function, it sees the `#[rustc_const_stable_indirect]` and allows it to be exposed on stable. This, finally, will let us expose `const fn` from hashbrown on stable.
The second commit makes const stability more like regular stability: via `check_missing_const_stability`, we ensure that all publicly reachable functions have a const stability attribute -- both in `staged_api` crates and `-Zforce-unstable-if-unmarked` crates. To achieve this, we move around the stability computation so that const stability is computed after regular stability is done. This lets us access the final result of the regular stability computation, which we use so that `const fn` can inherit the regular stability (but only if that is "unstable"). Fortunately, this lets us get rid of an `Option` in `ConstStability`.
This is the last PR that I have planned in this series.
r? `@compiler-errors`
Make sure to ignore elided lifetimes when pointing at args for fulfillment errors
See the comment I left in the code.
---
If we have something like:
```
fn foo<'a, T: 'a + BoundThatIsNotSatisfied>() {}
```
And the user turbofishes just the type args:
```
foo::<()>();
```
Then if we try pointing at `()` (i.e. the type argument for `T`), we don't actually consider the possibility that the lifetimes may have been left out of the turbofish. We try indexing incorrectly into the HIR args, and bail on the suggestion.
Consolidate type system const evaluation under `traits::evaluate_const`
Part of #130704Fixes#128232Fixes#118545
Removes `ty::Const::{normalize_internal, eval_valtree}` and `InferCtxt::(try_)const_eval_resolve`, consolidating the associated logic into `evaluate_const` in `rustc_trait_selection`. This results in an API for `ty::Const` that is free of any normalization/evaluation functions that would be incorrect to use under `min_generic_const_args`/`associated_const_equality`/`generic_const_exprs` or, more generally, that would be incorrect to use in the presence of generic type system constants.
Moving this logic to `rustc_trait_selection` and out of `rustc_middle` is also a pre-requisite for ensuring that we do not evaluate constants whose where clauses do not hold.
From this point it should be relatively simple (hah) to implement more complex normalization of type system constants such as: checking wf'ness before invoking CTFE machinery, or being able to normalize const aliases that still refer to generic parameters.
r? `@compiler-errors`
Feature gate yield expressions not in 2024
This changes it so that yield expressions are no longer allowed in the 2024 edition without a feature gate. We are currently only reserving the `gen` keyword in the 2024 edition, and not allowing anything else to be implicitly enabled by the edition.
In practice this doesn't have a significant difference since yield expressions can't really be used outside of coroutines or gen blocks, which have their own feature gates. However, it does affect what is accepted pre-expansion, and I would feel more comfortable not allowing yield expressions.
I believe the stabilization process for gen blocks or coroutines will not need to check the edition here, so this shouldn't ever be needed.
Remove attributes from generics in built-in derive macros
Related issue #132561
Removes all attributes from generics in the expanded implementations of built-in derive macros.
Make sure that we suggest turbofishing the right type arg for never suggestion
I had a bug where rust would suggest the wrong arg to turbofish `()` if there were any early-bound lifetimes...
r? WaffleLapkin
Don't use `maybe_unwrap_block` when checking for macro calls in a block expr
Fixes#131915
Using `maybe_unwrap_block` to determine if we are looking at a `{ mac_call!{} }` will fail sometimes as `mac_call!{}` could be a `StmtKind::MacCall` not a `StmtKind::Expr`. This caused the def collector to think that `{ mac_call!{} }` was a non-trivial const argument and create a definition for it even though it should not.
r? `@compiler-errors` cc `@camelid`
Provide placeholder generics for traits in "no method found for type parameter" suggestions
In the diagnostics for the error ``no method named `method` found for type parameter `T` in the current scope [E0599]``, the compiler will suggest adding bounds on `T` for traits that define a method named `method`. However, these suggestions didn't include any generic arguments, so applying them would result in a `missing generics for trait` or `missing lifetime specifier` error. This PR adds placeholder arguments to the suggestion in such cases. Specifically, I tried to base the placeholders off of what's done in suggestions for when generics are missing or too few are provided:
- The placeholder for a parameter without a default is the name of the parameter.
- Placeholders are not provided for parameters with defaults.
Placeholder arguments are enclosed in `/*` and `*/`, and the applicability of the suggestion is downgraded to `Applicability::HasPlaceholders` if any placeholders are provided.
Fixes#132407
Add a default implementation for CodegenBackend::link
As a side effect this should add raw-dylib support to cg_gcc as the default ArchiveBuilderBuilder that is used implements create_dll_import_lib. I haven't tested if the raw-dylib support actually works however.
Ensure that tail expr receive lifetime extension
cc `@jieyouxu` `@traviscross`
It just came to me that we should add a test to make sure that we honor the contract from the temporary lifetime rule #121346. We should continue to implement this rule in Edition 2021 onward and shorter tail expression lifetime should not override it.
This is a small PR to improve our assurance and establish a stronger contract.
Tracked by rust-lang/rust#123739
Stabilize WebAssembly `multivalue`, `reference-types`, and `tail-call` target features
For the `multivalue` and `reference-types` features this commit is
similar to https://github.com/rust-lang/rust/pull/117457 in that it's stabilizing target features specific to
WebAssembly targets. The previous PR left out these two features because
they weren't expected to change much about compiled code so it was
unclear what the rationale was. It has [since been discovered][blog]
that `reference-types` can be useful as it changes the binary format of
the `call_indirect` instruction. Additionally [on Zulip][zulip] there's
a use case of detecting these features at compile time and generating a
compile error to better warn users about features not supported on
engines.
This PR then additionally adds the `tail-call` feature which corresponds
to the [tail-call] proposal to WebAssembly. This feature advanced to
"phase 4" in the WebAssembly CG awhile back and has been supported in
LLVM for quite some time now. Engines are finishing up implementations
or have already shipped implementations, so while this is a bit of a
late addition to Rust itself it reflects the current status of
WebAssembly's state of the feature.
A test has been added here not only for these features but other
WebAssembly features as well to showcase that they're usable without
feature gates in stable Rust.
[blog]: https://blog.rust-lang.org/2024/09/24/webassembly-targets-change-in-default-target-features.html
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/wasm32.20reference-types.20.2F.20multivalue.20in.201.2E82-beta.20not.20enabled/near/473893987
[tail-call]: https://github.com/webassembly/tail-call
Prefer `pub(super)` in `unreachable_pub` lint suggestion
This PR updates the `unreachable_pub` lint suggestion to prefer `pub(super)` instead of `pub(crate)` when possible.
cc `@petrochenkov`
r? `@nnethercote`
Stabilize Arm64EC inline assembly
This stabilizes inline assembly for Arm64EC ("Emulation Compatible").
Corresponding reference PR: https://github.com/rust-lang/reference/pull/1653
---
From the requirements of stabilization mentioned in https://github.com/rust-lang/rust/issues/93335
> Each architecture needs to be reviewed before stabilization:
> - It must have clobber_abi.
Done in https://github.com/rust-lang/rust/pull/131332.
> - It must be possible to clobber every register that is normally clobbered by a function call.
This is possible from the time of the initial implementation.
> - Generally review that the exposed register classes make sense.
The registers available in this target are a subset of those available in the AArch64 inline assembly which is already stable.
The following registers cannot be used in Arm64EC compared to AArch64:
- `x13`, `x14`, `x23`, `x24`, `x28` (register class: `reg`)
- `v[16-31]` (register class: `vreg`)
- `p[0-15]`, `ffr` (clobber-only register class `preg`)
These are disallowed by the ABI (see also [abi docs](https://learn.microsoft.com/en-us/cpp/build/arm64ec-windows-abi-conventions?view=msvc-170#register-mapping) for `reg`/`vreg` and https://github.com/rust-lang/rust/pull/131332#issuecomment-2401189142 for `preg`).
Although not listed in the above requirements, preserves_flags is also implemented and the same as AArch64.
---
cc `@dpaoliello`
r? `@Amanieu`
`@rustbot` label O-windows O-AArch64 +A-inline-assembly +T-lang -T-compiler +needs-fcp
coverage: Restrict empty-span expansion to only cover `{` and `}`
Coverage instrumentation has some tricky code for converting a coverage-relevant `Span` into a set of start/end line/byte-column coordinates that will be embedded in the CGU's coverage metadata.
A big part of this complexity is special code for handling empty spans, which are expanded into non-empty spans (if possible) because LLVM's coverage reporter does not handle empty spans well.
This PR simplifies that code by restricting it to only apply in two specific situations: when the character after the empty span is `{`, or the character before the empty span is `}`.
(As an added benefit, this means that the expanded spans no longer extend awkwardly beyond the end of a physical line, which was common under the previous implementation.)
Along the way, this PR also removes some unhelpful code for dealing with function source code spread across multiple files. Functions currently can't have coverage spans in multiple files, and if that ever changes (e.g. to properly support expansion regions) then this code will need to be completely overhauled anyway.
For the `multivalue` and `reference-types` features this commit is
similar to #117457 in that it's stabilizing target features specific to
WebAssembly targets. The previous PR left out these two features because
they weren't expected to change much about compiled code so it was
unclear what the rationale was. It has [since been discovered][blog]
that `reference-types` can be useful as it changes the binary format of
the `call_indirect` instruction. Additionally [on Zulip][zulip] there's
a use case of detecting these features at compile time and generating a
compile error to better warn users about features not supported on
engines.
This PR then additionally adds the `tail-call` feature which corresponds
to the [tail-call] proposal to WebAssembly. This feature advanced to
"phase 4" in the WebAssembly CG awhile back and has been supported in
LLVM for quite some time now. Engines are finishing up implementations
or have already shipped implementations, so while this is a bit of a
late addition to Rust itself it reflects the current status of
WebAssembly's state of the feature.
A test has been added here not only for these features but other
WebAssembly features as well to showcase that they're usable without
feature gates in stable Rust.
[blog]: https://blog.rust-lang.org/2024/09/24/webassembly-targets-change-in-default-target-features.html
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/wasm32.20reference-types.20.2F.20multivalue.20in.201.2E82-beta.20not.20enabled/near/473893987
[tail-call]: https://github.com/webassembly/tail-call
Dont suggest `use<impl Trait>` when we have an edition-2024-related borrowck issue
#131186 implements some machinery to detect in borrowck when we may have RPIT overcaptures due to edition 2024, and suggests adding `+ use<'a, T>` to go back to the edition 2021 capture rules. However, we weren't filtering out cases when there are APITs in scope.
This PR implements a more sophisticated diagnostic where we will suggest turning any APITs in scope into type parameters, and applies this to both the borrowck error note, and to the `impl_trait_overcaptures` migration lint.
cc #132809
Additional tests to ensure let is rejected during parsing
In the original stabilization PR, @ `compiler-errors` has [pointed out](https://github.com/rust-lang/rust/pull/94927#issuecomment-1165156328) that #97295 wasn't enough to address the concerns about having `let` in expressions being rejected at parsing time, instead of later.
Thankfully, since then the situation has been greatly improved by #115677. This PR adds some additional tests to `disallowed-positions.rs`, and adds two additional revisions to the "normal" case which is now given the `feature` name:
* `no_feature`: Added to incorporate `disallowed-positions-without-feature-gate.rs` into the file, reducing duplication.
* `nothing`: like feature, but all functions are cfg'd out. Ensures that the errors are really emitted during parsing.
cc tracking issue #53667
require const_impl_trait gate for all conditional and trait const calls
Alternative to https://github.com/rust-lang/rust/pull/132786.
`@compiler-errors` this is basically what I meant with my proposals. I found it's easier to express this in code than English. ;)
r? `@compiler-errors`
Stabilize s390x inline assembly
This stabilizes inline assembly for s390x (SystemZ).
Corresponding reference PR: https://github.com/rust-lang/reference/pull/1643
---
From the requirements of stabilization mentioned in https://github.com/rust-lang/rust/issues/93335
> Each architecture needs to be reviewed before stabilization:
> - It must have clobber_abi.
Done in https://github.com/rust-lang/rust/pull/130630.
> - It must be possible to clobber every register that is normally clobbered by a function call.
Done in the PR that added support for clobber_abi.
> - Generally review that the exposed register classes make sense.
The followings can be used as input/output:
- `reg` (`r[0-10]`, `r[12-14]`): General-purpose register
- `reg_addr` (`r[1-10]`, `r[12-14]`): General-purpose register except `r0` which is evaluated as zero in an address context
This class is needed because `r0`, which may be allocated when using the `reg` class, cannot be used as a register in certain contexts. This is identical to the `a` constraint in LLVM and GCC. See https://github.com/rust-lang/rust/pull/119431 for details.
- `freg` (`f[0-15]`): Floating-point register
The followings are clobber-only:
- `vreg` (`v[0-31]`): Vector register
Technically `vreg` should be able to accept `#[repr(simd)]` types as input/output if the unstable `vector` target feature added is enabled, but `core::arch` has no s390x vector type and both `#[repr(simd)]` and `core::simd` are unstable. Everything related is unstable, so the fact that this is currently a clobber-only should not be considered a stabilization blocker. (https://github.com/rust-lang/rust/issues/130869 tracks unstable stuff here)
- `areg` (`a[2-15]`): Access register
All of the above register classes except `reg_addr` are needed for `clobber_abi`.
The followings cannot be used as operands for inline asm (see also [getReservedRegs](https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp#L258-L282) and [SystemZELFRegisters](https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h#L107-L128) in LLVM):
- `r11`: frame pointer
- `r15`: stack pointer
- `a0`, `a1`: Reserved for system use
- `c[0-15]` (control register) Reserved by the kernel
Although not listed in the above requirements, `preserves_flags` is implemented in https://github.com/rust-lang/rust/pull/111331.
---
cc ``@uweigand``
r? ``@Amanieu``
``@rustbot`` label +O-SystemZ +A-inline-assembly
Emit warning when calling/declaring functions with unavailable vectors.
On some architectures, vector types may have a different ABI depending on whether the relevant target features are enabled. (The ABI when the feature is disabled is often not specified, but LLVM implements some de-facto ABI.)
As discussed in rust-lang/lang-team#235, this turns out to very easily lead to unsound code.
This commit makes it a post-monomorphization future-incompat warning to declare or call functions using those vector types in a context in which the corresponding target features are disabled, if using an ABI for which the difference is relevant. This ensures that these functions are always called with a consistent ABI.
See the [nomination comment](https://github.com/rust-lang/rust/pull/127731#issuecomment-2288558187) for more discussion.
Part of #116558
r? RalfJung
Rollup of 7 pull requests
Successful merges:
- #132341 (Reject raw lifetime followed by `'`, like regular lifetimes do)
- #132363 (Enforce that raw lifetimes must be valid raw identifiers)
- #132744 (add regression test for #90781)
- #132754 (Simplify the internal API for declaring command-line options)
- #132772 (use `download-rustc="if-unchanged"` as a global default)
- #132774 (Use lld with non-LLVM backends)
- #132799 (Make `Ty::primitive_symbol` recognize `str`)
r? `@ghost`
`@rustbot` modify labels: rollup
Make `Ty::primitive_symbol` recognize `str`
Make `Ty::primitive_symbol` recognize `str`, which makes `str` eligible for the "expected primitive, found local type" (and vice versa) [diagnostic](https://github.com/rust-lang/rust/blob/master/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs#L1430-L1437) that already exists for other primitives.
<details><summary> diagnostic difference</summary>
```rs
#[allow(non_camel_case_types)]
struct str;
fn foo() {
let _: &str = "hello";
let _: &core::primitive::str = &str;
}
```
`rustc --crate-type lib --edition 2021 a.rs`
Current nightly:
```rs
error[E0308]: mismatched types
--> a.rs:5:19
|
5 | let _: &str = "hello";
| ---- ^^^^^^^ expected `str`, found a different `str`
| |
| expected due to this
|
= note: expected reference `&str`
found reference `&'static str`
error[E0308]: mismatched types
--> a.rs:6:36
|
6 | let _: &core::primitive::str = &str;
| --------------------- ^^^^ expected `str`, found a different `str`
| |
| expected due to this
|
= note: expected reference `&str` (`str`)
found reference `&str` (`str`)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.
```
With this patch:
```rs
error[E0308]: mismatched types
--> a.rs:5:19
|
5 | let _: &str = "hello";
| ---- ^^^^^^^ expected `str`, found a different `str`
| |
| expected due to this
|
= note: str and `str` have similar names, but are actually distinct types
= note: str is a primitive defined by the language
note: `str` is defined in the current crate
--> a.rs:2:1
|
2 | struct str;
| ^^^^^^^^^^
error[E0308]: mismatched types
--> a.rs:6:36
|
6 | let _: &core::primitive::str = &str;
| --------------------- ^^^^ expected `str`, found a different `str`
| |
| expected due to this
|
= note: str and `str` have similar names, but are actually distinct types
= note: str is a primitive defined by the language
note: `str` is defined in the current crate
--> a.rs:2:1
|
2 | struct str;
| ^^^^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.
```
</details>
Simplify the internal API for declaring command-line options
The internal APIs for declaring command-line options are old, and intimidatingly complex. This PR replaces them with a single function that takes explicit `stability` and `kind` arguments, making it easier to see how each option is handled, and whether it is treated as stable or unstable.
We also don't appear to have any tests for the output of `rustc --help` and similar, so I've added a run-make test to verify that this PR doesn't change any output. (There is already a similar run-make test for rustdoc's help output.)
---
The librustdoc changes are simply adjusting to updated compiler APIs; no functional change intended.
---
A side-effect of these changes is that rustfmt can once again format the entirety of these option declaration lists, which it was not doing before.
Enforce that raw lifetimes must be valid raw identifiers
Make sure that the identifier part of a raw lifetime is a valid raw identifier. This precludes `'r#_` and all module segment paths for now.
I don't believe this is compelling to support. This was raised by `@ehuss` in https://github.com/rust-lang/reference/pull/1603#discussion_r1822726753 (well, specifically the `'r#_` case), but I don't see why we shouldn't just make it consistent with raw identifiers.
Reject raw lifetime followed by `'`, like regular lifetimes do
See comment. We want to reject cases like `'r#long'id`, which currently gets interpreted as a raw lifetime (`'r#long`) followed by a lifetime (`'id`). This could have alternative lexes, such as an overlong char literal (`'r#long'`) followed by an identifier (`id`). To avoid committing to this in any case, let's reject the whole thing.
`@mattheww,` is this what you were looking for in https://github.com/rust-lang/reference/pull/1603#issuecomment-2339237325? I'd say ignore the details about the specific error message (the fact that this gets reinterpreted as a char literal is 🤷), just that because this causes a lexer error we're effectively saving syntactical space like you wanted.
LLVM does not expect to ever see multiple dbg_declares for the same variable at the same
location with different values. proc-macros make it possible for arbitrary code,
including multiple calls that get inlined, to happen at any given location in the source
code. Add discriminators when that happens so these locations are different to LLVM.
This may interfere with the AddDiscriminators pass in LLVM, which is added by the
unstable flag -Zdebug-info-for-profiling.
Fixes#131944
try_question_mark_nop: update test for LLVM 20
llvm/llvm-project@dd116369f6 changes the IR of this test in a way that I don't think is bad, but needs adjusting.
r? `@nikic`
`@rustbot` label: +llvm-main
pointee_info_at: fix logic for recursing into enums
Fixes https://github.com/rust-lang/rust/issues/131834
The logic in `pointee_info_at` was likely written at a time when the null pointer optimization was the *only* enum layout optimization -- and as `Variant::Multiple` kept getting expanded, nobody noticed that the logic is now unsound.
The job of this function is to figure out whether there is a dereferenceable-or-null and aligned pointer at a given offset inside a type. So when we recurse into a multi-variant enum, we better make sure that all the other enum variants must be null! This is the part that was forgotten, and this PR adds it.
The reason this didn't explode in many ways so far is that our references only have 1 niche value (null), so it's not possible on stable to have a multi-variant enum with a dereferenceable pointer and other enum variants that are not null. But with `rustc_layout_scalar_valid_range` attributes one can force such a layout, and if `@the8472's` work on alignment niches ever lands, that will make this possible on stable.
use verbose for path separator suggestion
A single `-` of suggestion underlining that is adjacent to a much more significant `^^^` underlying of the LHS path component is hard to distinguish. IMO this presents much more cleanly when it's verbose, especially because it's a *replacment* suggestion.
r? estebank
Don't suggest `.into_iter()` on iterators
This makes the the suggestion to call `.into_iter()` only consider unsatisfied `Iterator` bounds for the receiver type itself. That way, it ignores predicates generated by trying to auto-ref the receiver (the result of which usually won't implement `Iterator`).
Fixes#127511
Unfortunately, the error in that case is still confusing: it labels `Iterator` as an unsatisfied bound because `&impl Iterator: Iterator` can't be satisfied, despite that not being required or helpful. I'd like to handle that in a separate PR. ~~I'm hoping fixing #124802 will fix it too.~~ It doesn't look connected to that issue. Still, I think it'd be clearest to visually distinguish unsatisfied predicates from different attempts at `pick_method`; I'll make a PR for that soon.
Get rid of `check_opaque_type_well_formed`
Instead, replicate it by improving the span of the opaque in `check_opaque_meets_bounds`.
This has two consequences:
1. We now prefer "concrete type differs" errors, since we'll hit those first before we check the opaque is WF.
2. Spans have gotten slightly worse.
Specifically, (2.) could be improved by adding a new obligation cause that explains that the definition's environment has stronger assumptions than the declaration.
r? lcnr
remove support for rustc_safe_intrinsic attribute; use rustc_intrinsic functions instead
This brings us one step closer towards removing support for `extern "rust-intrinsic"` blocks, in favor of `#[rustc_intrinsic]` functions.
Also move `#[rustc_intrinsic]` under the `intrinsics` feature gate, to match the `extern "rust-intrinsic"` style.
Functions currently can't have mappings in multiple files, and if that ever
changes (e.g. to properly support expansion regions), this code will need to be
completely overhauled anyway.
Initialize channel `Block`s directly on the heap
The channel's `Block::new` was causing a stack overflow because it held
32 item slots, instantiated on the stack before moving to `Box::new`.
The 32x multiplier made modestly-large item sizes untenable.
That block is now initialized directly on the heap.
Fixes#102246
try-job: test-various
core: move intrinsics.rs into intrinsics folder
This makes the rustbot notification we have set up for this folder in `triagebot.toml` actually work. Also IMO it makes more sense to have it all in one folder.
[StableMIR] API to retrieve definitions from crates
Add functions to retrieve function definitions and static items from all crates (local and external).
For external crates, we're still missing items from trait implementation and primitives.
r? ````@compiler-errors:```` Do you know what is the best way to retrieve the associated items for primitives and trait implementations for external crates? Thanks!
Add `{ignore,needs}-{rustc,std}-debug-assertions` directive support
Add `{ignore,needs}-{rustc,std}-debug-assertions` compiletest directives and retire the old `{ignore,only}-debug` directives. The old `{ignore,only}-debug` directives were ambiguous because you could have std built with debug assertions but rustc not built with debug assertions or vice versa. If we want to support the use case of controlling test run based on if rustc was built with debug assertions, then having `{ignore,only}-debug` will be very confusing.
cc ````@matthiaskrgr````
Closes#123987.
r? bootstrap (or compiler tbh)
Tweak detection of multiple crate versions to be more encompassing
Previously, we only emitted the additional context if the type was in the same crate as the trait that appeared multiple times in the dependency tree. Now, we look at all traits looking for two with the same name in different crates with the same crate number, and we are more flexible looking for the types involved. This will work even if the type that implements the wrong trait version is from a different crate entirely.
```
error[E0277]: the trait bound `CustomErrorHandler: ErrorHandler` is not satisfied because the trait comes from a different crate version
--> src/main.rs:5:17
|
5 | cnb_runtime(CustomErrorHandler {});
| ^^^^^^^^^^^^^^^^^^^^^ the trait `ErrorHandler` is not implemented for `CustomErrorHandler`
|
note: there are multiple different versions of crate `c` in the dependency graph
--> /home/gh-estebank/testcase-rustc-crate-version-mismatch/c-v0.2/src/lib.rs:1:1
|
1 | pub trait ErrorHandler {}
| ^^^^^^^^^^^^^^^^^^^^^^ this is the required trait
|
::: src/main.rs:1:5
|
1 | use b::CustomErrorHandler;
| - one version of crate `c` is used here, as a dependency of crate `b`
2 | use c::cnb_runtime;
| - one version of crate `c` is used here, as a direct dependency of the current crate
|
::: /home/gh-estebank/testcase-rustc-crate-version-mismatch/b/src/lib.rs:1:1
|
1 | pub struct CustomErrorHandler {}
| ----------------------------- this type doesn't implement the required trait
|
::: /home/gh-estebank/testcase-rustc-crate-version-mismatch/c-v0.1/src/lib.rs:1:1
|
1 | pub trait ErrorHandler {}
| ---------------------- this is the found trait
= note: two types coming from two different versions of the same crate are different types even if they look the same
= help: you can use `cargo tree` to explore your dependency tree
```
Fix#89143.
Add functions to retrieve function definitions and static items from
all crates (local and external).
For external crates, add a query to retrieve the number of defs in a
foreign crate.
Basic inline assembly support for SPARC and SPARC64
This implements asm_experimental_arch (tracking issue https://github.com/rust-lang/rust/issues/93335) for SPARC and SPARC64.
This PR includes:
- General-purpose registers `r[0-31]` (`reg` register class, LLVM/GCC constraint `r`)
Supported types: i8, i16, i32, i64 (SPARC64-only)
Aliases: `g[0-7]` (`r[0-7]`), `o[0-7]` (`r[8-15]`), `l[0-7]` (`r[16-23]`), `i[0-7]` (`r[24-31]`)
- `y` register (clobber-only, needed for clobber_abi)
- preserves_flags: Integer condition codes (`icc`, `xcc`) and floating-point condition codes (`fcc*`)
The following are *not* included:
- 64-bit integer support on SPARC-V8+'s global or out registers (`g[0-7]`, `o[0-7]`): GCC's `h` constraint (it seems that there is no corresponding constraint in LLVM?)
- Floating-point registers (LLVM/GCC constraint `e`/`f`):
I initially tried to implement this, but postponed it for now because there seemed to be several parts in LLVM that behaved differently than in the LangRef's description.
- clobber_abi: Support for floating-point registers is needed.
Refs:
- LLVM
- Reserved registers https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp#L52
- Register definitions https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/SparcRegisterInfo.td
- Supported constraints https://llvm.org/docs/LangRef.html#supported-constraint-code-list
- GCC
- Reserved registers 63b6967b06/gcc/config/sparc/sparc.h (L633-L658)
- Supported constraints https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
- SPARC ISA/ABI
- (64-bit ISA) The SPARC Architecture Manual, Version 9
(32-bit ISA) The SPARC Architecture Manual, Version 8
(64-bit ABI) System V Application Binary Interface SPARC Version 9 Processor Supplement, Rev 1.35
(32-bit ABI) System V Application Binary Interface SPARC Processor Supplement, Third Edition
The above docs can be downloaded from https://sparc.org/technical-documents
- (32-bit V8+ ABI) The V8+ Technical Specification
https://temlib.org/pub/SparcStation/Standards/V8plus.pdf
cc `@thejpster` (sparc-unknown-none-elf target maintainer)
(AFAIK, other sparc/sprac64 targets don't have target maintainers)
r? `@Amanieu`
`@rustbot` label +O-SPARC +A-inline-assembly
```
error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied because the trait comes from a different crate version
--> multiple-dep-versions.rs:7:18
|
7 | do_something(Type);
| ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
|
note: there are multiple different versions of crate `dependency` in the dependency graph
--> /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:4:1
|
3 | pub struct Type(pub i32);
| --------------- this type implements the required trait
4 | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the required trait
|
::: multiple-dep-versions.rs:1:1
|
1 | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
2 | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
|
::: /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-2.rs:3:1
|
3 | pub struct Type;
| --------------- this type doesn't implement the required trait
4 | pub trait Trait {
| --------------- this is the found trait
= note: two types coming from two different versions of the same crate are different types even if they look the same
= help: you can use `cargo tree` to explore your dependency tree
```
The approach to accomplish this is a HACK, and we'd want a better way to do this. I believe that moving E0277 to be a structured diagnostic would help in that regard.
```
error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied because the trait comes from a different crate version
--> multiple-dep-versions.rs:7:18
|
7 | do_something(Type);
| ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
|
note: there are multiple different versions of crate `dependency` in the dependency graph
--> /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:4:1
|
3 | pub struct Type(pub i32);
| --------------- this type implements the required trait
4 | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the required trait
|
::: multiple-dep-versions.rs:1:1
|
1 | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
2 | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
|
::: /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-2.rs:3:1
|
3 | pub struct Type;
| --------------- this type doesn't implement the required trait
4 | pub trait Trait {
| --------------- this is the found trait
= note: two types coming from two different versions of the same crate are different types even if they look the same
= help: you can use `cargo tree` to explore your dependency tree
note: required by a bound in `do_something`
--> /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:12:24
|
12 | pub fn do_something<X: Trait>(_: X) {}
| ^^^^^ required by this bound in `do_something`
```
Previously, we only emitted the additional context if the type was in the same crate as the trait that appeared multiple times in the dependency tree. Now, we look at all traits looking for two with the same name in different crates with the same crate number, and we are more flexible looking for the types involved. This will work even if the type that implements the wrong trait version is from a different crate entirely.
```
error[E0277]: the trait bound `CustomErrorHandler: ErrorHandler` is not satisfied
--> src/main.rs:5:17
|
5 | cnb_runtime(CustomErrorHandler {});
| ----------- ^^^^^^^^^^^^^^^^^^^^^ the trait `ErrorHandler` is not implemented for `CustomErrorHandler`
| |
| required by a bound introduced by this call
|
help: you have multiple different versions of crate `c` in your dependency graph
--> src/main.rs:1:5
|
1 | use b::CustomErrorHandler;
| ^ one version of crate `c` is used here, as a dependency of crate `b`
2 | use c::cnb_runtime;
| ^ one version of crate `c` is used here, as a direct dependency of the current crate
note: two types coming from two different versions of the same crate are different types even if they look the same
--> /home/gh-estebank/testcase-rustc-crate-version-mismatch/c-v0.2/src/lib.rs:1:1
|
1 | pub trait ErrorHandler {}
| ^^^^^^^^^^^^^^^^^^^^^^ this is the required trait
|
::: /home/gh-estebank/testcase-rustc-crate-version-mismatch/b/src/lib.rs:1:1
|
1 | pub struct CustomErrorHandler {}
| ----------------------------- this type doesn't implement the required trait
|
::: /home/gh-estebank/testcase-rustc-crate-version-mismatch/c-v0.1/src/lib.rs:1:1
|
1 | pub trait ErrorHandler {}
| ---------------------- this is the found trait
= help: you can use `cargo tree` to explore your dependency tree
note: required by a bound in `cnb_runtime`
--> /home/gh-estebank/testcase-rustc-crate-version-mismatch/c-v0.2/src/lib.rs:3:41
|
3 | pub fn cnb_runtime(_error_handler: impl ErrorHandler) {}
| ^^^^^^^^^^^^ required by this bound in `cnb_runtime`
```
Fix#89143.
The channel's `Block::new` was causing a stack overflow because it held
32 item slots, instantiated on the stack before moving to `Box::new`.
The 32x multiplier made modestly-large item sizes untenable.
That block is now initialized directly on the heap.
Fixes#102246