@@ -51,7 +51,7 @@ impl ModPath {
51
51
path : ast:: Path ,
52
52
span_map : SpanMapRef < ' _ > ,
53
53
) -> Option < ModPath > {
54
- convert_path ( db, None , path, span_map)
54
+ convert_path ( db, path, span_map)
55
55
}
56
56
57
57
pub fn from_tt ( db : & dyn ExpandDatabase , tt : & [ tt:: TokenTree ] ) -> Option < ModPath > {
@@ -199,22 +199,15 @@ fn display_fmt_path(
199
199
200
200
fn convert_path (
201
201
db : & dyn ExpandDatabase ,
202
- prefix : Option < ModPath > ,
203
202
path : ast:: Path ,
204
203
span_map : SpanMapRef < ' _ > ,
205
204
) -> Option < ModPath > {
206
- let prefix = match path. qualifier ( ) {
207
- Some ( qual) => Some ( convert_path ( db, prefix, qual, span_map) ?) ,
208
- None => prefix,
209
- } ;
205
+ let mut segments = path. segments ( ) ;
210
206
211
- let segment = path . segment ( ) ?;
207
+ let segment = & segments . next ( ) ?;
212
208
let mut mod_path = match segment. kind ( ) ? {
213
209
ast:: PathSegmentKind :: Name ( name_ref) => {
214
210
if name_ref. text ( ) == "$crate" {
215
- if prefix. is_some ( ) {
216
- return None ;
217
- }
218
211
ModPath :: from_kind (
219
212
resolve_crate_root (
220
213
db,
@@ -224,48 +217,51 @@ fn convert_path(
224
217
. unwrap_or ( PathKind :: Crate ) ,
225
218
)
226
219
} else {
227
- let mut res = prefix. unwrap_or_else ( || {
228
- ModPath :: from_kind (
229
- segment. coloncolon_token ( ) . map_or ( PathKind :: Plain , |_| PathKind :: Abs ) ,
230
- )
231
- } ) ;
220
+ let mut res = ModPath :: from_kind (
221
+ segment. coloncolon_token ( ) . map_or ( PathKind :: Plain , |_| PathKind :: Abs ) ,
222
+ ) ;
232
223
res. segments . push ( name_ref. as_name ( ) ) ;
233
224
res
234
225
}
235
226
}
236
227
ast:: PathSegmentKind :: SelfTypeKw => {
237
- if prefix. is_some ( ) {
238
- return None ;
239
- }
240
228
ModPath :: from_segments ( PathKind :: Plain , Some ( known:: SELF_TYPE ) )
241
229
}
242
- ast:: PathSegmentKind :: CrateKw => {
243
- if prefix. is_some ( ) {
244
- return None ;
245
- }
246
- ModPath :: from_segments ( PathKind :: Crate , iter:: empty ( ) )
247
- }
248
- ast:: PathSegmentKind :: SelfKw => {
249
- if prefix. is_some ( ) {
250
- return None ;
251
- }
252
- ModPath :: from_segments ( PathKind :: Super ( 0 ) , iter:: empty ( ) )
253
- }
230
+ ast:: PathSegmentKind :: CrateKw => ModPath :: from_segments ( PathKind :: Crate , iter:: empty ( ) ) ,
231
+ ast:: PathSegmentKind :: SelfKw => ModPath :: from_segments ( PathKind :: Super ( 0 ) , iter:: empty ( ) ) ,
254
232
ast:: PathSegmentKind :: SuperKw => {
255
- let nested_super_count = match prefix. map ( |p| p. kind ) {
256
- Some ( PathKind :: Super ( n) ) => n,
257
- Some ( _) => return None ,
258
- None => 0 ,
259
- } ;
233
+ let mut deg = 1 ;
234
+ let mut next_segment = None ;
235
+ while let Some ( segment) = segments. next ( ) {
236
+ match segment. kind ( ) ? {
237
+ ast:: PathSegmentKind :: SuperKw => deg += 1 ,
238
+ ast:: PathSegmentKind :: Name ( name) => {
239
+ next_segment = Some ( name. as_name ( ) ) ;
240
+ break ;
241
+ }
242
+ ast:: PathSegmentKind :: Type { .. }
243
+ | ast:: PathSegmentKind :: SelfTypeKw
244
+ | ast:: PathSegmentKind :: SelfKw
245
+ | ast:: PathSegmentKind :: CrateKw => return None ,
246
+ }
247
+ }
260
248
261
- ModPath :: from_segments ( PathKind :: Super ( nested_super_count + 1 ) , iter :: empty ( ) )
249
+ ModPath :: from_segments ( PathKind :: Super ( deg ) , next_segment )
262
250
}
263
251
ast:: PathSegmentKind :: Type { .. } => {
264
252
// not allowed in imports
265
253
return None ;
266
254
}
267
255
} ;
268
256
257
+ for segment in segments {
258
+ let name = match segment. kind ( ) ? {
259
+ ast:: PathSegmentKind :: Name ( name) => name. as_name ( ) ,
260
+ _ => return None ,
261
+ } ;
262
+ mod_path. segments . push ( name) ;
263
+ }
264
+
269
265
// handle local_inner_macros :
270
266
// Basically, even in rustc it is quite hacky:
271
267
// https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456
0 commit comments