Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustdoc: also index impl trait and raw pointers #97592

Merged
merged 2 commits into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
35 changes: 27 additions & 8 deletions src/librustdoc/html/render/search_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,17 +226,17 @@ 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::BorrowedRef { ref type_, .. } | clean::RawPointer(_, ref type_) => {
get_index_type_name(type_)
}
clean::BareFunction(_)
| clean::Tuple(_)
| clean::Slice(_)
| clean::Array(_, _)
| clean::RawPointer(_, _)
| clean::QPath { .. }
| clean::Infer
| clean::ImplTrait(_) => None,
| clean::Infer => None,
}
}

Expand Down Expand Up @@ -264,10 +264,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
Expand Down Expand Up @@ -318,7 +320,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)));
Expand Down Expand Up @@ -398,6 +400,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.
Expand Down
51 changes: 51 additions & 0 deletions src/test/rustdoc-js/impl-trait.js
Original file line number Diff line number Diff line change
@@ -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 changes: 21 additions & 0 deletions src/test/rustdoc-js/impl-trait.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
55 changes: 55 additions & 0 deletions src/test/rustdoc-js/raw-pointer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// ignore-order

const QUERY = [
'Aaaaaaa -> i32',
'Aaaaaaa -> Aaaaaaa',
'Aaaaaaa -> usize',
'-> Aaaaaaa',
'Aaaaaaa',
];

const EXPECTED = [
{
// Aaaaaaa -> i32
'others': [
{ 'path': 'raw_pointer::Ccccccc', 'name': 'eeeeeee' },
],
},
{
// Aaaaaaa -> Aaaaaaa
'others': [
{ 'path': 'raw_pointer::Ccccccc', 'name': 'fffffff' },
{ 'path': 'raw_pointer::Ccccccc', 'name': 'ggggggg' },
],
},
{
// Aaaaaaa -> usize
'others': [],
},
{
// -> Aaaaaaa
'others': [
{ 'path': 'raw_pointer::Ccccccc', 'name': 'fffffff' },
{ 'path': 'raw_pointer::Ccccccc', 'name': 'ggggggg' },
{ 'path': 'raw_pointer::Ccccccc', 'name': 'ddddddd' },
{ 'path': 'raw_pointer', 'name': 'bbbbbbb' },
],
},
{
// Aaaaaaa
'others': [
{ 'path': 'raw_pointer', 'name': 'Aaaaaaa' },
],
'in_args': [
{ 'path': 'raw_pointer::Ccccccc', 'name': 'fffffff' },
{ 'path': 'raw_pointer::Ccccccc', 'name': 'ggggggg' },
{ 'path': 'raw_pointer::Ccccccc', 'name': 'eeeeeee' },
],
'returned': [
{ 'path': 'raw_pointer::Ccccccc', 'name': 'fffffff' },
{ 'path': 'raw_pointer::Ccccccc', 'name': 'ggggggg' },
{ 'path': 'raw_pointer::Ccccccc', 'name': 'ddddddd' },
{ 'path': 'raw_pointer', 'name': 'bbbbbbb' },
],
},
];
24 changes: 24 additions & 0 deletions src/test/rustdoc-js/raw-pointer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::ptr;

pub struct Aaaaaaa {}

pub fn bbbbbbb() -> *const Aaaaaaa {
ptr::null()
}

pub struct Ccccccc {}

impl Ccccccc {
pub fn ddddddd(&self) -> *const Aaaaaaa {
ptr::null()
}
pub fn eeeeeee(&self, _x: *const Aaaaaaa) -> i32 {
0
}
pub fn fffffff(&self, x: *const Aaaaaaa) -> *const Aaaaaaa {
x
}
pub fn ggggggg(&self, x: *mut Aaaaaaa) -> *mut Aaaaaaa {
x
}
}