aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/inlay_hints.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/inlay_hints.rs')
-rw-r--r--crates/ide/src/inlay_hints.rs129
1 files changed, 127 insertions, 2 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 49d8e4ae1..ac704ae21 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -1,6 +1,6 @@
1use assists::utils::FamousDefs; 1use assists::utils::FamousDefs;
2use either::Either; 2use either::Either;
3use hir::{known, HirDisplay, Semantics}; 3use hir::{known, Callable, HirDisplay, Semantics};
4use ide_db::RootDatabase; 4use ide_db::RootDatabase;
5use stdx::to_lower_snake_case; 5use stdx::to_lower_snake_case;
6use syntax::{ 6use syntax::{
@@ -170,7 +170,7 @@ fn get_param_name_hints(
170 }; 170 };
171 Some((param_name, arg)) 171 Some((param_name, arg))
172 }) 172 })
173 .filter(|(param_name, arg)| should_show_param_name_hint(sema, &callable, &param_name, &arg)) 173 .filter(|(param_name, arg)| should_show_param_name_hint(sema, &callable, param_name, &arg))
174 .map(|(param_name, arg)| InlayHint { 174 .map(|(param_name, arg)| InlayHint {
175 range: arg.syntax().text_range(), 175 range: arg.syntax().text_range(),
176 kind: InlayKind::ParameterHint, 176 kind: InlayKind::ParameterHint,
@@ -334,9 +334,11 @@ fn should_show_param_name_hint(
334 | hir::CallableKind::TupleEnumVariant(_) 334 | hir::CallableKind::TupleEnumVariant(_)
335 | hir::CallableKind::Closure => None, 335 | hir::CallableKind::Closure => None,
336 }; 336 };
337
337 if param_name.is_empty() 338 if param_name.is_empty()
338 || Some(param_name) == fn_name.as_ref().map(|s| s.trim_start_matches('_')) 339 || Some(param_name) == fn_name.as_ref().map(|s| s.trim_start_matches('_'))
339 || is_argument_similar_to_param_name(sema, argument, param_name) 340 || is_argument_similar_to_param_name(sema, argument, param_name)
341 || is_param_name_similar_to_fn_name(param_name, callable, fn_name.as_ref())
340 || param_name.starts_with("ra_fixture") 342 || param_name.starts_with("ra_fixture")
341 { 343 {
342 return false; 344 return false;
@@ -364,6 +366,26 @@ fn is_argument_similar_to_param_name(
364 } 366 }
365} 367}
366 368
369fn is_param_name_similar_to_fn_name(
370 param_name: &str,
371 callable: &Callable,
372 fn_name: Option<&String>,
373) -> bool {
374 // if it's the only parameter, don't show it if:
375 // - is the same as the function name, or
376 // - the function ends with '_' + param_name
377
378 match (callable.n_params(), fn_name) {
379 (1, Some(function)) => {
380 function == param_name
381 || (function.len() > param_name.len()
382 && function.ends_with(param_name)
383 && function[..function.len() - param_name.len()].ends_with('_'))
384 }
385 _ => false,
386 }
387}
388
367fn is_enum_name_similar_to_param_name( 389fn is_enum_name_similar_to_param_name(
368 sema: &Semantics<RootDatabase>, 390 sema: &Semantics<RootDatabase>,
369 argument: &ast::Expr, 391 argument: &ast::Expr,
@@ -457,6 +479,88 @@ fn main() {
457 } 479 }
458 480
459 #[test] 481 #[test]
482 fn param_name_similar_to_fn_name_still_hints() {
483 check_with_config(
484 InlayHintsConfig {
485 parameter_hints: true,
486 type_hints: false,
487 chaining_hints: false,
488 max_length: None,
489 },
490 r#"
491fn max(x: i32, y: i32) -> i32 { x + y }
492fn main() {
493 let _x = max(
494 4,
495 //^ x
496 4,
497 //^ y
498 );
499}"#,
500 );
501 }
502
503 #[test]
504 fn param_name_similar_to_fn_name() {
505 check_with_config(
506 InlayHintsConfig {
507 parameter_hints: true,
508 type_hints: false,
509 chaining_hints: false,
510 max_length: None,
511 },
512 r#"
513fn param_with_underscore(with_underscore: i32) -> i32 { with_underscore }
514fn main() {
515 let _x = param_with_underscore(
516 4,
517 );
518}"#,
519 );
520 }
521
522 #[test]
523 fn param_name_same_as_fn_name() {
524 check_with_config(
525 InlayHintsConfig {
526 parameter_hints: true,
527 type_hints: false,
528 chaining_hints: false,
529 max_length: None,
530 },
531 r#"
532fn foo(foo: i32) -> i32 { foo }
533fn main() {
534 let _x = foo(
535 4,
536 );
537}"#,
538 );
539 }
540
541 #[test]
542 fn never_hide_param_when_multiple_params() {
543 check_with_config(
544 InlayHintsConfig {
545 parameter_hints: true,
546 type_hints: false,
547 chaining_hints: false,
548 max_length: None,
549 },
550 r#"
551fn foo(bar: i32, baz: i32) -> i32 { bar + baz }
552fn main() {
553 let _x = foo(
554 4,
555 //^ bar
556 8,
557 //^ baz
558 );
559}"#,
560 );
561 }
562
563 #[test]
460 fn hints_disabled() { 564 fn hints_disabled() {
461 check_with_config( 565 check_with_config(
462 InlayHintsConfig { 566 InlayHintsConfig {
@@ -1235,4 +1339,25 @@ fn main() {
1235"#, 1339"#,
1236 ); 1340 );
1237 } 1341 }
1342
1343 #[test]
1344 fn infer_call_method_return_associated_types_with_generic() {
1345 check(
1346 r#"
1347 pub trait Default {
1348 fn default() -> Self;
1349 }
1350 pub trait Foo {
1351 type Bar: Default;
1352 }
1353
1354 pub fn quux<T: Foo>() -> T::Bar {
1355 let y = Default::default();
1356 //^ <T as Foo>::Bar
1357
1358 y
1359 }
1360 "#,
1361 );
1362 }
1238} 1363}