Rename `rustc_abi::Abi` to `BackendRepr`
Remove the confabulation of `rustc_abi::Abi` with what "ABI" actually means by renaming it to `BackendRepr`, and rename `Abi::Aggregate` to `BackendRepr::Memory`. The type never actually represented how things are passed, as that has to have `PassMode` considered, at minimum, but rather it just is how we represented some things to the backend. This conflation arose because LLVM, the primary backend at the time, would lower certain IR forms using certain ABIs. Even that only somewhat was true, as it broke down when one ventured significantly afield of what is described by the System V AMD64 ABI either by using different architectures, ABI-modifying IR annotations, the same architecture **with different ISA extensions enabled**, or other... unexpected delights.
Unfortunately both names are still somewhat of a misnomer right now, as people have written code for years based on this misunderstanding. Still, their original names are even moreso, and for better or worse, this backend code hasn't received as much maintenance as the rest of the compiler, lately. Actually arriving at a correct end-state will simply require us to disentangle a lot of code in order to fix, much of it pointlessly repeated in several places. Thus this is not an "actual fix", just a way to deflect further misunderstandings.
TypingMode: merge intercrate, reveal, and defining_opaque_types
This adds `TypingMode` and uses it in most places. We do not yet remove `Reveal` from `param_env`s. This and other future work as tracked in #132279 and via `FIXME`s.
Fetching the `TypingMode` of the `InferCtxt` asserts that the `TypingMode` agrees with `ParamEnv::reveal` to make sure we don't introduce any subtle bugs here. This will be unnecessary once `ParamEnv::reveal` no longer exists.
As the `TypingMode` is now a part of the query input, I've merged the coherence and non-coherence caches for the new solver. I've also enabled the local `infcx` cache during coherence by clearing the cache when forking it with a different `TypingMode`.
#### `TypingMode::from_param_env`
I am using this even in cases where I know that the `param_env` will always be `Reveal::UserFacing`. This is to make it easier to correctly refactor this code in the future, any time we use `Reveal::UserFacing` in a body while not defining its opaque types is incorrect and should use a `TypingMode` which only reveals opaques defined by that body instead, cc #124598
r? ``@compiler-errors``
Don't lint `irrefutable_let_patterns` on leading patterns if `else if` let-chains
fixes#128661
Is there any preference where the test goes? There looks to be several places it could fit.
The initial naming of "Abi" was an awful mistake, conveying wrong ideas
about how psABIs worked and even more about what the enum meant.
It was only meant to represent the way the value would be described to
a codegen backend as it was lowered to that intermediate representation.
It was never meant to mean anything about the actual psABI handling!
The conflation is because LLVM typically will associate a certain form
with a certain ABI, but even that does not hold when the special cases
that actually exist arise, plus the IR annotations that modify the ABI.
Reframe `rustc_abi::Abi` as the `BackendRepr` of the type, and rename
`BackendRepr::Aggregate` as `BackendRepr::Memory`. Unfortunately, due to
the persistent misunderstandings, this too is now incorrect:
- Scattered ABI-relevant code is entangled with BackendRepr
- We do not always pre-compute a correct BackendRepr that reflects how
we "actually" want this value to be handled, so we leave the backend
interface to also inject various special-cases here
- In some cases `BackendRepr::Memory` is a "real" aggregate, but in
others it is in fact using memory, and in some cases it is a scalar!
Our rustc-to-backend lowering code handles this sort of thing right now.
That will eventually be addressed by lifting duplicated lowering code
to either rustc_codegen_ssa or rustc_target as appropriate.
Taking a raw ref (`&raw (const|mut)`) of a deref of pointer (`*ptr`) is always safe
T-opsem decided in https://github.com/rust-lang/reference/pull/1387 that `*ptr` is only unsafe if the place is accessed. This means that taking a raw ref of a deref expr is always safe, since it doesn't constitute a read.
This also relaxes the `DEREF_NULLPTR` lint to stop warning in the case of raw ref of a deref'd nullptr, and updates its docs to reflect that change in the UB specification.
This does not change the behavior of `addr_of!((*ptr).field)`, since field projections still require the projection is in-bounds.
I'm on the fence whether this requires an FCP, since it's something that is guaranteed by the reference you could ostensibly call this a bugfix since we were counting truly safe operations as unsafe. Perhaps someone on opsem has a strong opinion? cc `@rust-lang/opsem`
"innermost", "outermost", "leftmost", and "rightmost" don't need hyphens
These are all standard dictionary words and don't require hyphenation.
-----
Encountered an instance of this in error messages and it bugged me, so I
figured I'd fix it across the entire codebase.
Implement edition 2024 match ergonomics restrictions
This implements the minimalest version of [match ergonomics for edition 2024](https://rust-lang.github.io/rfcs/3627-match-ergonomics-2024.html). This minimal version makes it an error to ever reset the default binding mode. The implemented proposal is described precisely [here](https://hackmd.io/zUqs2ISNQ0Wrnxsa9nhD0Q#RFC-3627-nano), where it is called "RFC 3627-nano".
Rules:
- Rule 1C: When the DBM (default binding mode) is not `move` (whether or not behind a reference), writing `mut`, `ref`, or `ref mut` on a binding is an error.
- Rule 2C: Reference patterns can only match against references in the scrutinee when the DBM is `move`.
This minimal version is forward-compatible with the main proposals for match ergonomics 2024: [RFC3627](https://rust-lang.github.io/rfcs/3627-match-ergonomics-2024.html) itself, the alternative [rule 4-early variant](https://rust-lang.github.io/rfcs/3627-match-ergonomics-2024.html), and [others](https://hackmd.io/zUqs2ISNQ0Wrnxsa9nhD0Q). The idea is to give us more time to iron out a final proposal.
This includes a migration lint that desugars any offending pattern into one that doesn't make use of match ergonomics. Such patterns have identical meaning across editions.
This PR insta-stabilizes the proposed behavior onto edition 2024.
r? `@ghost`
Tracking:
- https://github.com/rust-lang/rust/issues/123076
Retire the `unnamed_fields` feature for now
`#![feature(unnamed_fields)]` was implemented in part in #115131 and #115367, however work on that feature has (afaict) stalled and in the mean time there have been some concerns raised (e.g.[^1][^2]) about whether `unnamed_fields` is worthwhile to have in the language, especially in its current desugaring. Because it represents a compiler implementation burden including a new kind of anonymous ADT and additional complication to field selection, and is quite prone to bugs today, I'm choosing to remove the feature.
However, since I'm not one to really write a bunch of words, I'm specifically *not* going to de-RFC this feature. This PR essentially *rolls back* the state of this feature to "RFC accepted but not yet implemented"; however if anyone wants to formally unapprove the RFC from the t-lang side, then please be my guest. I'm just not totally willing to summarize the various language-facing reasons for why this feature is or is not worthwhile, since I'm coming from the compiler side mostly.
Fixes#117942Fixes#121161Fixes#121263Fixes#121299Fixes#121722Fixes#121799Fixes#126969Fixes#131041
Tracking:
* https://github.com/rust-lang/rust/issues/49804
[^1]: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Unnamed.20struct.2Funion.20fields
[^2]: https://github.com/rust-lang/rust/issues/49804#issuecomment-1972619108
`asm!()` is forced to be wrapped inside unsafe. If there's no special
treatment, the label blocks would also always be unsafe with no way
of opting out.
- fix for divergence
- fix error message
- fix another cranelift test
- fix some cranelift things
- don't set the NORETURN option for naked asm
- fix use of naked_asm! in doc comment
- fix use of naked_asm! in run-make test
- use `span_bug` in unreachable branch
Replace calls to `ty::Const::{try_}eval` in mir build/pattern analysis
We normalize consts in writeback: #130645. This means that consts are gonna be as normalized as they're ever gonna get in MIR building and pattern analysis. Therefore we can just use `try_to_target_usize` rather than calling `eval_target_usize`.
Regarding the `.expect` calls, I'm not totally certain whether they're correct given rigid unevaluated consts. But this PR shouldn't make *more* ICEs occur; we may have to squash these ICEs when mGCE comes around, tho 😺
Begin experimental support for pin reborrowing
This commit adds basic support for reborrowing `Pin` types in argument position. At the moment it only supports reborrowing `Pin<&mut T>` as `Pin<&mut T>` by inserting a call to `Pin::as_mut()`, and only in argument position (not as the receiver in a method call).
This PR makes the following example compile:
```rust
#![feature(pin_ergonomics)]
fn foo(_: Pin<&mut Foo>) {
}
fn bar(mut x: Pin<&mut Foo>) {
foo(x);
foo(x);
}
```
Previously, you would have had to write `bar` as:
```rust
fn bar(mut x: Pin<&mut Foo>) {
foo(x.as_mut());
foo(x);
}
```
Tracking:
- #130494
r? `@compiler-errors`
Generating a call to `as_mut()` let to more restrictive borrows than
what reborrowing usually gives us. Instead, we change the desugaring to
reborrow the pin internals directly which makes things more expressive.
Never patterns constitute a read for unsafety
This code is otherwise unsound if we don't emit an unsafety error here. Noticed when fixing #130528, but it's totally unrelated.
r? `@Nadrieril`
This commit adds basic support for reborrowing `Pin` types in argument
position. At the moment it only supports reborrowing `Pin<&mut T>` as
`Pin<&mut T>` by inserting a call to `Pin::as_mut()`, and only in
argument position (not as the receiver in a method call).
- Replace non-standard names like 's, 'p, 'rg, 'ck, 'parent, 'this, and
'me with vanilla 'a. These are cases where the original name isn't
really any more informative than 'a.
- Replace names like 'cx, 'mir, and 'body with vanilla 'a when the lifetime
applies to multiple fields and so the original lifetime name isn't
really accurate.
- Put 'tcx last in lifetime lists, and 'a before 'b.
Rescope temp lifetime in if-let into IfElse with migration lint
Tracking issue #124085
This PR shortens the temporary lifetime to cover only the pattern matching and consequent branch of a `if let`.
At the expression location, means that the lifetime is shortened from previously the deepest enclosing block or statement in Edition 2021. This warrants an Edition change.
Coming with the Edition change, this patch also implements an edition lint to warn about the change and a safe rewrite suggestion to preserve the 2021 semantics in most cases.
Related to #103108.
Related crater runs: https://github.com/rust-lang/rust/pull/129466.
Simplify some nested `if` statements
Applies some but not all instances of `clippy::collapsible_if`. Some ended up looking worse afterwards, though, so I left those out. Also applies instances of `clippy::collapsible_else_if`
Review with whitespace disabled please.
Use shorthand field initialization syntax more aggressively in the compiler
Caught these when cleaning up #129344 and decided to run clippy to find the rest
Use `bool` in favor of `Option<()>` for diagnostics
We originally only supported `Option<()>` for optional notes/labels, but we now support `bool`. Let's use that, since it usually leads to more readable code.
I'm not removing the support from the derive macro, though I guess we could error on it... 🤔
Rollup of 7 pull requests
Successful merges:
- #122884 (Optimize integer `pow` by removing the exit branch)
- #127857 (Allow to customize `// TODO:` comment for deprecated safe autofix)
- #129034 (Add `#[must_use]` attribute to `Coroutine` trait)
- #129049 (compiletest: Don't panic on unknown JSON-like output lines)
- #129050 (Emit a warning instead of an error if `--generate-link-to-definition` is used with other output formats than HTML)
- #129056 (Fix one usage of target triple in bootstrap)
- #129058 (Add mw back to review rotation)
r? `@ghost`
`@rustbot` modify labels: rollup
miri: make vtable addresses not globally unique
Miri currently gives vtables a unique global address. That's not actually matching reality though. So this PR enables Miri to generate different addresses for the same type-trait pair.
To avoid generating an unbounded number of `AllocId` (and consuming unbounded amounts of memory), we use the "salt" technique that we also already use for giving constants non-unique addresses: the cache is keyed on a "salt" value n top of the actually relevant key, and Miri picks a random salt (currently in the range `0..16`) each time it needs to choose an `AllocId` for one of these globals -- that means we'll get up to 16 different addresses for each vtable. The salt scheme is integrated into the global allocation deduplication logic in `tcx`, and also used for functions and string literals. (So this also fixes the problem that casting the same function to a fn ptr over and over will consume unbounded memory.)
r? `@saethlin`
Fixes https://github.com/rust-lang/miri/issues/3737
Use more slice patterns inside the compiler
Nothing super noteworthy. Just replacing the common 'fragile' pattern of "length check followed by indexing or unwrap" with slice patterns for legibility and 'robustness'.
r? ghost
match lowering: Hide `Candidate` from outside the lowering algorithm
The internals of `Candidate` are tricky and a source of confusion. This PR makes it so we don't expose `Candidate`s outside the lowering algorithm. Now:
- false edges are handled in `lower_match_tree`;
- `lower_match_tree` takes a list of patterns as input;
- `lower_match_tree` returns a flat datastructure that contains only the necessary information.
r? ```@matthewjasper```
Isolate the diagnostic code that expects `thir::Pat` to be printable
Currently, `thir::Pat` implements `fmt::Display` (and `IntoDiagArg`) directly, for use by a few diagnostics.
That makes it tricky to experiment with alternate representations for THIR patterns, because the patterns currently need to be printable on their own. That immediately rules out possibilities like storing subpatterns as a `PatId` index into a central list (instead of the current directly-owned `Box<Pat>`).
This PR therefore takes an incremental step away from that obstacle, by removing `thir::Pat` from diagnostic structs in `rustc_pattern_analysis`, and hiding the pattern-printing process behind a single public `Pat::to_string` method. Doing so makes it easier to identify and update the code that wants to print patterns, and gives a place to pass in additional context in the future if necessary.
---
I'm currently not sure whether switching over to `PatId` is actually desirable or not, but I think this change makes sense on its own merits, by reducing the coupling between `thir::Pat` and the pattern-analysis error types.
exhaustiveness: Explain why a given pattern is considered unreachable
This PR tells the user why a given pattern is considered unreachable. I reused the intersection information we were already computing; even though it's incomplete I convinced myself that it is sufficient to always get a set of patterns that cover the unreachable one.
I'm not a fan of the diagnostic messages I came up with, I'm open to suggestions.
Fixes https://github.com/rust-lang/rust/issues/127870. This is also the other one of the two diagnostic improvements I wanted to do before https://github.com/rust-lang/rust/pull/122792.
Note: the first commit is an unrelated drive-by tweak.
r? `@compiler-errors`
Various notes on match lowering
This is an assortment of comments for things that I found unclear or confusing when I was learning how match lowering works.
This PR only adds/modifies comments, so there are no functional changes.
I have tried to avoid touching code that would conflict with #127159.
r? `@Nadrieril`
treat `&raw (const|mut) UNSAFE_STATIC` implied deref as safe
Fixesrust-lang/rust#125833
As reported in that and related issues, `static mut STATIC_MUT: T` is very often used in embedded code, and is in many ways equivalent to `static STATIC_CELL: SyncUnsafeCell<T>`. The Rust expression of `&raw mut STATIC_MUT` and `SyncUnsafeCell::get(&STATIC_CELL)` are approximately equal, and both evaluate to `*mut T`. The library function is safe because it has *declared itself* to be safe. However, the raw ref operator is unsafe because all uses of `static mut` are considered unsafe, even though the static's value is not used by this expression (unlike, for example, `&STATIC_MUT`).
We can fix this unnatural difference by simply adding the proper exclusion for the safety check inside the THIR unsafeck, so that we do not declare it unsafe if it is not.
While the primary concern here is `static mut`, this change is made for all instances of an "unsafe static", which includes a static declared inside `extern "abi" {}`. Hypothetically, we could go as far as generalizing this to all instances of `&raw (const|mut) *ptr`, but today we do not, as we have not actually considered the range of possible expressions that use a similar encoding. We do not even extend this to thread-local equivalents, because they have less clear semantics.
The implied deref to statics introduced by HIR->THIR lowering is only
used to create place expressions, it lacks unsafe semantics.
It is also confusing, as there is no visible `*ident` in the source.
For both classes of "unsafe static" (extern static and static mut)
allow this operation.
We lack a clear story around `thread_local! { static mut }`, which
is actually its own category of item that reuses the static syntax but
has its own rules. It's possible they should be similarly included, but
in the absence of a good reason one way or another, we do not bless it.
Explain why we require `_` for empty patterns
This adds a note to the "non-exhaustive patterns" diagnostic to explain why we sometimes require extra `_` patterns on empty types. This is one of the two diagnostic improvements I wanted to do before [stabilizing `min_exhaustive_patterns`](https://github.com/rust-lang/rust/pull/122792).
r? ``@compiler-errors``
match lowering: Split `finalize_or_candidate` into more coherent methods
I noticed that `finalize_or_candidate` was responsible for several different postprocessing tasks, making it difficult to understand.
This PR aims to clean up some of the confusion by:
- Extracting `remove_never_subcandidates` from `merge_trivial_subcandidates`
- Extracting `test_remaining_match_pairs_after_or` from `finalize_or_candidate`
- Taking what remains of `finalize_or_candidate`, and inlining it into its caller
---
Reviewing individual commits and ignoring whitespace is recommended.
Most of the large-looking changes are just moving existing code around, mostly unaltered.
r? ``@Nadrieril``
Replace a long inline "autoref" comment with method docs
This comment has two problems:
- It is very long, making the flow of the enclosing method hard to follow.
- It starts by talking about an `autoref` flag that hasn't existed since #59114.
- This makes it hard to trust that the information in the comment is accurate or relevant, even though much of it still seems to be true.
This PR therefore replaces the long inline comment with a revised doc comment on `bind_matched_candidate_for_guard`, and some shorter inline comments.
For readers who want more historical context, we also link to the PR that added the old comment, and the PR that removed the `autoref` flag.
match lowering: Rename `MatchPair` to `MatchPairTree`
In #120904, `MatchPair` became able to store other match pairs as children, forming a tree. That has made the old name confusing, so this patch renames the type to `MatchPairTree`.
This PR also includes a patch renaming the `test` method to `pick_test_for_match_pair`, since it would conflict with the main change.
r? `@Nadrieril`
MIR building: Stop using `unpack!` for `BlockAnd<()>`
This is a subset of #127416, containing only the parts related to `BlockAnd<()>`.
The first patch removes the non-assigning form of the `unpack!` macro, because it is frustratingly inconsistent with the main form. We can replace it with an ordinary method that discards the `()` and returns the block.
The second patch then finds all of the remaining code that was using `unpack!` with `BlockAnd<()>`, and updates it to use that new method instead.
---
Changes since original review of #127416:
- Renamed `fn unpack_block` → `fn into_block`
- Removed `fn unpack_discard`, replacing it with `let _: BlockAnd<()> = ...` (2 occurrences)
- Tweaked `arm_end_blocks` to unpack earlier and build `Vec<BasicBlock>` instead of `Vec<BlockAnd<()>>`
In #120904, `MatchPair` became able to store other match pairs as children,
forming a tree. That has made the old name confusing, so this patch renames the
type to `MatchPairTree`.
match lowering: Use an iterator to find `expand_until`
A small cleanup that I noticed while looking at #127164.
This makes it easier to see that the split point is always the index after the found item, or the whole list if no stopping point was found.
r? `@Nadrieril`
match lowering: Move `MatchPair` tree creation to its own module
This makes it easier to see that `MatchPair::new` has only one non-recursive caller, because the recursive callers are all in this module. No functional changes.
---
I have used `git diff --color-moved` to verify that the moved code is identical to the old code, except for reduced visibility on the helper methods.
This comment has two problems:
- It is very long, making the flow of the enclosing method hard to follow.
- It starts by talking about an `autoref` flag that hasn't existed since #59114.
This PR therefore replaces the long inline comment with a revised doc comment
on `bind_matched_candidate_for_guard`, and some shorter inline comments.
For readers who want more historical context, we also link to the PR that added
the old comment, and the PR that removed the `autoref` flag.
Fix regression in the MIR lowering of or-patterns
In https://github.com/rust-lang/rust/pull/126553 I made a silly indexing mistake and regressed the MIR lowering of or-patterns. This fixes it.
r? `@compiler-errors` because I'd like this to be merged quickly 🙏
Support tail calls in mir via `TerminatorKind::TailCall`
This is one of the interesting bits in tail call implementation — MIR support.
This adds a new `TerminatorKind` which represents a tail call:
```rust
TailCall {
func: Operand<'tcx>,
args: Vec<Operand<'tcx>>,
fn_span: Span,
},
```
*Structurally* this is very similar to a normal `Call` but is missing a few fields:
- `destination` — tail calls don't write to destination, instead they pass caller's destination to the callee (such that eventual `return` will write to the caller of the function that used tail call)
- `target` — similarly to `destination` tail calls pass the caller's return address to the callee, so there is nothing to do
- `unwind` — I _think_ this is applicable too, although it's a bit confusing
- `call_source` — `become` forbids operators and is not created as a lowering of something else; tail calls always come from HIR (at least for now)
It might be helpful to read the interpreter implementation to understand what `TailCall` means exactly, although I've tried documenting it too.
-----
There are a few `FIXME`-questions still left, ideally we'd be able to answer them during review ':)
-----
r? `@oli-obk`
cc `@scottmcm` `@DrMeepster` `@JakobDegen`
Re-implement a type-size based limit
r? lcnr
This PR reintroduces the type length limit added in #37789, which was accidentally made practically useless by the caching changes to `Ty::walk` in #72412, which caused the `walk` function to no longer walk over identical elements.
Hitting this length limit is not fatal unless we are in codegen -- so it shouldn't affect passes like the mir inliner which creates potentially very large types (which we observed, for example, when the new trait solver compiles `itertools` in `--release` mode).
This also increases the type length limit from `1048576 == 2 ** 20` to `2 ** 24`, which covers all of the code that can be reached with craterbot-check. Individual crates can increase the length limit further if desired.
Perf regression is mild and I think we should accept it -- reinstating this limit is important for the new trait solver and to make sure we don't accidentally hit more type-size related regressions in the future.
Fixes#125460