diff options
Diffstat (limited to 'crates/hir_def/src/path')
-rw-r--r-- | crates/hir_def/src/path/lower.rs | 15 | ||||
-rw-r--r-- | crates/hir_def/src/path/lower/lower_use.rs | 7 |
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 |