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
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.
Fix x86_64-gnu-llvm-15 CI tests
The CI script was broken - if there was a test failure in the first command chain (inside the `if`), CI would not report the failure.
It happened because there were two command chains separated by `&&` in the script, and since `set -e` doesn't exit for chained commands, if the first chain has failed, the script would happily continue forward, ignoring any test failures.
This could be fixed e.g. by adding some `|| exit 1` to the first chain, but I suppose that the `&&` chaining is unnecessary here anyway.
Reported [on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra/topic/test.20failure.20didn't.20stop.20CI).
Fixes: https://github.com/rust-lang/rust/issues/116867
Mention the syntax for `use` on `mod foo;` if `foo` doesn't exist
Newcomers might get confused that `mod` is the only way of defining scopes, and that it can be used as if it were `use`.
Fix#69492.
fix spans for removing `.await` on `for` expressions
We need to use a span with the outer syntax context of a desugared `for` expression to join it with the `.await` span.
fixes https://github.com/rust-lang/rust/issues/117014
Lint `non_exhaustive_omitted_patterns` by columns
This is a rework of the `non_exhaustive_omitted_patterns` lint to make it more consistent. The intent of the lint is to help consumers of `non_exhaustive` enums ensure they stay up-to-date with all upstream variants. This rewrite fixes two cases we didn't handle well before:
First, because of details of exhaustiveness checking, the following wouldn't lint `Enum::C` as missing:
```rust
match Some(x) {
Some(Enum::A) => {}
Some(Enum::B) => {}
_ => {}
}
```
Second, because of the fundamental workings of exhaustiveness checking, the following would treat the `true` and `false` cases separately and thus lint about missing variants:
```rust
match (true, x) {
(true, Enum::A) => {}
(true, Enum::B) => {}
(false, Enum::C) => {}
_ => {}
}
```
Moreover, it would correctly not lint in the case where the pair is flipped, because of asymmetry in how exhaustiveness checking proceeds.
A drawback is that it no longer makes sense to set the lint level per-arm. This will silently break the lint for current users of it (but it's behind a feature gate so that's ok).
The new approach is now independent of the exhaustiveness algorithm; it's a separate pass that looks at patterns column by column. This is another of the motivations for this: I'm glad to move it out of the algorithm, it was akward there.
This PR is almost identical to https://github.com/rust-lang/rust/pull/111651. cc `@eholk` who reviewed it at the time. Compared to then, I'm more confident this is the right approach.
Point at assoc fn definition on type param divergence
When the number of type parameters in the associated function of an impl and its trait differ, we now *always* point at the trait one, even if it comes from a foreign crate. When it is local, we point at the specific params, when it is foreign, we point at the whole associated item.
Fix#69944.
Mention `into_iter` on borrow errors suggestions when appropriate
If we encounter a borrow error on `vec![1, 2, 3].iter()`, suggest `into_iter`.
Fix#68445.
coverage: Fix inconsistent handling of function signature spans
While doing some more cleanup of `spans`, I noticed a strange inconsistency in how function signatures are handled. Normally the function signature span is treated as though it were executable as part of the start of the function, but in some cases the signature span disappears entirely from coverage, for no obvious reason.
This is caused by the fact that spans created by `CoverageSpan::for_fn_sig` don't add the span to their `merged_spans` field (unlike normal statement/terminator spans). In cases where the span-processing code looks at those merged spans, it thinks the signature span is no longer visible and deletes it.
Adding the signature span to `merged_spans` resolves the inconsistency.
(Prior to #116409 this wouldn't have been possible, because there was no case in the old `CoverageStatement` enum representing a signature. Now that `merged_spans` is just a list of spans, that's no longer an obstacle.)
Add stable Instance::body() and RustcInternal trait
The `Instance::body()` returns a monomorphized body.
For that, we had to implement visitor that monomorphize types and constants. We are also introducing the RustcInternal trait that will allow us to convert back from Stable to Internal.
Note that this trait is not yet visible for our users as it depends on Tables. We should probably add a new trait that can be exposed.
The tests here are very simple, and I'm planning on creating more exhaustive tests in the project-mir repo. But I was hoping to get some feedback here first.
r? ```@oli-obk```
Typo suggestion to change bindings with leading underscore
When encountering a binding that isn't found but has a typo suggestion for a binding with a leading underscore, suggest changing the binding definition instead of the use place.
Fix#60164.
When the number of type parameters in the associated function of an impl
and its trait differ, we now *always* point at the trait one, even if it
comes from a foreign crate. When it is local, we point at the specific
params, when it is foreign, we point at the whole associated item.
Fix#69944.
When encountering a binding that isn't found but has a typo suggestion
for a binding with a leading underscore, suggest changing the binding
definition instead of the use place.
Fix#60164.
Move where doc comment meant as comment check
The new place makes more sense and covers more cases beyond individual statements.
```
error: expected one of `.`, `;`, `?`, `else`, or an operator, found doc comment `//!foo
--> $DIR/doc-comment-in-stmt.rs:25:22
|
LL | let y = x.max(1) //!foo
| ^^^^^^ expected one of `.`, `;`, `?`, `else`, or an operator
|
help: add a space before `!` to write a regular comment
|
LL | let y = x.max(1) // !foo
| +
```
Fix#65329.
Add a test showing failing closure signature inference in new solver
Been thinking a bit about how to make this test pass... but we don't actually have any good tests exercising this behavior in the suite.
r? lcnr
The new place makes more sense and covers more cases beyond individual
statements.
```
error: expected one of `.`, `;`, `?`, `else`, or an operator, found doc comment `//!foo
--> $DIR/doc-comment-in-stmt.rs:25:22
|
LL | let y = x.max(1) //!foo
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected one of `.`, `;`, `?`, `else`, or an operator
|
help: add a space before `!` to write a regular comment
|
LL | let y = x.max(1) // !foo
| +
```
Fix#65329.
Fix duplicate labels emitted in `render_multispan_macro_backtrace()`
This PR replaces the `Vec` used to store labels with an `FxIndexSet` in order to eliminate duplicates
Fixes#116836
The `Instance::body()` returns a monomorphized body.
For that, we had to implement visitor that monomorphize types and
constants. We are also introducing the RustcInternal trait that will
allow us to convert back from Stable to Internal.
Note that this trait is not yet visible for our users as it depends on
Tables. We should probably add a new trait that can be exposed.
Implement rustc part of RFC 3127 trim-paths
This PR implements (or at least tries to) [RFC 3127 trim-paths](https://github.com/rust-lang/rust/issues/111540), the rustc part. That is `-Zremap-path-scope` with all of it's components/scopes.
`@rustbot` label: +F-trim-paths