-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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 the SliceIndex
trait
#35729
Comments
Implement RFC 1679 cc #35729 r? @alexcrichton
This is now implemented and will land in the 1.15 release! |
Oh right, this should be the tracking issue for the unstable helper traits... |
SliceIndex
trait
Could we please stabilize this for the next release (or the next next release)? It seems like it is possible to use the new functionality, but it isn't possible to write (transparent) wrappers around it because any reference to the |
@sfackler I forget, was this an intended "never to be stabilized" trait or did we want this on the track to stabilization? @briansmith note that the trait can be vendored locally for now (if necessary) as it's not unstable to implement it, just to use the libstd version. Now that's a huge PITA (especially in multiple crates), but it at least gets the ergonomics immediately! |
I wouldn't call it a "never stabilize" kind of thing, but it's definitely a bit gross in its current form. One suggestion on the RFC was to split out a trait per method which could be a bit cleaner and more extensible in the future. |
@alexcrichton I don't know what you mean by "can be vendored." Here's what I'm trying to write: #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Slice<'a> {
bytes: &'a [u8]
}
impl<'a> Slice<'a> {
#[inline]
pub fn new(bytes: &'a [u8]) -> Slice<'a> {
Slice { bytes: bytes }
}
#[inline]
pub fn get<I>(&self, i: I) -> Option<&I::Output>
where I: std::slice::SliceIndex<u8> {
self.bytes.get(i)
}
} The result is "use of unstable library feature 'slice_get_slice' (see issue #35729))." |
@briansmith oh I just mean that you can add your own That'd work for one crate to get ergonomics, but it wouldn't work at large to continue abstracting over it. |
It'd be nice to see this trait combined with |
@alexcrichton I'm not sure what you mean in your recommendation to @briansmith? I want to take a generic slice index argument (i.e., may be a range), and then use it to index into a slice. If I copy the trait into my own crate, I can't then take something implementing that trait and pass to |
@jonhoo oh mean basically just copy/pasting the trait in libstd into your own crate. You wouldn't call |
Until rust-lang/rust#35729 stabilizes, we directly import and implement the `SliceIndex` trait, which lets us work correctly on stable!
This allows to use it as slice indice waiting for the `SliceIndex` trait to be stabilized (rust-lang/rust#35729)
Fixes rust-lang#35729 According to recommendations in rust-lang#35729 (comment)
#51147 implements #35729 (comment) except |
Stabilize SliceIndex trait. CC rust-lang#35729 According to recommendations in rust-lang#35729 (comment)
Stabilize SliceIndex trait. CC rust-lang#35729 According to recommendations in rust-lang#35729 (comment)
Would it be possible to add a blanket impl for |
Oh wait, I just remembered: that would replace specialized code with enum-based dispatch. I don’t know if that ends up being reliably optimized away. |
Couldn't we use impl specialization? |
If this doesn’t simplify the code, why is this blanker impl useful? |
It's useful because otherwise you can't write the following code (which I tried to do, which motivated my commenting here): fn foo<R: RangeBounds<usize>>(buf: &mut [u8], range: R) {
bar(&mut buf[range]);
} |
Can you have a bound on |
Unfortunately not - some of the code actually makes use of the methods on Click to expand
|
… then have two bounds? |
That doesn't work because generic code needs to call Click to expand pub fn slice_mut<'a, T, R: RangeBounds<usize>>(slc: &'a mut [T], range: &R) -> &'a mut [T] {
let lower = resolve_lower_bound(range.start_bound());
let upper = resolve_upper_bound(slc.len(), range.end_bound()).unwrap();
&mut slc[lower..upper]
}
// return the inclusive equivalent of the bound
fn resolve_lower_bound(bound: Bound<&usize>) -> usize {
match bound {
Bound::Included(x) => *x,
Bound::Excluded(x) => *x + 1,
Bound::Unbounded => 0,
}
}
// return the exclusive equivalent of the bound, verifying that it is in
// range of len
fn resolve_upper_bound(len: usize, bound: Bound<&usize>) -> Option<usize> {
let bound = match bound {
Bound::Included(x) => *x + 1,
Bound::Excluded(x) => *x,
Bound::Unbounded => len,
};
if bound > len {
return None;
}
Some(bound)
} |
Oh, sorry, I guess you mean have the bound |
Yes, if you want to do with a generic type two things that each require a different trait, have your own code require both traits. |
Oh, and one other issue. Since |
This higher-ranked trait bounds rather than types, but yeah, good point. |
This requires Rust 1.28.0, due to usage of [1], so I guess we'll have to gate it on the rustc version. [1]: rust-lang/rust#35729
Is there any chance of providing a way of implementing |
Tracking issue for rust-lang/rfcs#1679
The implementations are stable, but the
SliceIndex
trait is not.The text was updated successfully, but these errors were encountered: