Skip to content

Commit 7dc0d33

Browse files
committed
Refactor resolve_with_disambiguator into a separate function
1 parent 245f69a commit 7dc0d33

File tree

1 file changed

+190
-163
lines changed

1 file changed

+190
-163
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

+190-163
Original file line numberDiff line numberDiff line change
@@ -998,169 +998,19 @@ impl LinkCollector<'_, '_> {
998998
}
999999
}
10001000

1001-
match disambiguator.map(Disambiguator::ns) {
1002-
Some(ns @ (ValueNS | TypeNS)) => {
1003-
match self.resolve(path_str, ns, &current_item, base_node, &extra_fragment) {
1004-
Ok(res) => res,
1005-
Err(ErrorKind::Resolve(box mut kind)) => {
1006-
// We only looked in one namespace. Try to give a better error if possible.
1007-
if kind.full_res().is_none() {
1008-
let other_ns = if ns == ValueNS { TypeNS } else { ValueNS };
1009-
for &new_ns in &[other_ns, MacroNS] {
1010-
if let Some(res) = self.check_full_res(
1011-
new_ns,
1012-
path_str,
1013-
base_node,
1014-
&current_item,
1015-
&extra_fragment,
1016-
) {
1017-
kind = ResolutionFailure::WrongNamespace(res, ns);
1018-
break;
1019-
}
1020-
}
1021-
}
1022-
resolution_failure(
1023-
self,
1024-
&item,
1025-
path_str,
1026-
disambiguator,
1027-
dox,
1028-
link_range,
1029-
smallvec![kind],
1030-
);
1031-
// This could just be a normal link or a broken link
1032-
// we could potentially check if something is
1033-
// "intra-doc-link-like" and warn in that case.
1034-
return;
1035-
}
1036-
Err(ErrorKind::AnchorFailure(msg)) => {
1037-
anchor_failure(cx, &item, &ori_link, dox, link_range, msg);
1038-
return;
1039-
}
1040-
}
1041-
}
1042-
None => {
1043-
// Try everything!
1044-
let mut candidates = PerNS {
1045-
macro_ns: self
1046-
.macro_resolve(path_str, base_node)
1047-
.map(|res| (res, extra_fragment.clone())),
1048-
type_ns: match self.resolve(
1049-
path_str,
1050-
TypeNS,
1051-
&current_item,
1052-
base_node,
1053-
&extra_fragment,
1054-
) {
1055-
Ok(res) => {
1056-
debug!("got res in TypeNS: {:?}", res);
1057-
Ok(res)
1058-
}
1059-
Err(ErrorKind::AnchorFailure(msg)) => {
1060-
anchor_failure(cx, &item, &ori_link, dox, link_range, msg);
1061-
return;
1062-
}
1063-
Err(ErrorKind::Resolve(box kind)) => Err(kind),
1064-
},
1065-
value_ns: match self.resolve(
1066-
path_str,
1067-
ValueNS,
1068-
&current_item,
1069-
base_node,
1070-
&extra_fragment,
1071-
) {
1072-
Ok(res) => Ok(res),
1073-
Err(ErrorKind::AnchorFailure(msg)) => {
1074-
anchor_failure(cx, &item, &ori_link, dox, link_range, msg);
1075-
return;
1076-
}
1077-
Err(ErrorKind::Resolve(box kind)) => Err(kind),
1078-
}
1079-
.and_then(|(res, fragment)| {
1080-
// Constructors are picked up in the type namespace.
1081-
match res {
1082-
Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => {
1083-
Err(ResolutionFailure::WrongNamespace(res, TypeNS))
1084-
}
1085-
_ => match (fragment, extra_fragment) {
1086-
(Some(fragment), Some(_)) => {
1087-
// Shouldn't happen but who knows?
1088-
Ok((res, Some(fragment)))
1089-
}
1090-
(fragment, None) | (None, fragment) => Ok((res, fragment)),
1091-
},
1092-
}
1093-
}),
1094-
};
1095-
1096-
let len = candidates.iter().filter(|res| res.is_ok()).count();
1097-
1098-
if len == 0 {
1099-
resolution_failure(
1100-
self,
1101-
&item,
1102-
path_str,
1103-
disambiguator,
1104-
dox,
1105-
link_range,
1106-
candidates.into_iter().filter_map(|res| res.err()).collect(),
1107-
);
1108-
// this could just be a normal link
1109-
return;
1110-
}
1111-
1112-
if len == 1 {
1113-
candidates.into_iter().filter_map(|res| res.ok()).next().unwrap()
1114-
} else if len == 2 && is_derive_trait_collision(&candidates) {
1115-
candidates.type_ns.unwrap()
1116-
} else {
1117-
if is_derive_trait_collision(&candidates) {
1118-
candidates.macro_ns = Err(ResolutionFailure::Dummy);
1119-
}
1120-
// If we're reporting an ambiguity, don't mention the namespaces that failed
1121-
let candidates =
1122-
candidates.map(|candidate| candidate.ok().map(|(res, _)| res));
1123-
ambiguity_error(
1124-
cx,
1125-
&item,
1126-
path_str,
1127-
dox,
1128-
link_range,
1129-
candidates.present_items().collect(),
1130-
);
1131-
return;
1132-
}
1133-
}
1134-
Some(MacroNS) => {
1135-
match self.macro_resolve(path_str, base_node) {
1136-
Ok(res) => (res, extra_fragment),
1137-
Err(mut kind) => {
1138-
// `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
1139-
for &ns in &[TypeNS, ValueNS] {
1140-
if let Some(res) = self.check_full_res(
1141-
ns,
1142-
path_str,
1143-
base_node,
1144-
&current_item,
1145-
&extra_fragment,
1146-
) {
1147-
kind = ResolutionFailure::WrongNamespace(res, MacroNS);
1148-
break;
1149-
}
1150-
}
1151-
resolution_failure(
1152-
self,
1153-
&item,
1154-
path_str,
1155-
disambiguator,
1156-
dox,
1157-
link_range,
1158-
smallvec![kind],
1159-
);
1160-
return;
1161-
}
1162-
}
1163-
}
1001+
match self.resolve_with_disambiguator(
1002+
disambiguator,
1003+
item,
1004+
dox,
1005+
path_str,
1006+
current_item,
1007+
base_node,
1008+
extra_fragment,
1009+
&ori_link,
1010+
link_range.clone(),
1011+
) {
1012+
Some(x) => x,
1013+
None => return,
11641014
}
11651015
};
11661016

@@ -1274,6 +1124,183 @@ impl LinkCollector<'_, '_> {
12741124
item.attrs.links.push(ItemLink { link: ori_link, link_text, did: Some(id), fragment });
12751125
}
12761126
}
1127+
1128+
fn resolve_with_disambiguator(
1129+
&self,
1130+
disambiguator: Option<Disambiguator>,
1131+
item: &mut Item,
1132+
dox: &str,
1133+
path_str: &str,
1134+
current_item: &Option<String>,
1135+
base_node: Option<DefId>,
1136+
extra_fragment: Option<String>,
1137+
ori_link: &str,
1138+
link_range: Option<Range<usize>>,
1139+
) -> Option<(Res, Option<String>)> {
1140+
match disambiguator.map(Disambiguator::ns) {
1141+
Some(ns @ (ValueNS | TypeNS)) => {
1142+
match self.resolve(path_str, ns, &current_item, base_node, &extra_fragment) {
1143+
Ok(res) => Some(res),
1144+
Err(ErrorKind::Resolve(box mut kind)) => {
1145+
// We only looked in one namespace. Try to give a better error if possible.
1146+
if kind.full_res().is_none() {
1147+
let other_ns = if ns == ValueNS { TypeNS } else { ValueNS };
1148+
for &new_ns in &[other_ns, MacroNS] {
1149+
if let Some(res) = self.check_full_res(
1150+
new_ns,
1151+
path_str,
1152+
base_node,
1153+
&current_item,
1154+
&extra_fragment,
1155+
) {
1156+
kind = ResolutionFailure::WrongNamespace(res, ns);
1157+
break;
1158+
}
1159+
}
1160+
}
1161+
resolution_failure(
1162+
self,
1163+
&item,
1164+
path_str,
1165+
disambiguator,
1166+
dox,
1167+
link_range,
1168+
smallvec![kind],
1169+
);
1170+
// This could just be a normal link or a broken link
1171+
// we could potentially check if something is
1172+
// "intra-doc-link-like" and warn in that case.
1173+
return None;
1174+
}
1175+
Err(ErrorKind::AnchorFailure(msg)) => {
1176+
anchor_failure(self.cx, &item, &ori_link, dox, link_range, msg);
1177+
return None;
1178+
}
1179+
}
1180+
}
1181+
None => {
1182+
// Try everything!
1183+
let mut candidates = PerNS {
1184+
macro_ns: self
1185+
.macro_resolve(path_str, base_node)
1186+
.map(|res| (res, extra_fragment.clone())),
1187+
type_ns: match self.resolve(
1188+
path_str,
1189+
TypeNS,
1190+
&current_item,
1191+
base_node,
1192+
&extra_fragment,
1193+
) {
1194+
Ok(res) => {
1195+
debug!("got res in TypeNS: {:?}", res);
1196+
Ok(res)
1197+
}
1198+
Err(ErrorKind::AnchorFailure(msg)) => {
1199+
anchor_failure(self.cx, &item, ori_link, dox, link_range, msg);
1200+
return None;
1201+
}
1202+
Err(ErrorKind::Resolve(box kind)) => Err(kind),
1203+
},
1204+
value_ns: match self.resolve(
1205+
path_str,
1206+
ValueNS,
1207+
&current_item,
1208+
base_node,
1209+
&extra_fragment,
1210+
) {
1211+
Ok(res) => Ok(res),
1212+
Err(ErrorKind::AnchorFailure(msg)) => {
1213+
anchor_failure(self.cx, &item, ori_link, dox, link_range, msg);
1214+
return None;
1215+
}
1216+
Err(ErrorKind::Resolve(box kind)) => Err(kind),
1217+
}
1218+
.and_then(|(res, fragment)| {
1219+
// Constructors are picked up in the type namespace.
1220+
match res {
1221+
Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => {
1222+
Err(ResolutionFailure::WrongNamespace(res, TypeNS))
1223+
}
1224+
_ => match (fragment, extra_fragment) {
1225+
(Some(fragment), Some(_)) => {
1226+
// Shouldn't happen but who knows?
1227+
Ok((res, Some(fragment)))
1228+
}
1229+
(fragment, None) | (None, fragment) => Ok((res, fragment)),
1230+
},
1231+
}
1232+
}),
1233+
};
1234+
1235+
let len = candidates.iter().filter(|res| res.is_ok()).count();
1236+
1237+
if len == 0 {
1238+
resolution_failure(
1239+
self,
1240+
&item,
1241+
path_str,
1242+
disambiguator,
1243+
dox,
1244+
link_range,
1245+
candidates.into_iter().filter_map(|res| res.err()).collect(),
1246+
);
1247+
// this could just be a normal link
1248+
return None;
1249+
}
1250+
1251+
if len == 1 {
1252+
Some(candidates.into_iter().filter_map(|res| res.ok()).next().unwrap())
1253+
} else if len == 2 && is_derive_trait_collision(&candidates) {
1254+
Some(candidates.type_ns.unwrap())
1255+
} else {
1256+
if is_derive_trait_collision(&candidates) {
1257+
candidates.macro_ns = Err(ResolutionFailure::Dummy);
1258+
}
1259+
// If we're reporting an ambiguity, don't mention the namespaces that failed
1260+
let candidates = candidates.map(|candidate| candidate.ok().map(|(res, _)| res));
1261+
ambiguity_error(
1262+
self.cx,
1263+
&item,
1264+
path_str,
1265+
dox,
1266+
link_range,
1267+
candidates.present_items().collect(),
1268+
);
1269+
return None;
1270+
}
1271+
}
1272+
Some(MacroNS) => {
1273+
match self.macro_resolve(path_str, base_node) {
1274+
Ok(res) => Some((res, extra_fragment)),
1275+
Err(mut kind) => {
1276+
// `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
1277+
for &ns in &[TypeNS, ValueNS] {
1278+
if let Some(res) = self.check_full_res(
1279+
ns,
1280+
path_str,
1281+
base_node,
1282+
&current_item,
1283+
&extra_fragment,
1284+
) {
1285+
kind = ResolutionFailure::WrongNamespace(res, MacroNS);
1286+
break;
1287+
}
1288+
}
1289+
resolution_failure(
1290+
self,
1291+
&item,
1292+
path_str,
1293+
disambiguator,
1294+
dox,
1295+
link_range,
1296+
smallvec![kind],
1297+
);
1298+
return None;
1299+
}
1300+
}
1301+
}
1302+
}
1303+
}
12771304
}
12781305

12791306
#[derive(Copy, Clone, Debug, PartialEq, Eq)]

0 commit comments

Comments
 (0)