aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/path.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-01-11 22:42:39 +0000
committerGitHub <[email protected]>2020-01-11 22:42:39 +0000
commitbcfd297f4910bbf2305ec859d7cf42b7dca25f57 (patch)
treec6b53cd774e7baacf213e91b295734852a83f40b /crates/ra_hir_def/src/path.rs
parente90aa86fbfa716c4028f38d0d22654065011a964 (diff)
parentccb75f7c979b56bc62b61fadd81903e11a7f5d74 (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_def/src/path.rs')
-rw-r--r--crates/ra_hir_def/src/path.rs42
1 files changed, 41 insertions, 1 deletions
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 82cfa67a9..9f93a5424 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -1,7 +1,11 @@
1//! A desugared representation of paths like `crate::foo` or `<Type as Trait>::bar`. 1//! A desugared representation of paths like `crate::foo` or `<Type as Trait>::bar`.
2mod lower; 2mod lower;
3 3
4use std::{iter, sync::Arc}; 4use std::{
5 fmt::{self, Display},
6 iter,
7 sync::Arc,
8};
5 9
6use hir_expand::{ 10use hir_expand::{
7 hygiene::Hygiene, 11 hygiene::Hygiene,
@@ -248,6 +252,42 @@ impl From<Name> for ModPath {
248 } 252 }
249} 253}
250 254
255impl Display for ModPath {
256 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
257 let mut first_segment = true;
258 let mut add_segment = |s| {
259 if !first_segment {
260 f.write_str("::")?;
261 }
262 first_segment = false;
263 f.write_str(s)?;
264 Ok(())
265 };
266 match self.kind {
267 PathKind::Plain => {}
268 PathKind::Super(n) => {
269 if n == 0 {
270 add_segment("self")?;
271 }
272 for _ in 0..n {
273 add_segment("super")?;
274 }
275 }
276 PathKind::Crate => add_segment("crate")?,
277 PathKind::Abs => add_segment("")?,
278 PathKind::DollarCrate(_) => add_segment("$crate")?,
279 }
280 for segment in &self.segments {
281 if !first_segment {
282 f.write_str("::")?;
283 }
284 first_segment = false;
285 write!(f, "{}", segment)?;
286 }
287 Ok(())
288 }
289}
290
251pub use hir_expand::name as __name; 291pub use hir_expand::name as __name;
252 292
253#[macro_export] 293#[macro_export]