use rustc_span::def_id::CRATE_DEF_INDEX;
use rustc_target::spec::abi::Abi;
-use crate::clean::{self, utils::find_nearest_parent_module, ExternalCrate, ItemId, PrimitiveType};
+use crate::clean::{
+ self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, ItemId,
+ PrimitiveType,
+};
use crate::formats::item_type::ItemType;
use crate::html::escape::Escape;
-use crate::html::render::cache::ExternalLocation;
use crate::html::render::Context;
+use super::url_parts_builder::UrlPartsBuilder;
+
crate trait Print {
fn print(self, buffer: &mut Buffer);
}
display_fn(move |f| {
let mut bounds_dup = FxHashSet::default();
- for (i, bound) in
- bounds.iter().filter(|b| bounds_dup.insert(b.print(cx).to_string())).enumerate()
- {
+ for (i, bound) in bounds.iter().filter(|b| bounds_dup.insert(b.clone())).enumerate() {
if i > 0 {
f.write_str(" + ")?;
}
Ok(())
}
clean::GenericParamDefKind::Type { bounds, default, .. } => {
- f.write_str(&*self.name.as_str())?;
+ f.write_str(self.name.as_str())?;
if !bounds.is_empty() {
if f.alternate() {
cx: &'a Context<'tcx>,
) -> impl fmt::Display + 'a + Captures<'tcx> {
display_fn(move |f| {
- let real_params =
- self.params.iter().filter(|p| !p.is_synthetic_type_param()).collect::<Vec<_>>();
- if real_params.is_empty() {
+ let mut real_params =
+ self.params.iter().filter(|p| !p.is_synthetic_type_param()).peekable();
+ if real_params.peek().is_none() {
return Ok(());
}
+
if f.alternate() {
- write!(f, "<{:#}>", comma_sep(real_params.iter().map(|g| g.print(cx))))
+ write!(f, "<{:#}>", comma_sep(real_params.map(|g| g.print(cx))))
} else {
- write!(f, "<{}>", comma_sep(real_params.iter().map(|g| g.print(cx))))
+ write!(f, "<{}>", comma_sep(real_params.map(|g| g.print(cx))))
}
})
}
ExternalLocation::Remote(ref s) => {
is_remote = true;
let s = s.trim_end_matches('/');
- let mut s = vec![s];
- s.extend(module_fqp[..].iter().map(String::as_str));
- s
+ let mut builder = UrlPartsBuilder::singleton(s);
+ builder.extend(module_fqp.iter().map(String::as_str));
+ builder
}
ExternalLocation::Local => href_relative_parts(module_fqp, relative_to),
ExternalLocation::Unknown => return Err(HrefError::DocumentationNotBuilt),
if !is_remote {
if let Some(root_path) = root_path {
let root = root_path.trim_end_matches('/');
- url_parts.insert(0, root);
+ url_parts.push_front(root);
}
}
debug!(?url_parts);
let last = &fqp.last().unwrap()[..];
- let filename;
match shortty {
ItemType::Module => {
url_parts.push("index.html");
}
_ => {
- filename = format!("{}.{}.html", shortty.as_str(), last);
+ let filename = format!("{}.{}.html", shortty.as_str(), last);
url_parts.push(&filename);
}
}
- Ok((url_parts.join("/"), shortty, fqp.to_vec()))
+ Ok((url_parts.finish(), shortty, fqp.to_vec()))
}
crate fn href(did: DefId, cx: &Context<'_>) -> Result<(String, ItemType, Vec<String>), HrefError> {
/// Both paths should only be modules.
/// This is because modules get their own directories; that is, `std::vec` and `std::vec::Vec` will
/// both need `../iter/trait.Iterator.html` to get at the iterator trait.
-crate fn href_relative_parts<'a>(fqp: &'a [String], relative_to_fqp: &'a [String]) -> Vec<&'a str> {
+crate fn href_relative_parts(fqp: &[String], relative_to_fqp: &[String]) -> UrlPartsBuilder {
for (i, (f, r)) in fqp.iter().zip(relative_to_fqp.iter()).enumerate() {
// e.g. linking to std::iter from std::vec (`dissimilar_part_count` will be 1)
if f != r {
iter::repeat("..").take(dissimilar_part_count).collect()
// linking to the same module
} else {
- Vec::new()
+ UrlPartsBuilder::new()
}
}
last.name.to_string()
}
} else {
- anchor(did, &*last.name.as_str(), cx).to_string()
+ anchor(did, last.name.as_str(), cx).to_string()
};
write!(w, "{}{}", path, last.args.print(cx))?;
}
needs_termination = true;
}
Some(&def_id) => {
- let cname_str;
+ let cname_sym;
let loc = match m.extern_locations[&def_id.krate] {
ExternalLocation::Remote(ref s) => {
- cname_str =
- ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()).as_str();
- Some(vec![s.trim_end_matches('/'), &cname_str[..]])
+ cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx());
+ Some(vec![s.trim_end_matches('/'), cname_sym.as_str()])
}
ExternalLocation::Local => {
- cname_str =
- ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()).as_str();
- Some(if cx.current.first().map(|x| &x[..]) == Some(&cname_str[..]) {
+ cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx());
+ Some(if cx.current.first().map(|x| &x[..]) == Some(cname_sym.as_str()) {
iter::repeat("..").take(cx.current.len() - 1).collect()
} else {
- let cname = iter::once(&cname_str[..]);
+ let cname = iter::once(cname_sym.as_str());
iter::repeat("..").take(cx.current.len()).chain(cname).collect()
})
}
clean::Primitive(clean::PrimitiveType::Never) => {
primitive_link(f, PrimitiveType::Never, "!", cx)
}
- clean::Primitive(prim) => primitive_link(f, prim, &*prim.as_sym().as_str(), cx),
+ clean::Primitive(prim) => primitive_link(f, prim, prim.as_sym().as_str(), cx),
clean::BareFunction(ref decl) => {
if f.alternate() {
write!(
debug!("path={:?}", path);
// modified from `resolved_path()` to work with `DefPathData`
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
- let anchor = anchor(vis_did, &last_name.as_str(), cx).to_string();
+ let anchor = anchor(vis_did, last_name.as_str(), cx).to_string();
let mut s = "pub(in ".to_owned();
for seg in &path.data[..path.data.len() - 1] {
for seg in &self.path.segments[..self.path.segments.len() - 1] {
write!(f, "{}::", seg.name)?;
}
- let name = self.path.last_name();
+ let name = self.path.last();
if let hir::def::Res::PrimTy(p) = self.path.res {
- primitive_link(f, PrimitiveType::from(p), &*name, cx)?;
+ primitive_link(f, PrimitiveType::from(p), name.as_str(), cx)?;
} else {
write!(f, "{}", name)?;
}
cx: &'a Context<'tcx>,
) -> impl fmt::Display + 'a + Captures<'tcx> {
display_fn(move |f| {
- f.write_str(&*self.name.as_str())?;
+ f.write_str(self.name.as_str())?;
match self.kind {
clean::TypeBindingKind::Equality { ref ty } => {
if f.alternate() {