about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-11-10 18:52:28 +0100
committerGitHub <noreply@github.com>2021-11-10 18:52:28 +0100
commitb31f0198b14300d232dc1b6d1f52dc92da7818ff (patch)
treea3a7cface2d874cb785cdee72d57033afdeb43f9
parent858fea410d89986669c3613c63b5401abd72b891 (diff)
parent8d5ef320fc6c2d4436692d1558d36bd59c49394b (diff)
downloadrust-b31f0198b14300d232dc1b6d1f52dc92da7818ff.tar.gz
rust-b31f0198b14300d232dc1b6d1f52dc92da7818ff.zip
Rollup merge of #90727 - GuillaumeGomez:remove-potential-useless-search-index-data, r=notriddle,camelid
Remove potential useless data for search index

I uncovered this case when working on https://github.com/rust-lang/rust/pull/90726 to debug https://github.com/rust-lang/rust/pull/90385.

Explanations: if we have a full generic, we check if it has generics then we do the following:
 * If it has only one generic, we remove one nested level in order to not keep the "parent" generic (since it has empty name, it's useless after all).
 * Otherwise we add it alongside its generics.

However, I didn't handle the case where a generic had no generics. Meaning that we were adding items with empty names in the search index. So basically useless data in the search index.

r? `@camelid`
-rw-r--r--src/librustdoc/html/render/cache.rs85
1 files changed, 46 insertions, 39 deletions
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index ff1bd5e7ff2..79421c128bc 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -258,45 +258,52 @@ crate fn get_real_types<'tcx>(
     ) {
         let is_full_generic = ty.is_full_generic();
 
-        if is_full_generic && generics.len() == 1 {
-            // In this case, no need to go through an intermediate state if the generics
-            // contains only one element.
-            //
-            // For example:
-            //
-            // fn foo<T: Display>(r: Option<T>) {}
-            //
-            // In this case, it would contain:
-            //
-            // ```
-            // [{
-            //     name: "option",
-            //     generics: [{
-            //         name: "",
-            //         generics: [
-            //             name: "Display",
-            //             generics: []
-            //         }]
-            //     }]
-            // }]
-            // ```
-            //
-            // After removing the intermediate (unnecessary) full generic, it'll become:
-            //
-            // ```
-            // [{
-            //     name: "option",
-            //     generics: [{
-            //         name: "Display",
-            //         generics: []
-            //     }]
-            // }]
-            // ```
-            //
-            // To be noted that it can work if there is ONLY ONE generic, otherwise we still
-            // need to keep it as is!
-            res.push(generics.pop().unwrap());
-            return;
+        if is_full_generic {
+            if generics.is_empty() {
+                // This is a type parameter with no trait bounds (for example: `T` in
+                // `fn f<T>(p: T)`, so not useful for the rustdoc search because we would end up
+                // with an empty type with an empty name. Let's just discard it.
+                return;
+            } else if generics.len() == 1 {
+                // In this case, no need to go through an intermediate state if the type parameter
+                // contains only one trait bound.
+                //
+                // For example:
+                //
+                // `fn foo<T: Display>(r: Option<T>) {}`
+                //
+                // In this case, it would contain:
+                //
+                // ```
+                // [{
+                //     name: "option",
+                //     generics: [{
+                //         name: "",
+                //         generics: [
+                //             name: "Display",
+                //             generics: []
+                //         }]
+                //     }]
+                // }]
+                // ```
+                //
+                // After removing the intermediate (unnecessary) type parameter, it'll become:
+                //
+                // ```
+                // [{
+                //     name: "option",
+                //     generics: [{
+                //         name: "Display",
+                //         generics: []
+                //     }]
+                // }]
+                // ```
+                //
+                // To be noted that it can work if there is ONLY ONE trait bound, otherwise we still
+                // need to keep it as is!
+                res.push(generics.pop().unwrap());
+                return;
+            }
         }
         let mut index_ty = get_index_type(&ty, generics);
         if index_ty.name.as_ref().map(|s| s.is_empty()).unwrap_or(true) {