rustdoc-search: remove parallel searchWords array
This might have made sense if the algorithm could use `searchWords` to skip having to look at `searchIndex`, but since it always does a substring check on both the stock word and the normalizedName, it doesn't seem to help performance anyway.
Profile: http://notriddle.com/rustdoc-html-demo-8/searchwords/index.html
This might have made sense if the algorithm could use `searchWords`
to skip having to look at `searchIndex`, but since it always
does a substring check on both the stock word and the normalizedName,
it doesn't seem to help performance anyway.
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)
Currently, we assume that ScalarPair is always represented using
a two-element struct, both as an immediate value and when stored
in memory.
This currently works fairly well, but runs into problems with
https://github.com/rust-lang/rust/pull/116672, where a ScalarPair
involving an i128 type can no longer be represented as a two-element
struct in memory. For example, the tuple `(i32, i128)` needs to be
represented in-memory as `{ i32, [3 x i32], i128 }` to satisfy
alignment requirement. Using `{ i32, i128 }` instead will result in
the second element being stored at the wrong offset (prior to
LLVM 18).
Resolve this issue by no longer requiring that the immediate and
in-memory type for ScalarPair are the same. The in-memory type
will now look the same as for normal struct types (and will include
padding filler and similar), while the immediate type stays a
simple two-element struct type. This also means that booleans in
immediate ScalarPair are now represented as i1 rather than i8,
just like we do everywhere else.
The core change here is to llvm_type (which now treats ScalarPair
as a normal struct) and immediate_llvm_type (which returns the
two-element struct that llvm_type used to produce). The rest is
fixing things up to no longer assume these are the same. In
particular, this switches places that try to get pointers to the
ScalarPair elements to use byte-geps instead of struct-geps.
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`
Add inline const and other possible curly brace expressions to expr_trailing_brace
Add tests for `}` before `else` in `let...else` error
Change to explicit cases for expressions with optional values when being checked for trailing braces
Add tests for more complex cases of `}` before `else` in `let..else` statement
Move other possible `}` cases into separate arm and add FIXME for future reference
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.
codegen: panic when trying to compute size/align of extern type
The alignment is also computed when accessing a field of extern type at non-zero offset, so we also panic in that case.
Previously `size_of_val` worked because the code path there assumed that "thin pointer" means "sized". But that's not true any more with extern types. The returned size and align are just blatantly wrong, so it seems better to panic than returning wrong results. We use a non-unwinding panic since code probably does not expect size_of_val to panic.
[`RFC 3086`] Attempt to try to resolve blocking concerns
Implements what is described at https://github.com/rust-lang/rust/issues/83527#issuecomment-1744822345 to hopefully make some progress.
It is unknown if such approach is or isn't desired due to the lack of further feedback, as such, it is probably best to nominate this PR to the official entities.
`@rustbot` labels +I-compiler-nominated
Actually parse async gen blocks correctly
1. I got the control flow in `parse_expr_bottom` messed up, and obviously forgot a test for `async gen`, so we weren't actually ever parsing it correctly.
2. I forgot to gate the span for `async gen {}`, so even if we did parse it, we wouldn't have correctly denied it in `cfg(FALSE)`.
r? eholk
Add rustX check to codeblock attributes lint
We discovered this issue [here](https://github.com/rust-lang/rust/pull/118802#discussion_r1421815943).
I assume that the issue will be present in other places outside of the compiler so it's worth adding a check for it.
First commit is just a small cleanup about variables creation which was a bit strange (at least more than necessary).
r? ```@notriddle```
Fix alignment passed down to LLVM for simd_masked_load
Follow up to #117953
The alignment for a masked load operation should be that of the element/lane, not the vector as a whole
It can produce miscompilations after the LLVM optimizer notices the higher alignment and promotes this to an unmasked, aligned load followed up by blend/select - https://rust.godbolt.org/z/KEeGbevbb
tests: CGU tests require build-pass, not check-pass (remove FIXME)
CGU tests require CGU code to be exercised. We can't merely do "cargo check" on these tests.
Part of #62277
Correctly gate the parsing of match arms without body
https://github.com/rust-lang/rust/pull/118527 accidentally allowed the following to parse on stable:
```rust
match Some(0) {
None => { foo(); }
#[cfg(FALSE)]
Some(_)
}
```
This fixes that oversight. The way I choose which error to emit is the best I could think of, I'm open if you know a better way.
r? `@petrochenkov` since you're the one who noticed
Improve an error involving attribute values.
Attribute values must be literals. The error you get when that doesn't hold is pretty bad, e.g.:
```
unexpected expression: 1 + 1
```
You also get the same error if the attribute value is a literal, but an invalid literal, e.g.:
```
unexpected expression: "foo"suffix
```
This commit does two things.
- Changes the error message to "attribute value must be a literal", which gives a better idea of what the problem is and how to fix it. It also no longer prints the invalid expression, because the carets below highlight it anyway.
- Separates the "not a literal" case from the "invalid literal" case. Which means invalid literals now get the specific error at the literal level, rather than at the attribute level.
r? `@compiler-errors`
On borrow return type, suggest borrowing from arg or owned return type
When we encounter a function with a return type that has an anonymous lifetime with no argument to borrow from, besides suggesting the `'static` lifetime we now also suggest changing the arguments to be borrows or changing the return type to be an owned type.
```
error[E0106]: missing lifetime specifier
--> $DIR/variadic-ffi-6.rs:7:6
|
LL | ) -> &usize {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | ) -> &'static usize {
| +++++++
help: instead, you are more likely to want to change one of the arguments to be borrowed...
|
LL | x: &usize,
| +
help: ...or alternatively, to want to return an owned value
|
LL - ) -> &usize {
LL + ) -> usize {
|
```
Fix#85843.
dont ICE when ConstKind::Expr for is_const_evaluatable
The problem is that we are not handling ConstKind::Expr inside report_not_const_evaluatable_error
Fixes [#114151]
End locals' live range before suspending coroutine
State transforms retains storage statements for locals that are not
stored inside a coroutine. It ensures those locals are live when
resuming by inserting StorageLive as appropriate. It forgot to end the
storage of those locals when suspending, which is fixed here.
While the end of live range is implicit when executing return, it is
nevertheless useful for inliner which would otherwise extend the live
range beyond return.
Fixes#117733
Attribute values must be literals. The error you get when that doesn't
hold is pretty bad, e.g.:
```
unexpected expression: 1 + 1
```
You also get the same error if the attribute value is a literal, but an
invalid literal, e.g.:
```
unexpected expression: "foo"suffix
```
This commit does two things.
- Changes the error message to "attribute value must be a literal",
which gives a better idea of what the problem is and how to fix it. It
also no longer prints the invalid expression, because the carets below
highlight it anyway.
- Separates the "not a literal" case from the "invalid literal" case.
Which means invalid literals now get the specific error at the literal
level, rather than at the attribute level.
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.
State transforms retains storage statements for locals that are not
stored inside a coroutine. It ensures those locals are live when
resuming by inserting StorageLive as appropriate. It forgot to end the
storage of those locals when suspending, which is fixed here.
While the end of live range is implicit when executing return, it is
nevertheless useful for inliner which would otherwise extend the live
range beyond return.
`.debug_pubnames` and `.debug_pubtypes` are poorly designed and people
seldom use them. However, they take a considerable portion of size in
the final binary. This tells LLVM stop emitting those sections on
DWARFv4 or lower. DWARFv5 use `.debug_names` which is more concise
in size and performant for name lookup.
Do not parenthesize exterior struct lit inside match guards
Before this PR, the AST pretty-printer injects parentheses around expressions any time parens _could_ be needed depending on what else is in the code that surrounds that expression. But the pretty-printer did not pass around enough context to understand whether parentheses really _are_ needed on any particular expression. As a consequence, there are false positives where unneeded parentheses are being inserted.
Example:
```rust
#![feature(if_let_guard)]
macro_rules! pp {
($e:expr) => {
stringify!($e)
};
}
fn main() {
println!("{}", pp!(match () { () if let _ = Struct {} => {} }));
}
```
**Before:**
```console
match () { () if let _ = (Struct {}) => {} }
```
**After:**
```console
match () { () if let _ = Struct {} => {} }
```
This PR introduces a bit of state that is passed across various expression printing methods to help understand accurately whether particular situations require parentheses injected by the pretty printer, and it fixes one such false positive involving match guards as shown above.
There are other parenthesization false positive cases not fixed by this PR. I intend to address these in follow-up PRs. For example here is one: the expression `{ let _ = match x {} + 1; }` is pretty-printed as `{ let _ = (match x {}) + 1; }` despite there being no reason for parentheses to appear there.
Add lint against ambiguous wide pointer comparisons
This PR is the resolution of https://github.com/rust-lang/rust/issues/106447 decided in https://github.com/rust-lang/rust/issues/117717 by T-lang.
## `ambiguous_wide_pointer_comparisons`
*warn-by-default*
The `ambiguous_wide_pointer_comparisons` lint checks comparison of `*const/*mut ?Sized` as the operands.
### Example
```rust
let ab = (A, B);
let a = &ab.0 as *const dyn T;
let b = &ab.1 as *const dyn T;
let _ = a == b;
```
### Explanation
The comparison includes metadata which may not be expected.
-------
This PR also drops `clippy::vtable_address_comparisons` which is superseded by this one.
~~One thing: is the current naming right? `invalid` seems a bit too much.~~
Fixes https://github.com/rust-lang/rust/issues/117717
Remove edition umbrella features.
In the 2018 edition, there was an "umbrella" feature `#[feature(rust_2018_preview)]` which was used to enable several other features at once. This umbrella mechanism was not used in the 2021 edition and likely will not be used in 2024 either. During 2018 users reported that setting the feature was awkward, especially since they already needed to opt-in via the edition mechanism.
This PR removes this mechanism because I believe it will not be used (and will clean up and simplify the code). I believe that there are better ways to handle features and editions. In short:
- For highly experimental features, that may or may not be involved in an edition, they can implement regular feature gates like `tcx.features().my_feature`.
- For experimental features that *might* be involved in an edition, they should implement gates with `tcx.features().my_feature && span.at_least_rust_20xx()`. This requires the user to still specify `#![feature(my_feature)]`, to avoid disrupting testing of other edition features which are ready and have been accepted within the edition.
- For experimental features that have graduated to definitely be part of an edition, they should implement gates with `tcx.features().my_feature || span.at_least_rust_20xx()`, or just remove the feature check altogether and just check `span.at_least_rust_20xx()`.
- For relatively simple changes, they can skip the whole feature gating thing and just check `span.at_least_rust_20xx()`, and rely on the instability of the edition itself (which requires `-Zunstable-options`) to gate it.
I am working on documenting all of this in the rustc-dev-guide.
Implement repr(packed) for repr(simd)
This allows creating vectors with non-power-of-2 lengths that do not have padding. See rust-lang/portable-simd#319
Rearrange `default_configuration` and `CheckCfg::fill_well_known`.
There are comments saying these two functions should be kept in sync, but they have very different structures, process symbols in different orders, and there are some inconsistencies.
This commit reorders them so they're both mostly processing symbols in alphabetical order, which makes cross-checking them a lot easier. The commit also adds some macros to factor out repetitive code patterns.
The commit also moves the handling of `sym::test` out of `build_configuration` into `default_configuration`, where all the other symbols are handled.
r? `@bjorn3`
guarantee that char and u32 are ABI-compatible
In https://github.com/rust-lang/rust/pull/116894 we added a guarantee that `char` has the same alignment as `u32`, but there is still one axis where these types could differ: function call ABI. So let's nail that down as well: in a function signature, `char` and `u32` are completely equivalent.
This is a new stable guarantee, so it will need t-lang approval.
There are comments saying these two functions should be kept in sync,
but they have very different structures, process symbols in different
orders, and there are some inconsistencies.
This commit reorders them so they're both mostly processing symbols in
alphabetical order, which makes cross-checking them a lot easier. The
commit also adds some macros to factor out repetitive code patterns.
Plus it adds `sanitizer_cfi_normalize_{integers,pointers}` to
`fill_well_known`, which were missing.
The commit also moves the handling of `sym::test` out of
`build_configuration` into `default_configuration`, where all the other
symbols are handled.
This is an extension of the previous commit. It means the output of
something like this:
```
stringify!(let a: Vec<u32> = vec![];)
```
goes from this:
```
let a: Vec<u32> = vec![] ;
```
With this PR, it now produces this string:
```
let a: Vec<u32> = vec![];
```
`tokenstream::Spacing` appears on all `TokenTree::Token` instances,
both punct and non-punct. Its current usage:
- `Joint` means "can join with the next token *and* that token is a
punct".
- `Alone` means "cannot join with the next token *or* can join with the
next token but that token is not a punct".
The fact that `Alone` is used for two different cases is awkward.
This commit augments `tokenstream::Spacing` with a new variant
`JointHidden`, resulting in:
- `Joint` means "can join with the next token *and* that token is a
punct".
- `JointHidden` means "can join with the next token *and* that token is a
not a punct".
- `Alone` means "cannot join with the next token".
This *drastically* improves the output of `print_tts`. For example,
this:
```
stringify!(let a: Vec<u32> = vec![];)
```
currently produces this string:
```
let a : Vec < u32 > = vec! [] ;
```
With this PR, it now produces this string:
```
let a: Vec<u32> = vec![] ;
```
(The space after the `]` is because `TokenTree::Delimited` currently
doesn't have spacing information. The subsequent commit fixes this.)
The new `print_tts` doesn't replicate original code perfectly. E.g.
multiple space characters will be condensed into a single space
character. But it's much improved.
`print_tts` still produces the old, uglier output for code produced by
proc macros. Because we have to translate the generated code from
`proc_macro::Spacing` to the more expressive `token::Spacing`, which
results in too much `proc_macro::Along` usage and no
`proc_macro::JointHidden` usage. So `space_between` still exists and
is used by `print_tts` in conjunction with the `Spacing` field.
This change will also help with the removal of `Token::Interpolated`.
Currently interpolated tokens are pretty-printed nicely via AST pretty
printing. `Token::Interpolated` removal will mean they get printed with
`print_tts`. Without this change, that would result in much uglier
output for code produced by decl macro expansions. With this change, AST
pretty printing and `print_tts` produce similar results.
The commit also tweaks the comments on `proc_macro::Spacing`. In
particular, it refers to "compound tokens" rather than "multi-char
operators" because lifetimes aren't operators.
Implement `--env` compiler flag (without `tracked_env` support)
Part of https://github.com/rust-lang/rust/issues/80792.
Implementation of https://github.com/rust-lang/compiler-team/issues/653.
Not an implementation of https://github.com/rust-lang/rfcs/pull/2794.
It adds the `--env` compiler flag option which allows to set environment values used by `env!` and `option_env!`.
Important to note: When trying to retrieve an environment variable value, it will first look into the ones defined with `--env`, and if there isn't one, then only it will look into the environment variables. So if you use `--env PATH=a`, then `env!("PATH")` will return `"a"` and not the actual `PATH` value.
As mentioned in the title, `tracked_env` support is not added here. I'll do it in a follow-up PR.
r? rust-lang/compiler
remove redundant imports
detects redundant imports that can be eliminated.
for #117772 :
In order to facilitate review and modification, split the checking code and removing redundant imports code into two PR.
r? `@petrochenkov`
Don't print host effect param in pretty `path_generic_args`
Make `own_args_no_defaults` pass back the `GenericParamDef`, so that we can pass both the args *and* param definitions into `path_generic_args`. That allows us to use the `GenericParamDef` to filter out effect params.
This allows us to filter out the host param regardless of whether it's `sym::host` or `true`/`false`.
This also renames a couple of `const_effect_param` -> `host_effect_param`, and restores `~const` pretty printing to `TraitPredPrintModifiersAndPath`.
cc #118785
r? `@fee1-dead` cc `@oli-obk`
detects redundant imports that can be eliminated.
for #117772 :
In order to facilitate review and modification, split the checking code and
removing redundant imports code into two PR.
Rollup of 5 pull requests
Successful merges:
- #117966 (add safe compilation options)
- #118747 (Remove extra check cfg handled by libc directly)
- #118774 (add test for inductive cycle hangs)
- #118775 (chore: add test case for type with generic)
- #118782 (use `&` instead of start-process in x.ps1)
r? `@ghost`
`@rustbot` modify labels: rollup
Don't warn an empty pattern unreachable if we're not sure the data is valid
Exhaustiveness checking used to be naive about the possibility of a place containing invalid data. This could cause it to emit an "unreachable pattern" lint on an arm that was in fact reachable, as in https://github.com/rust-lang/rust/issues/117119.
This PR fixes that. We now track whether a place that is matched on may hold invalid data. This also forced me to be extra precise about how exhaustiveness manages empty types.
Note that this now errs in the opposite direction: the following arm is truly unreachable (because the binding causes a read of the value) but not linted as such. I'd rather not recommend writing a `match ... {}` that has the implicit side-effect of loading the value. [Never patterns](https://github.com/rust-lang/rust/issues/118155) will solve this cleanly.
```rust
match union.value {
_x => unreachable!(),
}
```
I recommend reviewing commit by commit. I went all-in on the test suite because this went through a lot of iterations and I kept everything. The bit I'm least confident in is `is_known_valid_scrutinee` in `check_match.rs`.
Fixes https://github.com/rust-lang/rust/issues/117119.
add test for inductive cycle hangs
the same pattern is already tested for coinductive cycles, but I now understand the underlying issue and want to make sure we also test it for inductive ones
r? `@compiler-errors`
Strengthen well known check-cfg names and values test
https://github.com/rust-lang/rust/pull/118494 is changing the implementation of how we expect well known check-cfg names and values, but we currently don't have a test that checks every well known only some of them.
This PR therefore strengthen our well known names/values test to include all of the configs to at least avoid unintended regressions and validate new entry.
*this PR also contains some drive-by consolidation of unexpected `target_os`, `target_arch` into a single file*
r? `@nnethercote` (maybe? feel free to re-assign)
Add more SIMD platform-intrinsics
- [x] simd_masked_load
- [x] LLVM codegen - llvm.masked.load
- [x] cranelift codegen - implemented but untested
- [ ] simd_masked_store
- [x] LLVM codegen - llvm.masked.store
- [ ] cranelift codegen
Also added a run-pass test to test both intrinsics, and additional build-fail & check-fail to cover validation for both intrinsics
as they unnecessarily clutter the diagnostic output and make the
experience of adding a new target to the compiler more painful than
it should be.
target_os and target_arch are still being tested in the
well-known-values.rs test, but in one place.
Make async generators fused by default
I actually changed my mind about this since the implementation PR landed. I think it's beneficial for `async gen` blocks to be "fused" by default -- i.e., for them to repeatedly return `Poll::Ready(None)` -- rather than panic.
We have [`FusedStream`](https://docs.rs/futures/latest/futures/stream/trait.FusedStream.html) in futures-rs to represent streams with this capability already anyways.
r? eholk
cc ```@rust-lang/wg-async,``` would like to know if anyone else has opinions about this.
coverage: Simplify the heuristic for ignoring `async fn` return spans
The code for extracting coverage spans from MIR has a special heuristic for dealing with `async fn`, so that the function's closing brace does not have a confusing double count.
The code implementing that heuristic is currently mixed in with the code for flushing remaining spans after the main refinement loop, making the refinement code harder to understand.
We can solve that by hoisting the heuristic to an earlier stage, after the spans have been extracted and sorted but before they have been processed by the refinement loop.
The coverage tests verify that the heuristic is still effective, so coverage mappings/reports for `async fn` have not changed.
---
This PR also has the side-effect of fixing the `None some_prev` panic that started appearing after #118525.
The old code assumed that `prev` would always be present after the refinement loop. That was only true if the list of collected spans was non-empty, but prior to #118525 that didn't seem to come up in practice. After that change, the list of collected spans could be empty in some specific circumstances, leading to panics.
The new code uses an `if let` to inspect `prev`, which correctly does nothing if there is no span present.
update target feature following LLVM API change
LLVM commit e817966718 renamed* the `unaligned-scalar-mem` target feature to `fast-unaligned-access`.
(*) technically the commit folded two previous features into one, but there are no references to the other one in rust.
Add tests related to normalization in implied bounds
Getting ```@aliemjay's``` tests from #109763, so we can better track what's going on in every different example.
r? ```@jackh726```
coverage: Use `SpanMarker` to improve coverage spans for `if !` expressions
Coverage instrumentation works by extracting source code spans from MIR. However, some kinds of syntax are effectively erased during MIR building, so their spans don't necessarily exist anywhere in MIR, making them invisible to the coverage instrumentor (unless we resort to various heuristics and hacks to recover them).
This PR introduces `CoverageKind::SpanMarker`, which is a new variant of `StatementKind::Coverage`. Its sole purpose is to represent spans that would otherwise not appear in MIR, so that the coverage instrumentor can extract them.
When coverage is enabled, the MIR builder can insert these dummy statements as needed, to improve the accuracy of spans used by coverage mappings.
Fixes#115468.
---
```@rustbot``` label +A-code-coverage
temporarily revert "ice on ambguity in mir typeck"
Reverts #116530 as a temporary measure to fix#117577. That issue should be ultimately fixed by checking WF of type annotations prior to normalization, which is implemented in #104098 but this PR is intended to be backported to beta.
r? ``@compiler-errors`` (the reviewer of the reverted PR)
recurse into refs when comparing tys for diagnostics
before:
![image](https://github.com/rust-lang/rust/assets/23638587/bf6abd62-c7f3-4c09-a47e-31b6e129de19)
after:
![image](https://github.com/rust-lang/rust/assets/23638587/b704d728-ddba-4204-aebe-c07dcbbcb55c)
this diff from the test suite is also quite nice imo:
```diff
`@@` -4,8 +4,8 `@@` error[E0308]: mismatched types
LL | debug_assert_eq!(iter.next(), Some(value));
| ^^^^^^^^^^^ expected `Option<<I as Iterator>::Item>`, found `Option<&<I as Iterator>::Item>`
|
- = note: expected enum `Option<<I as Iterator>::Item>`
- found enum `Option<&<I as Iterator>::Item>`
+ = note: expected enum `Option<_>`
+ found enum `Option<&_>`
```
privacy: visit trait def id of projections
Fixes#117997.
A refactoring in #117076 changed the `DefIdVisitorSkeleton` to avoid calling `visit_projection_ty` for `ty::Projection` aliases, and instead just iterate over the args - this makes sense, as `visit_projection_ty` will indirectly visit all of the same args, but in doing so, will also create a `TraitRef` containing the trait's `DefId`, which also gets visited. The trait's `DefId` isn't visited when we only visit the arguments without separating them into `TraitRef` and own args first.
Eventually this influences the reachability set and whether a function is encoded into the metadata.
Add instance evaluation and methods to read an allocation in StableMIR
The instance evaluation is needed to handle intrinsics such as `type_id` and `type_name`.
Since we now use Allocation to represent all evaluated constants, provide a few methods to help process the data inside an allocation.
I've also started to add a structured way to get information about the compilation target machine. For now, I've only added information needed to process an allocation.
r? ``````@ouz-a``````
according to a poll of gay people in my phone, purple is the most popular color to use for highlighting
| color | percentage |
| ---------- | ---------- |
| bold white | 6% |
| blue | 14% |
| cyan | 26% |
| purple | 37% |
| magenta | 17% |
unfortunately, purple is not supported by 16-color terminals, which rustc apparently wants to support for some reason.
until we require support for full 256-color terms (e.g. by doing the same feature detection as we currently do for urls), we can't use it.
instead, i have collapsed the purple votes into magenta on the theory that they're close, and also because magenta is pretty.
Introduce support for `async gen` blocks
I'm delighted to demonstrate that `async gen` block are not very difficult to support. They're simply coroutines that yield `Poll<Option<T>>` and return `()`.
**This PR is WIP and in draft mode for now** -- I'm mostly putting it up to show folks that it's possible. This PR needs a lang-team experiment associated with it or possible an RFC, since I don't think it falls under the jurisdiction of the `gen` RFC that was recently authored by oli (https://github.com/rust-lang/rfcs/pull/3513, https://github.com/rust-lang/rust/issues/117078).
### Technical note on the pre-generator-transform yield type:
The reason that the underlying coroutines yield `Poll<Option<T>>` and not `Poll<T>` (which would make more sense, IMO, for the pre-transformed coroutine), is because the `TransformVisitor` that is used to turn coroutines into built-in state machine functions would have to destructure and reconstruct the latter into the former, which requires at least inserting a new basic block (for a `switchInt` terminator, to match on the `Poll` discriminant).
This does mean that the desugaring (at the `rustc_ast_lowering` level) of `async gen` blocks is a bit more involved. However, since we already need to intercept both `.await` and `yield` operators, I don't consider it much of a technical burden.
r? `@ghost`
never_patterns: Parse match arms with no body
Never patterns are meant to signal unreachable cases, and thus don't take bodies:
```rust
let ptr: *const Option<!> = ...;
match *ptr {
None => { foo(); }
Some(!),
}
```
This PR makes rustc accept the above, and enforces that an arm has a body xor is a never pattern. This affects parsing of match arms even with the feature off, so this is delicate. (Plus this is my first non-trivial change to the parser).
~~The last commit is optional; it introduces a bit of churn to allow the new suggestions to be machine-applicable. There may be a better solution? I'm not sure.~~ EDIT: I removed that commit
r? `@compiler-errors`
A refactoring in #117076 changed the `DefIdVisitorSkeleton` to avoid
calling `visit_projection_ty` for `ty::Projection` aliases, and instead
just iterate over the args - this makes sense, as `visit_projection_ty`
will indirectly visit all of the same args, but in doing so, will also
create a `TraitRef` containing the trait's `DefId`, which also gets
visited. The trait's `DefId` isn't visited when we only visit the
arguments without separating them into `TraitRef` and own args first.
Signed-off-by: David Wood <david@davidtw.co>
When MIR is built for an if-not expression, the `!` part of the condition
doesn't correspond to any MIR statement, so coverage instrumentation normally
can't see it.
We can fix that by deliberately injecting a dummy statement whose sole purpose
is to associate that span with its enclosing block.
Resolve associated item bindings by namespace
This is the 3rd commit split off from #118360 with tests reblessed (they no longer contain duplicated diags which were caused by 4c0addc80a) & slightly adapted (removed supertraits from a UI test, cc #118040).
> * Resolve all assoc item bindings (type, const, fn (feature `return_type_notation`)) by namespace instead of trying to resolve a type first (in the non-RTN case) and falling back to consts afterwards. This is consistent with RTN. E.g., for `Tr<K = {…}>` we now always try to look up assoc consts (this extends to supertrait bounds). This gets rid of assoc tys shadowing assoc consts in assoc item bindings which is undesirable & inconsistent (types and consts live in different namespaces after all)
> * Consolidate the resolution of assoc {ty, const} bindings and RTN (dedup, better diags for RTN)
> * Fix assoc consts being labeled as assoc *types* in several diagnostics
> * Make a bunch of diagnostics translatable
Fixes#112560 (error → pass).
As discussed
r? `@compiler-errors`
---
**Addendum**: What I call “associated item bindings” are commonly referred to as “type bindings” for historical reasons. Nowadays, “type bindings” include assoc type bindings, assoc const bindings and RTN (return type notation) which is why I prefer not to use this outdated term.
Rollup of 6 pull requests
Successful merges:
- #116420 (discard invalid spans in external blocks)
- #118686 (Only check principal trait ref for object safety)
- #118688 (Add method to get type of an Rvalue in StableMIR)
- #118707 (Ping GuillaumeGomez for changes in rustc_codegen_gcc)
- #118712 (targets: remove not-added {i386,i486}-unknown-linux-gnu)
- #118719 (CFI: Add char to CFI integer normalization)
Failed merges:
- #117586 (Uplift the (new solver) canonicalizer into `rustc_next_trait_solver`)
r? `@ghost`
`@rustbot` modify labels: rollup
discard invalid spans in external blocks
Fixes#116203
This PR has discarded the invalid `const_span`, thereby making the format more neat.
r? ``@Nilstrieb``
Avoid adding builtin functions to `symbols.o`
We found performance regressions in #113923. The problem seems to be that `--gc-sections` does not remove these symbols. I tested that lld removes these symbols, but ld and gold do not.
I found that `used` adds symbols to `symbols.o` at 3e202ead60/compiler/rustc_codegen_ssa/src/back/linker.rs (L1786-L1791).
The PR removes builtin functions.
Note that under LTO, ld still preserves these symbols. (lld will still remove them.)
The first commit also fixes#118559. But I think the second commit also makes sense.
compile-time evaluation: detect writes through immutable pointers
This has two motivations:
- it unblocks https://github.com/rust-lang/rust/pull/116745 (and therefore takes a big step towards `const_mut_refs` stabilization), because we can now detect if the memory that we find in `const` can be interned as "immutable"
- it would detect the UB that was uncovered in https://github.com/rust-lang/rust/pull/117905, which was caused by accidental stabilization of `copy` functions in `const` that can only be called with UB
When UB is detected, we emit a future-compat warn-by-default lint. This is not a breaking change, so completely in line with [the const-UB RFC](https://rust-lang.github.io/rfcs/3016-const-ub.html), meaning we don't need t-lang FCP here. I made the lint immediately show up for dependencies since it is nearly impossible to even trigger this lint without `const_mut_refs` -- the accidentally stabilized `copy` functions are the only way this can happen, so the crates that popped up in #117905 are the only causes of such UB (in the code that crater covers), and the three cases of UB that we know about have all been fixed in their respective crates already.
The way this is implemented is by making use of the fact that our interpreter is already generic over the notion of provenance. For CTFE we now use the new `CtfeProvenance` type which is conceptually an `AllocId` plus a boolean `immutable` flag (but packed for a more efficient representation). This means we can mark a pointer as immutable when it is created as a shared reference. The flag will be propagated to all pointers derived from this one. We can then check the immutable flag on each write to reject writes through immutable pointers.
I just hope perf works out.
Fix is_foreign_item for StableMIR instance
Change the implementation of `Instance::is_foreign_item` to directly query the compiler for the instance `def_id` instead of incorrectly relying on the conversion to `CrateItem`. I also added a method to check if the instance has body, since the function already existed and it just wasn't exposed via public APIs. This makes it much cheaper for the user to check if the instance has body.
## Background:
- In pull https://github.com/rust-lang/rust/pull/118524, I fixed the conversion from Instance to CrateItem to avoid the conversion if the instance didn't have a body available. This broke the `is_foreign_item`.
r? `@ouz-a`
Enforce `must_use` on associated types and RPITITs that have a must-use trait in bounds
Warn when an RPITIT or (un-normalized) associated type with a `#[must_use]` trait in its bounds is unused.
This is pending T-lang approval, since it changes the semantics of the `#[must_use]` attribute slightly, but I think it strictly catches more strange errors.
I could also limit this to just RPITITs, but that seems less useful.
Fixes#118444
tip for define macro name after `macro_rules!`
Fixes#118295
~Note that there are some bad case such as `macro_rules![]` or `macro_rules!()`. However, I think these are acceptable as they are likely to be seldom used (feel free to close this if you think its shortcomings outweigh its benefits)~
Edit: this problem was resolved by utilizing the `source_map.span_to_next_source`.
r? `@petrochenkov`
Use the glob binding in resolve_rustdoc_path process
Fixes#117920
Returning `None` seems enough.
I reproduces and tests this locally by `cargo +stage1 build`, but I cannot reproduce this ICE by putting [the following code](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=8b3ca8f4a7676eb90baf30437ba041a2) into `tests/ui/...` and then compiling it using `rustc +stage1 /path/to/test.rs` or `x.py test`:
```rust
#![crate_type = "lib"]
use super::Hasher;
/// [`Hasher`]
pub use core:#️⃣:*;
```
r? `@petrochenkov`
Change the implementation of `Instance::is_foreign_item` to directly
query the compiler for the instance `def_id` instead of incorrectly
relying on the conversion to `CrateItem`.
Background:
- In pull https://github.com/rust-lang/rust/pull/118524, I fixed the
conversion from Instance to CrateItem to avoid the conversion if the
instance didn't have a body available. This broke the `is_foreign_item`.
Add ADT variant infomation to StableMIR and finish implementing TyKind::internal()
Introduce a `VariantDef` type and a mechanism to retrieve the definition from an `AdtDef`.
The `VariantDef` representation itself is just a combination of `AdtDef` and `VariantIdx`, which allow us to retrieve further information of a variant. I don't think we need to cache extra information for now, and we can translate on an on demand manner. I am leaving the fields public today due to https://github.com/rust-lang/project-stable-mir/issues/56, but they shouldn't. For this PR, I've only added a method to retrieve the variant name, and its fields. I also added an implementation of `RustcInternal` that allow users to retrieve more information using Rust internal APIs.
I have also finished the implementation of `RustcInternal` for `TyKind` which fixes https://github.com/rust-lang/project-stable-mir/issues/46.
## Motivation
Both of these changes are needed in order to properly interpret things like projections. For example,
- The variant definition is used to find out which variant we are downcasting to.
- Being able to create `Ty` from `TyKind` helps for example processing each stage of a projection, like the code in `place.ty()`.
Provide context when `?` can't be called because of `Result<_, E>`
When a method chain ending in `?` causes an E0277 because the expression's `Result::Err` variant doesn't have a type that can be converted to the `Result<_, E>` type parameter in the return type, provide additional context of which parts of the chain can and can't support the `?` operator.
```
error[E0277]: `?` couldn't convert the error to `String`
--> $DIR/question-mark-result-err-mismatch.rs:27:25
|
LL | fn bar() -> Result<(), String> {
| ------------------ expected `String` because of this
LL | let x = foo();
| ----- this has type `Result<_, String>`
...
LL | .map_err(|_| ())?;
| ---------------^ the trait `From<()>` is not implemented for `String`
| |
| this can't be annotated with `?` because it has type `Result<_, ()>`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `From<T>`:
<String as From<char>>
<String as From<Box<str>>>
<String as From<Cow<'a, str>>>
<String as From<&str>>
<String as From<&mut str>>
<String as From<&String>>
= note: required for `Result<(), String>` to implement `FromResidual<Result<Infallible, ()>>`
```
Fix#72124.
Remove `#[rustc_host]`, use internal desugaring
Also removed a way for users to explicitly specify the host param since that isn't particularly useful. This should eliminate any pain with encoding attributes across crates and etc.
r? `@compiler-errors`
Added shadowed hint for overlapping associated types
Previously, when you tried to set an associated type that is shadowed by an associated type in a subtrait, like this:
```rust
trait A {
type X;
}
trait B: A {
type X; // note: this is legal
}
impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
fn clone(&self) -> Self {
todo!()
}
}
you got a confusing error message, that says nothing about the shadowing:
error[E0719]: the value of the associated type `X` (from trait `B`) is already specified
--> test.rs:9:34
|
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| --- ^^^ re-bound here
| |
| `X` bound here first
error[E0191]: the value of the associated type `X` (from trait `A`) must be specified
--> test.rs:9:27
|
2 | type X;
| ------ `X` defined here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| ^^^^^^^^^^^ help: specify the associated type: `B<X=Y, X=Y, X = Type>`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.
```
Now instead, the error shows that the associated type is shadowed, and suggests renaming as a potential fix.
```rust
error[E0719]: the value of the associated type `X` in trait `B` is already specified
--> test.rs:9:34
|
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| --- ^^^ re-bound here
| |
| `X` bound here first
error[E0191]: the value of the associated type `X` in `A` must be specified
--> test.rs:9:27
|
2 | type X;
| ------ `A::X` defined here
...
6 | type X; // note: this is legal
| ------ `A::X` shadowed here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| ^^^^^^^^^^^ associated type `X` must be specified
|
help: consider renaming this associated type
--> test.rs:2:5
|
2 | type X;
| ^^^^^^
help: consider renaming this associated type
--> test.rs:6:5
|
6 | type X; // note: this is legal
| ^^^^^^
```
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.
The rename help message is only emitted when the trait is local. This is true both for the supertrait as for the subtrait.
There might be cases where you can use the fully qualified path (for instance, in a where clause), but this PR currently does not deal with that.
fixes#100109
(continues from #117642, because I didn't know renaming the branch would close the PR)
Shadowing the associated type of a supertrait is allowed.
This however makes it impossible to set the associated type
of the supertrait in a dyn object.
This PR makes the error message for that case clearer, like
adding a note that shadowing is happening, as well as suggesting
renaming of one of the associated types.
r=petrochenckov
When a method chain ending in `?` causes an E0277 because the
expression's `Result::Err` variant doesn't have a type that can be
converted to the `Result<_, E>` type parameter in the return type,
provide additional context of which parts of the chain can and can't
support the `?` operator.
```
error[E0277]: `?` couldn't convert the error to `String`
--> $DIR/question-mark-result-err-mismatch.rs:28:25
|
LL | fn bar() -> Result<(), String> {
| ------------------ expected `String` because of this
LL | let x = foo();
| ----- this can be annotated with `?` because it has type `Result<String, String>`
LL | let one = x
LL | .map(|s| ())
| ----------- this can be annotated with `?` because it has type `Result<(), String>`
LL | .map_err(|_| ())?;
| ---------------^ the trait `From<()>` is not implemented for `String`
| |
| this can't be annotated with `?` because it has type `Result<(), ()>`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `From<T>`:
<String as From<char>>
<String as From<Box<str>>>
<String as From<Cow<'a, str>>>
<String as From<&str>>
<String as From<&mut str>>
<String as From<&String>>
= note: required for `Result<(), String>` to implement `FromResidual<Result<Infallible, ()>>`
```
Fix#72124.
`build_session` is passed an `EarlyErrorHandler` and then constructs a
`Handler`. But the `EarlyErrorHandler` is still used for some time after
that.
This commit changes `build_session` so it consumes the passed
`EarlyErrorHandler`, and also drops it as soon as the `Handler` is
built. As a result, `parse_cfg` and `parse_check_cfg` now take a
`Handler` instead of an `EarlyErrorHandler`.
Although, we would like to avoid crashes whenever
possible, and that's why I wanted to make this API fallible. It's
looking pretty hard to do proper validation.
I think many of our APIs will unfortunately depend on the user doing
the correct thing since at the MIR level we are working on,
we expect types to have been checked already.
Add `deeply_normalize_for_diagnostics`, use it in coherence
r? lcnr
Normalize trait refs used for coherence error reporting with `-Ztrait-solver=next-coherence`.
Two things:
1. I said before that we can't add this to `TyErrCtxt` because we compute `OverlapResult`s even if there are no diagnostics being emitted, e.g. for a reservation impl.
2. I didn't want to add this to an `InferCtxtExt` trait because I felt it was unnecessary. I don't particularly care about the API though.
Pretty print `Fn<(..., ...)>` trait refs with parentheses (almost) always
It's almost always better, at least in diagnostics, to print `Fn(i32, u32)` instead of `Fn<(i32, u32)>`.
Related to but doesn't fix#118225. That needs a separate fix.
Add support for making lib features internal
We have the notion of an "internal" lang feature: a feature that is never intended to be stabilized, and using which can cause ICEs and other issues without that being considered a bug.
This extends that idea to lib features as well. It is an alternative to https://github.com/rust-lang/rust/pull/115623: instead of using an attribute to declare lib features internal, we simply do this based on the name. Everything ending in `_internals` or `_internal` is considered internal.
Then we rename `core_intrinsics` to `core_intrinsics_internal`, which fixes https://github.com/rust-lang/rust/issues/115597.
Make the following API stable:
// in core::any
pub fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str
Const stability is not added because this relies on `type_name` which is also
not const. That has a blocking issue.
Fixes#66359
Add support for `gen fn`
This builds on #116447 to add support for `gen fn` functions. For the most part we follow the same approach as desugaring `async fn`, but replacing `Future` with `Iterator` and `async {}` with `gen {}` for the body.
The version implemented here uses the return type of a `gen fn` as the yield type. For example:
```rust
gen fn count_to_three() -> i32 {
yield 1;
yield 2;
yield 3;
}
```
In the future, I think we should experiment with a syntax like `gen fn count_to_three() yield i32 { ... }`, but that can go in another PR.
cc `@oli-obk` `@compiler-errors`
Remove the `precise_pointer_size_matching` feature gate
`usize` and `isize` are special for pattern matching because their range might depend on the platform. To make code portable across platforms, the following is never considered exhaustive:
```rust
let x: usize = ...;
match x {
0..=18446744073709551615 => {}
}
```
Because of how rust handles constants, this also unfortunately counts `0..=usize::MAX` as non-exhaustive. The [`precise_pointer_size_matching`](https://github.com/rust-lang/rust/issues/56354) feature gate was introduced both for this convenience and for the possibility that the lang team could decide to allow the above.
Since then, [half-open range patterns](https://github.com/rust-lang/rust/issues/67264) have been implemented, and since #116692 they correctly support `usize`/`isize`:
```rust
match 0usize { // exhaustive!
0..5 => {}
5.. => {}
}
```
I believe this subsumes all the use cases of the feature gate. Moreover no attempt has been made to stabilize it in the 5 years of its existence. I therefore propose we retire this feature gate.
Closes https://github.com/rust-lang/rust/issues/56354
Remove mention of rust to make the error message generic.
The deprecation notice is used when in crates as well. This applies to versions Rust or Crates.
Relates #118148
Tweak unclosed generics errors
Remove unnecessary span label for parse errors that already have a suggestion.
Provide structured suggestion to close generics in more cases.
The deprecation notice is used when in crates as well. This applies to versions Rust or Crates.
Fixes#118148
Signed-off-by: Harold Dost <h.dost@criteo.com>
Tweak `.clone()` suggestion to work in more cases
When going through auto-deref, the `<T as Clone>` impl sometimes needs to be specified for rustc to actually clone the value and not the reference.
```
error[E0507]: cannot move out of dereference of `S`
--> $DIR/needs-clone-through-deref.rs:15:18
|
LL | for _ in self.clone().into_iter() {}
| ^^^^^^^^^^^^ ----------- value moved due to this method call
| |
| move occurs because value has type `Vec<usize>`, which does not implement the `Copy` trait
|
note: `into_iter` takes ownership of the receiver `self`, which moves value
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
LL | for _ in <Vec<usize> as Clone>::clone(&self.clone()).into_iter() {}
| ++++++++++++++++++++++++++++++ +
```
When encountering a move error, look for implementations of `Clone` for the moved type. If there is one, check if all its obligations are met. If they are, we suggest cloning without caveats. If they aren't, we suggest cloning while mentioning the unmet obligations, potentially suggesting `#[derive(Clone)]` when appropriate.
```
error[E0507]: cannot move out of a shared reference
--> $DIR/suggest-clone-when-some-obligation-is-unmet.rs:20:28
|
LL | let mut copy: Vec<U> = map.clone().into_values().collect();
| ^^^^^^^^^^^ ------------- value moved due to this method call
| |
| move occurs because value has type `HashMap<T, U, Hash128_1>`, which does not implement the `Copy` trait
|
note: `HashMap::<K, V, S>::into_values` takes ownership of the receiver `self`, which moves value
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
help: you could `clone` the value and consume it, if the `Hash128_1: Clone` trait bound could be satisfied
|
LL | let mut copy: Vec<U> = <HashMap<T, U, Hash128_1> as Clone>::clone(&map.clone()).into_values().collect();
| ++++++++++++++++++++++++++++++++++++++++++++ +
help: consider annotating `Hash128_1` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | pub struct Hash128_1;
|
```
Fix#109429.
When encountering multiple mutable borrows, suggest cloning and adding
derive annotations as needed.
```
error[E0596]: cannot borrow `sm.x` as mutable, as it is behind a `&` reference
--> $DIR/accidentally-cloning-ref-borrow-error.rs:32:9
|
LL | foo(&mut sm.x);
| ^^^^^^^^^ `sm` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: `Str` doesn't implement `Clone`, so this call clones the reference `&Str`
--> $DIR/accidentally-cloning-ref-borrow-error.rs:31:21
|
LL | let mut sm = sr.clone();
| ^^^^^^^
help: consider annotating `Str` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | struct Str {
|
help: consider specifying this binding's type
|
LL | let mut sm: &mut Str = sr.clone();
| ++++++++++
```
Fix#34629. Fix#76643. Fix#91532.
Structured `use` suggestion on privacy error
When encoutering a privacy error on an item through a re-export that is accessible in an alternative path, provide a structured suggestion with that path.
```
error[E0603]: module import `mem` is private
--> $DIR/private-std-reexport-suggest-public.rs:4:14
|
LL | use foo::mem;
| ^^^ private module import
|
note: the module import `mem` is defined here...
--> $DIR/private-std-reexport-suggest-public.rs:8:9
|
LL | use std::mem;
| ^^^^^^^^
note: ...and refers to the module `mem` which is defined here
--> $SRC_DIR/std/src/lib.rs:LL:COL
|
= note: you could import this
help: import `mem` through the re-export
|
LL | use std::mem;
| ~~~~~~~~
```
Fix#42909.
When encoutering a privacy error on an item through a re-export that is
accessible in an alternative path, provide a structured suggestion with
that path.
```
error[E0603]: module import `mem` is private
--> $DIR/private-std-reexport-suggest-public.rs:4:14
|
LL | use foo::mem;
| ^^^ private module import
|
note: the module import `mem` is defined here...
--> $DIR/private-std-reexport-suggest-public.rs:8:9
|
LL | use std::mem;
| ^^^^^^^^
note: ...and refers to the module `mem` which is defined here
--> $SRC_DIR/std/src/lib.rs:LL:COL
|
= note: you could import this
help: import `mem` through the re-export
|
LL | use std::mem;
| ~~~~~~~~
```
Fix#42909.
When encountering multiple mutable borrows, suggest cloning and adding
derive annotations as needed.
```
error[E0596]: cannot borrow `sm.x` as mutable, as it is behind a `&` reference
--> $DIR/accidentally-cloning-ref-borrow-error.rs:32:9
|
LL | foo(&mut sm.x);
| ^^^^^^^^^ `sm` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: `Str` doesn't implement `Clone`, so this call clones the reference `&Str`
--> $DIR/accidentally-cloning-ref-borrow-error.rs:31:21
|
LL | let mut sm = sr.clone();
| ^^^^^^^
help: consider annotating `Str` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | struct Str {
|
help: consider specifying this binding's type
|
LL | let mut sm: &mut Str = sr.clone();
| ++++++++++
```
```
error[E0596]: cannot borrow `*inner` as mutable, as it is behind a `&` reference
--> $DIR/issue-91206.rs:14:5
|
LL | inner.clear();
| ^^^^^ `inner` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: you can `clone` the `Vec<usize>` value and consume it, but this might not be your desired behavior
--> $DIR/issue-91206.rs:11:17
|
LL | let inner = client.get_inner_ref();
| ^^^^^^^^^^^^^^^^^^^^^^
help: consider specifying this binding's type
|
LL | let inner: &mut Vec<usize> = client.get_inner_ref();
| +++++++++++++++++
```
When encountering a case where `let x: T = (val: &T).clone();` and
`T: !Clone`, already mention that the reference is being cloned. We now
also suggest `#[derive(Clone)]` not only on `T` but also on type
parameters to satisfy blanket implementations.
```
error[E0308]: mismatched types
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:17:39
|
LL | let mut x: HashSet<Day> = v.clone();
| ------------ ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>`
| |
| expected due to this
|
= note: expected struct `HashSet<Day>`
found reference `&HashSet<Day>`
note: `HashSet<Day>` does not implement `Clone`, so `&HashSet<Day>` was cloned instead
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:17:39
|
LL | let mut x: HashSet<Day> = v.clone();
| ^
= help: `Clone` is not implemented because the trait bound `Day: Clone` is not satisfied
help: consider annotating `Day` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | enum Day {
|
```
Case taken from # #41825.
When encountering a move error, look for implementations of `Clone` for
the moved type. If there is one, check if all its obligations are met.
If they are, we suggest cloning without caveats. If they aren't, we
suggest cloning while mentioning the unmet obligations, potentially
suggesting `#[derive(Clone)]` when appropriate.
```
error[E0507]: cannot move out of a shared reference
--> $DIR/suggest-clone-when-some-obligation-is-unmet.rs:20:28
|
LL | let mut copy: Vec<U> = map.clone().into_values().collect();
| ^^^^^^^^^^^ ------------- value moved due to this method call
| |
| move occurs because value has type `HashMap<T, U, Hash128_1>`, which does not implement the `Copy` trait
|
note: `HashMap::<K, V, S>::into_values` takes ownership of the receiver `self`, which moves value
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
help: you could `clone` the value and consume it, if the `Hash128_1: Clone` trait bound could be satisfied
|
LL | let mut copy: Vec<U> = <HashMap<T, U, Hash128_1> as Clone>::clone(&map.clone()).into_values().collect();
| ++++++++++++++++++++++++++++++++++++++++++++ +
help: consider annotating `Hash128_1` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | pub struct Hash128_1;
|
```
Fix#109429.
When going through auto-deref, the `<T as Clone>` impl sometimes needs
to be specified for rustc to actually clone the value and not the
reference.
```
error[E0507]: cannot move out of dereference of `S`
--> $DIR/needs-clone-through-deref.rs:15:18
|
LL | for _ in self.clone().into_iter() {}
| ^^^^^^^^^^^^ ----------- value moved due to this method call
| |
| move occurs because value has type `Vec<usize>`, which does not implement the `Copy` trait
|
note: `into_iter` takes ownership of the receiver `self`, which moves value
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
LL | for _ in <Vec<usize> as Clone>::clone(&self.clone()).into_iter() {}
| ++++++++++++++++++++++++++++++ +
```
CC #109429.
[rustdoc] Don't generate the "Fields" heading if there is no field displayed
Fixes https://github.com/rust-lang/rust/issues/118195.
If no field is displayed, we should not generate the `Fields` heading in enum struct variants.
r? ``@notriddle``
Restrict what symbols can be used in `#[diagnostic::on_unimplemented]` format strings
This commit restricts what symbols can be used in a format string for any option of the `diagnostic::on_unimplemented` attribute. We previously allowed all the ad-hoc options supported by the internal `#[rustc_on_unimplemented]` attribute. For the stable attribute we only want to support generic parameter names and `{Self}` as parameters. For any other parameter an warning is emitted and the parameter is replaced by the literal parameter string, so for example `{integer}` turns into `{integer}`. This follows the general design of attributes in the `#[diagnostic]` attribute namespace, that any syntax "error" is treated as warning and subsequently ignored.
r? `@compiler-errors`
This commit restricts what symbols can be used in a format string for
any option of the `diagnostic::on_unimplemented` attribute. We
previously allowed all the ad-hoc options supported by the internal
`#[rustc_on_unimplemented]` attribute. For the stable attribute we only
want to support generic parameter names and `{Self}` as parameters. For
any other parameter an warning is emitted and the parameter is replaced
by the literal parameter string, so for example `{integer}` turns into
`{integer}`. This follows the general design of attributes in the
`#[diagnostic]` attribute namespace, that any syntax "error" is treated
as warning and subsequently ignored.
Rollup of 3 pull requests
Successful merges:
- #117869 ([rustdoc] Add highlighting for comments in items declaration)
- #118525 (coverage: Skip spans that can't be un-expanded back to the function body)
- #118574 (rustc_session: Address all `rustc::potential_query_instability` lints)
r? `@ghost`
`@rustbot` modify labels: rollup
coverage: Skip spans that can't be un-expanded back to the function body
When we extract coverage spans from MIR, we try to "un-expand" them back to spans that are inside the function's body span.
In cases where that doesn't succeed, the current code just swaps in the entire body span instead. But that tends to result in coverage spans that are completely unrelated to the control flow of the affected code, so it's better to just discard those spans.
---
Extracted from #118305, since this is a general improvement that isn't specific to branch coverage.
---
`@rustbot` label +A-code-coverage
[rustdoc] Add highlighting for comments in items declaration
Fixes#117555.
So after the discussion in https://github.com/rust-lang/rust/pull/117643, the outcome was that having the comments in the item declaration at the same level (in term of color) as the rest of the code was actually a bit distracting and could be improved.
The current highlighting color for comments is "lighter" than the rest and I think it fits perfectly to improve the current situation. With this, we now have different "levels" which makes it easier to read and filter out what we want when reading the items declaration.
Here's a screenshot:
![image](https://github.com/rust-lang/rust/assets/3050060/dbd98029-e98b-4997-9a89-6b823eaac9a4)
r? `@notriddle`
Provide structured suggestion for type mismatch in loop
We currently provide only a `help` message, this PR introduces the last two structured suggestions instead:
```
error[E0308]: mismatched types
--> $DIR/issue-98982.rs:2:5
|
LL | fn foo() -> i32 {
| --- expected `i32` because of return type
LL | / for i in 0..0 {
LL | | return i;
LL | | }
| |_____^ expected `i32`, found `()`
|
note: the function expects a value to always be returned, but loops might run zero times
--> $DIR/issue-98982.rs:2:5
|
LL | for i in 0..0 {
| ^^^^^^^^^^^^^ this might have zero elements to iterate on
LL | return i;
| -------- if the loop doesn't execute, this value would never get returned
help: return a value for the case when the loop has zero elements to iterate on
|
LL ~ }
LL ~ /* `i32` value */
|
help: otherwise consider changing the return type to account for that possibility
|
LL ~ fn foo() -> Option<i32> {
LL | for i in 0..0 {
LL ~ return Some(i);
LL ~ }
LL ~ None
|
```
Fix#98982.
Report errors in jobserver inherited through environment variables
This pr attempts to catch situations, when jobserver exists, but is not being inherited.
r? `@petrochenkov`
Because a macro invocation can expand to a never pattern, we can't rule
out a `arm!(),` arm at parse time. Instead we detect that case at
expansion time, if the macro tries to output a pattern followed by `=>`.
When we extract coverage spans from MIR, we try to "un-expand" them back to
spans that are inside the function's body span.
In cases where that doesn't succeed, the current code just swaps in the entire
body span instead. But that tends to result in coverage spans that are
completely unrelated to the control flow of the affected code, so it's better
to just discard those spans.
move packed-struct tests into packed/ folder
We already have a bunch of other tests named `packed/packed-struct*`, no reason to have these two tests be separate.
Add more information to StableMIR Instance
Allow stable MIR users to retrieve an instance function signature, the index for a VTable instance and more information about its underlying definition.
These are needed to properly interpret function calls, either via VTable or direct calls. The `CrateDef` implementation will also allow users to emit diagnostic messages.
I also fixed a few issues that we had identified before with how we were retrieving body of things that may not have a body available.
Handle recursion limit for subtype and well-formed predicates
Adds a recursion limit check for subtype predicates and well-formed predicates.
`-Ztrait-solver=next` currently panics with unimplemented for these cases.
These cases are arguably bugs in the occurs check but:
- I could not find a simple way to fix the occurs check
- There should still be a recursion limit check to prevent hangs anyway.
closes#117151
r? types
Centralize live loans maintenance to fix scope differences due to liveness
As found in the recent [polonius crater run](https://github.com/rust-lang/rust/pull/117593#issuecomment-1801398892), NLLs and the location-insensitive polonius computed different scopes on some specific CFG shapes, e.g. the following.
![image](https://github.com/rust-lang/rust/assets/247183/c3649f5e-3058-454e-854e-1a6b336bdd5e)
I had missed that liveness data was pushed from different sources than just the liveness computation: there are a few places that do this -- and some of them may be unneeded or at the very least untested, as no tests changed when I tried removing some of them.
Here, `_6` is e.g. dead on entry to `bb2[0]` during `liveness::trace`, but its regions will be marked as live later during "constraint generation" (which I plan to refactor away and put in the liveness module soon). This should cause the inflowing loans to be marked live, but they were only computed in `liveness::trace`.
Therefore, this PR moves live loan maintenance to `LivenessValues`, so that the various places pushing liveness data will all also update live loans at the same time -- except for promoteds which I don't believe need them, and their liveness handling is already interesting/peculiar.
All the regressions I saw in the initial crater run were related to this kind of shapes, and this change did fix all of them on the [next run](https://github.com/rust-lang/rust/pull/117593#issuecomment-1826132145).
r? `@matthewjasper`
(This will conflict with #117880 but whichever lands first is fine by me, the end goal is the same for both)
Restore `#![no_builtins]` crates participation in LTO.
After #113716, we can make `#![no_builtins]` crates participate in LTO again.
`#![no_builtins]` with LTO does not result in undefined references to the error. I believe this type of issue won't happen again.
Fixes#72140. Fixes#112245. Fixes#110606. Fixes#105734. Fixes#96486. Fixes#108853. Fixes#108893. Fixes#78744. Fixes#91158. Fixes https://github.com/rust-lang/cargo/issues/10118. Fixes https://github.com/rust-lang/compiler-builtins/issues/347.
The `nightly-2023-07-20` version does not always reproduce problems due to changes in compiler-builtins, core, and user code. That's why this issue recurs and disappears.
Some issues were not tested due to the difficulty of reproducing them.
r? pnkfelix
cc `@bjorn3` `@japaric` `@alexcrichton` `@Amanieu`
Stabilize C string literals
RFC: https://rust-lang.github.io/rfcs/3348-c-str-literal.html
Tracking issue: https://github.com/rust-lang/rust/issues/105723
Documentation PR (reference manual): https://github.com/rust-lang/reference/pull/1423
# Stabilization report
Stabilizes C string and raw C string literals (`c"..."` and `cr#"..."#`), which are expressions of type [`&CStr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html). Both new literals require Rust edition 2021 or later.
```rust
const HELLO: &core::ffi::CStr = c"Hello, world!";
```
C strings may contain any byte other than `NUL` (`b'\x00'`), and their in-memory representation is guaranteed to end with `NUL`.
## Implementation
Originally implemented by PR https://github.com/rust-lang/rust/pull/108801, which was reverted due to unintentional changes to lexer behavior in Rust editions < 2021.
The current implementation landed in PR https://github.com/rust-lang/rust/pull/113476, which restricts C string literals to Rust edition >= 2021.
## Resolutions to open questions from the RFC
* Adding C character literals (`c'.'`) of type `c_char` is not part of this feature.
* Support for `c"..."` literals does not prevent `c'.'` literals from being added in the future.
* C string literals should not be blocked on making `&CStr` a thin pointer.
* It's possible to declare constant expressions of type `&'static CStr` in stable Rust (as of v1.59), so C string literals are not adding additional coupling on the internal representation of `CStr`.
* The unstable `concat_bytes!` macro should not accept `c"..."` literals.
* C strings have two equally valid `&[u8]` representations (with or without terminal `NUL`), so allowing them to be used in `concat_bytes!` would be ambiguous.
* Adding a type to represent C strings containing valid UTF-8 is not part of this feature.
* Support for a hypothetical `&Utf8CStr` may be explored in the future, should such a type be added to Rust.
generic_const_exprs: suggest to add the feature, not use it
Usually our missing feature messages look something like
```
= help: add `#![feature(inline_const)]` to the crate attributes to enable
```
However `generic_const_exprs` used a different verb. That's inconsistent and it also means playground won't add that nice hyperlink to add the feature automatically. So let's use the same verb as everywhere else.
rustdoc: `div.where` instead of fmt-newline class
This is about equally readable, a lot more terse, and stops special-casing functions and methods.
```console
$ du -hs doc-old/ doc-new/
671M doc-old/
670M doc-new/
```
Add `-Zfunction-return={keep,thunk-extern}` option
This is intended to be used for Linux kernel RETHUNK builds.
With this commit (optionally backported to Rust 1.73.0), plus a patched Linux kernel to pass the flag, I get a RETHUNK build with Rust enabled that is `objtool`-warning-free and is able to boot in QEMU and load a sample Rust kernel module.
Issue: https://github.com/rust-lang/rust/issues/116853.
On Fn arg mismatch for a fn path, suggest a closure
When encountering a fn call that has a path to another fn being passed in, where an `Fn` impl is expected, and the arguments differ, suggest wrapping the argument with a closure with the appropriate arguments.
The last `help` is new:
```
error[E0631]: type mismatch in function arguments
--> $DIR/E0631.rs:9:9
|
LL | fn f(_: u64) {}
| ------------ found signature defined here
...
LL | foo(f);
| --- ^ expected due to this
| |
| required by a bound introduced by this call
|
= note: expected function signature `fn(usize) -> _`
found function signature `fn(u64) -> _`
note: required by a bound in `foo`
--> $DIR/E0631.rs:3:11
|
LL | fn foo<F: Fn(usize)>(_: F) {}
| ^^^^^^^^^ required by this bound in `foo`
help: consider wrapping the function in a closure
|
LL | foo(|arg0: usize| f(/* u64 */));
| +++++++++++++ +++++++++++
```
This is intended to be used for Linux kernel RETHUNK builds.
With this commit (optionally backported to Rust 1.73.0), plus a
patched Linux kernel to pass the flag, I get a RETHUNK build with
Rust enabled that is `objtool`-warning-free and is able to boot in
QEMU and load a sample Rust kernel module.
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This is about equally readable, a lot more terse, and stops
special-casing functions and methods.
```console
$ du -hs doc-old/ doc-new/
671M doc-old/
670M doc-new/
```
Add thinlto support to codegen, assembly and coverage tests
Using `--emit=llvm-ir` with thinlto usually result in multiple IR files.
Resolve test case failure issue reported in #113923.
Tweak message on ADT with private fields building
When trying to create an inaccessible ADT due to private fields, handle the case when no fields were passed.
```
error: cannot construct `Foo` with struct literal syntax due to private fields
--> $DIR/issue-76077.rs:8:5
|
LL | foo::Foo {};
| ^^^^^^^^
|
= note: private field `you_cant_use_this_field` that was not provided
```
rustdoc-search: allow spaces around `::` in path query
This restriction made sense back when spaces separated function parameters, but now that they separate path components, there's no real ambiguity any more.
Additionally, the Rust language allows it.
The other two commits are misc code cleanup.
Fix `PartialEq` args when `#[const_trait]` is enabled
This is based off of your PR that enforces effects on all methods, so just see the last commits.
r? fee1-dead
When encountering a fn call that has a path to another fn being passed
in, where an `Fn` impl is expected, and the arguments differ, suggest
wrapping the argument with a closure with the appropriate arguments.
When trying to create an inaccessible ADT due to private fields, handle
the case when no fields were passed.
```
error: cannot construct `Foo` with struct literal syntax due to private fields
--> $DIR/issue-76077.rs:8:5
|
LL | foo::Foo {};
| ^^^^^^^^
|
= note: private field `you_cant_use_this_field` that was not provided
```
This restriction made sense back when spaces separated function
parameters, but now that they separate path components, there's
no real ambiguity any more.
Additionally, the Rust language allows it.