Auto merge of #16089 - SomeoneToIgnore:fix-parameter-inlay-hints-resolution, r=Veykril
Query for nearest parent block around the hint to resolve This way, parameter hints will be found for resolution and https://github.com/rust-lang/rust-analyzer/pull/15522#issuecomment-1835896335 will be fixed Hopefully that also helps with whatever else (lifetimes', etc.) hints in https://github.com/rust-lang/rust-analyzer/issues/13962 > hints are resolved by querying for textDocument/inlayHint with hint's position turned into a [position-1, position+1] range (instead of the original, much wider document range). > > This might lead to issues in the future, with e.g. lifetime hints (currently there's nothing to resolve for them and it's fine) that belong to a certain position, but need to have textDocument/inlayHint query for much bigger range than their position+/-1
This commit is contained in:
commit
3aa6306728
@ -422,6 +422,11 @@ fn ty_to_text_edit(
|
||||
Some(builder.finish())
|
||||
}
|
||||
|
||||
pub enum RangeLimit {
|
||||
Fixed(TextRange),
|
||||
NearestParent(TextSize),
|
||||
}
|
||||
|
||||
// Feature: Inlay Hints
|
||||
//
|
||||
// rust-analyzer shows additional information inline with the source code.
|
||||
@ -443,7 +448,7 @@ fn ty_to_text_edit(
|
||||
pub(crate) fn inlay_hints(
|
||||
db: &RootDatabase,
|
||||
file_id: FileId,
|
||||
range_limit: Option<TextRange>,
|
||||
range_limit: Option<RangeLimit>,
|
||||
config: &InlayHintsConfig,
|
||||
) -> Vec<InlayHint> {
|
||||
let _p = profile::span("inlay_hints");
|
||||
@ -458,13 +463,31 @@ pub(crate) fn inlay_hints(
|
||||
|
||||
let hints = |node| hints(&mut acc, &famous_defs, config, file_id, node);
|
||||
match range_limit {
|
||||
Some(range) => match file.covering_element(range) {
|
||||
Some(RangeLimit::Fixed(range)) => match file.covering_element(range) {
|
||||
NodeOrToken::Token(_) => return acc,
|
||||
NodeOrToken::Node(n) => n
|
||||
.descendants()
|
||||
.filter(|descendant| range.intersect(descendant.text_range()).is_some())
|
||||
.for_each(hints),
|
||||
},
|
||||
Some(RangeLimit::NearestParent(position)) => {
|
||||
match file.token_at_offset(position).left_biased() {
|
||||
Some(token) => {
|
||||
if let Some(parent_block) =
|
||||
token.parent_ancestors().find_map(ast::BlockExpr::cast)
|
||||
{
|
||||
parent_block.syntax().descendants().for_each(hints)
|
||||
} else if let Some(parent_item) =
|
||||
token.parent_ancestors().find_map(ast::Item::cast)
|
||||
{
|
||||
parent_item.syntax().descendants().for_each(hints)
|
||||
} else {
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
None => return acc,
|
||||
}
|
||||
}
|
||||
None => file.descendants().for_each(hints),
|
||||
};
|
||||
}
|
||||
|
@ -177,7 +177,11 @@ mod tests {
|
||||
use syntax::{TextRange, TextSize};
|
||||
use test_utils::extract_annotations;
|
||||
|
||||
use crate::{fixture, inlay_hints::InlayHintsConfig, ClosureReturnTypeHints};
|
||||
use crate::{
|
||||
fixture,
|
||||
inlay_hints::{InlayHintsConfig, RangeLimit},
|
||||
ClosureReturnTypeHints,
|
||||
};
|
||||
|
||||
use crate::inlay_hints::tests::{
|
||||
check, check_edit, check_no_edit, check_with_config, DISABLED_CONFIG, TEST_CONFIG,
|
||||
@ -400,7 +404,7 @@ fn main() {
|
||||
.inlay_hints(
|
||||
&InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG },
|
||||
file_id,
|
||||
Some(TextRange::new(TextSize::from(500), TextSize::from(600))),
|
||||
Some(RangeLimit::Fixed(TextRange::new(TextSize::from(500), TextSize::from(600)))),
|
||||
)
|
||||
.unwrap();
|
||||
let actual =
|
||||
|
@ -94,7 +94,7 @@ macro_rules! eprintln {
|
||||
inlay_hints::{
|
||||
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
|
||||
InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayHintPosition,
|
||||
InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
|
||||
InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints, RangeLimit,
|
||||
},
|
||||
join_lines::JoinLinesConfig,
|
||||
markup::Markup,
|
||||
@ -397,7 +397,7 @@ pub fn inlay_hints(
|
||||
&self,
|
||||
config: &InlayHintsConfig,
|
||||
file_id: FileId,
|
||||
range: Option<TextRange>,
|
||||
range: Option<RangeLimit>,
|
||||
) -> Cancellable<Vec<InlayHint>> {
|
||||
self.with_db(|db| inlay_hints::inlay_hints(db, file_id, range, config))
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
use ide::{
|
||||
AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, FilePosition, FileRange,
|
||||
HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, RangeInfo, ReferenceCategory,
|
||||
Runnable, RunnableKind, SingleResolve, SourceChange, TextEdit,
|
||||
HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, RangeInfo, RangeLimit,
|
||||
ReferenceCategory, Runnable, RunnableKind, SingleResolve, SourceChange, TextEdit,
|
||||
};
|
||||
use ide_db::SymbolKind;
|
||||
use lsp_server::ErrorCode;
|
||||
@ -1409,7 +1409,7 @@ pub(crate) fn handle_inlay_hints(
|
||||
let inlay_hints_config = snap.config.inlay_hints();
|
||||
Ok(Some(
|
||||
snap.analysis
|
||||
.inlay_hints(&inlay_hints_config, file_id, Some(range))?
|
||||
.inlay_hints(&inlay_hints_config, file_id, Some(RangeLimit::Fixed(range)))?
|
||||
.into_iter()
|
||||
.map(|it| {
|
||||
to_proto::inlay_hint(
|
||||
@ -1440,22 +1440,13 @@ pub(crate) fn handle_inlay_hints_resolve(
|
||||
anyhow::ensure!(snap.file_exists(file_id), "Invalid LSP resolve data");
|
||||
|
||||
let line_index = snap.file_line_index(file_id)?;
|
||||
let range = from_proto::text_range(
|
||||
&line_index,
|
||||
lsp_types::Range { start: original_hint.position, end: original_hint.position },
|
||||
)?;
|
||||
let range_start = range.start();
|
||||
let range_end = range.end();
|
||||
let large_range = TextRange::new(
|
||||
range_start.checked_sub(1.into()).unwrap_or(range_start),
|
||||
range_end.checked_add(1.into()).unwrap_or(range_end),
|
||||
);
|
||||
let hint_position = from_proto::offset(&line_index, original_hint.position)?;
|
||||
let mut forced_resolve_inlay_hints_config = snap.config.inlay_hints();
|
||||
forced_resolve_inlay_hints_config.fields_to_resolve = InlayFieldsToResolve::empty();
|
||||
let resolve_hints = snap.analysis.inlay_hints(
|
||||
&forced_resolve_inlay_hints_config,
|
||||
file_id,
|
||||
Some(large_range),
|
||||
Some(RangeLimit::NearestParent(hint_position)),
|
||||
)?;
|
||||
|
||||
let mut resolved_hints = resolve_hints
|
||||
|
Loading…
Reference in New Issue
Block a user