]> git.lizzy.rs Git - rust.git/blobdiff - src/librustdoc/html/format.rs
Rollup merge of #92340 - camelid:search-index-cleanup, r=GuillaumeGomez
[rust.git] / src / librustdoc / html / format.rs
index a3cbb5756fefc38fa878f0ed481a6f7e95535e87..3a7c7186877e232cec28e2651e5a5a2706642f51 100644 (file)
 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);
 }
@@ -139,9 +143,7 @@ fn comma_sep<T: fmt::Display>(items: impl Iterator<Item = T>) -> impl fmt::Displ
     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(" + ")?;
             }
@@ -173,7 +175,7 @@ impl clean::GenericParamDef {
                 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() {
@@ -220,15 +222,16 @@ impl clean::Generics {
         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, "&lt;{}&gt;", comma_sep(real_params.iter().map(|g| g.print(cx))))
+                write!(f, "&lt;{}&gt;", comma_sep(real_params.map(|g| g.print(cx))))
             }
         })
     }
@@ -544,9 +547,9 @@ fn to_module_fqp(shortty: ItemType, fqp: &[String]) -> &[String] {
                         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),
@@ -560,22 +563,21 @@ fn to_module_fqp(shortty: ItemType, fqp: &[String]) -> &[String] {
     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> {
@@ -585,7 +587,7 @@ fn to_module_fqp(shortty: ItemType, fqp: &[String]) -> &[String] {
 /// 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 {
@@ -603,7 +605,7 @@ fn to_module_fqp(shortty: ItemType, fqp: &[String]) -> &[String] {
         iter::repeat("..").take(dissimilar_part_count).collect()
     // linking to the same module
     } else {
-        Vec::new()
+        UrlPartsBuilder::new()
     }
 }
 
@@ -637,7 +639,7 @@ fn resolved_path<'cx>(
                 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))?;
     }
@@ -666,20 +668,18 @@ fn primitive_link(
                 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()
                         })
                     }
@@ -774,7 +774,7 @@ fn fmt_type<'cx>(
         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!(
@@ -1270,7 +1270,7 @@ impl clean::Visibility {
                     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] {
@@ -1401,9 +1401,9 @@ impl clean::ImportSource {
                 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)?;
                 }
@@ -1419,7 +1419,7 @@ impl clean::TypeBinding {
         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() {