{"id":"083dcf6257fd8d86","repo":"rust-lang/rust","slug":"cannot-cast-a-to-non-native-integer","errorCode":null,"errorMessage":"cannot cast a {:?} to non-native integer","messagePattern":"cannot cast a (.+?) to non-native integer","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_gcc/src/int.rs","lineNumber":965,"sourceCode":"    ) -> RValue<'gcc> {\n        let value_type = value.get_type();\n        if self.is_native_int_type_or_bool(dest_typ) {\n            return self.context.new_cast(None, value, dest_typ);\n        }\n\n        debug_assert!(dest_typ.dyncast_array().is_some());\n        let (dest_type, param_type) = match self.type_kind(value_type) {\n            TypeKind::Half => (Some(self.float_type), self.float_type),\n            _ => (None, value_type),\n        };\n        let name_suffix = match self.type_kind(value_type) {\n            // cSpell:disable\n            // Since we will cast Half to a float, we use sfti for both.\n            TypeKind::Half | TypeKind::Float => \"sfti\",\n            TypeKind::Double => \"dfti\",\n            TypeKind::FP128 => \"tfti\",\n            // cSpell:enable\n            kind => panic!(\"cannot cast a {:?} to non-native integer\", kind),\n        };\n        let sign = if signed { \"\" } else { \"uns\" };\n        let func_name = format!(\"__fix{}{}\", sign, name_suffix);\n        let param = self.context.new_parameter(None, param_type, \"n\");\n        let func = self.context.new_function(\n            None,\n            FunctionType::Extern,\n            dest_typ,\n            &[param],\n            func_name,\n            false,\n        );\n        if let Some(dest_type) = dest_type {\n            value = self.context.new_cast(None, value, dest_type);\n        }\n        self.context.new_call(None, func, &[value])\n    }\n","sourceCodeStart":947,"sourceCodeEnd":983,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_gcc/src/int.rs#L947-L983","documentation":"This panic fires inside float_to_int_cast when converting a floating-point value to a non-native (array-backed, i128/u128) integer, in the branch that selects the compiler-rt/libgcc fix helper name by the source float's TypeKind. Only Half (routed via f32), Float (f32), Double (f64), and FP128 (f128) have defined suffixes (sfti/dfti/tfti). Any other kind reaching this branch (vector floats, complex, or a misreported type) panics.","triggerScenarios":"Casting a float whose TypeKind is not Half/Float/Double/FP128 into an i128/u128 destination on a target where the destination is array-backed. Triggered when the float operand is a vector-of-float, a complex float, or a type libgccjit reports with an unexpected TypeKind while the destination integer is non-native.","commonSituations":"SIMD-heavy code accidentally converting a vector float lane to a 128-bit int; cross-compiling for 32-bit targets where i128 is array-backed; libgccjit regressions in TypeKind reporting for float types.","solutions":["Ensure the float operand is a scalar (f16/f32/f64/f128) before converting to i128/u128.","Extract a lane from any vector float before casting to a 128-bit integer.","Add the missing TypeKind arm to float_to_int_cast with the appropriate compiler-rt helper suffix if the float kind is genuinely supported.","Upgrade libgccjit and confirm the float TypeKind matches one of the handled variants."],"exampleFix":"// before\nlet n: i128 = vec_float as i128; // vector float incorrectly cast\n// after (cast a scalar lane instead)\nlet n: i128 = vec_float.extract(0) as f32 as i128;","handlingStrategy":"validation","validationCode":"// Validate the source is a supported float kind BEFORE casting into a 128-bit int.\npub enum FloatSrc { F32, F64 }\npub fn float_to_int128(src: FloatSrc, bits: u32, val: f64) -> i128 {\n    match src {\n        FloatSrc::F32 => (val as f32) as i128, // Half/Float -> sfti path\n        FloatSrc::F64 => val as i128,          // Double -> dfti path\n        // No other source kinds -> cannot reach the panic at int.rs:965\n    }\n}","typeGuard":"// Only allow float sources for float -> 128-bit-int conversion.\nmod float_src {\n    pub trait FloatSrc: Copy + private::Sealed {}\n    mod private { pub trait Sealed {} }\n    impl Sealed for f32 {} impl FloatSrc for f32 {}\n    impl Sealed for f64 {} impl FloatSrc for f64 {}\n}\npub fn float_to_int<F: float_src::FloatSrc>(x: F) -> i128 { x as i128 } // F is f32 or f64 only","tryCatchPattern":null,"preventionTips":["Only cast f32 or f64 (or f16 via the Half path) into i128/u128; other type kinds hit int.rs:965.","Avoid casting integer/bool/pointer values `as i128`; widen through an f64 intermediate if needed.","Bound generic float->int helpers by a FloatSrc sealed trait.","Add a test confirming the source TypeKind is Half/Float/Double/FP128 before enabling the GCC backend."],"tags":["rust","codegen","gcc","libgccjit","float-cast","i128","panic"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}