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
- Guard the call with `is_scalar()`: `if repr.is_scalar() { repr.is_signed() } else { /* fall back to memory/pair handling */ }`.
- Prefer matching explicitly on the `BackendRepr` variant so each case is handled, rather than relying on `is_signed()`'s implicit scalar assumption.
- 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
- The doc comment calls this a sanity check: it only makes sense to ask signedness of a scalar.
- Always pair is_signed() behind an is_scalar() gate, or pattern-match BackendRepr::Scalar(_) explicitly.
- For SIMD/Pair/Memory/SimdVector variants, signedness is not a property of the repr.
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
- cannot change the valid range of a union
- Size::bits: {bytes} bytes in bits doesn't fit in u64
- Size::add: {} + {} doesn't fit in u64
- Size::sub: {} - {} would result in negative size
- Size::mul: {} * {} doesn't fit in u64
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/b17e92ae757edde3.json.
Report an issue: GitHub.