Substr slice giving temporary value

Hi again and sorry for the bunch of questions.

/// Scalar Value string type.
#[derive(Clone, PartialEq, PartialOrd)]
pub struct SvStr {
    m_chars: Vec<char>,
}

impl SvStr {
    pub fn slice(&self, mut from: i64, mut to: i64) -> SvStr {
        from = i64::max(0, from);
        from = i64::min(from, self.len());
        to = i64::max(0, to);
        to = i64::min(to, self.len());
        SvStr { m_chars: self.m_chars[(from as usize)..(to as usize)].to_vec() }
    }
}

impl Index<&dyn SvStrSliceIndex> for SvStr {
    type Output = SvStr;

    fn index(&self, index: &dyn SvStrSliceIndex) -> &Self::Output {
        // ERROR in following line!
        // cannot return reference to temporary value
        // returns a reference to data owned by the current function rustc E0515
        // lib.rs(89, 10): temporary value created here
        &self.slice(index.from_idx(), index.to_idx())
    }
}

pub trait SvStrSliceIndex {
    fn from_idx(&self) -> i64;
    fn to_idx(&self) -> i64;
}

Any idea? I tried to move code from slice() to Index's fn index(), but still failling.

The Index trait can only return a reference to a value already stored inside self. Since the return value of slice is not stored inside self, you can't return it.

2 Likes

I see... I'm trying to receive a Range in slice(), but I'm getting forced to borrow the range:

// ...
    pub fn slice(&self, index: &dyn SvStrSliceIndex) -> SvStr {
        self.slice_private(index.from_idx(), index.to_idx())
    }

    fn slice_private(&self, mut from: i64, mut to: i64) -> SvStr {
        from = i64::max(0, from);
        from = i64::min(from, self.len());
        to = i64::max(0, to);
        to = i64::min(to, self.len());
        SvStr { m_chars: self.m_chars[(from as usize)..(to as usize)].to_vec() }
    }
// ...

Yes, one character: s.slice(&0..10);, but I'd like to omit it anyway.

Just needed a type parameter with the bound SvStrSliceIndex:

pub fn slice<I: SvStrSliceIndex>(&self, index: I) -> SvStr {
    self.slice_private(index.from_idx(), index.to_idx())
}