{"id":"154158de0cfd9278","repo":"rust-lang/rust","slug":"vector-type","errorCode":null,"errorMessage":"vector type","messagePattern":"vector type","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_gcc/src/builder.rs","lineNumber":2035,"sourceCode":"\n    #[cfg(feature = \"master\")]\n    pub fn shuffle_vector(\n        &mut self,\n        v1: RValue<'gcc>,\n        v2: RValue<'gcc>,\n        mask: RValue<'gcc>,\n    ) -> RValue<'gcc> {\n        // NOTE: if the `mask` is a constant value, the following code will copy it in many places,\n        // which will make GCC create a lot (+4000) local variables in some cases.\n        // So we assign it to an explicit local variable once to avoid this.\n        let func = self.current_func();\n        let mask_var = func.new_local(self.location, mask.get_type(), \"mask\");\n        let block = self.block;\n        block.add_assignment(self.location, mask_var, mask);\n        let mask = mask_var.to_rvalue();\n\n        // FIXME(antoyo): use a recursive unqualified() here.\n        let vector_type = v1.get_type().unqualified().dyncast_vector().expect(\"vector type\");\n        let element_type = vector_type.get_element_type();\n        let vec_num_units = vector_type.get_num_units();\n\n        let mask_element_type = if element_type.is_integral() {\n            element_type\n        } else {\n            #[cfg(feature = \"master\")]\n            {\n                self.cx.type_ix(element_type.get_size() as u64 * 8)\n            }\n            #[cfg(not(feature = \"master\"))]\n            self.int_type\n        };\n\n        // NOTE: this condition is needed because we call shuffle_vector in the implementation of\n        // simd_gather.\n        let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() {\n            let mask_num_units = vector_type.get_num_units();","sourceCodeStart":2017,"sourceCodeEnd":2053,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_gcc/src/builder.rs#L2017-L2053","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nRUSTC_CODEGEN_BACKEND=gcc rustc -O my_simd_crate\n// after (LLVM handles portable_simd)\nrustc -O my_simd_crate","handlingStrategy":"type-guard","validationCode":"// shuffle_vector() calls v1.get_type().unqualified().dyncast_vector().expect(\"vector type\").\n// Verify BOTH shuffle operands are vectors before calling.\nfn ensure_vector_operands<'gcc>(v1: RValue<'gcc>, v2: RValue<'gcc>) -> Result<(), String> {\n    if v1.get_type().unqualified().dyncast_vector().is_none() {\n        return Err(format!(\"shuffle_vector: v1 is not a vector type: {:?}\", v1.get_type()));\n    }\n    if v2.get_type().unqualified().dyncast_vector().is_none() {\n        return Err(format!(\"shuffle_vector: v2 is not a vector type: {:?}\", v2.get_type()));\n    }\n    Ok(())\n}\n\nensure_vector_operands(v1, v2)?;\nlet r = bx.shuffle_vector(v1, v2, mask);","typeGuard":"// Narrow an RValue to a confirmed vector value before handing it to shuffle_vector.\nfn as_vector<'gcc>(v: RValue<'gcc>) -> Option<RValue<'gcc>> {\n    v.get_type().unqualified().dyncast_vector().is_some().then_some(v)\n}\n\n// Usage: only call shuffle_vector when both operands pass the guard.\nif let (Some(v1v), Some(v2v)) = (as_vector(v1), as_vector(v2)) {\n    let r = bx.shuffle_vector(v1v, v2v, mask);\n} else {\n    return Err(\"shuffle_vector requires both operands to be vector types\");\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["rust","codegen-gcc","simd","vector","shuffle","panic"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}