aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/semantics/source_to_def.rs20
1 files changed, 18 insertions, 2 deletions
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index 24afcfba0..0c5ba3a8f 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -1,6 +1,6 @@
1//! Maps *syntax* of various definitions to their semantic ids. 1//! Maps *syntax* of various definitions to their semantic ids.
2//! 2//!
3//! This is a very interesting module, and, in some sense, can be considered a 3//! This is a very interesting module, and, in some sense, can be considered the
4//! heart of the IDE parts of rust-analyzer. 4//! heart of the IDE parts of rust-analyzer.
5//! 5//!
6//! This module solves the following problem: 6//! This module solves the following problem:
@@ -17,7 +17,7 @@
17//! looking at the syntax of the function we can realise that it is a part of an 17//! looking at the syntax of the function we can realise that it is a part of an
18//! `impl` block, but we won't be able to tell what trait function the current 18//! `impl` block, but we won't be able to tell what trait function the current
19//! function overrides, and whether it does that correctly. For that, we need to 19//! function overrides, and whether it does that correctly. For that, we need to
20//! go from [`ast::Fn`] to [`crate::Function], and that's exactly what this 20//! go from [`ast::Fn`] to [`crate::Function`], and that's exactly what this
21//! module does. 21//! module does.
22//! 22//!
23//! As syntax trees are values and don't know their place of origin/identity, 23//! As syntax trees are values and don't know their place of origin/identity,
@@ -68,6 +68,22 @@
68//! current node. Then, `findSourceNonLocalFirDeclaration` gets `Fir` for this 68//! current node. Then, `findSourceNonLocalFirDeclaration` gets `Fir` for this
69//! parent. Finally, `findElementIn` function traverses `Fir` children to find 69//! parent. Finally, `findElementIn` function traverses `Fir` children to find
70//! one with the same source we originally started with. 70//! one with the same source we originally started with.
71//!
72//! One question is left though -- where does the recursion stops? This happens
73//! when we get to the file syntax node, which doesn't have a syntactic parent.
74//! In that case, we loop through all the crates that might contain this file
75//! and look for a module whose source is the given file.
76//!
77//! Note that the logic in this module is somewhat fundamentally imprecise --
78//! due to conditional compilation and `#[path]` attributes, there's no
79//! injective mapping from syntax nodes to defs. This is not an edge case --
80//! more or less every item in a `lib.rs` is a part of two distinct crates: a
81//! library with `--cfg test` and a library without.
82//!
83//! At the moment, we don't really handle this well and return the first answer
84//! that works. Ideally, we should first let the caller to pick a specific
85//! active crate for a given position, and then provide an API to resolve all
86//! syntax nodes against this specific crate.
71 87
72use base_db::FileId; 88use base_db::FileId;
73use hir_def::{ 89use hir_def::{