Skip to content

Commit 0b3c617

Browse files
committed
rustdoc-search: add support for type parameters
When writing a type-driven search query in rustdoc, specifically one with more than one query element, non-existent types become generic parameters instead of auto-correcting (which is currently only done for single-element queries) or giving no result. You can also force a generic type parameter by writing `generic:T` (and can force it to not use a generic type parameter with something like `struct:T` or whatever, though if this happens it means the thing you're looking for doesn't exist and will give you no results). There is no syntax provided for specifying type constraints for generic type parameters. When you have a generic type parameter in a search query, it will only match up with generic type parameters in the actual function, not concrete types that match, not concrete types that implement a trait. It also strictly matches based on when they're the same or different, so `option<T>, option<U> -> option<U>` matches `Option::and`, but not `Option::or`. Similarly, `option<T>, option<T> -> option<T>`` matches `Option::or`, but not `Option::and`.
1 parent 217fe24 commit 0b3c617

File tree

9 files changed

+669
-290
lines changed

9 files changed

+669
-290
lines changed

src/librustdoc/clean/types.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,10 +1637,6 @@ impl Type {
16371637
matches!(self, Type::Generic(_))
16381638
}
16391639

1640-
pub(crate) fn is_impl_trait(&self) -> bool {
1641-
matches!(self, Type::ImplTrait(_))
1642-
}
1643-
16441640
pub(crate) fn is_unit(&self) -> bool {
16451641
matches!(self, Type::Tuple(v) if v.is_empty())
16461642
}

src/librustdoc/html/render/mod.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ pub(crate) struct IndexItem {
101101
pub(crate) path: String,
102102
pub(crate) desc: String,
103103
pub(crate) parent: Option<DefId>,
104-
pub(crate) parent_idx: Option<usize>,
104+
pub(crate) parent_idx: Option<isize>,
105105
pub(crate) search_type: Option<IndexItemFunctionType>,
106106
pub(crate) aliases: Box<[Symbol]>,
107107
pub(crate) deprecation: Option<Deprecation>,
@@ -122,7 +122,10 @@ impl Serialize for RenderType {
122122
let id = match &self.id {
123123
// 0 is a sentinel, everything else is one-indexed
124124
None => 0,
125-
Some(RenderTypeId::Index(idx)) => idx + 1,
125+
// concrete type
126+
Some(RenderTypeId::Index(idx)) if *idx >= 0 => idx + 1,
127+
// generic type parameter
128+
Some(RenderTypeId::Index(idx)) => *idx,
126129
_ => panic!("must convert render types to indexes before serializing"),
127130
};
128131
if let Some(generics) = &self.generics {
@@ -140,14 +143,15 @@ impl Serialize for RenderType {
140143
pub(crate) enum RenderTypeId {
141144
DefId(DefId),
142145
Primitive(clean::PrimitiveType),
143-
Index(usize),
146+
Index(isize),
144147
}
145148

146149
/// Full type of functions/methods in the search index.
147150
#[derive(Debug)]
148151
pub(crate) struct IndexItemFunctionType {
149152
inputs: Vec<RenderType>,
150153
output: Vec<RenderType>,
154+
where_clause: Vec<Vec<RenderType>>,
151155
}
152156

153157
impl Serialize for IndexItemFunctionType {
@@ -170,10 +174,17 @@ impl Serialize for IndexItemFunctionType {
170174
_ => seq.serialize_element(&self.inputs)?,
171175
}
172176
match &self.output[..] {
173-
[] => {}
177+
[] if self.where_clause.is_empty() => {}
174178
[one] if one.generics.is_none() => seq.serialize_element(one)?,
175179
_ => seq.serialize_element(&self.output)?,
176180
}
181+
for constraint in &self.where_clause {
182+
if let [one] = &constraint[..] && one.generics.is_none() {
183+
seq.serialize_element(one)?;
184+
} else {
185+
seq.serialize_element(constraint)?;
186+
}
187+
}
177188
seq.end()
178189
}
179190
}

0 commit comments

Comments
 (0)