Skip to content

Commit 7256c6f

Browse files
committed
rustdoc: Remove fn resolve_macro
and otherwise unify resolution in macro namespace and other namespaces
1 parent 95fb05d commit 7256c6f

File tree

1 file changed

+43
-119
lines changed

1 file changed

+43
-119
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 43 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
6458
enum 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

Comments
 (0)