Skip to content

Commit a755d8d

Browse files
Support type search for arguments and returned types
1 parent 6af4fd3 commit a755d8d

File tree

7 files changed

+222
-103
lines changed

7 files changed

+222
-103
lines changed

src/librustdoc/clean/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,26 @@ impl Clean<PolyTrait> for hir::PolyTraitRef<'_> {
10781078
}
10791079
}
10801080

1081+
impl Clean<TypeKind> for hir::def::DefKind {
1082+
fn clean(&self, _: &DocContext<'_>) -> TypeKind {
1083+
match *self {
1084+
hir::def::DefKind::Mod => TypeKind::Module,
1085+
hir::def::DefKind::Struct => TypeKind::Struct,
1086+
hir::def::DefKind::Union => TypeKind::Union,
1087+
hir::def::DefKind::Enum => TypeKind::Enum,
1088+
hir::def::DefKind::Trait => TypeKind::Trait,
1089+
hir::def::DefKind::TyAlias => TypeKind::Typedef,
1090+
hir::def::DefKind::ForeignTy => TypeKind::Foreign,
1091+
hir::def::DefKind::TraitAlias => TypeKind::TraitAlias,
1092+
hir::def::DefKind::Fn => TypeKind::Function,
1093+
hir::def::DefKind::Const => TypeKind::Const,
1094+
hir::def::DefKind::Static => TypeKind::Static,
1095+
hir::def::DefKind::Macro(_) => TypeKind::Macro,
1096+
_ => TypeKind::Foreign,
1097+
}
1098+
}
1099+
}
1100+
10811101
impl Clean<Item> for hir::TraitItem<'_> {
10821102
fn clean(&self, cx: &DocContext<'_>) -> Item {
10831103
let inner = match self.kind {

src/librustdoc/clean/types.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -836,26 +836,26 @@ pub struct Method {
836836
pub decl: FnDecl,
837837
pub header: hir::FnHeader,
838838
pub defaultness: Option<hir::Defaultness>,
839-
pub all_types: Vec<Type>,
840-
pub ret_types: Vec<Type>,
839+
pub all_types: Vec<(Type, TypeKind)>,
840+
pub ret_types: Vec<(Type, TypeKind)>,
841841
}
842842

843843
#[derive(Clone, Debug)]
844844
pub struct TyMethod {
845845
pub header: hir::FnHeader,
846846
pub decl: FnDecl,
847847
pub generics: Generics,
848-
pub all_types: Vec<Type>,
849-
pub ret_types: Vec<Type>,
848+
pub all_types: Vec<(Type, TypeKind)>,
849+
pub ret_types: Vec<(Type, TypeKind)>,
850850
}
851851

852852
#[derive(Clone, Debug)]
853853
pub struct Function {
854854
pub decl: FnDecl,
855855
pub generics: Generics,
856856
pub header: hir::FnHeader,
857-
pub all_types: Vec<Type>,
858-
pub ret_types: Vec<Type>,
857+
pub all_types: Vec<(Type, TypeKind)>,
858+
pub ret_types: Vec<(Type, TypeKind)>,
859859
}
860860

861861
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -1043,7 +1043,7 @@ pub enum PrimitiveType {
10431043
Never,
10441044
}
10451045

1046-
#[derive(Clone, Copy, Debug)]
1046+
#[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
10471047
pub enum TypeKind {
10481048
Enum,
10491049
Function,

src/librustdoc/clean/utils.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ pub fn get_real_types(
186186
arg: &Type,
187187
cx: &DocContext<'_>,
188188
recurse: i32,
189-
) -> FxHashSet<Type> {
189+
) -> FxHashSet<(Type, TypeKind)> {
190190
let arg_s = arg.print().to_string();
191191
let mut res = FxHashSet::default();
192192
if recurse >= 10 {
@@ -211,7 +211,11 @@ pub fn get_real_types(
211211
if !adds.is_empty() {
212212
res.extend(adds);
213213
} else if !ty.is_full_generic() {
214-
res.insert(ty);
214+
if let Some(did) = ty.def_id() {
215+
if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
216+
res.insert((ty, kind));
217+
}
218+
}
215219
}
216220
}
217221
}
@@ -227,22 +231,32 @@ pub fn get_real_types(
227231
if !adds.is_empty() {
228232
res.extend(adds);
229233
} else if !ty.is_full_generic() {
230-
res.insert(ty.clone());
234+
if let Some(did) = ty.def_id() {
235+
if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
236+
res.insert((ty.clone(), kind));
237+
}
238+
}
231239
}
232240
}
233241
}
234242
}
235243
} else {
236-
res.insert(arg.clone());
244+
if let Some(did) = arg.def_id() {
245+
if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
246+
res.insert((arg.clone(), kind));
247+
}
248+
}
237249
if let Some(gens) = arg.generics() {
238250
for gen in gens.iter() {
239251
if gen.is_full_generic() {
240252
let adds = get_real_types(generics, gen, cx, recurse + 1);
241253
if !adds.is_empty() {
242254
res.extend(adds);
243255
}
244-
} else {
245-
res.insert(gen.clone());
256+
} else if let Some(did) = gen.def_id() {
257+
if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
258+
res.insert((gen.clone(), kind));
259+
}
246260
}
247261
}
248262
}
@@ -258,7 +272,7 @@ pub fn get_all_types(
258272
generics: &Generics,
259273
decl: &FnDecl,
260274
cx: &DocContext<'_>,
261-
) -> (Vec<Type>, Vec<Type>) {
275+
) -> (Vec<(Type, TypeKind)>, Vec<(Type, TypeKind)>) {
262276
let mut all_types = FxHashSet::default();
263277
for arg in decl.inputs.values.iter() {
264278
if arg.type_.is_self_type() {
@@ -268,15 +282,23 @@ pub fn get_all_types(
268282
if !args.is_empty() {
269283
all_types.extend(args);
270284
} else {
271-
all_types.insert(arg.type_.clone());
285+
if let Some(did) = arg.type_.def_id() {
286+
if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
287+
all_types.insert((arg.type_.clone(), kind));
288+
}
289+
}
272290
}
273291
}
274292

275293
let ret_types = match decl.output {
276294
FnRetTy::Return(ref return_type) => {
277295
let mut ret = get_real_types(generics, &return_type, cx, 0);
278296
if ret.is_empty() {
279-
ret.insert(return_type.clone());
297+
if let Some(did) = return_type.def_id() {
298+
if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
299+
ret.insert((return_type.clone(), kind));
300+
}
301+
}
280302
}
281303
ret.into_iter().collect()
282304
}

src/librustdoc/html/render.rs

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use rustc_span::symbol::{sym, Symbol};
5959
use serde::ser::SerializeSeq;
6060
use serde::{Serialize, Serializer};
6161

62-
use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy};
62+
use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy, TypeKind};
6363
use crate::config::RenderOptions;
6464
use crate::docfs::{DocFS, ErrorStorage, PathError};
6565
use crate::doctree;
@@ -303,8 +303,10 @@ impl Serialize for IndexItem {
303303
/// A type used for the search index.
304304
#[derive(Debug)]
305305
struct Type {
306+
ty: Option<DefId>,
307+
idx: Option<usize>,
306308
name: Option<String>,
307-
generics: Option<Vec<String>>,
309+
generics: Option<Vec<Generic>>,
308310
}
309311

310312
impl Serialize for Type {
@@ -314,7 +316,11 @@ impl Serialize for Type {
314316
{
315317
if let Some(name) = &self.name {
316318
let mut seq = serializer.serialize_seq(None)?;
317-
seq.serialize_element(&name)?;
319+
if let Some(id) = self.idx {
320+
seq.serialize_element(&id)?;
321+
} else {
322+
seq.serialize_element(&name)?;
323+
}
318324
if let Some(generics) = &self.generics {
319325
seq.serialize_element(&generics)?;
320326
}
@@ -325,11 +331,32 @@ impl Serialize for Type {
325331
}
326332
}
327333

334+
/// A type used for the search index.
335+
#[derive(Debug)]
336+
struct Generic {
337+
name: String,
338+
defid: Option<DefId>,
339+
idx: Option<usize>,
340+
}
341+
342+
impl Serialize for Generic {
343+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
344+
where
345+
S: Serializer,
346+
{
347+
if let Some(id) = self.idx {
348+
serializer.serialize_some(&id)
349+
} else {
350+
serializer.serialize_some(&self.name)
351+
}
352+
}
353+
}
354+
328355
/// Full type of functions/methods in the search index.
329356
#[derive(Debug)]
330357
struct IndexItemFunctionType {
331-
inputs: Vec<Type>,
332-
output: Option<Vec<Type>>,
358+
inputs: Vec<TypeWithKind>,
359+
output: Option<Vec<TypeWithKind>>,
333360
}
334361

335362
impl Serialize for IndexItemFunctionType {
@@ -340,8 +367,8 @@ impl Serialize for IndexItemFunctionType {
340367
// If we couldn't figure out a type, just write `null`.
341368
let mut iter = self.inputs.iter();
342369
if match self.output {
343-
Some(ref output) => iter.chain(output.iter()).any(|ref i| i.name.is_none()),
344-
None => iter.any(|ref i| i.name.is_none()),
370+
Some(ref output) => iter.chain(output.iter()).any(|ref i| i.ty.name.is_none()),
371+
None => iter.any(|ref i| i.ty.name.is_none()),
345372
} {
346373
serializer.serialize_none()
347374
} else {
@@ -359,6 +386,34 @@ impl Serialize for IndexItemFunctionType {
359386
}
360387
}
361388

389+
#[derive(Debug)]
390+
pub struct TypeWithKind {
391+
ty: Type,
392+
kind: TypeKind,
393+
}
394+
395+
impl From<(Type, TypeKind)> for TypeWithKind {
396+
fn from(x: (Type, TypeKind)) -> TypeWithKind {
397+
TypeWithKind {
398+
ty: x.0,
399+
kind: x.1,
400+
}
401+
}
402+
}
403+
404+
impl Serialize for TypeWithKind {
405+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
406+
where
407+
S: Serializer,
408+
{
409+
let mut seq = serializer.serialize_seq(None)?;
410+
seq.serialize_element(&self.ty.name)?;
411+
let x: ItemType = self.kind.into();
412+
seq.serialize_element(&x)?;
413+
seq.end()
414+
}
415+
}
416+
362417
thread_local!(static CACHE_KEY: RefCell<Arc<Cache>> = Default::default());
363418
thread_local!(pub static CURRENT_DEPTH: Cell<usize> = Cell::new(0));
364419

src/librustdoc/html/render/cache.rs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::path::{Path, PathBuf};
1212
use serde::Serialize;
1313

1414
use super::{plain_summary_line, shorten, Impl, IndexItem, IndexItemFunctionType, ItemType};
15-
use super::{RenderInfo, Type};
15+
use super::{Generic, RenderInfo, Type, TypeWithKind};
1616

1717
/// Indicates where an external crate can be found.
1818
pub enum ExternalLocation {
@@ -587,19 +587,22 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
587587
let mut lastpathid = 0usize;
588588

589589
for item in search_index {
590-
item.parent_idx = item.parent.map(|defid| {
591-
if defid_to_pathid.contains_key(&defid) {
592-
*defid_to_pathid.get(&defid).expect("no pathid")
593-
} else {
594-
let pathid = lastpathid;
595-
defid_to_pathid.insert(defid, pathid);
596-
lastpathid += 1;
590+
item.parent_idx = item.parent.and_then(|defid| {
591+
if defid_to_pathid.contains_key(&defid) {
592+
defid_to_pathid.get(&defid).map(|x| *x)
593+
} else {
594+
let pathid = lastpathid;
595+
defid_to_pathid.insert(defid, pathid);
596+
lastpathid += 1;
597597

598-
let &(ref fqp, short) = paths.get(&defid).unwrap();
598+
if let Some(&(ref fqp, short)) = paths.get(&defid) {
599599
crate_paths.push((short, fqp.last().unwrap().clone()));
600-
pathid
600+
Some(pathid)
601+
} else {
602+
None
601603
}
602-
});
604+
}
605+
});
603606

604607
// Omit the parent path if it is same to that of the prior item.
605608
if lastpath == item.path {
@@ -646,12 +649,15 @@ fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> {
646649
_ => return None,
647650
};
648651

649-
let inputs =
650-
all_types.iter().map(|arg| get_index_type(&arg)).filter(|a| a.name.is_some()).collect();
652+
let inputs = all_types
653+
.iter()
654+
.map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty), *kind)))
655+
.filter(|a| a.ty.name.is_some())
656+
.collect();
651657
let output = ret_types
652658
.iter()
653-
.map(|arg| get_index_type(&arg))
654-
.filter(|a| a.name.is_some())
659+
.map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty), *kind)))
660+
.filter(|a| a.ty.name.is_some())
655661
.collect::<Vec<_>>();
656662
let output = if output.is_empty() { None } else { Some(output) };
657663

@@ -660,6 +666,8 @@ fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> {
660666

661667
fn get_index_type(clean_type: &clean::Type) -> Type {
662668
let t = Type {
669+
ty: clean_type.def_id(),
670+
idx: None,
663671
name: get_index_type_name(clean_type, true).map(|s| s.to_ascii_lowercase()),
664672
generics: get_generics(clean_type),
665673
};
@@ -684,12 +692,15 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
684692
}
685693
}
686694

687-
fn get_generics(clean_type: &clean::Type) -> Option<Vec<String>> {
695+
fn get_generics(clean_type: &clean::Type) -> Option<Vec<Generic>> {
688696
clean_type.generics().and_then(|types| {
689697
let r = types
690698
.iter()
691-
.filter_map(|t| get_index_type_name(t, false))
692-
.map(|s| s.to_ascii_lowercase())
699+
.filter_map(|t| if let Some(name) = get_index_type_name(t, false) {
700+
Some(Generic { name: name.to_ascii_lowercase(), defid: t.def_id(), idx: None })
701+
} else {
702+
None
703+
})
693704
.collect::<Vec<_>>();
694705
if r.is_empty() { None } else { Some(r) }
695706
})

0 commit comments

Comments
 (0)