Commit Graph

163 Commits

Author SHA1 Message Date
Jules Bertholet
ef1d084c0b
Match ergonomics 2024: mut doesn't reset binding mode 2024-04-15 23:26:22 -04:00
Esteban Küber
d97d2fe744 Mention when the type of the moved value doesn't implement Clone 2024-04-11 16:41:42 +00:00
Esteban Küber
5a7caa3174 Fix accuracy of T: Clone check in suggestion 2024-04-11 16:41:41 +00:00
Esteban Küber
bce78102c3 Account for unops when suggesting cloning 2024-04-11 16:41:41 +00:00
Esteban Küber
fa2fc3ab96 Suggest .clone() when moved while borrowed 2024-04-11 16:41:41 +00:00
Nadrieril
27704c7f9e Fix union handling in exhaustiveness 2024-04-01 00:01:46 +02:00
Nadrieril
db9b4eac48 Add tests 2024-03-31 23:57:47 +02:00
Jules Bertholet
528d45af18
Feature gate 2024-03-27 11:20:28 -04:00
Michael Goulet
5fdc7555c1 Require DerefMut if deref pattern has nested ref mut binding 2024-03-25 19:39:45 -04:00
Michael Goulet
08235b1603 Validate that we're only matching on unit struct for path pattern 2024-03-22 20:53:42 -04:00
Michael Goulet
2d633317f3 Implement macro-based deref!() syntax for deref patterns
Stop using `box PAT` syntax for deref patterns, as it's misleading and
also causes their semantics being tangled up.
2024-03-21 11:42:49 -04:00
Nadrieril
120d3570aa Add barest-bones deref patterns
Co-authored-by: Deadbeef <ent3rm4n@gmail.com>
2024-03-20 22:30:27 +01:00
surechen
19f72dfe04 Fix incorrect mutable suggestion information for binding in ref pattern.
For ref pattern in func param, the mutability suggestion has to apply to the binding.

For example: `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)`

fixes #122415
2024-03-19 12:28:23 +08:00
Matthias Krüger
2d3dcfaade
Rollup merge of #121823 - Nadrieril:never-witnesses, r=compiler-errors
never patterns: suggest `!` patterns on non-exhaustive matches

When a match is non-exhaustive we now suggest never patterns whenever it makes sense.

r? ``@compiler-errors``
2024-03-18 22:24:36 +01:00
Matthias Krüger
9e153ccd45
Rollup merge of #122254 - estebank:issue-48677, r=oli-obk
Detect calls to .clone() on T: !Clone types on borrowck errors

When encountering a lifetime error on a type that *holds* a type that doesn't implement `Clone`, explore the item's body for potential calls to `.clone()` that are only cloning the reference `&T` instead of `T` because `T: !Clone`. If we find this, suggest `T: Clone`.

```
error[E0502]: cannot borrow `*list` as mutable because it is also borrowed as immutable
  --> $DIR/clone-on-ref.rs:7:5
   |
LL |     for v in list.iter() {
   |              ---- immutable borrow occurs here
LL |         cloned_items.push(v.clone())
   |                             ------- this call doesn't do anything, the result is still `&T` because `T` doesn't implement `Clone`
LL |     }
LL |     list.push(T::default());
   |     ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
LL |
LL |     drop(cloned_items);
   |          ------------ immutable borrow later used here
   |
help: consider further restricting this bound
   |
LL | fn foo<T: Default + Clone>(list: &mut Vec<T>) {
   |                   +++++++
```
```
error[E0505]: cannot move out of `x` because it is borrowed
  --> $DIR/clone-on-ref.rs:23:10
   |
LL | fn qux(x: A) {
   |        - binding `x` declared here
LL |     let a = &x;
   |             -- borrow of `x` occurs here
LL |     let b = a.clone();
   |               ------- this call doesn't do anything, the result is still `&A` because `A` doesn't implement `Clone`
LL |     drop(x);
   |          ^ move out of `x` occurs here
LL |
LL |     println!("{b:?}");
   |               ----- borrow later used here
   |
help: consider annotating `A` with `#[derive(Clone)]`
   |
LL + #[derive(Clone)]
LL | struct A;
   |
```

Fix #48677.
2024-03-15 21:51:56 +01:00
Esteban Küber
b367c25367 Tweak wording 2024-03-13 23:05:17 +00:00
Nadrieril
c4236785c7 Remove MaybeInfiniteInt::JustAfterMax
It was inherited from before half-open ranges, but it doesn't pull its
weight anymore. We lose a tiny bit of diagnostic precision.
2024-03-13 14:17:11 +01:00
Matthias Krüger
e6ba504029
Rollup merge of #121908 - Nadrieril:dynamic-variant-collection, r=matthewjasper
match lowering: don't collect test alternatives ahead of time

I'm very happy with this one. Before this, when sorting candidates into the possible test branches, we manually computed `usize` indices to determine in which branch each candidate goes. To make this work we had a first pass that collected the possible alternatives we'd have to deal with, and a second pass that actually sorts the candidates.

In this PR, I replace `usize` indices with a dedicated enum. This makes `sort_candidates` easier to follow, and we don't need the first pass anymore.

r? ``@matthewjasper``
2024-03-13 06:41:21 +01:00
Nadrieril
b878ab6a27 Don't suggest an arm when suggesting a never pattern 2024-03-12 21:38:31 +01:00
Nadrieril
9f2aa5b85a Suggest never pattern instead of _ for empty types 2024-03-12 21:38:30 +01:00
Nadrieril
844f173b5c Run the empty_types tests with never_patterns too 2024-03-12 21:38:30 +01:00
Nadrieril
8ac9a04257 Lint small gaps between ranges 2024-03-09 01:14:22 +01:00
Nadrieril
f783043ebf Allow lint where we don't care 2024-03-09 01:13:42 +01: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
f04b7ee130 Add and update tests to use pattern_complexity 2024-03-03 13:10:15 +01: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
Nadrieril
d46ff6415c Fix a subtle regression
Before, the SwitchInt cases were computed in two passes: if the first
pass accepted e.g. 0..=5 and then 1, the second pass would not accept
0..=5 anymore because 1 would be listed in the SwitchInt options.

Now there's a single pass, so if we sort 0..=5 we must take care to not
sort a subsequent 1.
2024-03-02 18:38:37 +01:00
Esteban Küber
bde2dfb127 Detect more cases of = to : typo
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span
arround and mention it. If the type could continue being parsed as an
expression, suggest replacing the `:` with a `=`.

```
error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
 --> file.rs:2:32
  |
2 |     let _: std::env::temp_dir().join("foo");
  |          -                     ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
  |          |
  |          while parsing the type for `_`
  |          help: use `=` if you meant to assign
```

Fix #119665.
2024-03-01 02:03:00 +00:00
Nadrieril
97bfa106c7 Add test for the known case that doesn't work 2024-02-28 01:41:25 +01:00
Matthias Krüger
26cb6c7287
Rollup merge of #120742 - Nadrieril:use-min_exh_pats, r=compiler-errors
mark `min_exhaustive_patterns` as complete

This is step 1 and 2 of my [proposal](https://github.com/rust-lang/rust/issues/119612#issuecomment-1918097361) to move `min_exhaustive_patterns` forward. The vast majority of in-tree use cases of `exhaustive_patterns` are covered by `min_exhaustive_patterns`. There are a few cases that still require `exhaustive_patterns` in tests and they're all behind references.

r? ``@ghost``
2024-02-23 17:02:03 +01:00
许杰友 Jieyou Xu (Joe)
ec2cc761bc
[AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
Esteban Küber
24b52fd9df Do not point at #[allow(_)] as the reason for compat lint triggering
Fix #121009.
2024-02-13 20:27:43 +00:00
Nadrieril
8e83d0cd75 Prefer min_exhaustive_patterns in tests 2024-02-13 16:45:53 +01:00
Nadrieril
61d6443467 Unmark the feature gate as incomplete 2024-02-13 16:45:29 +01:00
Caio
69a5264a52 Move some tests 2024-02-09 15:43:08 -03:00
Matthias Krüger
949e55299d
Rollup merge of #120775 - Nadrieril:more-min_exh_pats, r=compiler-errors
Make `min_exhaustive_patterns` match `exhaustive_patterns` better

Split off from https://github.com/rust-lang/rust/pull/120742.

There remained two edge cases where `min_exhaustive_patterns` wasn't behaving like `exhaustive_patterns`. This fixes them, and tests the feature in a bunch more cases. I essentially went through all uses of `exhaustive_patterns` to see which ones would be interesting to compare between the two features.

r? `@compiler-errors`
2024-02-08 20:34:59 +01:00
bors
1280928a99 Auto merge of #120767 - matthiaskrgr:rollup-0k8ib1c, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #119592 (resolve: Unload speculatively resolved crates before freezing cstore)
 - #120103 (Make it so that async-fn-in-trait is compatible with a concrete future in implementation)
 - #120206 (hir: Make sure all `HirId`s have corresponding HIR `Node`s)
 - #120214 (match lowering: consistently lower bindings deepest-first)
 - #120688 (GVN: also turn moves into copies with projections)
 - #120702 (docs: also check the inline stmt during redundant link check)
 - #120727 (exhaustiveness: Prefer "`0..MAX` not covered" to "`_` not covered")
 - #120734 (Add `SubdiagnosticMessageOp` as a trait alias.)
 - #120739 (improve pretty printing for associated items in trait objects)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-02-08 12:14:19 +00:00
Nadrieril
4733b1bba5 Test min_exhaustive_patterns in more cases 2024-02-08 11:48:38 +01:00
Oli Scherer
eab2adb660 Continue to borrowck even if there were previous errors 2024-02-08 08:10:43 +00:00
Matthias Krüger
5157190008
Rollup merge of #120727 - Nadrieril:tweak-int-reporting, r=compiler-errors
exhaustiveness: Prefer "`0..MAX` not covered" to "`_` not covered"

There was an exception when reporting integer ranges as missing, it's been there for as long as I can remember. This PR removes it. I think it's nicer to report "`0..MAX` not covered" than "`_` not covered". This also makes it consistent with enums, where we report individual enum variants in this case (as showcased in the rest of the `empty-match.rs` test).

r? ``@estebank``
2024-02-08 09:06:35 +01:00
Matthias Krüger
7fb36f2d3b
Rollup merge of #120214 - Nadrieril:fix-120210, r=pnkfelix
match lowering: consistently lower bindings deepest-first

Currently when lowering match expressions to MIR, we do a funny little dance with the order of bindings. I attempt to explain it in the third commit: we handle refutable (i.e. needing a test) patterns differently than irrefutable ones. This leads to inconsistencies, as reported in https://github.com/rust-lang/rust/issues/120210. The reason we need a dance at all is for situations like:

```rust
fn foo1(x: NonCopyStruct) {
    let y @ NonCopyStruct { copy_field: z } = x;
    // the above should turn into
    let z = x.copy_field;
    let y = x;
}
```

Here the `y ```````@```````` binding will move out of `x`, so we need to copy the field first.

I believe that the inconsistency came about when we fixed https://github.com/rust-lang/rust/issues/69971, and didn't notice that the fix didn't extend to refutable patterns. My guess then is that ordering bindings by "deepest-first, otherwise source order" is a sound choice. This PR implements that (at least I hope, match lowering is hard to follow 🥲).

Fixes https://github.com/rust-lang/rust/issues/120210

r? ```````@oli-obk``````` since you merged the original fix to https://github.com/rust-lang/rust/issues/69971
cc ```````@matthewjasper```````
2024-02-08 09:06:33 +01:00
Nadrieril
9dca6be7b8 Prefer "0..MAX not covered" to "_ not covered" 2024-02-07 23:25:11 +01:00
Nadrieril
970f46c60d Add tests 2024-02-07 23:22:46 +01:00
r0cky
c7519d42c2 Update tests 2024-02-07 10:42:01 +08:00
Matthias Krüger
176c4ba5c3
Rollup merge of #120423 - RalfJung:indirect-structural-match, r=petrochenkov
update indirect structural match lints to match RFC and to show up for dependencies

This is a large step towards implementing https://github.com/rust-lang/rfcs/pull/3535.
We currently have five lints related to "the structural match situation":
- nontrivial_structural_match
- indirect_structural_match
- pointer_structural_match
- const_patterns_without_partial_eq
- illegal_floating_point_literal_pattern

This PR concerns the first 3 of them. (The 4th already is set up to show for dependencies, and the 5th is removed by https://github.com/rust-lang/rust/pull/116284.) nontrivial_structural_match is being removed as per the RFC; the other two are enabled to show up in dependencies.

Fixes https://github.com/rust-lang/rust/issues/73448 by removing the affected analysis.
2024-02-06 22:45:41 +01:00
Matthias Krüger
89aa85d805
Rollup merge of #120597 - fmease:sugg-on-js-style-spread-op-in-pat, r=estebank
Suggest `[tail @ ..]` on `[..tail]` and `[...tail]` where `tail` is unresolved

Fixes #120591.
~~Will conflict with #120570~~ (rebased).

r? estebank or compiler
2024-02-06 19:40:07 +01:00
Ralf Jung
45d01b8131 update the tracking issue for structural match violations
and bless a test I missed
2024-02-05 20:36:11 +01:00
Ralf Jung
48abca761a show indirect_structural_match and pointer_structural_match in future compat reports 2024-02-05 20:36:11 +01:00
Matthias Krüger
ed27148812
Rollup merge of #116284 - RalfJung:no-nan-match, r=cjgillot
make matching on NaN a hard error, and remove the rest of illegal_floating_point_literal_pattern

These arms would never be hit anyway, so the pattern makes little sense. We have had a future-compat lint against float matches in general for a *long* time, so I hope we can get away with immediately making this a hard error.

This is part of implementing https://github.com/rust-lang/rfcs/pull/3535.

Closes https://github.com/rust-lang/rust/issues/41620 by removing the lint.

https://github.com/rust-lang/reference/pull/1456 updates the reference to match.
2024-02-05 11:07:26 +01:00
León Orell Valerian Liehr
285d8c225d
Suggest [tail @ ..] on [..tail] and [...tail] where tail is unresolved 2024-02-04 22:16:21 +01:00