Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion crates/ide/src/inlay_hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ fn hints(
pub struct InlayHintsConfig<'a> {
pub render_colons: bool,
pub type_hints: bool,
pub type_hints_placement: TypeHintsPlacement,
pub sized_bound: bool,
pub discriminant_hints: DiscriminantHints,
pub parameter_hints: bool,
Expand Down Expand Up @@ -331,6 +332,12 @@ pub struct InlayHintsConfig<'a> {
pub minicore: MiniCore<'a>,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum TypeHintsPlacement {
Inline,
EndOfLine,
}

impl InlayHintsConfig<'_> {
fn lazy_text_edit(&self, finish: impl FnOnce() -> TextEdit) -> LazyProperty<TextEdit> {
if self.fields_to_resolve.resolve_text_edits {
Expand Down Expand Up @@ -876,12 +883,15 @@ mod tests {
use crate::inlay_hints::{AdjustmentHints, AdjustmentHintsMode};
use crate::{LifetimeElisionHints, fixture, inlay_hints::InlayHintsConfig};

use super::{ClosureReturnTypeHints, GenericParameterHints, InlayFieldsToResolve};
use super::{
ClosureReturnTypeHints, GenericParameterHints, InlayFieldsToResolve, TypeHintsPlacement,
};

pub(super) const DISABLED_CONFIG: InlayHintsConfig<'_> = InlayHintsConfig {
discriminant_hints: DiscriminantHints::Never,
render_colons: false,
type_hints: false,
type_hints_placement: TypeHintsPlacement::Inline,
parameter_hints: false,
parameter_hints_for_missing_arguments: false,
sized_bound: false,
Expand Down Expand Up @@ -915,6 +925,7 @@ mod tests {
};
pub(super) const TEST_CONFIG: InlayHintsConfig<'_> = InlayHintsConfig {
type_hints: true,
type_hints_placement: TypeHintsPlacement::Inline,
parameter_hints: true,
chaining_hints: true,
closure_return_type_hints: ClosureReturnTypeHints::WithBlock,
Expand Down
98 changes: 92 additions & 6 deletions crates/ide/src/inlay_hints/bind_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ use ide_db::{RootDatabase, famous_defs::FamousDefs};

use itertools::Itertools;
use syntax::{
TextRange,
ast::{self, AstNode, HasGenericArgs, HasName},
match_ast,
};

use super::TypeHintsPlacement;
use crate::{
InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind,
inlay_hints::{closure_has_block_body, label_of_ty, ty_to_text_edit},
Expand All @@ -29,6 +31,7 @@ pub(super) fn hints(
}

let parent = pat.syntax().parent()?;
let mut enclosing_let_stmt = None;
let type_ascriptable = match_ast! {
match parent {
ast::Param(it) => {
Expand All @@ -41,6 +44,7 @@ pub(super) fn hints(
Some(it.colon_token())
},
ast::LetStmt(it) => {
enclosing_let_stmt = Some(it.clone());
if config.hide_closure_initialization_hints
&& let Some(ast::Expr::ClosureExpr(closure)) = it.initializer()
&& closure_has_block_body(&closure) {
Expand Down Expand Up @@ -101,16 +105,26 @@ pub(super) fn hints(
Some(name) => name.syntax().text_range(),
None => pat.syntax().text_range(),
};
let mut range = match type_ascriptable {
Some(Some(t)) => text_range.cover(t.text_range()),
_ => text_range,
};

let mut pad_left = !render_colons;
if matches!(config.type_hints_placement, TypeHintsPlacement::EndOfLine)
&& let Some(let_stmt) = enclosing_let_stmt
{
let stmt_range = let_stmt.syntax().text_range();
range = TextRange::new(range.start(), stmt_range.end());
pad_left = true;
}
acc.push(InlayHint {
range: match type_ascriptable {
Some(Some(t)) => text_range.cover(t.text_range()),
_ => text_range,
},
range,
kind: InlayKind::Type,
label,
text_edit,
position: InlayHintPosition::After,
pad_left: !render_colons,
pad_left,
pad_right: false,
resolve_parent: Some(pat.syntax().text_range()),
});
Expand Down Expand Up @@ -182,8 +196,10 @@ mod tests {

use crate::{ClosureReturnTypeHints, fixture, inlay_hints::InlayHintsConfig};

use super::TypeHintsPlacement;
use crate::inlay_hints::tests::{
DISABLED_CONFIG, TEST_CONFIG, check, check_edit, check_no_edit, check_with_config,
DISABLED_CONFIG, TEST_CONFIG, check, check_edit, check_expect, check_no_edit,
check_with_config,
};

#[track_caller]
Expand All @@ -203,6 +219,76 @@ fn main() {
);
}

#[test]
fn type_hints_end_of_line_placement() {
let mut config = InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG };
config.type_hints_placement = TypeHintsPlacement::EndOfLine;
check_expect(
config,
r#"
fn main() {
let foo = 92_i32;
}
"#,
expect![[r#"
[
(
20..33,
[
"i32",
],
),
]
"#]],
);
}

#[test]
fn type_hints_end_of_line_placement_chain_expr() {
let mut config = InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG };
config.type_hints_placement = TypeHintsPlacement::EndOfLine;
check_expect(
config,
r#"
fn main() {
struct Builder;
impl Builder {
fn iter(self) -> Builder { Builder }
fn map(self) -> Builder { Builder }
}
fn make() -> Builder { Builder }

let foo = make()
.iter()
.map();
}
"#,
expect![[r#"
[
(
192..236,
[
InlayHintLabelPart {
text: "Builder",
linked_location: Some(
Computed(
FileRangeWrapper {
file_id: FileId(
0,
),
range: 23..30,
},
),
),
tooltip: "",
},
],
),
]
"#]],
);
}

#[test]
fn type_hints_bindings_after_at() {
check_types(
Expand Down
107 changes: 97 additions & 10 deletions crates/ide/src/inlay_hints/chaining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
use hir::DisplayTarget;
use ide_db::famous_defs::FamousDefs;
use syntax::{
Direction, NodeOrToken, SyntaxKind, T,
Direction, NodeOrToken, SyntaxKind, T, TextRange,
ast::{self, AstNode},
};

use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind};

use super::label_of_ty;
use super::{TypeHintsPlacement, label_of_ty};

pub(super) fn hints(
acc: &mut Vec<InlayHint>,
Expand Down Expand Up @@ -40,13 +40,14 @@ pub(super) fn hints(

// Chaining can be defined as an expression whose next sibling tokens are newline and dot
// Ignoring extra whitespace and comments
let next = tokens.next()?.kind();
if next == SyntaxKind::WHITESPACE {
let mut next_next = tokens.next()?.kind();
while next_next == SyntaxKind::WHITESPACE {
next_next = tokens.next()?.kind();
let next_token = tokens.next()?;
if next_token.kind() == SyntaxKind::WHITESPACE {
let newline_token = next_token;
let mut next_next = tokens.next()?;
while next_next.kind() == SyntaxKind::WHITESPACE {
next_next = tokens.next()?;
}
if next_next == T![.] {
if next_next.kind() == T![.] {
let ty = sema.type_of_expr(desc_expr)?.original;
if ty.is_unknown() {
return None;
Expand All @@ -58,8 +59,18 @@ pub(super) fn hints(
return None;
}
let label = label_of_ty(famous_defs, config, &ty, display_target)?;
let range = {
let mut range = expr.syntax().text_range();
if config.type_hints_placement == TypeHintsPlacement::EndOfLine {
range = TextRange::new(
range.start(),
newline_token.text_range().start().max(range.end()),
);
}
range
};
acc.push(InlayHint {
range: expr.syntax().text_range(),
range,
kind: InlayKind::Chaining,
label,
text_edit: None,
Expand All @@ -79,7 +90,7 @@ mod tests {
use ide_db::text_edit::{TextRange, TextSize};

use crate::{
InlayHintsConfig, fixture,
InlayHintsConfig, TypeHintsPlacement, fixture,
inlay_hints::{
LazyProperty,
tests::{DISABLED_CONFIG, TEST_CONFIG, check_expect, check_with_config},
Expand Down Expand Up @@ -686,4 +697,80 @@ fn main() {
"#]],
);
}

#[test]
fn chaining_hints_end_of_line_placement() {
check_expect(
InlayHintsConfig {
chaining_hints: true,
type_hints_placement: TypeHintsPlacement::EndOfLine,
..DISABLED_CONFIG
},
r#"
fn main() {
let baz = make()
.into_bar()
.into_baz();
}

struct Foo;
struct Bar;
struct Baz;

impl Foo {
fn into_bar(self) -> Bar { Bar }
}

impl Bar {
fn into_baz(self) -> Baz { Baz }
}

fn make() -> Foo {
Foo
}
"#,
expect![[r#"
[
(
26..52,
[
InlayHintLabelPart {
text: "Bar",
linked_location: Some(
Computed(
FileRangeWrapper {
file_id: FileId(
0,
),
range: 96..99,
},
),
),
tooltip: "",
},
],
),
(
26..32,
[
InlayHintLabelPart {
text: "Foo",
linked_location: Some(
Computed(
FileRangeWrapper {
file_id: FileId(
0,
),
range: 84..87,
},
),
),
tooltip: "",
},
],
),
]
"#]],
);
}
}
2 changes: 1 addition & 1 deletion crates/ide/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pub use crate::{
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
GenericParameterHints, InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart,
InlayHintPosition, InlayHintsConfig, InlayKind, InlayTooltip, LazyProperty,
LifetimeElisionHints,
LifetimeElisionHints, TypeHintsPlacement,
},
join_lines::JoinLinesConfig,
markup::Markup,
Expand Down
3 changes: 2 additions & 1 deletion crates/ide/src/static_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::navigation_target::UpmappingResult;
use crate::{
Analysis, Fold, HoverConfig, HoverResult, InlayHint, InlayHintsConfig, TryToNav,
hover::{SubstTyLen, hover_for_definition},
inlay_hints::{AdjustmentHintsMode, InlayFieldsToResolve},
inlay_hints::{AdjustmentHintsMode, InlayFieldsToResolve, TypeHintsPlacement},
moniker::{MonikerResult, SymbolInformationKind, def_to_kind, def_to_moniker},
parent_module::crates_for,
};
Expand Down Expand Up @@ -167,6 +167,7 @@ impl StaticIndex<'_> {
render_colons: true,
discriminant_hints: crate::DiscriminantHints::Fieldless,
type_hints: true,
type_hints_placement: TypeHintsPlacement::Inline,
sized_bound: false,
parameter_hints: true,
parameter_hints_for_missing_arguments: false,
Expand Down
1 change: 1 addition & 0 deletions crates/rust-analyzer/src/cli/analysis_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,7 @@ impl flags::AnalysisStats {
&InlayHintsConfig {
render_colons: false,
type_hints: true,
type_hints_placement: ide::TypeHintsPlacement::Inline,
sized_bound: false,
discriminant_hints: ide::DiscriminantHints::Always,
parameter_hints: true,
Expand Down
Loading