rust-lang/rust · error

`is_signed` on non-scalar ABI {self:?}

Error message

`is_signed` on non-scalar ABI {self:?}

What it means

Thrown by `BackendRepr::is_signed` at compiler/rustc_abi/src/lib.rs:1851 (sanity check from PR #70189). The method only makes sense for `BackendRepr::Scalar(_)`, because only a single scalar has a well-defined signed/unsigned integer kind. Calling it on `ScalarPair`, `SimdVector`, `SimdScalableVector`, or `Memory` is a category error — those representations have no single sign.

Source

Thrown at compiler/rustc_abi/src/lib.rs:1851

            // need to be revisited and will depend on what `is_unsized` is used for.
            | BackendRepr::SimdScalableVector { .. }
            | BackendRepr::SimdVector { .. } => false,
            BackendRepr::Memory { sized } => !sized,
        }
    }

    #[inline]
    pub fn is_sized(&self) -> bool {
        !self.is_unsized()
    }

    /// Returns `true` if this is a single signed integer scalar.
    /// Sanity check: panics if this is not a scalar type (see PR #70189).
    #[inline]
    pub fn is_signed(&self) -> bool {
        match self {
            BackendRepr::Scalar(scal) => scal.is_signed(),
            _ => panic!("`is_signed` on non-scalar ABI {self:?}"),
        }
    }

    /// Returns `true` if this is specifically a [`Self::Scalar`] type.
    ///
    /// This excludes SIMD types.
    #[inline]
    pub fn is_scalar(&self) -> bool {
        matches!(*self, BackendRepr::Scalar(_))
    }

    /// Returns `true` if this is a scalar type or SIMD type.
    #[inline]
    pub fn is_scalar_or_simd(&self) -> bool {
        matches!(
            *self,
            BackendRepr::Scalar(_)
                | BackendRepr::SimdVector { .. }

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Guard the call with `is_scalar()`: `if repr.is_scalar() { repr.is_signed() } else { /* fall back to memory/pair handling */ }`.
  2. Prefer matching explicitly on the `BackendRepr` variant so each case is handled, rather than relying on `is_signed()`'s implicit scalar assumption.
  3. If a signed-ness check is genuinely needed for compound reprs, push the question down to the element `Scalar` rather than the top-level `BackendRepr`.

Example fix

// before
if backend_repr.is_signed() { emit_signed(...) } else { emit_unsigned(...) }

// after
match backend_repr {
    BackendRepr::Scalar(s) if s.is_signed() => emit_signed(...),
    BackendRepr::Scalar(_) => emit_unsigned(...),
    _ => emit_aggregate(...),
}
Defensive patterns

Strategy: type-guard

Validate before calling

// is_signed panics on any non-Scalar BackendRepr. Use is_scalar() first.
fn backend_is_signed(repr: &rustc_abi::BackendRepr) -> Option<bool> {
    repr.is_scalar().then(|| {
        if let rustc_abi::BackendRepr::Scalar(s) = repr { s.is_signed() } else { unreachable!() }
    })
}

Type guard

fn is_signed_scalar(repr: &rustc_abi::BackendRepr) -> bool {
    matches!(repr, rustc_abi::BackendRepr::Scalar(s) if s.is_signed())
}

Try / catch

// The panic is a sanity check (see PR #70189). Do not catch; fix the caller
// to verify is_scalar() before invoking is_signed().

Prevention

When it happens

Trigger: Calling `backend_repr.is_signed()` (or `.is_scalar_signed()`) on a non-scalar `BackendRepr`. Typically reached when generic ABI code assumes the representation is a scalar integer without first checking `is_scalar()`.

Common situations: Calling-convention lowering that asks `is_signed()` on a `ScalarPair` (e.g. a `i64` returned with a tag), or on a `Memory` repr for a struct that happens to contain a signed integer. Also seen when a refactor widens the type flowing into a scalar-only helper.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/b17e92ae757edde3.json. Report an issue: GitHub.