pola-rs/polars · error

not implemented

Error message

not implemented

What it means

The Pushable trait abstracts mutable output arrays for generic kernels. The non-null instantiation Pushable<bool> for MutableBooleanArray implements push and extend_constant, but push_null is a TODO: unimplemented!() (crates/polars-arrow/src/pushable.rs:282). Generic code parameterized over Pushable<bool> panics the first time it must propagate a null slot into the boolean output, e.g. when the input contained nulls.

Source

Thrown at crates/polars-arrow/src/pushable.rs:282

    type Freeze = BooleanArray;
    #[inline]
    fn reserve(&mut self, additional: usize) {
        MutableBooleanArray::reserve(self, additional)
    }

    #[inline]
    fn push(&mut self, value: bool) {
        MutableBooleanArray::push_value(self, value)
    }

    #[inline]
    fn len(&self) -> usize {
        self.values().len()
    }

    #[inline]
    fn push_null(&mut self) {
        unimplemented!()
    }

    #[inline]
    fn extend_constant(&mut self, additional: usize, value: bool) {
        MutableBooleanArray::extend_constant(self, additional, Some(value))
    }

    #[inline]
    fn extend_null_constant(&mut self, _additional: usize) {
        unimplemented!()
    }
    fn freeze(self) -> Self::Freeze {
        self.into()
    }
}

impl Pushable<Option<bool>> for MutableBooleanArray {
    type Freeze = BooleanArray;

View on GitHub (pinned to df599052da)

Solutions

  1. Use the Pushable<Option<bool>> impl instead (it implements push_null via push(None)) and push Some(v)/None
  2. Call the inherent MutableBooleanArray::push(None) / push_null() method directly rather than the trait method
  3. Constrain generic kernels to Pushable<Option<B>> so nullability is part of the contract
  4. Upstream: implement push_null as MutableBooleanArray::push_null(self) — the inherent method already exists

Example fix

// before
fn emit<P: Pushable<bool>>(out: &mut P, v: Option<bool>) {
    match v {
        Some(v) => out.push(v),
        None => out.push_null(), // panics: unimplemented!()
    }
}

// after
fn emit<P: Pushable<Option<bool>>>(out: &mut P, v: Option<bool>) {
    out.push(v); // None is handled by the Option impl
}
Defensive patterns

Strategy: fallback

Type guard

fn supports_null<T, P: Pushable<T>>(_: &P) -> bool { /* false for Pushable<bool>, true for Pushable<Option<bool>> */ }
// practical guard: write kernels against the Option impl
fn kernel<P: Pushable<Option<bool>>>(out: &mut P, v: Option<bool>) {
    out.push(v);
}

Try / catch

let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| out.push_null()));
if res.is_err() {
    // fall back to the inherent, null-aware API
    MutableBooleanArray::push_null(out);
}

Prevention

When it happens

Trigger: A generic kernel written as fn run<P: Pushable<bool>>(out: &mut P, ...) that calls out.push_null() — typically string/view/regexp kernels emitting boolean masks when the source array has null values.

Common situations: Writing new polars-compute or polars-arrow kernels against Pushable; refactoring Option<bool> kernels to plain bool to dodge unwrap; fuzz tests that include null inputs where nullability was assumed away.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/7a523b1ce15860eb. Report an issue: GitHub.