This makes this step take ~25ms on my machine (M3 Max 64GB) for Zed repo instead of ~150ms. Additionally it takes down the time needed for a clean cargo build of ripgrep from ~6.1s to 5.9s.
This change is mostly relevant for crates with multiple large CGUs.
Implement `default_overrides_default_fields` lint
Detect when a manual `Default` implementation isn't using the existing default field values and suggest using `..` instead:
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:14:1
|
LL | / impl Default for A {
LL | | fn default() -> Self {
LL | | A {
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
= help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time
note: the lint level is defined here
--> $DIR/manual-default-impl-could-be-derived.rs:5:9
|
LL | #![deny(default_overrides_default_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
r? `@compiler-errors`
This is a simpler version of #134441, detecting the simpler case when a field with a default should have not been specified in the manual `Default::default()`, instead using `..` for it. It doesn't provide any suggestions, nor the checks for "equivalences" nor whether the value used in the imp being used would be suitable as a default field value.
Skip parenthesis around tuple struct field calls
The pretty-printer previously did not distinguish between named vs unnamed fields when printing a function call containing a struct field. It would print the call as `(self.fun)()` for a named field which is correct, and `(self.0)()` for an unnamed field which is redundant.
This PR changes function calls of tuple struct fields to print without parens.
**Before:**
```rust
struct Tuple(fn());
fn main() {
let tuple = Tuple(|| {});
(tuple.0)();
}
```
**After:**
```rust
struct Tuple(fn());
fn main() {
let tuple = Tuple(|| {});
tuple.0();
}
```
Skip parenthesis if `.` makes statement boundary unambiguous
There is a rule in the parser that statements and match-arms never end in front of a `.` or `?` token (except when the `.` is really `..` or `..=` or `...`). So some of the leading subexpressions that need parentheses inserted when followed by some other operator like `-` or `+`, do not need parentheses when followed by `.` or `?`.
Example:
```rust
fn main() {
loop {}.to_string() + "";
match () {
_ => loop {}.to_string() + "",
};
}
```
`-Zunpretty=expanded` before:
```console
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
fn main() {
(loop {}).to_string() + "";
match () { _ => (loop {}).to_string() + "", };
}
```
After:
```console
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
fn main() {
loop {}.to_string() + "";
match () { _ => loop {}.to_string() + "", };
}
```
Make `ty::Error` implement all auto traits
I have no idea what's up with the crashes test I fixed--I really don't want to look into it since it has to do something with borrowck and multiple layers of opaques. I think the underlying idea of allowing error types to implement all auto traits is justified though.
Fixes#134796Fixes#131050
r? lcnr
Add a compiler intrinsic to back `bigint_helper_methods`
cc https://github.com/rust-lang/rust/issues/85532
This adds a new `carrying_mul_add` intrinsic, to implement `wide_mul` and `carrying_mul`.
It has fallback MIR for all types -- including `u128`, which isn't currently supported on nightly -- so that it'll continue to work on all backends, including CTFE.
Then it's overridden in `cg_llvm` to use wider intermediate types, including `i256` for `u128::carrying_mul`.
Spruce up the docs of several queries related to the type/trait system and const eval
- Editorial
- Proper rustdoc summary/synopsis line by making use of extra paragraphs: Leads to better rendered output on module pages, in search result lists and overall, too
- Use rustdoc warning blocks for admonitions of the form "do not call / avoid calling this query directly"
- Use intra-doc links of the form ``[`Self::$query`]`` to cross-link queries. Indeed, such links are generally a bit brittle due to the existence of `TyCtxtFeed` which only contains a subset of queries. Therefore the docs of `feedable` queries cannot cross-link to non-`feedable` ones. I'd say it's fine to use intra-doc links despite the potential/unlikely occasional future breakage (if a query with the aforementioned characteristics becomes `feedable`). `Self::` is nicer than `TyCtxt::` (which would be more stable) since it accounts for other contexts like `TyCtxt{Feed,At,Ensure{,WithValue}}`
- Informative
- Generally add, flesh out and correct some doc comments
- Add *Panic* sections (to a few selected queries only). The lists of panics aren't necessarily exhaustive and focus on the more "obvious" or "important" panics.
- Where applicable add a paragraph calling attention to the relevant [`#[rustc_*]` TEST attribute](https://rustc-dev-guide.rust-lang.org/compiler-debugging.html#rustc_-test-attributes)
The one non-doc change (it's internal and not observable):
Be even more defensive in `query constness`'s impl (spiritual follow-up to #134122) (see self review comment).
Fixes#133494.
r\? **any**(compiler-errors, oli-obk)
ptr::copy: fix docs for the overlapping case
Fixes https://github.com/rust-lang/unsafe-code-guidelines/issues/549
As discussed in that issue, it doesn't make any sense for `copy` to read a byte via `src` after it was already written via `dst`. The entire point of this method is that is copies correctly even if they overlap, and that requires always reading any given location before writing it.
Cc `@rust-lang/opsem`
[macro_metavar_expr_concat] Fix#128346Fix#128346Fix#131393
The syntax is invalid in both issues so I guess that theoretically the compiler should have aborted early.
This PR tries to fix a local problem but let me know if there are better options.
cc `@petrochenkov` if you are interested
fix default-backtrace-ice test
when running `tests/ui/panics/default-backtrace-ice.rs locally it gave this error:
```
failures:
---- [ui] tests/ui/panics/default-backtrace-ice.rs stdout ----
Saved the actual stderr to "/home/jyn/src/rust3/build/x86_64-unknown-linux-gnu/test/ui/panics/default-backtrace-ice/default-backtrace-ice.stderr"
diff of stderr:
7
8 aborting due to `-Z treat-err-as-bug=1`
9 stack backtrace:
- (end_short_backtrace)
- (begin_short_backtrace)
- (end_short_backtrace)
- (begin_short_backtrace)
+ [... omitted 22 frames ...]
+
```
(note that you must *not* use --bless; we previously did not have an error annotation to verify it was a full backtrace instead of a short backtrace.)
this is a regression from setting RUST_BACKTRACE=1 by default in https://github.com/rust-lang/rust/pull/134743. we need to turn off the new behavior when running UI tests so that they reflect our dist compiler. normally that's done by checking `sess.unstable_opts.ui_testing`, but this happens extremely early in the compiler before we've expanded arg files. do an extremely simple hack that doesn't work in all cases - we don't need it to work in all cases, only when running UI tests.
cc https://github.com/rust-lang/rust/pull/129658#issuecomment-2561988081
r? `@jieyouxu`
when running `tests/ui/panics/default-backtrace-ice.rs locally it gave this error:
```
failures:
---- [ui] tests/ui/panics/default-backtrace-ice.rs stdout ----
Saved the actual stderr to "/home/jyn/src/rust3/build/x86_64-unknown-linux-gnu/test/ui/panics/default-backtrace-ice/default-backtrace-ice.stderr"
diff of stderr:
7
8 aborting due to `-Z treat-err-as-bug=1`
9 stack backtrace:
- (end_short_backtrace)
- (begin_short_backtrace)
- (end_short_backtrace)
- (begin_short_backtrace)
+ [... omitted 22 frames ...]
+
```
this is a regression from setting RUST_BACKTRACE=1 by default. we need to turn off the new behavior when running UI tests so that they reflect our dist compiler. normally that's done by checking `sess.unstable_opts.ui_testing`, but this happens extremely early in the compiler before we've expanded arg files. do an extremely simple hack that doesn't work in all cases - we don't need it to work in all cases, only when running UI tests.
Detect when a manual `Default` implementation isn't using the existing default field values and suggest using `..` instead:
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:14:1
|
LL | / impl Default for A {
LL | | fn default() -> Self {
LL | | A {
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
= help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time
note: the lint level is defined here
--> $DIR/manual-default-impl-could-be-derived.rs:5:9
|
LL | #![deny(default_overrides_default_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Without a standard library, we cannot unwind, so it should be
panic=abort by default.
Additionally, it does not have std because while it is
Linux, it cannot use libc, which std uses today for Linux.
Update `#[coverage(..)]` attribute error messages to match the current implementation
The allowed positions for `#[coverage(..)]` attributes were expanded by #126721, but the corresponding error messages were never updated to reflect the new behaviour.
Part of #134749.
Default to short backtraces for dev builds of rustc itself
A dev build almost certainly means that whoever's built the compiler has the opportunity to rerun it to collect a more complete trace. So we don't need to default to a complete trace; we should hide irrelevant details by default.
A dev build almost certainly means that whoever's built the compiler
has the opportunity to rerun it to collect a more complete trace. So
we don't need to default to a complete trace; we should hide irrelevant
details by default.
Correctly note item kind in `NonConstFunctionCall` error message
Don't just call everything a "`fn`". This is more consistent with the error message we give for conditionally-const items, which do note the item's def kind.
r? fmease, this is a prerequisite for making those `~const PartialEq` error messages better. Re-roll if you're busy or don't want to review this.
Begin to implement type system layer of unsafe binders
Mostly TODOs, but there's a lot of match arms that are basically just noops so I wanted to split these out before I put up the MIR lowering/projection part of this logic.
r? oli-obk
Tracking:
- https://github.com/rust-lang/rust/issues/130516
Use `#[derive(Default)]` instead of manual `impl` when possible
While working on #134175 I noticed a few manual `Default` `impl`s that could be `derive`d instead. These likely predate the existence of the `#[default]` attribute for `enum`s.
Revert stabilization of the `#[coverage(..)]` attribute
Due to a process mixup, the PR to stabilize the `#[coverage(..)]` attribute (#130766) was merged while there are still outstanding concerns. The default action in that situation is to revert, and the feature is not sufficiently urgent or uncontroversial to justify special treatment, so this PR reverts that stabilization.
---
- A key point that came up in offline discussions is that unlike most user-facing features, this one never had a proper RFC, so parts of the normal stabilization process that implicitly rely on an RFC break down in this case.
- As the implementor and de-facto owner of the feature in its current form, I would like to think that I made good choices in designing and implementing it, but I don't feel comfortable proceeding to stabilization without further scrutiny.
- There hasn't been a clear opportunity for T-compiler to weigh in or express concerns prior to stabilization.
- The stabilization PR cites a T-lang FCP that occurred in the tracking issue, but due to the messy design and implementation history (and lack of a clear RFC), it's unclear what that FCP approval actually represents in this case.
- At the very least, we should not proceed without a clear statement from T-lang or the relevant members about the team's stance on this feature, especially in light of the other concerns listed here.
- The existing user-facing documentation doesn't clearly reflect which parts of the feature are stable commitments, and which parts are subject to change. And there doesn't appear to be a clear consensus anywhere about where that line is actually drawn, or whether the chosen boundary is acceptable to the relevant teams and individuals.
- For example, the [stabilization report comment](https://github.com/rust-lang/rust/issues/84605#issuecomment-2166514660) mentions that some aspects are subject to change, but that text isn't consistent with my earlier comments, and there doesn't appear to have been any explicit discussion or approval process.
- [The current reference text](https://github.com/rust-lang/reference/blob/4dfaa4f/src/attributes/coverage-instrumentation.md) doesn't mention this distinction at all, and instead simply describes the current implementation behaviour.
- When the implementation was changed to its current form, the associated user-facing error messages were not updated, so they still refer to the attribute only being allowed on functions and closures.
- On its own, this might have been reasonable to fix-forward in the absence of other concerns, but the fact that it never came up earlier highlights the breakdown in process that has occurred here.
---
Apologies to everyone who was excited for this stabilization to land, but unfortunately it simply isn't ready yet.
cleanup `TypeVerifier`
We should merge it with the `TypeChecker` as we no longer bail in cases where it encounters an error since #111863.
It's quite inconsistent whether a check lives in the verifier or the `TypeChecker`, so this feels like a quite impactful cleanup. I expect that for this we may want to change the `TypeChecker` to also be a MIR visitor 🤔 this is non-trivial so I didn't fully do it in this PR.
Best reviewed commit by commit.
r? `@compiler-errors` feel free to reassign however
Rollup of 6 pull requests
Successful merges:
- #130289 (docs: Permissions.readonly() also ignores root user special permissions)
- #134583 (docs: `transmute<&mut T, &mut MaybeUninit<T>>` is unsound when exposed to safe code)
- #134611 (Align `{i686,x86_64}-win7-windows-msvc` to their parent targets)
- #134629 (compiletest: Allow using a specific debugger when running debuginfo tests)
- #134642 (Implement `PointerLike` for `isize`, `NonNull`, `Cell`, `UnsafeCell`, and `SyncUnsafeCell`.)
- #134660 (Fix spacing of markdown code block fences in compiler rustdoc)
r? `@ghost`
`@rustbot` modify labels: rollup
Fix spacing of markdown code block fences in compiler rustdoc
Two place have misaligned open and close ```` ``` ````.
I noticed these because one of them disrupted syntax highlighting in my editor for the rest of the file as I was working on a different change.
<p align="center"><img src="https://github.com/user-attachments/assets/5de21d08-c30c-4e9c-8587-e83b988b9db5" width="500"></p>
Align `{i686,x86_64}-win7-windows-msvc` to their parent targets
There were some changes to `{i686,x86_64}-pc-windows-msvc`, include them in the backward compatibility targets as well.
CC `@roblabla`
Use `PtrMetadata` instead of `Len` in slice drop shims
I tried to do a bigger change in #134297 which didn't work, so here's the part I really wanted: Removing another use of `Len`, in favour of `PtrMetadata`.
Split into two commits where the first just adds a test, so you can look at the second commit to see how the drop shim for an array changes with this PR.
Reusing the same reviewer from the last one:
r? BoxyUwU
coroutine_clone: add comments
I was very surprised to learn that coroutines can be cloned. This has non-trivial semantic consequences that I do not think have been considered. Lucky enough, it's still unstable. Let's add some comments and pointers so we hopefully become aware when a MIR opt actually is in conflict with this.
Cc `@rust-lang/wg-mir-opt`
Explain why a type is not eligible for `impl PointerLike`.
The rules were baffling when I ran in to them trying to add some impls (to `std`, not my own code, as it happens), so I made the compiler explain them to me.
The logic of the successful cases is unchanged, but I did rearrange it to reverse the order of the primitive and `Adt` cases; this makes producing the errors easier. I'm still not very familiar with `rustc` internals, so let me know if there's a better way to do any of this.
This also adds test coverage for which impls are accepted or rejected, which I didn't see any of already.
The PR template tells me I should consider mentioning a tracking issue, but there isn't one for `pointer_like_trait`, so I'll mention `dyn_star`: #102425
Use E0665 for missing `#[default]` on enum and update doc
The docs for E0665 when doing `#[derive(Default]` on an `enum` previously didn't mention `#[default]` at all, or made a distinction between unit variants, that can be annotated, and tuple or struct variants, which cannot.
E0665 was not being emitted, we now use it for the same error it belonged to before.
```
error[E0665]: `#[derive(Default)]` on enum with no `#[default]`
--> $DIR/macros-nonfatal-errors.rs:42:10
|
LL | #[derive(Default)]
| ^^^^^^^
LL | / enum NoDeclaredDefault {
LL | | Foo,
LL | | Bar,
LL | | }
| |_- this enum needs a unit variant marked with `#[default]`
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
help: make this unit variant default by placing `#[default]` on it
|
LL | #[default] Foo,
| ++++++++++
help: make this unit variant default by placing `#[default]` on it
|
LL | #[default] Bar,
| ++++++++++
```
update `rustc_index_macros` feature handling
It seems that cargo can't [conditionally propagate features](214587c89d/compiler/rustc_index/Cargo.toml (L20)) if they were enabled by default on the target crate, but disabled with `default-features = false` in the current/parent crate.
Fixes#118129
Foundations of location-sensitive polonius
I'd like to land the prototype I'm describing in the [polonius project goal](https://github.com/rust-lang/rust-project-goals/issues/118). It still is incomplete and naive and terrible but it's working "well enough" to consider landing.
I'd also like to make review easier by not opening a huge PR, but have a couple small-ish ones (the +/- line change summary of this PR looks big, but >80% is moving datalog to a single place).
This PR starts laying the foundation for that work:
- it refactors and collects 99% of the old datalog fact gen, which was spread around everywhere, into a single dedicated module. It's still present at 3 small places (one of which we should revert anyways) that are kinda deep within localized components and are not as easily extractable into the rest of fact gen, so it's fine for now.
- starts introducing the localized constraints, the building blocks of the naive way of implementing the location-sensitive analysis in-tree, which is roughly sketched out in https://smallcultfollowing.com/babysteps/blog/2023/09/22/polonius-part-1/ and https://smallcultfollowing.com/babysteps/blog/2023/09/29/polonius-part-2/ but with a different vibe than per-point environments described in these posts, just `r1@p: r2@q` constraints.
- sets up the skeleton of generating these localized constraints: converting NLL typeck constraints, and creating liveness constraints
- introduces the polonius dual to NLL MIR to help development and debugging. It doesn't do much currently but is a way to see these localized constraints: it's an NLL MIR dump + a dumb listing of the constraints, that can be dumped with `-Zdump-mir=polonius -Zpolonius=next`. Its current state is not intended to be a long-term thing, just for testing purposes -- I will replace its contents in the future with a different approach (an HTML+js file where we can more easily explore/filter/trace these constraints and loan reachability, have mermaid graphs of the usual graphviz dumps, etc).
I've started documenting the approach in this PR, I'll add more in the future. It's quite simple, and should be very clear when more constraints are introduced anyways.
r? `@matthewjasper`
Best reviewed per commit so that the datalog move is less bothersome to read, but if you'd prefer we separate that into a different PR, I can do that (and michael has offered to review these more mechanical changes if it'd help).
Use orphaned error code for the same error it belonged to before.
```
error[E0665]: `#[derive(Default)]` on enum with no `#[default]`
--> $DIR/macros-nonfatal-errors.rs:42:10
|
LL | #[derive(Default)]
| ^^^^^^^
LL | / enum NoDeclaredDefault {
LL | | Foo,
LL | | Bar,
LL | | }
| |_- this enum needs a unit variant marked with `#[default]`
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
help: make this unit variant default by placing `#[default]` on it
|
LL | #[default] Foo,
| ~~~~~~~~~~~~~~
help: make this unit variant default by placing `#[default]` on it
|
LL | #[default] Bar,
| ~~~~~~~~~~~~~~
```
Provide a fallback in `best_blame_constraint` when `find_constraint_paths_between_regions` doesn't have a result. This code is due a rework to avoid the letf-over `unwrap()`, but avoids the ICE caused by the repro.
Fix#133252.
handle member constraints directly in the mir type checker
cleaner, faster, easier to change going forward :> fixes#109654
r? `@oli-obk` `@compiler-errors`
Fix parenthesization of chained comparisons by pretty-printer
Example:
```rust
macro_rules! repro {
() => {
1 < 2
};
}
fn main() {
let _ = repro!() == false;
}
```
Previously `-Zunpretty=expanded` would pretty-print this syntactically invalid output: `fn main() { let _ = 1 < 2 == false; }`
```console
error: comparison operators cannot be chained
--> <anon>:8:23
|
8 | fn main() { let _ = 1 < 2 == false; }
| ^ ^^
|
help: parenthesize the comparison
|
8 | fn main() { let _ = (1 < 2) == false; }
| + +
```
With the fix, it will print `fn main() { let _ = (1 < 2) == false; }`.
Making `-Zunpretty=expanded` consistently produce syntactically valid Rust output is important because that is what makes it possible for `cargo expand` to format and perform filtering on the expanded code.
## Review notes
According to `rg '\.fixity\(\)' compiler/` the `fixity` function is called only 3 places:
- 13170cd787/compiler/rustc_ast_pretty/src/pprust/state/expr.rs (L283-L287)
- 13170cd787/compiler/rustc_hir_pretty/src/lib.rs (L1295-L1299)
- 13170cd787/compiler/rustc_parse/src/parser/expr.rs (L282-L289)
The 2 pretty printers definitely want to treat comparisons using `Fixity::None`. That's the whole bug being fixed. Meanwhile, the parser's `Fixity::None` codepath is previously unreachable as indicated by the comment, so as long as `Fixity::None` here behaves exactly the way that `Fixity::Left` used to behave, you can tell that this PR definitely does not constitute any behavior change for the parser.
My guess for why comparison operators were set to `Fixity::Left` instead of `Fixity::None` is that it's a very old workaround for giving a good chained comparisons diagnostic (like what I pasted above). Nowadays that is handled by a different dedicated codepath.
Detect missing `.` in method chain in `let` bindings and statements
On parse errors where an ident is found where one wasn't expected, see if the next elements might have been meant as method call or field access.
```
error: expected one of `.`, `;`, `?`, `else`, or an operator, found `map`
--> $DIR/missing-dot-on-statement-expression.rs:7:29
|
LL | let _ = [1, 2, 3].iter()map(|x| x);
| ^^^ expected one of `.`, `;`, `?`, `else`, or an operator
|
help: you might have meant to write a method call
|
LL | let _ = [1, 2, 3].iter().map(|x| x);
| +
```
The rules were baffling when I ran in to them trying to add some impls,
so I made the compiler explain them to me.
The logic of the successful cases is unchanged, but I did rearrange it
to reverse the order of the primitive and `Adt` cases; this makes
producing the errors easier.
On parse errors where an ident is found where one wasn't expected, see if the next elements might have been meant as method call or field access.
```
error: expected one of `.`, `;`, `?`, `else`, or an operator, found `map`
--> $DIR/missing-dot-on-statement-expression.rs:7:29
|
LL | let _ = [1, 2, 3].iter()map(|x| x);
| ^^^ expected one of `.`, `;`, `?`, `else`, or an operator
|
help: you might have meant to write a method call
|
LL | let _ = [1, 2, 3].iter().map(|x| x);
| +
```
Also lint on option of function pointer comparisons
This PR is the first part of #134536, ie. the linting on `Option<{fn ptr}>` in the `unpredictable_function_pointer_comparisons` lint, which isn't part of the lang nomination that the second part is going trough, and so should be able to be approved independently.
Related to https://github.com/rust-lang/rust/issues/134527
r? `@compiler-errors`
Restrict `#[non_exaustive]` on structs with default field values
Do not allow users to apply `#[non_exaustive]` to a struct when they have also used default field values.
Arbitrary self types v2: no deshadow pre feature.
The arbitrary self types v2 work introduces a check for shadowed methods, whereby a method in some "outer" smart pointer type may called in preference to a method in the inner referent. This is bad if the outer pointer adds a method later, as it may change behavior, so we ensure we error in this circumstance.
It was intended that this new shadowing detection system only comes into play for users who enable the `arbitrary_self_types` feature (or of course everyone later if it's stabilized). It was believed that the new deshadowing code couldn't be reached without building the custom smart pointers that `arbitrary_self_types` enables, and therefore there was no risk of this code impacting existing users.
However, it turns out that cunning use of `Pin::get_ref` can cause this type of shadowing error to be emitted now. This commit adds a test for this case.
As we want this test to pass without arbitrary_self_types, but fail with it, I've split it into two files (one with run-pass and one without). If there's a better way I can amend it.
Part of #44874
r? ```@wesleywiser```
Precedence improvements: closures and jumps
This PR fixes some cases where rustc's pretty printers would redundantly parenthesize expressions that didn't need it.
<table>
<tr><th>Before</th><th>After</th></tr>
<tr><td><code>return (|x: i32| x)</code></td><td><code>return |x: i32| x</code></td></tr>
<tr><td><code>(|| -> &mut () { std::process::abort() }).clone()</code></td><td><code>|| -> &mut () { std::process::abort() }.clone()</code></td></tr>
<tr><td><code>(continue) + 1</code></td><td><code>continue + 1</code></td></tr>
</table>
Tested by `echo "fn main() { let _ = $AFTER; }" | rustc -Zunpretty=expanded /dev/stdin`.
The pretty-printer aims to render the syntax tree as it actually exists in rustc, as faithfully as possible, in Rust syntax. It can insert parentheses where forced by Rust's grammar in order to preserve the meaning of a macro-generated syntax tree, for example in the case of `a * $rhs` where $rhs is `b + c`. But for any expression parsed from source code, without a macro involved, there should never be a reason for inserting additional parentheses not present in the original.
For closures and jumps (return, break, continue, yield, do yeet, become) the unneeded parentheses came from the precedence of some of these expressions being misidentified. In the same order as the table above:
- Jumps and closures are supposed to have equal precedence. The [Rust Reference](https://doc.rust-lang.org/1.83.0/reference/expressions.html#expression-precedence) says so, and in Syn they do. There is no Rust syntax that would require making a precedence distinction between jumps and closures. But in rustc these were previously 2 distinct levels with the closure being lower, hence the parentheses around a closure inside a jump (but not a jump inside a closure).
- When a closure is written with an explicit return type, the grammar [requires](https://doc.rust-lang.org/1.83.0/reference/expressions/closure-expr.html) that the closure body consists of exactly one block expression, not any other arbitrary expression as usual for closures. Parsing of the closure body does not continue after the block expression. So in `|| { 0 }.clone()` the clone is inside the closure body and applies to `{ 0 }`, whereas in `|| -> _ { 0 }.clone()` the clone is outside and applies to the closure as a whole.
- Continue never needs parentheses. It was previously marked as having the lowest possible precedence but it should have been the highest, next to paths and loops and function calls, not next to jumps.
unimplement `PointerLike` for trait objects
Values of type `dyn* PointerLike` or `dyn PointerLike` are not pointer-like so these types should not implement `PointerLike`.
After https://github.com/rust-lang/rust/pull/133226, `PointerLike` allows user implementations, so we can't just mark it with `#[rustc_deny_explicit_impl(implement_via_object = false)]`. Instead, this PR splits the `#[rustc_deny_explicit_impl(implement_via_object = ...)]` attribute into two separate attributes `#[rustc_deny_explicit_impl]` and `#[rustc_do_not_implement_via_object]` so that we opt out of the automatic `impl PointerLike for dyn PointerLike` and still allow user implementations.
For traits that are marked with `#[do_not_implement_via_object]` but not `#[rustc_deny_explicit_impl]` I've also made it possible to add a manual `impl Trait for dyn Trait`. There is no immediate need for this, but it was one line to implement and seems nice to have.
fixes https://github.com/rust-lang/rust/issues/134545
fixes https://github.com/rust-lang/rust/issues/134543
r? `@compiler-errors`
Remove some dead code around import library generation
This was missed when replacing the usage of LLVM for generating import libraries.
``@bors`` rollup
Reduce the amount of explicit FatalError.raise()
Instead use dcx.abort_if_error() or guar.raise_fatal() instead. These guarantee that an error actually happened previously and thus we don't silently abort.
This commit splits the `#[rustc_deny_explicit_impl(implement_via_object = ...)]` attribute
into two attributes `#[rustc_deny_explicit_impl]` and `#[rustc_do_not_implement_via_object]`.
This allows us to have special traits that can have user-defined impls but do not have the
automatic trait impl for trait objects (`impl Trait for dyn Trait`).
Instead use dcx.abort_if_error() or guar.raise_fatal() instead. These
guarantee that an error actually happened previously and thus we don't
silently abort.
coverage: Rename `basic_coverage_blocks` to just `graph`
During coverage instrumentation, this variable always holds the current function's coverage graph, which is a simplified view of its MIR control-flow graph. The new name is clearer in context, and also shorter.
---
This is purely a rename, so there is no functional change.
Improve dependency_format a bit
* Make `DependencyList` an `IndexVec` rather than emulating one using a `Vec` (which was off-by-one as LOCAL_CRATE was intentionally skipped)
* Update some comments for the fact that we now use `#[global_allocator]` rather than `extern crate alloc_system;`/`extern crate alloc_jemalloc;` for specifying which allocator to use. We still use a similar mechanism for the panic runtime, so refer to the panic runtime in those comments instead.
* An unrelated refactor to `create_and_enter_global_ctxt` I forgot to include in https://github.com/rust-lang/rust/pull/134302. This refactor is too small to be worth it's own PR.
Fix logical error with what text is considered whitespace.
There appears to be a logical issue around what counts as leading white-space. There is code which does a subtraction assuming that no errors will be reported inside the leading whitespace. However we compute the length of that whitespace with std::char::is_whitespace and not rustc_lexer::is_whitespace. The former will include a no-break space while later will excluded it. We can only safely make the assumption that no errors will be reported in whitespace if it is all "Rust Standard" whitespace. Indeed an error does occur in unicode whitespace if it contains a no-break space. In that case the subtraction will cause a ICE (for a compiler in debug mode) as described in https://github.com/rust-lang/rust/issues/132918.
The arbitrary self types v2 work introduces a check for shadowed
methods, whereby a method in some "outer" smart pointer type may called
in preference to a method in the inner referent. This is bad if the
outer pointer adds a method later, as it may change behavior, so we
ensure we error in this circumstance.
It was intended that this new shadowing detection system only comes into
play for users who enable the `arbitrary_self_types` feature (or of
course everyone later if it's stabilized). It was believed that the
new deshadowing code couldn't be reached without building the custom
smart pointers that `arbitrary_self_types` enables, and therefore there
was no risk of this code impacting existing users.
However, it turns out that cunning use of `Pin::get_ref` can cause
this type of shadowing error to be emitted now. This commit adds a test
for this case.
During coverage instrumentation, this variable always holds the coverage graph,
which is a simplified view of the MIR control-flow graph. The new name is
clearer in context, and also shorter.
Use `MixedBitSet`s in const qualif
These analyses' domains should be very homogeneous, having compressed bitmaps on huge cfgs should make a difference (and doesn’t have an impact on the smaller / regular cfgs in our benchmarks).
This is a >40% walltime reduction on [this stress test](https://github.com/Manishearth/icu4x_compile_sample) extracted from a real world ICU case, and a 10x or so max-rss reduction.
cc `@oli-obk` `@RalfJung`
Should help with (or fix) issue #134404.
Speed up `Parser::expected_tokens`
The constant pushing/clearing of `Parser::expected_tokens` during parsing is slow. This PR speeds it up greatly.
r? `@estebank`
Make sure we handle `backwards_incompatible_lint` drops appropriately in drop elaboration
In #131326, a new kind of scheduled drop (`drop_kind: DropKind::Value` + `backwards_incompatible_lint: true`) was added so that we could insert a new kind of no-op MIR statement (`backward incompatible drop`) for linting purposes.
These drops were intended to have *no side-effects*, but drop elaboration code forgot to handle these drops specially and they were handled otherwise as normal drops in most of the code. This ends up being **unsound** since we insert more than one drop call for some values, which means that `Drop::drop` could be called more than once.
This PR fixes this by splitting out the `DropKind::ForLint` and adjusting the code. I'm not totally certain if all of the places I've adjusted are either reachable or correct, but I'm pretty certain that it's *more* correct than it was previously.
cc `@dingxiangfei2009`
r? nikomatsakis
Fixes#134482
Remove a duplicated check that doesn't do anything anymore.
fixes#134005
This code didn't actually `lub` the type of the previous expressions, but just the current type over and over again. Changing it to using the actual expression type does not change anything either, so may as well remove the entire loop.
coverage: Store coverage source regions as `Span` until codegen (take 2)
This is an attempt to re-land #133418:
> Historically, coverage spans were converted into line/column coordinates during the MIR instrumentation pass.
> This PR moves that conversion step into codegen, so that coverage spans spend most of their time stored as Span instead.
> In addition to being conceptually nicer, this also reduces the size of coverage mappings in MIR, because Span is smaller than 4x u32.
That PR was reverted by #133608, because in some circumstances not covered by our test suite we were emitting coverage metadata that was causing `llvm-cov` to exit with an error (#133606).
---
The implementation here is *mostly* the same, but adapted for subsequent changes in the relevant code (e.g. #134163).
I believe that the changes in #134163 should be sufficient to prevent the problem that required the original PR to be reverted. But I haven't been able to reproduce the original breakage in a regression test, and the `llvm-cov` error message is extremely unhelpful, so I can't completely rule out the possibility of this breaking again.
r? jieyouxu (reviewer of the original PR)
Some destructor/drop related tweaks
Two random tweaks I got from investigating some stuff around drops in edition 2024:
1. Use the `TypingEnv` of the mir builder, rather than making it over again.
2. Rename the `id` field from `Scope` to `local_id`, to reflect that it's a local id, and remove the `item_local_id()` accessor which just returned the id field.
Forbid overwriting types in typeck
While trying to figure out some type setting logic in https://github.com/rust-lang/rust/pull/134248 I realized that we sometimes set a type twice. While hopefully that would have been the same type, we didn't ensure that at all and just silently accepted it. So now we reject setting it twice, unless errors are happening, then we don't care.
Best reviewed commit by commit.
No behaviour change is intended.
Variants::Single: do not use invalid VariantIdx for uninhabited enums
~~Stacked on top of https://github.com/rust-lang/rust/pull/133681, only the last commit is new.~~
Currently, `Variants::Single` for an empty enum contains a `VariantIdx` of 0; looking that up in the enum variant list will ICE. That's quite confusing. So let's fix that by adding a new `Variants::Empty` case for types that have 0 variants.
try-job: i686-msvc
cleanup region handling: add `LateParamRegionKind`
The second commit is to enable a split between `BoundRegionKind` and `LateParamRegionKind`, by avoiding `BoundRegionKind` where it isn't necessary.
The third comment then adds `LateParamRegionKind` to avoid having the same late-param region for separate bound regions. This fixes#124021.
r? `@compiler-errors`
In codegen, a used function with `FunctionCoverageInfo` but no mappings has
historically indicated a bug. However, that will no longer be the case after
moving some fallible span-processing steps into codegen.
Currently it relies on having the right integer for every variant, and
if you add a variant you need to adjust the integers for all subsequent
variants, which is a pain.
This commit introduces a match guard formulation that takes advantage of
the enum-to-integer conversion to avoid specifying the integer for each
variant. And it does this via a macro to avoid lots of boilerplate.
The parser pushes a `TokenType` to `Parser::expected_token_types` on
every call to the various `check`/`eat` methods, and clears it on every
call to `bump`. Some of those `TokenType` values are full tokens that
require cloning and dropping. This is a *lot* of work for something
that is only used in error messages and it accounts for a significant
fraction of parsing execution time.
This commit overhauls `TokenType` so that `Parser::expected_token_types`
can be implemented as a bitset. This requires changing `TokenType` to a
C-style parameterless enum, and adding `TokenTypeSet` which uses a
`u128` for the bits. (The new `TokenType` has 105 variants.)
The new types `ExpTokenPair` and `ExpKeywordPair` are now arguments to
the `check`/`eat` methods. This is for maximum speed. The elements in
the pairs are always statically known; e.g. a
`token::BinOp(token::Star)` is always paired with a `TokenType::Star`.
So we now compute `TokenType`s in advance and pass them in to
`check`/`eat` rather than the current approach of constructing them on
insertion into `expected_token_types`.
Values of these pair types can be produced by the new `exp!` macro,
which is used at every `check`/`eat` call site. The macro is for
convenience, allowing any pair to be generated from a single identifier.
The ident/keyword filtering in `expected_one_of_not_found` is no longer
necessary. It was there to account for some sloppiness in
`TokenKind`/`TokenType` comparisons.
The existing `TokenType` is moved to a new file `token_type.rs`, and all
its new infrastructure is added to that file. There is more boilerplate
code than I would like, but I can't see how to make it shorter.
This is a naming convention used in a handful of spots in the parser for
delimiters. It confused me when I first saw it a long time ago, and I've
never liked it. A web search says "Bra-ket notation" exists in linear
algebra but the terminology has zero prior use in a programming context,
as far as I can tell.
This commit changes it to `open`/`close`, which is consistent with the
rest of the compiler.