aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/path
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/path')
-rw-r--r--crates/hir_def/src/path/lower.rs15
-rw-r--r--crates/hir_def/src/path/lower/lower_use.rs7
2 files changed, 16 insertions, 6 deletions
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs
index 9518ac109..505493a74 100644
--- a/crates/hir_def/src/path/lower.rs
+++ b/crates/hir_def/src/path/lower.rs
@@ -101,8 +101,12 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
101 break; 101 break;
102 } 102 }
103 ast::PathSegmentKind::SelfKw => { 103 ast::PathSegmentKind::SelfKw => {
104 kind = PathKind::Super(0); 104 // don't break out if `self` is the last segment of a path, this mean we got an
105 break; 105 // use tree like `foo::{self}` which we want to resolve as `foo`
106 if !segments.is_empty() {
107 kind = PathKind::Super(0);
108 break;
109 }
106 } 110 }
107 ast::PathSegmentKind::SuperKw => { 111 ast::PathSegmentKind::SuperKw => {
108 let nested_super_count = if let PathKind::Super(n) = kind { n } else { 0 }; 112 let nested_super_count = if let PathKind::Super(n) = kind { n } else { 0 };
@@ -117,6 +121,11 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
117 segments.reverse(); 121 segments.reverse();
118 generic_args.reverse(); 122 generic_args.reverse();
119 123
124 if segments.is_empty() && kind == PathKind::Plain && type_anchor.is_none() {
125 // plain empty paths don't exist, this means we got a single `self` segment as our path
126 kind = PathKind::Super(0);
127 }
128
120 // handle local_inner_macros : 129 // handle local_inner_macros :
121 // Basically, even in rustc it is quite hacky: 130 // Basically, even in rustc it is quite hacky:
122 // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 131 // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456
@@ -129,7 +138,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
129 } 138 }
130 } 139 }
131 140
132 let mod_path = ModPath { kind, segments }; 141 let mod_path = ModPath::from_segments(kind, segments);
133 return Some(Path { type_anchor, mod_path, generic_args }); 142 return Some(Path { type_anchor, mod_path, generic_args });
134 143
135 fn qualifier(path: &ast::Path) -> Option<ast::Path> { 144 fn qualifier(path: &ast::Path) -> Option<ast::Path> {
diff --git a/crates/hir_def/src/path/lower/lower_use.rs b/crates/hir_def/src/path/lower/lower_use.rs
index ba0d1f0e7..d584b0b70 100644
--- a/crates/hir_def/src/path/lower/lower_use.rs
+++ b/crates/hir_def/src/path/lower/lower_use.rs
@@ -75,9 +75,10 @@ fn convert_path(prefix: Option<ModPath>, path: ast::Path, hygiene: &Hygiene) ->
75 match hygiene.name_ref_to_name(name_ref) { 75 match hygiene.name_ref_to_name(name_ref) {
76 Either::Left(name) => { 76 Either::Left(name) => {
77 // no type args in use 77 // no type args in use
78 let mut res = prefix.unwrap_or_else(|| ModPath { 78 let mut res = prefix.unwrap_or_else(|| {
79 kind: segment.coloncolon_token().map_or(PathKind::Plain, |_| PathKind::Abs), 79 ModPath::from_kind(
80 segments: Vec::with_capacity(1), 80 segment.coloncolon_token().map_or(PathKind::Plain, |_| PathKind::Abs),
81 )
81 }); 82 });
82 res.segments.push(name); 83 res.segments.push(name);
83 res 84 res