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,
| ~~~~~~~~~~~~~~
```
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.