diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 5fd5eb1447843..0a0550ab82f9b 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -2717,9 +2717,26 @@ class DocSearch {
const normalizedUserQuery = parsedQuery.userQuery.toLowerCase();
const isMixedCase = normalizedUserQuery !== userQuery;
const result_list = [];
+ const isReturnTypeQuery = parsedQuery.elems.length === 0 ||
+ typeInfo === "returned";
for (const result of results.values()) {
result.item = this.searchIndex[result.id];
result.word = this.searchIndex[result.id].word;
+ if (isReturnTypeQuery) {
+ // we are doing a return-type based search,
+ // deprioritize "clone-like" results,
+ // ie. functions that also take the queried type as an argument.
+ const hasType = result.item && result.item.type;
+ if (!hasType) {
+ continue;
+ }
+ const inputs = result.item.type.inputs;
+ const where_clause = result.item.type.where_clause;
+ if (containsTypeFromQuery(inputs, where_clause)) {
+ result.path_dist *= 100;
+ result.dist *= 100;
+ }
+ }
result_list.push(result);
}
@@ -3540,6 +3557,35 @@ class DocSearch {
return false;
}
+ /**
+ * This function checks if the given list contains any
+ * (non-generic) types mentioned in the query.
+ *
+ * @param {Array} list - A list of function types.
+ * @param {[FunctionType]} where_clause - Trait bounds for generic items.
+ */
+ function containsTypeFromQuery(list, where_clause) {
+ if (!list) return false;
+ for (const ty of parsedQuery.returned) {
+ // negative type ids are generics
+ if (ty.id < 0) {
+ continue;
+ }
+ if (checkIfInList(list, ty, where_clause, null, 0)) {
+ return true;
+ }
+ }
+ for (const ty of parsedQuery.elems) {
+ if (ty.id < 0) {
+ continue;
+ }
+ if (checkIfInList(list, ty, where_clause, null, 0)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* This function checks if the object (`row`) matches the given type (`elem`) and its
* generics (if any).
diff --git a/tests/rustdoc-js-std/return-based-sort.js b/tests/rustdoc-js-std/return-based-sort.js
new file mode 100644
index 0000000000000..30baf1cd36e58
--- /dev/null
+++ b/tests/rustdoc-js-std/return-based-sort.js
@@ -0,0 +1,30 @@
+// test that `clone`-like functions are sorted lower when
+// a search is based soley on return type
+
+const FILTER_CRATE = "core";
+
+const EXPECTED = [
+ {
+ 'query': '-> AllocError',
+ 'others': [
+ { 'path': 'core::alloc::Allocator', 'name': 'allocate' },
+ { 'path': 'core::alloc::AllocError', 'name': 'clone' },
+ ],
+ },
+ {
+ 'query': 'AllocError',
+ 'returned': [
+ { 'path': 'core::alloc::Allocator', 'name': 'allocate' },
+ { 'path': 'core::alloc::AllocError', 'name': 'clone' },
+ ],
+ },
+ {
+ 'query': '-> &str',
+ 'others': [
+ // type_name_of_val should not be consider clone-like
+ { 'path': 'core::any', 'name': 'type_name_of_val' },
+ // this returns `Option<&str>`, and thus should be sorted lower
+ { 'path': 'core::str::Split', 'name': 'next' },
+ ],
+ },
+]