Open
Description
Motivation
There are times where "indexing" is desired but returning a literal reference is suboptimal or impossible.
@cuviper said (lightly edited by me):
For example, ndarray would want to return
ArrayView<'_, ..>
. For mutable indexing, it would wantArrayViewMut<'_, ..>
. GAT indexing would need a distinct typeOutput<'_>
[for each mutability]. Currently, without GAT, they useslice
andslice_mut
methods.
We recognize that this requires GATs and something else to be able to truly supplant core::ops::Index
and the []
syntax.
Details
A concrete example of the problem:
#![feature(generic_associated_types)]
fn main() {
let c = Container(42);
// Nightly
let w = c.index(());
// Desired, strawman syntax
let w = &c[()];
w.hello();
}
struct Wrapper<'a>(&'a u8);
impl Wrapper<'_> {
fn hello(&self) {
eprintln!("Hello, {}", self.0);
}
}
struct Container(u8);
impl Index<()> for Container {
type Output<'a> = Wrapper<'a>;
fn index(&self, index: ()) -> Self::Output<'_> {
Wrapper(&self.0)
}
}
pub trait Index<Idx>
where
Idx: ?Sized,
{
type Output<'a>: ?Sized
where
Self: 'a;
fn index(&self, index: Idx) -> Self::Output<'_>;
}
References in the wild
- How to implement std::ops::Index when the output value is not part of the type
- Implementing Index trait to return a value that is not a reference
- How to wrap a borrowed value in a newtype that is also a borrowed value?
Related traits
These traits might also conceptually benefit from similar ability:
Deref
Borrow
Metadata
Metadata
Assignees
Labels
No labels