From a7a43cd37308b774e4d562f1dbaf2793461ae09e Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Wed, 5 Feb 2025 12:54:31 +0000 Subject: [PATCH 1/3] use `Iterator::zip` instead of enumerating+indexing --- src/librustdoc/clean/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 92ef3ab7a1d47..dcc5fd12d81bf 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1150,9 +1150,9 @@ fn clean_args_from_types_and_body_id<'tcx>( Arguments { values: types .iter() - .enumerate() - .map(|(i, ty)| Argument { - name: name_from_pat(body.params[i].pat), + .zip(body.params) + .map(|(ty, param)| Argument { + name: name_from_pat(param.pat), type_: clean_ty(ty, cx), is_const: false, }) From 4a76615054efaea8a7c0a77ec4b77277da7c64be Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Wed, 5 Feb 2025 13:03:12 +0000 Subject: [PATCH 2/3] coalesce match patterns with identical bodies --- src/librustdoc/clean/utils.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 8a7d140bb1a69..418e60fd97254 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -299,10 +299,15 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { Symbol::intern(&match p.kind { // FIXME(never_patterns): does this make sense? - PatKind::Wild | PatKind::Err(_) | PatKind::Never | PatKind::Struct(..) => { + PatKind::Wild + | PatKind::Err(_) + | PatKind::Never + | PatKind::Struct(..) + | PatKind::Range(..) => { return kw::Underscore; } PatKind::Binding(_, _, ident, _) => return ident.name, + PatKind::Box(p) | PatKind::Ref(p, _) | PatKind::Guard(p, _) => return name_from_pat(p), PatKind::TupleStruct(ref p, ..) | PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref p), .. }) => qpath_to_string(p), PatKind::Or(pats) => { @@ -312,17 +317,13 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { "({})", elts.iter().map(|p| name_from_pat(p).to_string()).collect::>().join(", ") ), - PatKind::Box(p) => return name_from_pat(p), PatKind::Deref(p) => format!("deref!({})", name_from_pat(p)), - PatKind::Ref(p, _) => return name_from_pat(p), PatKind::Expr(..) => { warn!( "tried to get argument name from PatKind::Expr, which is silly in function arguments" ); return Symbol::intern("()"); } - PatKind::Guard(p, _) => return name_from_pat(p), - PatKind::Range(..) => return kw::Underscore, PatKind::Slice(begin, ref mid, end) => { let begin = begin.iter().map(|p| name_from_pat(p).to_string()); let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(p))).into_iter(); From c0b1c6eed516ca39a88dcd7d6a11051fe645fd4a Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Wed, 5 Feb 2025 17:48:26 +0000 Subject: [PATCH 3/3] librustdoc: more usages of `Joined::joined` --- src/librustdoc/clean/utils.rs | 60 +++++++++++++++--------- src/librustdoc/doctest/make.rs | 16 ++++--- src/librustdoc/html/render/print_item.rs | 28 +++++------ 3 files changed, 61 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 418e60fd97254..c69d22001d9b4 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -1,5 +1,5 @@ use std::assert_matches::debug_assert_matches; -use std::fmt::Write as _; +use std::fmt::{self, Display, Write as _}; use std::mem; use std::sync::LazyLock as Lazy; @@ -24,6 +24,7 @@ use crate::clean::{ clean_middle_ty, inline, }; use crate::core::DocContext; +use crate::display::Joined as _; #[cfg(test)] mod tests; @@ -250,16 +251,20 @@ pub(crate) fn qpath_to_string(p: &hir::QPath<'_>) -> String { hir::QPath::LangItem(lang_item, ..) => return lang_item.name().to_string(), }; - let mut s = String::new(); - for (i, seg) in segments.iter().enumerate() { - if i > 0 { - s.push_str("::"); - } - if seg.ident.name != kw::PathRoot { - s.push_str(seg.ident.as_str()); - } - } - s + fmt::from_fn(|f| { + segments + .iter() + .map(|seg| { + fmt::from_fn(|f| { + if seg.ident.name != kw::PathRoot { + write!(f, "{}", seg.ident)?; + } + Ok(()) + }) + }) + .joined("::", f) + }) + .to_string() } pub(crate) fn build_deref_target_impls( @@ -311,12 +316,11 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { PatKind::TupleStruct(ref p, ..) | PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref p), .. }) => qpath_to_string(p), PatKind::Or(pats) => { - pats.iter().map(|p| name_from_pat(p).to_string()).collect::>().join(" | ") + fmt::from_fn(|f| pats.iter().map(|p| name_from_pat(p)).joined(" | ", f)).to_string() + } + PatKind::Tuple(elts, _) => { + format!("({})", fmt::from_fn(|f| elts.iter().map(|p| name_from_pat(p)).joined(", ", f))) } - PatKind::Tuple(elts, _) => format!( - "({})", - elts.iter().map(|p| name_from_pat(p).to_string()).collect::>().join(", ") - ), PatKind::Deref(p) => format!("deref!({})", name_from_pat(p)), PatKind::Expr(..) => { warn!( @@ -324,11 +328,25 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { ); return Symbol::intern("()"); } - PatKind::Slice(begin, ref mid, end) => { - let begin = begin.iter().map(|p| name_from_pat(p).to_string()); - let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(p))).into_iter(); - let end = end.iter().map(|p| name_from_pat(p).to_string()); - format!("[{}]", begin.chain(mid).chain(end).collect::>().join(", ")) + PatKind::Slice(begin, mid, end) => { + fn print_pat<'a>(pat: &'a Pat<'a>, wild: bool) -> impl Display + 'a { + fmt::from_fn(move |f| { + if wild { + f.write_str("..")?; + } + name_from_pat(pat).fmt(f) + }) + } + + format!( + "[{}]", + fmt::from_fn(|f| { + let begin = begin.iter().map(|p| print_pat(p, false)); + let mid = mid.map(|p| print_pat(p, true)); + let end = end.iter().map(|p| print_pat(p, false)); + begin.chain(mid).chain(end).joined(", ", f) + }) + ) } }) } diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index d89caabefe3e0..4792bc525a592 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -1,6 +1,7 @@ //! Logic for transforming the raw code given by the user into something actually //! runnable, e.g. by adding a `main` function if it doesn't already exist. +use std::fmt::{self, Write as _}; use std::io; use std::sync::Arc; @@ -17,6 +18,7 @@ use rustc_span::symbol::sym; use tracing::debug; use super::GlobalTestOptions; +use crate::display::Joined as _; use crate::html::markdown::LangString; /// This struct contains information about the doctest itself which is then used to generate @@ -232,13 +234,15 @@ impl DocTestBuilder { // add extra 4 spaces for each line to offset the code block if opts.insert_indent_space { - prog.push_str( - &everything_else + write!( + prog, + "{}", + fmt::from_fn(|f| everything_else .lines() - .map(|line| format!(" {}", line)) - .collect::>() - .join("\n"), - ); + .map(|line| fmt::from_fn(move |f| write!(f, " {line}"))) + .joined("\n", f)) + ) + .unwrap(); } else { prog.push_str(everything_else); }; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index d2d7415261b9f..f320114703996 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -2,7 +2,6 @@ use std::cmp::Ordering; use std::fmt; use std::fmt::Display; -use itertools::Itertools; use rinja::Template; use rustc_abi::VariantIdx; use rustc_data_structures::captures::Captures; @@ -514,11 +513,7 @@ fn item_module(w: &mut String, cx: &Context<'_>, item: &clean::Item, items: &[cl class = myitem.type_(), unsafety_flag = unsafety_flag, href = item_path(myitem.type_(), myitem.name.unwrap().as_str()), - title = [myitem.type_().to_string(), full_path(cx, myitem)] - .iter() - .filter_map(|s| if !s.is_empty() { Some(s.as_str()) } else { None }) - .collect::>() - .join(" "), + title = format_args!("{} {}", myitem.type_(), full_path(cx, myitem)), ), ); } @@ -915,7 +910,7 @@ fn item_trait(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra w, format_args!( "
At least one of the `{}` methods is required.
", - list.iter().join("`, `") + fmt::from_fn(|f| list.iter().joined("`, `", f)) ), ); } @@ -1168,17 +1163,18 @@ fn item_trait(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra js_src_path.extend(cx.current.iter().copied()); js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), it.name.unwrap())); } - let extern_crates = extern_crates - .into_iter() - .map(|cnum| tcx.crate_name(cnum).to_string()) - .collect::>() - .join(","); - let (extern_before, extern_after) = - if extern_crates.is_empty() { ("", "") } else { (" data-ignore-extern-crates=\"", "\"") }; + let extern_crates = fmt::from_fn(|f| { + if !extern_crates.is_empty() { + f.write_str(" data-ignore-extern-crates=\"")?; + extern_crates.iter().map(|&cnum| tcx.crate_name(cnum)).joined(",", f)?; + f.write_str("\"")?; + } + Ok(()) + }); write_str( w, format_args!( - "", + "", src = js_src_path.finish() ), ); @@ -1400,7 +1396,7 @@ fn item_type_alias(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean .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 = self_fqp.iter().map(Symbol::as_str).collect::>().join("::"); + let self_path = fmt::from_fn(|f| self_fqp.iter().joined("::", f)); write_str( w, format_args!(