Skip to content

Commit 9397d13

Browse files
committed
Treat other items as functions for the purpose of type-based search
constants and statics are nullary functions, and struct fields are unary functions. functions (along with methods and trait methods) are prioritized over other items, like fields and constants.
1 parent d8a6409 commit 9397d13

File tree

6 files changed

+71
-2
lines changed

6 files changed

+71
-2
lines changed

src/doc/rustdoc/src/read-documentation/search.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ methods on the allocator or free functions.
5252

5353
[`Layout`]: ../../alloc/index.html?search=Layout&filter-crate=alloc
5454

55-
## Searching By Type Signature for functions
55+
## Searching By Type Signature
5656

5757
If you know more specifically what the function you want to look at does,
58+
or you want to know how to get from one type to another,
5859
Rustdoc can search by more than one type at once in the parameters and return
5960
value. Multiple parameters are separated by `,` commas, and the return value
6061
is written with after a `->` arrow.
@@ -86,6 +87,17 @@ the standard library and functions that are included in the results list:
8687
[iterasslice]: ../../std/vec/struct.Vec.html?search=vec%3A%3Aintoiter<T>%20->%20[T]&filter-crate=std
8788
[iterreduce]: ../../std/index.html?search=iterator<T>%2C%20fnmut%20->%20T&filter-crate=std
8889

90+
### Non-functions in type-based search
91+
Certain items that are not functions are treated as though they
92+
were a semantically equivelent function.
93+
94+
For example, struct fields are treated as though they were getter methods.
95+
This means that a search for `CpuidResult -> u32` will show
96+
the `CpuidResult::eax` field in the results.
97+
98+
Additionally, `const` and `static` items are treated as nullary functions,
99+
so `-> u32` will match `u32::MAX`.
100+
89101
### How type-based search works
90102

91103
In a complex type-based search, Rustdoc always treats every item's name as literal.

src/librustdoc/html/render/search_index.rs

+27
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,22 @@ pub(crate) fn get_function_type_for_search(
840840
| clean::RequiredMethodItem(ref f) => {
841841
get_fn_inputs_and_outputs(f, tcx, impl_or_trait_generics, cache)
842842
}
843+
clean::ConstantItem(ref c) => make_nullary_fn(&c.type_),
844+
clean::StaticItem(ref s) => make_nullary_fn(&s.type_),
845+
clean::StructFieldItem(ref t) => {
846+
let Some(parent) = parent else {
847+
return None;
848+
};
849+
let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> =
850+
Default::default();
851+
let output = get_index_type(t, vec![], &mut rgen);
852+
let input = RenderType {
853+
id: Some(RenderTypeId::DefId(parent)),
854+
generics: None,
855+
bindings: None,
856+
};
857+
(vec![input], vec![output], vec![], vec![])
858+
}
843859
_ => return None,
844860
};
845861

@@ -1353,6 +1369,17 @@ fn simplify_fn_constraint<'a>(
13531369
res.push((ty_constrained_assoc, ty_constraints));
13541370
}
13551371

1372+
/// Create a fake nullary function.
1373+
///
1374+
/// Used to allow type-based search on constants and statics.
1375+
fn make_nullary_fn(
1376+
clean_type: &clean::Type,
1377+
) -> (Vec<RenderType>, Vec<RenderType>, Vec<Symbol>, Vec<Vec<RenderType>>) {
1378+
let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> = Default::default();
1379+
let output = get_index_type(clean_type, vec![], &mut rgen);
1380+
(vec![], vec![output], vec![], vec![])
1381+
}
1382+
13561383
/// Return the full list of types when bounds have been resolved.
13571384
///
13581385
/// i.e. `fn foo<A: Display, B: Option<A>>(x: u32, y: B)` will return

src/librustdoc/html/static/js/search.js

+16
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ const TY_PRIMITIVE = itemTypes.indexOf("primitive");
6363
const TY_GENERIC = itemTypes.indexOf("generic");
6464
const TY_IMPORT = itemTypes.indexOf("import");
6565
const TY_TRAIT = itemTypes.indexOf("trait");
66+
const TY_FN = itemTypes.indexOf("fn");
67+
const TY_METHOD = itemTypes.indexOf("method");
68+
const TY_TYMETHOD = itemTypes.indexOf("tymethod");
6669
const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";
6770

6871
// Hard limit on how deep to recurse into generics when doing type-driven search.
@@ -191,6 +194,10 @@ function isEndCharacter(c) {
191194
return "=,>-])".indexOf(c) !== -1;
192195
}
193196

197+
function isFnLikeTy(ty) {
198+
return ty === TY_FN || ty === TY_METHOD || ty === TY_TYMETHOD;
199+
}
200+
194201
/**
195202
* Returns `true` if the given `c` character is a separator.
196203
*
@@ -2766,6 +2773,15 @@ class DocSearch {
27662773
return a - b;
27672774
}
27682775

2776+
// in type based search, put functions first
2777+
if (parsedQuery.hasReturnArrow) {
2778+
a = !isFnLikeTy(aaa.item.ty);
2779+
b = !isFnLikeTy(bbb.item.ty);
2780+
if (a !== b) {
2781+
return a - b;
2782+
}
2783+
}
2784+
27692785
// Sort by distance in the path part, if specified
27702786
// (less changes required to match means higher rankings)
27712787
a = aaa.path_dist;

tests/rustdoc-gui/search-tab.goml

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ set-window-size: (851, 600)
7979

8080
// Check the size and count in tabs
8181
assert-text: ("#search-tabs > button:nth-child(1) > .count", " (26) ")
82-
assert-text: ("#search-tabs > button:nth-child(2) > .count", " (6)  ")
82+
assert-text: ("#search-tabs > button:nth-child(2) > .count", " (7)  ")
8383
assert-text: ("#search-tabs > button:nth-child(3) > .count", " (0)  ")
8484
store-property: ("#search-tabs > button:nth-child(1)", {"offsetWidth": buttonWidth})
8585
assert-property: ("#search-tabs > button:nth-child(2)", {"offsetWidth": |buttonWidth|})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const EXPECTED = {
2+
'query': '-> char',
3+
'others': [
4+
{ 'path': 'std::char', 'name': 'from_digit' },
5+
{ 'path': 'std::char', 'name': 'MAX' },
6+
],
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const EXPECTED = {
2+
// one of the only non-generic structs with public fields
3+
'query': 'CpuidResult -> u32',
4+
'others': [
5+
{ 'path': 'core::arch::x86::CpuidResult', 'name': 'eax' },
6+
],
7+
}

0 commit comments

Comments
 (0)