rustdoc: also index impl trait
This commit is contained in:
parent
16a0d03698
commit
59d35d6e90
@ -1667,6 +1667,10 @@ impl Type {
|
||||
matches!(self, Type::Generic(_))
|
||||
}
|
||||
|
||||
pub(crate) fn is_impl_trait(&self) -> bool {
|
||||
matches!(self, Type::ImplTrait(_))
|
||||
}
|
||||
|
||||
pub(crate) fn is_primitive(&self) -> bool {
|
||||
self.primitive_type().is_some()
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
|
||||
Some(path.segments.last().unwrap().name)
|
||||
}
|
||||
// We return an empty name because we don't care about the generic name itself.
|
||||
clean::Generic(_) => Some(kw::Empty),
|
||||
clean::Generic(_) | clean::ImplTrait(_) => Some(kw::Empty),
|
||||
clean::Primitive(ref p) => Some(p.as_sym()),
|
||||
clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_),
|
||||
clean::BareFunction(_)
|
||||
@ -235,8 +235,7 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
|
||||
| clean::Array(_, _)
|
||||
| clean::RawPointer(_, _)
|
||||
| clean::QPath { .. }
|
||||
| clean::Infer
|
||||
| clean::ImplTrait(_) => None,
|
||||
| clean::Infer => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,10 +263,12 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>(
|
||||
mut generics: Vec<TypeWithKind>,
|
||||
cache: &Cache,
|
||||
) {
|
||||
let is_full_generic = ty.is_full_generic();
|
||||
// generics and impl trait are both identified by their generics,
|
||||
// rather than a type name itself
|
||||
let anonymous = ty.is_full_generic() || ty.is_impl_trait();
|
||||
let generics_empty = generics.is_empty();
|
||||
|
||||
if is_full_generic {
|
||||
if anonymous {
|
||||
if generics_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
|
||||
@ -318,7 +319,7 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>(
|
||||
if index_ty.name.as_ref().map(|s| s.is_empty() && generics_empty).unwrap_or(true) {
|
||||
return;
|
||||
}
|
||||
if is_full_generic {
|
||||
if anonymous {
|
||||
// We remove the name of the full generic because we have no use for it.
|
||||
index_ty.name = Some(String::new());
|
||||
res.push(TypeWithKind::from((index_ty, ItemType::Generic)));
|
||||
@ -398,6 +399,23 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>(
|
||||
}
|
||||
insert_ty(res, tcx, arg.clone(), ty_generics, cache);
|
||||
}
|
||||
} else if let Type::ImplTrait(ref bounds) = *arg {
|
||||
let mut ty_generics = Vec::new();
|
||||
for bound in bounds {
|
||||
if let Some(path) = bound.get_trait_path() {
|
||||
let ty = Type::Path { path };
|
||||
add_generics_and_bounds_as_types(
|
||||
self_,
|
||||
generics,
|
||||
&ty,
|
||||
tcx,
|
||||
recurse + 1,
|
||||
&mut ty_generics,
|
||||
cache,
|
||||
);
|
||||
}
|
||||
}
|
||||
insert_ty(res, tcx, arg.clone(), ty_generics, cache);
|
||||
} else {
|
||||
// This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
|
||||
// looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't.
|
||||
|
51
src/test/rustdoc-js/impl-trait.js
Normal file
51
src/test/rustdoc-js/impl-trait.js
Normal file
@ -0,0 +1,51 @@
|
||||
// ignore-order
|
||||
|
||||
const QUERY = [
|
||||
'Aaaaaaa -> i32',
|
||||
'Aaaaaaa -> Aaaaaaa',
|
||||
'Aaaaaaa -> usize',
|
||||
'-> Aaaaaaa',
|
||||
'Aaaaaaa',
|
||||
];
|
||||
|
||||
const EXPECTED = [
|
||||
{
|
||||
// Aaaaaaa -> i32
|
||||
'others': [
|
||||
{ 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
|
||||
],
|
||||
},
|
||||
{
|
||||
// Aaaaaaa -> Aaaaaaa
|
||||
'others': [
|
||||
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
|
||||
],
|
||||
},
|
||||
{
|
||||
// Aaaaaaa -> usize
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
// -> Aaaaaaa
|
||||
'others': [
|
||||
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
|
||||
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
|
||||
{ 'path': 'impl_trait', 'name': 'bbbbbbb' },
|
||||
],
|
||||
},
|
||||
{
|
||||
// Aaaaaaa
|
||||
'others': [
|
||||
{ 'path': 'impl_trait', 'name': 'Aaaaaaa' },
|
||||
],
|
||||
'in_args': [
|
||||
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
|
||||
{ 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
|
||||
],
|
||||
'returned': [
|
||||
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
|
||||
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
|
||||
{ 'path': 'impl_trait', 'name': 'bbbbbbb' },
|
||||
],
|
||||
},
|
||||
];
|
21
src/test/rustdoc-js/impl-trait.rs
Normal file
21
src/test/rustdoc-js/impl-trait.rs
Normal file
@ -0,0 +1,21 @@
|
||||
pub trait Aaaaaaa {}
|
||||
|
||||
impl Aaaaaaa for () {}
|
||||
|
||||
pub fn bbbbbbb() -> impl Aaaaaaa {
|
||||
()
|
||||
}
|
||||
|
||||
pub struct Ccccccc {}
|
||||
|
||||
impl Ccccccc {
|
||||
pub fn ddddddd(&self) -> impl Aaaaaaa {
|
||||
()
|
||||
}
|
||||
pub fn eeeeeee(&self, _x: impl Aaaaaaa) -> i32 {
|
||||
0
|
||||
}
|
||||
pub fn fffffff(&self, x: impl Aaaaaaa) -> impl Aaaaaaa {
|
||||
x
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user