{"record":{"id":"9775d39c80a7612a","repo":"pola-rs/polars","slug":"cannot-convert-negative-slice-into-range","errorCode":null,"errorMessage":"cannot convert negative slice into range","messagePattern":"cannot convert negative slice into range","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-utils/src/slice_enum.rs","lineNumber":171,"sourceCode":"                -i128::try_from(offset_from_end).unwrap(),\n                i128::try_from(len).unwrap(),\n            ),\n        }\n    }\n}\n\nimpl From<Slice> for Range<usize> {\n    fn from(value: Slice) -> Self {\n        match value {\n            Slice::Positive { offset, len } => {\n                offset\n                    ..offset\n                        .checked_add(len)\n                        // Infer if no len was specified, in which case we set to range end to the max possible.\n                        .or((len == usize::MAX).then_some(usize::MAX))\n                        .unwrap()\n            },\n            Slice::Negative { .. } => panic!(\"cannot convert negative slice into range\"),\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::Slice;\n\n    #[test]\n    fn test_slice_offset() {\n        assert_eq!(\n            Slice::Positive { offset: 3, len: 10 }.offsetted(1),\n            Slice::Positive { offset: 2, len: 10 }\n        );\n        assert_eq!(\n            Slice::Positive { offset: 3, len: 10 }.offsetted(5),\n            Slice::Positive { offset: 0, len: 8 }\n        );","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/crates/polars-utils/src/slice_enum.rs#L153-L189","documentation":"The From<Slice> for Range<usize> conversion hits unwrap() on checked_add when converting a slice whose offset+len overflows usize and no sentinel (len == usize::MAX meaning 'to the end') applies — an overflowing/impossible slice cannot be expressed as a Range.","triggerScenarios":"Converting a Slice::Negative to a Range (e.g. via .into() or From), typically when a slice expression like [:-3] reached code that materializes ranges.","commonSituations":"Passing user-supplied negative slice bounds into APIs that build ranges internally; iterating rows with slice.to_range() on negative slices.","solutions":["Resolve negative slices against the collection length before converting to a range","Match on the Slice enum and build the range yourself for Slice::Negative","Restrict inputs to non-negative slices at the boundary where users provide them"],"exampleFix":"// before\nlet range: Range<usize> = slice.into();\n// after\nlet range = match slice {\n    Slice::Positive { offset, len } => offset..offset + len,\n    Slice::Negative { offset, len } => (total_len - offset - len)..(total_len - offset),\n};","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def slice_to_range(s, total_len):\n    if s.is_negative():\n        return Range(total_len - s.offset - s.len, total_len - s.offset)\n    return Range(s.offset, s.offset + s.len)","tryCatchPattern":null,"preventionTips":["Only convert positive slices to ranges; handle Slice::Negative explicitly","Reject or resolve negative user-supplied slices at the API boundary","Prefer iterating with the Slice API rather than raw ranges"],"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"}