Skip to content

Commit 59d35d6

Browse files
committed
rustdoc: also index impl trait
1 parent 16a0d03 commit 59d35d6

File tree

4 files changed

+100
-6
lines changed

4 files changed

+100
-6
lines changed

src/librustdoc/clean/types.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1667,6 +1667,10 @@ impl Type {
16671667
matches!(self, Type::Generic(_))
16681668
}
16691669

1670+
pub(crate) fn is_impl_trait(&self) -> bool {
1671+
matches!(self, Type::ImplTrait(_))
1672+
}
1673+
16701674
pub(crate) fn is_primitive(&self) -> bool {
16711675
self.primitive_type().is_some()
16721676
}

src/librustdoc/html/render/search_index.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
226226
Some(path.segments.last().unwrap().name)
227227
}
228228
// We return an empty name because we don't care about the generic name itself.
229-
clean::Generic(_) => Some(kw::Empty),
229+
clean::Generic(_) | clean::ImplTrait(_) => Some(kw::Empty),
230230
clean::Primitive(ref p) => Some(p.as_sym()),
231231
clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_),
232232
clean::BareFunction(_)
@@ -235,8 +235,7 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
235235
| clean::Array(_, _)
236236
| clean::RawPointer(_, _)
237237
| clean::QPath { .. }
238-
| clean::Infer
239-
| clean::ImplTrait(_) => None,
238+
| clean::Infer => None,
240239
}
241240
}
242241

@@ -264,10 +263,12 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>(
264263
mut generics: Vec<TypeWithKind>,
265264
cache: &Cache,
266265
) {
267-
let is_full_generic = ty.is_full_generic();
266+
// generics and impl trait are both identified by their generics,
267+
// rather than a type name itself
268+
let anonymous = ty.is_full_generic() || ty.is_impl_trait();
268269
let generics_empty = generics.is_empty();
269270

270-
if is_full_generic {
271+
if anonymous {
271272
if generics_empty {
272273
// This is a type parameter with no trait bounds (for example: `T` in
273274
// `fn f<T>(p: T)`, so not useful for the rustdoc search because we would end up
@@ -318,7 +319,7 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>(
318319
if index_ty.name.as_ref().map(|s| s.is_empty() && generics_empty).unwrap_or(true) {
319320
return;
320321
}
321-
if is_full_generic {
322+
if anonymous {
322323
// We remove the name of the full generic because we have no use for it.
323324
index_ty.name = Some(String::new());
324325
res.push(TypeWithKind::from((index_ty, ItemType::Generic)));
@@ -398,6 +399,23 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>(
398399
}
399400
insert_ty(res, tcx, arg.clone(), ty_generics, cache);
400401
}
402+
} else if let Type::ImplTrait(ref bounds) = *arg {
403+
let mut ty_generics = Vec::new();
404+
for bound in bounds {
405+
if let Some(path) = bound.get_trait_path() {
406+
let ty = Type::Path { path };
407+
add_generics_and_bounds_as_types(
408+
self_,
409+
generics,
410+
&ty,
411+
tcx,
412+
recurse + 1,
413+
&mut ty_generics,
414+
cache,
415+
);
416+
}
417+
}
418+
insert_ty(res, tcx, arg.clone(), ty_generics, cache);
401419
} else {
402420
// This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
403421
// looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't.

src/test/rustdoc-js/impl-trait.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// ignore-order
2+
3+
const QUERY = [
4+
'Aaaaaaa -> i32',
5+
'Aaaaaaa -> Aaaaaaa',
6+
'Aaaaaaa -> usize',
7+
'-> Aaaaaaa',
8+
'Aaaaaaa',
9+
];
10+
11+
const EXPECTED = [
12+
{
13+
// Aaaaaaa -> i32
14+
'others': [
15+
{ 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
16+
],
17+
},
18+
{
19+
// Aaaaaaa -> Aaaaaaa
20+
'others': [
21+
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
22+
],
23+
},
24+
{
25+
// Aaaaaaa -> usize
26+
'others': [],
27+
},
28+
{
29+
// -> Aaaaaaa
30+
'others': [
31+
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
32+
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
33+
{ 'path': 'impl_trait', 'name': 'bbbbbbb' },
34+
],
35+
},
36+
{
37+
// Aaaaaaa
38+
'others': [
39+
{ 'path': 'impl_trait', 'name': 'Aaaaaaa' },
40+
],
41+
'in_args': [
42+
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
43+
{ 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
44+
],
45+
'returned': [
46+
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
47+
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
48+
{ 'path': 'impl_trait', 'name': 'bbbbbbb' },
49+
],
50+
},
51+
];

src/test/rustdoc-js/impl-trait.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
pub trait Aaaaaaa {}
2+
3+
impl Aaaaaaa for () {}
4+
5+
pub fn bbbbbbb() -> impl Aaaaaaa {
6+
()
7+
}
8+
9+
pub struct Ccccccc {}
10+
11+
impl Ccccccc {
12+
pub fn ddddddd(&self) -> impl Aaaaaaa {
13+
()
14+
}
15+
pub fn eeeeeee(&self, _x: impl Aaaaaaa) -> i32 {
16+
0
17+
}
18+
pub fn fffffff(&self, x: impl Aaaaaaa) -> impl Aaaaaaa {
19+
x
20+
}
21+
}

0 commit comments

Comments
 (0)