@@ -54,12 +54,6 @@ enum ErrorKind<'a> {
5454 AnchorFailure ( AnchorFailure ) ,
5555}
5656
57- impl < ' a > From < ResolutionFailure < ' a > > for ErrorKind < ' a > {
58- fn from ( err : ResolutionFailure < ' a > ) -> Self {
59- ErrorKind :: Resolve ( box err)
60- }
61- }
62-
6357#[ derive( Copy , Clone , Debug , Hash ) ]
6458enum Res {
6559 Def ( DefKind , DefId ) ,
@@ -371,7 +365,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
371365 path_str : & ' path str ,
372366 item_id : ItemId ,
373367 module_id : DefId ,
374- ) -> Result < ( Res , Option < ItemFragment > ) , ErrorKind < ' path > > {
368+ ) -> Result < ( Res , Option < ItemFragment > ) , ResolutionFailure < ' path > > {
375369 let tcx = self . cx . tcx ;
376370 let no_res = || ResolutionFailure :: NotResolved {
377371 item_id,
@@ -445,25 +439,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
445439 } )
446440 }
447441
448- /// Resolves a string as a macro.
449- ///
450- /// FIXME(jynelson): Can this be unified with `resolve()`?
451- fn resolve_macro (
452- & self ,
453- path_str : & ' a str ,
454- item_id : ItemId ,
455- module_id : DefId ,
456- ) -> Result < Res , ResolutionFailure < ' a > > {
457- self . resolve_path ( path_str, MacroNS , item_id, module_id) . ok_or_else ( || {
458- ResolutionFailure :: NotResolved {
459- item_id,
460- module_id,
461- partial_res : None ,
462- unresolved : path_str. into ( ) ,
463- }
464- } )
465- }
466-
467442 fn resolve_self_ty ( & self , path_str : & str , ns : Namespace , item_id : ItemId ) -> Option < Res > {
468443 if ns != TypeNS || path_str != "Self" {
469444 return None ;
@@ -556,12 +531,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
556531 module_id : DefId ,
557532 user_fragment : & Option < String > ,
558533 ) -> Result < ( Res , Option < UrlFragment > ) , ErrorKind < ' path > > {
559- let ( res, rustdoc_fragment) = self . resolve_inner ( path_str, ns, item_id, module_id) ?;
534+ let ( res, rustdoc_fragment) = self
535+ . resolve_inner ( path_str, ns, item_id, module_id)
536+ . map_err ( |err| ErrorKind :: Resolve ( box err) ) ?;
560537 let chosen_fragment = match ( user_fragment, rustdoc_fragment) {
561- ( Some ( _) , Some ( r_frag) ) => {
562- let diag_res = match r_frag {
563- ItemFragment ( _, did) => Res :: Def ( self . cx . tcx . def_kind ( did) , did) ,
564- } ;
538+ ( Some ( _) , Some ( ItemFragment ( _, did) ) ) => {
539+ let diag_res = Res :: Def ( self . cx . tcx . def_kind ( did) , did) ;
565540 let failure = AnchorFailure :: RustdocAnchorConflict ( diag_res) ;
566541 return Err ( ErrorKind :: AnchorFailure ( failure) ) ;
567542 }
@@ -578,7 +553,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
578553 ns : Namespace ,
579554 item_id : ItemId ,
580555 module_id : DefId ,
581- ) -> Result < ( Res , Option < ItemFragment > ) , ErrorKind < ' path > > {
556+ ) -> Result < ( Res , Option < ItemFragment > ) , ResolutionFailure < ' path > > {
582557 if let Some ( res) = self . resolve_path ( path_str, ns, item_id, module_id) {
583558 match res {
584559 // FIXME(#76467): make this fallthrough to lookup the associated
@@ -595,6 +570,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
595570 // Not a trait item; just return what we found.
596571 _ => return Ok ( ( res, None ) ) ,
597572 }
573+ } else if ns == MacroNS {
574+ return Err ( ResolutionFailure :: NotResolved {
575+ item_id,
576+ module_id,
577+ partial_res : None ,
578+ unresolved : path_str. into ( ) ,
579+ } ) ;
598580 }
599581
600582 // Try looking for methods and associated items.
@@ -639,8 +621,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
639621 module_id,
640622 partial_res : None ,
641623 unresolved : path_root. into ( ) ,
642- }
643- . into ( ) )
624+ } )
644625 }
645626 } )
646627 }
@@ -862,26 +843,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
862843 module_id : DefId ,
863844 extra_fragment : & Option < String > ,
864845 ) -> Option < Res > {
865- // resolve() can't be used for macro namespace
866- let result = match ns {
867- Namespace :: MacroNS => self
868- . resolve_macro ( path_str, item_id, module_id)
869- . map ( |res| ( res, None ) )
870- . map_err ( ErrorKind :: from) ,
871- Namespace :: TypeNS | Namespace :: ValueNS => {
872- self . resolve ( path_str, ns, item_id, module_id, extra_fragment)
873- }
874- } ;
875-
876- let res = match result {
846+ let res = match self . resolve ( path_str, ns, item_id, module_id, extra_fragment) {
877847 Ok ( ( res, frag) ) => {
878848 if let Some ( UrlFragment :: Item ( ItemFragment ( _, id) ) ) = frag {
879849 Some ( Res :: Def ( self . cx . tcx . def_kind ( id) , id) )
880850 } else {
881851 Some ( res)
882852 }
883853 }
884- Err ( ErrorKind :: Resolve ( box kind) ) => kind. full_res ( ) ,
854+ Err ( ErrorKind :: Resolve ( kind) ) => kind. full_res ( ) ,
885855 Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict ( res) ) ) => Some ( res) ,
886856 Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: MultipleAnchors ) ) => None ,
887857 } ;
@@ -1481,80 +1451,57 @@ impl LinkCollector<'_, '_> {
14811451 let extra_fragment = & key. extra_fragment ;
14821452
14831453 match disambiguator. map ( Disambiguator :: ns) {
1484- Some ( expected_ns @ ( ValueNS | TypeNS ) ) => {
1454+ Some ( expected_ns) => {
14851455 match self . resolve ( path_str, expected_ns, item_id, base_node, extra_fragment) {
14861456 Ok ( res) => Some ( res) ,
1487- Err ( ErrorKind :: Resolve ( box mut kind) ) => {
1457+ Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1458+ anchor_failure ( self . cx , diag, msg) ;
1459+ None
1460+ }
1461+ Err ( ErrorKind :: Resolve ( mut err) ) => {
14881462 // We only looked in one namespace. Try to give a better error if possible.
1489- if kind. full_res ( ) . is_none ( ) {
1490- let other_ns = if expected_ns == ValueNS { TypeNS } else { ValueNS } ;
1491- // FIXME: really it should be `resolution_failure` that does this, not `resolve_with_disambiguator`
1492- // See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach
1493- for new_ns in [ other_ns, MacroNS ] {
1463+ // FIXME: really it should be `resolution_failure` that does this, not `resolve_with_disambiguator`.
1464+ // See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach.
1465+ for other_ns in [ TypeNS , ValueNS , MacroNS ] {
1466+ if other_ns != expected_ns {
14941467 if let Some ( res) = self . check_full_res (
1495- new_ns ,
1468+ other_ns ,
14961469 path_str,
14971470 item_id,
14981471 base_node,
14991472 extra_fragment,
15001473 ) {
1501- kind = ResolutionFailure :: WrongNamespace { res, expected_ns } ;
1474+ * err = ResolutionFailure :: WrongNamespace { res, expected_ns } ;
15021475 break ;
15031476 }
15041477 }
15051478 }
1506- resolution_failure ( self , diag, path_str, disambiguator, smallvec ! [ kind ] ) ;
1479+ resolution_failure ( self , diag, path_str, disambiguator, smallvec ! [ * err ] ) ;
15071480 // This could just be a normal link or a broken link
15081481 // we could potentially check if something is
15091482 // "intra-doc-link-like" and warn in that case.
15101483 None
15111484 }
1512- Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1513- anchor_failure ( self . cx , diag, msg) ;
1514- None
1515- }
15161485 }
15171486 }
15181487 None => {
15191488 // Try everything!
1520- let candidates = PerNS {
1521- macro_ns : self
1522- . resolve_macro ( path_str, item_id, base_node)
1523- . map ( |res| ( res, extra_fragment. clone ( ) . map ( UrlFragment :: UserWritten ) ) ) ,
1524- type_ns : match self . resolve (
1525- path_str,
1526- TypeNS ,
1527- item_id,
1528- base_node,
1529- extra_fragment,
1530- ) {
1531- Ok ( res) => {
1532- debug ! ( "got res in TypeNS: {:?}" , res) ;
1533- Ok ( res)
1534- }
1489+ let mut candidate =
1490+ |ns| match self . resolve ( path_str, ns, item_id, base_node, extra_fragment) {
1491+ Ok ( res) => Some ( Ok ( res) ) ,
15351492 Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1536- anchor_failure ( self . cx , diag, msg) ;
1537- return None ;
1493+ anchor_failure ( self . cx , diag. clone ( ) , msg) ;
1494+ None
15381495 }
1539- Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
1540- } ,
1541- value_ns : match self . resolve (
1542- path_str,
1543- ValueNS ,
1544- item_id,
1545- base_node,
1546- extra_fragment,
1547- ) {
1548- Ok ( res) => Ok ( res) ,
1549- Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1550- anchor_failure ( self . cx , diag, msg) ;
1551- return None ;
1552- }
1553- Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
1554- }
1555- . and_then ( |( res, fragment) | {
1556- // Constructors are picked up in the type namespace.
1496+ Err ( ErrorKind :: Resolve ( err) ) => Some ( Err ( * err) ) ,
1497+ } ;
1498+
1499+ let candidates = PerNS {
1500+ macro_ns : candidate ( MacroNS ) ?,
1501+ type_ns : candidate ( TypeNS ) ?,
1502+ value_ns : candidate ( ValueNS ) ?. and_then ( |( res, fragment) | {
15571503 match res {
1504+ // Constructors are picked up in the type namespace.
15581505 Res :: Def ( DefKind :: Ctor ( ..) , _) => {
15591506 Err ( ResolutionFailure :: WrongNamespace { res, expected_ns : TypeNS } )
15601507 }
@@ -1604,29 +1551,6 @@ impl LinkCollector<'_, '_> {
16041551 None
16051552 }
16061553 }
1607- Some ( MacroNS ) => {
1608- match self . resolve_macro ( path_str, item_id, base_node) {
1609- Ok ( res) => Some ( ( res, extra_fragment. clone ( ) . map ( UrlFragment :: UserWritten ) ) ) ,
1610- Err ( mut kind) => {
1611- // `resolve_macro` only looks in the macro namespace. Try to give a better error if possible.
1612- for ns in [ TypeNS , ValueNS ] {
1613- if let Some ( res) = self . check_full_res (
1614- ns,
1615- path_str,
1616- item_id,
1617- base_node,
1618- extra_fragment,
1619- ) {
1620- kind =
1621- ResolutionFailure :: WrongNamespace { res, expected_ns : MacroNS } ;
1622- break ;
1623- }
1624- }
1625- resolution_failure ( self , diag, path_str, disambiguator, smallvec ! [ kind] ) ;
1626- None
1627- }
1628- }
1629- }
16301554 }
16311555 }
16321556}
0 commit comments