{"record":{"id":"f2fef1664a9f7203","repo":"pola-rs/polars","slug":"cannot-use-end-position-on-a-negative-slice","errorCode":null,"errorMessage":"cannot use end_position() on a negative slice","messagePattern":"cannot use end_position\\(\\) on a negative slice","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-utils/src/slice_enum.rs","lineNumber":54,"sourceCode":"    /// Returns the offset of a positive slice.\n    ///\n    /// # Panics\n    /// Panics if `self` is [`Slice::Negative`]\n    pub fn positive_offset(&self) -> usize {\n        let Slice::Positive { offset, len: _ } = self.clone() else {\n            panic!(\"cannot use positive_offset() on a negative slice\");\n        };\n\n        offset\n    }\n\n    /// Returns the end position of the slice (offset + len).\n    ///\n    /// # Panics\n    /// Panics if self is negative.\n    pub fn end_position(&self) -> usize {\n        let Slice::Positive { offset, len } = self.clone() else {\n            panic!(\"cannot use end_position() on a negative slice\");\n        };\n\n        offset.saturating_add(len)\n    }\n\n    /// Returns the equivalent slice to apply from an offsetted position.\n    ///\n    /// # Panics\n    /// Panics if self is negative.\n    pub fn offsetted(self, position: usize) -> Self {\n        let Slice::Positive { offset, len } = self else {\n            panic!(\"cannot use offsetted() on a negative slice\");\n        };\n\n        let (offset, len) = if position <= offset {\n            (offset - position, len)\n        } else {\n            let n_past_offset = position - offset;","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/crates/polars-utils/src/slice_enum.rs#L36-L72","documentation":"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.","triggerScenarios":"Calling end_position() on a Slice::Negative value, e.g. computing range ends for a slice produced from a negative slice expression.","commonSituations":"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.","solutions":["Match on the Slice enum and handle Slice::Negative explicitly before computing an end position","Resolve the negative slice against the concrete length first, then call end_position()","Guard call sites with an is_positive-style check or assertion"],"exampleFix":"// before\nlet end = slice.end_position();\n// after\nlet end = match &slice {\n    Slice::Positive { offset, len } => offset.saturating_add(*len),\n    Slice::Negative { .. } => panic!(\"resolve negative slice against length first\"),\n};","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn as_positive(s: &Slice) -> Option<(usize, usize)> {\n    match s { Slice::Positive { offset, len } => Some((*offset, *len)), _ => None }\n}","tryCatchPattern":null,"preventionTips":["Never assume a Slice is positive; match on the enum at boundaries","Resolve negative slices against a known length before computing end positions","Add tests for negative-index slicing paths"],"tags":["rust","panic","invalid-state","slices"],"backgroundTag":"invalid-state-transition","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}