Collect lang items from AST, get rid of `GenericBound::LangItemTrait`
r? `@cjgillot`
cc #115178
Looking forward, the work to remove `QPath::LangItem` will also be significantly more difficult, but I plan on doing it as well. Specifically, we have to change:
1. A lot of `rustc_ast_lowering` for things like expr `..`
2. A lot of astconv, since we actually instantiate lang and non-lang paths quite differently.
3. A ton of diagnostics and clippy lints that are special-cased via `QPath::LangItem`
Meanwhile, it was pretty easy to remove `GenericBound::LangItemTrait`, so I just did that here.
Rollup of 7 pull requests
Successful merges:
- #117824 (Stabilize `ptr::{from_ref, from_mut}`)
- #118234 (Stabilize `type_name_of_val`)
- #118944 (Move type relations into submodule `relate` in rustc_infer, and notify when it has changed)
- #118977 (Simplify `src-script.js` code)
- #118985 (Remove `@JohnTitor` from diagnostics pings)
- #118986 (Simplify JS code a little bit)
- #118988 (rustdoc: add regression test for JS data file loading)
r? `@ghost`
`@rustbot` modify labels: rollup
Stabilize `type_name_of_val`
Make the following API stable:
```rust
// in core::any
pub fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str
```
This is a convenience method to get the type name of a value, as opposed to `type_name` that takes a type as a generic.
Const stability is not added because this relies on `type_name` which is also not const. That has a blocking issue https://github.com/rust-lang/rust/issues/97156.
Wording was also changed to direct most of the details to `type_name` so we don't have as much duplicated documentation.
Fixes tracking issue #66359.
There were two main concerns in the tracking issue:
1. Naming: `type_name_of` and `type_name_of_val` seem like the only mentioned options. Differences in opinion here come from `std::mem::{size_of, align_of, size_of_val, align_of_val}`. This PR leaves the name as `type_name_of_val`, but I can change if desired since it is pretty verbose.
2. What this displays for `&dyn`: I don't think that having `type_name_of_val` function resolve those is worth the headache it would be, see https://github.com/rust-lang/rust/issues/66359#issuecomment-1718480774 for some workarounds. I also amended the docs wording to leave it open-ended, in case we have means to change that behavior in the future.
``@rustbot`` label -T-libs +T-libs-api +needs-fcp
r? libs-api
Stabilize `ptr::{from_ref, from_mut}`
I propose to stabilize the following APIs:
```rust
// mod core::ptr
pub const fn from_ref<T: ?Sized>(r: &T) -> *const T;
pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T;
```
Tracking issue: https://github.com/rust-lang/rust/issues/106116
---
``@RalfJung`` what do you think we should do with `from_mut`? Stabilize it as const, given that you can't call it anyway (no way to get `&mut` in `const fn`)? Defer stabilizing it as const leaving the same issue/feature? Change issue/feature? Change issue/feature to the "`&mut` in const fn" one?
codegen_llvm: set `DW_AT_accessibility`
Fixes#9228.
Based on #74778.
Sets the accessibility of types and fields in DWARF using `DW_AT_accessibility` attribute.
`DW_AT_accessibility` (public/protected/private) isn't exactly right for Rust, but neither is `DW_AT_visibility` (local/exported/qualified), and there's no way to set `DW_AT_visbility` in LLVM's API. Debuggers will special-case the handling of these per-language anyway.
r? `@wesleywiser` (visited in wg-debugging triage)
Sets the accessibility of types and fields in DWARF using
`DW_AT_accessibility` attribute.
`DW_AT_accessibility` (public/protected/private) isn't exactly right for
Rust, but neither is `DW_AT_visibility` (local/exported/qualified), and
there's no way to set `DW_AT_visbility` in LLVM's API.
Signed-off-by: David Wood <david@davidtw.co>
Some cleanup and improvement for invalid ref casting impl
This PR makes some cleanups and improvements to the `invalid_reference_casting` implementation in preparation for linting on new patterns, while reusing most of the logic.
r? `@est31` (feel free to re-assign)
rustdoc: allow resizing the sidebar / hiding the top bar
Fixes#97306
Preview: http://notriddle.com/rustdoc-html-demo-4/sidebar-resize/std/index.html
![image](https://github.com/rust-lang/rust/assets/1593513/a2f40ea2-0436-4e44-99e8-d160dab2a680)
## Summary
This feature adds:
1. A checkbox to the Settings popover to hide the persistent navigation bar (the sidebar on large viewports and the top bar on small ones).
2. On large viewports, it adds a resize handle to the persistent sidebar. Resizing it into nothing is equivalent to turning off the persistent navigation bar checkbox in Settings.
3. If the navigation bar is hidden, a toolbar button to the left of the search appears. Clicking it brings the navigation bar back.
## Motivation
While "mobile mode" is definitely a good default, it's not the only reason people have wanted to hide the sidebar:
* Some people use tiling window managers, and don't like rustdoc's current breakpoints. Changing the breakpoints might help with that, but there's no perfect solution, because there's a gap between "huge screen" and "smartphone" where reasonable people can disagree about whether it makes sense for the sidebar to be on-screen. https://github.com/rust-lang/rust/issues/97306
* Some people ask for ways to reduce on-screen clutter because it makes it easier to focus. There's not a media query for that (and if there was, privacy-conscious users would turn it off). https://github.com/rust-lang/rust/issues/59829
This feature is designed to avoid these problems. Resizing the sidebar especially helps, because it provides a way to hide the sidebar without adding a new top-level button (which would add clutter), and it provides a way to make rustdoc play nicer in complex, custom screen layouts.
## Guide and Reference-level explanation
On a desktop or laptop with a mouse, resize the sidebar by dragging its right edge.
On any browser, including mobile phones, the sticky top bar or side bar can be hidden from the Settings area (the button with the cog wheel, next to the search bar). When it's hidden, a convenient button will appear on the search bar's left.
## Drawbacks
This adds more JavaScript code to the render blocking area.
## Rationale and alternatives
The most obvious way to allow people to hide the sidebar would have been to let them "manually enter mobile mode." The upside is that it's a feature we already have. The downside is that it's actually really hard to come up with a terse description. Is it:
* A Setting that forces desktop viewers to always have the mobile-style top bar? If so, how do we label it? Should it be visible on mobile, and, if so, does it just not do anything?
* A persistent hide/show sidebar button, present on desktop, just like on mobile? That's clutter that I'd like to avoid.
## Prior art
* The new file browser in GitHub uses a similar divider with a mouse-over indicator
* mdBook and macOS Finder both allow you to resize the sidebar to nothing as a gesture to hide it
* https://www.nngroup.com/articles/drag-drop/
## Future possibilities
https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/Table.20of.20contents proposes a new, second sidebar (a table of contents). How should it fit in with this feature? Should it be resizeable? Hideable? Can it be accessed on mobile?
Don't merge cfg and doc(cfg) attributes for re-exports
Fixes#112881.
## Explanations
When re-exporting things with different `cfg`s there are two things that can happen:
* The re-export uses a subset of `cfg`s, this subset is sufficient so that the item will appear exactly with the subset
* The re-export uses a non-subset of `cfg`s (e.g. like the example I posted just above where the re-export is ungated), if the non-subset `cfg`s are active (e.g. compiling that example on windows) then this will be a compile error as the item doesn't exist to re-export, if the subset `cfg`s are active it behaves like 1.
### Glob re-exports?
**This only applies to non-glob inlined re-exports.** For glob re-exports the item may or may not exist to be re-exported (potentially the `cfg`s on the path up until the glob can be removed, and only `cfg`s on the globbed item itself matter), for non-inlined re-exports see https://github.com/rust-lang/rust/issues/85043.
cc `@Nemo157`
r? `@notriddle`
Opportunistically resolve region var in canonicalizer (instead of resolving root var)
See comment in `compiler/rustc_type_ir/src/infcx.rs`.
The **root** infer region for a given region vid may not actually be nameable from the universe of the original vid. That means that the assertion in the canonicalizer was too strict, since the `EagerResolver` that we use before canonicalizing is doing only as much resolving as it can.
This replaces `resolve_lt_var` and `probe_lt_var` in the `rustc_type_ir` API with `opportunistic_resolve_lt_var`, which acts as you expect it should. I left a FIXME that complains about the inconsistency.
This test is really gnarly, but I have no idea how to minimize it, since it seems to kind of just be coincidental that it triggered this issue. I hope the underlying root cause is easy enough to understand, though.
r? `@lcnr` or `@aliemjay`
Fixes#118950
Erase late bound regions from `Instance::fn_sig()` and add a few more details to StableMIR APIs
The Instance `fn_sig()` still included a late bound regions which needed a new compiler function in order to be erased. I've also bundled the following small fixes in this PR, let me know if you want me to isolate any of them.
- Add missing `CoroutineKind::AsyncGen`.
- Add optional spread argument to function body which is needed to properly analyze compiler shims.
- Add a utility method to iterate over all locals together with their declaration.
- Add a method to get the description of `AssertMessage`*.
* For the last one, we could consider eventually calling the internal `AssertKind::description()` to avoid code duplication. However, we still don't have ways to convert `AssertMessage`, `Operand`, `Place` and others, in order to use that. The other downside of using the internal method is that it will panic for some of the variants.
r ? `@ouz-a`
- Remove `fn_sig()` from Instance.
- Change return value of `AssertMessage::description` to `Cow<>`.
- Add assert to instance `ty()`.
- Generalize uint / int type creation.
Add all known `target_feature` configs to check-cfg
This PR adds all the known `target_feature` from ~~`rustc_codegen_ssa`~~ `rustc_target` to the well known list of check-cfg.
It does so by moving the list from `rustc_codegen_ssa` to `rustc_target` ~~`rustc_session` (I not sure about this, but some of the moved function take a `Session`)~~, then using it the `fill_well_known` function.
This already proved to be useful since portable-simd had a bad cfg.
cc `@nnethercote` (since we discussed it in https://github.com/rust-lang/rust/pull/118494)
Add -Zunpretty=stable-mir output test
As strongly suggested here https://github.com/rust-lang/rust/pull/118364#issuecomment-1827974148 this adds output test for `-Zunpretty=stable-mir`, added test shows almost all the functionality of the current printer.
r? `@compiler-errors`
fix dynamic size/align computation logic for packed types with dyn trait tail
This logic was never updated to support `packed(N)` where `N > 1`, and it turns out to be wrong for that case.
Fixes https://github.com/rust-lang/rust/issues/80925
`@bjorn3` I have not looked at cranelift; I assume it basically copied the size-of-val logic and hence could use much the same patch.
Enable stack probes on aarch64 for LLVM 18
I tested this on `aarch64-unknown-linux-gnu` with LLVM main (~18).
cc #77071, to be closed once we upgrade our LLVM submodule.
Tweak `short_ty_string` to reduce number of files
When shortening types and writing them to disk, make `short_ty_string` capable of reusing the same file, instead of writing a file per shortened type.
rustdoc-search: use set ops for ranking and filtering
This commit adds ranking and quick filtering to type-based search, improving performance and having it order results based on their type signatures.
Preview
-------
Profiler output: https://notriddle.com/rustdoc-html-demo-6/profile-8/index.html
Preview: https://notriddle.com/rustdoc-html-demo-6/ranking-and-filtering-v2/std/index.html
Motivation
----------
If I write a query like `str -> String`, a lot of functions come up. That's to be expected, but `String::from` should come up on top, and it doesn't right now. This is because the sorting algorithm is based on the functions name, and doesn't consider the type signature at all. `slice::join` even comes up above it!
To fix this, the sorting should take into account the function's signature, and the closer match should come up on top.
Guide-level description
-----------------------
When searching by type signature, types with a "closer" match will show up above types that match less precisely.
Reference-level explanation
---------------------------
Functions signature search works in three major phases:
* A compact "fingerprint," based on the [bloom filter] technique, is used to check for matches and to estimate the distance. It sometimes has false positive matches, but it also operates on 128 bit contiguous memory and requires no backtracking, so it performs a lot better than real unification.
The fingerprint represents the set of items in the type signature, but it does not represent nesting, and it ignores when the same item appears more than once.
The result is rejected if any query bits are absent in the function, or if the distance is higher than the current maximum and 200 results have already been found.
* The second step performs unification. This is where nesting and true bag semantics are taken into account, and it has no false positives. It uses a recursive, backtracking algorithm.
The result is rejected if any query elements are absent in the function.
[bloom filter]: https://en.wikipedia.org/wiki/Bloom_filter
Drawbacks
---------
This makes the code bigger.
More than that, this design is a subtle trade-off. It makes the cases I've tested against measurably faster, but it's not clear how well this extends to other crates with potentially more functions and fewer types.
The more complex things get, the more important it is to gather a good set of data to test with (this is arguably more important than the actual benchmarking ifrastructure right now).
Rationale and alternatives
--------------------------
Throwing a bloom filter in front makes it faster.
More than that, it tries to take a tactic where the system can not only check for potential matches, but also gets an accurate distance function without needing to do unification. That way it can skip unification even on items that have the needed elems, as long as they have more items than the currently found maximum.
If I didn't want to be able to cheaply do set operations on the fingerprint, a [cuckoo filter] is supposed to have better performance. But the nice bit-banging set intersection doesn't work AFAIK.
I also looked into [minhashing], but since it's actually an unbiased estimate of the similarity coefficient, I'm not sure how it could be used to skip unification (I wouldn't know if the estimate was too low or too high).
This function actually uses the number of distinct items as its "distance function." This should give the same results that it would have gotten from a Jaccard Distance $1-\frac{|F\cap{}Q|}{|F\cup{}Q|}$, while being cheaper to compute. This is because:
* The function $F$ must be a superset of the query $Q$, so their union is just $F$ and the intersection is $Q$ and it can be reduced to $1-\frac{|Q|}{|F|}.
* There are no magic thresholds. These values are only being used to compare against each other while sorting (and, if 200 results are found, to compare with the maximum match). This means we only care if one value is bigger than the other, not what it's actual value is, and since $Q$ is the same for everything, it can be safely left out, reducing the formula to $1-\frac{1}{|F|} = \frac{|F|}{|F|}-\frac{1}{|F|} = |F|-1$. And, since the values are only being compared with each other, $|F|$ is fine.
Prior art
---------
This is significantly different from how Hoogle does it.
It doesn't account for order, and it has no special account for nesting, though `Box<t>` is still two items, while `t` is only one.
This should give the same results that it would have gotten from a Jaccard Distance $1-\frac{|A\cap{}B|}{|A\cup{}B|}$, while being cheaper to compute.
Unresolved questions
--------------------
`[]` and `()`, the slice/array and tuple/union operators, are ignored while building the signature for the query. This is because they match more than one thing, making them ambiguous. Unfortunately, this also makes them a performance cliff. Is this likely to be a problem?
Right now, the system just stashes the type distance into the same field that levenshtein distance normally goes in. This means exact query matches show up on top (for example, if you have a function like `fn nothing(a: Nothing, b: i32)`, then searching for `nothing` will show it on top even if there's another function with `fn bar(x: Nothing)` that's technically a closer match in type signature.
Future possibilities
--------------------
It should be possible to adopt more sorting criteria to act as a tie breaker, which could be determined during unification.
[cuckoo filter]: https://en.wikipedia.org/wiki/Cuckoo_filter
[minhashing]: https://en.wikipedia.org/wiki/MinHash
Add more suggestions to unexpected cfg names and values
This pull request adds more suggestion to unexpected cfg names and values diagnostics:
- it first adds a links to the [rustc unstable book](https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html) or the [Cargo reference](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg), depending if rustc is invoked by Cargo
- it secondly adds a suggestion on how to expect the cfg name or value:
*excluding well known names and values*
- for Cargo: it suggest using a feature or `cargo:rust-check-cfg` in build script
- for rustc: it suggest using `--check-cfg` (with the correct invocation)
Those diagnostics improvements are directed towards enabling users to fix the issue if the previous suggestions weren't good enough.
r? `@petrochenkov`
This commit adds ranking and quick filtering to type-based search,
improving performance and having it order results based on their
type signatures.
Motivation
----------
If I write a query like `str -> String`, a lot of functions come up.
That's to be expected, but `String::from_str` should come up on top, and
it doesn't right now. This is because the sorting algorithm is based
on the functions name, and doesn't consider the type signature at all.
`slice::join` even comes up above it!
To fix this, the sorting should take into account the function's
signature, and the closer match should come up on top.
Guide-level description
-----------------------
When searching by type signature, types with a "closer" match will
show up above types that match less precisely.
Reference-level explanation
---------------------------
Functions signature search works in three major phases:
* A compact "fingerprint," based on the [bloom filter] technique, is used to
check for matches and to estimate the distance. It sometimes has false
positive matches, but it also operates on 128 bit contiguous memory and
requires no backtracking, so it performs a lot better than real
unification.
The fingerprint represents the set of items in the type signature, but it
does not represent nesting, and it ignores when the same item appears more
than once.
The result is rejected if any query bits are absent in the function, or
if the distance is higher than the current maximum and 200
results have already been found.
* The second step performs unification. This is where nesting and true bag
semantics are taken into account, and it has no false positives. It uses a
recursive, backtracking algorithm.
The result is rejected if any query elements are absent in the function.
[bloom filter]: https://en.wikipedia.org/wiki/Bloom_filter
Drawbacks
---------
This makes the code bigger.
More than that, this design is a subtle trade-off. It makes the cases I've
tested against measurably faster, but it's not clear how well this extends
to other crates with potentially more functions and fewer types.
The more complex things get, the more important it is to gather a good set
of data to test with (this is arguably more important than the actual
benchmarking ifrastructure right now).
Rationale and alternatives
--------------------------
Throwing a bloom filter in front makes it faster.
More than that, it tries to take a tactic where the system can not only check
for potential matches, but also gets an accurate distance function without
needing to do unification. That way it can skip unification even on items
that have the needed elems, as long as they have more items than the
currently found maximum.
If I didn't want to be able to cheaply do set operations on the fingerprint,
a [cuckoo filter] is supposed to have better performance.
But the nice bit-banging set intersection doesn't work AFAIK.
I also looked into [minhashing], but since it's actually an unbiased
estimate of the similarity coefficient, I'm not sure how it could be used
to skip unification (I wouldn't know if the estimate was too low or
too high).
This function actually uses the number of distinct items as its
"distance function."
This should give the same results that it would have gotten from a Jaccard
Distance $1-\frac{|F\cap{}Q|}{|F\cup{}Q|}$, while being cheaper to compute.
This is because:
* The function $F$ must be a superset of the query $Q$, so their union is
just $F$ and the intersection is $Q$ and it can be reduced to
$1-\frac{|Q|}{|F|}.
* There are no magic thresholds. These values are only being used to
compare against each other while sorting (and, if 200 results are found,
to compare with the maximum match). This means we only care if one value
is bigger than the other, not what it's actual value is, and since $Q$ is
the same for everything, it can be safely left out, reducing the formula
to $1-\frac{1}{|F|} = \frac{|F|}{|F|}-\frac{1}{|F|} = |F|-1$. And, since
the values are only being compared with each other, $|F|$ is fine.
Prior art
---------
This is significantly different from how Hoogle does it.
It doesn't account for order, and it has no special account for nesting,
though `Box<t>` is still two items, while `t` is only one.
This should give the same results that it would have gotten from a Jaccard
Distance $1-\frac{|A\cap{}B|}{|A\cup{}B|}$, while being cheaper to compute.
Unresolved questions
--------------------
`[]` and `()`, the slice/array and tuple/union operators, are ignored while
building the signature for the query. This is because they match more than
one thing, making them ambiguous. Unfortunately, this also makes them
a performance cliff. Is this likely to be a problem?
Right now, the system just stashes the type distance into the
same field that levenshtein distance normally goes in. This means exact
query matches show up on top (for example, if you have a function like
`fn nothing(a: Nothing, b: i32)`, then searching for `nothing` will show it
on top even if there's another function with `fn bar(x: Nothing)` that's
technically a closer match in type signature.
Future possibilities
--------------------
It should be possible to adopt more sorting criteria to act as a tie breaker,
which could be determined during unification.
[cuckoo filter]: https://en.wikipedia.org/wiki/Cuckoo_filter
[minhashing]: https://en.wikipedia.org/wiki/MinHash
Coroutine variant fields can be uninitialized
Wrap coroutine variant fields in MaybeUninit to indicate that they might be uninitialized. Otherwise an uninhabited field will make the entire variant uninhabited and introduce undefined behaviour.
The analogous issue in the prefix of coroutine layout was addressed by 6fae7f8071.
Support bare unit structs in destructuring assignments
We should be allowed to use destructuring assignments on *bare* unit structs, not just unit structs that are located within other pattern constructors.
Fixes#118753
r? petrochenkov since you reviewed #95380, reassign if you're busy or don't want to review this.