-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Postfix adjustment hints #13816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Postfix adjustment hints #13816
Conversation
The chain hint collision comes from the order we emit the hints in, if two hints affect the same text range their order matters, swapping rust-analyzer/crates/ide/src/inlay_hints.rs Lines 236 to 237 in 761b127
The ligature one is clearly a VSCode bug, we could problem work around it by putting similar to what we did for the decorator approach in the past #6236, though that requires intercepting the inlay hint middleware in the client (patching in the server for this feels wrong) so I can do that since I know my way around the client better. |
The order is correct though (type is shown before adjustments), it just looks weird |
Well yes, but I would also argue no, because the adjustment hints are mostly correct expressions (if you forget about them not existing in this postfix form), meanwhile a random type is now interspersed. (chaining hints are the one hints I consider noisy myself which is why I don't have them enabled and keep forgetting about them when touching hint code 😅). We could of course render the adjusted types for those instead when using postfix hints if you want to be completely correct here |
☔ The latest upstream changes (presumably #13817) made this pull request unmergeable. Please resolve the merge conflicts. |
f4618c8
to
be22568
Compare
// This is a very miserable pile of hacks... | ||
// | ||
// `Expr::needs_parens_in` requires that the expression is the child of the other expression, | ||
// that is supposed to be its parent. | ||
// | ||
// But we want to check what would happen if we add `*`/`.*` to the inner expression. | ||
// To check for inner we need `` expr.needs_parens_in(`*expr`) ``, | ||
// to check for outer we need `` `*expr`.needs_parens_in(parent) ``, | ||
// where "expr" is the `expr` parameter, `*expr` is the editted `expr`, | ||
// and "parent" is the parent of the original expression... | ||
// | ||
// For this we utilize mutable mutable trees, which is a HACK, but it works. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ye I am not fond of this at all to be honest :) But I also don't really want to block the PR on this since I can't think of a better way right now either ...
Can you put a FIXME on this/on needs_parens_in
API that this is not ideal? Or maybe open an issue about that, either works.
@bors delegate+ |
✌️ @WaffleLapkin can now approve this pull request |
☔ The latest upstream changes (presumably #13854) made this pull request unmergeable. Please resolve the merge conflicts. |
#13886 fixes the ligature problem |
I'd say "First stab at implementing..." but I've been working on this for a month already lol
be22568
to
a9676cf
Compare
@bors r=Veykril |
☀️ Test successful - checks-actions |
1 similar comment
☀️ Test successful - checks-actions |
👀 Test was successful, but fast-forwarding failed: 422 Changes must be made through a pull request. |
Basic Description
This PR implements "postfix" adjustment hints:

They are identical to normal adjustment hints, but are rendered after the expression. E.g.
expr.*
instead of*expr
.This mirrors "postfix deref" feature that I'm planning to eventually propose to the compiler.Motivation
The advantage of being postfix is that you need to add parentheses less often:
This is because a lot of "reborrow" hints are caused by field access or method calls, both of which are postfix and have higher "precedence" than prefix
&
and*
.Also IMHO it just looks nicer and it's more clear what is happening (order of operations).
Modes
However, there are some cases where postfix hints need parentheses but prefix don't (for example
&x
being turned into(&x).*.*.&
or&**&x
).This PR allows users to choose which look they like more. There are 4 options (
rust-analyzer.inlayHints.expressionAdjustmentHints.mode
setting):prefix
— always use prefix hints (default, what was used before that PR)postfix
— always use postfix hintsprefer_prefix
— try to minimize number of parentheses, breaking ties in favor of prefixprefer_postfix
— try to minimize number of parentheses, breaking ties in favor of postfixComparison of all modes:
Edge cases
Where are some rare cases where chain hints weirdly interact with adjustment hints, for example (note
SourceAnalyzer.&
):This is pre-existing, you can get the same effect with prefix hints (
SourceAnalyzer)
).Another weird thing is this:
Here
.&
is a hint and?
is written in the source code. It looks like?
is part of the hint because?.
is ligature in my font. IMO this is a bug in vscode, but still worth mentioning (I'm also too lazy to report it there...).Fixed bugs
I've used the "needs parens" API and this accidentally fixed a bug with parens around
as
, see the test diff:Changelog
changelog feature Add an option to make adjustment hints (aka reborrow hints) postfix
changelog fix Fix placement of parentheses around
as
casts for adjustment hints