rust-lang/rust · error
vector type
Error message
vector type
What it means
Panicked by `.expect("vector type")` at the top of `Builder::shuffle_vector` (master feature) in rustc_codegen_gcc/src/builder.rs:2035. After unwrapping qualifiers via `unqualified()`, the code calls `dyncast_vector()` on the type of `v1`; if that returns `None` the type is not a GCC vector type. The compiler therefore aborts because it cannot extract an element type or lane count for a SIMD shuffle.
Source
Thrown at compiler/rustc_codegen_gcc/src/builder.rs:2035
#[cfg(feature = "master")]
pub fn shuffle_vector(
&mut self,
v1: RValue<'gcc>,
v2: RValue<'gcc>,
mask: RValue<'gcc>,
) -> RValue<'gcc> {
// NOTE: if the `mask` is a constant value, the following code will copy it in many places,
// which will make GCC create a lot (+4000) local variables in some cases.
// So we assign it to an explicit local variable once to avoid this.
let func = self.current_func();
let mask_var = func.new_local(self.location, mask.get_type(), "mask");
let block = self.block;
block.add_assignment(self.location, mask_var, mask);
let mask = mask_var.to_rvalue();
// FIXME(antoyo): use a recursive unqualified() here.
let vector_type = v1.get_type().unqualified().dyncast_vector().expect("vector type");
let element_type = vector_type.get_element_type();
let vec_num_units = vector_type.get_num_units();
let mask_element_type = if element_type.is_integral() {
element_type
} else {
#[cfg(feature = "master")]
{
self.cx.type_ix(element_type.get_size() as u64 * 8)
}
#[cfg(not(feature = "master"))]
self.int_type
};
// NOTE: this condition is needed because we call shuffle_vector in the implementation of
// simd_gather.
let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() {
let mask_num_units = vector_type.get_num_units();View on GitHub (pinned to 22057b88b0)
Solutions
- Switch to the LLVM codegen backend (`-C codegen-backend=llvm`) for crates using portable SIMD, which is fully supported.
- Ensure you are building rustc_codegen_gcc with the `master` feature AND linking a recent `libgccjit` (master branch) that exposes complete vector APIs.
- Reduce the failing crate to a minimal SIMD snippet and file an issue on rustc_codegen_gcc with the reproducer; the panic indicates a codegen bug rather than user error.
- Avoid `simd_shuffle` intrinsics with non-power-of-two or odd lane counts that libgccjit may represent as non-vector aggregates.
Example fix
// before RUSTC_CODEGEN_BACKEND=gcc rustc -O my_simd_crate // after (LLVM handles portable_simd) rustc -O my_simd_crate
Defensive patterns
Strategy: type-guard
Validate before calling
// shuffle_vector() calls v1.get_type().unqualified().dyncast_vector().expect("vector type").
// Verify BOTH shuffle operands are vectors before calling.
fn ensure_vector_operands<'gcc>(v1: RValue<'gcc>, v2: RValue<'gcc>) -> Result<(), String> {
if v1.get_type().unqualified().dyncast_vector().is_none() {
return Err(format!("shuffle_vector: v1 is not a vector type: {:?}", v1.get_type()));
}
if v2.get_type().unqualified().dyncast_vector().is_none() {
return Err(format!("shuffle_vector: v2 is not a vector type: {:?}", v2.get_type()));
}
Ok(())
}
ensure_vector_operands(v1, v2)?;
let r = bx.shuffle_vector(v1, v2, mask); Type guard
// Narrow an RValue to a confirmed vector value before handing it to shuffle_vector.
fn as_vector<'gcc>(v: RValue<'gcc>) -> Option<RValue<'gcc>> {
v.get_type().unqualified().dyncast_vector().is_some().then_some(v)
}
// Usage: only call shuffle_vector when both operands pass the guard.
if let (Some(v1v), Some(v2v)) = (as_vector(v1), as_vector(v2)) {
let r = bx.shuffle_vector(v1v, v2v, mask);
} else {
return Err("shuffle_vector requires both operands to be vector types");
} Prevention
- Never pass scalar or aggregate (non-vector) RValues to shuffle_vector; both v1 and v2 must unqualified-dyncast to a vector type.
- Centralize SIMD value construction through a helper that only ever produces vector-typed RValues so the invariant is enforced at the source.
- When shuffling, also ensure v1 and v2 have matching element types and lane counts; mismatched vectors slip past the type guard but still produce wrong code.
When it happens
Trigger: Compiling Rust SIMD code (`std::simd`, `core::simd`, `simd_*` intrinsics, `simd_shuffle`) where codegen_gcc receives an `RValue` for the first vector operand whose GCC type is not a vector (e.g. an array/aggregate mistakenly treated as a vector, or a type produced by a non-master libgccjit).
Common situations: Using `#![feature(portable_simd)]` with the gcc backend. Building against an older libgccjit that lacks full vector support. Mixing LLVM-specific intrinsics that bypass the normal vector type construction.
Related errors
- mask should be of struct type
- Called extract_element on a non-vector type
- `NumScalableVectors(0)` is illformed
- `NumScalableVectors(N)` for N>8 is illformed
- first index in inbounds_gep
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/154158de0cfd9278.json.
Report an issue: GitHub.