Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,22 @@ impl String {
self.vec.extend_from_slice(string.as_bytes())
}

#[unstable(feature = "string_push_str_slice", issue = "none")]
#[inline]
pub fn push_str_slice(&mut self, slice: &[&str]) {
let additional = slice.iter().map(|x| x.len()).sum();
self.reserve(additional);
let (ptr, len, cap) = core::mem::take(self).into_raw_parts();
unsafe {
let mut dst = ptr.add(len);
for new in slice {
core::ptr::copy_nonoverlapping(new.as_ptr(), dst, new.len());
dst = dst.add(new.len());
}
*self = String::from_raw_parts(ptr, len + additional, cap);
}
}

/// Copies elements from `src` range to the end of the string.
///
/// # Panics
Expand Down
3 changes: 1 addition & 2 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2257,8 +2257,7 @@ pub(crate) fn compare_names(left: &str, right: &str) -> Ordering {

pub(super) fn full_path(cx: &Context<'_>, item: &clean::Item) -> String {
let mut s = join_path_syms(&cx.current);
s.push_str("::");
s.push_str(item.name.unwrap().as_str());
crate::push_str_slice(&mut s, &["::", item.name.unwrap().as_str()]);
s
}

Expand Down
17 changes: 17 additions & 0 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#![feature(rustc_private)]
#![feature(test)]
#![feature(trim_prefix_suffix)]
#![feature(vec_into_raw_parts)]
#![warn(rustc::internal)]
// tidy-alphabetical-end

Expand Down Expand Up @@ -983,3 +984,19 @@ fn dump_feature_usage_metrics(tcxt: TyCtxt<'_>, metrics_dir: &Path) {
tcxt.dcx().err(format!("cannot emit feature usage metrics: {error}"));
}
}

#[inline]
fn push_str_slice(s: &mut String, slice: &[&str]) {
use std::ptr::copy_nonoverlapping;
let additional = slice.iter().map(|x| x.len()).sum();
s.reserve(additional);
let (ptr, len, cap) = std::mem::take(s).into_raw_parts();
unsafe {
let mut dst = ptr.add(len);
for new in slice {
copy_nonoverlapping(new.as_ptr(), dst, new.len());
dst = dst.add(new.len());
}
*s = String::from_raw_parts(ptr, len + additional, cap);
}
}
9 changes: 5 additions & 4 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,17 +223,18 @@ impl UrlFragment {
DefKind::Field => {
let parent_id = tcx.parent(def_id);
if tcx.def_kind(parent_id) == DefKind::Variant {
s.push_str("variant.");
s.push_str(tcx.item_name(parent_id).as_str());
crate::push_str_slice(
s,
&["variant.", tcx.item_name(parent_id).as_str()],
);
".field."
} else {
"structfield."
}
}
kind => bug!("unexpected associated item kind: {kind:?}"),
};
s.push_str(kind);
s.push_str(tcx.item_name(def_id).as_str());
crate::push_str_slice(s, &[kind, tcx.item_name(def_id).as_str()]);
}
UrlFragment::UserWritten(raw) => s.push_str(raw),
}
Expand Down
Loading