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 RangeBounds #30877

Closed
durka opened this Issue Jan 13, 2016 · 75 comments

Comments

Projects
None yet
@durka
Copy link
Contributor

durka commented Jan 13, 2016

This issue tracks the collections_range feature which applies to std::collections::range::RangeArgument. It used to be lumped in with drain (#27711) but that was stabilized while RangeArgument may continue to be affected by experiments with inclusive ranges, so here we are.

@durka

This comment has been minimized.

Copy link
Contributor Author

durka commented Jan 13, 2016

I'm currently working on inclusive ranges, which is why I noticed this. A PR to change the issue link is incoming.

Manishearth added a commit to Manishearth/rust that referenced this issue Jan 14, 2016

bors added a commit that referenced this issue Mar 5, 2016

Auto merge of #30884 - durka:inclusive-ranges, r=aturon
This PR implements [RFC 1192](https://github.com/rust-lang/rfcs/blob/master/text/1192-inclusive-ranges.md), which is triple-dot syntax for inclusive range expressions. The new stuff is behind two feature gates (one for the syntax and one for the std::ops types). This replaces the deprecated functionality in std::iter. Along the way I simplified the desugaring for all ranges.

This is my first contribution to rust which changes more than one character outside of a test or comment, so please review carefully! Some of the individual commit messages have more of my notes. Also thanks for putting up with my dumb questions in #rust-internals.

- For implementing `std::ops::RangeInclusive`, I took @Stebalien's suggestion from rust-lang/rfcs#1192 (comment). It seemed to me to make the implementation easier and increase type safety. If that stands, the RFC should be amended to avoid confusion.
- I also kind of like @glaebhoerl's [idea](rust-lang/rfcs#1254 (comment)), which is unified inclusive/exclusive range syntax something like `x>..=y`. We can experiment with this while everything is behind a feature gate.
- There are a couple of FIXMEs left (see the last commit). I didn't know what to do about `RangeArgument` and I haven't added `Index` impls yet. Those should be discussed/finished before merging.

cc @Gankro since you [complained](https://www.reddit.com/r/rust/comments/3xkfro/what_happened_to_inclusive_ranges/cy5j0yq)
cc #27777 #30877 #1192 rust-lang/rfcs#1254
relevant to #28237 (tracking issue)

bors added a commit that referenced this issue Mar 6, 2016

Auto merge of #30884 - durka:inclusive-ranges, r=aturon
This PR implements [RFC 1192](https://github.com/rust-lang/rfcs/blob/master/text/1192-inclusive-ranges.md), which is triple-dot syntax for inclusive range expressions. The new stuff is behind two feature gates (one for the syntax and one for the std::ops types). This replaces the deprecated functionality in std::iter. Along the way I simplified the desugaring for all ranges.

This is my first contribution to rust which changes more than one character outside of a test or comment, so please review carefully! Some of the individual commit messages have more of my notes. Also thanks for putting up with my dumb questions in #rust-internals.

- For implementing `std::ops::RangeInclusive`, I took @Stebalien's suggestion from rust-lang/rfcs#1192 (comment). It seemed to me to make the implementation easier and increase type safety. If that stands, the RFC should be amended to avoid confusion.
- I also kind of like @glaebhoerl's [idea](rust-lang/rfcs#1254 (comment)), which is unified inclusive/exclusive range syntax something like `x>..=y`. We can experiment with this while everything is behind a feature gate.
- There are a couple of FIXMEs left (see the last commit). I didn't know what to do about `RangeArgument` and I haven't added `Index` impls yet. Those should be discussed/finished before merging.

cc @Gankro since you [complained](https://www.reddit.com/r/rust/comments/3xkfro/what_happened_to_inclusive_ranges/cy5j0yq)
cc #27777 #30877 #1192 rust-lang/rfcs#1254
relevant to #28237 (tracking issue)
@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented Mar 27, 2016

This trait is not actually being exported by std right now, meaning this feature can't be used without importing libcollections. I would submit a PR, but I'm not sure if a new range module in std::collections is the right place to mount it, or if it belongs under a different path.

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Sep 7, 2016

The libs team discussed this, and are placing RangeArgument into a final comment period to stabilize. We will need to tweak the API to support inclusive and exclusive bounds on each side to look something like:

pub enum Bound<T> {
    Unbound,
    Inclusive(T),
    Exclusive(T),
}

pub trait RangeArgument<T> {
    fn lower(&self) -> Bound<&T>;

    fn upper(&self) -> Bound<&T>;
}
@Stebalien

This comment has been minimized.

Copy link
Contributor

Stebalien commented Sep 7, 2016

@sfackler shouldn't the new API go though another stabilization period? Also, a way to extract the bounds by-value would be nice (but probably not necessary).

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Sep 14, 2016

Probably at this point yeah, particularly since we still haven't actually made the change.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Sep 29, 2016

The libs team discussed this at triage the other day and the conclusion was to punt on stabilization/deprecation because we didn't have time to implement the changes here

@clarfon

This comment has been minimized.

Copy link
Contributor

clarfon commented Feb 26, 2017

Question: is there a reason why this trait is in collections but not core?

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Feb 27, 2017

I don't think there's a good reason for it to not be in core off the top of my head - it should probably move!

@J-F-Liu

This comment has been minimized.

Copy link

J-F-Liu commented Mar 8, 2017

Should also impl RangeArgument for usize.

impl RangeArgument<usize> for usize {
    fn start(&self) -> Bound<usize> { Included(self) }
    fn end(&self) -> Bound<usize> { Included(self) }
}
@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Mar 8, 2017

@J-F-Liu There’s also a std::slice::SliceIndex trait that is implemented for both usize and various range types.

@J-F-Liu

This comment has been minimized.

Copy link

J-F-Liu commented Mar 9, 2017

@SimonSapin thanks for let me know this, it indicates should impl RangeArgument for usize as well.
SliceIndex is much more complex than RangeArgument, and its name is not obvious for range purpose.

@clarfon

This comment has been minimized.

Copy link
Contributor

clarfon commented Apr 9, 2017

Would people be willing to accept a PR for moving this to core? Everything would have the same features, and collections would re-export them for compatibility.

Only problem I see is that Bound is already stabilised but I'm not too worried about that.

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Apr 9, 2017

@Gankro

This comment has been minimized.

Copy link
Contributor

Gankro commented May 17, 2017

Can I nominate this for FCP? Seems like it does what it needs to do; fully general.

@glaebhoerl

This comment has been minimized.

Copy link
Contributor

glaebhoerl commented May 17, 2017

I've had various ideas w.r.t. the design which I posted and each time the discussion got moved somewhere else, I can't remember what they were and I'm too lazy to look them up, but at least let's call it something like IsRange instead of RangeArgument because there's nothing limiting it to being used in argument position.

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented May 17, 2017

Seems reasonable to FCP for stabilization. I'd be fine renaming as part of that!

@rfcbot fcp merge

@ltratt

This comment has been minimized.

Copy link
Contributor

ltratt commented Mar 12, 2018

On stable Rust today, you can also write your own RangeArgument trait and impls (or even copy the one in libstd into your own code) and use it in your API.

Yes, good point -- I hadn't considered that. I'm going to do it even though it feels pretty icky. Despite my griping, thanks for the pointer!

@Gankro

This comment has been minimized.

Copy link
Contributor

Gankro commented Mar 13, 2018

In case anyone else has a collection they want RangeArgument for: https://github.com/Gankro/thin-vec/blob/master/src/range.rs

This is an especially clean case of the unstable trait in public API pattern, as there's very little incentive to implement these traits outside of the like 4-5 std types which do.

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Mar 19, 2018

PR #49163: Rename RangeArgument to RangeBounds, move it and Bound to libcore

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Mar 19, 2018

Assuming this PR is accepted, the only issue in this thread that I feel might not be resolved is the possibility of replacing this trait with a type to be used with Into<_>.

@sfackler wrote “the Into<Foo> approach will have troubles with non-copy bounds” but I don’t quite understand what this troubles are. Into::into takes/moves its self argument. Either way, I think that a dedicated trait is fine.

@rust-lang/libs what do you think? If we decide to keep the dedicated trait, should we do another round of FCP or are we good to stabilize? (Again assuming the PR linked above.)

@cmyr cmyr referenced this issue Mar 28, 2018

Merged

Use Range instead of `start` & `end` in Rope impl #576

4 of 4 tasks complete

bors added a commit that referenced this issue Mar 28, 2018

Auto merge of #49163 - SimonSapin:range-bounds, r=alexcrichton
Rename RangeArgument to RangeBounds, move it and Bound to libcore

As proposed in the tracking issue: #30877

Changes to *stable* items:

* `core::ops::Bound` / `std::ops::Bound` is new
* `std::collections::Bound` is a deprecated reexport of it (does this actually cause a warning?)

Changes to *unstable* items

* `alloc::Bound` is gone
* `alloc::range::RangeArgument` is moved to `core::ops::RangeBounds` / `std::ops::RangeBounds`
* `alloc::range` is gone
* `std::collections::range::RangeArgument` is deprecated reexport, to be removed later
* `std::collections::range` is deprecated, to be removed later
* `impl RangeBounds<T> for Range{,From,To,Inclusive,ToInclusive}<&T>` are added

The idea of replacing this trait with a type to be used with `Into<_>` is left for future consideration / work.

bors added a commit that referenced this issue Mar 29, 2018

Auto merge of #49163 - SimonSapin:range-bounds, r=alexcrichton
Rename RangeArgument to RangeBounds, move it and Bound to libcore

As proposed in the tracking issue: #30877

Changes to *stable* items:

* `core::ops::Bound` / `std::ops::Bound` is new
* `std::collections::Bound` is a deprecated reexport of it (does this actually cause a warning?)

Changes to *unstable* items

* `alloc::Bound` is gone
* `alloc::range::RangeArgument` is moved to `core::ops::RangeBounds` / `std::ops::RangeBounds`
* `alloc::range` is gone
* `std::collections::range::RangeArgument` is deprecated reexport, to be removed later
* `std::collections::range` is deprecated, to be removed later
* `impl RangeBounds<T> for Range{,From,To,Inclusive,ToInclusive}<&T>` are added

The idea of replacing this trait with a type to be used with `Into<_>` is left for future consideration / work.

(Fixes rust-lang/rust-clippy#2552.)

@SimonSapin SimonSapin changed the title Tracking issue for RangeArgument Tracking issue for RangeBounds Mar 30, 2018

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Mar 30, 2018

The libs team discussed this and consensus was to stabilize after renaming the methods to start_bound and end_bound to avoid name collision with new inherent start and end methods of RangeInclusive.

@rfcbot fcp merge

Affected APIs are:

pub trait RangeBounds<T: ?Sized> {
    fn start_bound(&self) -> Bound<&T>;
    fn end_bound(&self) -> Bound<&T>;
}

impl<T: ?Sized> RangeBounds<T> for RangeFull {…}
impl<T> RangeBounds<T> for RangeFrom<T> {…}
impl<T> RangeBounds<T> for RangeTo<T> {…}
impl<T> RangeBounds<T> for Range<T> {…}
impl<T> RangeBounds<T> for RangeInclusive<T> {…}
impl<T> RangeBounds<T> for RangeToInclusive<T> {…}
impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) {…}
impl<'a, T: ?Sized + 'a> RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) {…}
impl<'a, T> RangeBounds<T> for RangeFrom<&'a T> {…}
impl<'a, T> RangeBounds<T> for RangeTo<&'a T> {…}
impl<'a, T> RangeBounds<T> for Range<&'a T> {…}
impl<'a, T> RangeBounds<T> for RangeInclusive<&'a T> {…}
impl<'a, T> RangeBounds<T> for RangeToInclusive<&'a T> {…}
@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Mar 30, 2018

Team member @SimonSapin has proposed to merge this. The next step is review by the rest of the tagged teams:

No concerns currently listed.

Once a majority of reviewers approve (and none object), 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.

@scottmcm

This comment has been minimized.

Copy link
Member

scottmcm commented Mar 31, 2018

Since the bikeshed was opened: why not lower_bound and upper_bound if they're going to include the word "bound"?

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Mar 31, 2018

This change is motivated by avoiding collision with the exact start and end method names of RangeInclusive #49022, but they’re still strongly related to those as well as the start and end fields of other range types. I think the names should reflect that relation in some way.

@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Apr 11, 2018

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

@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Apr 21, 2018

The final comment period is now complete.

coryshrmn added a commit to coryshrmn/rust that referenced this issue May 24, 2018

stabilize RangeBounds collections_range rust-lang#30877
rename RangeBounds::start() -> start_bound()
rename RangeBounds::end() -> end_bound()

coryshrmn added a commit to coryshrmn/rust that referenced this issue May 24, 2018

remove collections::range::RangeArgument
was already moved to ops::RangeBounds (see rust-lang#30877)

coryshrmn added a commit to coryshrmn/rust-clippy that referenced this issue May 24, 2018

rename RangeArgument->RangeBounds
The collections_range FPC closed,
with the decision to rename to RangeBounds::start_bound().

rust-lang/rust#30877

bors added a commit that referenced this issue May 25, 2018

Auto merge of #51033 - coryshrmn:master, r=dtolnay
stabilize RangeBounds collections_range #30877

The FCP for #30877 closed last month, with the decision to:
1. move from `collections::range::RangeArgument` to `ops::RangeBounds`, and
2. rename `start()` and `end()` to `start_bounds()` and `end_bounds()`.

Simon Sapin already moved it to `ops::RangeBounds` in #49163.

I renamed the functions, and removed the old `collections::range::RangeArgument` alias.

This is my first Rust PR, please let me know if I can improve anything. This passes all tests for me, except the `clippy` tool (which uses `RangeArgument::start()`).

I considered deprecating `start()` and `end()` instead of removing them, but the contribution guidelines indicate we can break `clippy` temporarily. I thought it was best to remove the functions, since we're worried about name collisions with `Range::start` and `end`.

Closes #30877.

@bors bors closed this in #51033 May 26, 2018

@DDOtten

This comment has been minimized.

Copy link

DDOtten commented Jul 1, 2018

I think a method like fn into_bounds(self) -> (Bound<T>, Bound<T>) would be very helpful. Currently RangeInclusive implements into_inner but other range types do not. (It also is the only range type to implement new, start and end and the only one to where the inner types are not public)

This would give a way to get the inner values without having to use clone. I am currently implementing a trie/prefix-tree and want to add a range function similar to a BTreeMap. This function takes something like a RangeBounds<I> where I: IntoIterator<T>. I would like to avoid an extra Clone bound for I and cloning these types is less efficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.