rustdoc: use focus for search navigation
Rather than keeping track of highlighted element inside the JS, take advantage of `.focus()` and the :focus CSS pseudo-class.
This required wrapping each row of results in one big `<a>` tag (because anchors can be focused, but table rows cannot). That in turn required moving from a table layout to a div layout with float.
This makes it so Ctrl+Enter opens links in new tabs, and using the arrow keys to navigate off the bottom of the page scrolls the rest of the page into view. It also simplifies the keyboard event handling. It eliminates the need for click handlers on the search results, and for tracking mouse movements.
This changes the UI treatment of mouse hovering. A hovered element now gets a light grey background, but does not change the focus. It's possible to have two highlighted search results: one that is focused (via keyboard) and one that is hovered (via mouse). Pressing enter will activate the focused link; clicking will activate the hovered link. This matches up with how Firefox and Chrome handle suggestions in their URL bar, and avoids stray mouse movements changing the focus.
Selecting tabs is now done with left/right arrows while any search result is focused. The visibility of results on each search tab is
controlled with the "active" class, rather than by setting display: none directly. Note that the old code kept track of highlighted search element when tabbing back and forth. The new code doesn't.
Demo at https://hoffman-andrews.com/rust/focus-search-results2/std/?search=fnFixes#84384Fixes#79962Fixes#79872
- make Allocation API offset-based (no more Pointer)
- make Memory API higher-level (combine checking for access and getting access into one operation)
Don't lint `multiple_inherent_impl` with generic arguments
fixes: #5772
changelog: Treat different generic arguments as different types in `multiple_inherent_impl`
Rollup of 7 pull requests
Successful merges:
- #84587 (rustdoc: Make "rust code block is empty" and "could not parse code block" warnings a lint (`INVALID_RUST_CODEBLOCKS`))
- #85280 (Toggle-wrap items differently than top-doc.)
- #85338 (Implement more Iterator methods on core::iter::Repeat)
- #85339 (Report an error if a lang item has the wrong number of generic arguments)
- #85369 (Suggest borrowing if a trait implementation is found for &/&mut <type>)
- #85393 (Suppress spurious errors inside `async fn`)
- #85415 (Clean up remnants of BorrowOfPackedField)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Deny warnings in every main sub-crate
Pointed out by `@xFrednet` in https://github.com/rust-lang/rust-clippy/pull/7229#issuecomment-842978909
This enables the same (rustc) lints in every main sub-crate:
- `clippy`
- `clippy_lints`
- `clippy_utils`
- `clippy_dev`
In addition it forwards the `deny-warnings` feature to those sub-crates, so we don't miss warnings that then become a problem during sync. (I wanted to fix that before, but forgot about it, so thanks for pointing it out `@xFrednet!)`
changelog: none
Suggest borrowing if a trait implementation is found for &/&mut <type>
This pull request fixes#84973 by suggesting to borrow if a trait is not implemented for some type `T`, but it is for `&T` or `&mut T`. For instance:
```rust
trait Ti {}
impl<T> Ti for &T {}
fn foo<T: Ti>(_: T) {}
trait Tm {}
impl<T> Tm for &mut T {}
fn bar<T: Tm>(_: T) {}
fn main() {
let a: i32 = 5;
foo(a);
let b: Box<i32> = Box::new(42);
bar(b);
}
```
gives, on current nightly:
```
error[E0277]: the trait bound `i32: Ti` is not satisfied
--> t2.rs:11:9
|
3 | fn foo<T: Ti>(_: T) {}
| -- required by this bound in `foo`
...
11 | foo(a);
| ^ the trait `Ti` is not implemented for `i32`
error[E0277]: the trait bound `Box<i32>: Tm` is not satisfied
--> t2.rs:14:9
|
7 | fn bar<T: Tm>(_: T) {}
| -- required by this bound in `bar`
...
14 | bar(b);
| ^ the trait `Tm` is not implemented for `Box<i32>`
error: aborting due to 2 previous errors
```
whereas with my changes, I get:
```
error[E0277]: the trait bound `i32: Ti` is not satisfied
--> t2.rs:11:9
|
3 | fn foo<T: Ti>(_: T) {}
| -- required by this bound in `foo`
...
11 | foo(a);
| ^
| |
| expected an implementor of trait `Ti`
| help: consider borrowing here: `&a`
error[E0277]: the trait bound `Box<i32>: Tm` is not satisfied
--> t2.rs:14:9
|
7 | fn bar<T: Tm>(_: T) {}
| -- required by this bound in `bar`
...
14 | bar(b);
| ^
| |
| expected an implementor of trait `Tm`
| help: consider borrowing mutably here: `&mut b`
error: aborting due to 2 previous errors
```
In my implementation, I have added a "blacklist" to make these suggestions flexible. In particular, suggesting to borrow can interfere with other suggestions, such as to add another trait bound to a generic argument. I have tried to configure this blacklist to cause the least amount of test case failures, i.e. to model the current behavior as closely as possible (I only had to change one existing test case, and this change was quite clearly an improvement).
Report an error if a lang item has the wrong number of generic arguments
This pull request fixes#83893. The issue is that the lang item code currently checks whether the lang item has the correct item kind (e.g. a `#[lang="add"]` has to be a trait), but not whether the item has the correct number of generic arguments.
This can lead to an "index out of bounds" ICE when the compiler tries to create more substitutions than there are suitable types available (if the lang item was declared with too many generic arguments).
For instance, here is a reduced ("reduced" in the sense that it does not trigger additional errors) version of the example given in #83893:
```rust
#![feature(lang_items,no_core)]
#![no_core]
#![crate_type="lib"]
#[lang = "sized"]
trait MySized {}
#[lang = "add"]
trait MyAdd<'a, T> {}
fn ice() {
let r = 5;
let a = 6;
r + a
}
```
On current nightly, this immediately causes an ICE without any warnings or errors emitted. With the changes in this PR, however, I get no ICE and two errors:
```
error[E0718]: `add` language item must be applied to a trait with 1 generic argument
--> pr-ex.rs:8:1
|
8 | #[lang = "add"]
| ^^^^^^^^^^^^^^^
9 | trait MyAdd<'a, T> {}
| ------- this trait has 2 generic arguments, not 1
error[E0369]: cannot add `{integer}` to `{integer}`
--> pr-ex.rs:14:7
|
14 | r + a
| - ^ - {integer}
| |
| {integer}
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0369, E0718.
For more information about an error, try `rustc --explain E0369`.
```
Implement more Iterator methods on core::iter::Repeat
`core::iter::Repeat` always returns the same element, which means we can
do better than implementing most `Iterator` methods in terms of
`Iterator::next`.
Fixes#81292.
#81292 raises the question of whether these changes violate the contract of `core::iter::Repeat`, but as far as I can tell `core::iter::repeat` doesn't make any guarantees around how it calls `Clone::clone`.
Unify Regions with RegionVids in UnificationTable
A few test output changes; might be able to revert those but figured I would open this for perf and comments.
r? `@nikomatsakis`
This enables the same warnings that are enabled in `clippy_lints` also
in `clippy_utils` and `clippy_dev`. Then it makes sure, that the
`deny-warnings` feature is passed down to `clippy_lints` and
`clippy_utils` when compiling Clippy.
Provide ExitStatusError
Closes#73125
In MR #81452 "Add #[must_use] to [...] process::ExitStatus" we concluded that the existing arrangements in are too awkward so adding that `#[must_use]` is blocked on improving the ergonomics.
I wrote a mini-RFC-style discusion of the approach in https://github.com/rust-lang/rust/issues/73125#issuecomment-771092741
This change adds pre-setup instructions that outline how x.py requires
python to be setup and how to work around the problem of x.py failing to
locate python, especially now that Ubuntu 20.04's dropped default python
command is causing people to encounter this issue regularly.
See also: #71818
Remove powi, "square can be computed more efficiently"
powi(2) produces exactly the same native code as x * x
powi was part of the [`suboptimal_flops`] lint
fixes#7058
changelog: Remove powi [`suboptimal_flops`], "square can be computed more efficiently"
# Stabilization report
## Summary
This stabilizes using macro expansion in key-value attributes, like so:
```rust
#[doc = include_str!("my_doc.md")]
struct S;
#[path = concat!(env!("OUT_DIR"), "/generated.rs")]
mod m;
```
See the changes to the reference for details on what macros are allowed;
see Petrochenkov's excellent blog post [on internals](https://internals.rust-lang.org/t/macro-expansion-points-in-attributes/11455)
for alternatives that were considered and rejected ("why accept no more
and no less?")
This has been available on nightly since 1.50 with no major issues.
## Notes
### Accepted syntax
The parser accepts arbitrary Rust expressions in this position, but any expression other than a macro invocation will ultimately lead to an error because it is not expected by the built-in expression forms (e.g., `#[doc]`). Note that decorators and the like may be able to observe other expression forms.
### Expansion ordering
Expansion of macro expressions in "inert" attributes occurs after decorators have executed, analogously to macro expressions appearing in the function body or other parts of decorator input.
There is currently no way for decorators to accept macros in key-value position if macro expansion must be performed before the decorator executes (if the macro can simply be copied into the output for later expansion, that can work).
## Test cases
- https://github.com/rust-lang/rust/blob/master/src/test/ui/attributes/key-value-expansion-on-mac.rs
- https://github.com/rust-lang/rust/blob/master/src/test/rustdoc/external-doc.rs
The feature has also been dogfooded extensively in the compiler and
standard library:
- https://github.com/rust-lang/rust/pull/83329
- https://github.com/rust-lang/rust/pull/83230
- https://github.com/rust-lang/rust/pull/82641
- https://github.com/rust-lang/rust/pull/80534
## Implementation history
- Initial proposal: https://github.com/rust-lang/rust/issues/55414#issuecomment-554005412
- Experiment to see how much code it would break: https://github.com/rust-lang/rust/pull/67121
- Preliminary work to restrict expansion that would conflict with this
feature: https://github.com/rust-lang/rust/pull/77271
- Initial implementation: https://github.com/rust-lang/rust/pull/78837
- Fix for an ICE: https://github.com/rust-lang/rust/pull/80563
## Unresolved Questions
~~https://github.com/rust-lang/rust/pull/83366#issuecomment-805180738 listed some concerns, but they have been resolved as of this final report.~~
## Additional Information
There are two workarounds that have a similar effect for `#[doc]`
attributes on nightly. One is to emulate this behavior by using a limited version of this feature that was stabilized for historical reasons:
```rust
macro_rules! forward_inner_docs {
($e:expr => $i:item) => {
#[doc = $e]
$i
};
}
forward_inner_docs!(include_str!("lib.rs") => struct S {});
```
This also works for other attributes (like `#[path = concat!(...)]`).
The other is to use `doc(include)`:
```rust
#![feature(external_doc)]
#[doc(include = "lib.rs")]
struct S {}
```
The first works, but is non-trivial for people to discover, and
difficult to read and maintain. The second is a strange special-case for
a particular use of the macro. This generalizes it to work for any use
case, not just including files.
I plan to remove `doc(include)` when this is stabilized. The
`forward_inner_docs` workaround will still compile without warnings, but
I expect it to be used less once it's no longer necessary.
Previously, setting `download-ci-llvm = true` when cmake wasn't
installed would give the following error:
```
failed to execute command: "cmake" "--help"
error: The system cannot find the file specified. (os error 2)
```
This adds a new lint to `rustc` that is used in rustdoc when a code
block is empty or cannot be parsed as valid Rust code.
Previously this was unconditionally a warning. As such some
documentation comments were (unknowingly) abusing this to pass despite
the `-Dwarnings` used when compiling `rustc`, this should not be the
case anymore.