Rollup of 7 pull requests - #161672
Open
JonathanBrouwer wants to merge 51 commits into
Open
Conversation
Example
---
```rust
const _: &str = env!("PATH",);
```
**Before this PR**
```
/* expand error: expected string literal */
```
**After this PR**
```rust
const _: &str = "/usr/bin:/bin";
```
This is basically the most optimized (memory-wise) storage possible, found after multiple measurements. The price we pay for this ultra-extra optimization is a bunch of unsafe, encapsulated in `tt/src/storage.rs`. Since macros and therefore token trees are so common in Rust code, I think this is worth it. Some stats: - On rust-analyzer itself, memory usage is reduced by 30mb. rust-analyzer doesn't use macros a lot and the previous optimization already took the most, but when considering that *all* token trees in r-a now consumes only about 40mb, this is still surprising. - On buck2, ~143mb is saved. - On omicron, ~436mb is saved, and this is after the previous optimization already ripped 880mb! It is only using ~180mb for token trees now, in total! The basic idea is to use a variable-length encoding into a bytes array. Multiple measurements were done in order to determine the most common forms of token trees along with their frequencies, and to find the best encoding. In addition, we also now sort the compressed spans by their frequencies (in a descending order), so that even if a `TopSubtree` has more than 2^4 unique compressed spans, we will still use the more efficient encoding for the biggest number of spans possible. This is made possible by the fact that unlike the previous encoding, now we don't force one span encoding for all tokens (or in fact even for the two spans in one subtree).
fix: don't error on tail comma for some macro
Addresses the FIXME in `hir-ty/src/infer/op.rs` inside
`infer_user_unop`, which previously silently discarded operator method
resolution failures for `!x` and `-x` expressions.
When the operand's type does not implement `std::ops::Not` (for `!`) or
`std::ops::Neg` (for `-`), rust-analyzer now reports the same E0600
error that rustc produces:
cannot apply unary operator `!` to type `Question`
Wired through the standard inference diagnostic pipeline: new
`InferenceDiagnostic::UnaryOperatorCannotBeApplied` variant in hir-ty,
matching `UnaryOperatorCannotBeApplied` struct plus conversion in hir,
and a handler in ide-diagnostics using
`DiagnosticCode::RustcHardError("E0600")`.
Filtering for unresolved / error-typed operands is done in
`resolve_diagnostics()` (crates/hir-ty/src/infer/unify.rs) alongside
the existing `references_non_lt_error()` filter chain for other
diagnostics that carry a type. This keeps `infer_user_unop` free of
callsite guards and lets the natural inference pipeline suppress
spurious reports on incomplete code and on macro expansions that
infer to `{unknown}`.
The `unary_ops` region of `test-utils/src/minicore.rs` also gains
builtin `Not` and `Neg` impls, mirroring how `add_impl!` provides them
in the `add` region. Without these, the diagnostic test fixture would
incorrectly flag `!true`, `!0i32` and similar builtin uses as errors,
because `lookup_op_method` would find no impl in the minicore fixture
even though real `core` has one. With the impls present, primitives
resolve normally and only genuinely unsupported operators trigger the
diagnostic. This also lets us correctly report `-1u32` as E0600, since
real `core` does not implement `Neg` for unsigned integers.
Because the new `not_impl!` / `neg_impl!` blocks live in a nested
`region:builtin_impls` inside `region:unary_ops`, the new tests opt
into both flags via `//- minicore: unary_ops, builtin_impls`. The
existing `legacy_const_generics` test in `mismatched_arg_count` uses
`-1i32` / `-1i8` inline and now needs the same directive so that
`core::ops::Neg` is in scope for its operands.
Minicore `region:eq` and `region:float_consts` now depend on
`unary_ops, builtin_impls` so their smoke tests resolve `Not`/`Neg`
without per-callsite guards. The `Clone for [T; 1]` impl inside
`region:builtin_impls` uses `self[0]`, so it is scoped to a nested
`region:index` and only compiles when `index` is also enabled.
The `UnaryOp::Deref` case is left unchanged; it is already handled by
the `CannotBeDereferenced` diagnostic (E0614) and `infer_user_unop` is
never called for `Deref`.
Part of rust-lang/rust-analyzer#22140.
This updates the rust-version file to 2c39ff4.
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: rust-lang/rust@2c39ff4 Filtered ref: rust-lang/rust-analyzer@3b5a9a7 Upstream diff: rust-lang/rust@7fb284d...2c39ff4 This merge was created using https://github.com/rust-lang/josh-sync.
Rustc pull update
internal: Download all artifacts in a single step
internal: Drop `zigbuild` support
minor: Drop duplicate function
internal: Split VSIX publishing into different jobs and skip duplicates
…-defined fix: emit E0600 when unary `!`/`-` is applied to unsupported type
minor: skip iter excludes 'into_iter' method
Label operands were inferred with `infer_expr`, which demands the block's
type be equal to `()`. A block that diverges has type `!`, so code like
`label { break; }` inside a loop reported a false `expected (), found !`.
Follow rustc's handling in `check_expr_asm` and only demand a supertype
when the block does not diverge, saving and restoring `diverges` around
it.
…verges fix: allow `asm!` label blocks to diverge
This updates the rust-version file to f7d782a.
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: rust-lang/rust@f7d782a Filtered ref: rust-lang/rust-analyzer@0417161 Upstream diff: rust-lang/rust@2c39ff4...f7d782a This merge was created using https://github.com/rust-lang/josh-sync.
Rustc pull update
minor: Fix 1.98.0 Clippy and rustfmt
fix(hir): Use expression store of parent body if available
This renaming should at least make Session and Builder easier to distinguish.
The meaning of `TokenTreeCursor::index` is context-dependent: in the innermost (current) `TokenTreeCursor` it points to the next token tree, but in all the other (stack) `TokenTreeCursor`s it points to the current token tree. This makes the meanings of "current", "next", and "look_ahead" confusing for it and for `TokenCursor`. This commit clarifies things by adjusting the stack `TokenTreeCursor`s to also point to the next token tree, and by improving various comments. The commit also renames `TokenCursor::next` as `TokenCursor::next_and_bump` for consistency with everything else: `next` means "get the next thing" and `bump` means "advance the cursor", and this operation does both.
`rust-analyzer` subtree update Subtree update of `rust-analyzer` to rust-lang/rust-analyzer@5c156cd. Created using https://github.com/rust-lang/josh-sync. r? @ghost
make `pad_i32` of `PassMode::cast` an integer
so that we can specify more than one i32 of padding. This PR only adds the functionality but does not yet use it: there should be no functional changes.
This is needed for the ABI of `Complex<{ float }>` on 32-bit powerpc. Other mechanisms, e.g. using `PassMode::prefixed` don't appear to work.
More discussion is in [#t-compiler/help > power complex abi](https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/power.20complex.20abi/with/613294420).
…JonathanBrouwer Remove `From<!> for T` *reservation* impl This PR removes the `<T> From<!> for T` *reservation* implementation added in rust-lang#62661 and tracked in rust-lang#64715 and rust-lang#64631. The reservation impl in question was added in order to reserve some space for adding the following impl: ```rust impl<T> From<!> for T { fn from(never: !) -> T { never } } ``` It is meant to prevent users from writing *some* impls that would overlap if the `From<!> for T` impl is to be added. This requires T-types FCP. Below is my proposal and necessary context: ## The reservation impl is not sufficient The reservation impl prevents one from assuming that `From<!> for T` is not implemented making the following [not compile](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=220e375c77db9a88c360230283f888cb): ```rust struct LocalType; trait SomeTrait { } impl<T: From<!>> SomeTrait for T { } impl SomeTrait for LocalType { } ``` However, it does not prevent *all* implementation that would overlap given `From<!> for T`. Namely, `From<!> for T` would overlap with the following impls, all of which are currently permitted (and exist): ```rust // T for T identity impl in `core` impl<T> From<T> for T { ... } // Various T->wrapper of T impls present in both the standard library, // and in external crates impl<T> From<T> for W<T> { ... } // !->Local is also allowed impl From<!> for Local {} ``` Also note that the reservation impl only exists for `From<!>`, but not for `From<Infallible>`, so even the impls that the reservation impl is meant to forbid, are currently allowed through `Infallible` anyway (we are planning to make `Infallible` a type alias to `!` at the same time as stabilizing `!`). ## Motivation for `From<!> for T` impl It is surprisingly hard to find the original motivation for `From<!> for T` impl or the reservation impl, other than "people vaguely think that all types should implement `From<!>`, since there is never-to-any coercion". One use-case seems to be "calling infallible function in a fallible one, and unwrapping `Result<_, !>` with `?`". However, nowdays it is trivial to unwrap the result safely without `?`: ```rust let Ok(owo) = infallible_function(); ``` Another use-case that I've seen [mentioned](rust-lang#62661 (comment)) is "fallible function with a set error, taking an infallible function": ```rust fn try_from<T>(t: T) -> Result<Meow, MyError> where Meow: TryFrom<T>, <Meow as TryFrom<T>>::Error: Into<MyError> { ... } ``` With such definition, you can't pass `Meow` into `try_from`, because `MyError: From<Infallible>` doesn't hold. This is more unfortunate, but it's not clear how widespread this problem is and how bad the workarounds would be. If a function expects `impl FnOnce(...) -> Result<...>`, it should be trivial to coerce the `!` error to an appropriate type. With other trait bounds (like in the example above) it could be solved by adding a custom impl for your specific error type (annoying, but workable). Certaintly this doesn't feel like a big roadblock to me. (let me know if you know more prior art on this) ## There is no clear path for adding `From<!> for T` impl Adding `From<!> for T` seems... hard... and hard to argue for. It would require ignoring overlap with a *bunch* of impls (as described above) and would also require low priority impls (to avoid inference failures in cases where previously the only applicable impl was the identity one, so adding `From<!>` makes "one impl rule" not apply). The [tracking issue](rust-lang#64715) says: > The precise mechanism to permit us to add the `From<!> for T` impl is not yet clear. The current "plan of record" is to extend the ["marker trait mechanism"](rust-lang#29864) to accommodate the idea of impls whose entire body consists of unreachable methods and to permit overlap. Considering "traits with all methods having arguments of uninhabited types" as marker traits is technically possible (I think?), but feels like a bit of a stretch. Making overlap check consider if all trait functions take arguments which are uninhabited (known to be uninhabited *in the current context*) seems like a big complication, especially considering how `From<T>` would not be a marker trait in the general case — only `From<!>`/`From<OtherUninhabitedTypes>` would be (also that requires attaching the overlap check to some context from which we can check if a type is publically uninhabited, which can also lead to situations where impl `A` overlaps with impl `B`, but impl `B` doesn't overlap with impl `A`[^1]). Allowing overlap with arbitrary user impls also is likely to cause unforcene issues in my opinion. [^1]: i.e. in the context of impl `A` a certain type is not known to be uninhabited, and thus the overlap between impls should not be allowed. at the same time in the context of impl `B` same type might be known to be uninhabited, allowing the overlap. ## The reservation impl causes problems for the never type stabilization Because the reservation impl reserves space for `From<!> for T`, but not for `From<Infallible> for T`, making `Infallible` an alias for `!` makes some code fail to compile. See rust-lang#155924: > 3. standard library contains a [reservation impl](https://doc.rust-lang.org/1.94.0/src/core/convert/mod.rs.html#802-806), which forbids [certain](rust-lang#64715) `From<!>` impls. After making `Infallible = !`, this reservation impl can conflict with existing implementations for `Infallible` - This breaks 14 crates total (including reverse-dependencies of broken crates) Given that both keeping the reservation impl (while making `Infallible = !`) and making the reservation a proper impl break code, we should decide which path we want to pursue before stabilizing the never type (and making `Infallible = !`). ## Proposal After trying to add `From<!> for T` as a proper impl, I'm not convinced that it's worth the complexity and messiness of allowing such widespread overlap (with user defined impls too!). **As such, I propose to remove the reservation impl**, to prevent unnecessary breakage from its combination with making `Infallible = !`, as described above. ## Alternatives - Add proper `impl<T> From<!> for T`, accepting the breakage, overlap, and the complexity. - I'm not sure how feasible this is, after trying to do this approach, it doesn't feel right - Keep the reservation impl / add the reservation impl `From<Infallible> for T` formally accepting the breakage of that, with the hopes that we can still add `impl<T> From<!> for T` in the future - This is the most breaking of the option, as it breaks code that depends on `From<Infallible> for T` not existing, *and* expects future breakage when adding `impl<T> From<!> for T` - It is unlikely that adding `impl<T> From<!> for T` in the future will be much easier than right now ----- Closes rust-lang#64715 r? types I'll remove the `rustc_reservation_impl` attribute in a separate PR (cc rust-lang#64631).
bootstrap: Rename `Build` to `Session` - Follow-up to rust-lang#161277 --- Having separate types named `Build` and `Builder` is quite confusing, especially since *build* by itself isn't a very informative name in the context of a build system. This PR therefore performs the change suggested in rust-lang#161277 (comment), renaming `Build` to `Session`. While *session* is not exactly the most descriptive name either, it at least has the virtue of being clearly distinct from *builder*. That should be helpful when trying to clarify the different roles of the two types. There should be no change to bootstrap behaviour.
…s, r=petrochenkov delegation: add tests for delegations to inherent impls Second part of rust-lang#160505, for more convenient reviewing. Part of rust-lang#118212. r? @petrochenkov
…r=Kobzol Clarify token cursor behaviour The meaning of `TokenTreeCursor::index` is context-dependent: in the innermost (current) `TokenTreeCursor` it points to the next token tree, but in all the other (stack) `TokenTreeCursor`s it points to the current token tree. This makes the meanings of "current", "next", and "look_ahead" confusing for it and for `TokenCursor`. This commit clarifies things by adjusting the stack `TokenTreeCursor`s to also point to the next token tree, and by improving various comments. The commit also renames `TokenCursor::next` as `TokenCursor::next_and_bump` for consistency with everything else: `next` means "get the next thing" and `bump` means "advance the cursor", and this operation does both. r? @Kobzol
…Brouwer Add codegen test for Vec::clear lowering to an unconditional store Closes rust-lang#45459
Member
Author
Contributor
This comment has been minimized.
This comment has been minimized.
rust-bors Bot
pushed a commit
that referenced
this pull request
Aug 24, 2026
Rollup of 7 pull requests try-job: dist-various-1 try-job: test-various try-job: x86_64-gnu-aux try-job: x86_64-gnu-llvm-21-3 try-job: x86_64-msvc-1 try-job: aarch64-apple-1 try-job: aarch64-apple-2 try-job: x86_64-mingw-1 try-job: i686-msvc-1 try-job: i686-msvc-2
Contributor
|
⌛ Testing commit 782d37d with merge 0a3fa2a... Workflow: https://github.com/rust-lang/rust/actions/runs/32734753359 |
rust-bors Bot
pushed a commit
that referenced
this pull request
Aug 24, 2026
…uwer Rollup of 7 pull requests Successful merges: - #161648 (`rust-analyzer` subtree update) - #160132 (make `pad_i32` of `PassMode::cast` an integer) - #160705 (Remove `From<!> for T` *reservation* impl) - #161600 (bootstrap: Rename `Build` to `Session`) - #161665 (delegation: add tests for delegations to inherent impls) - #161637 (Clarify token cursor behaviour) - #161653 (Add codegen test for Vec::clear lowering to an unconditional store)
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Successful merges:
rust-analyzersubtree update #161648 (rust-analyzersubtree update)pad_i32ofPassMode::castan integer #160132 (makepad_i32ofPassMode::castan integer)From<!> for T*reservation* impl #160705 (RemoveFrom<!> for Treservation impl)BuildtoSession#161600 (bootstrap: RenameBuildtoSession)r? @ghost
Create a similar rollup