Skip locking span interner for some syntax context checks
- `from_expansion` now never needs to consult the interner
- `eq_ctxt` now only needs the interner when both spans are fully interned
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.
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>
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.
clarify `must_produce_diag` ICE for debugging
We have a sanity check to ensure the expensive `trimmed_def_paths` functions are called only when producing diagnostics, and not e.g. on the happy path. The panic often happens IME during development because of randomly printing stuff, causing an ICE if no diagnostics were also emitted.
I have this change locally but figured it could be useful to others, so this PR clarifies the message when this happens during development.
The output currently looks like this by default; it's a bit confusing with words missing:
```
thread 'rustc' panicked at compiler/rustc_errors/src/lib.rs:628:17:
must_produce_diag: `trimmed_def_paths` called but no diagnostics emitted; `with_no_trimmed_paths` for debugging. called at: disabled backtrace
stack backtrace:
0: 0x7ffff79570f6 - std::backtrace_rs::backtrace::libunwind::trace::h33576c57327a3cea
at .../library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
1: 0x7ffff79570f6 - std::backtrace_rs::backtrace::trace_unsynchronized::h7972a09393b420db
at .../library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x7ffff79570f6 - std::sys::backtrace::_print_fmt::hae8c5bbfbf7a8322
at .../library/std/src/sys/backtrace.rs:66:9
3: 0x7ffff79570f6 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h1fd6a7a210f5b535
...
```
The new output mentions how to get more information and locate where the `with_no_trimmed_paths` call needs to be added.
1. By default, backtraces are disabled:
```
thread 'rustc' panicked at compiler/rustc_errors/src/lib.rs:642:17:
`trimmed_def_paths` called, diagnostics were expected but none were emitted. Use `with_no_trimmed_paths` for debugging. Backtraces are currently disabled: set `RUST_BACKTRACE=1` and re-run to see where it happened.
stack backtrace:
0: 0x7ffff79565f6 - std::backtrace_rs::backtrace::libunwind::trace::h33576c57327a3cea
...
```
2. With backtraces enabled:
```
thread 'rustc' panicked at compiler/rustc_errors/src/lib.rs:642:17:
`trimmed_def_paths` called, diagnostics were expected but none were emitted. Use `with_no_trimmed_paths` for debugging. This happened in the following `must_produce_diag` call's backtrace:
0: <rustc_errors::DiagCtxtHandle>::set_must_produce_diag
at .../compiler/rustc_errors/src/lib.rs:1133:58
1: <rustc_session::session::Session>::record_trimmed_def_paths
at .../compiler/rustc_session/src/session.rs:327:9
2: rustc_middle::ty::print::pretty::trimmed_def_paths
at .../compiler/rustc_middle/src/ty/print/pretty.rs:3351:5
...
```
A `\n` could be added here or there, but it didn't matter much whenever I hit this case with the new message.
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`
Delete the `cfg(not(parallel))` serial compiler
Since it's inception a long time ago, the parallel compiler and its cfgs have been a maintenance burden. This was a necessary evil the allow iteration while not degrading performance because of synchronization overhead.
But this time is over. Thanks to the amazing work by the parallel working group (and the dyn sync crimes), the parallel compiler has now been fast enough to be shipped by default in nightly for quite a while now.
Stable and beta have still been on the serial compiler, because they can't use `-Zthreads` anyways.
But this is quite suboptimal:
- the maintenance burden still sucks
- we're not testing the serial compiler in nightly
Because of these reasons, it's time to end it. The serial compiler has served us well in the years since it was split from the parallel one, but it's over now.
Let the knight slay one head of the two-headed dragon!
#113349
Note that the default is still 1 thread, as more than 1 thread is still fairly broken.
cc `@onur-ozkan` to see if i did the bootstrap field removal correctly, `@SparrowLii` on the sync parts
Since it's inception a long time ago, the parallel compiler and its cfgs
have been a maintenance burden. This was a necessary evil the allow
iteration while not degrading performance because of synchronization
overhead.
But this time is over. Thanks to the amazing work by the parallel
working group (and the dyn sync crimes), the parallel compiler has now
been fast enough to be shipped by default in nightly for quite a while
now.
Stable and beta have still been on the serial compiler, because they
can't use `-Zthreads` anyways.
But this is quite suboptimal:
- the maintenance burden still sucks
- we're not testing the serial compiler in nightly
Because of these reasons, it's time to end it. The serial compiler has
served us well in the years since it was split from the parallel one,
but it's over now.
Let the knight slay one head of the two-headed dragon!
move all mono-time checks into their own folder, and their own query
The mono item collector currently also drives two mono-time checks: the lint for "large moves", and the check whether function calls are done with all the required target features.
Instead of doing this "inside" the collector, this PR refactors things so that we have a new `rustc_monomorphize::mono_checks` module providing a per-instance query that does these checks. We already have a per-instance query for the ABI checks, so this should be "free" for incremental builds. Non-incremental builds might do a bit more work now since we now have two separate MIR visits (in the collector and the mono-time checks) -- but one of them is cached in case the MIR doesn't change, which is nice.
This slightly changes behavior of the large-move check since the "move_size_spans" deduplication logic now only works per-instance, not globally across the entire collector.
Cc `@saethlin` since you're also doing some work related to queries and caching and monomorphization, though I don't know if there's any interaction here.
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`
cleanup: Remove outdated comment of `thir_body`
When typeck fails, `thir_body` returns `ErrorGuaranteed` rather than empty body.
No other code follows this outdated description except `check_unsafety`, which is also cleaned up in this PR.
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.
Document some `check_expr` methods, and other misc `hir_typeck` tweaks
Most importantly, make sure that all of the expression checking functions that are called from `check_expr_kind` start with `check_expr_*`. This is super useful to me personally, since I grep these functions all the time, and the ones that *aren't* named consistently are incredibly hard to find.
Also document more of the `check_expr_*` functions, and squash two args for passing data about a call expr into one `Option`.
Arbitrary self types v2: (unused) Receiver trait
This commit contains a new `Receiver` trait, which is the basis for the Arbitrary Self Types v2 RFC. This allows smart pointers to be method receivers even if they're not Deref.
This is currently unused by the compiler - a subsequent PR will start to use this for method resolution if the `arbitrary_self_types` feature gate is enabled. This is being landed first simply to make review simpler: if people feel this should all be in an atomic PR let me know.
This is a part of the arbitrary self types v2 project, https://github.com/rust-lang/rfcs/pull/3519https://github.com/rust-lang/rust/issues/44874
r? `@wesleywiser`