-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Parameter inlay hint separate from variable type inlay? #2876 #3543
Conversation
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.
Thanks for the PR.
I've added a few comments on how I think it can be improved to scale better in the future.
Out CI shows a small compile error: https://github.com/rust-analyzer/rust-analyzer/pull/3543/checks?check_run_id=497229725#step:8:250
so you might want to fix that also :)
crates/ra_project_model/src/lib.rs
Outdated
#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] | ||
#[serde(rename_all = "camelCase", default)] | ||
pub struct InlayHintOptions { | ||
pub display_type: InlayHintDisplayType, |
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.
#2741 have plans to add more various inlay hint types later.
I think we'd better allow to have various combinations of the types turned on simultaneously, since there will be requests for those.
So should we go with a set of InlayKind
's instead of this enum?
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.
A bitset I guess?
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.
Imo, just the HashSet<InlayKind>
is enough.
Or its fx
counterpart, since we use FxHashMap
in the project.
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.
I recall @matklad once said it's better not to use HashSet where Vec is enough
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.
I'm still a bit of a beginner with rust, but @matklad suggested it be a POD (I'm assuming meaning that it implements Copy
?). If I use a Vec or any of these structures it can't be a Copy type.
Add setting to allow enabling either type inlay hints or parameter inlay hints or both. Group the the max inlay hint length option into the object. - Add a new type for the inlayHint options. - Add tests to ensure the inlays don't happen on the server side
@matklad What came to my mind is a feature flag for |
- Updated naming of config - Define struct in ra_ide and use remote derive in rust-analyzer/config - Make inlayConfig type more flexible to support more future types - Remove constructor only used in tests
I fixed the build error and addressed the issues mentioned above. |
crates/rust-analyzer/src/config.rs
Outdated
use rustc_hash::FxHashMap; | ||
|
||
use ra_project_model::CargoFeatures; | ||
use serde::{Deserialize, Deserializer}; | ||
|
||
#[derive(Deserialize)] | ||
#[serde(remote = "InlayKind")] | ||
pub enum InlayKindDef { |
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.
I think there's already an enum for this entity:
https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/rust-analyzer/src/req.rs#L199
so let's not create a copy of it.
A few more observations, feel free to implement any (or none) of them, if you want to:
-
It could be a bit simpler to use a
match
to map between bothInlayKind
enums, similar to the https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/rust-analyzer/src/main_loop/handlers.rs#L1006 -
Since you can easily deserialize a
Vec<InlayKind>
, you can ask for that in thepackage.json
instead and get rid of all changes in thera_project_model
crate.
Less code with more flexibility for the end users (as long as they know which options are available)
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.
Does it make sense to deduplicate the InlayKind
as mentioned and then just use the serde remote feature so we don't even need to do the match in the first place?
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.
Personally, I'd prefer using match
, but if your way works, it's also good, thanks for the dedup.
- Remove match conversion for InlayKind since we're using remote
Did you try to install and run the branch after all the changes? I've tried and got
I think I also notice that the Or, as proposed earlier, we can fully remove the chages in |
editors/code/package.json
Outdated
"rust-analyzer.inlayHintOpts.displayType": { | ||
"type": "string", | ||
"enum": [ | ||
"off", | ||
"typeHints", | ||
"parameterHints", | ||
"full" | ||
], | ||
"enumDescriptions": [ | ||
"No type inlay hints", | ||
"Type inlays hints only", | ||
"Parameter inlays hints only", | ||
"All inlay hints types" | ||
], |
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.
"rust-analyzer.inlayHintOpts.displayType": { | |
"type": "string", | |
"enum": [ | |
"off", | |
"typeHints", | |
"parameterHints", | |
"full" | |
], | |
"enumDescriptions": [ | |
"No type inlay hints", | |
"Type inlays hints only", | |
"Parameter inlays hints only", | |
"All inlay hints types" | |
], | |
"rust-analyzer.inlayHints": { | |
"type": "object", | |
"properties": { | |
"types": { | |
"type": "boolean", | |
"default": true, | |
"description": "Whether to show inlay type hints" | |
}, | |
"parameterNames": { | |
"type": "boolean", | |
"default": true, | |
"description": "Whether to show function parameter names inlay hints at the call site" | |
} | |
} |
I believe just a struct with boolean
s will play well. This should be more user-friendly, since people tend to misspel enum string values to much (and we don't validate this on client-side, but misspelling of config keys is handled by vscode). This also gives us flexibility to add new kinds of inlay hints without having to create enum value for each of their combination (i.e. off
, full
, inlay1
, inlay1_and_inlay2
, inlay1_and_inlay3
... etc. this gives us a combinatorial explosion)
And maybe this makes sense to use such a struct on the server-side as well @SomeoneToIgnore, @slyngbaek ?
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.
I converted from using the Vec<InlayKind>
to an object with props. Instead of using a single object type I made several nested props so that they show up in the GUI.
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.
@SomeoneToIgnore You're right. I tested it before pushing this time. I also removed the dead code in the ra_project_model
.
- Instead of a single object type, use several individual nested types to allow toggling from the settings GUI - Remove unused struct definitions - Install and test that the toggles work
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.
Nice, thanks for the fixes.
I think we're good to merge it.
bors r+ |
ra_ide knows nothing about LSP by design. The cost of copy-paste is much smaller than the cost of breaching the strong abstraction boundary ra_ide is. EDIT: sorry, this is a too short reply,let me actually take some time to write smth more reasonable :) |
Build succeeded |
Yeah, I think we are just choosing between what looks less workaround-y |
Longer reply. rust-analyzer is intended to be isolated from LSP. I feel that the potential use-cases for rust-analyzer stretch far beyond just LSP, and, down the road, hard dependency on LSP would be a liability. This is the reason why we spend 700 lines of code in conv.rs doing mostly trivial conversions between the types. It's a design goal that all the types exported from In this particlar case, what happens is that we need two completely unrelated things:
The fact that the the same struct can server both cases, now, is a pure coincidence. Specifically, if we upstream this feature to LSP, the LSP would likely use the type of the different shape. This is kind of a general instance of the advice that you don't make your domain objects directly serializable, but instead have an intermediate layer which specifically handles serizliation. This makes it possible to vary domain objects and serialization independently. |
Okay you persuaded me, thanks for taking the time! |
Add setting to allow enabling either type inlay hints or parameter
inlay hints or both. Group the the max inlay hint length option
into the object.