Commit Graph

1653 Commits

Author SHA1 Message Date
Ross Smyth
567c98b30f Add postfix match MatchSource to HIR 2024-03-06 00:51:48 -05:00
Nicholas Nethercote
573267cf3c Rename SubdiagnosticMessageOp as SubdiagMessageOp. 2024-03-05 12:14:49 +11:00
Matthias Krüger
58a0f64c8b
Rollup merge of #121928 - Zalathar:then-else-args, r=Nadrieril
Extract an arguments struct for `Builder::then_else_break`

Most of this method's arguments are usually or always forwarded as-is to recursive invocations.

Wrapping them in a dedicated struct allows us to document each struct field, and lets us use struct-update syntax to indicate which arguments are being modified when making a recursive call.

---

While trying to understand the lowering of `if` expressions, I found it difficult to keep track of the half-dozen arguments passed through to every call to `then_else_break`. I tried switching over to an arguments struct, and I found that it really helps to make sense of what each argument does, and how each call is modifying the arguments.

I have some further ideas for how to streamline these recursive calls, but I've kept those out of this PR so that it's a pure refactoring with no behavioural changes.
2024-03-04 22:16:32 +01:00
Zalathar
4146136d6d Extract an arguments struct for Builder::then_else_break
Most of this method's arguments are usually or always forwarded as-is to
recursive invocations.

Wrapping them in a dedicated struct allows us to document each struct field,
and lets us use struct-update syntax to indicate which arguments are being
modified when making a recursive call.
2024-03-04 18:42:12 +11:00
Guillaume Gomez
7d8f74f8b2
Rollup merge of #121917 - GuillaumeGomez:pattern-complexity_limit.rs, r=Nadrieril
Add new `pattern_complexity` attribute to add possibility to limit and check recursion in pattern matching

Needed for https://github.com/rust-lang/rust-analyzer/issues/9528.

This PR adds a new attribute only available when running rust testsuite called `pattern_complexity` which allows to set the maximum recursion for the pattern matching. It is quite useful to ensure the complexity doesn't grow, like in `tests/ui/pattern/usefulness/issue-118437-exponential-time-on-diagonal-match.rs`.

r? `@Nadrieril`
2024-03-03 14:07:43 +01:00
Guillaume Gomez
be31b6b6cd Add new pattern_complexity attribute to add possibility to limit and check recursion in pattern matching 2024-03-03 13:10:15 +01:00
bors
0decdac390 Auto merge of #121914 - Nadrieril:rollup-ol98ncg, r=Nadrieril
Rollup of 5 pull requests

Successful merges:

 - #120761 (Add initial support for DataFlowSanitizer)
 - #121622 (Preserve same vtable pointer when cloning raw waker, to fix Waker::will_wake)
 - #121716 (match lowering: Lower bindings in a predictable order)
 - #121731 (Now that inlining, mir validation and const eval all use reveal-all, we won't be constraining hidden types here anymore)
 - #121841 (`f16` and `f128` step 2: intrinsics)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-03-02 22:59:19 +00:00
Guillaume Boisseau
30976fbe2b
Rollup merge of #121716 - Nadrieril:simple-binding-order, r=matthewjasper
match lowering: Lower bindings in a predictable order

After the recent refactorings, we can now lower bindings in a truly predictable order. The order in https://github.com/rust-lang/rust/pull/120214 was an improvement but not very clear. With this PR, we lower bindings from left to right, with the special case that `x @ pat` is traversed as `pat @ x` (i.e. `x` is lowered after any bindings in `pat`).

This description only applies in the absence of or-patterns. Or-patterns make everything complicated, because the binding place depends on the subpattern. Until I have a better idea I leave them to be handled in whatever weird order arises from today's code.

r? `@matthewjasper`
2024-03-02 20:13:23 +01:00
Matthias Krüger
7bacfced95
Rollup merge of #121892 - Zalathar:expr-kind-let, r=Nadrieril
The ordinary lowering of `thir::ExprKind::Let` is unreachable

After desugaring, `let` expressions should only appear inside `if` expressions or `match` guards, possibly nested within a let-chain. In both cases they are specifically handled by the lowerings of those expressions, so this case is currently unreachable.

---

Context: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Lowering.20of.20.60thir.3A.3AExprKind.3A.3ALet.60.20is.20unreachable

My conclusions are partly based on the observation that stubbing out this match arm doesn't cause any test failures. So either this really is unreachable, or it can be reached in some obscure circumstances that our test suite doesn't cover.

If we end up needing this code (or something like it) for an implementation of https://github.com/rust-lang/rfcs/pull/3573, it should be easy enough to pull it back out of version control history.

I looked into having the `if`/`match` lowerings call back into `expr_into_dest`, but from what I can tell that won't work well, because there are extra scoping considerations that require some awareness of the enclosing if/match.

r? ```@Nadrieril```
2024-03-02 16:53:16 +01:00
Zalathar
972d8daf47 The ordinary lowering of thir::ExprKind::Let is unreachable
After desugaring, `let` expressions should only appear inside `if` expressions
or `match` guards, possibly nested within a let-chain. In both cases they are
specifically handled by the lowerings of those expressions, so this case is
currently unreachable.
2024-03-02 20:49:29 +11:00
Matthias Krüger
b2c933a1b9
Rollup merge of #121715 - Nadrieril:testcase-or, r=matthewjasper
match lowering: pre-simplify or-patterns too

This is the final part of my work to simplify match pairs early: now we do it for or-patterns too. This makes it possible to collect fake borrows separately from the main match lowering algorithm. That'll enable more simplifications of or-pattern handling.

Note: I was tempted to have `Candidate` contain a `FlatPat`, but there are so many places that use `candidate.match_pairs` etc directly that I chose not to.

r? `@matthewjasper`
2024-03-02 10:09:35 +01:00
Matthias Krüger
0d2205f9a6
Rollup merge of #121750 - Nadrieril:switchkind-if, r=matthewjasper
match lowering: Separate the `bool` case from other integers in `TestKind`

`TestKind::SwitchInt` had a special case for `bool` essentially everywhere it's used, so I made `TestKind::If` to handle the bool case on its own.

r? `@matthewjasper`
2024-03-01 22:38:49 +01:00
Matthias Krüger
1fbc53af48
Rollup merge of #121706 - Nadrieril:simplify-sort-candidate, r=matthewjasper
match lowering: Remove hacky branch in sort_candidate

Reusing `self.test()` there wasn't actually pulling a lot of weight. In particular the `TestKind::Len` cases were all already correctly handled.

r? `@matthewjasper`
2024-03-01 22:38:48 +01:00
Matthias Krüger
1a4c93e3ed
Rollup merge of #121784 - Zalathar:if-or-converge, r=Nadrieril
Make the success arms of `if lhs || rhs` meet up in a separate block

Extracted from #118305, where this is necessary to avoid introducing a bug when injecting marker statements into the then/else arms.

---

In the previous code (#111752), the success block of `lhs` would jump directly to the success block of `rhs`. However, `rhs_success_block` could already contain statements that are specific to the RHS, and the direct goto causes them to be executed in the LHS success path as well.

This patch therefore creates a fresh block that the LHS and RHS success blocks can both jump to.

---

I think the reason we currently get away with this is that `rhs_success_block` usually doesn't contain anything other than StorageDead statements for locals used by the RHS, and those statements don't seem to cause problems in the LHS success path (which never makes those locals live).

But if we start adding meaningful statements for branch coverage (or MC/DC coverage), it's important to keep the LHS and RHS blocks separate.
2024-03-01 17:51:30 +01:00
bors
6cbf0926d5 Auto merge of #121728 - tgross35:f16-f128-step1-ty-updates, r=compiler-errors
Add stubs in IR and ABI for `f16` and `f128`

This is the very first step toward the changes in https://github.com/rust-lang/rust/pull/114607 and the [`f16` and `f128` RFC](https://rust-lang.github.io/rfcs/3453-f16-and-f128.html). It adds the types to `rustc_type_ir::FloatTy` and `rustc_abi::Primitive`, and just propagates those out as `unimplemented!` stubs where necessary.

These types do not parse yet so there is no feature gate, and it should be okay to use `unimplemented!`.

The next steps will probably be AST support with parsing and the feature gate.

r? `@compiler-errors`
cc `@Nilstrieb` suggested breaking the PR up in https://github.com/rust-lang/rust/pull/120645#issuecomment-1925900572
2024-03-01 03:36:11 +00:00
Guillaume Gomez
2e0a26a32a
Rollup merge of #121376 - Nadrieril:mir-half-ranges, r=pnkfelix
Skip unnecessary comparison with half-open range patterns

This is the last remaining detail in the implementation of half-open range patterns. Until now, a half-open range pattern like `10..` was converted to `10..T::MAX` before lowering to MIR, which generated an extra pointless comparison. With this PR we don't generate it.
2024-02-29 17:08:37 +01:00
Zalathar
a7832b14b1 Make the success arms of if lhs || rhs meet up in a separate block
In the previous code, the success block of `lhs` would jump directly to the
success block of `rhs`. However, `rhs_success_block` could already contain
statements that are specific to the RHS, and the direct goto causes them to be
executed in the LHS success path as well.

This patch therefore creates a fresh block that the LHS and RHS success blocks
can both jump to.
2024-02-29 20:24:43 +11:00
Trevor Gross
e3f63d9375 Add f16 and f128 to rustc_type_ir::FloatTy and rustc_abi::Primitive
Make changes necessary to support these types in the compiler.
2024-02-28 12:58:32 -05:00
Nadrieril
d6332ae79c Separate the bool case from other integers in TestKind 2024-02-28 18:23:26 +01:00
Nadrieril
ae1e1bd216 No need to pass fake_borrows everywhere now 2024-02-28 01:48:00 +01:00
Nadrieril
ca5edfa724 Collect fake borrows ahead of time 2024-02-28 01:47:31 +01:00
Nadrieril
29666118b6 Pre-simplify or-patterns too 2024-02-28 01:44:44 +01:00
Nadrieril
00497ad24b Lower bindings in a predictable order 2024-02-28 01:41:25 +01:00
Nadrieril
5d31e29b56 Appease rust-analyzer
For some reason it doesn't figure out the slice coercion.
2024-02-28 00:30:22 +01:00
Nicholas Nethercote
8199632aa8 Rename DiagnosticArg{,Map,Name,Value} as DiagArg{,Map,Name,Value}. 2024-02-28 08:55:37 +11:00
Nicholas Nethercote
899cb40809 Rename DiagnosticBuilder as Diag.
Much better!

Note that this involves renaming (and updating the value of)
`DIAGNOSTIC_BUILDER` in clippy.
2024-02-28 08:55:35 +11:00
Nadrieril
f363c1a3fe Group default cases in sort_candidate 2024-02-27 22:37:44 +01:00
Nadrieril
5e11a99bb6 Remove hacky branch in sort_candidate
Reusing `self.test` wasn't actually pulling a lot of weight.
2024-02-27 22:37:44 +01:00
Nadrieril
205319d962 Skip unnecessary comparison with half-open ranges 2024-02-27 17:22:21 +01:00
Ralf Jung
5b7786cd1d make non-PartialEq-typed consts as patterns a hard error 2024-02-25 11:30:10 +01:00
Matthias Krüger
f4ba47f1ed
Rollup merge of #121374 - Nadrieril:factor-explain, r=matthewjasper
match lowering: Split off `test_candidates` into several functions and improve comments

The logic of `test_candidates` has three steps: pick a test, sort the candidates, and generate code for everything. So I split it off into three methods.

I also ended up reworking the comments that explain the algorithm. In particular I added detailed examples. I removed the digression about https://github.com/rust-lang/rust/issues/29740 because it's no longer relevant to how the code is structured today.

r? ``@matthewjasper``
2024-02-24 22:38:58 +01:00
Guillaume Boisseau
de4efa5e46
Tweak debug!() call
Co-authored-by: matthewjasper <20113453+matthewjasper@users.noreply.github.com>
2024-02-24 09:17:26 +01:00
Matthias Krüger
86a7fc840f compiler: clippy::complexity fixes 2024-02-23 19:56:35 +01:00
Matthias Krüger
01ec4eb319
Rollup merge of #121427 - nnethercote:fix-Rocket, r=oli-obk
Fix panic when compiling `Rocket`.

This panic was reported [here](https://github.com/rust-lang/rust/pull/120576#issuecomment-1957515484).

r? ``@oli-obk``
2024-02-22 18:09:54 +01:00
Nicholas Nethercote
02423a5747 Make some IntoDiagnostic impls generic.
PR #119097 made the decision to make all `IntoDiagnostic` impls generic,
because this allowed a bunch of nice cleanups. But four hand-written
impls were unintentionally overlooked. This commit makes them generic.
2024-02-22 13:47:30 +11:00
Nadrieril
0610f59194 Inline simplify_match_pair 2024-02-21 21:19:00 +01:00
Nadrieril
b1a0607e10 Process bindings and ascriptions in MatchPair::new() 2024-02-21 21:19:00 +01:00
Nadrieril
a181bdc065 Introduce TestCase enum to replace most matching on PatKind 2024-02-21 21:18:59 +01:00
Nadrieril
5c9d580fea Tiny simplification 2024-02-21 21:17:43 +01:00
León Orell Valerian Liehr
4daa43aaff
Rollup merge of #121175 - Nadrieril:simplify-or-selection, r=matthewjasper
match lowering: test one or pattern at a time

This is a bit more opinionated than the previous PRs. On the face of it this is less efficient and more complex than before, but I personally found the loop that digs into `leaf_candidates` on each iteration very confusing. Instead this does "generate code for this or-pattern" then "generate further code for each branch if needed" in two steps.

Incidentally this way we don't _require_ or patterns to be sorted at the end. It's still an important optimization but I find it clearer to not rely on it for correctness.

r? `@matthewjasper`
2024-02-21 16:32:57 +01:00
Nadrieril
893cb760e0 Split off test_candidates into several functions and improve comments 2024-02-21 11:45:04 +01:00
Nadrieril
c1514a6324 Test one or pattern at a time 2024-02-21 11:35:44 +01:00
Nadrieril
780beda83c Tweak block management 2024-02-21 11:25:11 +01:00
Dylan DPC
d5206c6ecd
Rollup merge of #121208 - nnethercote:delayed_bug-to-bug, r=lcnr
Convert `delayed_bug`s to `bug`s.

I have a suspicion that quite a few delayed bug paths are impossible to reach, so I did an experiment.

I converted every `delayed_bug` to a `bug`, ran the full test suite, then converted back every `bug` that was hit. A surprising number were never hit.

This is too dangerous to merge. Increased coverage (fuzzing or a crater run) would likely hit more cases. But it might be useful for people to look at and think about which paths are genuinely unreachable.

r? `@ghost`
2024-02-21 08:55:56 +00:00
bors
096598dc79 Auto merge of #121172 - Nadrieril:simplify-empty-selection, r=matthewjasper
match lowering: simplify empty candidate selection

In match lowering, `match_simplified_candidates` is tasked with removing candidates that are fully matched and linking them up properly. The code that does that was needlessly complicated; this PR simplifies it.

The overall change isn't big but I split it up into tiny commits to convince myself that I was correctly preserving behavior. The test changes are all due to the first commit. Let me know if you'd prefer me to split up the PR to make reviewing easier.

r? `@matthewjasper`
2024-02-21 03:11:24 +00:00
bors
4e65074933 Auto merge of #120904 - Nadrieril:match-lowering-intermediate-repr, r=matthewjasper
match lowering: eagerly simplify match pairs

This removes one important complication from match lowering. Before this, match pair simplification (which includes collecting bindings and type ascriptions) was intertwined with the whole match lowering algorithm.

I'm avoiding this by storing in each `MatchPair` the sub-`MatchPair`s that correspond to its subfields. This makes it possible to simplify everything (except or-patterns) in `Candidate::new()`.

This should open up further simplifications. It will also give us proper control over the order of bindings.

r? `@matthewjasper`
2024-02-21 01:11:34 +00:00
Nicholas Nethercote
2903bbbc15 Convert bugs back to delayed_bugs.
This commit undoes some of the previous commit's mechanical changes,
based on human judgment.
2024-02-21 10:35:54 +11:00
Nicholas Nethercote
010f3944e0 Convert delayed_bugs to bugs.
I have a suspicion that quite a few delayed bug paths are impossible to
reach, so I did an experiment.

I converted every `delayed_bug` to a `bug`, ran the full test suite,
then converted back every `bug` that was hit. A surprising number were
never hit.

The next commit will convert some more back, based on human judgment.
2024-02-21 10:20:05 +11:00
Nadrieril
a45d8925b8 Upgrade a debug_assert to assert 2024-02-20 16:53:16 +01:00
Nicholas Nethercote
f6f8779843 Reduce capabilities of Diagnostic.
Currently many diagnostic modifier methods are available on both
`Diagnostic` and `DiagnosticBuilder`. This commit removes most of them
from `Diagnostic`. To minimize the diff size, it keeps them within
`diagnostic.rs` but changes the surrounding `impl Diagnostic` block to
`impl DiagnosticBuilder`. (I intend to move things around later, to give
a more sensible code layout.)

`Diagnostic` keeps a few methods that it still needs, like `sub`,
`arg`, and `replace_args`.

The `forward!` macro, which defined two additional methods per call
(e.g. `note` and `with_note`), is replaced by the `with_fn!` macro,
which defines one additional method per call (e.g. `with_note`). It's
now also only used when necessary -- not all modifier methods currently
need a `with_*` form. (New ones can be easily added as necessary.)

All this also requires changing `trait AddToDiagnostic` so its methods
take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many
mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`.

There are three subdiagnostics -- `DelayedAtWithoutNewline`,
`DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` --
that are created within the diagnostics machinery and appended to
external diagnostics. These are handled at the `Diagnostic` level, which
means it's now hard to construct them via `derive(Diagnostic)`, so
instead we construct them by hand. This has no effect on what they look
like when printed.

There are lots of new `allow` markers for `untranslatable_diagnostics`
and `diagnostics_outside_of_impl`. This is because
`#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic`
modifier methods, but missing from the `DiagnosticBuilder` modifier
methods. They're now present.
2024-02-20 13:22:17 +11:00