diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index c326688ae6a..29259167419 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -90,32 +90,34 @@ pub enum AdjustmentHintsMode { PreferPostfix, } -// FIXME: Clean up this mess, the kinds are mainly used for setting different rendering properties in the lsp layer -// We should probably turns this into such a property holding struct. Or clean this up in some other form. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum InlayKind { + Adjustment, BindingMode, Chaining, ClosingBrace, - ClosureReturnType, - GenericParamList, - Adjustment, - AdjustmentPostfix, - Lifetime, ClosureCapture, + Discriminant, + GenericParamList, + Lifetime, Parameter, Type, - Discriminant, - OpeningParenthesis, - ClosingParenthesis, +} + +#[derive(Debug)] +pub enum InlayHintPosition { + Before, + After, } #[derive(Debug)] pub struct InlayHint { /// The text range this inlay hint applies to. pub range: TextRange, - /// The kind of this inlay hint. This is used to determine side and padding of the hint for - /// rendering purposes. + pub position: InlayHintPosition, + pub pad_left: bool, + pub pad_right: bool, + /// The kind of this inlay hint. pub kind: InlayKind, /// The actual label to show in the inlay hint. pub label: InlayHintLabel, @@ -124,20 +126,26 @@ pub struct InlayHint { } impl InlayHint { - fn closing_paren(range: TextRange) -> InlayHint { + fn closing_paren_after(kind: InlayKind, range: TextRange) -> InlayHint { InlayHint { range, - kind: InlayKind::ClosingParenthesis, + kind, label: InlayHintLabel::from(")"), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: false, } } - fn opening_paren(range: TextRange) -> InlayHint { + fn opening_paren_before(kind: InlayKind, range: TextRange) -> InlayHint { InlayHint { range, - kind: InlayKind::OpeningParenthesis, + kind, label: InlayHintLabel::from("("), text_edit: None, + position: InlayHintPosition::Before, + pad_left: false, + pad_right: false, } } } @@ -303,13 +311,13 @@ impl InlayHintLabelBuilder<'_> { fn label_of_ty( famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - ty: hir::Type, + ty: &hir::Type, ) -> Option { fn rec( sema: &Semantics<'_, RootDatabase>, famous_defs: &FamousDefs<'_, '_>, mut max_length: Option, - ty: hir::Type, + ty: &hir::Type, label_builder: &mut InlayHintLabelBuilder<'_>, config: &InlayHintsConfig, ) -> Result<(), HirDisplayError> { @@ -342,7 +350,7 @@ fn label_of_ty( label_builder.write_str(LABEL_ITEM)?; label_builder.end_location_link(); label_builder.write_str(LABEL_MIDDLE2)?; - rec(sema, famous_defs, max_length, ty, label_builder, config)?; + rec(sema, famous_defs, max_length, &ty, label_builder, config)?; label_builder.write_str(LABEL_END)?; Ok(()) } @@ -574,7 +582,8 @@ mod tests { let inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap(); let actual = inlay_hints .into_iter() - .map(|it| (it.range, it.label.to_string())) + // FIXME: We trim the start because some inlay produces leading whitespace which is not properly supported by our annotation extraction + .map(|it| (it.range, it.label.to_string().trim_start().to_owned())) .sorted_by_key(|(range, _)| range.start()) .collect::>(); expected.sort_by_key(|(range, _)| range.start()); diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs index 27e9ba3c36b..10bee2a6acc 100644 --- a/crates/ide/src/inlay_hints/adjustment.rs +++ b/crates/ide/src/inlay_hints/adjustment.rs @@ -3,6 +3,7 @@ //! let _: u32 = /* */ loop {}; //! let _: &u32 = /* &* */ &mut 0; //! ``` +use either::Either; use hir::{ Adjust, Adjustment, AutoBorrow, HirDisplay, Mutability, OverloadedDeref, PointerCast, Safety, Semantics, @@ -16,8 +17,8 @@ use syntax::{ }; use crate::{ - AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, - InlayTooltip, + AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintLabel, InlayHintPosition, + InlayHintsConfig, InlayKind, InlayTooltip, }; pub(super) fn hints( @@ -63,22 +64,26 @@ pub(super) fn hints( mode_and_needs_parens_for_adjustment_hints(expr, config.adjustment_hints_mode); if needs_outer_parens { - acc.push(InlayHint::opening_paren(expr.syntax().text_range())); + acc.push(InlayHint::opening_paren_before( + InlayKind::Adjustment, + expr.syntax().text_range(), + )); } if postfix && needs_inner_parens { - acc.push(InlayHint::opening_paren(expr.syntax().text_range())); - acc.push(InlayHint::closing_paren(expr.syntax().text_range())); + acc.push(InlayHint::opening_paren_before( + InlayKind::Adjustment, + expr.syntax().text_range(), + )); + acc.push(InlayHint::closing_paren_after(InlayKind::Adjustment, expr.syntax().text_range())); } - let (mut tmp0, mut tmp1); - let iter: &mut dyn Iterator = if postfix { - tmp0 = adjustments.into_iter(); - &mut tmp0 + let mut iter = if postfix { + Either::Left(adjustments.into_iter()) } else { - tmp1 = adjustments.into_iter().rev(); - &mut tmp1 + Either::Right(adjustments.into_iter().rev()) }; + let iter: &mut dyn Iterator = iter.as_mut().either(|it| it as _, |it| it as _); for Adjustment { source, target, kind } in iter { if source == target { @@ -134,7 +139,10 @@ pub(super) fn hints( }; acc.push(InlayHint { range: expr.syntax().text_range(), - kind: if postfix { InlayKind::AdjustmentPostfix } else { InlayKind::Adjustment }, + pad_left: false, + pad_right: false, + position: if postfix { InlayHintPosition::After } else { InlayHintPosition::Before }, + kind: InlayKind::Adjustment, label: InlayHintLabel::simple( if postfix { format!(".{}", text.trim_end()) } else { text.to_owned() }, Some(InlayTooltip::Markdown(format!( @@ -148,11 +156,14 @@ pub(super) fn hints( }); } if !postfix && needs_inner_parens { - acc.push(InlayHint::opening_paren(expr.syntax().text_range())); - acc.push(InlayHint::closing_paren(expr.syntax().text_range())); + acc.push(InlayHint::opening_paren_before( + InlayKind::Adjustment, + expr.syntax().text_range(), + )); + acc.push(InlayHint::closing_paren_after(InlayKind::Adjustment, expr.syntax().text_range())); } if needs_outer_parens { - acc.push(InlayHint::closing_paren(expr.syntax().text_range())); + acc.push(InlayHint::closing_paren_after(InlayKind::Adjustment, expr.syntax().text_range())); } Some(()) } diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs index 6991a66c7c2..f98cc129a93 100644 --- a/crates/ide/src/inlay_hints/bind_pat.rs +++ b/crates/ide/src/inlay_hints/bind_pat.rs @@ -14,7 +14,7 @@ use syntax::{ use crate::{ inlay_hints::{closure_has_block_body, label_of_ty, ty_to_text_edit}, - InlayHint, InlayHintsConfig, InlayKind, + InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, }; pub(super) fn hints( @@ -36,7 +36,7 @@ pub(super) fn hints( return None; } - let label = label_of_ty(famous_defs, config, ty.clone())?; + let mut label = label_of_ty(famous_defs, config, &ty)?; if config.hide_named_constructor_hints && is_named_constructor(sema, pat, &label.to_string()).is_some() @@ -44,31 +44,46 @@ pub(super) fn hints( return None; } - let type_annotation_is_valid = desc_pat - .syntax() - .parent() - .map(|it| ast::LetStmt::can_cast(it.kind()) || ast::Param::can_cast(it.kind())) - .unwrap_or(false); - let text_edit = if type_annotation_is_valid { + let type_ascriptable = desc_pat.syntax().parent().and_then(|it| { + ast::LetStmt::cast(it.clone()) + .map(|it| it.colon_token()) + .or_else(|| ast::Param::cast(it).map(|it| it.colon_token())) + }); + let text_edit = if let Some(colon_token) = &type_ascriptable { ty_to_text_edit( sema, desc_pat.syntax(), &ty, - pat.syntax().text_range().end(), - String::from(": "), + colon_token + .as_ref() + .map_or_else(|| pat.syntax().text_range(), |t| t.text_range()) + .end(), + if colon_token.is_some() { String::new() } else { String::from(": ") }, ) } else { None }; + let has_colon = matches!(type_ascriptable, Some(Some(_))) && !config.render_colons; + if !has_colon { + label.prepend_str(": "); + } + + let text_range = match pat.name() { + Some(name) => name.syntax().text_range(), + None => pat.syntax().text_range(), + }; acc.push(InlayHint { - range: match pat.name() { - Some(name) => name.syntax().text_range(), - None => pat.syntax().text_range(), + range: match type_ascriptable { + Some(Some(t)) => text_range.cover(t.text_range()), + _ => text_range, }, kind: InlayKind::Type, label, text_edit, + position: InlayHintPosition::Before, + pad_left: !has_colon, + pad_right: false, }); Some(()) @@ -218,7 +233,7 @@ mod tests { fn foo(a: i32, b: i32) -> i32 { a + b } fn main() { let _x = foo(4, 4); - //^^ i32 + //^^ : i32 }"#, ); } @@ -230,17 +245,17 @@ fn main() { //- minicore: option fn main() { let ref foo @ bar @ ref mut baz = 0; - //^^^ &i32 - //^^^ i32 - //^^^ &mut i32 + //^^^ : &i32 + //^^^ : i32 + //^^^ : &mut i32 let [x @ ..] = [0]; - //^ [i32; 1] + //^ : [i32; 1] if let x @ Some(_) = Some(0) {} - //^ Option + //^ : Option let foo @ (bar, baz) = (3, 3); - //^^^ (i32, i32) - //^^^ i32 - //^^^ i32 + //^^^ : (i32, i32) + //^^^ : i32 + //^^^ : i32 }"#, ); } @@ -253,11 +268,11 @@ struct Test { k: K, t: T } fn main() { let zz = Test { t: 23u8, k: 33 }; - //^^ Test + //^^ : Test let zz_ref = &zz; - //^^^^^^ &Test + //^^^^^^ : &Test let test = || zz; - //^^^^ impl FnOnce() -> Test + //^^^^ : impl FnOnce() -> Test }"#, ); } @@ -285,10 +300,10 @@ impl Iterator for SomeIter { fn main() { let mut some_iter = SomeIter::new(); - //^^^^^^^^^ SomeIter>> + //^^^^^^^^^ : SomeIter>> some_iter.push(iter::repeat(2).take(2)); let iter_of_iters = some_iter.take(2); - //^^^^^^^^^^^^^ impl Iterator> + //^^^^^^^^^^^^^ : impl Iterator> } "#, ); @@ -347,7 +362,7 @@ fn main(a: SliceIter<'_, Container>) { pub fn quux() -> T::Bar { let y = Default::default(); - //^ ::Bar + //^ : ::Bar y } @@ -371,21 +386,21 @@ fn foo7() -> *const (impl Fn(f64, f64) -> u32 + Sized) { loop {} } fn main() { let foo = foo(); - // ^^^ impl Fn() + // ^^^ : impl Fn() let foo = foo1(); - // ^^^ impl Fn(f64) + // ^^^ : impl Fn(f64) let foo = foo2(); - // ^^^ impl Fn(f64, f64) + // ^^^ : impl Fn(f64, f64) let foo = foo3(); - // ^^^ impl Fn(f64, f64) -> u32 + // ^^^ : impl Fn(f64, f64) -> u32 let foo = foo4(); - // ^^^ &dyn Fn(f64, f64) -> u32 + // ^^^ : &dyn Fn(f64, f64) -> u32 let foo = foo5(); - // ^^^ &dyn Fn(&dyn Fn(f64, f64) -> u32, f64) -> u32 + // ^^^ : &dyn Fn(&dyn Fn(f64, f64) -> u32, f64) -> u32 let foo = foo6(); - // ^^^ impl Fn(f64, f64) -> u32 + // ^^^ : impl Fn(f64, f64) -> u32 let foo = foo7(); - // ^^^ *const impl Fn(f64, f64) -> u32 + // ^^^ : *const impl Fn(f64, f64) -> u32 } "#, ) @@ -408,9 +423,9 @@ fn main() { let foo = foo(); let foo = foo1(); let foo = foo2(); - // ^^^ impl Fn(f64, f64) + // ^^^ : impl Fn(f64, f64) let foo = foo3(); - // ^^^ impl Fn(f64, f64) -> u32 + // ^^^ : impl Fn(f64, f64) -> u32 let foo = foo4(); let foo = foo5(); let foo = foo6(); @@ -451,25 +466,25 @@ fn foo10() -> *const (impl Fn() + Sized + ?Sized) { loop {} } fn main() { let foo = foo1(); - // ^^^ *const impl Fn() + // ^^^ : *const impl Fn() let foo = foo2(); - // ^^^ *const impl Fn() + // ^^^ : *const impl Fn() let foo = foo3(); - // ^^^ *const (impl Fn() + ?Sized) + // ^^^ : *const (impl Fn() + ?Sized) let foo = foo4(); - // ^^^ *const impl Fn() + // ^^^ : *const impl Fn() let foo = foo5(); - // ^^^ *const (impl Fn() + ?Sized) + // ^^^ : *const (impl Fn() + ?Sized) let foo = foo6(); - // ^^^ *const (impl Fn() + Trait) + // ^^^ : *const (impl Fn() + Trait) let foo = foo7(); - // ^^^ *const (impl Fn() + Trait) + // ^^^ : *const (impl Fn() + Trait) let foo = foo8(); - // ^^^ *const (impl Fn() + Trait + ?Sized) + // ^^^ : *const (impl Fn() + Trait + ?Sized) let foo = foo9(); - // ^^^ *const (impl Fn() -> u8 + ?Sized) + // ^^^ : *const (impl Fn() -> u8 + ?Sized) let foo = foo10(); - // ^^^ *const impl Fn() + // ^^^ : *const impl Fn() } "#, ) @@ -520,24 +535,24 @@ fn main() { struct InnerStruct {} let test = 54; - //^^^^ i32 + //^^^^ : i32 let test: i32 = 33; let mut test = 33; - //^^^^ i32 + //^^^^ : i32 let _ = 22; let test = "test"; - //^^^^ &str + //^^^^ : &str let test = InnerStruct {}; - //^^^^ InnerStruct + //^^^^ : InnerStruct let test = unresolved(); let test = (42, 'a'); - //^^^^ (i32, char) - let (a, (b, (c,)) = (2, (3, (9.2,)); - //^ i32 ^ i32 ^ f64 + //^^^^ : (i32, char) + let (a, (b, (c,)) = (2, (3, (9.2,)); + //^ : i32 ^ : i32 ^ : f64 let &x = &92; - //^ i32 + //^ : i32 }"#, ); } @@ -551,22 +566,22 @@ struct Test { a: Option, b: u8 } fn main() { let test = Some(Test { a: Some(3), b: 1 }); - //^^^^ Option + //^^^^ : Option if let None = &test {}; if let test = &test {}; - //^^^^ &Option + //^^^^ : &Option if let Some(test) = &test {}; - //^^^^ &Test - if let Some(Test { a, b }) = &test {}; - //^ &Option ^ &u8 - if let Some(Test { a: x, b: y }) = &test {}; - //^ &Option ^ &u8 - if let Some(Test { a: Some(x), b: y }) = &test {}; - //^ &u32 ^ &u8 + //^^^^ : &Test + if let Some(Test { a, b }) = &test {}; + //^ : &Option ^ : &u8 + if let Some(Test { a: x, b: y }) = &test {}; + //^ : &Option ^ : &u8 + if let Some(Test { a: Some(x), b: y }) = &test {}; + //^ : &u32 ^ : &u8 if let Some(Test { a: None, b: y }) = &test {}; - //^ &u8 + //^ : &u8 if let Some(Test { b: y, .. }) = &test {}; - //^ &u8 + //^ : &u8 if test == None {} }"#, ); @@ -581,9 +596,9 @@ struct Test { a: Option, b: u8 } fn main() { let test = Some(Test { a: Some(3), b: 1 }); - //^^^^ Option - while let Some(Test { a: Some(x), b: y }) = &test {}; - //^ &u32 ^ &u8 + //^^^^ : Option + while let Some(Test { a: Some(x), b: y }) = &test {}; + //^ : &u32 ^ : &u8 }"#, ); } @@ -599,9 +614,9 @@ fn main() { match Some(Test { a: Some(3), b: 1 }) { None => (), test => (), - //^^^^ Option - Some(Test { a: Some(x), b: y }) => (), - //^ u32 ^ u8 + //^^^^ : Option + Some(Test { a: Some(x), b: y }) => (), + //^ : u32 ^ : u8 _ => {} } }"#, @@ -633,12 +648,12 @@ impl Iterator for IntoIter { fn main() { let mut data = Vec::new(); - //^^^^ Vec<&str> + //^^^^ : Vec<&str> data.push("foo"); for i in data { - //^ &str + //^ : &str let z = i; - //^ &str + //^ : &str } } "#, @@ -663,11 +678,11 @@ auto trait Sync {} fn main() { // The block expression wrapping disables the constructor hint hiding logic let _v = { Vec::>::new() }; - //^^ Vec> + //^^ : Vec> let _v = { Vec::>::new() }; - //^^ Vec> + //^^ : Vec> let _v = { Vec::>::new() }; - //^^ Vec> + //^^ : Vec> } "#, ); @@ -691,14 +706,14 @@ impl Iterator for MyIter { fn main() { let _x = MyIter; - //^^ MyIter + //^^ : MyIter let _x = iter::repeat(0); - //^^ impl Iterator + //^^ : impl Iterator fn generic(t: T) { let _x = iter::repeat(t); - //^^ impl Iterator + //^^ : impl Iterator let _chained = iter::repeat(t).take(10); - //^^^^^^^^ impl Iterator + //^^^^^^^^ : impl Iterator } } "#, @@ -762,20 +777,20 @@ fn main() { let tuple_struct = TupleStruct(); let generic0 = Generic::new(); - // ^^^^^^^^ Generic + // ^^^^^^^^ : Generic let generic1 = Generic(0); - // ^^^^^^^^ Generic + // ^^^^^^^^ : Generic let generic2 = Generic::::new(); let generic3 = >::new(); let generic4 = Generic::(0); let option = Some(0); - // ^^^^^^ Option + // ^^^^^^ : Option let func = times2; - // ^^^^ fn times2(i32) -> i32 + // ^^^^ : fn times2(i32) -> i32 let closure = |x: i32| x * 2; - // ^^^^^^^ impl Fn(i32) -> i32 + // ^^^^^^^ : impl Fn(i32) -> i32 } fn fallible() -> ControlFlow<()> { @@ -813,72 +828,25 @@ impl Generic { fn main() { let strukt = Struct::new(); - // ^^^^^^ Struct + // ^^^^^^ : Struct let tuple_struct = TupleStruct(); - // ^^^^^^^^^^^^ TupleStruct + // ^^^^^^^^^^^^ : TupleStruct let generic0 = Generic::new(); - // ^^^^^^^^ Generic + // ^^^^^^^^ : Generic let generic1 = Generic::::new(); - // ^^^^^^^^ Generic + // ^^^^^^^^ : Generic let generic2 = >::new(); - // ^^^^^^^^ Generic + // ^^^^^^^^ : Generic } fn fallible() -> ControlFlow<()> { let strukt = Struct::try_new()?; - // ^^^^^^ Struct + // ^^^^^^ : Struct } "#, ); } - #[test] - fn closures() { - check( - r#" -fn main() { - let mut start = 0; - //^^^^^ i32 - (0..2).for_each(|increment | { start += increment; }); - //^^^^^^^^^ i32 - - let multiply = - //^^^^^^^^ impl Fn(i32, i32) -> i32 - | a, b| a * b - //^ i32 ^ i32 - - ; - - let _: i32 = multiply(1, 2); - //^ a ^ b - let multiply_ref = &multiply; - //^^^^^^^^^^^^ &impl Fn(i32, i32) -> i32 - - let return_42 = || 42; - //^^^^^^^^^ impl Fn() -> i32 - || { 42 }; - //^^ i32 -}"#, - ); - } - - #[test] - fn return_type_hints_for_closure_without_block() { - check_with_config( - InlayHintsConfig { - closure_return_type_hints: ClosureReturnTypeHints::Always, - ..DISABLED_CONFIG - }, - r#" -fn main() { - let a = || { 0 }; - //^^ i32 - let b = || 0; - //^^ i32 -}"#, - ); - } - #[test] fn closure_style() { check_with_config( @@ -887,15 +855,15 @@ fn main() { //- minicore: fn fn main() { let x = || 2; - //^ impl Fn() -> i32 + //^ : impl Fn() -> i32 let y = |t: i32| x() + t; - //^ impl Fn(i32) -> i32 + //^ : impl Fn(i32) -> i32 let mut t = 5; - //^ i32 + //^ : i32 let z = |k: i32| { t += k; }; - //^ impl FnMut(i32) + //^ : impl FnMut(i32) let p = (y, z); - //^ (impl Fn(i32) -> i32, impl FnMut(i32)) + //^ : (impl Fn(i32) -> i32, impl FnMut(i32)) } "#, ); @@ -909,15 +877,15 @@ fn main() { //- minicore: fn fn main() { let x = || 2; - //^ || -> i32 + //^ : || -> i32 let y = |t: i32| x() + t; - //^ |i32| -> i32 + //^ : |i32| -> i32 let mut t = 5; - //^ i32 + //^ : i32 let z = |k: i32| { t += k; }; - //^ |i32| -> () + //^ : |i32| -> () let p = (y, z); - //^ (|i32| -> i32, |i32| -> ()) + //^ : (|i32| -> i32, |i32| -> ()) } "#, ); @@ -931,15 +899,15 @@ fn main() { //- minicore: fn fn main() { let x = || 2; - //^ {closure#0} + //^ : {closure#0} let y = |t: i32| x() + t; - //^ {closure#1} + //^ : {closure#1} let mut t = 5; - //^ i32 + //^ : i32 let z = |k: i32| { t += k; }; - //^ {closure#2} + //^ : {closure#2} let p = (y, z); - //^ ({closure#1}, {closure#2}) + //^ : ({closure#1}, {closure#2}) } "#, ); @@ -953,15 +921,15 @@ fn main() { //- minicore: fn fn main() { let x = || 2; - //^ … + //^ : … let y = |t: i32| x() + t; - //^ … + //^ : … let mut t = 5; - //^ i32 + //^ : i32 let z = |k: i32| { t += k; }; - //^ … + //^ : … let p = (y, z); - //^ (…, …) + //^ : (…, …) } "#, ); @@ -981,24 +949,24 @@ fn main() { let multiple_2 = |x: i32| { x * 2 }; let multiple_2 = |x: i32| x * 2; - // ^^^^^^^^^^ impl Fn(i32) -> i32 + // ^^^^^^^^^^ : impl Fn(i32) -> i32 let (not) = (|x: bool| { !x }); - // ^^^ impl Fn(bool) -> bool + // ^^^ : impl Fn(bool) -> bool let (is_zero, _b) = (|x: usize| { x == 0 }, false); - // ^^^^^^^ impl Fn(usize) -> bool - // ^^ bool + // ^^^^^^^ : impl Fn(usize) -> bool + // ^^ : bool let plus_one = |x| { x + 1 }; - // ^ u8 + // ^ : u8 foo(plus_one); let add_mul = bar(|x: u8| { x + 1 }); - // ^^^^^^^ impl FnOnce(u8) -> u8 + ?Sized + // ^^^^^^^ : impl FnOnce(u8) -> u8 + ?Sized let closure = if let Some(6) = add_mul(2).checked_sub(1) { - // ^^^^^^^ fn(i32) -> i32 + // ^^^^^^^ : fn(i32) -> i32 |x: i32| { x * 2 } } else { |x: i32| { x * 3 } @@ -1025,11 +993,11 @@ struct VeryLongOuterName(T); fn main() { let a = Smol(0u32); - //^ Smol + //^ : Smol let b = VeryLongOuterName(0usize); - //^ VeryLongOuterName<…> + //^ : VeryLongOuterName<…> let c = Smol(Smol(0u32)) - //^ Smol> + //^ : Smol> }"#, ); } diff --git a/crates/ide/src/inlay_hints/binding_mode.rs b/crates/ide/src/inlay_hints/binding_mode.rs index dada4dd0485..343cf17e50e 100644 --- a/crates/ide/src/inlay_hints/binding_mode.rs +++ b/crates/ide/src/inlay_hints/binding_mode.rs @@ -7,7 +7,7 @@ use ide_db::RootDatabase; use syntax::ast::{self, AstNode}; -use crate::{InlayHint, InlayHintsConfig, InlayKind}; +use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind}; pub(super) fn hints( acc: &mut Vec, @@ -54,6 +54,9 @@ pub(super) fn hints( kind: InlayKind::BindingMode, label: r.to_string().into(), text_edit: None, + position: InlayHintPosition::Before, + pad_left: false, + pad_right: mut_reference, }); }); match pat { @@ -69,11 +72,20 @@ pub(super) fn hints( kind: InlayKind::BindingMode, label: bm.to_string().into(), text_edit: None, + position: InlayHintPosition::Before, + pad_left: false, + pad_right: true, }); } ast::Pat::OrPat(pat) if !pattern_adjustments.is_empty() && outer_paren_pat.is_none() => { - acc.push(InlayHint::opening_paren(pat.syntax().text_range())); - acc.push(InlayHint::closing_paren(pat.syntax().text_range())); + acc.push(InlayHint::opening_paren_before( + InlayKind::BindingMode, + pat.syntax().text_range(), + )); + acc.push(InlayHint::closing_paren_after( + InlayKind::BindingMode, + pat.syntax().text_range(), + )); } _ => (), } diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs index d8c8401af77..cd1ac1e55e8 100644 --- a/crates/ide/src/inlay_hints/chaining.rs +++ b/crates/ide/src/inlay_hints/chaining.rs @@ -5,7 +5,7 @@ use syntax::{ Direction, NodeOrToken, SyntaxKind, T, }; -use crate::{FileId, InlayHint, InlayHintsConfig, InlayKind}; +use crate::{FileId, InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind}; use super::label_of_ty; @@ -60,8 +60,11 @@ pub(super) fn hints( acc.push(InlayHint { range: expr.syntax().text_range(), kind: InlayKind::Chaining, - label: label_of_ty(famous_defs, config, ty)?, + label: label_of_ty(famous_defs, config, &ty)?, text_edit: None, + position: InlayHintPosition::After, + pad_left: true, + pad_right: false, }); } } @@ -104,6 +107,9 @@ fn main() { [ InlayHint { range: 147..172, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -125,6 +131,9 @@ fn main() { }, InlayHint { range: 147..154, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -191,6 +200,9 @@ fn main() { [ InlayHint { range: 143..190, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -212,6 +224,9 @@ fn main() { }, InlayHint { range: 143..179, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -262,6 +277,9 @@ fn main() { [ InlayHint { range: 143..190, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -283,6 +301,9 @@ fn main() { }, InlayHint { range: 143..179, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -334,6 +355,9 @@ fn main() { [ InlayHint { range: 246..283, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -368,6 +392,9 @@ fn main() { }, InlayHint { range: 246..265, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -434,6 +461,9 @@ fn main() { [ InlayHint { range: 174..241, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "impl ", @@ -468,6 +498,9 @@ fn main() { }, InlayHint { range: 174..224, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "impl ", @@ -502,6 +535,9 @@ fn main() { }, InlayHint { range: 174..206, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "impl ", @@ -536,6 +572,9 @@ fn main() { }, InlayHint { range: 174..189, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "&mut ", @@ -586,9 +625,12 @@ fn main() { [ InlayHint { range: 124..130, + position: Before, + pad_left: true, + pad_right: false, kind: Type, label: [ - "", + ": ", InlayHintLabelPart { text: "Struct", linked_location: Some( @@ -616,6 +658,9 @@ fn main() { }, InlayHint { range: 145..185, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -637,6 +682,9 @@ fn main() { }, InlayHint { range: 145..168, + position: After, + pad_left: true, + pad_right: false, kind: Chaining, label: [ "", @@ -658,6 +706,9 @@ fn main() { }, InlayHint { range: 222..228, + position: Before, + pad_left: false, + pad_right: true, kind: Parameter, label: [ InlayHintLabelPart { diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs index 10b5acd064e..cd5a815abb0 100644 --- a/crates/ide/src/inlay_hints/closing_brace.rs +++ b/crates/ide/src/inlay_hints/closing_brace.rs @@ -10,7 +10,7 @@ use syntax::{ match_ast, SyntaxKind, SyntaxNode, T, }; -use crate::{FileId, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind}; +use crate::{FileId, InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; pub(super) fn hints( acc: &mut Vec, @@ -113,6 +113,9 @@ pub(super) fn hints( kind: InlayKind::ClosingBrace, label: InlayHintLabel::simple(label, None, linked_location), text_edit: None, + position: InlayHintPosition::After, + pad_left: true, + pad_right: false, }); None diff --git a/crates/ide/src/inlay_hints/closure_captures.rs b/crates/ide/src/inlay_hints/closure_captures.rs index 60c4fe411f4..3ee118f6e8c 100644 --- a/crates/ide/src/inlay_hints/closure_captures.rs +++ b/crates/ide/src/inlay_hints/closure_captures.rs @@ -5,7 +5,7 @@ use ide_db::{base_db::FileId, famous_defs::FamousDefs}; use syntax::ast::{self, AstNode}; use text_edit::{TextRange, TextSize}; -use crate::{InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind}; +use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; pub(super) fn hints( acc: &mut Vec, @@ -35,6 +35,9 @@ pub(super) fn hints( kind: InlayKind::ClosureCapture, label: InlayHintLabel::simple("move", None, None), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: false, }); range } @@ -44,6 +47,9 @@ pub(super) fn hints( kind: InlayKind::ClosureCapture, label: InlayHintLabel::from("("), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: false, }); let last = captures.len() - 1; for (idx, capture) in captures.into_iter().enumerate() { @@ -71,6 +77,9 @@ pub(super) fn hints( source.name().and_then(|name| sema.original_range_opt(name.syntax())), ), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: false, }); if idx != last { @@ -79,6 +88,9 @@ pub(super) fn hints( kind: InlayKind::ClosureCapture, label: InlayHintLabel::simple(", ", None, None), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: false, }); } } @@ -87,6 +99,9 @@ pub(super) fn hints( kind: InlayKind::ClosureCapture, label: InlayHintLabel::from(")"), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: true, }); Some(()) diff --git a/crates/ide/src/inlay_hints/closure_ret.rs b/crates/ide/src/inlay_hints/closure_ret.rs index 6214e9c8e7f..3b41db0f13d 100644 --- a/crates/ide/src/inlay_hints/closure_ret.rs +++ b/crates/ide/src/inlay_hints/closure_ret.rs @@ -6,7 +6,7 @@ use syntax::ast::{self, AstNode}; use crate::{ inlay_hints::{closure_has_block_body, label_of_ty, ty_to_text_edit}, - ClosureReturnTypeHints, InlayHint, InlayHintsConfig, InlayKind, + ClosureReturnTypeHints, InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, }; pub(super) fn hints( @@ -20,9 +20,12 @@ pub(super) fn hints( return None; } - if closure.ret_type().is_some() { - return None; - } + let ret_type = closure.ret_type().map(|rt| (rt.thin_arrow_token(), rt.ty().is_some())); + let arrow = match ret_type { + Some((_, true)) => return None, + Some((arrow, _)) => arrow, + None => None, + }; let has_block_body = closure_has_block_body(&closure); if !has_block_body && config.closure_return_type_hints == ClosureReturnTypeHints::WithBlock { @@ -35,18 +38,26 @@ pub(super) fn hints( let ty = sema.type_of_expr(&ast::Expr::ClosureExpr(closure.clone()))?.adjusted(); let callable = ty.as_callable(sema.db)?; let ty = callable.return_type(); - if ty.is_unit() { + if arrow.is_none() && ty.is_unit() { return None; } + let mut label = label_of_ty(famous_defs, config, &ty)?; + + if arrow.is_none() { + label.prepend_str(" -> "); + } // FIXME?: We could provide text edit to insert braces for closures with non-block body. let text_edit = if has_block_body { ty_to_text_edit( sema, closure.syntax(), &ty, - param_list.syntax().text_range().end(), - String::from(" -> "), + arrow + .as_ref() + .map_or_else(|| param_list.syntax().text_range(), |t| t.text_range()) + .end(), + if arrow.is_none() { String::from(" -> ") } else { String::new() }, ) } else { None @@ -54,9 +65,36 @@ pub(super) fn hints( acc.push(InlayHint { range: param_list.syntax().text_range(), - kind: InlayKind::ClosureReturnType, - label: label_of_ty(famous_defs, config, ty)?, + kind: InlayKind::Type, + label, text_edit, + position: InlayHintPosition::After, + pad_left: false, + pad_right: false, }); Some(()) } + +#[cfg(test)] +mod tests { + use crate::inlay_hints::tests::{check_with_config, DISABLED_CONFIG}; + + use super::*; + + #[test] + fn return_type_hints_for_closure_without_block() { + check_with_config( + InlayHintsConfig { + closure_return_type_hints: ClosureReturnTypeHints::Always, + ..DISABLED_CONFIG + }, + r#" +fn main() { + let a = || { 0 }; + //^^ -> i32 + let b = || 0; + //^^ -> i32 +}"#, + ); + } +} diff --git a/crates/ide/src/inlay_hints/discriminant.rs b/crates/ide/src/inlay_hints/discriminant.rs index f9047efaf1a..9bff98f6110 100644 --- a/crates/ide/src/inlay_hints/discriminant.rs +++ b/crates/ide/src/inlay_hints/discriminant.rs @@ -9,7 +9,8 @@ use ide_db::{base_db::FileId, famous_defs::FamousDefs, RootDatabase}; use syntax::ast::{self, AstNode, HasName}; use crate::{ - DiscriminantHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, InlayTooltip, + DiscriminantHints, InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind, + InlayTooltip, }; pub(super) fn enum_hints( @@ -41,10 +42,11 @@ fn variant_hints( sema: &Semantics<'_, RootDatabase>, variant: &ast::Variant, ) -> Option<()> { - if variant.eq_token().is_some() { + if variant.expr().is_some() { return None; } + let eq_token = variant.eq_token(); let name = variant.name()?; let descended = sema.descend_node_into_attributes(variant.clone()).pop(); @@ -52,30 +54,39 @@ fn variant_hints( let v = sema.to_def(desc_pat)?; let d = v.eval(sema.db); + let range = match variant.field_list() { + Some(field_list) => name.syntax().text_range().cover(field_list.syntax().text_range()), + None => name.syntax().text_range(), + }; + let eq_ = if eq_token.is_none() { " =" } else { "" }; + let label = InlayHintLabel::simple( + match d { + Ok(x) => { + if x >= 10 { + format!("{eq_} {x} ({x:#X})") + } else { + format!("{eq_} {x}") + } + } + Err(_) => format!("{eq_} ?"), + }, + Some(InlayTooltip::String(match &d { + Ok(_) => "enum variant discriminant".into(), + Err(e) => format!("{e:?}").into(), + })), + None, + ); acc.push(InlayHint { - range: match variant.field_list() { - Some(field_list) => name.syntax().text_range().cover(field_list.syntax().text_range()), - None => name.syntax().text_range(), + range: match eq_token { + Some(t) => range.cover(t.text_range()), + _ => range, }, kind: InlayKind::Discriminant, - label: InlayHintLabel::simple( - match d { - Ok(x) => { - if x >= 10 { - format!("{x} ({x:#X})") - } else { - format!("{x}") - } - } - Err(_) => "?".into(), - }, - Some(InlayTooltip::String(match &d { - Ok(_) => "enum variant discriminant".into(), - Err(e) => format!("{e:?}").into(), - })), - None, - ), + label, text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: false, }); Some(()) @@ -113,14 +124,14 @@ mod tests { r#" enum Enum { Variant, -//^^^^^^^0 +//^^^^^^^ = 0$ Variant1, -//^^^^^^^^1 +//^^^^^^^^ = 1$ Variant2, -//^^^^^^^^2 +//^^^^^^^^ = 2$ Variant5 = 5, Variant6, -//^^^^^^^^6 +//^^^^^^^^ = 6$ } "#, ); @@ -128,14 +139,14 @@ enum Enum { r#" enum Enum { Variant, -//^^^^^^^0 +//^^^^^^^ = 0 Variant1, -//^^^^^^^^1 +//^^^^^^^^ = 1 Variant2, -//^^^^^^^^2 +//^^^^^^^^ = 2 Variant5 = 5, Variant6, -//^^^^^^^^6 +//^^^^^^^^ = 6 } "#, ); @@ -147,16 +158,16 @@ enum Enum { r#" enum Enum { Variant(), - //^^^^^^^^^0 + //^^^^^^^^^ = 0 Variant1, - //^^^^^^^^1 + //^^^^^^^^ = 1 Variant2 {}, - //^^^^^^^^^^^2 + //^^^^^^^^^^^ = 2 Variant3, - //^^^^^^^^3 + //^^^^^^^^ = 3 Variant5 = 5, Variant6, - //^^^^^^^^6 + //^^^^^^^^ = 6 } "#, ); @@ -180,16 +191,16 @@ enum Enum { r#" enum Enum { Variant(), - //^^^^^^^^^0 + //^^^^^^^^^ = 0 Variant1, - //^^^^^^^^1 + //^^^^^^^^ = 1 Variant2 {}, - //^^^^^^^^^^^2 + //^^^^^^^^^^^ = 2 Variant3, - //^^^^^^^^3 + //^^^^^^^^ = 3 Variant5 = 5, Variant6, - //^^^^^^^^6 + //^^^^^^^^ = 6 } "#, ); diff --git a/crates/ide/src/inlay_hints/fn_lifetime_fn.rs b/crates/ide/src/inlay_hints/fn_lifetime_fn.rs index 34eb5eb94c4..5fce11b785a 100644 --- a/crates/ide/src/inlay_hints/fn_lifetime_fn.rs +++ b/crates/ide/src/inlay_hints/fn_lifetime_fn.rs @@ -10,7 +10,7 @@ use syntax::{ SyntaxToken, }; -use crate::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints}; +use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, LifetimeElisionHints}; pub(super) fn hints( acc: &mut Vec, @@ -26,6 +26,9 @@ pub(super) fn hints( kind: InlayKind::Lifetime, label: label.into(), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: true, }; let param_list = func.param_list()?; @@ -191,6 +194,9 @@ pub(super) fn hints( ) .into(), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: true, }); } (None, allocated_lifetimes) => acc.push(InlayHint { @@ -198,6 +204,9 @@ pub(super) fn hints( kind: InlayKind::GenericParamList, label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: false, }), } Some(()) diff --git a/crates/ide/src/inlay_hints/implicit_static.rs b/crates/ide/src/inlay_hints/implicit_static.rs index ba875649f79..fc297a8d824 100644 --- a/crates/ide/src/inlay_hints/implicit_static.rs +++ b/crates/ide/src/inlay_hints/implicit_static.rs @@ -8,7 +8,7 @@ use syntax::{ SyntaxKind, }; -use crate::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints}; +use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, LifetimeElisionHints}; pub(super) fn hints( acc: &mut Vec, @@ -35,6 +35,9 @@ pub(super) fn hints( kind: InlayKind::Lifetime, label: "'static".to_owned().into(), text_edit: None, + position: InlayHintPosition::After, + pad_left: false, + pad_right: true, }); } } diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs index 9729a43c220..c4f43f41175 100644 --- a/crates/ide/src/inlay_hints/param_name.rs +++ b/crates/ide/src/inlay_hints/param_name.rs @@ -10,7 +10,7 @@ use ide_db::{base_db::FileRange, RootDatabase}; use stdx::to_lower_snake_case; use syntax::ast::{self, AstNode, HasArgList, HasName, UnaryOp}; -use crate::{InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind}; +use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; pub(super) fn hints( acc: &mut Vec, @@ -31,16 +31,16 @@ pub(super) fn hints( // Only annotate hints for expressions that exist in the original file let range = sema.original_range_opt(arg.syntax())?; let (param_name, name_syntax) = match param.as_ref()? { - Either::Left(pat) => ("self".to_string(), pat.name()), + Either::Left(pat) => (pat.name()?, pat.name()), Either::Right(pat) => match pat { - ast::Pat::IdentPat(it) => (it.name()?.to_string(), it.name()), + ast::Pat::IdentPat(it) => (it.name()?, it.name()), _ => return None, }, }; Some((name_syntax, param_name, arg, range)) }) .filter(|(_, param_name, arg, _)| { - !should_hide_param_name_hint(sema, &callable, param_name, arg) + !should_hide_param_name_hint(sema, &callable, ¶m_name.text(), arg) }) .map(|(param, param_name, _, FileRange { range, .. })| { let mut linked_location = None; @@ -53,11 +53,17 @@ pub(super) fn hints( } } + let colon = if config.render_colons { ":" } else { "" }; + let label = + InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location); InlayHint { range, kind: InlayKind::Parameter, - label: InlayHintLabel::simple(param_name, None, linked_location), + label, text_edit: None, + position: InlayHintPosition::Before, + pad_left: false, + pad_right: true, } }); diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index b84d5df8107..72d20af6637 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -87,8 +87,8 @@ pub use crate::{ hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult}, inlay_hints::{ AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints, InlayHint, - InlayHintLabel, InlayHintLabelPart, InlayHintsConfig, InlayKind, InlayTooltip, - LifetimeElisionHints, + InlayHintLabel, InlayHintLabelPart, InlayHintPosition, InlayHintsConfig, InlayKind, + InlayTooltip, LifetimeElisionHints, }, join_lines::JoinLinesConfig, markup::Markup, diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 9e9dfaaf5a3..96629b90ef5 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -1349,9 +1349,7 @@ pub(crate) fn handle_inlay_hints( snap.analysis .inlay_hints(&inlay_hints_config, file_id, Some(range))? .into_iter() - .map(|it| { - to_proto::inlay_hint(&snap, &line_index, inlay_hints_config.render_colons, it) - }) + .map(|it| to_proto::inlay_hint(&snap, &line_index, it)) .collect::>>()?, )) } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 1b7fd558906..521b7a76279 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -434,87 +434,21 @@ pub(crate) fn signature_help( pub(crate) fn inlay_hint( snap: &GlobalStateSnapshot, line_index: &LineIndex, - render_colons: bool, - mut inlay_hint: InlayHint, + inlay_hint: InlayHint, ) -> Cancellable { - match inlay_hint.kind { - InlayKind::Parameter if render_colons => inlay_hint.label.append_str(":"), - InlayKind::Type if render_colons => inlay_hint.label.prepend_str(": "), - InlayKind::ClosureReturnType => inlay_hint.label.prepend_str(" -> "), - InlayKind::Discriminant => inlay_hint.label.prepend_str(" = "), - _ => {} - } - let (label, tooltip) = inlay_hint_label(snap, inlay_hint.label)?; Ok(lsp_types::InlayHint { - position: match inlay_hint.kind { - // before annotated thing - InlayKind::OpeningParenthesis - | InlayKind::Parameter - | InlayKind::Adjustment - | InlayKind::BindingMode => position(line_index, inlay_hint.range.start()), - // after annotated thing - InlayKind::ClosureReturnType - | InlayKind::ClosureCapture - | InlayKind::Type - | InlayKind::Discriminant - | InlayKind::Chaining - | InlayKind::GenericParamList - | InlayKind::ClosingParenthesis - | InlayKind::AdjustmentPostfix - | InlayKind::Lifetime - | InlayKind::ClosingBrace => position(line_index, inlay_hint.range.end()), + position: match inlay_hint.position { + ide::InlayHintPosition::Before => position(line_index, inlay_hint.range.start()), + ide::InlayHintPosition::After => position(line_index, inlay_hint.range.end()), }, - padding_left: Some(match inlay_hint.kind { - InlayKind::Type => !render_colons, - InlayKind::Chaining | InlayKind::ClosingBrace => true, - InlayKind::ClosingParenthesis - | InlayKind::ClosureCapture - | InlayKind::Discriminant - | InlayKind::OpeningParenthesis - | InlayKind::BindingMode - | InlayKind::ClosureReturnType - | InlayKind::GenericParamList - | InlayKind::Adjustment - | InlayKind::AdjustmentPostfix - | InlayKind::Lifetime - | InlayKind::Parameter => false, - }), - padding_right: Some(match inlay_hint.kind { - InlayKind::ClosingParenthesis - | InlayKind::OpeningParenthesis - | InlayKind::Chaining - | InlayKind::ClosureReturnType - | InlayKind::GenericParamList - | InlayKind::Adjustment - | InlayKind::AdjustmentPostfix - | InlayKind::Type - | InlayKind::Discriminant - | InlayKind::ClosingBrace => false, - InlayKind::ClosureCapture => { - matches!(&label, lsp_types::InlayHintLabel::String(s) if s == ")") - } - InlayKind::BindingMode => { - matches!(&label, lsp_types::InlayHintLabel::String(s) if s != "&") - } - InlayKind::Parameter | InlayKind::Lifetime => true, - }), + padding_left: Some(inlay_hint.pad_left), + padding_right: Some(inlay_hint.pad_right), kind: match inlay_hint.kind { InlayKind::Parameter => Some(lsp_types::InlayHintKind::PARAMETER), - InlayKind::ClosureReturnType | InlayKind::Type | InlayKind::Chaining => { - Some(lsp_types::InlayHintKind::TYPE) - } - InlayKind::ClosingParenthesis - | InlayKind::ClosureCapture - | InlayKind::Discriminant - | InlayKind::OpeningParenthesis - | InlayKind::BindingMode - | InlayKind::GenericParamList - | InlayKind::Lifetime - | InlayKind::Adjustment - | InlayKind::AdjustmentPostfix - | InlayKind::ClosingBrace => None, + InlayKind::Type | InlayKind::Chaining => Some(lsp_types::InlayHintKind::TYPE), + _ => None, }, text_edits: inlay_hint.text_edit.map(|it| text_edit_vec(line_index, it)), data: None,