Skip to content

Tracking issue for slice_take #62280

Closed

Description

@cramertj

Feature gate: #![feature(slice_take)]

Public API

impl<T> [T] {
    fn split_off<'a, R: OneSidedRange<usize>>(self: &mut &'a Self, range: R) -> Option<&'a Self>;
    fn split_off_mut<'a, R: OneSidedRange<usize>>(self: &mut &'a mut Self, range: R) -> Option<&'a mut Self>;
    fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T>;
    fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T>;
    fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T>;
    fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T>;
}


// core::ops

trait OneSidedRange<T: ?Sized>: RangeBounds<T> {}
impl<T> OneSidedRange<T> for RangeTo<T> where Self: RangeBounds<T>;
impl<T> OneSidedRange<T> for RangeFrom<T> where Self: RangeBounds<T>;
impl<T> OneSidedRange<T> for RangeToInclusive<T> where Self: RangeBounds<T>;

Steps / History

Unresolved Questions

Activity

  1. added
    T-libs-api[DEPRECATED; DO NOT USE]
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    on Jul 1, 2019
  2. KodrAus commented on Jul 30, 2020

    @KodrAus
  3. m-ou-se commented on Nov 28, 2020

    @m-ou-se
  4. SimonSapin commented on Jan 31, 2022

    @SimonSapin
    Contributor

    https://doc.rust-lang.org/nightly/std/ops/trait.OneSidedRange.html links to #69780 which is closed. Either it should be reopened (and some details filled in) or #[unstable] attributes should be changed to point here instead, depending on whether it’s useful to track OneSidedRange separately.

  5. lilyball commented on Apr 27, 2022

    @lilyball
    Contributor

    Can we implement OneSidedRange for RangeFull as well? I'd like to be able to say self.slice.take(..) as a shorthand for std::mem::swap(&mut self.slice, &[]) (or I suppose for self.slice.take(0..)). This doesn't fit the naming OneSidedRange or the description that says the range is unbounded on one side1, but I don't see any reason why RangeFull should not be usable here.

    Footnotes

    1. Technically it doesn't say it has to be bounded on the other side, but it does list .. as a non-compliant type. ↩

  6. andersk commented on Nov 4, 2022

    @andersk
    Contributor

    Can we implement OneSidedRange for RangeFull as well?

    Perhaps also rename OneSidedRange to UnboundedRange, in that case?

  7. safinaskar commented on Jun 3, 2023

    @safinaskar
    Contributor

    Please, rename. Method take is unusable with its current name, because it conflicts with std::io::Read::take.

    Let me describe my actual production use case.

    First I read some data from file using std::io::Read::read_to_end. To be able to read data I have to write use std::io::Read. Then I started to parse that data using various functions, including <[T]>::take. But I was unable to do this because of use std::io::Read, see playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=e467873898a5f160420a5d6f13274ffa

  8. clarfonthey commented on Jun 5, 2023

    @clarfonthey
    Contributor

    FYI: #69780 is still being linked for OneSideRange in the docs when that issue is closed; should the tracking issue be moved to here?

  9. jongiddy commented on Jul 1, 2023

    @jongiddy
    Contributor

    I agree with @safinaskar that a different name for take (and take_mut) should be considered. I like take_slice and take_slice_mut for the current API.

    But changing the API to replace take(range) with take_before(usize) and take_after(usize) (and possibly take_all()) would be clearer and removes the need to resolve issues with OneSidedRange.

  10. jongiddy commented on Sep 25, 2023

    @jongiddy
    Contributor

    I'd love to see taking from a slice stabilized. But the introduction of OneSidedRange seems to be the wrong path to take. I looked at the previous discussion for the benefits of adding OneSidedRange. They are:

    • "pretty neat"
    • "looks nice"
    • "works with regular indices rather than distances from the end of the slice"
    • "don't have the method naming problem and don't have to add so many methods"
    • "might be useful in a couple of other scenarios"

    OneSidedRange did not solve the method naming problem, the original design without OneSidedRange can also use regular indices rather than length from the end, and I don't see any other code that uses OneSidedRange. The only objective benefit realized from the above is that the number of methods reduced from 8 to 6.

    Meanwhile the OneSidedRange code requires two match statements to turn the range parameter back into a single index and then call separate paths for the two possible directions. It also adds panic code for the unreachable variants when changing the range to an index and a direction.

    The benefits of OneSidedRange just do not justify the additional complexity, especially as part of the standard library.

    I propose the creation of a new implementation PR to remove OneSidedRange and replace take with take_before and take_after methods + _mut variants. I'm happy to make the PR (but also happy for someone else to do it). But I'd like to check if anyone is strongly opposed first.

    cc @nox @cramertj @timvermeulen @ibraheemdev who worked on the previous implementation PR's.

  11. WaffleLapkin commented on Oct 2, 2023

    @WaffleLapkin
    Member

    @safinaskar this conflict is indeed very unfortunate, however do note that there are workarounds. Notably you can:

    • Import the Read trait in a different module or function (you can write use inside a function) than the usage of the take method
    • Explicitly take mutable reference ((&mut s).take(..1))
    • Explicitly write the function (<[_]>::take(&mut s, ..1))
    • Use the method on a mut ref (s.take(..1) where s has type &mut &[_])

    See playground.

  12. 32 remaining items

  13. rfcbot commented on Feb 18, 2025

    @rfcbot

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

  14. added
    to-announceAnnounce this issue on triage meeting
    and removed
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    on Feb 28, 2025
  15. rfcbot commented on Feb 28, 2025

    @rfcbot

    The final comment period, with a disposition to merge, 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.

    This will be merged soon.

  16. added a commit that references this issue on Mar 4, 2025
    acdf367
  17. added 2 commits that reference this issue on Mar 4, 2025
    60709ff
    29d3ad9
  18. added a commit that references this issue on Mar 5, 2025
    02bd4f5
  19. added 2 commits that reference this issue on Mar 11, 2025
  20. stepancheg commented on Mar 16, 2025

    @stepancheg
    Contributor

    Overlap with Vec might be misleading. @Kimundi raised this concern above, but maybe did not emphasize it enough. Consider this example:

    fn main() {
        let mut v = vec!["a", "b", "c", "d"];
        let _ignore = v.split_off(2);
        println!("{v:?}");
        // prints ["a", "b"]
        
        let v = vec!["a", "b", "c", "d"];
        let _ignore = (&*v).split_off(2..);
        println!("{v:?}");
        // prints ["a", "b", "c", "d"]
    }

    Play.

  21. added this to the 1.87.0 milestone on Mar 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-sliceArea: `[T]`C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libs-api[DEPRECATED; DO NOT USE]disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions