From 258be67fc7fcd0cae0650a97f9a121041fe7d7f7 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sat, 13 Dec 2025 02:32:00 +0200 Subject: [PATCH] `join_path_syms_lazy` --- src/librustdoc/html/format.rs | 18 +++++++++++---- src/librustdoc/html/render/context.rs | 4 ++-- src/librustdoc/html/render/print_item.rs | 8 +++---- src/librustdoc/html/render/search_index.rs | 27 ++++++++++++---------- 4 files changed, 34 insertions(+), 23 deletions(-) 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() }