Enable ConstGoto and SeparateConstSwitch passes by default
These 2 passes implement a limited form of jump-threading.
Filing this PR to see if enabling them would be lighter than https://github.com/rust-lang/rust/pull/107009.
Enable ScalarReplacementOfAggregates in optimized builds
Like MatchBranchSimplification, this pass is known to produce significant runtime improvements in Cranelift artifacts, and I believe based on the perf runs here that the primary effect of this pass is to empower MatchBranchSimplification. ScalarReplacementOfAggregates on its own has little effect on anything, but when this was rebased up to include https://github.com/rust-lang/rust/pull/112001 we started seeing significant and majority-positive results.
Based on the fact that we see most of the regressions in debug builds (https://github.com/rust-lang/rust/pull/112002#issuecomment-1566270144) and some rather significant ones in cycles and wall time, I'm only enabling this in optimized builds at the moment.
Preserve substs in opaques recorded in typeck results
This means that we now prepopulate MIR with opaques with the right substs.
The first commit is a hack that I think we discussed, having to do with `DefiningAnchor::Bubble` basically being equivalent to `DefiningAnchor::Error` in the new solver, so having to use `DefiningAnchor::Bind` instead, lol.
r? `@lcnr`
rustdoc: add interaction delays for tooltip popovers
Preview:
* [notable traits](http://notriddle.com/rustdoc-demo-html-3/delay-tooltip/testing/struct.Vec.html#method.iter)
* [panicking code block](http://notriddle.com/rustdoc-demo-html-3/delay-tooltip/testing/struct.Vec.html#indexing)
Designing a good hover microinteraction is a matter of guessing user intent from what are, literally, vague gestures. In this case, guessing if hovering in our out of the tooltip base is intentional or not.
To figure this out, a few different techniques are used:
* When the mouse pointer enters a tooltip anchor point, its hitbox is grown on the bottom, where the popover is/will appear. This was already there before this commit: search "hover tunnel" in rustdoc.css for the implementation.
* This commit adds a delay when the mouse pointer enters the base anchor, in case the mouse pointer was just passing through and the user didn't want to open it.
* This commit also adds a delay when the mouse pointer exits the tooltip's base anchor or its popover, before hiding it.
* A fade-out animation is layered onto the pointer exit delay to immediately inform the user that they successfully dismissed the popover, while still providing a way for them to cancel it if it was a mistake and they still wanted to interact with it.
* No animation is used for revealing it, because we don't want people to try to interact with an element while it's in the middle of fading in: either they're allowed to interact with it while it's fading in, meaning it can't serve as mistake- proofing for opening the popover, or they can't, but they might try and be frustrated.
See also:
* https://www.nngroup.com/articles/timing-exposing-content/
* https://www.nngroup.com/articles/tooltip-guidelines/
* https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown
Add a distinct `OperandValue::ZeroSized` variant for ZSTs
These tend to have special handling in a bunch of places anyway, so the variant helps remember that. And I think it's easier to grok than `Aggregate`s sometimes being `Immediates` (after all, I previously got that wrong and caused #109992). As a minor bonus, it means we don't need to generate poison LLVM values for ZSTs to pass around in `OperandValue::Immediate`s.
Inspired by https://github.com/rust-lang/rust/pull/110021#discussion_r1160486991, so
r? `@compiler-errors`
rustdoc: Fix LinkReplacer link matching
It currently just uses the first link with the same href which might not necessarily be the matching one.
This fixes replacements when there are several links to the same item but with different text (e.g. `[X] and [struct@X]`). It also fixes replacements in summaries since those use a links list with empty hrefs, so currently all links would always match the first link by href but then not match its text. This could also lead to a panic in the `original_lext[1..len() - 1]` part when the first link only has a single character, which is why the new code uses `.get(..)` instead.
Replace const eval limit by a lint and add an exponential backoff warning
The lint triggers at the first power of 2 that comes after 1 million function calls or traversed back-edges (takes less than a second on usual programs). After the first emission, an unsilenceable warning is repeated at every following power of 2 terminators, causing it to get reported less and less the longer the evaluation runs.
cc `@rust-lang/wg-const-eval`
fixes#93481closes#67217
These tend to have special handling in a bunch of places anyway, so the variant helps remember that. And I think it's easier to grok than non-Scalar Aggregates sometimes being `Immediates` (like I got wrong and caused 109992). As a minor bonus, it means we don't need to generate poison LLVM values for them to pass around in `OperandValue::Immediate`s.
Uplift `clippy::cast_ref_to_mut` lint
This PR aims at uplifting the `clippy::cast_ref_to_mut` lint into rustc.
## `cast_ref_to_mut`
(deny-by-default)
The `cast_ref_to_mut` lint checks for casts of `&T` to `&mut T` without using interior mutability.
### Example
```rust,compile_fail
fn x(r: &i32) {
unsafe {
*(r as *const i32 as *mut i32) += 1;
}
}
```
### Explanation
Casting `&T` to `&mut T` without interior mutability is undefined behavior, as it's a violation of Rust reference aliasing requirements.
-----
Mostly followed the instructions for uplifting a clippy lint described here: https://github.com/rust-lang/rust/pull/99696#pullrequestreview-1134072751
`@rustbot` label: +I-lang-nominated
r? compiler
-----
For Clippy:
changelog: Moves: Uplifted `clippy::cast_ref_to_mut` into rustc
linker: Report linker flavors incompatible with the current target
The linker flavor is checked for target compatibility even if linker is never used (e.g. we are producing a rlib).
If it causes trouble, we can move the check to `link.rs` so it will run if the linker (flavor) is actually used.
And also feature gate explicitly specifying linker flavors for tier 3 targets.
The next step is supporting all the internal linker flavors in user-visible interfaces (command line and json).
Only rewrite valtree-constants to patterns and keep other constants opaque
Now that we can reliably fall back to comparing constants with `PartialEq::eq` to the match scrutinee, we can
1. eagerly try to convert constants to valtrees
2. then deeply convert the valtree to a pattern
3. if the to-valtree conversion failed, create an "opaque constant" pattern.
This PR specifically avoids any behavioral changes or major cleanups. What we can now do as follow ups is
* move the two remaining call sites to `destructure_mir_constant` off that query
* make valtree to pattern conversion infallible
* this needs to be done after careful analysis of the effects. There may be user visible changes from that.
based on https://github.com/rust-lang/rust/pull/111768
Rollup of 5 pull requests
Successful merges:
- #111772 (Fix linkage for large binaries on mips64 platforms)
- #111975 (Stop normalizing so many different prefixes)
- #111979 (Respect CARGOFLAGS in bootstrap.py)
- #112089 (Add `--warnings warn` flag to `x.py`)
- #112103 (Bootstrap update to 1.71 beta)
r? `@ghost`
`@rustbot` modify labels: rollup
Stop normalizing so many different prefixes
Previously, we would normalize *all* of
- the absolute path to the repository checkout
- the /rustc/$sha for stage1 (if `remap-debuginfo` was enabled)
- the /rustc/$sha for download-rustc
- the sysroot for download-rustc
Now, we consistently only normalize /rustc/FAKE_PREFIX. Not only is this much simpler, but it also avoids ongoing maintenance for download-rustc and makes it much less likely that tests break by accident.
- Change `tests/ui/track-diagnostics/track6.rs` to use a relative path instead of an absolute one. I am not actually sure why `track_caller` works here, but it does seem to work 🤷
- Pass `-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX` to all suites, not just UI. In particular, mir-opt tests emit /rustc/ paths in their output.
r? ```@cjgillot``` since you reviewed https://github.com/rust-lang/rust/pull/110699 - this is the test that it doesn't regress :)
Fix linkage for large binaries on mips64 platforms
This pull request fixes the linkage for large binaries on mips64 platforms by enabling the `xgot` feature in LLVM.
It is well understood that the generated binary will gain a hefty performance penalty where the external symbol jumps now cost at least three instructions each.
Also, this pull request does not address the same issue on the mips32 counterparts (due to being unable to test the changes thoroughly).
Should fix#52108
move `super_relate_consts` hack to `normalize_param_env_or_error`
`super_relate_consts` has as hack in it to work around the fact that `normalize_param_env_or_error` is broken. When relating two constants we attempt to evaluate them (aka normalize them). This is not an issue in any way specific to const generics, type aliases also have the same issue as demonstrated in [this code](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=84b6d3956a2c852a04b60782476b56c9).
Since the hack in `super_relate_consts` only exists to make `normalize_param_env_or_error` emit less errors move it to `normalize_param_env_or_error`. This makes `super_relate_consts` act more like the normal plain structural equality its supposed to and should help ensure that the hack doesnt accidentally affect other situations.
r? `@compiler-errors`
Fix re-export of doc hidden item inside private item not displayed
This PR fixes this bug:
```rust
mod private_module {
#[doc(hidden)]
pub struct Public;
}
pub use crate::private_module::Public as Foo;
```
`pub use crate::private_module::Public as Foo;` should be visible in the generated doc (and not inlined!) but currently isn't. This PR fixes it.
r? `@notriddle`
offset_of: don't require type to be `Sized`
Fixes#112051
~~The RFC [explicitly forbids](https://rust-lang.github.io/rfcs/3308-offset_of.html#limitations) non-`Sized` types, but it looks like only the fields being recursed into were checked. The sized check also seemed to have been completely missing for tuples~~
change `BorrowKind::Unique` to be a mutating `PlaceContext`
fixes#112056
I believe that `BorrowKind::Unique` is a footgun in general, so I added a FIXME and opened https://github.com/rust-lang/rust/issues/112072. This is a bit too involved for this PR though.
refactor and cleanup the leak check, add it to new solver
ended up being a bit more involved than I wanted but is hopefully still easy enough to review as a single PR, can split it into separate ones otherwise.
this can be reviewed commit by commit:
a473d55cdb9284aa2b01282d1b529a2a4d26547b 31a686646534ca006d906ec757ece4e771d6f973 949039c107852a5e36361c08b62821a0613656f5 242917bf5170d9a723c6c8e23e9d9d0c2fa8dc9d ed2b25a7aa28be3184be9e3022c2796a30eaad87 are all pretty straightforward.
03dd83b4c3f4ff27558f5c8ab859bd9f83db1d04 makes it easier to refactor coherence in a later commit, see the commit description, cc `@oli-obk`
4fe311d807a77b6270f384e41689bf5d58f46aec I don't quite remember what we wanted to test here, this definitely doesn't test that the occurs check doesn't cause incorrect errors in coherence, also cc `@oli-obk` here. I may end up writing a new test for this myself later.
5c200d88a91b75bd0875b973150655bd581ef97a is the main refactor of the leak check, changing it to take the `outer_universe` instead of getting it from a snapshot. Using a snapshot requires us to be in a probe which we aren't in the new solver, it also just feels dirty as snapshots don't really have anything to do with universes.
with all of this cfc230d54188d9c7ed867a9a0d1f51be77b485f9 is now kind of trivial.
r? `@nikomatsakis`
Don't typecheck recovered method call from suggestion
Only make the use-dot-operator-to-call-method suggestion, but do not double down and use the recovered type to perform method call typechecking as it will produce confusing diagnostics relevant for the *fixed* code.
### Code Sample
```rust
struct Client;
impl Client {
fn post<T: std::ops::Add>(&self, _: T, _: T) {}
}
fn f() {
let c = Client;
post(c, ());
}
```
### Before This PR
```
error[[E0277]](https://doc.rust-lang.org/stable/error_codes/E0277.html): cannot add `()` to `()`
--> src/lib.rs:9:5
|
9 | post(c, ());
| ^^^^^^^^^^^ no implementation for `() + ()`
|
= help: the trait `Add` is not implemented for `()`
note: required by a bound in `Client::post`
--> src/lib.rs:4:16
|
4 | fn post<T: std::ops::Add>(&self, _: T, _: T) {}
| ^^^^^^^^^^^^^ required by this bound in `Client::post`
error[[E0061]](https://doc.rust-lang.org/stable/error_codes/E0061.html): this function takes 2 arguments but 1 argument was supplied
--> src/lib.rs:9:5
|
9 | post(c, ());
| ^^^^ an argument of type `()` is missing
|
note: method defined here
--> src/lib.rs:4:8
|
4 | fn post<T: std::ops::Add>(&self, _: T, _: T) {}
| ^^^^ ----- ---- ----
help: provide the argument
|
9 | post((), ())(c, ());
| ++++++++
error[[E0425]](https://doc.rust-lang.org/stable/error_codes/E0425.html): cannot find function `post` in this scope
--> src/lib.rs:9:5
|
9 | post(c, ());
| ^^^^ not found in this scope
|
help: use the `.` operator to call the method `post` on `&Client`
|
9 - post(c, ());
9 + c.post(());
|
Some errors have detailed explanations: E0061, E0277, E0425.
For more information about an error, try `rustc --explain E0061`.
```
### After This PR
```
error[E0425]: cannot find function `post` in this scope
--> tests/ui/typeck/issue-106929.rs:9:5
|
9 | post(c, ());
| ^^^^ not found in this scope
|
help: use the `.` operator to call the method `post` on `&Client`
|
9 - post(c, ());
9 + c.post(());
|
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.
```
Fixes#106929.
fix: dedup `static_candidates` before report
Fixes https://github.com/rust-lang/rust/issues/103646
`record_static_candidate` had been executed twice, resulting in the presence of two identical `CandidateSource::Trait(Cat)` in static_candidates. This PR aims to deduplication the `static_candidates` list, allowing it to execute `suggest_associated_call_syntax` properly.
Uplift `clippy::invalid_utf8_in_unchecked` lint
This PR aims at uplifting the `clippy::invalid_utf8_in_unchecked` lint into two lints.
## `invalid_from_utf8_unchecked`
(deny-by-default)
The `invalid_from_utf8_unchecked` lint checks for calls to `std::str::from_utf8_unchecked` and `std::str::from_utf8_unchecked_mut` with an invalid UTF-8 literal.
### Example
```rust
unsafe {
std::str::from_utf8_unchecked(b"cl\x82ippy");
}
```
### Explanation
Creating such a `str` would result in undefined behavior as per documentation for `std::str::from_utf8_unchecked` and `std::str::from_utf8_unchecked_mut`.
## `invalid_from_utf8`
(warn-by-default)
The `invalid_from_utf8` lint checks for calls to `std::str::from_utf8` and `std::str::from_utf8_mut` with an invalid UTF-8 literal.
### Example
```rust
std::str::from_utf8(b"ru\x82st");
```
### Explanation
Trying to create such a `str` would always return an error as per documentation for `std::str::from_utf8` and `std::str::from_utf8_mut`.
-----
Mostly followed the instructions for uplifting a clippy lint described here: https://github.com/rust-lang/rust/pull/99696#pullrequestreview-1134072751
````@rustbot```` label: +I-lang-nominated
r? compiler
-----
For Clippy:
changelog: Moves: Uplifted `clippy::invalid_utf8_in_unchecked` into rustc
we can otherwise assign a hidden type to the opaque which
causes ICE if we don't use `take_opaque_types` during
coherence. This is annoying so I didn't bother. Added a test
showing the behavior this prevents.
Optimize scalar and scalar pair representations loaded from ByRef in llvm
in https://github.com/rust-lang/rust/pull/105653 I noticed that we were generating suboptimal LLVM IR if we had a `ConstValue::ByRef` that could be represented by a `ScalarPair`. Before https://github.com/rust-lang/rust/pull/105653 this is probably rare, but after it, every slice will go down this suboptimal code path that requires LLVM to untangle a bunch of indirections and translate static allocations that are only used once to read a scalar pair from.
Only make the use-dot-operator-to-call-method suggestion, but do not
double down and use the recovered type to perform method call
typechecking as it will produce confusing diagnostics on the "fixed"
code.
`[T; N]::zip` is "eager" but most zips are mapped.
This causes poor optimization in generated code.
This is a fundamental design issue and "zip" is
"prime real estate" in terms of function names,
so let's free it up again.
Make `TrustedStep` require `Copy`
All the implementations of the trait already are `Copy`, and this seems to be enough to simplify the implementations enough to make the MIR inliner willing to inline basics like `Range::next`.
r? `@thomcc`
All the implementations of the trait already are `Copy`, and this seems to be enough to simplify the implementations enough to make the MIR inliner willing to inline basics like `Range::next`.
Add a test for issue 110457/incremental ICE with closures with the same span
Closes#110457
It's probably possible to minimize the test case more, considering that we now know the underlying reason for the ICE, but I didn't.
r? `@cjgillot`
Make `TyKind: Debug` have less verbose output
Current `TyKind: Debug` impl is basically unusable for debugging, its too verbose even for verbose debugging 🤣 This PR replaces the debug logic for `TyKind` with a more manual debug impl instead of a hand expanded derived impl. This should help make #107084 more reasonable to land since the output of `Ty: Debug` will be better.
This isn't a fully completed change to the `Debug` impl of `TyKind` as there's still logic from the derive macro for some variants. Some of the variants are also not consisten with the `-Zverbose` printing of `Ty`, ideally `-Zverbose` printing of `Ty` would also just defer to the debug impl instead of having lots of checks in pretty printing. I plan on fixing this in follow up PRs since it seems tricky to do in this one and its already a large PR 😅
Use `Cow` in `{D,Subd}iagnosticMessage`.
Each of `{D,Subd}iagnosticMessage::{Str,Eager}` has a comment:
```
// FIXME(davidtwco): can a `Cow<'static, str>` be used here?
```
This commit answers that question in the affirmative. It's not the most compelling change ever, but it might be worth merging.
This requires changing the `impl<'a> From<&'a str>` impls to `impl From<&'static str>`, which involves a bunch of knock-on changes that require/result in call sites being a little more precise about exactly what kind of string they use to create errors, and not just `&str`. This will result in fewer unnecessary allocations, though this will not have any notable perf effects given that these are error paths.
Note that I was lazy within Clippy, using `to_string` in a few places to preserve the existing string imprecision. I could have used `impl Into<{D,Subd}iagnosticMessage>` in various places as is done in the compiler, but that would have required changes to *many* call sites (mostly changing `&format("...")` to `format!("...")`) which didn't seem worthwhile.
r? `@WaffleLapkin`
Rollup of 5 pull requests
Successful merges:
- #112029 (Recover upon mistyped error on typo'd `const` in const param def)
- #112037 (Add details about `unsafe_op_in_unsafe_fn` to E0133)
- #112039 (compiler: update solaris/illumos to enable tsan support.)
- #112042 (Migrate GUI colors test to original CSS color format)
- #112045 (Followup to #111973)
r? `@ghost`
`@rustbot` modify labels: rollup
Recover upon mistyped error on typo'd `const` in const param def
And add machine-applicable fix for the typo'd `const` keyword.
### Before
```
error: expected one of `,`, `:`, `=`, or `>`, found `N`
--> src/lib.rs:1:18
|
1 | pub fn bar<Const N: u8>() {}
| ^ expected one of `,`, `:`, `=`, or `>`
```
### After This PR
```
error: `const` keyword was mistyped as `Const`
--> test.rs:1:8
|
1 | fn bar<Const N: u8>() {}
| ^^^^^
|
help: use the `const` keyword
|
1 | fn bar<const N: u8>() {}
| ~~~~~
```
Fixes#111941.
Inline derived `hash`
Because most of the other derived functions are inlined: `clone`, `default`, `eq`, `partial_cmp`, `cmp`. The exception is `fmt`, but it tends to not be on hot paths as much.
r? `@ghost`
Each of `{D,Subd}iagnosticMessage::{Str,Eager}` has a comment:
```
// FIXME(davidtwco): can a `Cow<'static, str>` be used here?
```
This commit answers that question in the affirmative. It's not the most
compelling change ever, but it might be worth merging.
This requires changing the `impl<'a> From<&'a str>` impls to `impl
From<&'static str>`, which involves a bunch of knock-on changes that
require/result in call sites being a little more precise about exactly
what kind of string they use to create errors, and not just `&str`. This
will result in fewer unnecessary allocations, though this will not have
any notable perf effects given that these are error paths.
Note that I was lazy within Clippy, using `to_string` in a few places to
preserve the existing string imprecision. I could have used `impl
Into<{D,Subd}iagnosticMessage>` in various places as is done in the
compiler, but that would have required changes to *many* call sites
(mostly changing `&format("...")` to `format!("...")`) which didn't seem
worthwhile.
MIR: opt-in normalization of `BasicBlock` and `Local` numbering
This doesn't matter at all for actual codegen, but after spending some time reading pre-codegen MIR, I was wishing I didn't have to jump around so much in reading post-inlining code.
So this add two passes that are off by default for every mir level, but can be enabled (`-Zmir-enable-passes=+ReorderBasicBlocks,+ReorderLocals`) for humans.
Don't check for misaligned raw pointer derefs inside Rvalue::AddressOf
From https://github.com/rust-lang/rust/pull/112026#issuecomment-1565686697:
rustc 1.70 (stable next week) added a Mir pass to add pointer alignment checks in debug mode. Adding these checks caused some crates to break, but that was expected, since they contain broken code (https://github.com/rust-lang/rust/issues/111487) for tracking that.
However, the checks added are slightly more aggressive than they should have been. Specifically, they also check the place in an `addr_of!` expression. Whether lack of alignment there is or isn't UB is unclear. This PR modifies the pass to not affect those cases.
I spot checked the crater regressions and the ones I saw were not the case that this PR is modifying. It still seems good to not land anything overaggressive though