emilk/egui · error

Pos2 index out of bounds: {index}

Error message

Pos2 index out of bounds: {index}

What it means

Pos2 implements Index<usize> so p[0]/p[1] read x/y, but any other index panics with "Pos2 index out of bounds". This is a deliberate guard because a 2D point has only two components; there is no z or further element. The panic reports the offending index and points at the indexing site via track_caller.

Source

Thrown at crates/emath/src/pos2.rs:217

    /// Linearly interpolate towards another point, so that `0.0 => self, 1.0 => other`.
    pub fn lerp(&self, other: Self, t: f32) -> Self {
        Self {
            x: lerp(self.x..=other.x, t),
            y: lerp(self.y..=other.y, t),
        }
    }
}

impl core::ops::Index<usize> for Pos2 {
    type Output = f32;

    #[inline(always)]
    fn index(&self, index: usize) -> &f32 {
        match index {
            0 => &self.x,
            1 => &self.y,
            _ => panic!("Pos2 index out of bounds: {index}"),
        }
    }
}

impl core::ops::IndexMut<usize> for Pos2 {
    #[inline(always)]
    fn index_mut(&mut self, index: usize) -> &mut f32 {
        match index {
            0 => &mut self.x,
            1 => &mut self.y,
            _ => panic!("Pos2 index out of bounds: {index}"),
        }
    }
}

impl PartialEq for Pos2 {
    #[track_caller]
    #[inline]

View on GitHub (pinned to 441971a776)

Solutions

  1. Fix the index to be 0 (x) or 1 (y); for z you need a Vec3/emath Vec3, not Pos2.
  2. Clamp or bound any dynamic index: assert!(i < 2) before p[i].
  3. Use p.x / p.y field access instead of indexing to get compile-time safety.
  4. If the data is truly 3D, change the type from Pos2 to Vec3 rather than indexing Pos2 out of range.

Example fix

// before
let z = pos2[2]; // panics

// after
let z = vec3.z; // use Vec3 for 3 components, or:
let y = pos2.y; // field access instead of index
Defensive patterns

Strategy: type-guard

Validate before calling

// before indexing
let component = |p: emath::Pos2, i: usize| -> Option<f32> {
    match i { 0 => Some(p.x), 1 => Some(p.y), _ => None }
};
assert!(idx < 2, "Pos2 has only x and y");

Type guard

fn pos2_component(p: emath::Pos2, i: usize) -> Option<f32> {
    match i { 0 => Some(p.x), 1 => Some(p.y), _ => None }
}

Try / catch

// panics are not catchable idiomatically in Rust; validate instead
// std::panic::catch_unwind only as a last resort around test code
let v = match idx { 0 => p.x, 1 => p.y, _ => return Err("index out of range") };

Prevention

When it happens

Trigger: Indexing a Pos2 with a value other than 0 or 1, e.g. p[2], p[i] with a loop bound of 3, or indexing with a variable derived from a 3-component loop (pos2[i] in code shared with Vec3).

Common situations: Generic code written for 3D vectors (Vec3) reused on 2D points, loop bounds copied from 3-component data, confusing Pos2 with Rgba (which has 4 components) or Vec3, off-by-one when iterating coordinates.

Related errors


AI-assisted analysis of emilk/egui@441971a776 (2026-09-12). Data as JSON: /api/errors/48e01ebd27d32599. Report an issue: GitHub.