diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-08-06 17:50:49 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-08-06 17:50:49 +0100 |
commit | 7e12422fa2c8ba7b3df63b4e4297464a0071a359 (patch) | |
tree | f88de34c48e08ea8cf481a29f5764f13492a9ac9 /crates/ra_ide_api/src/inlay_hints.rs | |
parent | 811492aa546d83daf56f61d334d6ee295651f111 (diff) | |
parent | c5598d9ade92e9ec4474a14229bb34a44a4edad5 (diff) |
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: https://github.com/rust-analyzer/rust-analyzer/pull/1606#issuecomment-515968055
* 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]>
Diffstat (limited to 'crates/ra_ide_api/src/inlay_hints.rs')
-rw-r--r-- | crates/ra_ide_api/src/inlay_hints.rs | 98 |
1 files changed, 41 insertions, 57 deletions
diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide_api/src/inlay_hints.rs index a524e014f..7b9190314 100644 --- a/crates/ra_ide_api/src/inlay_hints.rs +++ b/crates/ra_ide_api/src/inlay_hints.rs | |||
@@ -9,14 +9,9 @@ use ra_syntax::{ | |||
9 | SmolStr, SyntaxKind, SyntaxNode, TextRange, | 9 | SmolStr, SyntaxKind, SyntaxNode, TextRange, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | #[derive(Debug, PartialEq, Eq, Clone)] | 12 | #[derive(Debug, PartialEq, Eq)] |
13 | pub enum InlayKind { | 13 | pub enum InlayKind { |
14 | LetBindingType, | 14 | TypeHint, |
15 | ClosureParameterType, | ||
16 | ForExpressionBindingType, | ||
17 | IfExpressionType, | ||
18 | WhileLetExpressionType, | ||
19 | MatchArmType, | ||
20 | } | 15 | } |
21 | 16 | ||
22 | #[derive(Debug)] | 17 | #[derive(Debug)] |
@@ -46,7 +41,7 @@ fn get_inlay_hints( | |||
46 | } | 41 | } |
47 | let pat = let_statement.pat()?; | 42 | let pat = let_statement.pat()?; |
48 | let analyzer = SourceAnalyzer::new(db, file_id, let_statement.syntax(), None); | 43 | 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)) |
50 | }) | 45 | }) |
51 | .visit(|closure_parameter: LambdaExpr| { | 46 | .visit(|closure_parameter: LambdaExpr| { |
52 | let analyzer = SourceAnalyzer::new(db, file_id, closure_parameter.syntax(), None); | 47 | let analyzer = SourceAnalyzer::new(db, file_id, closure_parameter.syntax(), None); |
@@ -55,15 +50,7 @@ fn get_inlay_hints( | |||
55 | .params() | 50 | .params() |
56 | .filter(|closure_param| closure_param.ascribed_type().is_none()) | 51 | .filter(|closure_param| closure_param.ascribed_type().is_none()) |
57 | .filter_map(|closure_param| closure_param.pat()) | 52 | .filter_map(|closure_param| closure_param.pat()) |
58 | .map(|root_pat| { | 53 | .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, false)) |
59 | get_pat_hints( | ||
60 | db, | ||
61 | &analyzer, | ||
62 | root_pat, | ||
63 | InlayKind::ClosureParameterType, | ||
64 | false, | ||
65 | ) | ||
66 | }) | ||
67 | .flatten() | 54 | .flatten() |
68 | .collect() | 55 | .collect() |
69 | }) | 56 | }) |
@@ -71,17 +58,17 @@ fn get_inlay_hints( | |||
71 | .visit(|for_expression: ForExpr| { | 58 | .visit(|for_expression: ForExpr| { |
72 | let pat = for_expression.pat()?; | 59 | let pat = for_expression.pat()?; |
73 | let analyzer = SourceAnalyzer::new(db, file_id, for_expression.syntax(), None); | 60 | 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)) |
75 | }) | 62 | }) |
76 | .visit(|if_expr: IfExpr| { | 63 | .visit(|if_expr: IfExpr| { |
77 | let pat = if_expr.condition()?.pat()?; | 64 | let pat = if_expr.condition()?.pat()?; |
78 | let analyzer = SourceAnalyzer::new(db, file_id, if_expr.syntax(), None); | 65 | 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)) |
80 | }) | 67 | }) |
81 | .visit(|while_expr: WhileExpr| { | 68 | .visit(|while_expr: WhileExpr| { |
82 | let pat = while_expr.condition()?.pat()?; | 69 | let pat = while_expr.condition()?.pat()?; |
83 | let analyzer = SourceAnalyzer::new(db, file_id, while_expr.syntax(), None); | 70 | 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)) |
85 | }) | 72 | }) |
86 | .visit(|match_arm_list: MatchArmList| { | 73 | .visit(|match_arm_list: MatchArmList| { |
87 | let analyzer = SourceAnalyzer::new(db, file_id, match_arm_list.syntax(), None); | 74 | let analyzer = SourceAnalyzer::new(db, file_id, match_arm_list.syntax(), None); |
@@ -90,9 +77,7 @@ fn get_inlay_hints( | |||
90 | .arms() | 77 | .arms() |
91 | .map(|match_arm| match_arm.pats()) | 78 | .map(|match_arm| match_arm.pats()) |
92 | .flatten() | 79 | .flatten() |
93 | .map(|root_pat| { | 80 | .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, true)) |
94 | get_pat_hints(db, &analyzer, root_pat, InlayKind::MatchArmType, true) | ||
95 | }) | ||
96 | .flatten() | 81 | .flatten() |
97 | .collect(), | 82 | .collect(), |
98 | ) | 83 | ) |
@@ -100,11 +85,10 @@ fn get_inlay_hints( | |||
100 | .accept(&node)? | 85 | .accept(&node)? |
101 | } | 86 | } |
102 | 87 | ||
103 | fn get_pat_hints( | 88 | fn get_pat_type_hints( |
104 | db: &RootDatabase, | 89 | db: &RootDatabase, |
105 | analyzer: &SourceAnalyzer, | 90 | analyzer: &SourceAnalyzer, |
106 | root_pat: Pat, | 91 | root_pat: Pat, |
107 | kind: InlayKind, | ||
108 | skip_root_pat_hint: bool, | 92 | skip_root_pat_hint: bool, |
109 | ) -> Vec<InlayHint> { | 93 | ) -> Vec<InlayHint> { |
110 | let original_pat = &root_pat.clone(); | 94 | let original_pat = &root_pat.clone(); |
@@ -118,7 +102,7 @@ fn get_pat_hints( | |||
118 | }) | 102 | }) |
119 | .map(|(range, pat_type)| InlayHint { | 103 | .map(|(range, pat_type)| InlayHint { |
120 | range, | 104 | range, |
121 | kind: kind.clone(), | 105 | kind: InlayKind::TypeHint, |
122 | label: pat_type.display(db).to_string().into(), | 106 | label: pat_type.display(db).to_string().into(), |
123 | }) | 107 | }) |
124 | .collect() | 108 | .collect() |
@@ -232,52 +216,52 @@ fn main() { | |||
232 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ | 216 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ |
233 | InlayHint { | 217 | InlayHint { |
234 | range: [193; 197), | 218 | range: [193; 197), |
235 | kind: LetBindingType, | 219 | kind: TypeHint, |
236 | label: "i32", | 220 | label: "i32", |
237 | }, | 221 | }, |
238 | InlayHint { | 222 | InlayHint { |
239 | range: [236; 244), | 223 | range: [236; 244), |
240 | kind: LetBindingType, | 224 | kind: TypeHint, |
241 | label: "i32", | 225 | label: "i32", |
242 | }, | 226 | }, |
243 | InlayHint { | 227 | InlayHint { |
244 | range: [275; 279), | 228 | range: [275; 279), |
245 | kind: LetBindingType, | 229 | kind: TypeHint, |
246 | label: "&str", | 230 | label: "&str", |
247 | }, | 231 | }, |
248 | InlayHint { | 232 | InlayHint { |
249 | range: [539; 543), | 233 | range: [539; 543), |
250 | kind: LetBindingType, | 234 | kind: TypeHint, |
251 | label: "(i32, char)", | 235 | label: "(i32, char)", |
252 | }, | 236 | }, |
253 | InlayHint { | 237 | InlayHint { |
254 | range: [566; 567), | 238 | range: [566; 567), |
255 | kind: LetBindingType, | 239 | kind: TypeHint, |
256 | label: "i32", | 240 | label: "i32", |
257 | }, | 241 | }, |
258 | InlayHint { | 242 | InlayHint { |
259 | range: [570; 571), | 243 | range: [570; 571), |
260 | kind: LetBindingType, | 244 | kind: TypeHint, |
261 | label: "i32", | 245 | label: "i32", |
262 | }, | 246 | }, |
263 | InlayHint { | 247 | InlayHint { |
264 | range: [573; 574), | 248 | range: [573; 574), |
265 | kind: LetBindingType, | 249 | kind: TypeHint, |
266 | label: "i32", | 250 | label: "i32", |
267 | }, | 251 | }, |
268 | InlayHint { | 252 | InlayHint { |
269 | range: [584; 585), | 253 | range: [584; 585), |
270 | kind: LetBindingType, | 254 | kind: TypeHint, |
271 | label: "i32", | 255 | label: "i32", |
272 | }, | 256 | }, |
273 | InlayHint { | 257 | InlayHint { |
274 | range: [577; 578), | 258 | range: [577; 578), |
275 | kind: LetBindingType, | 259 | kind: TypeHint, |
276 | label: "f64", | 260 | label: "f64", |
277 | }, | 261 | }, |
278 | InlayHint { | 262 | InlayHint { |
279 | range: [580; 581), | 263 | range: [580; 581), |
280 | kind: LetBindingType, | 264 | kind: TypeHint, |
281 | label: "f64", | 265 | label: "f64", |
282 | }, | 266 | }, |
283 | ]"# | 267 | ]"# |
@@ -299,12 +283,12 @@ fn main() { | |||
299 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ | 283 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ |
300 | InlayHint { | 284 | InlayHint { |
301 | range: [21; 30), | 285 | range: [21; 30), |
302 | kind: LetBindingType, | 286 | kind: TypeHint, |
303 | label: "i32", | 287 | label: "i32", |
304 | }, | 288 | }, |
305 | InlayHint { | 289 | InlayHint { |
306 | range: [57; 66), | 290 | range: [57; 66), |
307 | kind: ClosureParameterType, | 291 | kind: TypeHint, |
308 | label: "i32", | 292 | label: "i32", |
309 | }, | 293 | }, |
310 | ]"# | 294 | ]"# |
@@ -326,12 +310,12 @@ fn main() { | |||
326 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ | 310 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ |
327 | InlayHint { | 311 | InlayHint { |
328 | range: [21; 30), | 312 | range: [21; 30), |
329 | kind: LetBindingType, | 313 | kind: TypeHint, |
330 | label: "i32", | 314 | label: "i32", |
331 | }, | 315 | }, |
332 | InlayHint { | 316 | InlayHint { |
333 | range: [44; 53), | 317 | range: [44; 53), |
334 | kind: ForExpressionBindingType, | 318 | kind: TypeHint, |
335 | label: "i32", | 319 | label: "i32", |
336 | }, | 320 | }, |
337 | ]"# | 321 | ]"# |
@@ -364,7 +348,7 @@ fn main() { | |||
364 | if let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {}; | 348 | if let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {}; |
365 | if let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {}; | 349 | if let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {}; |
366 | if let CustomOption::Some(Test { b: y, .. }) = &test {}; | 350 | if let CustomOption::Some(Test { b: y, .. }) = &test {}; |
367 | 351 | ||
368 | if test == CustomOption::None {} | 352 | if test == CustomOption::None {} |
369 | }"#, | 353 | }"#, |
370 | ); | 354 | ); |
@@ -372,27 +356,27 @@ fn main() { | |||
372 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ | 356 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ |
373 | InlayHint { | 357 | InlayHint { |
374 | range: [166; 170), | 358 | range: [166; 170), |
375 | kind: LetBindingType, | 359 | kind: TypeHint, |
376 | label: "CustomOption<Test>", | 360 | label: "CustomOption<Test>", |
377 | }, | 361 | }, |
378 | InlayHint { | 362 | InlayHint { |
379 | range: [334; 338), | 363 | range: [334; 338), |
380 | kind: IfExpressionType, | 364 | kind: TypeHint, |
381 | label: "&Test", | 365 | label: "&Test", |
382 | }, | 366 | }, |
383 | InlayHint { | 367 | InlayHint { |
384 | range: [389; 390), | 368 | range: [389; 390), |
385 | kind: IfExpressionType, | 369 | kind: TypeHint, |
386 | label: "&CustomOption<u32>", | 370 | label: "&CustomOption<u32>", |
387 | }, | 371 | }, |
388 | InlayHint { | 372 | InlayHint { |
389 | range: [392; 393), | 373 | range: [392; 393), |
390 | kind: IfExpressionType, | 374 | kind: TypeHint, |
391 | label: "&u8", | 375 | label: "&u8", |
392 | }, | 376 | }, |
393 | InlayHint { | 377 | InlayHint { |
394 | range: [531; 532), | 378 | range: [531; 532), |
395 | kind: IfExpressionType, | 379 | kind: TypeHint, |
396 | label: "&u32", | 380 | label: "&u32", |
397 | }, | 381 | }, |
398 | ]"# | 382 | ]"# |
@@ -425,7 +409,7 @@ fn main() { | |||
425 | while let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {}; | 409 | while let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {}; |
426 | while let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {}; | 410 | while let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {}; |
427 | while let CustomOption::Some(Test { b: y, .. }) = &test {}; | 411 | while let CustomOption::Some(Test { b: y, .. }) = &test {}; |
428 | 412 | ||
429 | while test == CustomOption::None {} | 413 | while test == CustomOption::None {} |
430 | }"#, | 414 | }"#, |
431 | ); | 415 | ); |
@@ -433,7 +417,7 @@ fn main() { | |||
433 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ | 417 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ |
434 | InlayHint { | 418 | InlayHint { |
435 | range: [166; 170), | 419 | range: [166; 170), |
436 | kind: LetBindingType, | 420 | kind: TypeHint, |
437 | label: "CustomOption<Test>", | 421 | label: "CustomOption<Test>", |
438 | }, | 422 | }, |
439 | ]"# | 423 | ]"# |
@@ -445,7 +429,7 @@ fn main() { | |||
445 | let (analysis, file_id) = single_file( | 429 | let (analysis, file_id) = single_file( |
446 | r#" | 430 | r#" |
447 | #[derive(PartialEq)] | 431 | #[derive(PartialEq)] |
448 | enum CustomOption<T> { | 432 | enum CustomOption<T> { |
449 | None, | 433 | None, |
450 | Some(T), | 434 | Some(T), |
451 | } | 435 | } |
@@ -473,23 +457,23 @@ fn main() { | |||
473 | 457 | ||
474 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ | 458 | assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ |
475 | InlayHint { | 459 | InlayHint { |
476 | range: [312; 316), | 460 | range: [311; 315), |
477 | kind: MatchArmType, | 461 | kind: TypeHint, |
478 | label: "Test", | 462 | label: "Test", |
479 | }, | 463 | }, |
480 | InlayHint { | 464 | InlayHint { |
481 | range: [359; 360), | 465 | range: [358; 359), |
482 | kind: MatchArmType, | 466 | kind: TypeHint, |
483 | label: "CustomOption<u32>", | 467 | label: "CustomOption<u32>", |
484 | }, | 468 | }, |
485 | InlayHint { | 469 | InlayHint { |
486 | range: [362; 363), | 470 | range: [361; 362), |
487 | kind: MatchArmType, | 471 | kind: TypeHint, |
488 | label: "u8", | 472 | label: "u8", |
489 | }, | 473 | }, |
490 | InlayHint { | 474 | InlayHint { |
491 | range: [485; 486), | 475 | range: [484; 485), |
492 | kind: MatchArmType, | 476 | kind: TypeHint, |
493 | label: "u32", | 477 | label: "u32", |
494 | }, | 478 | }, |
495 | ]"# | 479 | ]"# |