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

Tracking issue for Option::contains and Result::contains #62358

Closed
Centril opened this issue Jul 4, 2019 · 149 comments
Closed

Tracking issue for Option::contains and Result::contains #62358

Centril opened this issue Jul 4, 2019 · 149 comments
Labels
A-result-option Area: Result and Option combinators B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC disposition-close This PR / issue is in PFCP or FCP with a disposition to close it. finished-final-comment-period The final comment period is finished for this PR / Issue. Libs-Small Libs issues that are considered "small" or self-contained Libs-Tracked Libs issues that are tracked on the team's project board. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@Centril
Copy link
Contributor

Centril commented Jul 4, 2019

This is a tracking issue for Option::contains and Result::contains.

The implementations are as follows:

    pub fn contains(&self, x: &T) -> bool where T: PartialEq {
        match self {
            Some(y) => y == x,
            None => false,
        }
    }

    pub fn contains(&self, x: &T) -> bool where T: PartialEq {
        match self {
            Ok(y) => y == x,
            Err(_) => false,
        }
    }
``
@Centril Centril added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC labels Jul 4, 2019
@Mark-Simulacrum
Copy link
Member

Should we update the signatures to fn contains<U>(&self, x: &U) -> bool where T: PartialEq<U>?

@Centril
Copy link
Contributor Author

Centril commented Jul 4, 2019

@Mark-Simulacrum That seems like a good idea -- type inference should be driven by x in any case. Let's do that in the PR.

@timvermeulen
Copy link
Contributor

Looks like slice/Vec/VecDeque/LinkedList and possibly others have a contains method that could benefit in the same way.

@soc
Copy link
Contributor

soc commented Jul 4, 2019

@Mark-Simulacrum I didn't do that because I checked the collections first, and they were all invariant. Shall I change this for Option and Result only?

@Mark-Simulacrum
Copy link
Member

We usually can't change preexisting APIs due to inference breakage, but since this is new, we should be able to be general.

@frewsxcv
Copy link
Member

frewsxcv commented Jul 6, 2019

Are these functionally equivalent?

    pub fn contains(&self, x: &T) -> bool where T: PartialEq {
        match self {
            Some(y) => y == x,
            None => false,
        }
    }
    pub fn contains(&self, x: &T) -> bool where T: PartialEq {
        self.as_ref() == Some(x)
    }

@soc
Copy link
Contributor

soc commented Jul 8, 2019

@frewsxcv Not quite, due to the requested variance changes.

@czipperz
Copy link
Contributor

What does that mean @soc?

@soc
Copy link
Contributor

soc commented Jul 14, 2019

@czipperz The implementation is:

// Option
pub fn contains<U>(&self, x: &U) -> bool where U: PartialEq<T> {
    match self {
        Some(y) => x == y,
        None => false,
    }
}

// Result
pub fn contains<U>(&self, x: &U) -> bool where U: PartialEq<T> {
    match self {
        Ok(y) => x == y,
        Err(_) => false
    }
}

pub fn contains_err<F>(&self, f: &F) -> bool where F: PartialEq<E> {
    match self {
        Ok(_) => false,
        Err(e) => f == e
    }
}

The argument doesn't have to be of the same type as the value inside option/result, only that it knows how to compare itself to it. I. e. the operation is not invariant on the contained type, it allows an arbitrary type.

@czipperz
Copy link
Contributor

So there's no implementation of PartialEq<Option<U>> for Option<T> where U: PartialEq<T>?

@timvermeulen
Copy link
Contributor

timvermeulen commented Jul 14, 2019

There is indeed not, see #20063.

ppannuto added a commit to alphan/tock that referenced this issue May 19, 2020
This matches the new `contains` method of Option:
rust-lang/rust#62358
@dtolnay
Copy link
Member

dtolnay commented Jun 17, 2020

These methods are way too high up in the docs on both the Option and Result rustdoc. Would someone be able to send a PR to move these a lot further down? For example stuff like ok and map and and_then should all be featured higher than contains.

@sinistersnare
Copy link
Contributor

What is the status on this? I would love to use these in stable.

@KodrAus KodrAus added A-result-option Area: Result and Option combinators Libs-Small Libs issues that are considered "small" or self-contained Libs-Tracked Libs issues that are tracked on the team's project board. labels Jul 29, 2020
@xkr47
Copy link
Contributor

xkr47 commented Aug 19, 2020

Assume you have a function getFoo() returning Option<String> then it might be misleading if you do getFoo().contains("bar") since it looks like it checks for a substring when it in fact checks for an exact match. Would some other name perhaps be more clear?

@sinistersnare
Copy link
Contributor

how about contains_in or map_contains?

@soc
Copy link
Contributor

soc commented Aug 19, 2020

option.contains_in("foo") reads weird. You could of course pick something else entirely different, like option.has("foo") or option.includes("foo").

But in the end, Rust is a typed language, so we should not be scared that much about confusion, because the types tell us which contains method is used.

@camsteffen
Copy link
Contributor

Naming bikeshed. Sorry if this is the wrong place.

How about the names eq_some, eq_ok and eq_err? Or maybe only using those names for Result? I get that contains is consistent with containers, but that analogy weakens especially with Result.

@Amanieu
Copy link
Member

Amanieu commented Mar 5, 2023

#108095 argues that this should be removed in favor of is_some_with (#93050) and I agree. That API is more flexible than contains and has a better name.

@rfcbot fcp close

@rfcbot
Copy link

rfcbot commented Mar 5, 2023

Team member @Amanieu has proposed to close this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-close This PR / issue is in PFCP or FCP with a disposition to close it. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Mar 5, 2023
@rfcbot
Copy link

rfcbot commented Mar 7, 2023

🔔 This is now entering its final comment period, as per the review above. 🔔

@BrianLondon
Copy link

My anecdotal experience with Scala, which has an Option[T] with both contains(t: T): bool and exists(t: T => bool): bool the later of which is equivalent to the proposed is_some_and, is that use of contains is far more common. I don't know enough about the compiler internals to speak to what performance penalty comes from wrapping the equality check in the closure, but if any, I'd be concerned about the added overhead.

@soc
Copy link
Contributor

soc commented Mar 9, 2023

@BrianLondon To avoid any disappointment, please refer to

I wouldn't suggest throwing around your experience working on Scala as much as you do.

If you just want to carbon copy the ideology of Scala into Rust, and are not interested in improving on the language, I suggest you go back and work on Scala

Please keep in mind that, while your experience in Scala may be very good with applying Scala ideology to Scala problems, Rust might not fit in the same corner.

to learn about the community's preferences on this topic.

Thanks!

@BrianLondon
Copy link

Thanks @soc, is there a document you're quoting? If so can you link to the original please? I'd like to read the rest of it.

I think you're making some incorrect assumptions about my motivations. To be clear I am not suggesting a carbon copy of Scala, or even proposing to bring any particular Scala idiom into Rust. I am categorically not, for example, saying is_some_and should be renamed exists or something. What I am saying is that I expect is_some_and(|x| x == target) to be the predominant way it's used, and I'm asking whether there is a performance cost to running the comparison through the closure.

@BurntSushi
Copy link
Member

@BrianLondon soc does not speak for the community, and as a member of libs-api, I am generally happy to hear about experiences from other programming languages. (Although I do always, regardless of language, cast a skeptical eye because it can be tricky to analogize different environments. But I think your experience is relevant here.)

@camsteffen
Copy link
Contributor

@BrianLondon, @soc is just quoting earlier comments in this thread where they got into a squabble with another individual, so no need to worry about that. Generally the community is welcoming to different perspectives.

@AaronKutch
Copy link
Contributor

AaronKutch commented Mar 9, 2023

I personally think that Option::contains makes sense and should be a thing in parallel to is_some_and. Result::contains, however, will result in a cognitive ambiguity in Result<T, T> cases (I have used these multiple times in practice). For Result there should just be is_ok_and and is_err_and (edit: or also maybe ok_contains and err_contains?)

@khionu
Copy link
Member

khionu commented Mar 9, 2023

As the moderator who handled the referred situation, I want to confirm that Brian's original comment from yesterday was not of the same problems. What was done well was that Brian noted that their experience was anecdotal, not treating their views as authoritative, and they also softened their contribution by acknowledging what they weren't aware of. This makes a world of difference in how one brings outside experience to Rust.

@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Mar 17, 2023
@rfcbot
Copy link

rfcbot commented Mar 17, 2023

The final comment period, with a disposition to close, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Mar 23, 2023
bors added a commit to rust-lang-ci/rust that referenced this issue Mar 28, 2023
Drop unstable `Option::contains`, `Result::contains`, `Result::contains_err`

This is a proposal to drop the three functions `Option::contains`, `Result::contains` and `Result::contains_err`.

The discovery of `Option::is_some_with`/`Result::is_ok_with`/`Result::is_err_with` in rust-lang#93051 obviates the need for these methods (non-stabilization tracked in rust-lang#62358).

An additional benefit of change is that it avoids spurious error messages in IDEs, when `contains` is supplied by a third-party library:
![option-result-unstable](https://user-images.githubusercontent.com/42493/219127961-13cb559e-6ee8-4449-8dc9-d28d07270ad5.png)
@soc
Copy link
Contributor

soc commented Mar 29, 2023

@Centril methods have been removed, this issue can be closed now.

@Amanieu Amanieu closed this as completed Mar 29, 2023
readysetbot pushed a commit to readysettech/readyset that referenced this issue Mar 29, 2023
Per rust-lang/rust#62358, this feature has
been removed. To prepare for a future nightly toolchain bump, this
replaces all the places we're using Option::contains with
`iter().any(...)`.

Change-Id: Idd507bdc9b35415061e3b7b8b37cc98bbb980c77
Reviewed-on: https://gerrit.readyset.name/c/readyset/+/4612
Tested-by: Buildkite CI
Reviewed-by: Dan Wilbanks <[email protected]>
oli-obk pushed a commit to oli-obk/miri that referenced this issue Apr 4, 2023
Drop unstable `Option::contains`, `Result::contains`, `Result::contains_err`

This is a proposal to drop the three functions `Option::contains`, `Result::contains` and `Result::contains_err`.

The discovery of `Option::is_some_with`/`Result::is_ok_with`/`Result::is_err_with` in rust-lang/rust#93051 obviates the need for these methods (non-stabilization tracked in rust-lang/rust#62358).

An additional benefit of change is that it avoids spurious error messages in IDEs, when `contains` is supplied by a third-party library:
![option-result-unstable](https://user-images.githubusercontent.com/42493/219127961-13cb559e-6ee8-4449-8dc9-d28d07270ad5.png)
@univerz
Copy link

univerz commented Apr 19, 2023

i tried to remove .contains(&y), but rewriting it to .as_ref().is_some_and(|x| x == &y) annoyed me so much i had to re/introduce Contains trait into my stdx.rs file

@bjorn
Copy link

bjorn commented Apr 19, 2023

@univerz As per above commit one could also replace by iter().any(...), but it is only a little bit shorter so not any less annoying. I'm sad about the outcome of this issue. :-(

@soc
Copy link
Contributor

soc commented Apr 19, 2023

@univerz Perhaps option-ext can be of use to you!

thomcc pushed a commit to tcdi/postgrestd that referenced this issue Jun 1, 2023
Drop unstable `Option::contains`, `Result::contains`, `Result::contains_err`

This is a proposal to drop the three functions `Option::contains`, `Result::contains` and `Result::contains_err`.

The discovery of `Option::is_some_with`/`Result::is_ok_with`/`Result::is_err_with` in rust-lang/rust#93051 obviates the need for these methods (non-stabilization tracked in rust-lang/rust#62358).

An additional benefit of change is that it avoids spurious error messages in IDEs, when `contains` is supplied by a third-party library:
![option-result-unstable](https://user-images.githubusercontent.com/42493/219127961-13cb559e-6ee8-4449-8dc9-d28d07270ad5.png)
RalfJung pushed a commit to RalfJung/rust-analyzer that referenced this issue Apr 20, 2024
Drop unstable `Option::contains`, `Result::contains`, `Result::contains_err`

This is a proposal to drop the three functions `Option::contains`, `Result::contains` and `Result::contains_err`.

The discovery of `Option::is_some_with`/`Result::is_ok_with`/`Result::is_err_with` in rust-lang/rust#93051 obviates the need for these methods (non-stabilization tracked in rust-lang/rust#62358).

An additional benefit of change is that it avoids spurious error messages in IDEs, when `contains` is supplied by a third-party library:
![option-result-unstable](https://user-images.githubusercontent.com/42493/219127961-13cb559e-6ee8-4449-8dc9-d28d07270ad5.png)
RalfJung pushed a commit to RalfJung/rust-analyzer that referenced this issue Apr 27, 2024
Drop unstable `Option::contains`, `Result::contains`, `Result::contains_err`

This is a proposal to drop the three functions `Option::contains`, `Result::contains` and `Result::contains_err`.

The discovery of `Option::is_some_with`/`Result::is_ok_with`/`Result::is_err_with` in rust-lang/rust#93051 obviates the need for these methods (non-stabilization tracked in rust-lang/rust#62358).

An additional benefit of change is that it avoids spurious error messages in IDEs, when `contains` is supplied by a third-party library:
![option-result-unstable](https://user-images.githubusercontent.com/42493/219127961-13cb559e-6ee8-4449-8dc9-d28d07270ad5.png)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-result-option Area: Result and Option combinators B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC disposition-close This PR / issue is in PFCP or FCP with a disposition to close it. finished-final-comment-period The final comment period is finished for this PR / Issue. Libs-Small Libs issues that are considered "small" or self-contained Libs-Tracked Libs issues that are tracked on the team's project board. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests