Improve VecCache under parallel frontend
This replaces the single Vec allocation with a series of progressively larger buckets. With the cfg for parallel enabled but with -Zthreads=1, this looks like a slight regression in i-count and cycle counts (~1%).
With the parallel frontend at -Zthreads=4, this is an improvement (-5% wall-time from 5.788 to 5.4688 on libcore) than our current Lock-based approach, likely due to reducing the bouncing of the cache line holding the lock. At -Zthreads=32 it's a huge improvement (-46%: 8.829 -> 4.7319 seconds).
try-job: i686-gnu-nopt
try-job: dist-x86_64-linux
Use `TypingMode` throughout the compiler instead of `ParamEnv`
Hopefully the biggest single PR as part of https://github.com/rust-lang/types-team/issues/128.
## `infcx.typing_env` while defining opaque types
I don't know how'll be able to correctly handle opaque types when using something taking a `TypingEnv` while defining opaque types. To correctly handle the opaques we need to be able to pass in the current `opaque_type_storage` and return constraints, i.e. we need to use a proper canonical query. We should migrate all the queries used during HIR typeck and borrowck where this matters to proper canonical queries. This is
## `layout_of` and `Reveal::All`
We convert the `ParamEnv` to `Reveal::All` right at the start of the `layout_of` query, so I've changed callers of `layout_of` to already use a post analysis `TypingEnv` when encountering it.
ca87b535a0/compiler/rustc_ty_utils/src/layout.rs (L51)
## `Ty::is_[unpin|sized|whatever]`
I haven't migrated `fn is_item_raw` to use `TypingEnv`, will do so in a followup PR, this should significantly reduce the amount of `typing_env.param_env`. At some point there will probably be zero such uses as using the type system while ignoring the `typing_mode` is incorrect.
## `MirPhase` and phase-transitions
When inside of a MIR-body, we can mostly use its `MirPhase` to figure out the right `typing_mode`. This does not work during phase transitions, most notably when transitioning from `Analysis` to `Runtime`:
dae7ac133b/compiler/rustc_mir_transform/src/lib.rs (L606-L625)
All these passes still run with `MirPhase::Analysis`, but we should only use `Reveal::All` once we're run the `RevealAll` pass. This required me to manually construct the right `TypingEnv` in all these passes. Given that it feels somewhat easy to accidentally miss this going forward, I would maybe like to change `Body::phase` to an `Option` and replace it at the start of phase transitions. This then makes it clear that the MIR is currently in a weird state.
r? `@ghost`
stability: remove skip_stability_check_due_to_privacy
This was added in https://github.com/rust-lang/rust/pull/38689 to deal with https://github.com/rust-lang/rust/issues/38412. However, even after removing the check, the relevant tests still pass. Let's see if CI finds any other tests that rely on this. If not, it seems like logic elsewhere in the compiler changed so this is not required any more.
the behavior of the type system not only depends on the current
assumptions, but also the currentnphase of the compiler. This is
mostly necessary as we need to decide whether and how to reveal
opaque types. We track this via the `TypingMode`.
rename rustc_const_stable_intrinsic -> rustc_intrinsic_const_stable_indirect
In https://github.com/rust-lang/rust/pull/120370 this name caused confusion as the author thought the intrinsic was stable. So let's try a different name...
If we can land this before the beta cutoff we can avoid needing `cfg(bootstrap)` for this. ;)
Cc `@compiler-errors` `@saethlin`
Overhaul the `-l` option parser (for linking to native libs)
The current parser for `-l` options has accumulated over time, making it hard to follow. This PR tries to clean it up in several ways.
Key changes:
- This code now gets its own submodule, to slightly reduce clutter in `rustc_session::config`.
- Cleaner division between iterating over multiple `-l` options, and processing each individual one.
- Separate “split” step that breaks up the value string into `[KIND[:MODIFIERS]=]NAME[:NEW_NAME]`, but leaves parsing/validating those parts to later steps.
- This step also gets its own (disposable) unit test, to make sure it works as expected.
- A context struct reduces the burden of parameter passing, and makes it easier to write error messages that adapt to nightly/stable compilers.
- Fewer calls to `nightly_options` helper functions, because at this point we can get the same information from `UnstableOptions` and `UnstableFeatures` (which are downstream of earlier calls to those helper functions).
There should be no overall change in compiler behaviour.
Diagnostics for let mut in item context
The diagnostics for `let` at the top level did not account for `let mut`, which [made the error unclear](https://users.rust-lang.org/t/create-a-vector-of-constants-outside-main/121251/1).
I've made the diagnostic always display a link to valid items. I've added dedicated help for `let mut` case that suggests using a `Mutex` (to steer novice users away from the `static mut` trap). Unfortunately, neither the Rust book, nor libstd docs have dedicated section listing all other types for interior-mutable `static`s.
`suggest_borrow_generic_arg`: instantiate clauses properly
This simplifies and fixes the way `suggest_borrow_generic_arg` instantiates callees' predicates when testing them to see if a moved argument can instead be borrowed. Previously, it would ICE if the moved argument's type included a region variable, since it was getting passed to a call of `EarlyBinder::instantiate`. This makes the instantiation much more straightforward, which also fixes the ICE.
Fixes#133118
This also modifies `tests/ui/moves/moved-value-on-as-ref-arg.rs` to have more useful bounds on the tests for suggestions to borrow `Borrow` and `BorrowMut` arguments. With its old tautological `T: BorrowMut<T>` bound, this fix would make it suggest a shared borrow for that argument.
Make rustc consider itself a stable compiler when `RUSTC_BOOTSTRAP=-1`
Addresses https://github.com/rust-lang/rust/issues/123404 to allow test writers to specify `//@ rustc-env:RUSTC_BOOTSTRAP=-1` to have a given rustc consider itself a stable rustc. This is only intended for testing usages.
I did not use `RUSTC_BOOTSTRAP=0` because that can be confusing, i.e. one might think that means "not bootstrapping", but "forcing a given rustc to consider itself a stable compiler" is a different use case.
I also added a specific test to check `RUSTC_BOOTSTRAP`'s various values and how that interacts with rustc's stability story w.r.t. features and cli flags.
Noticed when trying to write a test for enabling ICE file dumping on stable.
Dunno if this needs a compiler FCP or MCP, but I can file an MCP or ask someone to start an FCP if needed. Note that `RUSTC_BOOTSTRAP` is a perma-unstable env var and has no stability guarantees (heh) whatsoever. This does not affect bootstrapping because bootstrap never sets `RUSTC_BOOTSTRAP=-1`. If someone does set that when bootstrapping, it is considered PEBKAC.
Accompanying dev-guide PR: https://github.com/rust-lang/rustc-dev-guide/pull/2136
cc `@estebank` and `@rust-lang/wg-diagnostics` for FYI
Check `use<..>` in RPITIT for refinement
`#![feature(precise_capturing_in_traits)]` allows users to write `+ use<>` bounds on RPITITs to control what lifetimes are captured by the RPITIT.
Since RPITITs currently also warn for refinement in implementations, this PR extends that refinement check for cases where we *undercapture* in an implementation, since that may be indirectly "promising" a more relaxed outlives bound than the impl author intended.
For an opaque to be refining, we need to capture *fewer* parameters than those mentioned in the captured params of the trait. For example:
```
trait TypeParam<T> {
fn test() -> impl Sized;
}
// Indirectly capturing a lifetime param through a type param substitution.
impl<'a> TypeParam<&'a ()> for i32 {
fn test() -> impl Sized + use<> {}
//~^ WARN impl trait in impl method captures fewer lifetimes than in trait
}
```
Since the opaque in the method (implicitly) captures `use<Self, T>`, and `Self = i32, T = &'a ()` in the impl, we must mention `'a` in our `use<..>` on the impl.
Tracking:
* https://github.com/rust-lang/rust/issues/130044
Fixes issue 133118.
This also modifies `tests/ui/moves/moved-value-on-as-ref-arg.rs` to have more
useful bounds on the tests for suggestions to borrow `Borrow` and `BorrowMut`
arguments. With its old tautological `T: BorrowMut<T>` bound, this fix would
make it suggest a shared borrow for that argument.
Trim whitespace in RemoveLet primary span
Separate `RemoveLet` span into primary span for `let` and removal suggestion span for `let `, so that primary span does not include whitespace.
Fixes: #133031
Increase accuracy of `if` condition misparse suggestion
Fix#132656.
Look at the expression that was parsed when trying to recover from a bad `if` condition to determine what was likely intended by the user beyond "maybe this was meant to be an `else` body".
```
error: expected `{`, found `map`
--> $DIR/missing-dot-on-if-condition-expression-fixable.rs:4:30
|
LL | for _ in [1, 2, 3].iter()map(|x| x) {}
| ^^^ expected `{`
|
help: you might have meant to write a method call
|
LL | for _ in [1, 2, 3].iter().map(|x| x) {}
| +
```
If a macro statement has been parsed after `else`, suggest a missing `if`:
```
error: expected `{`, found `falsy`
--> $DIR/else-no-if.rs:47:12
|
LL | } else falsy! {} {
| ---- ^^^^^
| |
| expected an `if` or a block after this `else`
|
help: add an `if` if this is the condition of a chained `else if` statement
|
LL | } else if falsy! {} {
| ++
```
Querify MonoItem collection
Factored out of https://github.com/rust-lang/rust/pull/131650. These changes are required for post-mono MIR opts, because the previous implementation would load the MIR for every Instance that we traverse (as well as invoke queries on it). The cost of that would grow massively with post-mono MIR opts because we'll need to load new MIR for every Instance, instead of re-using the `optimized_mir` for every Instance with the same DefId.
So the approach here is to add two new queries, `items_of_instance` and `size_estimate`, which contain the specific information about an Instance's MIR that MirUsedCollector and CGU partitioning need, respectively. Caching these significantly increases the size of the query cache, but that's justified by our improved incrementality (I'm sure walking all the MIR for a huge crate scales quite poorly).
This also changes `MonoItems` into a type that will retain the traversal order (otherwise we perturb a bunch of diagnostics), and will also eliminate duplicate findings. Eliminating duplicates removes about a quarter of the query cache size growth.
The perf improvements in this PR are inflated because rustc-perf uses `-Zincremental-verify-ich`, which makes loading MIR a lot slower because MIR contains a lot of Spans and computing the stable hash of a Span is slow. And the primary goal of this PR is to load less MIR. Some squinting at `collector profile_local perf-record +stage1` runs suggests the magnitude of the improvements in this PR would be decreased by between a third and a half if that flag weren't being used. Though this effect may apply to the regressions too since most are incr-full and this change also causes such builds to encode more Spans.
Deny capturing late-bound ty/const params in nested opaques
First, this reverts a7f609504c. I can't exactly remember why I approved this specific bit of https://github.com/rust-lang/rust/pull/132466; specifically, I don't know that the purpose of that commit is, and afaict we will never have an opaque that captures late-bound params through a const because opaques can't be used inside of anon consts. Am I missing something `@cjgillot?` Since I can't see a case where this matters, and no tests seem to fail.
The second commit adds a `deny_late_regions: bool` to distinguish `Scope::LateBoundary` which should deny *any* late-bound params or just ty/consts. Then, when resolving opaques we wrap ourselves in a `Scope::LateBoundary { deny_late_regions: false }` so that we deny late-bound ty/const, which fixes a bunch of ICEs that all vaguely look like `impl for<T> Trait<Assoc = impl OtherTrait<T>>`.
I guess this could be achieved other ways; for example, with a different scope kind, or maybe we could just reuse `Scope::Opaque`. But this seems a bit more verbose. I'm open to feedback anyways.
Fixes#131535Fixes#131637Fixes#132530
I opted to remove those crashes tests ^ without adding them as regular tests, since they're basically triggering uninteresting late-bound ICEs far off in the trait solver, and the reason that existing tests such as `tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs` don't ICE are kinda just coincidental (i.e. due to a missing impl block). I don't really feel motivated to add random permutations to tests just to exercise non-lifetime binders.
r? cjgillot
Unify FnKind between AST visitors and make WalkItemKind more straight forward
Unifying `FnKind` requires a bunch of changes to `WalkItemKind::walk` signature so I'll change them in one go
related to #128974
r? `@petrochenkov`
If a macro statement has been parsed after `else`, suggest a missing `if`:
```
error: expected `{`, found `falsy`
--> $DIR/else-no-if.rs:47:12
|
LL | } else falsy! {} {
| ---- ^^^^^
| |
| expected an `if` or a block after this `else`
|
help: add an `if` if this is the condition of a chained `else if` statement
|
LL | } else if falsy! {} {
| ++
```
Look at the expression that was parsed when trying to recover from a bad `if` condition to determine what was likely intended by the user beyond "maybe this was meant to be an `else` body".
```
error: expected `{`, found `map`
--> $DIR/missing-dot-on-if-condition-expression-fixable.rs:4:30
|
LL | for _ in [1, 2, 3].iter()map(|x| x) {}
| ^^^ expected `{`
|
help: you might have meant to write a method call
|
LL | for _ in [1, 2, 3].iter().map(|x| x) {}
| +
```
This replaces the single Vec allocation with a series of progressively
larger buckets. With the cfg for parallel enabled but with -Zthreads=1,
this looks like a slight regression in i-count and cycle counts (<0.1%).
With the parallel frontend at -Zthreads=4, this is an improvement (-5%
wall-time from 5.788 to 5.4688 on libcore) than our current Lock-based
approach, likely due to reducing the bouncing of the cache line holding
the lock. At -Zthreads=32 it's a huge improvement (-46%: 8.829 -> 4.7319
seconds).
Fix span edition for 2024 RPIT coming from an external macro
This fixes a problem where code generated by an external macro with an RPIT would end up using the call-site edition instead of the macro's edition for the RPIT. When used from a 2024 crate, this caused the code to change behavior to the 2024 capturing rules, which we don't want.
This was caused by the impl-trait lowering code would replace the span with one marked with `DesugaringKind::OpaqueTy` desugaring. However, it was also overriding the edition of the span with the edition of the local crate. Instead it should be using the edition of the span itself.
Fixes https://github.com/rust-lang/rust/issues/132917
Mention both release *and* edition breakage for never type lints
This PR makes ~~two changes~~ a change to the never type lints (`dependency_on_unit_never_type_fallback` and `never_type_fallback_flowing_into_unsafe`):
1. Change the wording of the note to mention that the breaking change will be made in an edition _and_ in a future release
2. ~~Make these warnings be reported in deps (hopefully the lints are matured enough)~~
r? ``@compiler-errors``
cc ``@ehuss``
closes#132930
Rollup of 4 pull requests
Successful merges:
- #132817 (Recurse into APITs in `impl_trait_overcaptures`)
- #133021 (Refactor `configure_annotatable`)
- #133045 (tests: Test pac-ret flag merging on clang with LTO)
- #133049 (Change Visitor::visit_precise_capturing_arg so it returns a Visitor::Result)
r? `@ghost`
`@rustbot` modify labels: rollup
This fixes a problem where code generated by an external macro with an
RPIT would end up using the call-site edition instead of the macro's
edition for the RPIT. When used from a 2024 crate, this caused the code
to change behavior to the 2024 capturing rules, which we don't want.
This was caused by the impl-trait lowering code would replace the span
with one marked with `DesugaringKind::OpaqueTy` desugaring. However, it
was also overriding the edition of the span with the edition of the
local crate. Instead it should be using the edition of the span itself.
Fixes https://github.com/rust-lang/rust/issues/132917