Commit graph

5883 commits

Author SHA1 Message Date
Matthias Krüger
0437a0c372 some minor code simplifications 2024-03-17 13:44:44 +01:00
Matthias Krüger
57f210400b
Rollup merge of #122495 - Manishearth:rustdoc-👻👻👻, r=GuillaumeGomez
Visually mark 👻hidden👻 items with document-hidden-items

Fixes #122485

This adds a 👻 in the item list (much like the 🔒 used for private items), and also shows `#[doc(hidden)]` in the code view, where `pub(crate)` etc gets shown for private items.

This does not do anything for enum variants, if people have ideas. I think we can just show the attribute.
2024-03-15 21:51:56 +01:00
Guillaume Gomez
6ec4092eaf
Rollup merge of #122530 - klensy:as_str, r=fee1-dead
less symbol interner locks

This reduces instructions under 1% (in rustdoc run), but essentially free.
2024-03-15 17:24:10 +01:00
klensy
7ea4f35766 less symbols interner locks 2024-03-15 10:54:40 +03:00
Matthias Krüger
a95e2f999a
Rollup merge of #122247 - notriddle:notriddle/search-unbox-limit, r=GuillaumeGomez
rustdoc-search: depth limit `T<U>` -> `U` unboxing

Profiler output:
https://notriddle.com/rustdoc-html-demo-9/search-unbox-limit/ (the only significant change is that one of the `rust` tests went from 378416ms to 16ms).

This is a performance enhancement aimed at a problem I found while using type-driven search on the Rust compiler. It is caused by [`Interner`], a trait with 41 associated types, many of which recurse back to `Self` again.

This caused search.js to struggle. It eventually terminates, after about 10 minutes of turning my PC into a space header, but it's doing `41!` unifications and that's too slow.

[`Interner`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.Interner.html
2024-03-14 15:44:32 +01:00
Manish Goregaokar
9718144599 fix polarity 2024-03-14 15:08:16 +01:00
Manish Goregaokar
580e5b855d inline 2024-03-14 15:07:30 +01:00
Manish Goregaokar
bd03fad8ee Make compact 2024-03-14 14:51:01 +01:00
Manish Goregaokar
102015645d print doc(hidden) 2024-03-14 14:14:44 +01:00
Manish Goregaokar
343c77c102 Refactor visibility_print_with_space to directly take an item 2024-03-14 12:56:12 +01:00
Manish Goregaokar
8da262139a print ghosts 2024-03-14 12:15:05 +01:00
Matthias Krüger
6694918344
Rollup merge of #119676 - notriddle:notriddle/rustdoc-search-hof, r=GuillaumeGomez
rustdoc-search: search types by higher-order functions

This feature extends rustdoc with syntax and search index information for searching function pointers and closures (Higher-Order Functions, or HOF). Part of https://github.com/rust-lang/rust/issues/60485

This PR adds two syntaxes: a high-level one for finding any kind of HOF, and a direct implementation of the parenthesized path syntax that Rust itself uses.

## Preview pages

| Query | Results |
|-------|---------|
| [`option<T>, (fnonce (T) -> bool) -> option<T>`][optionfilter] | `Option::filter` |
| [`option<T>, (T -> bool) -> option<T>`][optionfilter2] | `Option::filter` |

Updated chapter of the book: https://notriddle.com/rustdoc-html-demo-9/search-hof/rustdoc/read-documentation/search.html

[optionfilter]: https://notriddle.com/rustdoc-html-demo-9/search-hof/std/vec/struct.Vec.html?search=option<T>%2C+(fnonce+(T)+->+bool)+->+option<T>&filter-crate=std
[optionfilter2]: https://notriddle.com/rustdoc-html-demo-9/search-hof/std/vec/struct.Vec.html?search=option<T>%2C+(T+->+bool)+->+option<T>&filter-crate=std

## 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 references, raw pointers, function pointers, and closures. This PR adds function pointers and closures.

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

There's been demand for something "like Hoogle, but for Rust" expressed a few times [1](https://www.reddit.com/r/rust/comments/y8sbid/is_there_a_website_like_haskells_hoogle_for_rust/) [2](https://users.rust-lang.org/t/rust-equivalent-of-haskells-hoogle/102280) [3](https://internals.rust-lang.org/t/std-library-inclusion-policy/6852/2) [4](https://discord.com/channels/442252698964721669/448238009733742612/1109502307495858216). Some of them just don't realize what functionality already exists ([`Duration -> u64`](https://doc.rust-lang.org/nightly/std/?search=duration%20-%3E%20u64) already works), but a lot of them specifically want to search for higher-order functions like option combinators.

## Guide-level explanation (from the Rustdoc book)

To search for a function that accepts a function as a parameter, like `Iterator::all`, wrap the nested signature in parenthesis, as in [`Iterator<T>, (T -> bool) -> bool`][iterator-all]. You can also search for a specific closure trait, such as `Iterator<T>, (FnMut(T) -> bool) -> bool`, but you need to know which one you want.

[iterator-all]: https://notriddle.com/rustdoc-html-demo-9/search-hof/std/vec/struct.Vec.html?search=Iterator<T>%2C+(T+->+bool)+->+bool&filter-crate=std

## Reference-level description (also from the Rustdoc book)

### Primitives with Special Syntax

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

The `->` operator has lower precedence than comma. If it's not wrapped in brackets, it delimits the return value for the function being searched for. To search for functions that take functions as parameters, use parenthesis.

### Search query grammar

```ebnf
ident = *(ALPHA / DIGIT / "_")
path = ident *(DOUBLE-COLON ident) [BANG]
slice-like = OPEN-SQUARE-BRACKET [ nonempty-arg-list ] CLOSE-SQUARE-BRACKET
tuple-like = OPEN-PAREN [ nonempty-arg-list ] CLOSE-PAREN
arg = [type-filter *WS COLON *WS] (path [generics] / slice-like / tuple-like)
type-sep = COMMA/WS *(COMMA/WS)
nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep) [ return-args ]
generic-arg-list = *(type-sep) arg [ EQUAL arg ] *(type-sep arg [ EQUAL arg ]) *(type-sep)
normal-generics = OPEN-ANGLE-BRACKET [ generic-arg-list ] *(type-sep)
            CLOSE-ANGLE-BRACKET
fn-like-generics = OPEN-PAREN [ nonempty-arg-list ] CLOSE-PAREN [ RETURN-ARROW arg ]
generics = normal-generics / fn-like-generics
return-args = RETURN-ARROW *(type-sep) nonempty-arg-list

exact-search = [type-filter *WS COLON] [ RETURN-ARROW ] *WS QUOTE ident QUOTE [ generics ]
type-search = [ nonempty-arg-list ]

query = *WS (exact-search / type-search) *WS

; unchanged parts of the grammar, like the full list of type filters, are omitted
```

## Future direction

### The remaining type expression grammar

As described in https://github.com/rust-lang/rust/pull/118194, this is another step in the type expression grammar: BareFunction, and the function-like mode of TypePath, are now supported.

* RawPointerType and ReferenceType actually are a priority.
* ImplTraitType and TraitObjectType (and ImplTraitTypeOneBound and TraitObjectTypeOneBound) aren't as much of a priority, since they desugar pretty easily.

### Search subtyping and traits

This is the other major factor that makes it less useful than it should be.

* `iterator<result<t>> -> result<t>` doesn't find `Result::from_iter`. You have to search [`intoiterator<result<t>> -> result<t>`](https://notriddle.com/rustdoc-html-demo-9/search-hof/std/vec/struct.Vec.html?search=intoiterator%3Cresult%3Ct%3E%3E%20-%3E%20result%3Ct%3E&filter-crate=std). Nobody's going to search for IntoIterator unless they basically already know about it and don't need the search engine anyway.

* Iterator combinators are usually structs that happen to implement Iterator, like `std::iter::Map`.

To solve these cases, it needs to look at trait implementations, knowing that Iterator is a "subtype of" IntoIterator, and Map is a "subtype of" Iterator, so `iterator -> result` is a subtype of `intoiterator -> result` and `iterator<t>, (t -> u) -> iterator<u>` is a subtype of [`iterator<t>, (t -> u) -> map<t -> u>`](https://notriddle.com/rustdoc-html-demo-9/search-hof/std/vec/struct.Vec.html?search=iterator%3Ct%3E%2C%20(t%20-%3E%20u)%20-%3E%20map%3Ct%20-%3E%20u%3E&filter-crate=std).
2024-03-14 11:09:56 +01:00
Elijah Riggs
f3b348bf96 rustdoc: do not preload fonts when browsing locally 2024-03-12 15:00:22 -07:00
Michael Howell
7b926555b7 rustdoc-search: add search query syntax Fn(T) -> U
This is implemented, in addition to the ML-style one,
because Rust does it. If we don't, we'll never hear the end of it.

This commit also refactors some duplicate parts of the parser
into a dedicated function.
2024-03-11 22:27:22 -07:00
Michael Howell
23e931fd07 rustdoc: use const for the special type name ids
Initialize them before the search index is loaded.
2024-03-11 21:22:03 -07:00
Michael Howell
d38527eb82 rustdoc: clean up search.js by removing empty sort case
It's going to be a no-op on the empty list anyway
(we have plenty of test cases that return nothing)
so why send extra code?
2024-03-11 21:22:03 -07:00
Michael Howell
7f427f86bd rustdoc-search: parse and search with ML-style HOF
Option::map, for example, looks like this:

    option<t>, (t -> u) -> option<u>

This syntax searches all of the HOFs in Rust: traits Fn, FnOnce,
and FnMut, and bare fn primitives.
2024-03-11 21:22:03 -07:00
Michael Howell
bcc3f193b8 rustdoc-search: depth limit T<U> -> U unboxing
Profiler output:
https://notriddle.com/rustdoc-html-demo-9/search-unbox-limit/

This is a performance enhancement aimed at a problem I found while
using type-driven search on the Rust compiler. It is caused by
[`Interner`], a trait with 41 associated types, many of which
recurse back to `Self` again.

This caused search.js to struggle. It eventually terminates,
after about 10 minutes of turning my PC into a space header, but it's
doing `41!` unifications and that's too slow.

[`Interner`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.Interner.html
2024-03-09 10:56:21 -07:00
Nicholas Nethercote
18715c98c6 Rename DiagnosticMessage as DiagMessage. 2024-03-05 12:14:49 +11:00
Guillaume Gomez
bc261998c5 Correctly generate item info of trait items 2024-03-01 15:33:02 +01:00
Matthias Krüger
843920f0f6
Rollup merge of #121689 - GuillaumeGomez:rustdoc-highlighting-whitespace, r=notriddle
[rustdoc] Prevent inclusion of whitespace character after macro_rules ident

Discovered this bug randomly when looking at:

![image](https://github.com/rust-lang/rust/assets/3050060/dca38047-9085-4377-bfac-f98890224be4)

We were too eagerly trying to merge tokens that shouldn't be merged together (for example if you have a code comment followed by a code comment, we merge them in one attribute to reduce the DOM size).

r? ``@notriddle``
2024-02-29 00:16:59 +01:00
bors
c475e2303b Auto merge of #121489 - nnethercote:diag-renaming, r=davidtwco
Diagnostic renaming

Renaming various diagnostic types from `Diagnostic*` to `Diag*`. Part of https://github.com/rust-lang/compiler-team/issues/722. There are more to do but this is enough for one PR.

r? `@davidtwco`
2024-02-28 20:39:38 +00:00
Guillaume Gomez
632d26aeff Add regression test for inclusion of whitespace characters in rustdoc highlighting 2024-02-28 16:08:46 +01:00
Nicholas Nethercote
899cb40809 Rename DiagnosticBuilder as Diag.
Much better!

Note that this involves renaming (and updating the value of)
`DIAGNOSTIC_BUILDER` in clippy.
2024-02-28 08:55:35 +11:00
Guillaume Gomez
5df9593f1a Prevent inclusion of whitespace character after macro_rules ident 2024-02-27 17:40:29 +01:00
Guillaume Gomez
8719b74027 Fix link generation for locate foreign macro in jump to definition feature 2024-02-27 16:19:19 +01:00
Guillaume Gomez
a1593a678f
Rollup merge of #121590 - GuillaumeGomez:rustdoc-js-changed, r=notriddle
Correctly handle if rustdoc JS script hash changed

It's something that annoyed me for quite some time: I have nightly docs open (for both std and compiler). And often, I don't look at the page for some days. Then when I come back to it, I make a search... except nothing happens. Took me a while to figure out that it was because the hash of one of the JS files we load for the search (either `search.js` or `search-index.js`) was updated in the meantime, preventing the search to be done. To go around it, I added to press `ENTER` to make the form submitted (which would reload the same page but with the correct hashes this time and the search being run).

r? `@notriddle`
2024-02-26 10:27:42 +01:00
bors
b0d3e04ca9 Auto merge of #120393 - Urgau:rfc3373-non-local-defs, r=WaffleLapkin
Implement RFC 3373: Avoid non-local definitions in functions

This PR implements [RFC 3373: Avoid non-local definitions in functions](https://github.com/rust-lang/rust/issues/120363).
2024-02-25 19:11:06 +00:00
Guillaume Gomez
3af67bba18 Correctly handle if rustdoc JS script hash changed 2024-02-25 16:28:38 +01:00
Gurinder Singh
e0bfa5c294 Rustdoc: include crate name in links for local primitives
It makes the link easier to use in cases in which
the path of the page where it will be embedded is not
known beforehand such as when we generate impls
dynamically from `register_type_impls` method in
`main.js`

Earlier for local primitives we would generate a path
that was relative to the current page depth passed in `cx.current`
. e.g if the current page was `std::simd::prelude::Simd` the
generated path would be `../../primitive.<prim>.html`  After this
change the path will first take you to the the wesite root and add
the crate name. e.g. for `std::simd::prelude::Simd` the path now
will be `../../../std/primitive.<prim>.html`
2024-02-24 10:34:09 +05:30
León Orell Valerian Liehr
28c0fa87bb
Rollup merge of #121160 - fmease:rustdoc-fix-n-refactor-html-rendering, r=GuillaumeGomez
rustdoc: fix and refactor HTML rendering a bit

* refactoring: get rid of a bunch of manual `f.alternate()` branches
  * not sure why this wasn't done so already, is this perf-sensitive?
* fix an ICE in debug builds of rustdoc
  * rustdoc used to crash on empty outlives-bounds: `where 'a:`
* properly escape const generic defaults
* actually print empty trait and outlives-bounds (doesn't work for cross-crate reexports yet, will fix that at some other point) since they can have semantic significance
  * outlives-bounds: forces lifetime params to be early-bound instead of late-bound which is technically speaking part of the public API
  * trait-bounds: can affect the well-formedness, consider
    * makeshift “const-evaluatable” bounds under `generic_const_exprs`
    * bounds to force wf-checking in light of #100041 (quite artificial I know, I couldn't figure out something better), see https://github.com/rust-lang/rust/pull/121160#discussion_r1491563816
2024-02-18 05:10:17 +01:00
León Orell Valerian Liehr
fb5982f14e
Rollup merge of #120526 - GuillaumeGomez:mobile-long-crate-name, r=notriddle
rustdoc: Correctly handle long crate names on mobile

Fixes https://github.com/rust-lang/rust/issues/120471.

It now renders like this:

![image](https://github.com/rust-lang/rust/assets/3050060/065b4b8b-ba55-4163-a928-8d7bf735c111)

r? `@notriddle`
2024-02-18 05:10:16 +01:00
Urgau
6320ad0b07 Fix non_local_definitions lint in rustdoc 2024-02-17 13:59:46 +01:00
León Orell Valerian Liehr
5fbb1b2f4d
rustdoc: fix and refactor HTML rendering a bit 2024-02-16 21:29:16 +01:00
yukang
bd546fb20a add extra indent spaces for rust-playground link 2024-02-15 18:57:21 +08:00
Guillaume Gomez
14e0dab96b Unify item relative path computation in one function 2024-02-09 14:16:37 +01:00
Guillaume Gomez
f0d002b890 Correctly generate path for non-local items in source code pages 2024-02-09 11:29:40 +01:00
Vadim Petrochenkov
a61019b290 hir: Remove fn opt_hir_id and fn opt_span 2024-02-07 09:38:24 +03:00
Matthias Krüger
a2d3eed58d
Rollup merge of #120641 - klensy:copypaste-me, r=notriddle
rustdoc: trait.impl, type.impl: sort impls to make it not depend on serialization order

Can be tested by running `cargo doc` with different rust versions on some crate and comparing `doc` folders: files in `trait.impl` and `type.impl` will sometimes have different order of impls.
2024-02-05 06:37:17 +01:00
klensy
cb4e69ad67 rustdoc: trait.impl, type.impl: sort impls to make it not depend on serialization order 2024-02-04 16:44:37 +03:00
Guillaume Gomez
d907a6b8ed rustdoc: Correctly handle long crate names on mobile 2024-01-31 16:40:23 +01:00
Guillaume Gomez
efff26701b
Rollup merge of #117906 - GuillaumeGomez:improve-crate-name-hover, r=fmease,notriddle
Improve display of crate name when hovered

Currently when we hover the crate name, the background is stuck to the version and to the logo (when there is one):

![Screenshot from 2023-11-14 11-42-39](https://github.com/rust-lang/rust/assets/3050060/717190cd-483d-45a1-a462-e9ba342d4376)
![Screenshot from 2023-11-14 11-43-19](https://github.com/rust-lang/rust/assets/3050060/23f8bc9b-1304-4f91-ae1e-96bc508e9da6)

I find it very unpleasant so I reduced the padding size and increased the margin (left and top) to keep the same positioning but not making it stuck anymore:

![Screenshot from 2024-01-29 20-40-11](https://github.com/rust-lang/rust/assets/3050060/82cf266c-7f99-4a46-a62b-ebe2445f52be)
![Screenshot from 2024-01-29 20-48-01](https://github.com/rust-lang/rust/assets/3050060/e7097c10-6e09-4bdc-a37f-070b6dac671d)

[online docs](https://rustdoc.crud.net/imperio/improve-crate-name-hover/std/index.html)

r? `@notriddle`
2024-01-30 16:57:46 +01:00
Guillaume Gomez
b60707e174
Rollup merge of #120250 - chadnorvell:rustdoc-xss, r=notriddle
rustdoc: Prevent JS injection from localStorage

It turns out that you can execute arbitrary JavaScript on the rustdocs settings page. Here's how:

1. Open `settings.html` on a rustdocs site.
2. Set "preferred light theme" to "dark" to initialize the corresponding localStorage value.
3. Plant a payload by executing this in your browser's dev console: ``Object.keys(localStorage).forEach(key=>localStorage.setItem(key,`javascript:alert()//*/javascript:javascript:"/*'/*\`/*--></noscript></title></textarea></style></template></noembed></script><html " onmouseover=/*&lt;svg/*/onload=alert()onload=alert()//><svg onload=alert()><svg onload=alert()>*/</style><script>alert()</script><style>`));``
4. Refresh the page -- you should see an alert.

This could be particularly dangerous if rustdocs are deployed on a domain hosting some other application. Malicious code could circumvent `same-origin` policies and do mischievous things with user data.

This change ensures that only defined themes can actually be selected (arbitrary strings from localStorage will not be written to the document), and for good measure sanitizes the theme name.
2024-01-30 11:19:13 +01:00
Guillaume Gomez
96e6cfa34a Improve display of crate name when hovered 2024-01-29 20:40:43 +01:00
Chad Norvell
32a0afe30c rustdoc: Prevent JS injection from localStorage 2024-01-29 18:25:56 +00:00
clubby789
da336190e3 Bump askama version 2024-01-24 01:04:34 +00:00
Nicholas Nethercote
cfdea760f5 Rename TyCtxt::struct_span_lint_hir as TyCtxt::node_span_lint. 2024-01-23 08:09:01 +11:00
Matthias Krüger
6687e8e460
Rollup merge of #119746 - notriddle:notriddle/resize-close-modals, r=fmease
rustdoc: hide modals when resizing the sidebar

Follow-up for
https://github.com/rust-lang/rust/pull/119477#discussion_r1439085011

CC `@lukas-code`
2024-01-22 07:56:42 +01:00
Matthias Krüger
cad609d9e3
Rollup merge of #117662 - GuillaumeGomez:links-in-headings, r=notriddle
[rustdoc] Allows links in headings

Reopening of https://github.com/rust-lang/rust/pull/94360.

# Explanations

Rustdoc currently doesn't follow the markdown spec on headings: we don't allow links in them. So instead of having headings linking to themselves, this PR generates an anchor on the left side like this:

![image](https://github.com/rust-lang/rust/assets/3050060/a118a7e9-5ef8-4d07-914f-46defc3245c3)

<details>
<summary>previous version</summary>

![image](https://github.com/rust-lang/rust/assets/3050060/c34fa844-9cd4-47dc-bb51-b37f5f66afee)

</details>

Having the anchor always displayed allows for mobile devices users to be able to have a link to the anchor. The different color used for the anchor itself is the same as links so people notice when looking at it that they can click on it.

You can test it [here](https://rustdoc.crud.net/imperio/links-in-headings/std/index.html).

cc `@camelid`
r? `@notriddle`
2024-01-19 19:26:59 +01:00
Nicholas Nethercote
ff40ad4107 Shorten some error invocations.
- `struct_foo` + `emit` -> `foo`
- `create_foo` + `emit` -> `emit_foo`

I have made recent commits in other PRs that have removed some of these
shortcuts for combinations with few uses, e.g.
`struct_span_err_with_code`. But for the remaining combinations that
have high levels of use, we might as well use them wherever possible.
2024-01-10 07:33:06 +11:00