Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lint towards rejecting consts in patterns that do not implement PartialEq #115893

Merged
merged 4 commits into from
Sep 26, 2023

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Sep 16, 2023

I think we definitely don't want to allow such consts, so even while the general plan around structural matching is up in the air, we can start the process of getting non-PartialEq matches out of the ecosystem.

@rustbot
Copy link
Collaborator

rustbot commented Sep 16, 2023

r? @b-naber

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 16, 2023
@rustbot
Copy link
Collaborator

rustbot commented Sep 16, 2023

Some changes might have occurred in exhaustiveness checking

cc @Nadrieril

@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member Author

Crucially, tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-use-behind-cousin-variant.rs is still accepted; this is the example where #62411 (indirect_structural_match) was initially over-eager.

@RalfJung RalfJung added T-lang Relevant to the language team, which will review and decide on the PR/issue. S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). I-lang-nominated Nominated for discussion during a lang team meeting. labels Sep 17, 2023
@RalfJung
Copy link
Member Author

RalfJung commented Sep 17, 2023

@rust-lang/lang I found a surprising gap in our pattern-related future-incompat lints, which lead to us still accepting (without a warning) some consts as patterns that don't even implement PartialEq. I think we definitely don't want that (and @oli-obk said the intent of his lints was to catch all such cases), so this PR closes that gap. The new lint is immediately set up to show in cargo's reports. I expect this to be rare (one has to work pretty hard to get such a const to be accepted), so it doesn't seem worth the extra delay of having a phase where the lint only shows up for the local crates.

So the question for you is, are you okay with consts in patterns requiring at least a PartialEq bound? (There might be further restrictions, related to all this "structural equality" business. That doesn't have to be answered here. This is just asking whether we need at least PartialEq.)

If you are curious about what the affected code looks like, here are some examples:

On both cases, the reason the constant isn't PartialEq is an unnecessary trait bound introduced by derive(PartialEq). That's why the compiler is still able to generate code that compares the constant with the matched place. These unnecessary trait bounds aren't great, but I don't think that should affect our const-in-match-pattern rules.

@nikomatsakis
Copy link
Contributor

Checking in from the @rust-lang/lang meeting and unnominating:

Our judgment is that this is a bug fix and only causes more warnings, so no FCP is required, and we are in favor of going forward.

However, we were pretty confused about what the story is around constants and matching -- requiring a PartialEq bound makes sense if we are invoking ==, but it's not clear if that is the case? Or sometimes the case? We would much appreciate to hear the latest thinking at some point (design meeting?).

@rustbot labels -I-lang-nominated

@rustbot rustbot removed the I-lang-nominated Nominated for discussion during a lang team meeting. label Sep 19, 2023
@RalfJung
Copy link
Member Author

RalfJung commented Sep 19, 2023

However, we were pretty confused about what the story is around constants and matching -- requiring a PartialEq bound makes sense if we are invoking ==, but it's not clear if that is the case? Or sometimes the case? We would much appreciate to hear the latest thinking at some point (design meeting?).

Yeah I think a design meeting is due, also see here. Maybe we shouldn't add further warnings until that happened, to avoid having to take back the warning again.

@RalfJung
Copy link
Member Author

I started writing up a design meeting document and there good reasons for requiring PartialEq in either case. So as far as I am concerned, and based on t-lang feedback above, I think it makes sense to go ahead and land this, if the compiler team agrees.

@oli-obk @lcnr what do you think?

@rust-log-analyzer

This comment has been minimized.

@est31
Copy link
Member

est31 commented Sep 25, 2023

Regarding the lint's name, maybe it is too general? I assume you do not want to forbid code like this:

enum Foo { Bar, Baz }
impl Foo {
    fn is_bar(&self) -> bool {
        matches!(self, Foo::Bar)
    }
}

Where Foo has no derive for PartialEq. I at least have been using this trick a few times when I thought that adding a derive was too burdensome.

Would the name constants_matching_without_partial_eq be better maybe? It's a bit longer but no idea what to remove. (also, generally, lints should be in plural form).

@RalfJung
Copy link
Member Author

I renamed it to const_patterns_without_partial_eq.

@rust-log-analyzer

This comment has been minimized.


// Always check for `PartialEq`, even if we emitted other lints. (But not if there were
// any errors.) This ensures it shows up in cargo's future-compat reports as well.
if !self.type_has_partial_eq_impl(cv.ty()) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is the potential alternative of checking for Eq here instead of PartialEq. This would then subsume the "disallow floats in patterns" lint as well. However with t-lang in the past having been disinclined to disallow float patterns, it's not clear that we want to require Eq.

@oli-obk
Copy link
Contributor

oli-obk commented Sep 26, 2023

@bors r+

let's land this and figure out the details of consts in patterns in a design meeting with T-lang

@bors
Copy link
Contributor

bors commented Sep 26, 2023

📌 Commit a1d6fc4 has been approved by oli-obk

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). labels Sep 26, 2023
@bors
Copy link
Contributor

bors commented Sep 26, 2023

⌛ Testing commit a1d6fc4 with merge 1f2bacf...

@bors
Copy link
Contributor

bors commented Sep 26, 2023

☀️ Test successful - checks-actions
Approved by: oli-obk
Pushing 1f2bacf to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Sep 26, 2023
@bors bors merged commit 1f2bacf into rust-lang:master Sep 26, 2023
11 checks passed
@rustbot rustbot added this to the 1.74.0 milestone Sep 26, 2023
@RalfJung RalfJung added relnotes Marks issues that should be documented in the release notes of the next release. and removed relnotes Marks issues that should be documented in the release notes of the next release. labels Sep 26, 2023
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (1f2bacf): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.4% [3.4%, 3.4%] 1
Improvements ✅
(primary)
-0.6% [-0.6%, -0.6%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.6% [-0.6%, -0.6%] 1

Cycles

This benchmark run did not return any relevant results for this metric.

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 631.784s -> 630.892s (-0.14%)
Artifact size: 317.18 MiB -> 317.28 MiB (0.03%)

@RalfJung RalfJung deleted the match-require-partial-eq branch September 30, 2023 20:27
bors added a commit to rust-lang-ci/rust that referenced this pull request Jan 25, 2024
remove StructuralEq trait

The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.

One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust rust-lang#115893 to check for `Eq`, and rule out float matching for good.

Fixes rust-lang#115881
bors added a commit to rust-lang-ci/rust that referenced this pull request Jan 25, 2024
remove StructuralEq trait

The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.

One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust rust-lang#115893 to check for `Eq`, and rule out float matching for good.

Fixes rust-lang#115881
bors added a commit to rust-lang-ci/rust that referenced this pull request Jan 26, 2024
remove StructuralEq trait

The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.

One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust rust-lang#115893 to check for `Eq`, and rule out float matching for good.

Fixes rust-lang#115881
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jan 26, 2024
remove StructuralEq trait

The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.

One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust rust-lang/rust#115893 to check for `Eq`, and rule out float matching for good.

Fixes rust-lang/rust#115881
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Jan 27, 2024
remove StructuralEq trait

The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.

One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust rust-lang/rust#115893 to check for `Eq`, and rule out float matching for good.

Fixes rust-lang/rust#115881
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Feb 8, 2024
remove StructuralEq trait

The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.

One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust rust-lang/rust#115893 to check for `Eq`, and rule out float matching for good.

Fixes rust-lang/rust#115881
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 8, 2024
make non-PartialEq-typed consts as patterns a hard error

This lint was introduced in rust-lang#115893, for Rust 1.74, so we just had the third stable release where this is shown as a future-compat lint (which is shown for dependencies). Not a single comment or backreference showed up in the tracking issue, rust-lang#116122. So this seems fairly safe to turn into a hard error.

Of course we should do a crater run first.

This is part of rust-lang#120362.
GuillaumeGomez pushed a commit to GuillaumeGomez/rustc_codegen_gcc that referenced this pull request Feb 15, 2024
remove StructuralEq trait

The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.

One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust rust-lang/rust#115893 to check for `Eq`, and rule out float matching for good.

Fixes rust-lang/rust#115881
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Feb 25, 2024
…li-obk

make non-PartialEq-typed consts as patterns a hard error

This lint was introduced in rust-lang#115893, for Rust 1.74, so we just had the third stable release where this is shown as a future-compat lint (which is shown for dependencies). Not a single comment or backreference showed up in the tracking issue, rust-lang#116122. So this seems fairly safe to turn into a hard error.

Of course we should do a crater run first.

This is part of rust-lang#120362.
Closes rust-lang#116122.
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Feb 25, 2024
Rollup merge of rust-lang#120805 - RalfJung:const-pat-partial-eq, r=oli-obk

make non-PartialEq-typed consts as patterns a hard error

This lint was introduced in rust-lang#115893, for Rust 1.74, so we just had the third stable release where this is shown as a future-compat lint (which is shown for dependencies). Not a single comment or backreference showed up in the tracking issue, rust-lang#116122. So this seems fairly safe to turn into a hard error.

Of course we should do a crater run first.

This is part of rust-lang#120362.
Closes rust-lang#116122.
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Feb 26, 2024
make non-PartialEq-typed consts as patterns a hard error

This lint was introduced in rust-lang/rust#115893, for Rust 1.74, so we just had the third stable release where this is shown as a future-compat lint (which is shown for dependencies). Not a single comment or backreference showed up in the tracking issue, rust-lang/rust#116122. So this seems fairly safe to turn into a hard error.

Of course we should do a crater run first.

This is part of rust-lang/rust#120362.
Closes rust-lang/rust#116122.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants