Skip to content

Commit fc3a405

Browse files
committed
still verify disambiguators for primitives
1 parent e33a205 commit fc3a405

File tree

1 file changed

+57
-47
lines changed

1 file changed

+57
-47
lines changed

Diff for: src/librustdoc/passes/collect_intra_doc_links.rs

+57-47
Original file line numberDiff line numberDiff line change
@@ -1146,60 +1146,70 @@ impl LinkCollector<'_, '_> {
11461146
callback,
11471147
);
11481148
};
1149-
match res {
1150-
Res::Primitive(_) if self.kind_side_channel.get().is_none() => match disambiguator {
1151-
Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => {
1152-
Some(ItemLink { link: ori_link.link, link_text, did: None, fragment })
1153-
}
1154-
Some(other) => {
1155-
report_mismatch(other, Disambiguator::Primitive);
1156-
None
1157-
}
1158-
},
1159-
Res::Primitive(_) => Some(ItemLink { link: ori_link, link_text, did: None, fragment }),
1160-
Res::Def(kind, id) => {
1161-
debug!("intra-doc link to {} resolved to {:?}", path_str, res);
1162-
1163-
// Disallow e.g. linking to enums with `struct@`
1164-
debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator);
1165-
match (self.kind_side_channel.take().map(|(kind, _)| kind).unwrap_or(kind), disambiguator) {
1166-
| (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const)))
1167-
// NOTE: this allows 'method' to mean both normal functions and associated functions
1168-
// This can't cause ambiguity because both are in the same namespace.
1169-
| (DefKind::Fn | DefKind::AssocFn, Some(Disambiguator::Kind(DefKind::Fn)))
1170-
// These are namespaces; allow anything in the namespace to match
1171-
| (_, Some(Disambiguator::Namespace(_)))
1172-
// If no disambiguator given, allow anything
1173-
| (_, None)
1174-
// All of these are valid, so do nothing
1175-
=> {}
1176-
(actual, Some(Disambiguator::Kind(expected))) if actual == expected => {}
1177-
(_, Some(specified @ Disambiguator::Kind(_) | specified @ Disambiguator::Primitive)) => {
1178-
report_mismatch(specified, Disambiguator::Kind(kind));
1179-
return None;
1149+
1150+
let (kind, id) = match res {
1151+
Res::Primitive(_) => {
1152+
if let Some((kind, id)) = self.kind_side_channel.take() {
1153+
(kind, id)
1154+
} else {
1155+
match disambiguator {
1156+
Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => {
1157+
return Some(ItemLink {
1158+
link: ori_link.link,
1159+
link_text,
1160+
did: None,
1161+
fragment,
1162+
});
1163+
}
1164+
Some(other) => {
1165+
report_mismatch(other, Disambiguator::Primitive);
1166+
return None;
1167+
}
11801168
}
11811169
}
1170+
}
1171+
Res::Def(kind, id) => (kind, id),
1172+
};
11821173

1183-
// item can be non-local e.g. when using #[doc(primitive = "pointer")]
1184-
if let Some((src_id, dst_id)) = id
1185-
.as_local()
1186-
.and_then(|dst_id| item.def_id.as_local().map(|src_id| (src_id, dst_id)))
1187-
{
1188-
use rustc_hir::def_id::LOCAL_CRATE;
1174+
debug!("intra-doc link to {} resolved to {:?}", path_str, res);
1175+
1176+
// Disallow e.g. linking to enums with `struct@`
1177+
debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator);
1178+
match (self.kind_side_channel.take().map(|(kind, _)| kind).unwrap_or(kind), disambiguator) {
1179+
| (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const)))
1180+
// NOTE: this allows 'method' to mean both normal functions and associated functions
1181+
// This can't cause ambiguity because both are in the same namespace.
1182+
| (DefKind::Fn | DefKind::AssocFn, Some(Disambiguator::Kind(DefKind::Fn)))
1183+
// These are namespaces; allow anything in the namespace to match
1184+
| (_, Some(Disambiguator::Namespace(_)))
1185+
// If no disambiguator given, allow anything
1186+
| (_, None)
1187+
// All of these are valid, so do nothing
1188+
=> {}
1189+
(actual, Some(Disambiguator::Kind(expected))) if actual == expected => {}
1190+
(_, Some(specified @ Disambiguator::Kind(_) | specified @ Disambiguator::Primitive)) => {
1191+
report_mismatch(specified, Disambiguator::Kind(kind));
1192+
return None;
1193+
}
1194+
}
11891195

1190-
let hir_src = self.cx.tcx.hir().local_def_id_to_hir_id(src_id);
1191-
let hir_dst = self.cx.tcx.hir().local_def_id_to_hir_id(dst_id);
1196+
// item can be non-local e.g. when using #[doc(primitive = "pointer")]
1197+
if let Some((src_id, dst_id)) =
1198+
id.as_local().and_then(|dst_id| item.def_id.as_local().map(|src_id| (src_id, dst_id)))
1199+
{
1200+
use rustc_hir::def_id::LOCAL_CRATE;
11921201

1193-
if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src)
1194-
&& !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst)
1195-
{
1196-
privacy_error(cx, &item, &path_str, dox, &ori_link);
1197-
}
1198-
}
1199-
let id = clean::register_res(cx, rustc_hir::def::Res::Def(kind, id));
1200-
Some(ItemLink { link: ori_link.link, link_text, did: Some(id), fragment })
1202+
let hir_src = self.cx.tcx.hir().local_def_id_to_hir_id(src_id);
1203+
let hir_dst = self.cx.tcx.hir().local_def_id_to_hir_id(dst_id);
1204+
1205+
if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src)
1206+
&& !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst)
1207+
{
1208+
privacy_error(cx, &item, &path_str, dox, &ori_link);
12011209
}
12021210
}
1211+
let id = clean::register_res(cx, rustc_hir::def::Res::Def(kind, id));
1212+
Some(ItemLink { link: ori_link.link, link_text, did: Some(id), fragment })
12031213
}
12041214

12051215
fn resolve_with_disambiguator_cached(

0 commit comments

Comments
 (0)