astral-sh/ruff · error
i is bounded by INLINE_MAX_SEGMENTS
Error message
i is bounded by INLINE_MAX_SEGMENTS
What it means
SmallSegments packs up to 7 member-access segments into a single u64. try_from_slice returns None up front when segments.len() > INLINE_MAX_SEGMENTS (7), so inside the loop u32::try_from(i) with i < 7 cannot fail; .expect("i is bounded by INLINE_MAX_SEGMENTS") documents that invariant, not a user-facing condition.
Source
Thrown at crates/ty_python_core/src/member.rs:878
}
// Pack into inline representation
// Store count minus 1 (since segments are never empty, range 0-6 represents 1-7 segments)
let mut packed = (segments.len() - 1) as u64;
let mut prev_offset = TextSize::new(0);
for (i, segment) in segments.iter().enumerate() {
// Compute relative offset on-the-fly
let relative_offset = segment.offset() - prev_offset;
if relative_offset > TextSize::from(INLINE_MAX_RELATIVE_OFFSET) {
return None;
}
let kind = segment.kind() as u64;
let relative_offset_val = u64::from(relative_offset.to_u32());
let segment_data = (relative_offset_val << INLINE_KIND_BITS) | kind;
let shift = INLINE_COUNT_BITS
+ (u32::try_from(i).expect("i is bounded by INLINE_MAX_SEGMENTS")
* INLINE_SEGMENT_BITS);
packed |= segment_data << shift;
prev_offset = segment.offset();
}
Some(Self(packed))
}
#[expect(
clippy::cast_possible_truncation,
reason = "INLINE_COUNT_MASK ensures value is at most 7"
)]
const fn len(self) -> usize {
// Add 1 because we store count minus 1
((self.0 & INLINE_COUNT_MASK) + 1) as usize
}
View on GitHub (pinned to fca5c7cf2c)
Solutions
- Keep the segments.len() > INLINE_MAX_SEGMENTS early-return consistent with the bit layout whenever the constants change
- If observed at runtime, capture a repro and file a ty issue - the value was produced through an unsupported path
- Keep unit tests covering the 6/7/8-segment boundary in pack/iterate round trips
Defensive patterns
Strategy: validation
Validate before calling
assert!(segments.len() <= INLINE_MAX_SEGMENTS); // keep paired with the packing layout
Try / catch
let packed = std::panic::catch_unwind(|| SmallSegments::try_from_slice(&segs)); // fuzz harness isolation only
Prevention
- When changing INLINE_* bit constants, update the length guard and layout doc together
- Construct SmallSegments only via try_from_slice
- Round-trip test pack/iterate at the 7-segment boundary
When it happens
Trigger: Only reachable if the early-return guard at the top of try_from_slice is removed or changed inconsistently with the bit layout, or a SmallSegments value is constructed bypassing try_from_slice - an internal regression, not an input-driven failure.
Common situations: Contributors editing the packing constants (INLINE_COUNT_BITS, INLINE_SEGMENT_BITS, INLINE_MAX_SEGMENTS) without keeping the guard in sync; fuzzers mutating the packed representation.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- index is bounded by INLINE_MAX_SEGMENTS
- expected class
- expected function
- expected type alias
- PySourceType always parses into a module
AI-assisted analysis of astral-sh/ruff@fca5c7cf2c (2026-08-20).
Data as JSON: /api/errors/9f5eacd324755566.
Report an issue: GitHub.