rust/tests/rustdoc-js
Matthias Krüger d5fd88cb85
Rollup merge of #118194 - notriddle:notriddle/tuple-unit, r=GuillaumeGomez
rustdoc: search for tuples and unit by type with `()`

This feature extends rustdoc to support the syntax that most users will naturally attempt to use to search for tuples. Part of https://github.com/rust-lang/rust/issues/60485

Function signature searches already support tuples and unit. The explicit name `primitive:tuple` and `primitive:unit` can be used to match a tuple or unit, while `()` will match either one. It also follows the direction set by the actual language for parens as a group, so `(u8,)` will only match a tuple, while `(u8)` will match a plain, unwrapped byte—thanks to loose search semantics, it will also match the tuple.

## Preview

* [`option<t>, option<u> -> (t, u)`](<https://notriddle.com/rustdoc-html-demo-5/tuple-unit/std/index.html?search=option%3Ct%3E%2C option%3Cu%3E -%3E (t%2C u)>)
* [`[t] -> (t,)`](<https://notriddle.com/rustdoc-html-demo-5/tuple-unit/std/index.html?search=[t] -%3E (t%2C)>)
* [`(ipaddr,) -> socketaddr`](<https://notriddle.com/rustdoc-html-demo-5/tuple-unit/std/index.html?search=(ipaddr%2C) -%3E socketaddr>)

## Motivation

When type-based search was first landed, it was directly [described as incomplete][a comment].

[a comment]: https://github.com/rust-lang/rust/pull/23289#issuecomment-79437386

Filling out the missing functionality is going to mean adding support for more of Rust's [type expression] syntax, such as tuples (in this PR), references, raw pointers, function pointers, and closures.

[type expression]: https://doc.rust-lang.org/reference/types.html#type-expressions

There does seem to be demand for this sort of thing, such as [this Discord message](https://discord.com/channels/442252698964721669/443150878111694848/1042145740065099796) expressing regret at rustdoc not supporting tuples in search queries.

## Reference description (from the Rustdoc book)

<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 colspan="2">After this PR</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>
</tbody>
</table>

A single type expression wrapped in parens is the same as that type expression, since parens act as the grouping operator. If they're empty, though, they will match both `unit` and `tuple`, and if there's more than one type (or a trailing or leading comma) it is the same as `primitive:tuple<...>`.

However, since items can be left out of the query, `(T)` will still return results for types that match tuples, even though it also matches the type on its own. That is, `(u32)` matches `(u32,)` for the exact same reason that it also matches `Result<u32, Error>`.

## Future direction

The [type expression grammar](https://doc.rust-lang.org/reference/types.html#type-expressions) from the Reference is given below:

<pre><code>Syntax
    Type :
        TypeNoBounds
        | <a href="https://doc.rust-lang.org/reference/types/impl-trait.html">ImplTraitType</a>
        | <a href="https://doc.rust-lang.org/reference/types/trait-object.html">TraitObjectType</a>
<br>
    TypeNoBounds :
        <a href="https://doc.rust-lang.org/reference/types.html#parenthesized-types">ParenthesizedType</a>
        | <a href="https://doc.rust-lang.org/reference/types/impl-trait.html">ImplTraitTypeOneBound</a>
        | <a href="https://doc.rust-lang.org/reference/types/trait-object.html">TraitObjectTypeOneBound</a>
        | <a href="https://doc.rust-lang.org/reference/paths.html#paths-in-types">TypePath</a>
        | <a href="https://doc.rust-lang.org/reference/types/tuple.html#tuple-types">TupleType</a>
        | <a href="https://doc.rust-lang.org/reference/types/never.html">NeverType</a>
        | <a href="https://doc.rust-lang.org/reference/types/pointer.html#raw-pointers-const-and-mut">RawPointerType</a>
        | <a href="https://doc.rust-lang.org/reference/types/pointer.html#shared-references-">ReferenceType</a>
        | <a href="https://doc.rust-lang.org/reference/types/array.html">ArrayType</a>
        | <a href="https://doc.rust-lang.org/reference/types/slice.html">SliceType</a>
        | <a href="https://doc.rust-lang.org/reference/types/inferred.html">InferredType</a>
        | <a href="https://doc.rust-lang.org/reference/paths.html#qualified-paths">QualifiedPathInType</a>
        | <a href="https://doc.rust-lang.org/reference/types/function-pointer.html">BareFunctionType</a>
        | <a href="https://doc.rust-lang.org/reference/macros.html#macro-invocation">MacroInvocation</a>
</code></pre>

ImplTraitType and TraitObjectType (and ImplTraitTypeOneBound and TraitObjectTypeOneBound) are not yet implemented. They would mostly desugar to `trait:`, similarly to how `!` desugars to `primitive:never`.

ParenthesizedType and TuplePath are added in this PR.

TypePath is already implemented (except const generics, which is not planned, and function-like trait syntax, which is planned as part of closure support).

NeverType is already implemented.

RawPointerType and ReferenceType require parsing and fixes to the search index to store this information, but otherwise their behavior seems simple enough. Just like tuples and slices, `&T` would be equivalent to `primitive:reference<T>`, `&mut T` would be equivalent to `primitive:reference<keyword:mut, T>`, `*T` would be equivalent to `primitive:pointer<T>`, `*mut T` would be equivalent to `primitive:pointer<keyword:mut, T>`, and `*const T` would be equivalent to `primitive:pointer<keyword:const, T>`. Lifetime generics support is not planned, because lifetime subtyping seems too complicated.

ArrayType is subsumed by SliceType right now. Implementing const generics is not planned, because it seems like it would require a lot of implementation complexity for not much gain.

InferredType isn't really covered right now. Its semantics in a search context are not obvious.

QualifiedPathInType is not implemented, and it is not planned. I would need a use case to justify it, and act as a guide for what the exact semantics should be.

BareFunctionType is not implemented. Along with function-like trait syntax, which is formally considered a TypePath, it's the biggest missing feature to be able to do structured searches over generic APIs like `Option`.

MacroInvocation is not parsed (macro names are, but they don't mean the same thing here at all). Those are gone by the time Rustdoc sees the source code.
2024-01-06 16:07:46 +01:00
..
auxiliary Add regression test for #115480 2023-10-11 11:41:39 +02:00
assoc-type-backtrack.js rustdoc-search: add support for associated types 2023-11-19 18:54:36 -07:00
assoc-type-backtrack.rs rustdoc-search: add support for associated types 2023-11-19 18:54:36 -07:00
assoc-type-loop.js rustdoc-search: avoid infinite where clause unbox 2023-11-24 10:42:11 -07:00
assoc-type-loop.rs rustdoc-search: avoid infinite where clause unbox 2023-11-24 10:42:11 -07:00
assoc-type.js rustdoc-search: use set ops for ranking and filtering 2023-12-13 10:37:15 -07:00
assoc-type.rs rustdoc-search: add support for associated types 2023-11-19 18:54:36 -07:00
basic.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
basic.rs
big-result.js rustdoc-search: use set ops for ranking and filtering 2023-12-13 10:37:15 -07:00
big-result.rs rustdoc-search: use set ops for ranking and filtering 2023-12-13 10:37:15 -07:00
doc-alias-filter-out.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
doc-alias-filter-out.rs
doc-alias-filter.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
doc-alias-filter.rs
doc-alias-whitespace.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
doc-alias-whitespace.rs
doc-alias.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
doc-alias.rs
enum-variant-not-type.js rustdoc-search: do not treat associated type names as types 2023-12-10 16:52:21 -07:00
enum-variant-not-type.rs rustdoc-search: do not treat associated type names as types 2023-12-10 16:52:21 -07:00
exact-match.js rustdoc-search: count path edits with separate edit limit 2023-12-26 18:46:17 -07:00
exact-match.rs
foreign-type-path.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
foreign-type-path.rs
full-path-function.js rustdoc-search: use set ops for ranking and filtering 2023-12-13 10:37:15 -07:00
full-path-function.rs Correctly handle paths from foreign items 2023-09-02 23:04:37 +02:00
gat.js rustdoc-search: add support for associated types 2023-11-19 18:54:36 -07:00
gat.rs rustdoc-search: add support for associated types 2023-11-19 18:54:36 -07:00
generics2.js rustdoc-search: fix accidental shared, mutable map 2023-11-17 18:22:31 -07:00
generics2.rs rustdoc-search: fix accidental shared, mutable map 2023-11-17 18:22:31 -07:00
generics-impl.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
generics-impl.rs
generics-match-ambiguity.js rustdoc-search: fix bugs when unboxing and reordering combine 2023-09-09 16:58:37 -07:00
generics-match-ambiguity.rs rustdoc-search: fix order-independence bug 2023-06-11 18:57:33 -07:00
generics-multi-trait.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
generics-multi-trait.rs
generics-nested.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
generics-nested.rs rustdoc-search: add support for nested generics 2023-04-14 14:55:45 -07:00
generics-trait.js rustdoc: fix test case for generics that look like names 2023-09-03 13:06:08 -07:00
generics-trait.rs
generics-unbox.js rustdoc-search: fix bugs when unboxing and reordering combine 2023-09-09 16:58:37 -07:00
generics-unbox.rs rustdoc-search: fix bugs when unboxing and reordering combine 2023-09-09 16:58:37 -07:00
generics.js rustdoc-search: use set ops for ranking and filtering 2023-12-13 10:37:15 -07:00
generics.rs
impl-trait.js rustdoc-search: use set ops for ranking and filtering 2023-12-13 10:37:15 -07:00
impl-trait.rs rustdoc-search: fix bug with multi-item impl trait 2023-10-05 22:32:37 -07:00
macro-search.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
macro-search.rs rustdoc: search by macro when query ends with ! 2023-02-16 18:16:09 -07:00
module-substring.js rustdoc-search: count path edits with separate edit limit 2023-12-26 18:46:17 -07:00
module-substring.rs
nested-unboxed.js rustdoc-search: build args, return, and generics on one unifier 2023-06-11 18:19:37 -07:00
nested-unboxed.rs rustdoc-search: build args, return, and generics on one unifier 2023-06-11 18:19:37 -07:00
never-search.js rustdoc-search: add support for associated types 2023-11-19 18:54:36 -07:00
never-search.rs rustdoc-search: search never type with ! 2023-06-12 17:30:23 -07:00
path-maxeditdistance.js rustdoc-search: count path edits with separate edit limit 2023-12-26 18:46:17 -07:00
path-maxeditdistance.rs rustdoc-search: count path edits with separate edit limit 2023-12-26 18:46:17 -07:00
path-ordering.js rustdoc-search: count path edits with separate edit limit 2023-12-26 18:46:17 -07:00
path-ordering.rs rustdoc-search: count path edits with separate edit limit 2023-12-26 18:46:17 -07:00
primitive.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
primitive.rs
prototype.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
prototype.rs
raw-pointer.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
raw-pointer.rs
reexport.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
reexport.rs
search-bag-semantics.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
search-bag-semantics.rs rustdoc: implement bag semantics for function parameter search 2023-03-19 18:19:24 -07:00
search-method-disambiguate.js rustdoc-search: add impl disambiguator to duplicate assoc items 2023-09-21 15:16:44 -07:00
search-method-disambiguate.rs rustdoc-search: add impl disambiguator to duplicate assoc items 2023-09-21 15:16:44 -07:00
search-non-local-trait-impl.js Add regression test for #115480 2023-10-11 11:41:39 +02:00
search-non-local-trait-impl.rs Add regression test for #115480 2023-10-11 11:41:39 +02:00
search-short-types.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
search-short-types.rs
slice-array.js rustdoc: add note about slice/array searches to help popup 2023-06-10 14:08:26 -07:00
slice-array.rs rustdoc: search for slices and arrays by type with [] 2023-06-10 13:52:54 -07:00
struct-like-variant.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
struct-like-variant.rs
substring.js rustdoc-search: remove parallel searchWords array 2023-12-15 16:26:35 -07:00
substring.rs rustdoc-search: remove parallel searchWords array 2023-12-15 16:26:35 -07:00
summaries.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
summaries.rs
trait-methods.js rustdoc-search: add support for associated types 2023-11-19 18:54:36 -07:00
trait-methods.rs rustdoc-search: add support for associated types 2023-11-19 18:54:36 -07:00
tuple-unit.js rustdoc: search for tuples and unit by type with () 2023-12-26 12:54:17 -07:00
tuple-unit.rs rustdoc: search for tuples and unit by type with () 2023-12-26 12:54:17 -07:00
type-parameters.js rustdoc-search: use set ops for ranking and filtering 2023-12-13 10:37:15 -07:00
type-parameters.rs rustdoc-search: add support for type parameters 2023-09-03 13:06:06 -07:00
where-clause.js Update rustdoc-js* format 2023-06-09 17:00:47 +02:00
where-clause.rs rustdoc: fix type search when more than one where clause applies 2023-03-07 11:37:04 -07:00