@@ -69,16 +69,21 @@ impl<'a, 'tcx, 'rcx, 'cstore> LinkCollector<'a, 'tcx, 'rcx, 'cstore> {
69
69
/// Resolve a given string as a path, along with whether or not it is
70
70
/// in the value namespace. Also returns an optional URL fragment in the case
71
71
/// of variants and methods
72
- fn resolve ( & self , path_str : & str , is_val : bool , current_item : & Option < String > )
72
+ fn resolve ( & self ,
73
+ path_str : & str ,
74
+ is_val : bool ,
75
+ current_item : & Option < String > ,
76
+ parent_id : Option < NodeId > )
73
77
-> Result < ( Def , Option < String > ) , ( ) >
74
78
{
75
79
let cx = self . cx ;
76
80
77
81
// In case we're in a module, try to resolve the relative
78
82
// path
79
- if let Some ( id) = self . mod_ids . last ( ) {
83
+ if let Some ( id) = parent_id. or ( self . mod_ids . last ( ) . cloned ( ) ) {
84
+ // FIXME: `with_scope` requires the NodeId of a module
80
85
let result = cx. resolver . borrow_mut ( )
81
- . with_scope ( * id,
86
+ . with_scope ( id,
82
87
|resolver| {
83
88
resolver. resolve_str_path_error ( DUMMY_SP ,
84
89
& path_str, is_val)
@@ -129,8 +134,9 @@ impl<'a, 'tcx, 'rcx, 'cstore> LinkCollector<'a, 'tcx, 'rcx, 'cstore> {
129
134
}
130
135
}
131
136
137
+ // FIXME: `with_scope` requires the NodeId of a module
132
138
let ty = cx. resolver . borrow_mut ( )
133
- . with_scope ( * id,
139
+ . with_scope ( id,
134
140
|resolver| {
135
141
resolver. resolve_str_path_error ( DUMMY_SP , & path, false )
136
142
} ) ?;
@@ -218,6 +224,20 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor
218
224
None
219
225
} ;
220
226
227
+ // FIXME: get the resolver to work with non-local resolve scopes
228
+ let parent_node = self . cx . as_local_node_id ( item. def_id ) . and_then ( |node_id| {
229
+ // FIXME: this fails hard for impls in non-module scope, but is necessary for the
230
+ // current resolve() implementation
231
+ match self . cx . tcx . hir . get_module_parent_node ( node_id) {
232
+ id if id != node_id => Some ( id) ,
233
+ _ => None ,
234
+ }
235
+ } ) ;
236
+
237
+ if parent_node. is_some ( ) {
238
+ debug ! ( "got parent node for {} {:?}, id {:?}" , item. type_( ) , item. name, item. def_id) ;
239
+ }
240
+
221
241
let current_item = match item. inner {
222
242
ModuleItem ( ..) => {
223
243
if item. attrs . inner_docs {
@@ -227,10 +247,10 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor
227
247
None
228
248
}
229
249
} else {
230
- match self . mod_ids . last ( ) {
231
- Some ( parent) if * parent != NodeId :: new ( 0 ) => {
250
+ match parent_node . or ( self . mod_ids . last ( ) . cloned ( ) ) {
251
+ Some ( parent) if parent != NodeId :: new ( 0 ) => {
232
252
//FIXME: can we pull the parent module's name from elsewhere?
233
- Some ( self . cx . tcx . hir . name ( * parent) . to_string ( ) )
253
+ Some ( self . cx . tcx . hir . name ( parent) . to_string ( ) )
234
254
}
235
255
_ => None ,
236
256
}
@@ -294,7 +314,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor
294
314
295
315
match kind {
296
316
PathKind :: Value => {
297
- if let Ok ( def) = self . resolve ( path_str, true , & current_item) {
317
+ if let Ok ( def) = self . resolve ( path_str, true , & current_item, parent_node ) {
298
318
def
299
319
} else {
300
320
resolution_failure ( cx, & item. attrs , path_str, & dox, link_range) ;
@@ -305,7 +325,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor
305
325
}
306
326
}
307
327
PathKind :: Type => {
308
- if let Ok ( def) = self . resolve ( path_str, false , & current_item) {
328
+ if let Ok ( def) = self . resolve ( path_str, false , & current_item, parent_node ) {
309
329
def
310
330
} else {
311
331
resolution_failure ( cx, & item. attrs , path_str, & dox, link_range) ;
@@ -316,16 +336,18 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor
316
336
PathKind :: Unknown => {
317
337
// try everything!
318
338
if let Some ( macro_def) = macro_resolve ( cx, path_str) {
319
- if let Ok ( type_def) = self . resolve ( path_str, false , & current_item) {
339
+ if let Ok ( type_def) =
340
+ self . resolve ( path_str, false , & current_item, parent_node)
341
+ {
320
342
let ( type_kind, article, type_disambig)
321
343
= type_ns_kind ( type_def. 0 , path_str) ;
322
344
ambiguity_error ( cx, & item. attrs , path_str,
323
345
article, type_kind, & type_disambig,
324
346
"a" , "macro" , & format ! ( "macro@{}" , path_str) ) ;
325
347
continue ;
326
- } else if let Ok ( value_def) = self . resolve ( path_str ,
327
- true ,
328
- & current_item ) {
348
+ } else if let Ok ( value_def) =
349
+ self . resolve ( path_str , true , & current_item , parent_node )
350
+ {
329
351
let ( value_kind, value_disambig)
330
352
= value_ns_kind ( value_def. 0 , path_str)
331
353
. expect ( "struct and mod cases should have been \
@@ -335,12 +357,16 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor
335
357
"a" , "macro" , & format ! ( "macro@{}" , path_str) ) ;
336
358
}
337
359
( macro_def, None )
338
- } else if let Ok ( type_def) = self . resolve ( path_str, false , & current_item) {
360
+ } else if let Ok ( type_def) =
361
+ self . resolve ( path_str, false , & current_item, parent_node)
362
+ {
339
363
// It is imperative we search for not-a-value first
340
364
// Otherwise we will find struct ctors for when we are looking
341
365
// for structs, and the link won't work.
342
366
// if there is something in both namespaces
343
- if let Ok ( value_def) = self . resolve ( path_str, true , & current_item) {
367
+ if let Ok ( value_def) =
368
+ self . resolve ( path_str, true , & current_item, parent_node)
369
+ {
344
370
let kind = value_ns_kind ( value_def. 0 , path_str) ;
345
371
if let Some ( ( value_kind, value_disambig) ) = kind {
346
372
let ( type_kind, article, type_disambig)
@@ -352,7 +378,9 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor
352
378
}
353
379
}
354
380
type_def
355
- } else if let Ok ( value_def) = self . resolve ( path_str, true , & current_item) {
381
+ } else if let Ok ( value_def) =
382
+ self . resolve ( path_str, true , & current_item, parent_node)
383
+ {
356
384
value_def
357
385
} else {
358
386
resolution_failure ( cx, & item. attrs , path_str, & dox, link_range) ;
0 commit comments