diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-01-11 22:42:39 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-01-11 22:42:39 +0000 |
commit | bcfd297f4910bbf2305ec859d7cf42b7dca25f57 (patch) | |
tree | c6b53cd774e7baacf213e91b295734852a83f40b /crates/ra_hir/src | |
parent | e90aa86fbfa716c4028f38d0d22654065011a964 (diff) | |
parent | ccb75f7c979b56bc62b61fadd81903e11a7f5d74 (diff) |
Merge #2727
2727: Qualify paths in 'add impl members' r=flodiebold a=flodiebold
This makes the 'add impl members' assist qualify paths, so that they should resolve to the same thing as in the definition. To do that, it adds an algorithm that finds a path to refer to any item from any module (if possible), which is actually probably the more important part of this PR :smile: It handles visibility, reexports, renamed crates, prelude etc.; I think the only thing that's missing is support for local items. I'm not sure about the performance, since it takes into account every location where the target item has been `pub use`d, and then recursively goes up the module tree; there's probably potential for optimization by memoizing more, but I think the general shape of the algorithm is necessary to handle every case in Rust's module system.
~The 'find path' part is actually pretty complete, I think; I'm still working on the assist (hence the failing tests).~
Fixes #1943.
Co-authored-by: Florian Diebold <[email protected]>
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/from_id.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 4 |
3 files changed, 35 insertions, 0 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index cc42068a1..df9c151e5 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -227,6 +227,21 @@ impl Module { | |||
227 | pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module { | 227 | pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module { |
228 | Module::new(self.krate(), module_id) | 228 | Module::new(self.krate(), module_id) |
229 | } | 229 | } |
230 | |||
231 | /// Finds a path that can be used to refer to the given item from within | ||
232 | /// this module, if possible. | ||
233 | pub fn find_use_path( | ||
234 | self, | ||
235 | db: &impl DefDatabase, | ||
236 | item: ModuleDef, | ||
237 | ) -> Option<hir_def::path::ModPath> { | ||
238 | // FIXME expose namespace choice | ||
239 | hir_def::find_path::find_path( | ||
240 | db, | ||
241 | hir_def::item_scope::ItemInNs::Types(item.into()), | ||
242 | self.into(), | ||
243 | ) | ||
244 | } | ||
230 | } | 245 | } |
231 | 246 | ||
232 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 247 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 75a1a7772..c16c17072 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -91,6 +91,22 @@ impl From<ModuleDefId> for ModuleDef { | |||
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | impl From<ModuleDef> for ModuleDefId { | ||
95 | fn from(id: ModuleDef) -> Self { | ||
96 | match id { | ||
97 | ModuleDef::Module(it) => ModuleDefId::ModuleId(it.into()), | ||
98 | ModuleDef::Function(it) => ModuleDefId::FunctionId(it.into()), | ||
99 | ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()), | ||
100 | ModuleDef::EnumVariant(it) => ModuleDefId::EnumVariantId(it.into()), | ||
101 | ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()), | ||
102 | ModuleDef::Static(it) => ModuleDefId::StaticId(it.into()), | ||
103 | ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()), | ||
104 | ModuleDef::TypeAlias(it) => ModuleDefId::TypeAliasId(it.into()), | ||
105 | ModuleDef::BuiltinType(it) => ModuleDefId::BuiltinType(it), | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | |||
94 | impl From<DefWithBody> for DefWithBodyId { | 110 | impl From<DefWithBody> for DefWithBodyId { |
95 | fn from(def: DefWithBody) -> Self { | 111 | fn from(def: DefWithBody) -> Self { |
96 | match def { | 112 | match def { |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 2c422af8b..a2a9d968c 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -205,6 +205,10 @@ impl SourceAnalyzer { | |||
205 | } | 205 | } |
206 | } | 206 | } |
207 | 207 | ||
208 | pub fn module(&self) -> Option<crate::code_model::Module> { | ||
209 | Some(crate::code_model::Module { id: self.resolver.module()? }) | ||
210 | } | ||
211 | |||
208 | fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { | 212 | fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { |
209 | let src = InFile { file_id: self.file_id, value: expr }; | 213 | let src = InFile { file_id: self.file_id, value: expr }; |
210 | self.body_source_map.as_ref()?.node_expr(src) | 214 | self.body_source_map.as_ref()?.node_expr(src) |