rustdoc: add interaction delays for tooltip popovers
Preview:
* [notable traits](http://notriddle.com/rustdoc-demo-html-3/delay-tooltip/testing/struct.Vec.html#method.iter)
* [panicking code block](http://notriddle.com/rustdoc-demo-html-3/delay-tooltip/testing/struct.Vec.html#indexing)
Designing a good hover microinteraction is a matter of guessing user intent from what are, literally, vague gestures. In this case, guessing if hovering in our out of the tooltip base is intentional or not.
To figure this out, a few different techniques are used:
* When the mouse pointer enters a tooltip anchor point, its hitbox is grown on the bottom, where the popover is/will appear. This was already there before this commit: search "hover tunnel" in rustdoc.css for the implementation.
* This commit adds a delay when the mouse pointer enters the base anchor, in case the mouse pointer was just passing through and the user didn't want to open it.
* This commit also adds a delay when the mouse pointer exits the tooltip's base anchor or its popover, before hiding it.
* A fade-out animation is layered onto the pointer exit delay to immediately inform the user that they successfully dismissed the popover, while still providing a way for them to cancel it if it was a mistake and they still wanted to interact with it.
* No animation is used for revealing it, because we don't want people to try to interact with an element while it's in the middle of fading in: either they're allowed to interact with it while it's fading in, meaning it can't serve as mistake- proofing for opening the popover, or they can't, but they might try and be frustrated.
See also:
* https://www.nngroup.com/articles/timing-exposing-content/
* https://www.nngroup.com/articles/tooltip-guidelines/
* https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown
rustdoc: Fix LinkReplacer link matching
It currently just uses the first link with the same href which might not necessarily be the matching one.
This fixes replacements when there are several links to the same item but with different text (e.g. `[X] and [struct@X]`). It also fixes replacements in summaries since those use a links list with empty hrefs, so currently all links would always match the first link by href but then not match its text. This could also lead to a panic in the `original_lext[1..len() - 1]` part when the first link only has a single character, which is why the new code uses `.get(..)` instead.
Each of `{D,Subd}iagnosticMessage::{Str,Eager}` has a comment:
```
// FIXME(davidtwco): can a `Cow<'static, str>` be used here?
```
This commit answers that question in the affirmative. It's not the most
compelling change ever, but it might be worth merging.
This requires changing the `impl<'a> From<&'a str>` impls to `impl
From<&'static str>`, which involves a bunch of knock-on changes that
require/result in call sites being a little more precise about exactly
what kind of string they use to create errors, and not just `&str`. This
will result in fewer unnecessary allocations, though this will not have
any notable perf effects given that these are error paths.
Note that I was lazy within Clippy, using `to_string` in a few places to
preserve the existing string imprecision. I could have used `impl
Into<{D,Subd}iagnosticMessage>` in various places as is done in the
compiler, but that would have required changes to *many* call sites
(mostly changing `&format("...")` to `format!("...")`) which didn't seem
worthwhile.
Migrate `item_foreign_type` to Askama
This PR continues the migration of `print_item.rs` functions to Askama. This piece of work migrates the function `item_foreign_type`
Refers https://github.com/rust-lang/rust/issues/108868
Clean up usage of `cx.tcx` when `tcx` is already set into a variable
I discovered a few cases where `cx.tcx` (and equivalents) was used whereas `tcx` was already stored into a variable. In those cases, better to just use `tcx` directly.
r? `@notriddle`
Migrate `item_static` to Askama
This pull request addresses the type signature of the item_static function in our codebase. Previously, this function accepted a mutable reference to a Buffer for writing output. The current changes modify this to instead accept a mutable reference to any type that implements the Write trait.
Referes https://github.com/rust-lang/rust/issues/108868
rustdoc: Cleanup doc string collapsing
`doc_value` and (former) `collapsed_doc_value` can be implemented in terms of each other, and `doc_value` doesn't need the `Option`.
This PR doesn't do any semantic changes, only refactoring, although some pre-existing choices between `doc_value` and `collapsed_doc_value` across rustdoc may be questionable.
Designing a good hover microinteraction is a matter of guessing
user intent from what are, literally, vague gestures. In this case,
guessing if hovering in our out of the tooltip base is intentional
or not.
To figure this out, a few different techniques are used:
* When the mouse pointer enters a tooltip anchor point, its hitbox
is grown on the bottom, where the popover is/will appear. This was
already there before this commit: search "hover tunnel" in
rustdoc.css for the implementation.
* This commit adds a delay when the mouse pointer enters the base
anchor, in case the mouse pointer was just passing through and the
user didn't want to open it.
* This commit also adds a delay when the mouse pointer exits the
tooltip's base anchor or its popover, before hiding it.
* A fade-out animation is layered onto the pointer exit delay to
immediately inform the user that they successfully dismissed the
popover, while still providing a way for them to cancel it if
it was a mistake and they still wanted to interact with it.
* No animation is used for revealing it, because we don't want
people to try to interact with an element while it's in the
middle of fading in: either they're allowed to interact with
it while it's fading in, meaning it can't serve as mistake-
proofing for opening the popover, or they can't, but they
might try and be frustrated.
See also:
* https://www.nngroup.com/articles/timing-exposing-content/
* https://www.nngroup.com/articles/tooltip-guidelines/
* https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown
This was added to control percentage sizes, in
79956b96e8
Now, the only percentage size is [`border-radius`], which is
based on the size of the box itself, not its containing block.
This leaves the property unused.
[`border-radius`]: https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius
Error message all end up passing into a function as an `impl
Into<{D,Subd}iagnosticMessage>`. If an error message is creatd as
`&format("...")` that means we allocate a string (in the `format!`
call), then take a reference, and then clone (allocating again) the
reference to produce the `{D,Subd}iagnosticMessage`, which is silly.
This commit removes the leading `&` from a lot of these cases. This
means the original `String` is moved into the
`{D,Subd}iagnosticMessage`, avoiding the double allocations. This
requires changing some function argument types from `&str` to `String`
(when all arguments are `String`) or `impl
Into<{D,Subd}iagnosticMessage>` (when some arguments are `String` and
some are `&str`).
Introduce `AliasKind::Inherent` for inherent associated types
Allows us to check (possibly generic) inherent associated types for well-formedness.
Type inference now also works properly.
Follow-up to #105961. Supersedes #108430.
Fixes#106722.
Fixes#108957.
Fixes#109768.
Fixes#109789.
Fixes#109790.
~Not to be merged before #108860 (`AliasKind::Weak`).~
CC `@jackh726`
r? `@compiler-errors`
`@rustbot` label T-types F-inherent_associated_types
rustdoc-search: add slices and arrays to index
This indexes them as primitives with generics, so `slice<u32>` is how you search for `[u32]`, and `array<u32>` for `[u32; 1]`. A future commit will desugar the square bracket syntax to search both arrays and slices at once.
Avoid ICEing miri on layout query cycles
Miri has special logic for catching panics during interpretation. Raising a fatal error in rustc uses unwinding to abort compilation. Thus miri ends up catching that fatal error and thinks it saw an ICE. While we should probably change that to ignore `Fatal` payloads, I think it's also neat to continue compilation after a layout query cycle 😆
Query cycles now (in addition to reporting an error just like before), return `Err(Cycle)` instead of raising a fatal error. This allows the interpreter to wind down via the regular error paths.
r? `@RalfJung` for a first round, feel free to reroll for the compiler team once the miri side looks good
Implement negative bounds for internal testing purposes
Implements partial support the `!` negative polarity on trait bounds. This is incomplete, but should allow us to at least be able to play with the feature.
Not even gonna consider them as a public-facing feature, but I'm implementing them because would've been nice to have in UI tests, for example in #110671.
Currently a `{D,Subd}iagnosticMessage` can be created from any type that
impls `Into<String>`. That includes `&str`, `String`, and `Cow<'static,
str>`, which are reasonable. It also includes `&String`, which is pretty
weird, and results in many places making unnecessary allocations for
patterns like this:
```
self.fatal(&format!(...))
```
This creates a string with `format!`, takes a reference, passes the
reference to `fatal`, which does an `into()`, which clones the
reference, doing a second allocation. Two allocations for a single
string, bleh.
This commit changes the `From` impls so that you can only create a
`{D,Subd}iagnosticMessage` from `&str`, `String`, or `Cow<'static,
str>`. This requires changing all the places that currently create one
from a `&String`. Most of these are of the `&format!(...)` form
described above; each one removes an unnecessary static `&`, plus an
allocation when executed. There are also a few places where the existing
use of `&String` was more reasonable; these now just use `clone()` at
the call site.
As well as making the code nicer and more efficient, this is a step
towards possibly using `Cow<'static, str>` in
`{D,Subd}iagnosticMessage::{Str,Eager}`. That would require changing
the `From<&'a str>` impls to `From<&'static str>`, which is doable, but
I'm not yet sure if it's worthwhile.
rustdoc: Get `repr` information through `AdtDef` for foreign items
As suggested by `@notriddle,` this approach works too. The only downside is that the display of the original attribute isn't kept, but I think it's an acceptable downside.
r? `@notriddle`