opt-dist: propagate channel info to bootstrap
Fixes#133503.
Previously, `tests/ui/bootstrap/rustc_bootstap.rs` [sic] failed during [beta bump](https://github.com/rust-lang/rust/pull/133447#issuecomment-2501298794) in opt-dist tests. This is because:
- `opt-dist` tried to run `./x test` against beta-channel dist `rustc` through `bootstrap`.
- The dist build produced during the beta bump produces a `rustc` which correctly thinks that it is a beta compiler based on `src/ci/channel` info.
- `opt-dist` tries to run `./x test` on the beta `rustc` from the dist build, but without specifying channel through a synthetic `config.toml`, so `bootstrap` tells `compiletest` that we're on the `nightly` channel (by default).
- Now there's a channel mismatch: `compiletest` believes the `rustc` under test is a *nightly* rustc, but the `rustc` under test actually considers itself a *beta* rustc. This means that `//@ only-nightly` will be satisfied yet the test will fail as the *beta* rustc is not a *nightly* rustc.
This PR:
- Fixes the test failure during beta bump (i.e. #133503) by having `opt-dist` faithfully report the channel of the dist `rustc` being tested (i.e. "beta" in a beta bump PR). This will properly make the test be ignored during beta bump as the `rustc` under test is not a *nightly* rustc.
- Fixes the test name `rustc_bootstap.rs` -> `rustc_bootstrap.rs`. No more stapping.
- Slightly adjusts the doc comment in the test to make it more clear.
I ran a try-job against the beta branch (explicitly running the opt-dist tests by modifying the job definition) with these changes in #134131, and it appears that the try-job was [successful](https://github.com/rust-lang/rust/pull/134131#issuecomment-2555492215). The two commits in this PR are cherry-picked from #134131, with the test commit slightly modified (to also adjust the test comments).
r? `@Kobzol` (or compiler or bootstrap or infra I guess?)
Use `#[derive(Default)]` instead of manual `impl` when possible
While working on #134175 I noticed a few manual `Default` `impl`s that could be `derive`d instead. These likely predate the existence of the `#[default]` attribute for `enum`s.
Revert stabilization of the `#[coverage(..)]` attribute
Due to a process mixup, the PR to stabilize the `#[coverage(..)]` attribute (#130766) was merged while there are still outstanding concerns. The default action in that situation is to revert, and the feature is not sufficiently urgent or uncontroversial to justify special treatment, so this PR reverts that stabilization.
---
- A key point that came up in offline discussions is that unlike most user-facing features, this one never had a proper RFC, so parts of the normal stabilization process that implicitly rely on an RFC break down in this case.
- As the implementor and de-facto owner of the feature in its current form, I would like to think that I made good choices in designing and implementing it, but I don't feel comfortable proceeding to stabilization without further scrutiny.
- There hasn't been a clear opportunity for T-compiler to weigh in or express concerns prior to stabilization.
- The stabilization PR cites a T-lang FCP that occurred in the tracking issue, but due to the messy design and implementation history (and lack of a clear RFC), it's unclear what that FCP approval actually represents in this case.
- At the very least, we should not proceed without a clear statement from T-lang or the relevant members about the team's stance on this feature, especially in light of the other concerns listed here.
- The existing user-facing documentation doesn't clearly reflect which parts of the feature are stable commitments, and which parts are subject to change. And there doesn't appear to be a clear consensus anywhere about where that line is actually drawn, or whether the chosen boundary is acceptable to the relevant teams and individuals.
- For example, the [stabilization report comment](https://github.com/rust-lang/rust/issues/84605#issuecomment-2166514660) mentions that some aspects are subject to change, but that text isn't consistent with my earlier comments, and there doesn't appear to have been any explicit discussion or approval process.
- [The current reference text](https://github.com/rust-lang/reference/blob/4dfaa4f/src/attributes/coverage-instrumentation.md) doesn't mention this distinction at all, and instead simply describes the current implementation behaviour.
- When the implementation was changed to its current form, the associated user-facing error messages were not updated, so they still refer to the attribute only being allowed on functions and closures.
- On its own, this might have been reasonable to fix-forward in the absence of other concerns, but the fact that it never came up earlier highlights the breakdown in process that has occurred here.
---
Apologies to everyone who was excited for this stabilization to land, but unfortunately it simply isn't ready yet.
cleanup `TypeVerifier`
We should merge it with the `TypeChecker` as we no longer bail in cases where it encounters an error since #111863.
It's quite inconsistent whether a check lives in the verifier or the `TypeChecker`, so this feels like a quite impactful cleanup. I expect that for this we may want to change the `TypeChecker` to also be a MIR visitor 🤔 this is non-trivial so I didn't fully do it in this PR.
Best reviewed commit by commit.
r? `@compiler-errors` feel free to reassign however
Asserts the maximum value that can be returned from `Vec::len`
Currently, casting `Vec<i32>` to `Vec<u32>` takes O(1) time:
```rust
// See <https://godbolt.org/z/hxq3hnYKG> for assembly output.
pub fn cast(vec: Vec<i32>) -> Vec<u32> {
vec.into_iter().map(|e| e as _).collect()
}
```
But the generated assembly is not the same as the identity function, which prevents us from casting `Vec<Vec<i32>>` to `Vec<Vec<u32>>` within O(1) time:
```rust
// See <https://godbolt.org/z/7n48bxd9f> for assembly output.
pub fn cast(vec: Vec<Vec<i32>>) -> Vec<Vec<u32>> {
vec.into_iter()
.map(|e| e.into_iter().map(|e| e as _).collect())
.collect()
}
```
This change tries to fix the problem. You can see the comparison here: <https://godbolt.org/z/jdManrKvx>.
Use `PtrMetadata` instead of `Len` in slice drop shims
I tried to do a bigger change in #134297 which didn't work, so here's the part I really wanted: Removing another use of `Len`, in favour of `PtrMetadata`.
Split into two commits where the first just adds a test, so you can look at the second commit to see how the drop shim for an array changes with this PR.
Reusing the same reviewer from the last one:
r? BoxyUwU
Optimize `is_ascii` for `str` and `[u8]` further
Replace the existing optimized function with one that enables auto-vectorization.
This is especially beneficial on x86-64 as `pmovmskb` can be emitted with careful structuring of the code. The instruction can detect non-ASCII characters one vector register width at a time instead of the current `usize` at a time check.
The resulting implementation is completely safe.
`case00_libcore` is the current implementation, `case04_while_loop` is this PR.
```
benchmarks:
ascii::is_ascii_slice::long::case00_libcore 22.25/iter +/- 1.09
ascii::is_ascii_slice::long::case04_while_loop 6.78/iter +/- 0.92
ascii::is_ascii_slice::medium::case00_libcore 2.81/iter +/- 0.39
ascii::is_ascii_slice::medium::case04_while_loop 1.56/iter +/- 0.78
ascii::is_ascii_slice::short::case00_libcore 5.55/iter +/- 0.85
ascii::is_ascii_slice::short::case04_while_loop 3.75/iter +/- 0.22
ascii::is_ascii_slice::unaligned_both_long::case00_libcore 26.59/iter +/- 0.66
ascii::is_ascii_slice::unaligned_both_long::case04_while_loop 5.78/iter +/- 0.16
ascii::is_ascii_slice::unaligned_both_medium::case00_libcore 2.97/iter +/- 0.32
ascii::is_ascii_slice::unaligned_both_medium::case04_while_loop 2.41/iter +/- 0.10
ascii::is_ascii_slice::unaligned_head_long::case00_libcore 23.71/iter +/- 0.79
ascii::is_ascii_slice::unaligned_head_long::case04_while_loop 7.83/iter +/- 1.31
ascii::is_ascii_slice::unaligned_head_medium::case00_libcore 3.69/iter +/- 0.54
ascii::is_ascii_slice::unaligned_head_medium::case04_while_loop 7.05/iter +/- 0.32
ascii::is_ascii_slice::unaligned_tail_long::case00_libcore 24.44/iter +/- 1.41
ascii::is_ascii_slice::unaligned_tail_long::case04_while_loop 5.12/iter +/- 0.18
ascii::is_ascii_slice::unaligned_tail_medium::case00_libcore 3.24/iter +/- 0.40
ascii::is_ascii_slice::unaligned_tail_medium::case04_while_loop 2.86/iter +/- 0.14
```
`unaligned_head_medium` is the main regression in the benchmarks. It is a 32 byte string being sliced `bytes[1..]`.
The first commit can be used to run the benchmarks against the current core implementation.
Previous implementation was done in #74066
---
Two potential drawbacks of this implementation are that it increases instruction count and may regress other platforms/architectures. The benches here may also be too artificial to glean much insight from.
https://rust.godbolt.org/z/G9znGfY36
Foundations of location-sensitive polonius
I'd like to land the prototype I'm describing in the [polonius project goal](https://github.com/rust-lang/rust-project-goals/issues/118). It still is incomplete and naive and terrible but it's working "well enough" to consider landing.
I'd also like to make review easier by not opening a huge PR, but have a couple small-ish ones (the +/- line change summary of this PR looks big, but >80% is moving datalog to a single place).
This PR starts laying the foundation for that work:
- it refactors and collects 99% of the old datalog fact gen, which was spread around everywhere, into a single dedicated module. It's still present at 3 small places (one of which we should revert anyways) that are kinda deep within localized components and are not as easily extractable into the rest of fact gen, so it's fine for now.
- starts introducing the localized constraints, the building blocks of the naive way of implementing the location-sensitive analysis in-tree, which is roughly sketched out in https://smallcultfollowing.com/babysteps/blog/2023/09/22/polonius-part-1/ and https://smallcultfollowing.com/babysteps/blog/2023/09/29/polonius-part-2/ but with a different vibe than per-point environments described in these posts, just `r1@p: r2@q` constraints.
- sets up the skeleton of generating these localized constraints: converting NLL typeck constraints, and creating liveness constraints
- introduces the polonius dual to NLL MIR to help development and debugging. It doesn't do much currently but is a way to see these localized constraints: it's an NLL MIR dump + a dumb listing of the constraints, that can be dumped with `-Zdump-mir=polonius -Zpolonius=next`. Its current state is not intended to be a long-term thing, just for testing purposes -- I will replace its contents in the future with a different approach (an HTML+js file where we can more easily explore/filter/trace these constraints and loan reachability, have mermaid graphs of the usual graphviz dumps, etc).
I've started documenting the approach in this PR, I'll add more in the future. It's quite simple, and should be very clear when more constraints are introduced anyways.
r? `@matthewjasper`
Best reviewed per commit so that the datalog move is less bothersome to read, but if you'd prefer we separate that into a different PR, I can do that (and michael has offered to review these more mechanical changes if it'd help).
handle member constraints directly in the mir type checker
cleaner, faster, easier to change going forward :> fixes#109654
r? `@oli-obk` `@compiler-errors`
Use `MixedBitSet`s in const qualif
These analyses' domains should be very homogeneous, having compressed bitmaps on huge cfgs should make a difference (and doesn’t have an impact on the smaller / regular cfgs in our benchmarks).
This is a >40% walltime reduction on [this stress test](https://github.com/Manishearth/icu4x_compile_sample) extracted from a real world ICU case, and a 10x or so max-rss reduction.
cc `@oli-obk` `@RalfJung`
Should help with (or fix) issue #134404.
Speed up `Parser::expected_tokens`
The constant pushing/clearing of `Parser::expected_tokens` during parsing is slow. This PR speeds it up greatly.
r? `@estebank`
Make sure we handle `backwards_incompatible_lint` drops appropriately in drop elaboration
In #131326, a new kind of scheduled drop (`drop_kind: DropKind::Value` + `backwards_incompatible_lint: true`) was added so that we could insert a new kind of no-op MIR statement (`backward incompatible drop`) for linting purposes.
These drops were intended to have *no side-effects*, but drop elaboration code forgot to handle these drops specially and they were handled otherwise as normal drops in most of the code. This ends up being **unsound** since we insert more than one drop call for some values, which means that `Drop::drop` could be called more than once.
This PR fixes this by splitting out the `DropKind::ForLint` and adjusting the code. I'm not totally certain if all of the places I've adjusted are either reachable or correct, but I'm pretty certain that it's *more* correct than it was previously.
cc `@dingxiangfei2009`
r? nikomatsakis
Fixes#134482
Some destructor/drop related tweaks
Two random tweaks I got from investigating some stuff around drops in edition 2024:
1. Use the `TypingEnv` of the mir builder, rather than making it over again.
2. Rename the `id` field from `Scope` to `local_id`, to reflect that it's a local id, and remove the `item_local_id()` accessor which just returned the id field.
Forbid overwriting types in typeck
While trying to figure out some type setting logic in https://github.com/rust-lang/rust/pull/134248 I realized that we sometimes set a type twice. While hopefully that would have been the same type, we didn't ensure that at all and just silently accepted it. So now we reject setting it twice, unless errors are happening, then we don't care.
Best reviewed commit by commit.
No behaviour change is intended.
reduce compiler `Assemble` complexity
`compile::Assemble` is already complicated by its nature (as it handles core internals like recursive building logic, etc.) and also handles half of `LldWrapper` tool logic for no good reason since it should be done in the build step directly.
This change moves it there to reduce complexity of `compile::Assemble` logic.
Fix intra doc links not generated inside footnote definitions
Fixes#132208.
The problem was that we were running the `Footnote` "pass" before the `LinkReplacer` one. Sadly, the change is bigger than it should because we can't specialize the `Iterator` trait implementation, forcing me to add a new type to handle the other `Iterator` kind (the one which still has the `Range`).
r? ``@notriddle``
Variants::Single: do not use invalid VariantIdx for uninhabited enums
~~Stacked on top of https://github.com/rust-lang/rust/pull/133681, only the last commit is new.~~
Currently, `Variants::Single` for an empty enum contains a `VariantIdx` of 0; looking that up in the enum variant list will ICE. That's quite confusing. So let's fix that by adding a new `Variants::Empty` case for types that have 0 variants.
try-job: i686-msvc
Split up attribute parsing code and move data types to `rustc_attr_data_structures`
This change renames `rustc_attr` to `rustc_attr_parsing`, and splits up the parsing code. At the same time, all the data types used move to `rustc_attr_data_structures`. This is in preparation of also having a third crate: `rustc_attr_validation`
I initially envisioned this as two separate PRs, but I think doing it in one go reduces the number of ways others would have to rebase their changes on this. However, I can still split them.
r? `@oli-obk` (we already discussed how this is a first step in a larger plan)
For a more detailed plan on how attributes are going to change, see https://github.com/rust-lang/rust/issues/131229
Edit: this looks like a giant PR, but the changes are actually rather trivial. Each commit is reviewable on its own, and mostly moves code around. No new logic is added.
Remove queries from the driver interface
All uses of driver queries in the public api of rustc_driver have been removed in https://github.com/rust-lang/rust/pull/134130 already. This removes driver queries from rustc_interface and does a couple of cleanups around TyCtxt construction and entering enabled by this removal.
Finishes the removal of driver queries started with https://github.com/rust-lang/rust/pull/126834.
`UniqueRc` trait impls
UniqueRc tracking Issue: #112566
Stable traits: (i.e. impls behind only the `unique_rc_arc` feature gate)
* Support the same formatting as `Rc`:
* `fmt::Debug` and `fmt::Display` delegate to the pointee.
* `fmt::Pointer` prints the address of the pointee.
* Add explicit `!Send` and `!Sync` impls, to mirror `Rc`.
* Borrowing traits: `Borrow`, `BorrowMut`, `AsRef`, `AsMut`
* `Rc` does not implement `BorrowMut` and `AsMut`, but `UniqueRc` can.
* Unconditional `Unpin`, like other heap-allocated types.
* Comparison traits `(Partial)Ord` and `(Partial)Eq` delegate to the pointees.
* `PartialEq for UniqueRc` does not do `Rc`'s specialization shortcut for pointer equality when `T: Eq`, since by definition two `UniqueRc`s cannot share an allocation.
* `Hash` delegates to the pointee.
* `AsRawFd`, `AsFd`, `AsHandle`, `AsSocket` delegate to the pointee like `Rc`.
* Sidenote: The bounds on `T` for the existing `Pointer<T>` impls for specifically `AsRawFd` and `AsSocket` do not allow `T: ?Sized`. For the added `UniqueRc` impls I allowed `T: ?Sized` for all four traits, but I did not change the existing (stable) impls.
Unstable traits:
* `DispatchFromDyn`, allows using `UniqueRc<Self>` as a method receiver under `feature(arbitrary_self_types)`.
* Existing `PinCoerceUnsized for UniqueRc` is generalized to allow non-`Global` allocators, like `Rc`.
* `DerefPure`, allows using `UniqueRc` in deref-patterns under `feature(deref_patterns)`, like `Rc`.
For documentation, `Rc` only has documentation on the comparison traits' methods, so I copied/adapted the documentation for those, and left the rest without impl-specific docs.
~~Edit: Marked as draft while I figure out `UnwindSafe`.~~
Edit: Ignoring `UnwindSafe` for this PR
Bounds-check with PtrMetadata instead of Len in MIR
Rather than emitting `Len(*_n)` in array index bounds checks, emit `PtrMetadata(copy _n)` instead -- with some asterisks for arrays and `&mut` that need it to be done slightly differently.
We're getting pretty close to removing `Len` entirely, actually. I think just one more PR after this (for slice drop shims).
r? mir
forbid toggling x87 and fpregs on hard-float targets
Part of https://github.com/rust-lang/rust/issues/116344, follow-up to https://github.com/rust-lang/rust/pull/129884:
The `x87` target feature on x86 and the `fpregs` target feature on ARM must not be disabled on a hardfloat target, as that would change the float ABI. However, *enabling* `fpregs` on ARM is [explicitly requested](https://github.com/rust-lang/rust/issues/130988) as it seems to be useful. Therefore, we need to refine the distinction of "forbidden" target features and "allowed" target features: all (un)stable target features can determine on a per-target basis whether they should be allowed to be toggled or not. `fpregs` then checks whether the current target has the `soft-float` feature, and if yes, `fpregs` is permitted -- otherwise, it is not. (Same for `x87` on x86).
Also fixes https://github.com/rust-lang/rust/issues/132351. Since `fpregs` and `x87` can be enabled on some builds and disabled on others, it would make sense that one can query it via `cfg`. Therefore, I made them behave in `cfg` like any other unstable target feature.
The first commit prepares the infrastructure, but does not change behavior. The second commit then wires up `fpregs` and `x87` with that new infrastructure.
r? `@workingjubilee`
Move impl constness into impl trait header
This PR is kind of the opposite of the rejected https://github.com/rust-lang/rust/pull/134114
Instead of moving more things into the `constness` query, we want to keep them where their corresponding hir nodes are lowered. So I gave this a spin for impls, which have an obvious place to be (the impl trait header). And surprisingly it's also a perf improvement (likely just slightly better query & cache usage).
The issue was that removing anything from the `constness` query makes it just return `NotConst`, which is wrong. So I had to change it to `bug!` out if used wrongly, and only then remove the impl blocks from the `constness` query. I think this change is good in general, because it makes using `constness` more robust (as can be seen by how few sites that had to be changed, so it was almost solely used specifically for the purpose of asking for functions' constness). The main thing where this change was not great was in clippy, which was using the `constness` query as a general DefId -> constness map. I added a `DefKind` filter in front of that. If it becomes a more common pattern we can always move that helper into rustc.
Switch inline(always) in core/src/fmt/rt.rs to plain inline
I have a vague memory of these being instantiated a lot. Let's ask perf.
Looks like this is an improvement!