2
2
//!
3
3
//! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md
4
4
5
+ use pulldown_cmark:: LinkType ;
5
6
use rustc_data_structures:: { fx:: FxHashMap , intern:: Interned , stable_set:: FxHashSet } ;
6
7
use rustc_errors:: { Applicability , Diagnostic } ;
7
- use rustc_hir:: def:: {
8
- DefKind ,
9
- Namespace :: { self , * } ,
10
- PerNS ,
11
- } ;
8
+ use rustc_hir:: def:: Namespace :: * ;
9
+ use rustc_hir:: def:: { DefKind , Namespace , PerNS } ;
12
10
use rustc_hir:: def_id:: { DefId , CRATE_DEF_ID } ;
13
11
use rustc_hir:: Mutability ;
14
12
use rustc_middle:: ty:: { DefIdTree , Ty , TyCtxt } ;
@@ -19,10 +17,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
19
17
use rustc_span:: { BytePos , DUMMY_SP } ;
20
18
use smallvec:: { smallvec, SmallVec } ;
21
19
22
- use pulldown_cmark:: LinkType ;
23
-
24
20
use std:: borrow:: Cow ;
25
- use std:: convert:: { TryFrom , TryInto } ;
26
21
use std:: fmt:: Write ;
27
22
use std:: mem;
28
23
use std:: ops:: Range ;
@@ -487,25 +482,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
487
482
item_id : ItemId ,
488
483
module_id : DefId ,
489
484
) -> Result < Res , ResolutionFailure < ' a > > {
490
- self . cx . enter_resolver ( |resolver| {
491
- // NOTE: this needs 2 separate lookups because `resolve_rustdoc_path` doesn't take
492
- // lexical scope into account (it ignores all macros not defined at the mod-level)
493
- debug ! ( "resolving {} as a macro in the module {:?}" , path_str, module_id) ;
494
- if let Some ( res) = resolver. resolve_rustdoc_path ( path_str, MacroNS , module_id) {
495
- // don't resolve builtins like `#[derive]`
496
- if let Ok ( res) = res. try_into ( ) {
497
- return Ok ( res) ;
498
- }
499
- }
500
- if let Some ( & res) = resolver. all_macros ( ) . get ( & Symbol :: intern ( path_str) ) {
501
- return Ok ( res. try_into ( ) . unwrap ( ) ) ;
502
- }
503
- Err ( ResolutionFailure :: NotResolved {
485
+ self . resolve_path ( path_str, MacroNS , item_id, module_id) . ok_or_else ( || {
486
+ ResolutionFailure :: NotResolved {
504
487
item_id,
505
488
module_id,
506
489
partial_res : None ,
507
490
unresolved : path_str. into ( ) ,
508
- } )
491
+ }
509
492
} )
510
493
}
511
494
@@ -539,6 +522,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
539
522
} )
540
523
}
541
524
525
+ /// HACK: Try to search the macro name in the list of all `macro_rules` items in the crate.
526
+ /// Used when nothing else works, may often give an incorrect result.
527
+ fn resolve_macro_rules ( & self , path_str : & str , ns : Namespace ) -> Option < Res > {
528
+ if ns != MacroNS {
529
+ return None ;
530
+ }
531
+
532
+ self . cx
533
+ . resolver_caches
534
+ . all_macro_rules
535
+ . get ( & Symbol :: intern ( path_str) )
536
+ . copied ( )
537
+ . and_then ( |res| res. try_into ( ) . ok ( ) )
538
+ }
539
+
542
540
/// Convenience wrapper around `resolve_rustdoc_path`.
543
541
///
544
542
/// This also handles resolving `true` and `false` as booleans.
@@ -560,7 +558,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
560
558
. cx
561
559
. enter_resolver ( |resolver| resolver. resolve_rustdoc_path ( path_str, ns, module_id) )
562
560
. and_then ( |res| res. try_into ( ) . ok ( ) )
563
- . or_else ( || resolve_primitive ( path_str, ns) ) ;
561
+ . or_else ( || resolve_primitive ( path_str, ns) )
562
+ . or_else ( || self . resolve_macro_rules ( path_str, ns) ) ;
564
563
debug ! ( "{} resolved to {:?} in namespace {:?}" , path_str, result, ns) ;
565
564
result
566
565
}
0 commit comments