diff options
Diffstat (limited to 'crates/hir/src')
-rw-r--r-- | crates/hir/src/semantics/source_to_def.rs | 20 |
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 | ||
72 | use base_db::FileId; | 88 | use base_db::FileId; |
73 | use hir_def::{ | 89 | use hir_def::{ |