Skip to content

Commit 987c731

Browse files
Integrate generate_macro_def_id_path into href_with_root_path
1 parent f4db07e commit 987c731

File tree

2 files changed

+72
-68
lines changed

2 files changed

+72
-68
lines changed

src/librustdoc/html/format.rs

+70-1
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
use std::borrow::Cow;
99
use std::cell::Cell;
1010
use std::fmt;
11-
use std::iter;
11+
use std::iter::{self, once};
1212

13+
use rustc_ast as ast;
1314
use rustc_attr::{ConstStability, StabilityLevel};
1415
use rustc_data_structures::captures::Captures;
1516
use rustc_data_structures::fx::FxHashSet;
1617
use rustc_hir as hir;
1718
use rustc_hir::def::DefKind;
1819
use rustc_hir::def_id::DefId;
20+
use rustc_metadata::creader::{CStore, LoadedMacro};
1921
use rustc_middle::ty;
2022
use rustc_middle::ty::DefIdTree;
2123
use rustc_middle::ty::TyCtxt;
@@ -557,6 +559,71 @@ pub(crate) fn join_with_double_colon(syms: &[Symbol]) -> String {
557559
s
558560
}
559561

562+
/// This function is to get the external macro path because they are not in the cache used in
563+
/// `href_with_root_path`.
564+
fn generate_macro_def_id_path(
565+
def_id: DefId,
566+
cx: &Context<'_>,
567+
root_path: Option<&str>,
568+
) -> (String, ItemType, Vec<Symbol>) {
569+
let tcx = cx.shared.tcx;
570+
let crate_name = tcx.crate_name(def_id.krate).to_string();
571+
let cache = cx.cache();
572+
573+
let fqp: Vec<Symbol> = tcx
574+
.def_path(def_id)
575+
.data
576+
.into_iter()
577+
.filter_map(|elem| {
578+
// extern blocks (and a few others things) have an empty name.
579+
match elem.data.get_opt_name() {
580+
Some(s) if !s.is_empty() => Some(s),
581+
_ => None,
582+
}
583+
})
584+
.collect();
585+
let relative = fqp.iter().map(|elem| elem.to_string());
586+
// Check to see if it is a macro 2.0 or built-in macro.
587+
// More information in <https://rust-lang.github.io/rfcs/1584-macros.html>.
588+
let is_macro_2 = match CStore::from_tcx(tcx).load_macro_untracked(def_id, tcx.sess) {
589+
LoadedMacro::MacroDef(def, _) => {
590+
// If `ast_def.macro_rules` is `true`, then it's not a macro 2.0.
591+
matches!(&def.kind, ast::ItemKind::MacroDef(ast_def) if !ast_def.macro_rules)
592+
}
593+
_ => false,
594+
};
595+
596+
let mut path = if is_macro_2 {
597+
once(crate_name.clone()).chain(relative).collect()
598+
} else {
599+
vec![crate_name.clone(), relative.last().unwrap()]
600+
};
601+
if path.len() < 2 {
602+
// The minimum we can have is the crate name followed by the macro name. If shorter, then
603+
// it means that that `relative` was empty, which is an error.
604+
panic!("macro path cannot be empty!");
605+
}
606+
607+
if let Some(last) = path.last_mut() {
608+
*last = format!("macro.{}.html", last);
609+
}
610+
611+
let url = match cache.extern_locations[&def_id.krate] {
612+
ExternalLocation::Remote(ref s) => {
613+
// `ExternalLocation::Remote` always end with a `/`.
614+
format!("{}{}", s, path.join("/"))
615+
}
616+
ExternalLocation::Local => {
617+
// `root_path` always end with a `/`.
618+
format!("{}{}/{}", root_path.unwrap_or(""), crate_name, path.join("/"))
619+
}
620+
ExternalLocation::Unknown => {
621+
panic!("crate {} not in cache when linkifying macros", crate_name)
622+
}
623+
};
624+
(url, ItemType::Macro, fqp)
625+
}
626+
560627
pub(crate) fn href_with_root_path(
561628
did: DefId,
562629
cx: &Context<'_>,
@@ -612,6 +679,8 @@ pub(crate) fn href_with_root_path(
612679
ExternalLocation::Unknown => return Err(HrefError::DocumentationNotBuilt),
613680
},
614681
)
682+
} else if matches!(def_kind, DefKind::Macro(_)) {
683+
return Ok(generate_macro_def_id_path(did, cx, root_path));
615684
} else {
616685
return Err(HrefError::NotInExternalCache);
617686
}

src/librustdoc/html/highlight.rs

+2-67
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,15 @@
55
//!
66
//! Use the `render_with_highlighting` to highlight some rust code.
77
8-
use crate::clean::{ExternalLocation, PrimitiveType};
8+
use crate::clean::PrimitiveType;
99
use crate::html::escape::Escape;
1010
use crate::html::render::Context;
1111

1212
use std::collections::VecDeque;
1313
use std::fmt::{Display, Write};
14-
use std::iter::once;
1514

16-
use rustc_ast as ast;
1715
use rustc_data_structures::fx::FxHashMap;
18-
use rustc_hir::def_id::DefId;
1916
use rustc_lexer::{LiteralKind, TokenKind};
20-
use rustc_metadata::creader::{CStore, LoadedMacro};
2117
use rustc_span::edition::Edition;
2218
use rustc_span::symbol::Symbol;
2319
use rustc_span::{BytePos, Span, DUMMY_SP};
@@ -784,17 +780,8 @@ fn string_without_closing_tag<T: Display>(
784780
.map(|s| format!("{}{}", href_context.root_path, s)),
785781
LinkFromSrc::External(def_id) => {
786782
format::href_with_root_path(*def_id, context, Some(href_context.root_path))
787-
.map(|(url, _, _)| url)
788-
.or_else(|e| {
789-
if e == format::HrefError::NotInExternalCache
790-
&& matches!(klass, Class::Macro(_))
791-
{
792-
Ok(generate_macro_def_id_path(href_context, *def_id))
793-
} else {
794-
Err(e)
795-
}
796-
})
797783
.ok()
784+
.map(|(url, _, _)| url)
798785
}
799786
LinkFromSrc::Primitive(prim) => format::href_with_root_path(
800787
PrimitiveType::primitive_locations(context.tcx())[prim],
@@ -814,57 +801,5 @@ fn string_without_closing_tag<T: Display>(
814801
Some("</span>")
815802
}
816803

817-
/// This function is to get the external macro path because they are not in the cache used in
818-
/// `href_with_root_path`.
819-
fn generate_macro_def_id_path(href_context: &HrefContext<'_, '_, '_>, def_id: DefId) -> String {
820-
let tcx = href_context.context.shared.tcx;
821-
let crate_name = tcx.crate_name(def_id.krate).to_string();
822-
let cache = href_context.context.cache();
823-
824-
let relative = tcx.def_path(def_id).data.into_iter().filter_map(|elem| {
825-
// extern blocks have an empty name
826-
let s = elem.data.to_string();
827-
if !s.is_empty() { Some(s) } else { None }
828-
});
829-
// Check to see if it is a macro 2.0 or built-in macro.
830-
// More information in <https://rust-lang.github.io/rfcs/1584-macros.html>.
831-
let is_macro_2 = match CStore::from_tcx(tcx).load_macro_untracked(def_id, tcx.sess) {
832-
LoadedMacro::MacroDef(def, _) => {
833-
// If `ast_def.macro_rules` is `true`, then it's not a macro 2.0.
834-
matches!(&def.kind, ast::ItemKind::MacroDef(ast_def) if !ast_def.macro_rules)
835-
}
836-
_ => false,
837-
};
838-
839-
let mut path = if is_macro_2 {
840-
once(crate_name.clone()).chain(relative).collect()
841-
} else {
842-
vec![crate_name.clone(), relative.last().unwrap()]
843-
};
844-
if path.len() < 2 {
845-
// The minimum we can have is the crate name followed by the macro name. If shorter, then
846-
// it means that that `relative` was empty, which is an error.
847-
panic!("macro path cannot be empty!");
848-
}
849-
850-
if let Some(last) = path.last_mut() {
851-
*last = format!("macro.{}.html", last);
852-
}
853-
854-
match cache.extern_locations[&def_id.krate] {
855-
ExternalLocation::Remote(ref s) => {
856-
// `ExternalLocation::Remote` always end with a `/`.
857-
format!("{}{}", s, path.join("/"))
858-
}
859-
ExternalLocation::Local => {
860-
// `href_context.root_path` always end with a `/`.
861-
format!("{}{}/{}", href_context.root_path, crate_name, path.join("/"))
862-
}
863-
ExternalLocation::Unknown => {
864-
panic!("crate {} not in cache when linkifying macros", crate_name)
865-
}
866-
}
867-
}
868-
869804
#[cfg(test)]
870805
mod tests;

0 commit comments

Comments
 (0)