Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/semantics.rs')
-rw-r--r--crates/hir/src/semantics.rs21
1 files changed, 17 insertions, 4 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index e53d126928..e4b9f479e8 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -562,6 +562,8 @@ impl<'db> SemanticsImpl<'db> {
// Note this return type is deliberate as [`find_nodes_at_offset_with_descend`] wants to stop
// traversing the inner iterator when it finds a node.
+ // The outer iterator is over the tokens descendants
+ // The inner iterator is the ancestors of a descendant
fn descend_node_at_offset(
&self,
node: &SyntaxNode,
@@ -570,8 +572,16 @@ impl<'db> SemanticsImpl<'db> {
// Handle macro token cases
node.token_at_offset(offset)
.map(move |token| self.descend_into_macros(token))
- .map(|it| it.into_iter().map(move |it| self.token_ancestors_with_macros(it)))
- .flatten()
+ .map(|descendants| {
+ descendants.into_iter().map(move |it| self.token_ancestors_with_macros(it))
+ })
+ // re-order the tokens from token_at_offset by returning the ancestors with the smaller first nodes first
+ // See algo::ancestors_at_offset, which uses the same approach
+ .kmerge_by(|left, right| {
+ left.clone()
+ .map(|node| node.text_range().len())
+ .lt(right.clone().map(|node| node.text_range().len()))
+ })
}
fn original_range(&self, node: &SyntaxNode) -> FileRange {
@@ -589,11 +599,14 @@ impl<'db> SemanticsImpl<'db> {
fn token_ancestors_with_macros(
&self,
token: SyntaxToken,
- ) -> impl Iterator<Item = SyntaxNode> + '_ {
+ ) -> impl Iterator<Item = SyntaxNode> + Clone + '_ {
token.parent().into_iter().flat_map(move |parent| self.ancestors_with_macros(parent))
}
- fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ {
+ fn ancestors_with_macros(
+ &self,
+ node: SyntaxNode,
+ ) -> impl Iterator<Item = SyntaxNode> + Clone + '_ {
let node = self.find_file(node);
node.ancestors_with_macros(self.db.upcast()).map(|it| it.value)
}