pola-rs/polars · error

cannot use end_position() on a negative slice

Error message

cannot use end_position() on a negative slice

What it means

Slice::end_position is only defined for Slice::Positive; calling it on a Slice::Negative (a slice counted from the end, whose absolute position depends on the total length) panics because the end position cannot be known without resolving the negative slice first.

Solutions

  1. Match on the Slice enum and handle Slice::Negative explicitly before computing an end position
  2. Resolve the negative slice against the concrete length first, then call end_position()
  3. Guard call sites with an is_positive-style check or assertion

Example fix

// before
let end = slice.end_position();
// after
let end = match &slice {
    Slice::Positive { offset, len } => offset.saturating_add(*len),
    Slice::Negative { .. } => panic!("resolve negative slice against length first"),
};
Defensive patterns

Strategy: type-guard

Type guard

fn as_positive(s: &Slice) -> Option<(usize, usize)> {
    match s { Slice::Positive { offset, len } => Some((*offset, *len)), _ => None }
}

Prevention

When it happens

Trigger: Calling end_position() on a Slice::Negative value, e.g. computing range ends for a slice produced from a negative slice expression.

Common situations: Same family as 281: code paths assuming positive slices, often when slicing DataFrames/Series with expressions like s[-10:] or when converting slices to ranges.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/f2fef1664a9f7203. Report an issue: GitHub.

Appendix: source

Thrown at crates/polars-utils/src/slice_enum.rs:54

    /// Returns the offset of a positive slice.
    ///
    /// # Panics
    /// Panics if `self` is [`Slice::Negative`]
    pub fn positive_offset(&self) -> usize {
        let Slice::Positive { offset, len: _ } = self.clone() else {
            panic!("cannot use positive_offset() on a negative slice");
        };

        offset
    }

    /// Returns the end position of the slice (offset + len).
    ///
    /// # Panics
    /// Panics if self is negative.
    pub fn end_position(&self) -> usize {
        let Slice::Positive { offset, len } = self.clone() else {
            panic!("cannot use end_position() on a negative slice");
        };

        offset.saturating_add(len)
    }

    /// Returns the equivalent slice to apply from an offsetted position.
    ///
    /// # Panics
    /// Panics if self is negative.
    pub fn offsetted(self, position: usize) -> Self {
        let Slice::Positive { offset, len } = self else {
            panic!("cannot use offsetted() on a negative slice");
        };

        let (offset, len) = if position <= offset {
            (offset - position, len)
        } else {
            let n_past_offset = position - offset;

View on GitHub (pinned to fe841f959e)