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 Cow::is_borrowed and Cow::is_owned #65143

Open
clarfonthey opened this issue Oct 5, 2019 · 24 comments
Open

Tracking issue for Cow::is_borrowed and Cow::is_owned #65143

clarfonthey opened this issue Oct 5, 2019 · 24 comments
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. 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

@clarfonthey
Copy link
Contributor

clarfonthey commented Oct 5, 2019

I just tried to use these in my own code and was kind of shocked they didn't exist.

Justification: this seems like a common Rust pattern. We have is_some and is_none for Option, is_ok and is_err for Result, etc., so, it seems pretty fair to have is_borrowed and is_owned for Cow.

Having as_borrowed and as_owned wouldn't really make much sense, as a simple & and &mut/to_mut cover those use cases. But, these check functions are pretty useful on their own.

@jonas-schievink jonas-schievink added C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. B-unstable Blocker: Implemented in the nightly compiler and unstable. and removed C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Oct 5, 2019
@clarfonthey clarfonthey changed the title Cow::is_borrowed and Cow::is_owned Tracking issue: Cow::is_borrowed and Cow::is_owned Oct 5, 2019
@petertodd
Copy link
Contributor

I'm no expert on how backwards compatibility is handled. But Cow implements Deref, which means these new methods wouldn't be backwards compatible as they'd conflict with methods of the same name on the inner object. To fix this you'll have to change them to take cow: &Self, similar to what most of the methods on Box/Rc etc. take.

@SimonSapin SimonSapin changed the title Tracking issue: Cow::is_borrowed and Cow::is_owned Feature request: Cow::is_borrowed and Cow::is_owned Oct 18, 2019
@SimonSapin SimonSapin added C-feature-request Category: A feature request, i.e: not implemented / a PR. and removed B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. labels Oct 18, 2019
@SimonSapin
Copy link
Contributor

Procedural: I’ve edited the title and labels to reflect that this is not implemented.

My opinion: I’m not sure that these method carry their weight, since if let Cow::Borrowed(_) = foo or matches!(foo, Cow::Borrowed(_)) can be used. Neither of these existed when Option::is_some was added, and Option is much more common than Cow.

@clarfonthey
Copy link
Contributor Author

@petertodd That's fair; that said, though, I think that having methods named is_borrowed or is_owned on a type which implements ToOwned would be extremely unusual, because to_owned would not affect said methods.

@SimonSapin I agree that Option is much more common than Cow, but I feel that these are still useful enough to carry their own weight. This is partially because I was writing code and was honestly surprised they didn't exist, so, I'm already pre-biased to assume that they should exist.

Mostly, I figured that adding these methods would be worthwhile because they're unlikely to clash with existing ones, and can incubate in nightly for a while to see if they do carry their weight. If they don't, they can be removed.

Centril added a commit to Centril/rust that referenced this issue Oct 23, 2019
Add Cow::is_borrowed and Cow::is_owned

Implements rust-lang#65143.
@clarfonthey
Copy link
Contributor Author

It appears that this is now merged.

Centril added a commit to Centril/rust that referenced this issue Oct 23, 2019
Add Cow::is_borrowed and Cow::is_owned

Implements rust-lang#65143.
@clarfonthey
Copy link
Contributor Author

@SimonSapin it would make sense to revert the changes to the title and tags, or discuss here whether the change should be reverted.

@SimonSapin SimonSapin changed the title Feature request: Cow::is_borrowed and Cow::is_owned Tracking issue for Cow::is_borrowed and Cow::is_owned Oct 27, 2019
@SimonSapin SimonSapin added B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. and removed C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Oct 27, 2019
@SimonSapin
Copy link
Contributor

Done.

@SimonSapin
Copy link
Contributor

Sorry for the somewhat-pointless churn, I’d gotten here from https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AC-tracking-issue+label%3AT-libs and hadn’t realized there was an implementation PR already.

@clarfonthey
Copy link
Contributor Author

All good! Thanks for updating things :)

@KodrAus KodrAus added the Libs-Tracked Libs issues that are tracked on the team's project board. label Jul 30, 2020
CDirkx pushed a commit to CDirkx/rust that referenced this issue Aug 31, 2020
Constify the following methods of `alloc::borrow::Cow`:
 - `is_borrowed`
 - `is_owned`

These methods are still unstable under `cow_is_borrowed`.
Possible because of rust-lang#49146 (Allow if and match in constants).

Tracking issue: rust-lang#65143
tmandry added a commit to tmandry/rust that referenced this issue Sep 1, 2020
…morse

Make `cow_is_borrowed` methods const

Constify the following methods of `alloc::borrow::Cow`:
 - `is_borrowed`
 - `is_owned`

Analogous to the const methods `is_some` and `is_none` for Option, and `is_ok` and `is_err` for Result.

These methods are still unstable under `cow_is_borrowed`.
Possible because of rust-lang#49146 (Allow if and match in constants).

Tracking issue: rust-lang#65143
@zbraniecki
Copy link

Is anything blocking this from being stabilized?

@fosskers
Copy link

Six month check-in: I don't see any issues involving these on the Issue Tracker. Can we move to the next stage?

@antmelnyk
Copy link

Quite sad it's not stabilized yet. Are there any issues? 🥲 I find the method would be pretty convenient when cloning of the content under Cow is bad and has to be double-checked for being Owned in critical places.

Example:

if my_expensive_thing.is_borrowed() {
  return Err(MyError::AttemptToCloneExpensiveThing);
} else {
  do_something_heavy(my_expensive_thing.to_mut());
}

@SimonSapin
Copy link
Contributor

At this point I feel this should be fine to stabilize, but until that happens you can match a pattern: #65143 (comment)

@clarfonthey
Copy link
Contributor Author

Going through some old issues. Is there anything stopping this from going into FCP? I found myself using one of these methods again recently.

@robjtede
Copy link
Contributor

robjtede commented Jul 29, 2023

I can't see a strong case for the inherent methods over match cow {} or matches!(cow, Cow::Owned(_)) nor can I think of any compelling uses for passing a Cow::is_owned fn pointer.

Let-else being stabilized surely plays into this decision, too.

@clarfonthey
Copy link
Contributor Author

clarfonthey commented Jul 30, 2023

I would agree, but there exist other methods like is_some, is_ok, and is_err which are also useful but could be replaced by similar patterns.

EDIT: Note, below may be wrong in most cases:

Another important thing to consider is that the method ensures that you're always borrowing the argument, whereas matches!(cow, Cow::Owned(_)) would consume cow by-value and require adding &cow.

@robjtede
Copy link
Contributor

matches!(cow, Cow::Owned(_)) would consume cow by-value and require adding &cow

That's not the case. See this playground.

You'd have to name the inner pattern for there to be an issue. E.g., matches!(cow, Cow::Owned(_cow)).

@clarfonthey
Copy link
Contributor Author

Hmm, I guess you're right then. Still, I question whether such usages are always-applicable (e.g. if there's some usage that might break it), and the original point about other methods existing still stands. IMHO, unless those other methods are deprecated (which seems unlikely), this method should be considered for inclusion.

@yshavit
Copy link

yshavit commented Jun 30, 2024

One use case for which I wanted these: I'm writing unit tests in which I want to differentiate between a borrowed and owned Cow. I have a helper function that takes a expected: Cow<Foo> as well as some inputs, then calls the method-under-test on the inputs to get an actual Cow:

fn check(expected: Cow<Foo>, input: &str) {
    let actual = method_under_test(input);
    assert_eq!(expected, actual); // does not differentiate between borrowed or owned
    assert_eq!(expected.is_owned(), actual.is_owned());
}

It's not hard to work around the absence of this method, and I don't know if it's worth adding the method just for that use case; but I figured I'd mention it.

(I'm also a self-taught Rust newbie, so it's possible there's a better way to do this that I just don't know!)

@GKFX
Copy link
Contributor

GKFX commented Aug 25, 2024

For the assertion in that unit test, you can assert_eq two matches! calls, which is only marginally longer.

More broadly, I don’t think it is reasonable for all enums to provide is_ methods. Pattern matching has become substantially more ergonomic over time, and is likely to be improved further with e.g. if-let chaining. IMO if suitable language features exist they should be used, rather than providing more functions which bloat the API for little benefit.

@clarfonthey
Copy link
Contributor Author

I believe this proposal actually predates matches!, huh.

Yeah, I guess it's fair to say that pattern-matching is the best way to do this. We'll see what people prefer.

@petertodd
Copy link
Contributor

petertodd commented Sep 3, 2024 via email

@robjtede
Copy link
Contributor

robjtede commented Sep 3, 2024

The only case where matches! might not be desired (only via preference) is when passing a function reference (e.g., .filter(Cow::is_owned)) though certainly this is a less useful method than other types in std when it comes to filter/filter_map etc.

@murlakatamenka
Copy link

While matches! is a working solution, is_borrowed/is_owned would be much less cognitively demanding one, so to speak. More like natural language (if cow is owned, then). And IDE completion friendly, easy to find: cow.<TAB COMPLETION>. While know and remember matches!(cow, Cow::Owned(_)) you must know and remember.

We already write option.is_some(), result.is_ok(), str.is_empty() etc right?

All the is_* methods to complete the picture:

https://doc.rust-lang.org/std/?search=is_


That's why I'd like to see this stabilized one day, even if it's just a syntax sugar for some.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 12, 2024
…tgross35

remove const_cow_is_borrowed feature gate

The two functions guarded by this are still unstable, and there's no reason to require a separate feature gate for their const-ness -- we can just have `cow_is_borrowed` cover both kinds of stability.

Cc rust-lang#65143
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 12, 2024
…tgross35

remove const_cow_is_borrowed feature gate

The two functions guarded by this are still unstable, and there's no reason to require a separate feature gate for their const-ness -- we can just have `cow_is_borrowed` cover both kinds of stability.

Cc rust-lang#65143
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Oct 13, 2024
Rollup merge of rust-lang#131617 - RalfJung:const_cow_is_borrowed, r=tgross35

remove const_cow_is_borrowed feature gate

The two functions guarded by this are still unstable, and there's no reason to require a separate feature gate for their const-ness -- we can just have `cow_is_borrowed` cover both kinds of stability.

Cc rust-lang#65143
@scovich
Copy link

scovich commented Nov 4, 2024

While matches! is a working solution, is_borrowed/is_owned would be much less cognitively demanding one, so to speak. More like natural language (if cow is owned, then). And IDE completion friendly, easy to find: cow.<TAB COMPLETION>. While know and remember matches!(cow, Cow::Owned(_)) you must know and remember.

We already write option.is_some(), result.is_ok(), str.is_empty() etc right?

+1 from me here -- every time I've tried to use matches! in the past (for any reason), reviewers complain that it's hard to read and ask if there's way to avoid it.

As long as this feature isn't stable, I just end up injecting the methods with an extension trait for readability purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. 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