Generalize reborrow hints as adjustment hints

This commit is contained in:
Lukas Wirth 2022-11-04 17:11:15 +01:00
parent cd2603299c
commit c98fc537e6
9 changed files with 182 additions and 78 deletions

View file

@ -53,7 +53,7 @@ pub use builder::{ParamKind, TyBuilder};
pub use chalk_ext::*; pub use chalk_ext::*;
pub use infer::{ pub use infer::{
could_coerce, could_unify, Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic, could_coerce, could_unify, Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic,
InferenceResult, InferenceResult, OverloadedDeref, PointerCast,
}; };
pub use interner::Interner; pub use interner::Interner;
pub use lower::{ pub use lower::{

View file

@ -117,7 +117,7 @@ pub use {
name::{known, Name}, name::{known, Name},
ExpandResult, HirFileId, InFile, MacroFile, Origin, ExpandResult, HirFileId, InFile, MacroFile, Origin,
}, },
hir_ty::display::HirDisplay, hir_ty::{display::HirDisplay, PointerCast, Safety},
}; };
// These are negative re-exports: pub using these names is forbidden, they // These are negative re-exports: pub using these names is forbidden, they
@ -3651,6 +3651,28 @@ impl From<ItemInNs> for ScopeDef {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Adjust {
/// Go from ! to any type.
NeverToAny,
/// Dereference once, producing a place.
Deref(Option<OverloadedDeref>),
/// Take the address and produce either a `&` or `*` pointer.
Borrow(AutoBorrow),
Pointer(PointerCast),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum AutoBorrow {
/// Converts from T to &T.
Ref(Mutability),
/// Converts from T to *T.
RawPtr(Mutability),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct OverloadedDeref(pub Mutability);
pub trait HasVisibility { pub trait HasVisibility {
fn visibility(&self, db: &dyn HirDatabase) -> Visibility; fn visibility(&self, db: &dyn HirDatabase) -> Visibility;
fn is_visible_from(&self, db: &dyn HirDatabase, module: Module) -> bool { fn is_visible_from(&self, db: &dyn HirDatabase, module: Module) -> bool {

View file

@ -29,9 +29,10 @@ use crate::{
db::HirDatabase, db::HirDatabase,
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
source_analyzer::{resolve_hir_path, SourceAnalyzer}, source_analyzer::{resolve_hir_path, SourceAnalyzer},
Access, BindingMode, BuiltinAttr, Callable, ConstParam, Crate, DeriveHelper, Field, Function, Access, Adjust, AutoBorrow, BindingMode, BuiltinAttr, Callable, ConstParam, Crate,
HasSource, HirFileId, Impl, InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef, DeriveHelper, Field, Function, HasSource, HirFileId, Impl, InFile, Label, LifetimeParam, Local,
Name, Path, ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef, Macro, Module, ModuleDef, Name, OverloadedDeref, Path, ScopeDef, ToolModule, Trait, Type,
TypeAlias, TypeParam, VariantDef,
}; };
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@ -333,9 +334,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.resolve_trait(trait_) self.imp.resolve_trait(trait_)
} }
// FIXME: Figure out a nice interface to inspect adjustments pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjust>> {
pub fn is_implicit_reborrow(&self, expr: &ast::Expr) -> Option<Mutability> { self.imp.expr_adjustments(expr)
self.imp.is_implicit_reborrow(expr)
} }
pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> { pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> {
@ -1067,8 +1067,29 @@ impl<'db> SemanticsImpl<'db> {
} }
} }
fn is_implicit_reborrow(&self, expr: &ast::Expr) -> Option<Mutability> { fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjust>> {
self.analyze(expr.syntax())?.is_implicit_reborrow(self.db, expr) let mutability = |m| match m {
hir_ty::Mutability::Not => Mutability::Shared,
hir_ty::Mutability::Mut => Mutability::Mut,
};
self.analyze(expr.syntax())?.expr_adjustments(self.db, expr).map(|it| {
it.iter()
.map(|adjust| match adjust.kind {
hir_ty::Adjust::NeverToAny => Adjust::NeverToAny,
hir_ty::Adjust::Deref(Some(hir_ty::OverloadedDeref(m))) => {
Adjust::Deref(Some(OverloadedDeref(mutability(m))))
}
hir_ty::Adjust::Deref(None) => Adjust::Deref(None),
hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::RawPtr(m)) => {
Adjust::Borrow(AutoBorrow::RawPtr(mutability(m)))
}
hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::Ref(m)) => {
Adjust::Borrow(AutoBorrow::Ref(mutability(m)))
}
hir_ty::Adjust::Pointer(pc) => Adjust::Pointer(pc),
})
.collect()
})
} }
fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> { fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> {

View file

@ -38,8 +38,7 @@ use hir_ty::{
UnsafeExpr, UnsafeExpr,
}, },
method_resolution::{self, lang_names_for_bin_op}, method_resolution::{self, lang_names_for_bin_op},
Adjust, Adjustment, AutoBorrow, InferenceResult, Interner, Substitution, Ty, TyExt, TyKind, Adjustment, InferenceResult, Interner, Substitution, Ty, TyExt, TyKind, TyLoweringContext,
TyLoweringContext,
}; };
use itertools::Itertools; use itertools::Itertools;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -156,21 +155,14 @@ impl SourceAnalyzer {
Some(res) Some(res)
} }
pub(crate) fn is_implicit_reborrow( pub(crate) fn expr_adjustments(
&self, &self,
db: &dyn HirDatabase, db: &dyn HirDatabase,
expr: &ast::Expr, expr: &ast::Expr,
) -> Option<Mutability> { ) -> Option<&[Adjustment]> {
let expr_id = self.expr_id(db, expr)?; let expr_id = self.expr_id(db, expr)?;
let infer = self.infer.as_ref()?; let infer = self.infer.as_ref()?;
let adjustments = infer.expr_adjustments.get(&expr_id)?; infer.expr_adjustments.get(&expr_id).map(|v| &**v)
adjustments.windows(2).find_map(|slice| match slice {
&[Adjustment {kind: Adjust::Deref(None), ..}, Adjustment {kind: Adjust::Borrow(AutoBorrow::Ref(m)), ..}] => Some(match m {
hir_ty::Mutability::Mut => Mutability::Mut,
hir_ty::Mutability::Not => Mutability::Shared,
}),
_ => None,
})
} }
pub(crate) fn type_of_expr( pub(crate) fn type_of_expr(

View file

@ -1,7 +1,10 @@
use std::fmt; use std::fmt;
use either::Either; use either::Either;
use hir::{known, Callable, HasVisibility, HirDisplay, Mutability, Semantics, TypeInfo}; use hir::{
known, Adjust, AutoBorrow, Callable, HasVisibility, HirDisplay, Mutability, OverloadedDeref,
PointerCast, Safety, Semantics, TypeInfo,
};
use ide_db::{ use ide_db::{
base_db::FileRange, famous_defs::FamousDefs, syntax_helpers::node_ext::walk_ty, FxHashMap, base_db::FileRange, famous_defs::FamousDefs, syntax_helpers::node_ext::walk_ty, FxHashMap,
RootDatabase, RootDatabase,
@ -22,7 +25,7 @@ pub struct InlayHintsConfig {
pub type_hints: bool, pub type_hints: bool,
pub parameter_hints: bool, pub parameter_hints: bool,
pub chaining_hints: bool, pub chaining_hints: bool,
pub reborrow_hints: ReborrowHints, pub adjustment_hints: AdjustmentHints,
pub closure_return_type_hints: ClosureReturnTypeHints, pub closure_return_type_hints: ClosureReturnTypeHints,
pub binding_mode_hints: bool, pub binding_mode_hints: bool,
pub lifetime_elision_hints: LifetimeElisionHints, pub lifetime_elision_hints: LifetimeElisionHints,
@ -48,7 +51,7 @@ pub enum LifetimeElisionHints {
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum ReborrowHints { pub enum AdjustmentHints {
Always, Always,
MutableOnly, MutableOnly,
Never, Never,
@ -61,7 +64,8 @@ pub enum InlayKind {
ClosingBraceHint, ClosingBraceHint,
ClosureReturnTypeHint, ClosureReturnTypeHint,
GenericParamListHint, GenericParamListHint,
ImplicitReborrowHint, AdjustmentHint,
AdjustmentHintClosingParenthesis,
LifetimeHint, LifetimeHint,
ParameterHint, ParameterHint,
TypeHint, TypeHint,
@ -115,6 +119,12 @@ impl From<String> for InlayHintLabel {
} }
} }
impl From<&str> for InlayHintLabel {
fn from(s: &str) -> Self {
Self { parts: vec![InlayHintLabelPart { text: s.into(), linked_location: None }] }
}
}
impl fmt::Display for InlayHintLabel { impl fmt::Display for InlayHintLabel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.parts.iter().map(|part| &part.text).format("")) write!(f, "{}", self.parts.iter().map(|part| &part.text).format(""))
@ -221,6 +231,7 @@ fn hints(
match node { match node {
ast::Expr(expr) => { ast::Expr(expr) => {
chaining_hints(hints, sema, &famous_defs, config, file_id, &expr); chaining_hints(hints, sema, &famous_defs, config, file_id, &expr);
adjustment_hints(hints, sema, config, &expr);
match expr { match expr {
ast::Expr::CallExpr(it) => param_name_hints(hints, sema, config, ast::Expr::from(it)), ast::Expr::CallExpr(it) => param_name_hints(hints, sema, config, ast::Expr::from(it)),
ast::Expr::MethodCallExpr(it) => { ast::Expr::MethodCallExpr(it) => {
@ -229,7 +240,7 @@ fn hints(
ast::Expr::ClosureExpr(it) => closure_ret_hints(hints, sema, &famous_defs, config, file_id, it), ast::Expr::ClosureExpr(it) => closure_ret_hints(hints, sema, &famous_defs, config, file_id, it),
// We could show reborrows for all expressions, but usually that is just noise to the user // We could show reborrows for all expressions, but usually that is just noise to the user
// and the main point here is to show why "moving" a mutable reference doesn't necessarily move it // and the main point here is to show why "moving" a mutable reference doesn't necessarily move it
ast::Expr::PathExpr(_) => reborrow_hints(hints, sema, config, &expr), // ast::Expr::PathExpr(_) => reborrow_hints(hints, sema, config, &expr),
_ => None, _ => None,
} }
}, },
@ -617,30 +628,83 @@ fn closure_ret_hints(
Some(()) Some(())
} }
fn reborrow_hints( fn adjustment_hints(
acc: &mut Vec<InlayHint>, acc: &mut Vec<InlayHint>,
sema: &Semantics<'_, RootDatabase>, sema: &Semantics<'_, RootDatabase>,
config: &InlayHintsConfig, config: &InlayHintsConfig,
expr: &ast::Expr, expr: &ast::Expr,
) -> Option<()> { ) -> Option<()> {
if config.reborrow_hints == ReborrowHints::Never { if config.adjustment_hints == AdjustmentHints::Never {
return None; // return None;
} }
let parent = expr.syntax().parent().and_then(ast::Expr::cast);
let descended = sema.descend_node_into_attributes(expr.clone()).pop(); let descended = sema.descend_node_into_attributes(expr.clone()).pop();
let desc_expr = descended.as_ref().unwrap_or(expr); let desc_expr = descended.as_ref().unwrap_or(expr);
let mutability = sema.is_implicit_reborrow(desc_expr)?; let adjustments = sema.expr_adjustments(desc_expr).filter(|it| !it.is_empty())?;
let label = match mutability { let needs_parens = match parent {
hir::Mutability::Shared if config.reborrow_hints != ReborrowHints::MutableOnly => "&*", Some(parent) => {
hir::Mutability::Mut => "&mut *", match parent {
_ => return None, ast::Expr::AwaitExpr(_)
| ast::Expr::CallExpr(_)
| ast::Expr::CastExpr(_)
| ast::Expr::FieldExpr(_)
| ast::Expr::MethodCallExpr(_)
| ast::Expr::TryExpr(_) => true,
// FIXME: shorthands need special casing, though not sure if adjustments are even valid there
ast::Expr::RecordExpr(_) => false,
ast::Expr::IndexExpr(index) => index.base().as_ref() == Some(expr),
_ => false,
}
}
None => false,
}; };
acc.push(InlayHint { if needs_parens {
range: expr.syntax().text_range(), acc.push(InlayHint {
kind: InlayKind::ImplicitReborrowHint, range: expr.syntax().text_range(),
label: label.to_string().into(), kind: InlayKind::AdjustmentHint,
tooltip: Some(InlayTooltip::String("Compiler inserted reborrow".into())), label: "(".into(),
}); tooltip: None,
});
}
for adjustment in adjustments.into_iter().rev() {
// FIXME: Add some nicer tooltips to each of these
let text = match adjustment {
Adjust::NeverToAny => "<never-to-any>",
Adjust::Deref(None) => "*",
Adjust::Deref(Some(OverloadedDeref(Mutability::Mut))) => "*",
Adjust::Deref(Some(OverloadedDeref(Mutability::Shared))) => "*",
Adjust::Borrow(AutoBorrow::Ref(Mutability::Shared)) => "&",
Adjust::Borrow(AutoBorrow::Ref(Mutability::Mut)) => "&mut ",
Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Shared)) => "&raw const ",
Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Mut)) => "&raw mut ",
// some of these could be represented via `as` casts, but that's not too nice and
// handling everything as a prefix expr makes the `(` and `)` insertion easier
Adjust::Pointer(cast) => match cast {
PointerCast::ReifyFnPointer => "<fn-item-to-fn-pointer>",
PointerCast::UnsafeFnPointer => "<safe-fn-pointer-to-unsafe-fn-pointer>",
PointerCast::ClosureFnPointer(Safety::Unsafe) => "<closure-to-unsafe-fn-pointer>",
PointerCast::ClosureFnPointer(Safety::Safe) => "<closure-to-fn-pointer>",
PointerCast::MutToConstPointer => "<mut-ptr-to-const-ptr>",
PointerCast::ArrayToPointer => "<array-ptr-to-element-ptr>",
PointerCast::Unsize => "<unsize>",
},
};
acc.push(InlayHint {
range: expr.syntax().text_range(),
kind: InlayKind::AdjustmentHint,
label: text.into(),
tooltip: None,
});
}
if needs_parens {
acc.push(InlayHint {
range: expr.syntax().text_range(),
kind: InlayKind::AdjustmentHintClosingParenthesis,
label: ")".into(),
tooltip: None,
});
}
Some(()) Some(())
} }
@ -785,23 +849,23 @@ fn binding_mode_hints(
tooltip: Some(InlayTooltip::String("Inferred binding mode".into())), tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
}); });
}); });
match pat { // match pat {
ast::Pat::IdentPat(pat) if pat.ref_token().is_none() && pat.mut_token().is_none() => { // ast::Pat::IdentPat(pat) if pat.ref_token().is_none() && pat.mut_token().is_none() => {
let bm = sema.binding_mode_of_pat(pat)?; // let bm = sema.binding_mode_of_pat(pat)?;
let bm = match bm { // let bm = match bm {
hir::BindingMode::Move => return None, // hir::BindingMode::Move => return None,
hir::BindingMode::Ref(Mutability::Mut) => "ref mut", // hir::BindingMode::Ref(Mutability::Mut) => "ref mut",
hir::BindingMode::Ref(Mutability::Shared) => "ref", // hir::BindingMode::Ref(Mutability::Shared) => "ref",
}; // };
acc.push(InlayHint { // acc.push(InlayHint {
range, // range,
kind: InlayKind::BindingModeHint, // kind: InlayKind::BindingModeHint,
label: bm.to_string().into(), // label: bm.to_string().into(),
tooltip: Some(InlayTooltip::String("Inferred binding mode".into())), // tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
}); // });
} // }
_ => (), // _ => (),
} // }
Some(()) Some(())
} }
@ -1218,7 +1282,7 @@ mod tests {
use syntax::{TextRange, TextSize}; use syntax::{TextRange, TextSize};
use test_utils::extract_annotations; use test_utils::extract_annotations;
use crate::inlay_hints::ReborrowHints; use crate::inlay_hints::AdjustmentHints;
use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints}; use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints};
use super::ClosureReturnTypeHints; use super::ClosureReturnTypeHints;
@ -1230,7 +1294,7 @@ mod tests {
chaining_hints: false, chaining_hints: false,
lifetime_elision_hints: LifetimeElisionHints::Never, lifetime_elision_hints: LifetimeElisionHints::Never,
closure_return_type_hints: ClosureReturnTypeHints::Never, closure_return_type_hints: ClosureReturnTypeHints::Never,
reborrow_hints: ReborrowHints::Always, adjustment_hints: AdjustmentHints::Always,
binding_mode_hints: false, binding_mode_hints: false,
hide_named_constructor_hints: false, hide_named_constructor_hints: false,
hide_closure_initialization_hints: false, hide_closure_initialization_hints: false,
@ -1242,7 +1306,7 @@ mod tests {
type_hints: true, type_hints: true,
parameter_hints: true, parameter_hints: true,
chaining_hints: true, chaining_hints: true,
reborrow_hints: ReborrowHints::Always, adjustment_hints: AdjustmentHints::Always,
closure_return_type_hints: ClosureReturnTypeHints::WithBlock, closure_return_type_hints: ClosureReturnTypeHints::WithBlock,
binding_mode_hints: true, binding_mode_hints: true,
lifetime_elision_hints: LifetimeElisionHints::Always, lifetime_elision_hints: LifetimeElisionHints::Always,
@ -2849,7 +2913,7 @@ impl () {
fn hints_implicit_reborrow() { fn hints_implicit_reborrow() {
check_with_config( check_with_config(
InlayHintsConfig { InlayHintsConfig {
reborrow_hints: ReborrowHints::Always, adjustment_hints: AdjustmentHints::Always,
parameter_hints: true, parameter_hints: true,
..DISABLED_CONFIG ..DISABLED_CONFIG
}, },

View file

@ -81,8 +81,8 @@ pub use crate::{
highlight_related::{HighlightRelatedConfig, HighlightedRange}, highlight_related::{HighlightRelatedConfig, HighlightedRange},
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult}, hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
inlay_hints::{ inlay_hints::{
ClosureReturnTypeHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, AdjustmentHints, ClosureReturnTypeHints, InlayHint, InlayHintLabel, InlayHintsConfig,
InlayTooltip, LifetimeElisionHints, ReborrowHints, InlayKind, InlayTooltip, LifetimeElisionHints,
}, },
join_lines::JoinLinesConfig, join_lines::JoinLinesConfig,
markup::Markup, markup::Markup,

View file

@ -111,7 +111,7 @@ impl StaticIndex<'_> {
chaining_hints: true, chaining_hints: true,
closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock, closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock,
lifetime_elision_hints: crate::LifetimeElisionHints::Never, lifetime_elision_hints: crate::LifetimeElisionHints::Never,
reborrow_hints: crate::ReborrowHints::Never, adjustment_hints: crate::AdjustmentHints::Never,
hide_named_constructor_hints: false, hide_named_constructor_hints: false,
hide_closure_initialization_hints: false, hide_closure_initialization_hints: false,
param_names_for_lifetime_elision_hints: false, param_names_for_lifetime_elision_hints: false,

View file

@ -261,6 +261,7 @@ config_data! {
files_excludeDirs: Vec<PathBuf> = "[]", files_excludeDirs: Vec<PathBuf> = "[]",
/// Controls file watching implementation. /// Controls file watching implementation.
files_watcher: FilesWatcherDef = "\"client\"", files_watcher: FilesWatcherDef = "\"client\"",
/// Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords. /// Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords.
highlightRelated_breakPoints_enable: bool = "true", highlightRelated_breakPoints_enable: bool = "true",
/// Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`). /// Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`).
@ -1200,10 +1201,10 @@ impl Config {
hide_closure_initialization_hints: self hide_closure_initialization_hints: self
.data .data
.inlayHints_typeHints_hideClosureInitialization, .inlayHints_typeHints_hideClosureInitialization,
reborrow_hints: match self.data.inlayHints_reborrowHints_enable { adjustment_hints: match self.data.inlayHints_reborrowHints_enable {
ReborrowHintsDef::Always => ide::ReborrowHints::Always, ReborrowHintsDef::Always => ide::AdjustmentHints::Always,
ReborrowHintsDef::Never => ide::ReborrowHints::Never, ReborrowHintsDef::Never => ide::AdjustmentHints::Never,
ReborrowHintsDef::Mutable => ide::ReborrowHints::MutableOnly, ReborrowHintsDef::Mutable => ide::AdjustmentHints::MutableOnly,
}, },
binding_mode_hints: self.data.inlayHints_bindingModeHints_enable, binding_mode_hints: self.data.inlayHints_bindingModeHints_enable,
param_names_for_lifetime_elision_hints: self param_names_for_lifetime_elision_hints: self

View file

@ -440,32 +440,35 @@ pub(crate) fn inlay_hint(
Ok(lsp_types::InlayHint { Ok(lsp_types::InlayHint {
position: match inlay_hint.kind { position: match inlay_hint.kind {
// before annotated thing // before annotated thing
InlayKind::ParameterHint InlayKind::ParameterHint | InlayKind::AdjustmentHint | InlayKind::BindingModeHint => {
| InlayKind::ImplicitReborrowHint position(line_index, inlay_hint.range.start())
| InlayKind::BindingModeHint => position(line_index, inlay_hint.range.start()), }
// after annotated thing // after annotated thing
InlayKind::ClosureReturnTypeHint InlayKind::ClosureReturnTypeHint
| InlayKind::TypeHint | InlayKind::TypeHint
| InlayKind::ChainingHint | InlayKind::ChainingHint
| InlayKind::GenericParamListHint | InlayKind::GenericParamListHint
| InlayKind::AdjustmentHintClosingParenthesis
| InlayKind::LifetimeHint | InlayKind::LifetimeHint
| InlayKind::ClosingBraceHint => position(line_index, inlay_hint.range.end()), | InlayKind::ClosingBraceHint => position(line_index, inlay_hint.range.end()),
}, },
padding_left: Some(match inlay_hint.kind { padding_left: Some(match inlay_hint.kind {
InlayKind::TypeHint => !render_colons, InlayKind::TypeHint => !render_colons,
InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true, InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true,
InlayKind::BindingModeHint InlayKind::AdjustmentHintClosingParenthesis
| InlayKind::BindingModeHint
| InlayKind::ClosureReturnTypeHint | InlayKind::ClosureReturnTypeHint
| InlayKind::GenericParamListHint | InlayKind::GenericParamListHint
| InlayKind::ImplicitReborrowHint | InlayKind::AdjustmentHint
| InlayKind::LifetimeHint | InlayKind::LifetimeHint
| InlayKind::ParameterHint => false, | InlayKind::ParameterHint => false,
}), }),
padding_right: Some(match inlay_hint.kind { padding_right: Some(match inlay_hint.kind {
InlayKind::ChainingHint InlayKind::AdjustmentHintClosingParenthesis
| InlayKind::ChainingHint
| InlayKind::ClosureReturnTypeHint | InlayKind::ClosureReturnTypeHint
| InlayKind::GenericParamListHint | InlayKind::GenericParamListHint
| InlayKind::ImplicitReborrowHint | InlayKind::AdjustmentHint
| InlayKind::TypeHint | InlayKind::TypeHint
| InlayKind::ClosingBraceHint => false, | InlayKind::ClosingBraceHint => false,
InlayKind::BindingModeHint => inlay_hint.label.as_simple_str() != Some("&"), InlayKind::BindingModeHint => inlay_hint.label.as_simple_str() != Some("&"),
@ -476,10 +479,11 @@ pub(crate) fn inlay_hint(
InlayKind::ClosureReturnTypeHint | InlayKind::TypeHint | InlayKind::ChainingHint => { InlayKind::ClosureReturnTypeHint | InlayKind::TypeHint | InlayKind::ChainingHint => {
Some(lsp_types::InlayHintKind::TYPE) Some(lsp_types::InlayHintKind::TYPE)
} }
InlayKind::BindingModeHint InlayKind::AdjustmentHintClosingParenthesis
| InlayKind::BindingModeHint
| InlayKind::GenericParamListHint | InlayKind::GenericParamListHint
| InlayKind::LifetimeHint | InlayKind::LifetimeHint
| InlayKind::ImplicitReborrowHint | InlayKind::AdjustmentHint
| InlayKind::ClosingBraceHint => None, | InlayKind::ClosingBraceHint => None,
}, },
text_edits: None, text_edits: None,