1
Fork 0

Auto merge of #84279 - Dylan-DPC:rollup-k7otd7e, r=Dylan-DPC

Rollup of 4 pull requests

Successful merges:

 - #83237 (rustdoc: use more precise relative URLs)
 - #84150 (rustdoc: move some search code into search.js)
 - #84203 (rustdoc: Give a more accurate span for anchor failures)
 - #84257 (Add documentation to help people find `Ipv4Addr::UNSPECIFIED`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-04-17 20:41:37 +00:00
commit 392ba2ba1a
55 changed files with 2298 additions and 2257 deletions

View file

@ -334,6 +334,8 @@ impl Ipv4Addr {
/// An IPv4 address representing an unspecified address: 0.0.0.0 /// An IPv4 address representing an unspecified address: 0.0.0.0
/// ///
/// This corresponds to the constant `INADDR_ANY` in other languages.
///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
@ -342,6 +344,7 @@ impl Ipv4Addr {
/// let addr = Ipv4Addr::UNSPECIFIED; /// let addr = Ipv4Addr::UNSPECIFIED;
/// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0)); /// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0));
/// ``` /// ```
#[doc(alias = "INADDR_ANY")]
#[stable(feature = "ip_constructors", since = "1.30.0")] #[stable(feature = "ip_constructors", since = "1.30.0")]
pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0); pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0);

View file

@ -41,6 +41,7 @@ use crate::core::DocContext;
use crate::formats::cache::Cache; use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType; use crate::formats::item_type::ItemType;
use crate::html::render::cache::ExternalLocation; use crate::html::render::cache::ExternalLocation;
use crate::html::render::Context;
use self::FnRetTy::*; use self::FnRetTy::*;
use self::ItemKind::*; use self::ItemKind::*;
@ -193,19 +194,18 @@ impl Item {
self.attrs.collapsed_doc_value() self.attrs.collapsed_doc_value()
} }
crate fn links(&self, cache: &Cache) -> Vec<RenderedLink> { crate fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> {
use crate::html::format::href; use crate::html::format::href;
use crate::html::render::CURRENT_DEPTH;
cache cx.cache()
.intra_doc_links .intra_doc_links
.get(&self.def_id) .get(&self.def_id)
.map_or(&[][..], |v| v.as_slice()) .map_or(&[][..], |v| v.as_slice())
.iter() .iter()
.filter_map(|ItemLink { link: s, link_text, did, fragment }| { .filter_map(|ItemLink { link: s, link_text, did, ref fragment }| {
match *did { match *did {
Some(did) => { Some(did) => {
if let Some((mut href, ..)) = href(did, cache) { if let Some((mut href, ..)) = href(did, cx) {
if let Some(ref fragment) = *fragment { if let Some(ref fragment) = *fragment {
href.push('#'); href.push('#');
href.push_str(fragment); href.push_str(fragment);
@ -219,16 +219,26 @@ impl Item {
None None
} }
} }
// FIXME(83083): using fragments as a side-channel for
// primitive names is very unfortunate
None => { None => {
let relative_to = &cx.current;
if let Some(ref fragment) = *fragment { if let Some(ref fragment) = *fragment {
let url = match cache.extern_locations.get(&self.def_id.krate) { let url = match cx.cache().extern_locations.get(&self.def_id.krate) {
Some(&(_, _, ExternalLocation::Local)) => { Some(&(_, _, ExternalLocation::Local)) => {
let depth = CURRENT_DEPTH.with(|l| l.get()); if relative_to[0] == "std" {
"../".repeat(depth) let depth = relative_to.len() - 1;
"../".repeat(depth)
} else {
let depth = relative_to.len();
format!("{}std/", "../".repeat(depth))
}
}
Some(&(_, _, ExternalLocation::Remote(ref s))) => {
format!("{}/std/", s.trim_end_matches('/'))
} }
Some(&(_, _, ExternalLocation::Remote(ref s))) => s.to_string(),
Some(&(_, _, ExternalLocation::Unknown)) | None => format!( Some(&(_, _, ExternalLocation::Unknown)) | None => format!(
"https://doc.rust-lang.org/{}", "https://doc.rust-lang.org/{}/std/",
crate::doc_rust_lang_org_channel(), crate::doc_rust_lang_org_channel(),
), ),
}; };
@ -238,9 +248,8 @@ impl Item {
original_text: s.clone(), original_text: s.clone(),
new_text: link_text.clone(), new_text: link_text.clone(),
href: format!( href: format!(
"{}{}std/primitive.{}.html{}", "{}primitive.{}.html{}",
url, url,
if !url.ends_with('/') { "/" } else { "" },
&fragment[..tail], &fragment[..tail],
&fragment[tail..] &fragment[tail..]
), ),

File diff suppressed because it is too large Load diff

View file

@ -113,7 +113,8 @@ crate fn render<T: Print, S: Print>(
<section class=\"footer\"></section>\ <section class=\"footer\"></section>\
{after_content}\ {after_content}\
<div id=\"rustdoc-vars\" data-root-path=\"{root_path}\" data-current-crate=\"{krate}\" \ <div id=\"rustdoc-vars\" data-root-path=\"{root_path}\" data-current-crate=\"{krate}\" \
data-search-js=\"{root_path}search-index{suffix}.js\"></div> data-search-index-js=\"{root_path}search-index{suffix}.js\" \
data-search-js=\"{static_root_path}search{suffix}.js\"></div>
<script src=\"{static_root_path}main{suffix}.js\"></script>\ <script src=\"{static_root_path}main{suffix}.js\"></script>\
{extra_scripts}\ {extra_scripts}\
</body>\ </body>\

View file

@ -8,3 +8,6 @@ crate mod render;
crate mod sources; crate mod sources;
crate mod static_files; crate mod static_files;
crate mod toc; crate mod toc;
#[cfg(test)]
mod tests;

View file

@ -40,7 +40,7 @@ use crate::html::{layout, sources};
crate struct Context<'tcx> { crate struct Context<'tcx> {
/// Current hierarchy of components leading down to what's currently being /// Current hierarchy of components leading down to what's currently being
/// rendered /// rendered
pub(super) current: Vec<String>, pub(crate) current: Vec<String>,
/// The current destination folder of where HTML artifacts should be placed. /// The current destination folder of where HTML artifacts should be placed.
/// This changes as the context descends into the module hierarchy. /// This changes as the context descends into the module hierarchy.
pub(super) dst: PathBuf, pub(super) dst: PathBuf,
@ -144,10 +144,14 @@ impl SharedContext<'_> {
} }
impl<'tcx> Context<'tcx> { impl<'tcx> Context<'tcx> {
pub(super) fn tcx(&self) -> TyCtxt<'tcx> { pub(crate) fn tcx(&self) -> TyCtxt<'tcx> {
self.shared.tcx self.shared.tcx
} }
pub(crate) fn cache(&self) -> &Cache {
&self.cache
}
fn sess(&self) -> &'tcx Session { fn sess(&self) -> &'tcx Session {
&self.shared.tcx.sess &self.shared.tcx.sess
} }

View file

@ -51,7 +51,6 @@ use rustc_hir::def::CtorKind;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::Mutability; use rustc_hir::Mutability;
use rustc_middle::middle::stability; use rustc_middle::middle::stability;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use serde::ser::SerializeSeq; use serde::ser::SerializeSeq;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
@ -61,7 +60,7 @@ use crate::docfs::PathError;
use crate::error::Error; use crate::error::Error;
use crate::formats::cache::Cache; use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType; use crate::formats::item_type::ItemType;
use crate::formats::{AssocItemRender, FormatRenderer, Impl, RenderMode}; use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape; use crate::html::escape::Escape;
use crate::html::format::{ use crate::html::format::{
href, print_abi_with_space, print_default_space, print_generic_bounds, print_where_clause, href, print_abi_with_space, print_default_space, print_generic_bounds, print_where_clause,
@ -560,11 +559,10 @@ fn document_short(
return; return;
} }
if let Some(s) = item.doc_value() { if let Some(s) = item.doc_value() {
let mut summary_html = MarkdownSummaryLine(&s, &item.links(&cx.cache)).into_string(); let mut summary_html = MarkdownSummaryLine(&s, &item.links(cx)).into_string();
if s.contains('\n') { if s.contains('\n') {
let link = let link = format!(r#" <a href="{}">Read more</a>"#, naive_assoc_href(item, link, cx));
format!(r#" <a href="{}">Read more</a>"#, naive_assoc_href(item, link, cx.cache()));
if let Some(idx) = summary_html.rfind("</p>") { if let Some(idx) = summary_html.rfind("</p>") {
summary_html.insert_str(idx, &link); summary_html.insert_str(idx, &link);
@ -599,7 +597,7 @@ fn document_full(
) { ) {
if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) { if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) {
debug!("Doc block: =====\n{}\n=====", s); debug!("Doc block: =====\n{}\n=====", s);
render_markdown(w, cx, &*s, item.links(&cx.cache), prefix, is_hidden); render_markdown(w, cx, &*s, item.links(cx), prefix, is_hidden);
} else if !prefix.is_empty() { } else if !prefix.is_empty() {
if is_hidden { if is_hidden {
w.write_str("<div class=\"docblock hidden\">"); w.write_str("<div class=\"docblock hidden\">");
@ -785,7 +783,7 @@ fn render_impls(
w.write_str(&impls.join("")); w.write_str(&impls.join(""));
} }
fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>, cache: &Cache) -> String { fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) -> String {
use crate::formats::item_type::ItemType::*; use crate::formats::item_type::ItemType::*;
let name = it.name.as_ref().unwrap(); let name = it.name.as_ref().unwrap();
@ -799,7 +797,7 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>, cache: &Cache) ->
AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id), AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id),
AssocItemLink::Anchor(None) => anchor, AssocItemLink::Anchor(None) => anchor,
AssocItemLink::GotoSource(did, _) => { AssocItemLink::GotoSource(did, _) => {
href(did, cache).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor) href(did, cx).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
} }
} }
} }
@ -813,16 +811,14 @@ fn assoc_const(
extra: &str, extra: &str,
cx: &Context<'_>, cx: &Context<'_>,
) { ) {
let cache = cx.cache();
let tcx = cx.tcx();
write!( write!(
w, w,
"{}{}const <a href=\"{}\" class=\"constant\"><b>{}</b></a>: {}", "{}{}const <a href=\"{}\" class=\"constant\"><b>{}</b></a>: {}",
extra, extra,
it.visibility.print_with_space(tcx, it.def_id, cache), it.visibility.print_with_space(it.def_id, cx),
naive_assoc_href(it, link, cache), naive_assoc_href(it, link, cx),
it.name.as_ref().unwrap(), it.name.as_ref().unwrap(),
ty.print(cache, tcx) ty.print(cx)
); );
} }
@ -833,21 +829,20 @@ fn assoc_type(
default: Option<&clean::Type>, default: Option<&clean::Type>,
link: AssocItemLink<'_>, link: AssocItemLink<'_>,
extra: &str, extra: &str,
cache: &Cache, cx: &Context<'_>,
tcx: TyCtxt<'_>,
) { ) {
write!( write!(
w, w,
"{}type <a href=\"{}\" class=\"type\">{}</a>", "{}type <a href=\"{}\" class=\"type\">{}</a>",
extra, extra,
naive_assoc_href(it, link, cache), naive_assoc_href(it, link, cx),
it.name.as_ref().unwrap() it.name.as_ref().unwrap()
); );
if !bounds.is_empty() { if !bounds.is_empty() {
write!(w, ": {}", print_generic_bounds(bounds, cache, tcx)) write!(w, ": {}", print_generic_bounds(bounds, cx))
} }
if let Some(default) = default { if let Some(default) = default {
write!(w, " = {}", default.print(cache, tcx)) write!(w, " = {}", default.print(cx))
} }
} }
@ -897,8 +892,6 @@ fn render_assoc_item(
parent: ItemType, parent: ItemType,
cx: &Context<'_>, cx: &Context<'_>,
) { ) {
let cache = cx.cache();
let tcx = cx.tcx();
let name = meth.name.as_ref().unwrap(); let name = meth.name.as_ref().unwrap();
let href = match link { let href = match link {
AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id), AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id),
@ -912,19 +905,19 @@ fn render_assoc_item(
ItemType::TyMethod ItemType::TyMethod
}; };
href(did, cache) href(did, cx)
.map(|p| format!("{}#{}.{}", p.0, ty, name)) .map(|p| format!("{}#{}.{}", p.0, ty, name))
.unwrap_or_else(|| format!("#{}.{}", ty, name)) .unwrap_or_else(|| format!("#{}.{}", ty, name))
} }
}; };
let vis = meth.visibility.print_with_space(tcx, meth.def_id, cache).to_string(); let vis = meth.visibility.print_with_space(meth.def_id, cx).to_string();
let constness = header.constness.print_with_space(); let constness = header.constness.print_with_space();
let asyncness = header.asyncness.print_with_space(); let asyncness = header.asyncness.print_with_space();
let unsafety = header.unsafety.print_with_space(); let unsafety = header.unsafety.print_with_space();
let defaultness = print_default_space(meth.is_default()); let defaultness = print_default_space(meth.is_default());
let abi = print_abi_with_space(header.abi).to_string(); let abi = print_abi_with_space(header.abi).to_string();
// NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`. // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`.
let generics_len = format!("{:#}", g.print(cache, tcx)).len(); let generics_len = format!("{:#}", g.print(cx)).len();
let mut header_len = "fn ".len() let mut header_len = "fn ".len()
+ vis.len() + vis.len()
+ constness.len() + constness.len()
@ -958,10 +951,10 @@ fn render_assoc_item(
abi, abi,
href = href, href = href,
name = name, name = name,
generics = g.print(cache, tcx), generics = g.print(cx),
decl = d.full_print(cache, tcx, header_len, indent, header.asyncness), decl = d.full_print(header_len, indent, header.asyncness, cx),
notable_traits = notable_traits_decl(&d, cache, tcx), notable_traits = notable_traits_decl(&d, cx),
where_clause = print_where_clause(g, cache, tcx, indent, end_newline), where_clause = print_where_clause(g, cx, indent, end_newline),
) )
} }
match *item.kind { match *item.kind {
@ -988,8 +981,7 @@ fn render_assoc_item(
default.as_ref(), default.as_ref(),
link, link,
if parent == ItemType::Trait { " " } else { "" }, if parent == ItemType::Trait { " " } else { "" },
cx.cache(), cx,
cx.tcx(),
), ),
_ => panic!("render_assoc_item called on non-associated-item"), _ => panic!("render_assoc_item called on non-associated-item"),
} }
@ -1076,11 +1068,9 @@ fn render_assoc_items(
RenderMode::Normal RenderMode::Normal
} }
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
let id = cx.derive_id(small_url_encode(format!( let id =
"deref-methods-{:#}", cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
type_.print(cache, tcx) debug!("Adding {} to deref id map", type_.print(cx));
)));
debug!("Adding {} to deref id map", type_.print(cache, tcx));
cx.deref_id_map.borrow_mut().insert(type_.def_id_full(cache).unwrap(), id.clone()); cx.deref_id_map.borrow_mut().insert(type_.def_id_full(cache).unwrap(), id.clone());
write!( write!(
w, w,
@ -1089,8 +1079,8 @@ fn render_assoc_items(
<a href=\"#{id}\" class=\"anchor\"></a>\ <a href=\"#{id}\" class=\"anchor\"></a>\
</h2>", </h2>",
id = id, id = id,
trait_ = trait_.print(cache, tcx), trait_ = trait_.print(cx),
type_ = type_.print(cache, tcx), type_ = type_.print(cx),
); );
RenderMode::ForDeref { mut_: deref_mut_ } RenderMode::ForDeref { mut_: deref_mut_ }
} }
@ -1242,36 +1232,34 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, cache: &Cache) -> bo
} }
} }
fn notable_traits_decl(decl: &clean::FnDecl, cache: &Cache, tcx: TyCtxt<'_>) -> String { fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
let mut out = Buffer::html(); let mut out = Buffer::html();
let mut trait_ = String::new(); let mut trait_ = String::new();
if let Some(did) = decl.output.def_id_full(cache) { if let Some(did) = decl.output.def_id_full(cx.cache()) {
if let Some(impls) = cache.impls.get(&did) { if let Some(impls) = cx.cache().impls.get(&did) {
for i in impls { for i in impls {
let impl_ = i.inner_impl(); let impl_ = i.inner_impl();
if impl_ if impl_.trait_.def_id().map_or(false, |d| {
.trait_ cx.cache().traits.get(&d).map(|t| t.is_notable).unwrap_or(false)
.def_id() }) {
.map_or(false, |d| cache.traits.get(&d).map(|t| t.is_notable).unwrap_or(false))
{
if out.is_empty() { if out.is_empty() {
write!( write!(
&mut out, &mut out,
"<h3 class=\"notable\">Notable traits for {}</h3>\ "<h3 class=\"notable\">Notable traits for {}</h3>\
<code class=\"content\">", <code class=\"content\">",
impl_.for_.print(cache, tcx) impl_.for_.print(cx)
); );
trait_.push_str(&impl_.for_.print(cache, tcx).to_string()); trait_.push_str(&impl_.for_.print(cx).to_string());
} }
//use the "where" class here to make it small //use the "where" class here to make it small
write!( write!(
&mut out, &mut out,
"<span class=\"where fmt-newline\">{}</span>", "<span class=\"where fmt-newline\">{}</span>",
impl_.print(cache, false, tcx) impl_.print(false, cx)
); );
let t_did = impl_.trait_.def_id_full(cache).unwrap(); let t_did = impl_.trait_.def_id_full(cx.cache()).unwrap();
for it in &impl_.items { for it in &impl_.items {
if let clean::TypedefItem(ref tydef, _) = *it.kind { if let clean::TypedefItem(ref tydef, _) = *it.kind {
out.push_str("<span class=\"where fmt-newline\"> "); out.push_str("<span class=\"where fmt-newline\"> ");
@ -1282,8 +1270,7 @@ fn notable_traits_decl(decl: &clean::FnDecl, cache: &Cache, tcx: TyCtxt<'_>) ->
Some(&tydef.type_), Some(&tydef.type_),
AssocItemLink::GotoSource(t_did, &FxHashSet::default()), AssocItemLink::GotoSource(t_did, &FxHashSet::default()),
"", "",
cache, cx,
tcx,
); );
out.push_str(";</span>"); out.push_str(";</span>");
} }
@ -1322,18 +1309,18 @@ fn render_impl(
// in documentation pages for trait with automatic implementations like "Send" and "Sync". // in documentation pages for trait with automatic implementations like "Send" and "Sync".
aliases: &[String], aliases: &[String],
) { ) {
let traits = &cx.cache.traits;
let tcx = cx.tcx(); let tcx = cx.tcx();
let cache = cx.cache(); let cache = cx.cache();
let traits = &cache.traits;
let trait_ = i.trait_did_full(cache).map(|did| &traits[&did]); let trait_ = i.trait_did_full(cache).map(|did| &traits[&did]);
if render_mode == RenderMode::Normal { if render_mode == RenderMode::Normal {
let id = cx.derive_id(match i.inner_impl().trait_ { let id = cx.derive_id(match i.inner_impl().trait_ {
Some(ref t) => { Some(ref t) => {
if is_on_foreign_type { if is_on_foreign_type {
get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t, cache, tcx) get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t, cx)
} else { } else {
format!("impl-{}", small_url_encode(format!("{:#}", t.print(cache, tcx)))) format!("impl-{}", small_url_encode(format!("{:#}", t.print(cx))))
} }
} }
None => "impl".to_string(), None => "impl".to_string(),
@ -1345,7 +1332,7 @@ fn render_impl(
}; };
if let Some(use_absolute) = use_absolute { if let Some(use_absolute) = use_absolute {
write!(w, "<h3 id=\"{}\" class=\"impl\"{}><code class=\"in-band\">", id, aliases); write!(w, "<h3 id=\"{}\" class=\"impl\"{}><code class=\"in-band\">", id, aliases);
write!(w, "{}", i.inner_impl().print(cache, use_absolute, tcx)); write!(w, "{}", i.inner_impl().print(use_absolute, cx));
if show_def_docs { if show_def_docs {
for it in &i.inner_impl().items { for it in &i.inner_impl().items {
if let clean::TypedefItem(ref tydef, _) = *it.kind { if let clean::TypedefItem(ref tydef, _) = *it.kind {
@ -1357,8 +1344,7 @@ fn render_impl(
Some(&tydef.type_), Some(&tydef.type_),
AssocItemLink::Anchor(None), AssocItemLink::Anchor(None),
"", "",
cache, cx,
tcx,
); );
w.write_str(";</span>"); w.write_str(";</span>");
} }
@ -1371,7 +1357,7 @@ fn render_impl(
"<h3 id=\"{}\" class=\"impl\"{}><code class=\"in-band\">{}</code>", "<h3 id=\"{}\" class=\"impl\"{}><code class=\"in-band\">{}</code>",
id, id,
aliases, aliases,
i.inner_impl().print(cache, false, tcx) i.inner_impl().print(false, cx)
); );
} }
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id); write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
@ -1398,7 +1384,7 @@ fn render_impl(
"<div class=\"docblock\">{}</div>", "<div class=\"docblock\">{}</div>",
Markdown( Markdown(
&*dox, &*dox,
&i.impl_item.links(&cx.cache), &i.impl_item.links(cx),
&mut ids, &mut ids,
cx.shared.codes, cx.shared.codes,
cx.shared.edition, cx.shared.edition,
@ -1495,8 +1481,7 @@ fn render_impl(
Some(&tydef.type_), Some(&tydef.type_),
link.anchor(if trait_.is_some() { &source_id } else { &id }), link.anchor(if trait_.is_some() { &source_id } else { &id }),
"", "",
cx.cache(), cx,
tcx,
); );
w.write_str("</code>"); w.write_str("</code>");
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id); write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
@ -1546,8 +1531,7 @@ fn render_impl(
default.as_ref(), default.as_ref(),
link.anchor(if trait_.is_some() { &source_id } else { &id }), link.anchor(if trait_.is_some() { &source_id } else { &id }),
"", "",
cx.cache(), cx,
tcx,
); );
w.write_str("</code>"); w.write_str("</code>");
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id); write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
@ -1853,7 +1837,6 @@ fn small_url_encode(s: String) -> String {
fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) { fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
if let Some(v) = cx.cache.impls.get(&it.def_id) { if let Some(v) = cx.cache.impls.get(&it.def_id) {
let mut used_links = FxHashSet::default(); let mut used_links = FxHashSet::default();
let tcx = cx.tcx();
let cache = cx.cache(); let cache = cx.cache();
{ {
@ -1888,9 +1871,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
.iter() .iter()
.filter_map(|it| { .filter_map(|it| {
if let Some(ref i) = it.inner_impl().trait_ { if let Some(ref i) = it.inner_impl().trait_ {
let i_display = format!("{:#}", i.print(cache, tcx)); let i_display = format!("{:#}", i.print(cx));
let out = Escape(&i_display); let out = Escape(&i_display);
let encoded = small_url_encode(format!("{:#}", i.print(cache, tcx))); let encoded = small_url_encode(format!("{:#}", i.print(cx)));
let generated = format!( let generated = format!(
"<a href=\"#impl-{}\">{}{}</a>", "<a href=\"#impl-{}\">{}{}</a>",
encoded, encoded,
@ -1962,7 +1945,6 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &Vec<Impl>) { fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &Vec<Impl>) {
let c = cx.cache(); let c = cx.cache();
let tcx = cx.tcx();
debug!("found Deref: {:?}", impl_); debug!("found Deref: {:?}", impl_);
if let Some((target, real_target)) = if let Some((target, real_target)) =
@ -2011,11 +1993,8 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
out, out,
"<a class=\"sidebar-title\" href=\"#{}\">Methods from {}&lt;Target={}&gt;</a>", "<a class=\"sidebar-title\" href=\"#{}\">Methods from {}&lt;Target={}&gt;</a>",
id, id,
Escape(&format!( Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(cx))),
"{:#}", Escape(&format!("{:#}", real_target.print(cx))),
impl_.inner_impl().trait_.as_ref().unwrap().print(c, tcx)
)),
Escape(&format!("{:#}", real_target.print(c, tcx))),
); );
// We want links' order to be reproducible so we don't use unstable sort. // We want links' order to be reproducible so we don't use unstable sort.
ret.sort(); ret.sort();
@ -2071,27 +2050,20 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
fn get_id_for_impl_on_foreign_type( fn get_id_for_impl_on_foreign_type(
for_: &clean::Type, for_: &clean::Type,
trait_: &clean::Type, trait_: &clean::Type,
cache: &Cache, cx: &Context<'_>,
tcx: TyCtxt<'_>,
) -> String { ) -> String {
small_url_encode(format!( small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx),))
"impl-{:#}-for-{:#}",
trait_.print(cache, tcx),
for_.print(cache, tcx)
))
} }
fn extract_for_impl_name( fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> {
item: &clean::Item,
cache: &Cache,
tcx: TyCtxt<'_>,
) -> Option<(String, String)> {
match *item.kind { match *item.kind {
clean::ItemKind::ImplItem(ref i) => { clean::ItemKind::ImplItem(ref i) => {
if let Some(ref trait_) = i.trait_ { if let Some(ref trait_) = i.trait_ {
// Alternative format produces no URLs,
// so this parameter does nothing.
Some(( Some((
format!("{:#}", i.for_.print(cache, tcx)), format!("{:#}", i.for_.print(cx)),
get_id_for_impl_on_foreign_type(&i.for_, trait_, cache, tcx), get_id_for_impl_on_foreign_type(&i.for_, trait_, cx),
)) ))
} else { } else {
None None
@ -2172,7 +2144,6 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
if let Some(implementors) = cx.cache.implementors.get(&it.def_id) { if let Some(implementors) = cx.cache.implementors.get(&it.def_id) {
let cache = cx.cache(); let cache = cx.cache();
let tcx = cx.tcx();
let mut res = implementors let mut res = implementors
.iter() .iter()
.filter(|i| { .filter(|i| {
@ -2181,7 +2152,7 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
.def_id_full(cache) .def_id_full(cache)
.map_or(false, |d| !cx.cache.paths.contains_key(&d)) .map_or(false, |d| !cx.cache.paths.contains_key(&d))
}) })
.filter_map(|i| extract_for_impl_name(&i.impl_item, cache, tcx)) .filter_map(|i| extract_for_impl_name(&i.impl_item, cx))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
if !res.is_empty() { if !res.is_empty() {

View file

@ -15,9 +15,8 @@ use super::{
render_impl, render_stability_since_raw, write_srclink, AssocItemLink, Context, render_impl, render_stability_since_raw, write_srclink, AssocItemLink, Context,
}; };
use crate::clean::{self, GetDefId}; use crate::clean::{self, GetDefId};
use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType; use crate::formats::item_type::ItemType;
use crate::formats::{AssocItemRender, FormatRenderer, Impl, RenderMode}; use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape; use crate::html::escape::Escape;
use crate::html::format::{print_abi_with_space, print_where_clause, Buffer, PrintWithSpace}; use crate::html::format::{print_abi_with_space, print_where_clause, Buffer, PrintWithSpace};
use crate::html::highlight; use crate::html::highlight;
@ -268,15 +267,15 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
Some(ref src) => write!( Some(ref src) => write!(
w, w,
"<tr><td><code>{}extern crate {} as {};", "<tr><td><code>{}extern crate {} as {};",
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id, cx.cache()), myitem.visibility.print_with_space(myitem.def_id, cx),
anchor(myitem.def_id, &*src.as_str(), cx.cache()), anchor(myitem.def_id, &*src.as_str(), cx),
myitem.name.as_ref().unwrap(), myitem.name.as_ref().unwrap(),
), ),
None => write!( None => write!(
w, w,
"<tr><td><code>{}extern crate {};", "<tr><td><code>{}extern crate {};",
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id, cx.cache()), myitem.visibility.print_with_space(myitem.def_id, cx),
anchor(myitem.def_id, &*myitem.name.as_ref().unwrap().as_str(), cx.cache()), anchor(myitem.def_id, &*myitem.name.as_ref().unwrap().as_str(), cx),
), ),
} }
w.write_str("</code></td></tr>"); w.write_str("</code></td></tr>");
@ -286,8 +285,8 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
write!( write!(
w, w,
"<tr><td><code>{}{}</code></td></tr>", "<tr><td><code>{}{}</code></td></tr>",
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id, cx.cache()), myitem.visibility.print_with_space(myitem.def_id, cx),
import.print(cx.cache(), cx.tcx()), import.print(cx),
); );
} }
@ -318,7 +317,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
</tr>", </tr>",
name = *myitem.name.as_ref().unwrap(), name = *myitem.name.as_ref().unwrap(),
stab_tags = extra_info_tags(myitem, item, cx.tcx()), stab_tags = extra_info_tags(myitem, item, cx.tcx()),
docs = MarkdownSummaryLine(&doc_value, &myitem.links(&cx.cache)).into_string(), docs = MarkdownSummaryLine(&doc_value, &myitem.links(cx)).into_string(),
class = myitem.type_(), class = myitem.type_(),
add = add, add = add,
stab = stab.unwrap_or_else(String::new), stab = stab.unwrap_or_else(String::new),
@ -387,13 +386,13 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) ->
fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) { fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
let header_len = format!( let header_len = format!(
"{}{}{}{}{:#}fn {}{:#}", "{}{}{}{}{:#}fn {}{:#}",
it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), it.visibility.print_with_space(it.def_id, cx),
f.header.constness.print_with_space(), f.header.constness.print_with_space(),
f.header.asyncness.print_with_space(), f.header.asyncness.print_with_space(),
f.header.unsafety.print_with_space(), f.header.unsafety.print_with_space(),
print_abi_with_space(f.header.abi), print_abi_with_space(f.header.abi),
it.name.as_ref().unwrap(), it.name.as_ref().unwrap(),
f.generics.print(cx.cache(), cx.tcx()) f.generics.print(cx),
) )
.len(); .len();
w.write_str("<pre class=\"rust fn\">"); w.write_str("<pre class=\"rust fn\">");
@ -402,22 +401,22 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
w, w,
"{vis}{constness}{asyncness}{unsafety}{abi}fn \ "{vis}{constness}{asyncness}{unsafety}{abi}fn \
{name}{generics}{decl}{notable_traits}{where_clause}</pre>", {name}{generics}{decl}{notable_traits}{where_clause}</pre>",
vis = it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), vis = it.visibility.print_with_space(it.def_id, cx),
constness = f.header.constness.print_with_space(), constness = f.header.constness.print_with_space(),
asyncness = f.header.asyncness.print_with_space(), asyncness = f.header.asyncness.print_with_space(),
unsafety = f.header.unsafety.print_with_space(), unsafety = f.header.unsafety.print_with_space(),
abi = print_abi_with_space(f.header.abi), abi = print_abi_with_space(f.header.abi),
name = it.name.as_ref().unwrap(), name = it.name.as_ref().unwrap(),
generics = f.generics.print(cx.cache(), cx.tcx()), generics = f.generics.print(cx),
where_clause = print_where_clause(&f.generics, cx.cache(), cx.tcx(), 0, true), where_clause = print_where_clause(&f.generics, cx, 0, true),
decl = f.decl.full_print(cx.cache(), cx.tcx(), header_len, 0, f.header.asyncness), decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
notable_traits = notable_traits_decl(&f.decl, cx.cache(), cx.tcx()), notable_traits = notable_traits_decl(&f.decl, cx),
); );
document(w, cx, it, None) document(w, cx, it, None)
} }
fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) { fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) {
let bounds = bounds(&t.bounds, false, cx.cache(), cx.tcx()); let bounds = bounds(&t.bounds, false, cx);
let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>(); let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>(); let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
let required = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>(); let required = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>();
@ -430,16 +429,16 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
write!( write!(
w, w,
"{}{}{}trait {}{}{}", "{}{}{}trait {}{}{}",
it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), it.visibility.print_with_space(it.def_id, cx),
t.unsafety.print_with_space(), t.unsafety.print_with_space(),
if t.is_auto { "auto " } else { "" }, if t.is_auto { "auto " } else { "" },
it.name.as_ref().unwrap(), it.name.as_ref().unwrap(),
t.generics.print(cx.cache(), cx.tcx()), t.generics.print(cx),
bounds bounds
); );
if !t.generics.where_predicates.is_empty() { if !t.generics.where_predicates.is_empty() {
write!(w, "{}", print_where_clause(&t.generics, cx.cache(), cx.tcx(), 0, true)); write!(w, "{}", print_where_clause(&t.generics, cx, 0, true));
} else { } else {
w.write_str(" "); w.write_str(" ");
} }
@ -634,8 +633,8 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) =
local.iter().partition(|i| i.inner_impl().synthetic); local.iter().partition(|i| i.inner_impl().synthetic);
synthetic.sort_by(|a, b| compare_impl(a, b, cx.cache(), cx.tcx())); synthetic.sort_by(|a, b| compare_impl(a, b, cx));
concrete.sort_by(|a, b| compare_impl(a, b, cx.cache(), cx.tcx())); concrete.sort_by(|a, b| compare_impl(a, b, cx));
if !foreign.is_empty() { if !foreign.is_empty() {
write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", ""); write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", "");
@ -740,9 +739,9 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea
w, w,
"trait {}{}{} = {};</pre>", "trait {}{}{} = {};</pre>",
it.name.as_ref().unwrap(), it.name.as_ref().unwrap(),
t.generics.print(cx.cache(), cx.tcx()), t.generics.print(cx),
print_where_clause(&t.generics, cx.cache(), cx.tcx(), 0, true), print_where_clause(&t.generics, cx, 0, true),
bounds(&t.bounds, true, cx.cache(), cx.tcx()) bounds(&t.bounds, true, cx)
); );
document(w, cx, it, None); document(w, cx, it, None);
@ -761,9 +760,9 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean:
w, w,
"type {}{}{where_clause} = impl {bounds};</pre>", "type {}{}{where_clause} = impl {bounds};</pre>",
it.name.as_ref().unwrap(), it.name.as_ref().unwrap(),
t.generics.print(cx.cache(), cx.tcx()), t.generics.print(cx),
where_clause = print_where_clause(&t.generics, cx.cache(), cx.tcx(), 0, true), where_clause = print_where_clause(&t.generics, cx, 0, true),
bounds = bounds(&t.bounds, false, cx.cache(), cx.tcx()), bounds = bounds(&t.bounds, false, cx),
); );
document(w, cx, it, None); document(w, cx, it, None);
@ -782,9 +781,9 @@ fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::T
w, w,
"type {}{}{where_clause} = {type_};</pre>", "type {}{}{where_clause} = {type_};</pre>",
it.name.as_ref().unwrap(), it.name.as_ref().unwrap(),
t.generics.print(cx.cache(), cx.tcx()), t.generics.print(cx),
where_clause = print_where_clause(&t.generics, cx.cache(), cx.tcx(), 0, true), where_clause = print_where_clause(&t.generics, cx, 0, true),
type_ = t.type_.print(cx.cache(), cx.tcx()), type_ = t.type_.print(cx),
); );
document(w, cx, it, None); document(w, cx, it, None);
@ -831,7 +830,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
id = id, id = id,
name = name, name = name,
shortty = ItemType::StructField, shortty = ItemType::StructField,
ty = ty.print(cx.cache(), cx.tcx()), ty = ty.print(cx),
); );
if let Some(stability_class) = field.stability_class(cx.tcx()) { if let Some(stability_class) = field.stability_class(cx.tcx()) {
write!(w, "<span class=\"stab {stab}\"></span>", stab = stability_class); write!(w, "<span class=\"stab {stab}\"></span>", stab = stability_class);
@ -849,10 +848,10 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
write!( write!(
w, w,
"{}enum {}{}{}", "{}enum {}{}{}",
it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), it.visibility.print_with_space(it.def_id, cx),
it.name.as_ref().unwrap(), it.name.as_ref().unwrap(),
e.generics.print(cx.cache(), cx.tcx()), e.generics.print(cx),
print_where_clause(&e.generics, cx.cache(), cx.tcx(), 0, true), print_where_clause(&e.generics, cx, 0, true),
); );
if e.variants.is_empty() && !e.variants_stripped { if e.variants.is_empty() && !e.variants_stripped {
w.write_str(" {}"); w.write_str(" {}");
@ -874,7 +873,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
if i > 0 { if i > 0 {
w.write_str(",&nbsp;") w.write_str(",&nbsp;")
} }
write!(w, "{}", ty.print(cx.cache(), cx.tcx())); write!(w, "{}", ty.print(cx));
} }
w.write_str(")"); w.write_str(")");
} }
@ -924,7 +923,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
if i > 0 { if i > 0 {
w.write_str(",&nbsp;"); w.write_str(",&nbsp;");
} }
write!(w, "{}", ty.print(cx.cache(), cx.tcx())); write!(w, "{}", ty.print(cx));
} }
w.write_str(")"); w.write_str(")");
} }
@ -961,7 +960,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
</span>", </span>",
id = id, id = id,
f = field.name.as_ref().unwrap(), f = field.name.as_ref().unwrap(),
t = ty.print(cx.cache(), cx.tcx()) t = ty.print(cx)
); );
document(w, cx, field, Some(variant)); document(w, cx, field, Some(variant));
} }
@ -1030,9 +1029,9 @@ fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::
write!( write!(
w, w,
"{vis}const {name}: {typ}", "{vis}const {name}: {typ}",
vis = it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), vis = it.visibility.print_with_space(it.def_id, cx),
name = it.name.as_ref().unwrap(), name = it.name.as_ref().unwrap(),
typ = c.type_.print(cx.cache(), cx.tcx()), typ = c.type_.print(cx),
); );
let value = c.value(cx.tcx()); let value = c.value(cx.tcx());
@ -1102,7 +1101,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
item_type = ItemType::StructField, item_type = ItemType::StructField,
id = id, id = id,
name = field.name.as_ref().unwrap(), name = field.name.as_ref().unwrap(),
ty = ty.print(cx.cache(), cx.tcx()) ty = ty.print(cx)
); );
document(w, cx, field, Some(it)); document(w, cx, field, Some(it));
} }
@ -1117,10 +1116,10 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
write!( write!(
w, w,
"{vis}static {mutability}{name}: {typ}</pre>", "{vis}static {mutability}{name}: {typ}</pre>",
vis = it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), vis = it.visibility.print_with_space(it.def_id, cx),
mutability = s.mutability.print_with_space(), mutability = s.mutability.print_with_space(),
name = it.name.as_ref().unwrap(), name = it.name.as_ref().unwrap(),
typ = s.type_.print(cx.cache(), cx.tcx()) typ = s.type_.print(cx)
); );
document(w, cx, it, None) document(w, cx, it, None)
} }
@ -1131,7 +1130,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
write!( write!(
w, w,
" {}type {};\n}}</pre>", " {}type {};\n}}</pre>",
it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), it.visibility.print_with_space(it.def_id, cx),
it.name.as_ref().unwrap(), it.name.as_ref().unwrap(),
); );
@ -1195,12 +1194,7 @@ pub(super) fn item_path(ty: ItemType, name: &str) -> String {
} }
} }
fn bounds( fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>) -> String {
t_bounds: &[clean::GenericBound],
trait_alias: bool,
cache: &Cache,
tcx: TyCtxt<'_>,
) -> String {
let mut bounds = String::new(); let mut bounds = String::new();
if !t_bounds.is_empty() { if !t_bounds.is_empty() {
if !trait_alias { if !trait_alias {
@ -1210,7 +1204,7 @@ fn bounds(
if i > 0 { if i > 0 {
bounds.push_str(" + "); bounds.push_str(" + ");
} }
bounds.push_str(&p.print(cache, tcx).to_string()); bounds.push_str(&p.print(cx).to_string());
} }
} }
bounds bounds
@ -1240,17 +1234,12 @@ fn render_stability_since(
) )
} }
fn compare_impl<'a, 'b>( fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl, cx: &Context<'_>) -> Ordering {
lhs: &'a &&Impl, let lhss = format!("{}", lhs.inner_impl().print(false, cx));
rhs: &'b &&Impl, let rhss = format!("{}", rhs.inner_impl().print(false, cx));
cache: &Cache,
tcx: TyCtxt<'_>,
) -> Ordering {
let lhs = format!("{}", lhs.inner_impl().print(cache, false, tcx));
let rhs = format!("{}", rhs.inner_impl().print(cache, false, tcx));
// lhs and rhs are formatted as HTML, which may be unnecessary // lhs and rhs are formatted as HTML, which may be unnecessary
compare_names(&lhs, &rhs) compare_names(&lhss, &rhss)
} }
fn render_implementor( fn render_implementor(
@ -1300,13 +1289,13 @@ fn render_union(
write!( write!(
w, w,
"{}{}{}", "{}{}{}",
it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), it.visibility.print_with_space(it.def_id, cx),
if structhead { "union " } else { "" }, if structhead { "union " } else { "" },
it.name.as_ref().unwrap() it.name.as_ref().unwrap()
); );
if let Some(g) = g { if let Some(g) = g {
write!(w, "{}", g.print(cx.cache(), cx.tcx())); write!(w, "{}", g.print(cx));
write!(w, "{}", print_where_clause(&g, cx.cache(), cx.tcx(), 0, true)); write!(w, "{}", print_where_clause(&g, cx, 0, true));
} }
write!(w, " {{\n{}", tab); write!(w, " {{\n{}", tab);
@ -1322,9 +1311,9 @@ fn render_union(
write!( write!(
w, w,
" {}{}: {},\n{}", " {}{}: {},\n{}",
field.visibility.print_with_space(cx.tcx(), field.def_id, cx.cache()), field.visibility.print_with_space(field.def_id, cx),
field.name.as_ref().unwrap(), field.name.as_ref().unwrap(),
ty.print(cx.cache(), cx.tcx()), ty.print(cx),
tab tab
); );
} }
@ -1352,17 +1341,17 @@ fn render_struct(
write!( write!(
w, w,
"{}{}{}", "{}{}{}",
it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), it.visibility.print_with_space(it.def_id, cx),
if structhead { "struct " } else { "" }, if structhead { "struct " } else { "" },
it.name.as_ref().unwrap() it.name.as_ref().unwrap()
); );
if let Some(g) = g { if let Some(g) = g {
write!(w, "{}", g.print(cx.cache(), cx.tcx())) write!(w, "{}", g.print(cx))
} }
match ty { match ty {
CtorKind::Fictive => { CtorKind::Fictive => {
if let Some(g) = g { if let Some(g) = g {
write!(w, "{}", print_where_clause(g, cx.cache(), cx.tcx(), 0, true),) write!(w, "{}", print_where_clause(g, cx, 0, true),)
} }
w.write_str(" {"); w.write_str(" {");
let count_fields = let count_fields =
@ -1378,9 +1367,9 @@ fn render_struct(
w, w,
"\n{} {}{}: {},", "\n{} {}{}: {},",
tab, tab,
field.visibility.print_with_space(cx.tcx(), field.def_id, cx.cache()), field.visibility.print_with_space(field.def_id, cx),
field.name.as_ref().unwrap(), field.name.as_ref().unwrap(),
ty.print(cx.cache(), cx.tcx()), ty.print(cx),
); );
} }
} }
@ -1412,8 +1401,8 @@ fn render_struct(
write!( write!(
w, w,
"{}{}", "{}{}",
field.visibility.print_with_space(cx.tcx(), field.def_id, cx.cache()), field.visibility.print_with_space(field.def_id, cx),
ty.print(cx.cache(), cx.tcx()), ty.print(cx),
) )
} }
_ => unreachable!(), _ => unreachable!(),
@ -1421,14 +1410,14 @@ fn render_struct(
} }
w.write_str(")"); w.write_str(")");
if let Some(g) = g { if let Some(g) = g {
write!(w, "{}", print_where_clause(g, cx.cache(), cx.tcx(), 0, false),) write!(w, "{}", print_where_clause(g, cx, 0, false),)
} }
w.write_str(";"); w.write_str(";");
} }
CtorKind::Const => { CtorKind::Const => {
// Needed for PhantomData. // Needed for PhantomData.
if let Some(g) = g { if let Some(g) = g {
write!(w, "{}", print_where_clause(g, cx.cache(), cx.tcx(), 0, false),) write!(w, "{}", print_where_clause(g, cx, 0, false),)
} }
w.write_str(";"); w.write_str(";");
} }

View file

@ -16,7 +16,6 @@ use crate::clean::Crate;
use crate::config::{EmitType, RenderOptions}; use crate::config::{EmitType, RenderOptions};
use crate::docfs::PathError; use crate::docfs::PathError;
use crate::error::Error; use crate::error::Error;
use crate::formats::FormatRenderer;
use crate::html::{layout, static_files}; use crate::html::{layout, static_files};
crate static FILES_UNVERSIONED: Lazy<FxHashMap<&str, &[u8]>> = Lazy::new(|| { crate static FILES_UNVERSIONED: Lazy<FxHashMap<&str, &[u8]>> = Lazy::new(|| {
@ -223,6 +222,7 @@ pub(super) fn write_shared(
&format!(" = {}", serde_json::to_string(&themes).unwrap()), &format!(" = {}", serde_json::to_string(&themes).unwrap()),
), ),
)?; )?;
write_minify("search.js", static_files::SEARCH_JS)?;
write_minify("settings.js", static_files::SETTINGS_JS)?; write_minify("settings.js", static_files::SETTINGS_JS)?;
if cx.shared.include_sources { if cx.shared.include_sources {
write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT)?; write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT)?;
@ -410,7 +410,7 @@ pub(super) fn write_shared(
write_crate("search-index.js", &|| { write_crate("search-index.js", &|| {
let mut v = String::from("var searchIndex = JSON.parse('{\\\n"); let mut v = String::from("var searchIndex = JSON.parse('{\\\n");
v.push_str(&all_indexes.join(",\\\n")); v.push_str(&all_indexes.join(",\\\n"));
v.push_str("\\\n}');\ninitSearch(searchIndex);"); v.push_str("\\\n}');\nif (window.initSearch) {window.initSearch(searchIndex)};");
Ok(v.into_bytes()) Ok(v.into_bytes())
})?; })?;
@ -500,7 +500,7 @@ pub(super) fn write_shared(
None None
} else { } else {
Some(Implementor { Some(Implementor {
text: imp.inner_impl().print(cx.cache(), false, cx.tcx()).to_string(), text: imp.inner_impl().print(false, cx).to_string(),
synthetic: imp.inner_impl().synthetic, synthetic: imp.inner_impl().synthetic,
types: collect_paths_for_type(imp.inner_impl().for_.clone(), cx.cache()), types: collect_paths_for_type(imp.inner_impl().for_.clone(), cx.cache()),
}) })

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,9 @@ crate static NORMALIZE_CSS: &str = include_str!("static/normalize.css");
/// including search behavior and docblock folding, among others. /// including search behavior and docblock folding, among others.
crate static MAIN_JS: &str = include_str!("static/main.js"); crate static MAIN_JS: &str = include_str!("static/main.js");
/// The file contents of `search.js`, which contains the search behavior.
crate static SEARCH_JS: &str = include_str!("static/search.js");
/// The file contents of `settings.js`, which contains the JavaScript used to handle the settings /// The file contents of `settings.js`, which contains the JavaScript used to handle the settings
/// page. /// page.
crate static SETTINGS_JS: &str = include_str!("static/settings.js"); crate static SETTINGS_JS: &str = include_str!("static/settings.js");

View file

@ -0,0 +1,44 @@
use crate::html::format::href_relative_parts;
fn assert_relative_path(expected: &[&str], relative_to_fqp: &[&str], fqp: &[&str]) {
let relative_to_fqp: Vec<String> = relative_to_fqp.iter().copied().map(String::from).collect();
let fqp: Vec<String> = fqp.iter().copied().map(String::from).collect();
assert_eq!(expected, href_relative_parts(&fqp, &relative_to_fqp));
}
#[test]
fn href_relative_parts_basic() {
let relative_to_fqp = &["std", "vec"];
let fqp = &["std", "iter"];
assert_relative_path(&["..", "iter"], relative_to_fqp, fqp);
}
#[test]
fn href_relative_parts_parent_module() {
let relative_to_fqp = &["std", "vec"];
let fqp = &["std"];
assert_relative_path(&[".."], relative_to_fqp, fqp);
}
#[test]
fn href_relative_parts_different_crate() {
let relative_to_fqp = &["std", "vec"];
let fqp = &["core", "iter"];
assert_relative_path(&["..", "..", "core", "iter"], relative_to_fqp, fqp);
}
#[test]
fn href_relative_parts_same_module() {
let relative_to_fqp = &["std", "vec"];
let fqp = &["std", "vec"];
assert_relative_path(&[], relative_to_fqp, fqp);
}
#[test]
fn href_relative_parts_child_module() {
let relative_to_fqp = &["std"];
let fqp = &["std", "vec"];
assert_relative_path(&["vec"], relative_to_fqp, fqp);
}
#[test]
fn href_relative_parts_root() {
let relative_to_fqp = &[];
let fqp = &["std"];
assert_relative_path(&["std"], relative_to_fqp, fqp);
}

View file

@ -289,7 +289,13 @@ fn opts() -> Vec<RustcOptGroup> {
stable("cfg", |o| o.optmulti("", "cfg", "pass a --cfg to rustc", "")), stable("cfg", |o| o.optmulti("", "cfg", "pass a --cfg to rustc", "")),
stable("extern", |o| o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")), stable("extern", |o| o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")),
unstable("extern-html-root-url", |o| { unstable("extern-html-root-url", |o| {
o.optmulti("", "extern-html-root-url", "base URL to use for dependencies", "NAME=URL") o.optmulti(
"",
"extern-html-root-url",
"base URL to use for dependencies; for example, \
\"std=/doc\" links std::vec::Vec to /doc/std/vec/struct.Vec.html",
"NAME=URL",
)
}), }),
stable("plugin-path", |o| o.optmulti("", "plugin-path", "removed", "DIR")), stable("plugin-path", |o| o.optmulti("", "plugin-path", "removed", "DIR")),
stable("C", |o| { stable("C", |o| {

View file

@ -1957,20 +1957,28 @@ fn resolution_failure(
/// Report an anchor failure. /// Report an anchor failure.
fn anchor_failure(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, failure: AnchorFailure) { fn anchor_failure(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, failure: AnchorFailure) {
let msg = match failure { let (msg, anchor_idx) = match failure {
AnchorFailure::MultipleAnchors => { AnchorFailure::MultipleAnchors => {
format!("`{}` contains multiple anchors", diag_info.ori_link) (format!("`{}` contains multiple anchors", diag_info.ori_link), 1)
} }
AnchorFailure::RustdocAnchorConflict(res) => format!( AnchorFailure::RustdocAnchorConflict(res) => (
"`{}` contains an anchor, but links to {kind}s are already anchored", format!(
diag_info.ori_link, "`{}` contains an anchor, but links to {kind}s are already anchored",
kind = res.descr(), diag_info.ori_link,
kind = res.descr(),
),
0,
), ),
}; };
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, &diag_info, |diag, sp| { report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, &diag_info, |diag, sp| {
if let Some(sp) = sp { if let Some(mut sp) = sp {
diag.span_label(sp, "contains invalid anchor"); if let Some((fragment_offset, _)) =
diag_info.ori_link.char_indices().filter(|(_, x)| *x == '#').nth(anchor_idx)
{
sp = sp.with_lo(sp.lo() + rustc_span::BytePos(fragment_offset as _));
}
diag.span_label(sp, "invalid anchor");
} }
if let AnchorFailure::RustdocAnchorConflict(Res::Primitive(_)) = failure { if let AnchorFailure::RustdocAnchorConflict(Res::Primitive(_)) = failure {
diag.note("this restriction may be lifted in a future release"); diag.note("this restriction may be lifted in a future release");

View file

@ -2,7 +2,9 @@ error: `prim@usize#x` contains an anchor, but links to builtin types are already
--> $DIR/anchors.rs:47:6 --> $DIR/anchors.rs:47:6
| |
LL | /// [prim@usize#x] LL | /// [prim@usize#x]
| ^^^^^^^^^^^^ contains invalid anchor | ^^^^^^^^^^--
| |
| invalid anchor
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/anchors.rs:1:9 --> $DIR/anchors.rs:1:9
@ -16,25 +18,33 @@ error: `Foo::f#hola` contains an anchor, but links to fields are already anchore
--> $DIR/anchors.rs:25:15 --> $DIR/anchors.rs:25:15
| |
LL | /// Or maybe [Foo::f#hola]. LL | /// Or maybe [Foo::f#hola].
| ^^^^^^^^^^^ contains invalid anchor | ^^^^^^-----
| |
| invalid anchor
error: `hello#people#!` contains multiple anchors error: `hello#people#!` contains multiple anchors
--> $DIR/anchors.rs:31:28 --> $DIR/anchors.rs:31:28
| |
LL | /// Another anchor error: [hello#people#!]. LL | /// Another anchor error: [hello#people#!].
| ^^^^^^^^^^^^^^ contains invalid anchor | ^^^^^^^^^^^^--
| |
| invalid anchor
error: `Enum::A#whatever` contains an anchor, but links to variants are already anchored error: `Enum::A#whatever` contains an anchor, but links to variants are already anchored
--> $DIR/anchors.rs:37:28 --> $DIR/anchors.rs:37:28
| |
LL | /// Damn enum's variants: [Enum::A#whatever]. LL | /// Damn enum's variants: [Enum::A#whatever].
| ^^^^^^^^^^^^^^^^ contains invalid anchor | ^^^^^^^---------
| |
| invalid anchor
error: `u32#hello` contains an anchor, but links to builtin types are already anchored error: `u32#hello` contains an anchor, but links to builtin types are already anchored
--> $DIR/anchors.rs:43:6 --> $DIR/anchors.rs:43:6
| |
LL | /// [u32#hello] LL | /// [u32#hello]
| ^^^^^^^^^ contains invalid anchor | ^^^------
| |
| invalid anchor
| |
= note: this restriction may be lifted in a future release = note: this restriction may be lifted in a future release
= note: see https://github.com/rust-lang/rust/issues/83083 for more information = note: see https://github.com/rust-lang/rust/issues/83083 for more information

View file

@ -2,7 +2,9 @@ warning: `with#anchor#error` contains multiple anchors
--> $DIR/double-anchor.rs:5:18 --> $DIR/double-anchor.rs:5:18
| |
LL | /// docs [label][with#anchor#error] LL | /// docs [label][with#anchor#error]
| ^^^^^^^^^^^^^^^^^ contains invalid anchor | ^^^^^^^^^^^------
| |
| invalid anchor
| |
= note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

View file

@ -6,14 +6,14 @@ pub trait Index<I: ?Sized> {
type Output: ?Sized; type Output: ?Sized;
// @has - '//*[@id="tymethod.index"]//code' \ // @has - '//*[@id="tymethod.index"]//code' \
// "fn index<'a>(&'a self, index: I) -> &'a Self::Output" // "fn index<'a>(&'a self, index: I) -> &'a Self::Output"
// @has - '//*[@id="tymethod.index"]//code//a[@href="../assoc_types/trait.Index.html#associatedtype.Output"]' \ // @has - '//*[@id="tymethod.index"]//code//a[@href="trait.Index.html#associatedtype.Output"]' \
// "Output" // "Output"
fn index<'a>(&'a self, index: I) -> &'a Self::Output; fn index<'a>(&'a self, index: I) -> &'a Self::Output;
} }
// @has assoc_types/fn.use_output.html // @has assoc_types/fn.use_output.html
// @has - '//*[@class="rust fn"]' '-> &T::Output' // @has - '//*[@class="rust fn"]' '-> &T::Output'
// @has - '//*[@class="rust fn"]//a[@href="../assoc_types/trait.Index.html#associatedtype.Output"]' 'Output' // @has - '//*[@class="rust fn"]//a[@href="trait.Index.html#associatedtype.Output"]' 'Output'
pub fn use_output<T: Index<usize>>(obj: &T, index: usize) -> &T::Output { pub fn use_output<T: Index<usize>>(obj: &T, index: usize) -> &T::Output {
obj.index(index) obj.index(index)
} }
@ -24,12 +24,12 @@ pub trait Feed {
// @has assoc_types/fn.use_input.html // @has assoc_types/fn.use_input.html
// @has - '//*[@class="rust fn"]' 'T::Input' // @has - '//*[@class="rust fn"]' 'T::Input'
// @has - '//*[@class="rust fn"]//a[@href="../assoc_types/trait.Feed.html#associatedtype.Input"]' 'Input' // @has - '//*[@class="rust fn"]//a[@href="trait.Feed.html#associatedtype.Input"]' 'Input'
pub fn use_input<T: Feed>(_feed: &T, _element: T::Input) { } pub fn use_input<T: Feed>(_feed: &T, _element: T::Input) { }
// @has assoc_types/fn.cmp_input.html // @has assoc_types/fn.cmp_input.html
// @has - '//*[@class="rust fn"]' 'where T::Input: PartialEq<U::Input>' // @has - '//*[@class="rust fn"]' 'where T::Input: PartialEq<U::Input>'
// @has - '//*[@class="rust fn"]//a[@href="../assoc_types/trait.Feed.html#associatedtype.Input"]' 'Input' // @has - '//*[@class="rust fn"]//a[@href="trait.Feed.html#associatedtype.Input"]' 'Input'
pub fn cmp_input<T: Feed, U: Feed>(a: &T::Input, b: &U::Input) -> bool pub fn cmp_input<T: Feed, U: Feed>(a: &T::Input, b: &U::Input) -> bool
where T::Input: PartialEq<U::Input> where T::Input: PartialEq<U::Input>
{ {

View file

@ -0,0 +1,6 @@
// compile-flags: --crate-type lib --edition 2018
#[doc(primitive = "usize")]
/// This is the built-in type `usize`.
mod usize {
}

View file

@ -2,7 +2,7 @@
pub struct Foo; pub struct Foo;
// @has foo/struct.Bar.html '//a[@href="../foo/struct.Foo.html"]' 'Foo' // @has foo/struct.Bar.html '//a[@href="struct.Foo.html"]' 'Foo'
/// Code-styled reference to [`Foo`]. /// Code-styled reference to [`Foo`].
pub struct Bar; pub struct Bar;

View file

@ -0,0 +1,9 @@
// aux-build:primitive-doc.rs
// compile-flags: --extern-html-root-url=primitive_doc=../ -Z unstable-options
#![no_std]
extern crate primitive_doc;
// @has 'cross_crate_primitive_doc/fn.foo.html' '//a[@href="../primitive_doc/primitive.usize.html"]' 'usize'
pub fn foo() -> usize { 0 }

View file

@ -1,7 +1,7 @@
#![crate_name = "foo"] #![crate_name = "foo"]
// @has foo/trait.Foo.html '//a[@href="../foo/trait.Foo.html#tymethod.req"]' 'req' // @has foo/trait.Foo.html '//a[@href="trait.Foo.html#tymethod.req"]' 'req'
// @has foo/trait.Foo.html '//a[@href="../foo/trait.Foo.html#method.prov"]' 'prov' // @has foo/trait.Foo.html '//a[@href="trait.Foo.html#method.prov"]' 'prov'
/// Always make sure to implement [`req`], but you don't have to implement [`prov`]. /// Always make sure to implement [`req`], but you don't have to implement [`prov`].
/// ///

View file

@ -3,7 +3,7 @@
extern crate cross_crate_self; extern crate cross_crate_self;
// @has self/struct.S.html '//a[@href="../self/struct.S.html#method.f"]' "Self::f" // @has self/struct.S.html '//a[@href="struct.S.html#method.f"]' "Self::f"
// @has self/struct.S.html '//a[@href="../self/struct.S.html"]' "Self" // @has self/struct.S.html '//a[@href="struct.S.html"]' "Self"
// @has self/struct.S.html '//a[@href="../cross_crate_self/index.html"]' "crate" // @has self/struct.S.html '//a[@href="../cross_crate_self/index.html"]' "crate"
pub use cross_crate_self::S; pub use cross_crate_self::S;

View file

@ -4,7 +4,7 @@
pub struct Something; pub struct Something;
// @has anchors/struct.SomeOtherType.html // @has anchors/struct.SomeOtherType.html
// @has - '//a/@href' '../anchors/struct.Something.html#Anchor!' // @has - '//a/@href' 'struct.Something.html#Anchor!'
/// I want... /// I want...
/// ///

View file

@ -9,14 +9,14 @@ pub trait TraitWithDefault {
} }
/// Link to [UsesDefaults::T] and [UsesDefaults::f] /// Link to [UsesDefaults::T] and [UsesDefaults::f]
// @has 'associated_defaults/struct.UsesDefaults.html' '//a[@href="../associated_defaults/struct.UsesDefaults.html#associatedtype.T"]' 'UsesDefaults::T' // @has 'associated_defaults/struct.UsesDefaults.html' '//a[@href="struct.UsesDefaults.html#associatedtype.T"]' 'UsesDefaults::T'
// @has 'associated_defaults/struct.UsesDefaults.html' '//a[@href="../associated_defaults/struct.UsesDefaults.html#method.f"]' 'UsesDefaults::f' // @has 'associated_defaults/struct.UsesDefaults.html' '//a[@href="struct.UsesDefaults.html#method.f"]' 'UsesDefaults::f'
pub struct UsesDefaults; pub struct UsesDefaults;
impl TraitWithDefault for UsesDefaults {} impl TraitWithDefault for UsesDefaults {}
/// Link to [OverridesDefaults::T] and [OverridesDefaults::f] /// Link to [OverridesDefaults::T] and [OverridesDefaults::f]
// @has 'associated_defaults/struct.OverridesDefaults.html' '//a[@href="../associated_defaults/struct.OverridesDefaults.html#associatedtype.T"]' 'OverridesDefaults::T' // @has 'associated_defaults/struct.OverridesDefaults.html' '//a[@href="struct.OverridesDefaults.html#associatedtype.T"]' 'OverridesDefaults::T'
// @has 'associated_defaults/struct.OverridesDefaults.html' '//a[@href="../associated_defaults/struct.OverridesDefaults.html#method.f"]' 'OverridesDefaults::f' // @has 'associated_defaults/struct.OverridesDefaults.html' '//a[@href="struct.OverridesDefaults.html#method.f"]' 'OverridesDefaults::f'
pub struct OverridesDefaults; pub struct OverridesDefaults;
impl TraitWithDefault for OverridesDefaults { impl TraitWithDefault for OverridesDefaults {
type T = bool; type T = bool;

View file

@ -9,10 +9,10 @@
pub fn foo() {} pub fn foo() {}
/// Link to [MyStruct], [link from struct][MyStruct::method], [MyStruct::clone], [MyStruct::Input] /// Link to [MyStruct], [link from struct][MyStruct::method], [MyStruct::clone], [MyStruct::Input]
// @has 'associated_items/struct.MyStruct.html' '//a[@href="../associated_items/struct.MyStruct.html"]' 'MyStruct' // @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html"]' 'MyStruct'
// @has 'associated_items/struct.MyStruct.html' '//a[@href="../associated_items/struct.MyStruct.html#method.method"]' 'link from struct' // @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.method"]' 'link from struct'
// @has 'associated_items/struct.MyStruct.html' '//a[@href="../associated_items/struct.MyStruct.html#method.clone"]' 'MyStruct::clone' // @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.clone"]' 'MyStruct::clone'
// @has 'associated_items/struct.MyStruct.html' '//a[@href="../associated_items/struct.MyStruct.html#associatedtype.Input"]' 'MyStruct::Input' // @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#associatedtype.Input"]' 'MyStruct::Input'
pub struct MyStruct { foo: () } pub struct MyStruct { foo: () }
impl Clone for MyStruct { impl Clone for MyStruct {
@ -30,7 +30,7 @@ impl T for MyStruct {
type Input = usize; type Input = usize;
/// [link from method][MyStruct::method] on method /// [link from method][MyStruct::method] on method
// @has 'associated_items/struct.MyStruct.html' '//a[@href="../associated_items/struct.MyStruct.html#method.method"]' 'link from method' // @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.method"]' 'link from method'
fn method(i: usize) { fn method(i: usize) {
} }
} }

View file

@ -1,21 +1,21 @@
// @has basic/index.html // @has basic/index.html
// @has - '//a/@href' '../basic/struct.ThisType.html' // @has - '//a/@href' 'struct.ThisType.html'
// @has - '//a/@href' '../basic/struct.ThisType.html#method.this_method' // @has - '//a/@href' 'struct.ThisType.html#method.this_method'
// @has - '//a/@href' '../basic/enum.ThisEnum.html' // @has - '//a/@href' 'enum.ThisEnum.html'
// @has - '//a/@href' '../basic/enum.ThisEnum.html#variant.ThisVariant' // @has - '//a/@href' 'enum.ThisEnum.html#variant.ThisVariant'
// @has - '//a/@href' '../basic/trait.ThisTrait.html' // @has - '//a/@href' 'trait.ThisTrait.html'
// @has - '//a/@href' '../basic/trait.ThisTrait.html#tymethod.this_associated_method' // @has - '//a/@href' 'trait.ThisTrait.html#tymethod.this_associated_method'
// @has - '//a/@href' '../basic/trait.ThisTrait.html#associatedtype.ThisAssociatedType' // @has - '//a/@href' 'trait.ThisTrait.html#associatedtype.ThisAssociatedType'
// @has - '//a/@href' '../basic/trait.ThisTrait.html#associatedconstant.THIS_ASSOCIATED_CONST' // @has - '//a/@href' 'trait.ThisTrait.html#associatedconstant.THIS_ASSOCIATED_CONST'
// @has - '//a/@href' '../basic/trait.ThisTrait.html' // @has - '//a/@href' 'trait.ThisTrait.html'
// @has - '//a/@href' '../basic/type.ThisAlias.html' // @has - '//a/@href' 'type.ThisAlias.html'
// @has - '//a/@href' '../basic/union.ThisUnion.html' // @has - '//a/@href' 'union.ThisUnion.html'
// @has - '//a/@href' '../basic/fn.this_function.html' // @has - '//a/@href' 'fn.this_function.html'
// @has - '//a/@href' '../basic/constant.THIS_CONST.html' // @has - '//a/@href' 'constant.THIS_CONST.html'
// @has - '//a/@href' '../basic/static.THIS_STATIC.html' // @has - '//a/@href' 'static.THIS_STATIC.html'
// @has - '//a/@href' '../basic/macro.this_macro.html' // @has - '//a/@href' 'macro.this_macro.html'
// @has - '//a/@href' '../basic/trait.SoAmbiguous.html' // @has - '//a/@href' 'trait.SoAmbiguous.html'
// @has - '//a/@href' '../basic/fn.SoAmbiguous.html' // @has - '//a/@href' 'fn.SoAmbiguous.html'
//! In this crate we would like to link to: //! In this crate we would like to link to:
//! //!
//! * [`ThisType`](ThisType) //! * [`ThisType`](ThisType)
@ -46,7 +46,7 @@ macro_rules! this_macro {
() => {}; () => {};
} }
// @has basic/struct.ThisType.html '//a/@href' '../basic/macro.this_macro.html' // @has basic/struct.ThisType.html '//a/@href' 'macro.this_macro.html'
/// another link to [`this_macro!()`] /// another link to [`this_macro!()`]
pub struct ThisType; pub struct ThisType;
@ -72,10 +72,10 @@ pub trait SoAmbiguous {}
pub fn SoAmbiguous() {} pub fn SoAmbiguous() {}
// @has basic/struct.SomeOtherType.html '//a/@href' '../basic/struct.ThisType.html' // @has basic/struct.SomeOtherType.html '//a/@href' 'struct.ThisType.html'
// @has - '//a/@href' '../basic/struct.ThisType.html#method.this_method' // @has - '//a/@href' 'struct.ThisType.html#method.this_method'
// @has - '//a/@href' '../basic/enum.ThisEnum.html' // @has - '//a/@href' 'enum.ThisEnum.html'
// @has - '//a/@href' '../basic/enum.ThisEnum.html#variant.ThisVariant' // @has - '//a/@href' 'enum.ThisEnum.html#variant.ThisVariant'
/// Shortcut links for: /// Shortcut links for:
/// * [`ThisType`] /// * [`ThisType`]
/// * [`ThisType::this_method`] /// * [`ThisType::this_method`]

View file

@ -4,7 +4,7 @@
extern crate my_rand; extern crate my_rand;
// @has 'additional_doc/trait.Rng.html' '//a[@href="../additional_doc/trait.Rng.html"]' 'Rng' // @has 'additional_doc/trait.Rng.html' '//a[@href="trait.Rng.html"]' 'Rng'
// @has 'additional_doc/trait.Rng.html' '//a[@href="../my_rand/trait.RngCore.html"]' 'RngCore' // @has 'additional_doc/trait.Rng.html' '//a[@href="../my_rand/trait.RngCore.html"]' 'RngCore'
/// This is an [`Rng`]. /// This is an [`Rng`].
pub use my_rand::Rng; pub use my_rand::Rng;

View file

@ -6,5 +6,5 @@
extern crate hidden_dep; extern crate hidden_dep;
// @has 'hidden/struct.Ready.html' '//a/@href' '../hidden/fn.ready.html' // @has 'hidden/struct.Ready.html' '//a/@href' 'fn.ready.html'
pub use hidden_dep::future::{ready, Ready}; pub use hidden_dep::future::{ready, Ready};

View file

@ -11,6 +11,6 @@ pub mod bar {
// NOTE: we re-exported both `Foo` and `Bar` here, // NOTE: we re-exported both `Foo` and `Bar` here,
// NOTE: so they are inlined and therefore we link to the current module. // NOTE: so they are inlined and therefore we link to the current module.
// @has 'submodule_outer/trait.Foo.html' '//a[@href="../submodule_outer/bar/trait.Bar.html"]' 'Bar' // @has 'submodule_outer/trait.Foo.html' '//a[@href="bar/trait.Bar.html"]' 'Bar'
// @has 'submodule_outer/trait.Foo.html' '//a[@href="../submodule_outer/trait.Baz.html"]' 'Baz' // @has 'submodule_outer/trait.Foo.html' '//a[@href="trait.Baz.html"]' 'Baz'
pub use ::bar_::{Foo, Baz}; pub use ::bar_::{Foo, Baz};

View file

@ -2,26 +2,26 @@
// first try backticks // first try backticks
/// Trait: [`trait@Name`], fn: [`fn@Name`], [`Name`][`macro@Name`] /// Trait: [`trait@Name`], fn: [`fn@Name`], [`Name`][`macro@Name`]
// @has disambiguators_removed/struct.AtDisambiguator.html // @has disambiguators_removed/struct.AtDisambiguator.html
// @has - '//a[@href="../disambiguators_removed/trait.Name.html"][code]' "Name" // @has - '//a[@href="trait.Name.html"][code]' "Name"
// @has - '//a[@href="../disambiguators_removed/fn.Name.html"][code]' "Name" // @has - '//a[@href="fn.Name.html"][code]' "Name"
// @has - '//a[@href="../disambiguators_removed/macro.Name.html"][code]' "Name" // @has - '//a[@href="macro.Name.html"][code]' "Name"
pub struct AtDisambiguator; pub struct AtDisambiguator;
/// fn: [`Name()`], macro: [`Name!`] /// fn: [`Name()`], macro: [`Name!`]
// @has disambiguators_removed/struct.SymbolDisambiguator.html // @has disambiguators_removed/struct.SymbolDisambiguator.html
// @has - '//a[@href="../disambiguators_removed/fn.Name.html"][code]' "Name()" // @has - '//a[@href="fn.Name.html"][code]' "Name()"
// @has - '//a[@href="../disambiguators_removed/macro.Name.html"][code]' "Name!" // @has - '//a[@href="macro.Name.html"][code]' "Name!"
pub struct SymbolDisambiguator; pub struct SymbolDisambiguator;
// Now make sure that backticks aren't added if they weren't already there // Now make sure that backticks aren't added if they weren't already there
/// [fn@Name] /// [fn@Name]
// @has disambiguators_removed/trait.Name.html // @has disambiguators_removed/trait.Name.html
// @has - '//a[@href="../disambiguators_removed/fn.Name.html"]' "Name" // @has - '//a[@href="fn.Name.html"]' "Name"
// @!has - '//a[@href="../disambiguators_removed/fn.Name.html"][code]' "Name" // @!has - '//a[@href="fn.Name.html"][code]' "Name"
// FIXME: this will turn !() into ! alone // FIXME: this will turn !() into ! alone
/// [Name!()] /// [Name!()]
// @has - '//a[@href="../disambiguators_removed/macro.Name.html"]' "Name!" // @has - '//a[@href="macro.Name.html"]' "Name!"
pub trait Name {} pub trait Name {}
#[allow(non_snake_case)] #[allow(non_snake_case)]
@ -29,22 +29,22 @@ pub trait Name {}
// Try collapsed reference links // Try collapsed reference links
/// [macro@Name][] /// [macro@Name][]
// @has disambiguators_removed/fn.Name.html // @has disambiguators_removed/fn.Name.html
// @has - '//a[@href="../disambiguators_removed/macro.Name.html"]' "Name" // @has - '//a[@href="macro.Name.html"]' "Name"
// Try links that have the same text as a generated URL // Try links that have the same text as a generated URL
/// Weird URL aligned [../disambiguators_removed/macro.Name.html][trait@Name] /// Weird URL aligned [macro.Name.html][trait@Name]
// @has - '//a[@href="../disambiguators_removed/trait.Name.html"]' "../disambiguators_removed/macro.Name.html" // @has - '//a[@href="trait.Name.html"]' "macro.Name.html"
pub fn Name() {} pub fn Name() {}
#[macro_export] #[macro_export]
// Rustdoc doesn't currently handle links that have weird interspersing of inline code blocks. // Rustdoc doesn't currently handle links that have weird interspersing of inline code blocks.
/// [fn@Na`m`e] /// [fn@Na`m`e]
// @has disambiguators_removed/macro.Name.html // @has disambiguators_removed/macro.Name.html
// @has - '//a[@href="../disambiguators_removed/fn.Name.html"]' "fn@Name" // @has - '//a[@href="fn.Name.html"]' "fn@Name"
// It also doesn't handle any case where the code block isn't the whole link text: // It also doesn't handle any case where the code block isn't the whole link text:
/// [trait@`Name`] /// [trait@`Name`]
// @has - '//a[@href="../disambiguators_removed/trait.Name.html"]' "trait@Name" // @has - '//a[@href="trait.Name.html"]' "trait@Name"
macro_rules! Name { macro_rules! Name {
() => () () => ()
} }

View file

@ -11,4 +11,4 @@ pub enum Foo {
/// I want [Foo::X::y]. /// I want [Foo::X::y].
pub fn foo() {} pub fn foo() {}
// @has foo/fn.foo.html '//a/@href' '../foo/enum.Foo.html#variant.X.field.y' // @has foo/fn.foo.html '//a/@href' 'enum.Foo.html#variant.X.field.y'

View file

@ -12,6 +12,6 @@ impl ExternType {
// @has 'extern_type/foreigntype.ExternType.html' // @has 'extern_type/foreigntype.ExternType.html'
// @has 'extern_type/fn.links_to_extern_type.html' \ // @has 'extern_type/fn.links_to_extern_type.html' \
// 'href="../extern_type/foreigntype.ExternType.html#method.f"' // 'href="foreigntype.ExternType.html#method.f"'
/// See also [ExternType::f] /// See also [ExternType::f]
pub fn links_to_extern_type() {} pub fn links_to_extern_type() {}

View file

@ -8,4 +8,4 @@ pub enum Foo {
}, },
} }
// @has foo/enum.Foo.html '//a/@href' '../foo/enum.Foo.html#variant.Bar.field.abc' // @has foo/enum.Foo.html '//a/@href' 'enum.Foo.html#variant.Bar.field.abc'

View file

@ -6,11 +6,11 @@ pub fn foo() {
} }
pub mod foo {} pub mod foo {}
// @has mod_ambiguity/struct.A.html '//a/@href' '../mod_ambiguity/foo/index.html' // @has mod_ambiguity/struct.A.html '//a/@href' 'foo/index.html'
/// Module is [`module@foo`] /// Module is [`module@foo`]
pub struct A; pub struct A;
// @has mod_ambiguity/struct.B.html '//a/@href' '../mod_ambiguity/fn.foo.html' // @has mod_ambiguity/struct.B.html '//a/@href' 'fn.foo.html'
/// Function is [`fn@foo`] /// Function is [`fn@foo`]
pub struct B; pub struct B;

View file

@ -11,6 +11,6 @@ pub mod char {
pub struct MyString; pub struct MyString;
/// See also [crate::char] and [mod@char] /// See also [crate::char] and [mod@char]
// @has prim_precedence/struct.MyString2.html '//*[@href="../prim_precedence/char/index.html"]' 'crate::char' // @has prim_precedence/struct.MyString2.html '//*[@href="char/index.html"]' 'crate::char'
// @has - '//*[@href="../prim_precedence/char/index.html"]' 'mod@char' // @has - '//*[@href="char/index.html"]' 'mod@char'
pub struct MyString2; pub struct MyString2;

View file

@ -4,9 +4,9 @@
// make sure to update `rustdoc-ui/intra-doc/private.rs` if you update this file // make sure to update `rustdoc-ui/intra-doc/private.rs` if you update this file
/// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x]
// @has private/struct.DocMe.html '//*a[@href="../private/struct.DontDocMe.html"]' 'DontDocMe' // @has private/struct.DocMe.html '//*a[@href="struct.DontDocMe.html"]' 'DontDocMe'
// @has private/struct.DocMe.html '//*a[@href="../private/struct.DontDocMe.html#method.f"]' 'DontDocMe::f' // @has private/struct.DocMe.html '//*a[@href="struct.DontDocMe.html#method.f"]' 'DontDocMe::f'
// @has private/struct.DocMe.html '//*a[@href="../private/struct.DontDocMe.html#structfield.x"]' 'DontDocMe::x' // @has private/struct.DocMe.html '//*a[@href="struct.DontDocMe.html#structfield.x"]' 'DontDocMe::x'
pub struct DocMe; pub struct DocMe;
struct DontDocMe { struct DontDocMe {
x: usize, x: usize,

View file

@ -9,17 +9,17 @@ pub use proc_macro_macro::{DeriveA, attr_a};
use proc_macro_macro::{DeriveB, attr_b}; use proc_macro_macro::{DeriveB, attr_b};
// @has proc_macro/struct.Foo.html // @has proc_macro/struct.Foo.html
// @has - '//a/@href' '../proc_macro/derive.DeriveA.html' // @has - '//a/@href' 'derive.DeriveA.html'
// @has - '//a/@href' '../proc_macro/attr.attr_a.html' // @has - '//a/@href' 'attr.attr_a.html'
// @has - '//a/@href' '../proc_macro/trait.DeriveTrait.html' // @has - '//a/@href' 'trait.DeriveTrait.html'
// @has - '//a/@href' '../proc_macro_macro/derive.DeriveB.html' // @has - '//a/@href' '../proc_macro_macro/derive.DeriveB.html'
// @has - '//a/@href' '../proc_macro_macro/attr.attr_b.html' // @has - '//a/@href' '../proc_macro_macro/attr.attr_b.html'
/// Link to [DeriveA], [attr_a], [DeriveB], [attr_b], [DeriveTrait] /// Link to [DeriveA], [attr_a], [DeriveB], [attr_b], [DeriveTrait]
pub struct Foo; pub struct Foo;
// @has proc_macro/struct.Bar.html // @has proc_macro/struct.Bar.html
// @has - '//a/@href' '../proc_macro/derive.DeriveA.html' // @has - '//a/@href' 'derive.DeriveA.html'
// @has - '//a/@href' '../proc_macro/attr.attr_a.html' // @has - '//a/@href' 'attr.attr_a.html'
/// Link to [deriveA](derive@DeriveA) [attr](macro@attr_a) /// Link to [deriveA](derive@DeriveA) [attr](macro@attr_a)
pub struct Bar; pub struct Bar;

View file

@ -13,7 +13,7 @@ extern crate inner;
// @has outer/index.html // @has outer/index.html
// @ has - '//a[@href="https://doc.rust-lang.org/nightly/std/env/fn.var.html"]' "std::env" // @ has - '//a[@href="https://doc.rust-lang.org/nightly/std/env/fn.var.html"]' "std::env"
// @ has - '//a[@href="../outer/fn.f.html"]' "g" // @ has - '//a[@href="fn.f.html"]' "g"
pub use f as g; pub use f as g;
// FIXME: same as above // FIXME: same as above

View file

@ -5,7 +5,7 @@ pub mod r#impl {
impl S { impl S {
/// See [Self::b]. /// See [Self::b].
// @has raw_ident_self/impl/struct.S.html // @has raw_ident_self/impl/struct.S.html
// @has - '//a[@href="../../raw_ident_self/impl/struct.S.html#method.b"]' 'Self::b' // @has - '//a[@href="struct.S.html#method.b"]' 'Self::b'
pub fn a() {} pub fn a() {}
pub fn b() {} pub fn b() {}

View file

@ -3,13 +3,13 @@
#![crate_name = "foo"] #![crate_name = "foo"]
extern crate inner; extern crate inner;
// @has foo/struct.Inner.html '//a[@href="../foo/fn.with_code.html"]' 'crate::with_code' // @has foo/struct.Inner.html '//a[@href="fn.with_code.html"]' 'crate::with_code'
/// [crate::with_code] /// [crate::with_code]
// @has - '//a[@href="../foo/fn.with_code.html"]' 'different text' // @has - '//a[@href="fn.with_code.html"]' 'different text'
/// [different text][with_code] /// [different text][with_code]
// @has - '//a[@href="../foo/fn.me_too.html"]' 'me_too' // @has - '//a[@href="fn.me_too.html"]' 'me_too'
#[doc = "[me_too]"] #[doc = "[me_too]"]
// @has - '//a[@href="../foo/fn.me_three.html"]' 'reference link' // @has - '//a[@href="fn.me_three.html"]' 'reference link'
/// This [reference link] /// This [reference link]
#[doc = "has an attr in the way"] #[doc = "has an attr in the way"]
/// ///

View file

@ -1,8 +1,8 @@
#![crate_name = "foo"] #![crate_name = "foo"]
// @has foo/index.html '//a/@href' '../foo/struct.Foo.html#method.new' // @has foo/index.html '//a/@href' 'struct.Foo.html#method.new'
// @has foo/struct.Foo.html '//a/@href' '../foo/struct.Foo.html#method.new' // @has foo/struct.Foo.html '//a/@href' 'struct.Foo.html#method.new'
/// Use [`new`] to create a new instance. /// Use [`new`] to create a new instance.
/// ///
@ -15,8 +15,8 @@ impl Foo {
} }
} }
// @has foo/index.html '//a/@href' '../foo/struct.Bar.html#method.new2' // @has foo/index.html '//a/@href' 'struct.Bar.html#method.new2'
// @has foo/struct.Bar.html '//a/@href' '../foo/struct.Bar.html#method.new2' // @has foo/struct.Bar.html '//a/@href' 'struct.Bar.html#method.new2'
/// Use [`new2`] to create a new instance. /// Use [`new2`] to create a new instance.
/// ///
@ -30,7 +30,7 @@ impl Bar {
} }
pub struct MyStruct { pub struct MyStruct {
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#structfield.struct_field' // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#structfield.struct_field'
/// [`struct_field`] /// [`struct_field`]
/// ///
@ -39,7 +39,7 @@ pub struct MyStruct {
} }
pub enum MyEnum { pub enum MyEnum {
// @has foo/enum.MyEnum.html '//a/@href' '../foo/enum.MyEnum.html#variant.EnumVariant' // @has foo/enum.MyEnum.html '//a/@href' 'enum.MyEnum.html#variant.EnumVariant'
/// [`EnumVariant`] /// [`EnumVariant`]
/// ///
@ -48,7 +48,7 @@ pub enum MyEnum {
} }
pub union MyUnion { pub union MyUnion {
// @has foo/union.MyUnion.html '//a/@href' '../foo/union.MyUnion.html#structfield.union_field' // @has foo/union.MyUnion.html '//a/@href' 'union.MyUnion.html#structfield.union_field'
/// [`union_field`] /// [`union_field`]
/// ///
@ -57,21 +57,21 @@ pub union MyUnion {
} }
pub trait MyTrait { pub trait MyTrait {
// @has foo/trait.MyTrait.html '//a/@href' '../foo/trait.MyTrait.html#associatedtype.AssoType' // @has foo/trait.MyTrait.html '//a/@href' 'trait.MyTrait.html#associatedtype.AssoType'
/// [`AssoType`] /// [`AssoType`]
/// ///
/// [`AssoType`]: Self::AssoType /// [`AssoType`]: Self::AssoType
type AssoType; type AssoType;
// @has foo/trait.MyTrait.html '//a/@href' '../foo/trait.MyTrait.html#associatedconstant.ASSO_CONST' // @has foo/trait.MyTrait.html '//a/@href' 'trait.MyTrait.html#associatedconstant.ASSO_CONST'
/// [`ASSO_CONST`] /// [`ASSO_CONST`]
/// ///
/// [`ASSO_CONST`]: Self::ASSO_CONST /// [`ASSO_CONST`]: Self::ASSO_CONST
const ASSO_CONST: i32 = 1; const ASSO_CONST: i32 = 1;
// @has foo/trait.MyTrait.html '//a/@href' '../foo/trait.MyTrait.html#method.asso_fn' // @has foo/trait.MyTrait.html '//a/@href' 'trait.MyTrait.html#method.asso_fn'
/// [`asso_fn`] /// [`asso_fn`]
/// ///
@ -80,7 +80,7 @@ pub trait MyTrait {
} }
impl MyStruct { impl MyStruct {
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#method.for_impl' // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#method.for_impl'
/// [`for_impl`] /// [`for_impl`]
/// ///
@ -91,21 +91,21 @@ impl MyStruct {
} }
impl MyTrait for MyStruct { impl MyTrait for MyStruct {
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#associatedtype.AssoType' // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#associatedtype.AssoType'
/// [`AssoType`] /// [`AssoType`]
/// ///
/// [`AssoType`]: Self::AssoType /// [`AssoType`]: Self::AssoType
type AssoType = u32; type AssoType = u32;
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#associatedconstant.ASSO_CONST' // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#associatedconstant.ASSO_CONST'
/// [`ASSO_CONST`] /// [`ASSO_CONST`]
/// ///
/// [`ASSO_CONST`]: Self::ASSO_CONST /// [`ASSO_CONST`]: Self::ASSO_CONST
const ASSO_CONST: i32 = 10; const ASSO_CONST: i32 = 10;
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#method.asso_fn' // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#method.asso_fn'
/// [`asso_fn`] /// [`asso_fn`]
/// ///

View file

@ -5,21 +5,21 @@ pub struct MyStruct;
impl MyTrait for MyStruct { impl MyTrait for MyStruct {
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#associatedtype.AssoType' // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#associatedtype.AssoType'
/// [`AssoType`] /// [`AssoType`]
/// ///
/// [`AssoType`]: MyStruct::AssoType /// [`AssoType`]: MyStruct::AssoType
type AssoType = u32; type AssoType = u32;
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#associatedconstant.ASSO_CONST' // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#associatedconstant.ASSO_CONST'
/// [`ASSO_CONST`] /// [`ASSO_CONST`]
/// ///
/// [`ASSO_CONST`]: MyStruct::ASSO_CONST /// [`ASSO_CONST`]: MyStruct::ASSO_CONST
const ASSO_CONST: i32 = 10; const ASSO_CONST: i32 = 10;
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#method.trait_fn' // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#method.trait_fn'
/// [`trait_fn`] /// [`trait_fn`]
/// ///

View file

@ -2,7 +2,7 @@
/// Link to [S::assoc_fn()] /// Link to [S::assoc_fn()]
/// Link to [Default::default()] /// Link to [Default::default()]
// @has trait_item/struct.S.html '//*[@href="../trait_item/struct.S.html#method.assoc_fn"]' 'S::assoc_fn()' // @has trait_item/struct.S.html '//*[@href="struct.S.html#method.assoc_fn"]' 'S::assoc_fn()'
// @has - '//*[@href="https://doc.rust-lang.org/nightly/core/default/trait.Default.html#tymethod.default"]' 'Default::default()' // @has - '//*[@href="https://doc.rust-lang.org/nightly/core/default/trait.Default.html#tymethod.default"]' 'Default::default()'
pub struct S; pub struct S;

View file

@ -1,12 +1,12 @@
#![crate_name = "foo"] #![crate_name = "foo"]
// @has foo/enum.E1.html '//a/@href' '../foo/enum.E1.html#variant.A' // @has foo/enum.E1.html '//a/@href' 'enum.E1.html#variant.A'
/// [Self::A::b] /// [Self::A::b]
pub enum E1 { pub enum E1 {
A { b: usize } A { b: usize }
} }
// @has foo/enum.E2.html '//a/@href' '../foo/enum.E2.html#variant.A' // @has foo/enum.E2.html '//a/@href' 'enum.E2.html#variant.A'
/// [Self::A::b] /// [Self::A::b]
pub enum E2 { pub enum E2 {

View file

@ -23,9 +23,9 @@ impl Foo {
} }
impl Bar for Foo { impl Bar for Foo {
// @has - '//*[@href="../issue_28478/trait.Bar.html#associatedtype.Bar"]' 'Bar' // @has - '//*[@href="trait.Bar.html#associatedtype.Bar"]' 'Bar'
// @has - '//*[@href="../issue_28478/trait.Bar.html#associatedconstant.Baz"]' 'Baz' // @has - '//*[@href="trait.Bar.html#associatedconstant.Baz"]' 'Baz'
// @has - '//*[@href="../issue_28478/trait.Bar.html#tymethod.bar"]' 'bar' // @has - '//*[@href="trait.Bar.html#tymethod.bar"]' 'bar'
fn bar() {} fn bar() {}
// @has - '//*[@href="../issue_28478/trait.Bar.html#method.baz"]' 'baz' // @has - '//*[@href="trait.Bar.html#method.baz"]' 'baz'
} }

View file

@ -2,19 +2,19 @@
// @has issue_55364/subone/index.html // @has issue_55364/subone/index.html
// These foo/bar links in the module's documentation should refer inside `subone` // These foo/bar links in the module's documentation should refer inside `subone`
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/subone/fn.foo.html"]' 'foo' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="fn.foo.html"]' 'foo'
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/subone/fn.bar.html"]' 'bar' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="fn.bar.html"]' 'bar'
pub mod subone { pub mod subone {
//! See either [foo] or [bar]. //! See either [foo] or [bar].
// This should refer to subone's `bar` // This should refer to subone's `bar`
// @has issue_55364/subone/fn.foo.html // @has issue_55364/subone/fn.foo.html
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/subone/fn.bar.html"]' 'bar' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="fn.bar.html"]' 'bar'
/// See [bar] /// See [bar]
pub fn foo() {} pub fn foo() {}
// This should refer to subone's `foo` // This should refer to subone's `foo`
// @has issue_55364/subone/fn.bar.html // @has issue_55364/subone/fn.bar.html
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/subone/fn.foo.html"]' 'foo' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="fn.foo.html"]' 'foo'
/// See [foo] /// See [foo]
pub fn bar() {} pub fn bar() {}
} }
@ -23,11 +23,11 @@ pub mod subone {
// @has issue_55364/subtwo/index.html // @has issue_55364/subtwo/index.html
// These foo/bar links in the module's documentation should not reference inside `subtwo` // These foo/bar links in the module's documentation should not reference inside `subtwo`
// @!has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/subtwo/fn.foo.html"]' 'foo' // @!has - '//section[@id="main"]/div[@class="docblock"]//a[@href="fn.foo.html"]' 'foo'
// @!has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/subtwo/fn.bar.html"]' 'bar' // @!has - '//section[@id="main"]/div[@class="docblock"]//a[@href="fn.bar.html"]' 'bar'
// Instead it should be referencing the top level functions // Instead it should be referencing the top level functions
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/fn.foo.html"]' 'foo' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../fn.foo.html"]' 'foo'
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/fn.bar.html"]' 'bar' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../fn.bar.html"]' 'bar'
// Though there should be such links later // Though there should be such links later
// @has - '//section[@id="main"]/table//tr[@class="module-item"]/td/a[@class="fn"][@href="fn.foo.html"]' 'foo' // @has - '//section[@id="main"]/table//tr[@class="module-item"]/td/a[@class="fn"][@href="fn.foo.html"]' 'foo'
// @has - '//section[@id="main"]/table//tr[@class="module-item"]/td/a[@class="fn"][@href="fn.bar.html"]' 'bar' // @has - '//section[@id="main"]/table//tr[@class="module-item"]/td/a[@class="fn"][@href="fn.bar.html"]' 'bar'
@ -37,13 +37,13 @@ pub mod subtwo {
// Despite the module's docs referring to the top level foo/bar, // Despite the module's docs referring to the top level foo/bar,
// this should refer to subtwo's `bar` // this should refer to subtwo's `bar`
// @has issue_55364/subtwo/fn.foo.html // @has issue_55364/subtwo/fn.foo.html
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/subtwo/fn.bar.html"]' 'bar' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="fn.bar.html"]' 'bar'
/// See [bar] /// See [bar]
pub fn foo() {} pub fn foo() {}
// Despite the module's docs referring to the top level foo/bar, // Despite the module's docs referring to the top level foo/bar,
// this should refer to subtwo's `foo` // this should refer to subtwo's `foo`
// @has issue_55364/subtwo/fn.bar.html // @has issue_55364/subtwo/fn.bar.html
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/subtwo/fn.foo.html"]' 'foo' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="fn.foo.html"]' 'foo'
/// See [foo] /// See [foo]
pub fn bar() {} pub fn bar() {}
} }
@ -59,8 +59,8 @@ pub fn bar() {}
// @has issue_55364/subthree/index.html // @has issue_55364/subthree/index.html
// This module should also refer to the top level foo/bar // This module should also refer to the top level foo/bar
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/fn.foo.html"]' 'foo' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../fn.foo.html"]' 'foo'
// @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../../issue_55364/fn.bar.html"]' 'bar' // @has - '//section[@id="main"]/div[@class="docblock"]//a[@href="../fn.bar.html"]' 'bar'
pub mod subthree { pub mod subthree {
//! See either [foo][super::foo] or [bar][super::bar] //! See either [foo][super::foo] or [bar][super::bar]
} }
@ -68,8 +68,8 @@ pub mod subthree {
// Next we go *deeper* - In order to ensure it's not just "this or parent" // Next we go *deeper* - In order to ensure it's not just "this or parent"
// we test `crate::` and a `super::super::...` chain // we test `crate::` and a `super::super::...` chain
// @has issue_55364/subfour/subfive/subsix/subseven/subeight/index.html // @has issue_55364/subfour/subfive/subsix/subseven/subeight/index.html
// @has - '//section[@id="main"]/table//tr[@class="module-item"]/td[@class="docblock-short"]//a[@href="../../../../../../issue_55364/subone/fn.foo.html"]' 'other foo' // @has - '//section[@id="main"]/table//tr[@class="module-item"]/td[@class="docblock-short"]//a[@href="../../../../../subone/fn.foo.html"]' 'other foo'
// @has - '//section[@id="main"]/table//tr[@class="module-item"]/td[@class="docblock-short"]//a[@href="../../../../../../issue_55364/subtwo/fn.bar.html"]' 'other bar' // @has - '//section[@id="main"]/table//tr[@class="module-item"]/td[@class="docblock-short"]//a[@href="../../../../../subtwo/fn.bar.html"]' 'other bar'
pub mod subfour { pub mod subfour {
pub mod subfive { pub mod subfive {
pub mod subsix { pub mod subsix {

View file

@ -10,7 +10,7 @@ impl Body {
} }
impl Default for Body { impl Default for Body {
// @has foo/struct.Body.html '//a/@href' '../foo/struct.Body.html#method.empty' // @has foo/struct.Body.html '//a/@href' 'struct.Body.html#method.empty'
/// Returns [`Body::empty()`](Body::empty). /// Returns [`Body::empty()`](Body::empty).
fn default() -> Body { fn default() -> Body {

View file

@ -1,7 +1,7 @@
#![crate_name = "foo"] #![crate_name = "foo"]
// @has foo/index.html '//a[@href="../foo/foo/constant.FIRSTCONST.html"]' 'foo::FIRSTCONST' // @has foo/index.html '//a[@href="foo/constant.FIRSTCONST.html"]' 'foo::FIRSTCONST'
// @has foo/index.html '//a[@href="../foo/struct.Bar.html#associatedconstant.CONST"]' 'Bar::CONST' // @has foo/index.html '//a[@href="struct.Bar.html#associatedconstant.CONST"]' 'Bar::CONST'
//! We have here [`foo::FIRSTCONST`] and [`Bar::CONST`]. //! We have here [`foo::FIRSTCONST`] and [`Bar::CONST`].

View file

@ -61,12 +61,12 @@ pub fn some_derive(_item: TokenStream) -> TokenStream {
// @has some_macros/foo/index.html // @has some_macros/foo/index.html
mod foo { mod foo {
// @has - '//code' 'pub use some_proc_macro;' // @has - '//code' 'pub use some_proc_macro;'
// @has - '//a/@href' '../../some_macros/macro.some_proc_macro.html' // @has - '//a/@href' '../macro.some_proc_macro.html'
pub use some_proc_macro; pub use some_proc_macro;
// @has - '//code' 'pub use some_proc_attr;' // @has - '//code' 'pub use some_proc_attr;'
// @has - '//a/@href' '../../some_macros/attr.some_proc_attr.html' // @has - '//a/@href' '../attr.some_proc_attr.html'
pub use some_proc_attr; pub use some_proc_attr;
// @has - '//code' 'pub use some_derive;' // @has - '//code' 'pub use some_derive;'
// @has - '//a/@href' '../../some_macros/derive.SomeDerive.html' // @has - '//a/@href' '../derive.SomeDerive.html'
pub use some_derive; pub use some_derive;
} }

View file

@ -8,13 +8,13 @@ pub mod internal {
/// ///
/// [name]: mod /// [name]: mod
/// [other name]: crate::internal::mod /// [other name]: crate::internal::mod
// @has 'raw_ident_eliminate_r_hashtag/internal/struct.B.html' '//*a[@href="../../raw_ident_eliminate_r_hashtag/internal/struct.mod.html"]' 'name' // @has 'raw_ident_eliminate_r_hashtag/internal/struct.B.html' '//*a[@href="struct.mod.html"]' 'name'
// @has 'raw_ident_eliminate_r_hashtag/internal/struct.B.html' '//*a[@href="../../raw_ident_eliminate_r_hashtag/internal/struct.mod.html"]' 'other name' // @has 'raw_ident_eliminate_r_hashtag/internal/struct.B.html' '//*a[@href="struct.mod.html"]' 'other name'
pub struct B; pub struct B;
} }
/// See [name]. /// See [name].
/// ///
/// [name]: internal::mod /// [name]: internal::mod
// @has 'raw_ident_eliminate_r_hashtag/struct.A.html' '//*a[@href="../raw_ident_eliminate_r_hashtag/internal/struct.mod.html"]' 'name' // @has 'raw_ident_eliminate_r_hashtag/struct.A.html' '//*a[@href="internal/struct.mod.html"]' 'name'
pub struct A; pub struct A;

View file

@ -1,9 +1,9 @@
#![crate_name = "foo"] #![crate_name = "foo"]
// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/struct.Foo.html#structfield.bar"]' 'Foo::bar' // @has foo/index.html '//*[@class="docblock"]/p/a[@href="struct.Foo.html#structfield.bar"]' 'Foo::bar'
// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/union.Bar.html#structfield.foo"]' 'Bar::foo' // @has foo/index.html '//*[@class="docblock"]/p/a[@href="union.Bar.html#structfield.foo"]' 'Bar::foo'
// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/enum.Uniooon.html#variant.X"]' 'Uniooon::X' // @has foo/index.html '//*[@class="docblock"]/p/a[@href="enum.Uniooon.html#variant.X"]' 'Uniooon::X'
//! Test with [Foo::bar], [Bar::foo], [Uniooon::X] //! Test with [Foo::bar], [Bar::foo], [Uniooon::X]

View file

@ -40,25 +40,25 @@ impl MyTrait for Vec<u8> {
impl MyTrait for MyStruct { impl MyTrait for MyStruct {
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="type"]/@href' #associatedtype.Assoc // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="type"]/@href' #associatedtype.Assoc
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="anchor"]/@href' #associatedtype.Assoc-3 // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="anchor"]/@href' #associatedtype.Assoc-3
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="type"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedtype.Assoc // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="type"]/@href' trait.MyTrait.html#associatedtype.Assoc
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="anchor"]/@href' #associatedtype.Assoc // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="anchor"]/@href' #associatedtype.Assoc
type Assoc = bool; type Assoc = bool;
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="constant"]/@href' #associatedconstant.VALUE // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="constant"]/@href' #associatedconstant.VALUE
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-3 // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-3
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedconstant.VALUE // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' trait.MyTrait.html#associatedconstant.VALUE
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE
const VALUE: u32 = 20; const VALUE: u32 = 20;
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="fnname"]/@href' #tymethod.trait_function // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="fnname"]/@href' #tymethod.trait_function
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="anchor"]/@href' #method.trait_function-2 // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="anchor"]/@href' #method.trait_function-2
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#tymethod.trait_function // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' trait.MyTrait.html#tymethod.trait_function
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
fn trait_function(&self) {} fn trait_function(&self) {}
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="fnname"]/@href' #method.defaulted_override // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="fnname"]/@href' #method.defaulted_override
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="anchor"]/@href' #method.defaulted_override-3 // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="anchor"]/@href' #method.defaulted_override-3
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#method.defaulted_override // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="fnname"]/@href' trait.MyTrait.html#method.defaulted_override
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="anchor"]/@href' #method.defaulted_override // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="anchor"]/@href' #method.defaulted_override
fn defaulted_override(&self) {} fn defaulted_override(&self) {}
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#method.defaulted // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted"]//a[@class="fnname"]/@href' trait.MyTrait.html#method.defaulted
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted"]//a[@class="anchor"]/@href' #method.defaulted // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted"]//a[@class="anchor"]/@href' #method.defaulted
} }

View file

@ -1,4 +1,4 @@
// @has trait_self_link/trait.Foo.html //a/@href ../trait_self_link/trait.Foo.html // @has trait_self_link/trait.Foo.html //a/@href trait.Foo.html
pub trait Foo {} pub trait Foo {}
pub struct Bar; pub struct Bar;

View file

@ -246,7 +246,7 @@ function lookForEntry(entry, data) {
return null; return null;
} }
function loadMainJsAndIndex(mainJs, searchIndex, storageJs, crate) { function loadSearchJsAndIndex(searchJs, searchIndex, storageJs, crate) {
if (searchIndex[searchIndex.length - 1].length === 0) { if (searchIndex[searchIndex.length - 1].length === 0) {
searchIndex.pop(); searchIndex.pop();
} }
@ -270,9 +270,9 @@ function loadMainJsAndIndex(mainJs, searchIndex, storageJs, crate) {
ALIASES = {}; ALIASES = {};
finalJS += 'window = { "currentCrate": "' + crate + '", rootPath: "../" };\n'; finalJS += 'window = { "currentCrate": "' + crate + '", rootPath: "../" };\n';
finalJS += loadThings(["hasOwnProperty", "onEach"], 'function', extractFunction, storageJs); finalJS += loadThings(["hasOwnProperty", "onEach"], 'function', extractFunction, storageJs);
finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, searchJs);
finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); finalJS += loadThings(variablesToLoad, 'variable', extractVariable, searchJs);
finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs); finalJS += loadThings(functionsToLoad, 'function', extractFunction, searchJs);
var loaded = loadContent(finalJS); var loaded = loadContent(finalJS);
var index = loaded.buildIndex(searchIndex.rawSearchIndex); var index = loaded.buildIndex(searchIndex.rawSearchIndex);
@ -382,12 +382,12 @@ function runChecks(testFile, loaded, index) {
} }
function load_files(doc_folder, resource_suffix, crate) { function load_files(doc_folder, resource_suffix, crate) {
var mainJs = readFile(path.join(doc_folder, "main" + resource_suffix + ".js")); var searchJs = readFile(path.join(doc_folder, "search" + resource_suffix + ".js"));
var storageJs = readFile(path.join(doc_folder, "storage" + resource_suffix + ".js")); var storageJs = readFile(path.join(doc_folder, "storage" + resource_suffix + ".js"));
var searchIndex = readFile( var searchIndex = readFile(
path.join(doc_folder, "search-index" + resource_suffix + ".js")).split("\n"); path.join(doc_folder, "search-index" + resource_suffix + ".js")).split("\n");
return loadMainJsAndIndex(mainJs, searchIndex, storageJs, crate); return loadSearchJsAndIndex(searchJs, searchIndex, storageJs, crate);
} }
function showHelp() { function showHelp() {