Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustdoc: use JS to inline target type impl docs into alias #116471

Merged
merged 12 commits into from
Oct 28, 2023

Commits on Oct 22, 2023

  1. rustdoc: rename /implementors to /impl.trait

    This is shorter, avoids potential conflicts with a crate
    named `implementors`[^1], and will be less confusing when JS
    include files are added for type aliases.
    
    [^1]: AFAIK, this couldn't actually cause any problems right now,
    but it's simpler just to make it impossible than relying on never
    having a file named `trait.Foo.js` in the crate data area.
    notriddle committed Oct 22, 2023
    Configuration menu
    Copy the full SHA
    ade7ecf View commit details
    Browse the repository at this point in the history
  2. Revert "rustdoc: filter before storing in vec"

    This reverts commit c79b960.
    notriddle committed Oct 22, 2023
    Configuration menu
    Copy the full SHA
    aa76a59 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    ab125a2 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    36b8d58 View commit details
    Browse the repository at this point in the history
  5. Revert "Add note about lazy_type_alias"

    This reverts commit b3686c2.
    notriddle committed Oct 22, 2023
    Configuration menu
    Copy the full SHA
    77da7c6 View commit details
    Browse the repository at this point in the history
  6. Revert "rustdoc: list matching impls on type aliases"

    This reverts commit 19edb3c.
    notriddle committed Oct 22, 2023
    Configuration menu
    Copy the full SHA
    e701e64 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    4dfd827 View commit details
    Browse the repository at this point in the history
  8. rustdoc: use JS to inline target type impl docs into alias

    This is an attempt to balance three problems, each of which would
    be violated by a simpler implementation:
    
    - A type alias should show all the `impl` blocks for the target
      type, and vice versa, if they're applicable. If nothing was
      done, and rustdoc continues to match them up in HIR, this
      would not work.
    
    - Copying the target type's docs into its aliases' HTML pages
      directly causes far too much redundant HTML text to be generated
      when a crate has large numbers of methods and large numbers
      of type aliases.
    
    - Using JavaScript exclusively for type alias impl docs would
      be a functional regression, and could make some docs very hard
      to find for non-JS readers.
    
    - Making sure that only applicable docs are show in the
      resulting page requires a type checkers. Do not reimplement
      the type checker in JavaScript.
    
    So, to make it work, rustdoc stashes these type-alias-inlined docs
    in a JSONP "database-lite". The file is generated in `write_shared.rs`,
    included in a `<script>` tag added in `print_item.rs`, and `main.js`
    takes care of patching the additional docs into the DOM.
    
    The format of `trait.impl` and `type.impl` JS files are superficially
    similar. Each line, except the JSONP wrapper itself, belongs to a crate,
    and they are otherwise separate (rustdoc should be idempotent). The
    "meat" of the file is HTML strings, so the frontend code is very simple.
    Links are relative to the doc root, though, so the frontend needs to fix
    that up, and inlined docs can reuse these files.
    
    However, there are a few differences, caused by the sophisticated
    features that type aliases have. Consider this crate graph:
    
    ```text
     ---------------------------------
     | crate A: struct Foo<T>        |
     |          type Bar = Foo<i32>  |
     |          impl X for Foo<i8>   |
     |          impl Y for Foo<i32>  |
     ---------------------------------
         |
     ----------------------------------
     | crate B: type Baz = A::Foo<i8> |
     |          type Xyy = A::Foo<i8> |
     |          impl Z for Xyy        |
     ----------------------------------
    ```
    
    The type.impl/A/struct.Foo.js JS file has a structure kinda like this:
    
    ```js
    JSONP({
    "A": [["impl Y for Foo<i32>", "Y", "A::Bar"]],
    "B": [["impl X for Foo<i8>", "X", "B::Baz", "B::Xyy"], ["impl Z for Xyy", "Z", "B::Baz"]],
    });
    ```
    
    When the type.impl file is loaded, only the current crate's docs are
    actually used. The main reason to bundle them together is that there's
    enough duplication in them for DEFLATE to remove the redundancy.
    
    The contents of a crate are a list of impl blocks, themselves
    represented as lists. The first item in the sublist is the HTML block,
    the second item is the name of the trait (which goes in the sidebar),
    and all others are the names of type aliases that successfully match.
    
    This way:
    
    - There's no need to generate these files for types that have no aliases
      in the current crate. If a dependent crate makes a type alias, it'll
      take care of generating its own docs.
    - There's no need to reimplement parts of the type checker in
      JavaScript. The Rust backend does the checking, and includes its
      results in the file.
    - Docs defined directly on the type alias are dropped directly in the
      HTML by `render_assoc_items`, and are accessible without JavaScript.
      The JSONP file will not list impl items that are known to be part
      of the main HTML file already.
    
    [JSONP]: https://en.wikipedia.org/wiki/JSONP
    notriddle committed Oct 22, 2023
    Configuration menu
    Copy the full SHA
    fa10e4d View commit details
    Browse the repository at this point in the history
  9. rustdoc: remove as_ref from method sidebar test

    I fixed this in the code, but forgot to fix it in the test.
    notriddle committed Oct 22, 2023
    Configuration menu
    Copy the full SHA
    d8afa67 View commit details
    Browse the repository at this point in the history
  10. rustdoc: clean up sidebar.html block class

    This line is longer than 100 characters, but apparently,
    [tidy's list of checked extensions] doesn't include html,
    so the line length doesn't matter.
    
    [tidy's list of checked extensions]: https://github.com/rust-lang/rust/blob/31be8cc41148983e742fea8f559aacca0f6647db/src/tools/tidy/src/style.rs#L245
    notriddle committed Oct 22, 2023
    Configuration menu
    Copy the full SHA
    fd9ab34 View commit details
    Browse the repository at this point in the history
  11. Configuration menu
    Copy the full SHA
    62c67a6 View commit details
    Browse the repository at this point in the history
  12. Configuration menu
    Copy the full SHA
    46fdeb2 View commit details
    Browse the repository at this point in the history