Skip to content

Commit 7e12422

Browse files
Merge #1652
1652: Improve type hints behavior r=matklad a=SomeoneToIgnore This PR fixed the following type hints issues: * Restructures the `InlayKind` enum contents based on the discussion here: #1606 (comment) * Races described in #1639 * Caches the latest decorations received for each file to show them the next time the file is opened (instead of a new server request) Co-authored-by: Kirill Bulatov <[email protected]>
2 parents 811492a + c5598d9 commit 7e12422

File tree

5 files changed

+98
-112
lines changed

5 files changed

+98
-112
lines changed

crates/ra_ide_api/src/inlay_hints.rs

Lines changed: 41 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,9 @@ use ra_syntax::{
99
SmolStr, SyntaxKind, SyntaxNode, TextRange,
1010
};
1111

12-
#[derive(Debug, PartialEq, Eq, Clone)]
12+
#[derive(Debug, PartialEq, Eq)]
1313
pub enum InlayKind {
14-
LetBindingType,
15-
ClosureParameterType,
16-
ForExpressionBindingType,
17-
IfExpressionType,
18-
WhileLetExpressionType,
19-
MatchArmType,
14+
TypeHint,
2015
}
2116

2217
#[derive(Debug)]
@@ -46,7 +41,7 @@ fn get_inlay_hints(
4641
}
4742
let pat = let_statement.pat()?;
4843
let analyzer = SourceAnalyzer::new(db, file_id, let_statement.syntax(), None);
49-
Some(get_pat_hints(db, &analyzer, pat, InlayKind::LetBindingType, false))
44+
Some(get_pat_type_hints(db, &analyzer, pat, false))
5045
})
5146
.visit(|closure_parameter: LambdaExpr| {
5247
let analyzer = SourceAnalyzer::new(db, file_id, closure_parameter.syntax(), None);
@@ -55,33 +50,25 @@ fn get_inlay_hints(
5550
.params()
5651
.filter(|closure_param| closure_param.ascribed_type().is_none())
5752
.filter_map(|closure_param| closure_param.pat())
58-
.map(|root_pat| {
59-
get_pat_hints(
60-
db,
61-
&analyzer,
62-
root_pat,
63-
InlayKind::ClosureParameterType,
64-
false,
65-
)
66-
})
53+
.map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, false))
6754
.flatten()
6855
.collect()
6956
})
7057
})
7158
.visit(|for_expression: ForExpr| {
7259
let pat = for_expression.pat()?;
7360
let analyzer = SourceAnalyzer::new(db, file_id, for_expression.syntax(), None);
74-
Some(get_pat_hints(db, &analyzer, pat, InlayKind::ForExpressionBindingType, false))
61+
Some(get_pat_type_hints(db, &analyzer, pat, false))
7562
})
7663
.visit(|if_expr: IfExpr| {
7764
let pat = if_expr.condition()?.pat()?;
7865
let analyzer = SourceAnalyzer::new(db, file_id, if_expr.syntax(), None);
79-
Some(get_pat_hints(db, &analyzer, pat, InlayKind::IfExpressionType, true))
66+
Some(get_pat_type_hints(db, &analyzer, pat, true))
8067
})
8168
.visit(|while_expr: WhileExpr| {
8269
let pat = while_expr.condition()?.pat()?;
8370
let analyzer = SourceAnalyzer::new(db, file_id, while_expr.syntax(), None);
84-
Some(get_pat_hints(db, &analyzer, pat, InlayKind::WhileLetExpressionType, true))
71+
Some(get_pat_type_hints(db, &analyzer, pat, true))
8572
})
8673
.visit(|match_arm_list: MatchArmList| {
8774
let analyzer = SourceAnalyzer::new(db, file_id, match_arm_list.syntax(), None);
@@ -90,21 +77,18 @@ fn get_inlay_hints(
9077
.arms()
9178
.map(|match_arm| match_arm.pats())
9279
.flatten()
93-
.map(|root_pat| {
94-
get_pat_hints(db, &analyzer, root_pat, InlayKind::MatchArmType, true)
95-
})
80+
.map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, true))
9681
.flatten()
9782
.collect(),
9883
)
9984
})
10085
.accept(&node)?
10186
}
10287

103-
fn get_pat_hints(
88+
fn get_pat_type_hints(
10489
db: &RootDatabase,
10590
analyzer: &SourceAnalyzer,
10691
root_pat: Pat,
107-
kind: InlayKind,
10892
skip_root_pat_hint: bool,
10993
) -> Vec<InlayHint> {
11094
let original_pat = &root_pat.clone();
@@ -118,7 +102,7 @@ fn get_pat_hints(
118102
})
119103
.map(|(range, pat_type)| InlayHint {
120104
range,
121-
kind: kind.clone(),
105+
kind: InlayKind::TypeHint,
122106
label: pat_type.display(db).to_string().into(),
123107
})
124108
.collect()
@@ -232,52 +216,52 @@ fn main() {
232216
assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
233217
InlayHint {
234218
range: [193; 197),
235-
kind: LetBindingType,
219+
kind: TypeHint,
236220
label: "i32",
237221
},
238222
InlayHint {
239223
range: [236; 244),
240-
kind: LetBindingType,
224+
kind: TypeHint,
241225
label: "i32",
242226
},
243227
InlayHint {
244228
range: [275; 279),
245-
kind: LetBindingType,
229+
kind: TypeHint,
246230
label: "&str",
247231
},
248232
InlayHint {
249233
range: [539; 543),
250-
kind: LetBindingType,
234+
kind: TypeHint,
251235
label: "(i32, char)",
252236
},
253237
InlayHint {
254238
range: [566; 567),
255-
kind: LetBindingType,
239+
kind: TypeHint,
256240
label: "i32",
257241
},
258242
InlayHint {
259243
range: [570; 571),
260-
kind: LetBindingType,
244+
kind: TypeHint,
261245
label: "i32",
262246
},
263247
InlayHint {
264248
range: [573; 574),
265-
kind: LetBindingType,
249+
kind: TypeHint,
266250
label: "i32",
267251
},
268252
InlayHint {
269253
range: [584; 585),
270-
kind: LetBindingType,
254+
kind: TypeHint,
271255
label: "i32",
272256
},
273257
InlayHint {
274258
range: [577; 578),
275-
kind: LetBindingType,
259+
kind: TypeHint,
276260
label: "f64",
277261
},
278262
InlayHint {
279263
range: [580; 581),
280-
kind: LetBindingType,
264+
kind: TypeHint,
281265
label: "f64",
282266
},
283267
]"#
@@ -299,12 +283,12 @@ fn main() {
299283
assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
300284
InlayHint {
301285
range: [21; 30),
302-
kind: LetBindingType,
286+
kind: TypeHint,
303287
label: "i32",
304288
},
305289
InlayHint {
306290
range: [57; 66),
307-
kind: ClosureParameterType,
291+
kind: TypeHint,
308292
label: "i32",
309293
},
310294
]"#
@@ -326,12 +310,12 @@ fn main() {
326310
assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
327311
InlayHint {
328312
range: [21; 30),
329-
kind: LetBindingType,
313+
kind: TypeHint,
330314
label: "i32",
331315
},
332316
InlayHint {
333317
range: [44; 53),
334-
kind: ForExpressionBindingType,
318+
kind: TypeHint,
335319
label: "i32",
336320
},
337321
]"#
@@ -364,35 +348,35 @@ fn main() {
364348
if let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {};
365349
if let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {};
366350
if let CustomOption::Some(Test { b: y, .. }) = &test {};
367-
351+
368352
if test == CustomOption::None {}
369353
}"#,
370354
);
371355

372356
assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
373357
InlayHint {
374358
range: [166; 170),
375-
kind: LetBindingType,
359+
kind: TypeHint,
376360
label: "CustomOption<Test>",
377361
},
378362
InlayHint {
379363
range: [334; 338),
380-
kind: IfExpressionType,
364+
kind: TypeHint,
381365
label: "&Test",
382366
},
383367
InlayHint {
384368
range: [389; 390),
385-
kind: IfExpressionType,
369+
kind: TypeHint,
386370
label: "&CustomOption<u32>",
387371
},
388372
InlayHint {
389373
range: [392; 393),
390-
kind: IfExpressionType,
374+
kind: TypeHint,
391375
label: "&u8",
392376
},
393377
InlayHint {
394378
range: [531; 532),
395-
kind: IfExpressionType,
379+
kind: TypeHint,
396380
label: "&u32",
397381
},
398382
]"#
@@ -425,15 +409,15 @@ fn main() {
425409
while let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {};
426410
while let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {};
427411
while let CustomOption::Some(Test { b: y, .. }) = &test {};
428-
412+
429413
while test == CustomOption::None {}
430414
}"#,
431415
);
432416

433417
assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
434418
InlayHint {
435419
range: [166; 170),
436-
kind: LetBindingType,
420+
kind: TypeHint,
437421
label: "CustomOption<Test>",
438422
},
439423
]"#
@@ -445,7 +429,7 @@ fn main() {
445429
let (analysis, file_id) = single_file(
446430
r#"
447431
#[derive(PartialEq)]
448-
enum CustomOption<T> {
432+
enum CustomOption<T> {
449433
None,
450434
Some(T),
451435
}
@@ -473,23 +457,23 @@ fn main() {
473457

474458
assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[
475459
InlayHint {
476-
range: [312; 316),
477-
kind: MatchArmType,
460+
range: [311; 315),
461+
kind: TypeHint,
478462
label: "Test",
479463
},
480464
InlayHint {
481-
range: [359; 360),
482-
kind: MatchArmType,
465+
range: [358; 359),
466+
kind: TypeHint,
483467
label: "CustomOption<u32>",
484468
},
485469
InlayHint {
486-
range: [362; 363),
487-
kind: MatchArmType,
470+
range: [361; 362),
471+
kind: TypeHint,
488472
label: "u8",
489473
},
490474
InlayHint {
491-
range: [485; 486),
492-
kind: MatchArmType,
475+
range: [484; 485),
476+
kind: TypeHint,
493477
label: "u32",
494478
},
495479
]"#

crates/ra_lsp_server/src/main_loop/handlers.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -885,14 +885,7 @@ pub fn handle_inlay_hints(
885885
label: api_type.label.to_string(),
886886
range: api_type.range.conv_with(&line_index),
887887
kind: match api_type.kind {
888-
ra_ide_api::InlayKind::LetBindingType => InlayKind::LetBindingType,
889-
ra_ide_api::InlayKind::ClosureParameterType => InlayKind::ClosureParameterType,
890-
ra_ide_api::InlayKind::ForExpressionBindingType => {
891-
InlayKind::ForExpressionBindingType
892-
}
893-
ra_ide_api::InlayKind::IfExpressionType => InlayKind::IfExpressionType,
894-
ra_ide_api::InlayKind::WhileLetExpressionType => InlayKind::WhileLetExpressionType,
895-
ra_ide_api::InlayKind::MatchArmType => InlayKind::MatchArmType,
888+
ra_ide_api::InlayKind::TypeHint => InlayKind::TypeHint,
896889
},
897890
})
898891
.collect())

crates/ra_lsp_server/src/req.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,7 @@ pub struct InlayHintsParams {
213213

214214
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
215215
pub enum InlayKind {
216-
LetBindingType,
217-
ClosureParameterType,
218-
ForExpressionBindingType,
219-
IfExpressionType,
220-
WhileLetExpressionType,
221-
MatchArmType,
216+
TypeHint,
222217
}
223218

224219
#[derive(Debug, Deserialize, Serialize)]

0 commit comments

Comments
 (0)