diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index eee13ff2b0dc0..d1f262f40c6c4 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -14,7 +14,6 @@ use std::slice;
use itertools::{Either, Itertools};
use rustc_abi::ExternAbi;
-use rustc_ast::join_path_syms;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, MacroKinds};
@@ -37,6 +36,15 @@ use crate::html::escape::{Escape, EscapeBodyText};
use crate::html::render::Context;
use crate::passes::collect_intra_doc_links::UrlFragment;
+pub(crate) fn join_path_syms_lazy(path: &[Symbol]) -> impl Display + '_ {
+ fmt::from_fn(move |f| {
+ path.iter()
+ .copied()
+ .map(|seg| Some(seg).filter(|seg| *seg != kw::PathRoot).maybe_display())
+ .joined("::", f)
+ })
+}
+
pub(crate) fn print_generic_bounds(
bounds: &[clean::GenericBound],
cx: &Context<'_>,
@@ -674,7 +682,7 @@ pub(crate) fn link_tooltip(
write!(f, "{}", cx.tcx().item_name(id))?;
} else if !fqp.is_empty() {
write!(f, "{shortty} ")?;
- write!(f, "{}", join_path_syms(fqp))?;
+ write!(f, "{}", join_path_syms_lazy(fqp))?;
}
Ok(())
})
@@ -705,7 +713,7 @@ fn resolved_path(
write!(
f,
"{path}::{anchor}",
- path = join_path_syms(&rust_path[..rust_path.len() - 1]),
+ path = join_path_syms_lazy(&rust_path[..rust_path.len() - 1]),
anchor = print_anchor(did, *rust_path.last().unwrap(), cx)
)
} else {
@@ -863,7 +871,7 @@ pub(crate) fn print_anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl D
f,
r#"{text}"#,
anchor = fragment(did, cx.tcx()),
- path = join_path_syms(rust_path),
+ path = join_path_syms_lazy(&rust_path),
text = EscapeBodyText(text.as_str()),
)
} else {
@@ -1097,7 +1105,7 @@ fn print_qpath_data(qpath_data: &clean::QPathData, cx: &Context<'_>) -> impl Dis
title=\"type {path}::{name}\">{name}",
shortty = ItemType::AssocType,
name = assoc.name,
- path = join_path_syms(rust_path),
+ path = join_path_syms_lazy(&rust_path),
)
} else {
write!(f, "{}", assoc.name)
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 3d4dff4a17d22..d788e5a584ecd 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -6,7 +6,6 @@ use std::path::{Path, PathBuf};
use std::sync::mpsc::{Receiver, channel};
use askama::Template;
-use rustc_ast::join_path_syms;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_hir::Attribute;
use rustc_hir::attrs::AttributeKind;
@@ -30,6 +29,7 @@ use crate::formats::FormatRenderer;
use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType;
use crate::html::escape::Escape;
+use crate::html::format::join_path_syms_lazy;
use crate::html::macro_expansion::ExpandedCode;
use crate::html::markdown::{self, ErrorCodes, IdMap, plain_text_summary};
use crate::html::render::span_map::Span;
@@ -228,7 +228,7 @@ impl<'tcx> Context<'tcx> {
title.push_str(" in ");
}
// No need to include the namespace for primitive types and keywords
- title.push_str(&join_path_syms(&self.current));
+ write!(title, "{}", join_path_syms_lazy(&self.current)).unwrap();
};
title.push_str(" - Rust");
let tyname = it.type_();
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index f88a5b8974fb9..dcfe762644c36 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -31,9 +31,9 @@ use crate::formats::Impl;
use crate::formats::item_type::ItemType;
use crate::html::escape::{Escape, EscapeBodyTextWithWbr};
use crate::html::format::{
- Ending, PrintWithSpace, full_print_fn_decl, print_abi_with_space, print_constness_with_space,
- print_generic_bound, print_generics, print_impl, print_import, print_type, print_where_clause,
- visibility_print_with_space,
+ Ending, PrintWithSpace, full_print_fn_decl, join_path_syms_lazy, print_abi_with_space,
+ print_constness_with_space, print_generic_bound, print_generics, print_impl, print_import,
+ print_type, print_where_clause, visibility_print_with_space,
};
use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
use crate::html::render::sidebar::filters;
@@ -1451,7 +1451,7 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) ->
iter::repeat_n("..", cx.current.len()).chain(iter::once("type.impl")).collect();
js_src_path.extend(target_fqp[..target_fqp.len() - 1].iter().copied());
js_src_path.push_fmt(format_args!("{target_type}.{}.js", target_fqp.last().unwrap()));
- let self_path = join_path_syms(self_fqp);
+ let self_path = join_path_syms_lazy(self_fqp);
write!(
w,
"",
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index 12b207dda5693..0ab76927dd394 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -10,7 +10,6 @@ use std::{io, iter};
use ::serde::de::{self, Deserializer, Error as _};
use ::serde::ser::{SerializeSeq, Serializer};
use ::serde::{Deserialize, Serialize};
-use rustc_ast::join_path_syms;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::thin_vec::ThinVec;
use rustc_hir::attrs::AttributeKind;
@@ -28,6 +27,7 @@ use crate::config::ShouldMerge;
use crate::error::Error;
use crate::formats::cache::{Cache, OrphanImplItem};
use crate::formats::item_type::ItemType;
+use crate::html::format::join_path_syms_lazy;
use crate::html::markdown::short_markdown_summary;
use crate::html::render::{self, IndexItem, IndexItemFunctionType, RenderType, RenderTypeId};
@@ -971,6 +971,17 @@ struct PathData {
exact_module_path: Option>,
}
+struct SerializedPath<'a>(&'a [Symbol]);
+
+impl<'a> Serialize for SerializedPath<'a> {
+ fn serialize(&self, serializer: S) -> Result
+ where
+ S: Serializer,
+ {
+ serializer.collect_str(&join_path_syms_lazy(self.0))
+ }
+}
+
impl Serialize for PathData {
fn serialize(&self, serializer: S) -> Result
where
@@ -978,17 +989,9 @@ impl Serialize for PathData {
{
let mut seq = serializer.serialize_seq(None)?;
seq.serialize_element(&self.ty)?;
- seq.serialize_element(&if self.module_path.is_empty() {
- String::new()
- } else {
- join_path_syms(&self.module_path)
- })?;
- if let Some(ref path) = self.exact_module_path {
- seq.serialize_element(&if path.is_empty() {
- String::new()
- } else {
- join_path_syms(path)
- })?;
+ seq.serialize_element(&SerializedPath(&self.module_path))?;
+ if let Some(path) = &self.exact_module_path {
+ seq.serialize_element(&SerializedPath(path))?;
}
seq.end()
}