Skip to content

Commit e94f2b1

Browse files
authored
Unrolled build for rust-lang#124148
Rollup merge of rust-lang#124148 - notriddle:notriddle/reference, r=GuillaumeGomez rustdoc-search: search for references This feature extends rustdoc with syntax and search index information for searching borrow references. Part of rust-lang#60485 ## Preview - [`&mut`](https://notriddle.com/rustdoc-html-demo-11/reference/std/index.html?search=%26mut) - [`&Option<T> -> Option<&T>`](https://notriddle.com/rustdoc-html-demo-11/reference/std/index.html?search=%26Option%3CT%3E%20-%3E%20Option%3C%26T%3E) - [`&mut Option<T> -> Option<&mut T>`](https://notriddle.com/rustdoc-html-demo-11/reference/std/index.html?search=%26mut%20Option%3CT%3E%20-%3E%20Option%3C%26mut%20T%3E) Updated chapter of the book: https://notriddle.com/rustdoc-html-demo-11/reference/rustdoc/read-documentation/search.html ## Motivation See rust-lang#119676 ## Guide-level explanation You can't search by lifetimes, but other than that it's the same syntax references normally use. ## Reference-level description <table> <thead> <tr> <th>Shorthand</th> <th>Explicit names</th> </tr> </thead> <tbody> <tr><td colspan="2">Before this PR</td></tr> <tr> <td><code>[]</code></td> <td><code>primitive:slice</code> and/or <code>primitive:array</code></td> </tr> <tr> <td><code>[T]</code></td> <td><code>primitive:slice&lt;T&gt;</code> and/or <code>primitive:array&lt;T&gt;</code></td> </tr> <tr> <td><code>!</code></td> <td><code>primitive:never</code></td> </tr> <tr> <td><code>()</code></td> <td><code>primitive:unit</code> and/or <code>primitive:tuple</code></td> </tr> <tr> <td><code>(T)</code></td> <td><code>T</code></td> </tr> <tr> <td><code>(T,)</code></td> <td><code>primitive:tuple&lt;T&gt;</code></td> </tr> <tr> <td><code>(T, U -> V, W)</code></td> <td><code>fn(T, U) -> (V, W)</code>, Fn, FnMut, and FnOnce</td> </tr> <tr><td colspan="2">New additions with this PR</td></tr> <tr> <td><code>&</code></td> <td><code>primitive:reference</td> </tr> <tr> <td><code>&mut</code></td> <td><code>primitive:reference&lt;keyword:mut&gt;</td> </tr> <tr> <td><code>&T</code></td> <td><code>primitive:reference&lt;T&gt;</td> </tr> <tr> <td><code>&mut T</code></td> <td><code>primitive:reference&lt;keyword:mut, T&gt;</td> </tr> </tbody> </table> ### Search query grammar <code><pre><strong>borrow-ref = AMP *WS [MUT] *WS [arg]</strong> arg = [type-filter *WS COLON *WS] (path [generics] / slice-like / tuple-like / <strong>borrow-ref</strong>)</pre></code> ``` AMP = "&" MUT = "mut" ``` ## Future direction As described in rust-lang#118194 and rust-lang#119676 * The remaining type expression grammar (this is another step in the type expression grammar: `ReferenceType` is now supported) * Search subtyping and traits
2 parents 06e88c3 + c514471 commit e94f2b1

File tree

7 files changed

+874
-24
lines changed

7 files changed

+874
-24
lines changed

src/doc/rustdoc/src/read-documentation/search.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ and number of matches. For example, a function with the signature
146146
`fn read_all(&mut self: impl Read) -> Result<Vec<u8>, Error>`
147147
will match these queries:
148148

149+
* `&mut Read -> Result<Vec<u8>, Error>`
149150
* `Read -> Result<Vec<u8>, Error>`
150151
* `Read -> Result<Error, Vec>`
151152
* `Read -> Result<Vec<u8>>`
@@ -166,6 +167,10 @@ but you need to know which one you want.
166167

167168
| Shorthand | Explicit names |
168169
| ---------------- | ------------------------------------------------- |
170+
| `&` | `primitive:reference` |
171+
| `&T` | `primitive:reference<T>` |
172+
| `&mut` | `primitive:reference<keyword:mut>` |
173+
| `&mut T` | `primitive:reference<keyword:mut, T>` |
169174
| `[]` | `primitive:slice` and/or `primitive:array` |
170175
| `[T]` | `primitive:slice<T>` and/or `primitive:array<T>` |
171176
| `()` | `primitive:unit` and/or `primitive:tuple` |
@@ -253,7 +258,8 @@ ident = *(ALPHA / DIGIT / "_")
253258
path = ident *(DOUBLE-COLON ident) [BANG]
254259
slice-like = OPEN-SQUARE-BRACKET [ nonempty-arg-list ] CLOSE-SQUARE-BRACKET
255260
tuple-like = OPEN-PAREN [ nonempty-arg-list ] CLOSE-PAREN
256-
arg = [type-filter *WS COLON *WS] (path [generics] / slice-like / tuple-like)
261+
borrow-ref = AMP *WS [MUT] *WS [arg]
262+
arg = [type-filter *WS COLON *WS] (path [generics] / slice-like / tuple-like / borrow-ref)
257263
type-sep = COMMA/WS *(COMMA/WS)
258264
nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep) [ return-args ]
259265
generic-arg-list = *(type-sep) arg [ EQUAL arg ] *(type-sep arg [ EQUAL arg ]) *(type-sep)
@@ -310,6 +316,8 @@ COMMA = ","
310316
RETURN-ARROW = "->"
311317
EQUAL = "="
312318
BANG = "!"
319+
AMP = "&"
320+
MUT = "mut"
313321
314322
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
315323
DIGIT = %x30-39

src/librustdoc/html/render/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ pub(crate) enum RenderTypeId {
182182
Primitive(clean::PrimitiveType),
183183
AssociatedType(Symbol),
184184
Index(isize),
185+
Mut,
185186
}
186187

187188
impl RenderTypeId {

src/librustdoc/html/render/search_index.rs

+38-23
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
77
use rustc_middle::ty::TyCtxt;
88
use rustc_span::def_id::DefId;
99
use rustc_span::sym;
10-
use rustc_span::symbol::Symbol;
10+
use rustc_span::symbol::{kw, Symbol};
1111
use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer};
1212
use thin_vec::ThinVec;
1313

@@ -163,6 +163,15 @@ pub(crate) fn build_index<'tcx>(
163163
) -> Option<RenderTypeId> {
164164
let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache;
165165
match id {
166+
RenderTypeId::Mut => Some(insert_into_map(
167+
primitives,
168+
kw::Mut,
169+
lastpathid,
170+
crate_paths,
171+
ItemType::Keyword,
172+
&[kw::Mut],
173+
None,
174+
)),
166175
RenderTypeId::DefId(defid) => {
167176
if let Some(&(ref fqp, item_type)) =
168177
paths.get(&defid).or_else(|| external_paths.get(&defid))
@@ -765,9 +774,8 @@ fn get_index_type_id(
765774
bounds.get(0).map(|b| RenderTypeId::DefId(b.trait_.def_id()))
766775
}
767776
clean::Primitive(p) => Some(RenderTypeId::Primitive(p)),
768-
clean::BorrowedRef { ref type_, .. } | clean::RawPointer(_, ref type_) => {
769-
get_index_type_id(type_, rgen)
770-
}
777+
clean::BorrowedRef { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::Reference)),
778+
clean::RawPointer(_, ref type_) => get_index_type_id(type_, rgen),
771779
// The type parameters are converted to generics in `simplify_fn_type`
772780
clean::Slice(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Slice)),
773781
clean::Array(_, _) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Array)),
@@ -833,28 +841,14 @@ fn simplify_fn_type<'tcx, 'a>(
833841
}
834842

835843
// First, check if it's "Self".
836-
let mut is_self = false;
837-
let mut arg = if let Some(self_) = self_ {
838-
match &*arg {
839-
Type::BorrowedRef { type_, .. } if type_.is_self_type() => {
840-
is_self = true;
841-
self_
842-
}
843-
type_ if type_.is_self_type() => {
844-
is_self = true;
845-
self_
846-
}
847-
arg => arg,
848-
}
844+
let (is_self, arg) = if let Some(self_) = self_
845+
&& arg.is_self_type()
846+
{
847+
(true, self_)
849848
} else {
850-
arg
849+
(false, arg)
851850
};
852851

853-
// strip references from the argument type
854-
while let Type::BorrowedRef { type_, .. } = &*arg {
855-
arg = &*type_;
856-
}
857-
858852
// If this argument is a type parameter and not a trait bound or a type, we need to look
859853
// for its bounds.
860854
if let Type::Generic(arg_s) = *arg {
@@ -1027,6 +1021,27 @@ fn simplify_fn_type<'tcx, 'a>(
10271021
bindings: Some(ty_bindings),
10281022
generics: Some(ty_generics),
10291023
});
1024+
} else if let Type::BorrowedRef { lifetime: _, mutability, ref type_ } = *arg {
1025+
let mut ty_generics = Vec::new();
1026+
if mutability.is_mut() {
1027+
ty_generics.push(RenderType {
1028+
id: Some(RenderTypeId::Mut),
1029+
generics: None,
1030+
bindings: None,
1031+
});
1032+
}
1033+
simplify_fn_type(
1034+
self_,
1035+
generics,
1036+
&type_,
1037+
tcx,
1038+
recurse + 1,
1039+
&mut ty_generics,
1040+
rgen,
1041+
is_return,
1042+
cache,
1043+
);
1044+
res.push(get_index_type(arg, ty_generics, rgen));
10301045
} else {
10311046
// This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
10321047
// looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't.

src/librustdoc/html/static/js/search.js

+31
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,37 @@ function initSearch(rawSearchIndex) {
786786
}
787787
elems.push(makePrimitiveElement(name, { bindingName, generics }));
788788
}
789+
} else if (parserState.userQuery[parserState.pos] === "&") {
790+
if (parserState.typeFilter !== null && parserState.typeFilter !== "primitive") {
791+
throw [
792+
"Invalid search type: primitive ",
793+
"&",
794+
" and ",
795+
parserState.typeFilter,
796+
" both specified",
797+
];
798+
}
799+
parserState.typeFilter = null;
800+
parserState.pos += 1;
801+
let c = parserState.userQuery[parserState.pos];
802+
while (c === " " && parserState.pos < parserState.length) {
803+
parserState.pos += 1;
804+
c = parserState.userQuery[parserState.pos];
805+
}
806+
const generics = [];
807+
if (parserState.userQuery.slice(parserState.pos, parserState.pos + 3) === "mut") {
808+
generics.push(makePrimitiveElement("mut", { typeFilter: "keyword"}));
809+
parserState.pos += 3;
810+
c = parserState.userQuery[parserState.pos];
811+
}
812+
while (c === " " && parserState.pos < parserState.length) {
813+
parserState.pos += 1;
814+
c = parserState.userQuery[parserState.pos];
815+
}
816+
if (!isEndCharacter(c) && parserState.pos < parserState.length) {
817+
getFilteredNextElem(query, parserState, generics, isInGenerics);
818+
}
819+
elems.push(makePrimitiveElement("reference", { generics }));
789820
} else {
790821
const isStringElem = parserState.userQuery[start] === "\"";
791822
// We handle the strings on their own mostly to make code easier to follow.

0 commit comments

Comments
 (0)