{"id":"ed8f5559b2038489","repo":"rust-lang/rust","slug":"cannot-cast-a-non-native-integer-to-type","errorCode":null,"errorMessage":"cannot cast a non-native integer to type {:?}","messagePattern":"cannot cast a non-native integer to type (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_gcc/src/int.rs","lineNumber":914,"sourceCode":"    fn int_to_float_cast(\n        &self,\n        signed: bool,\n        value: RValue<'gcc>,\n        dest_typ: Type<'gcc>,\n    ) -> RValue<'gcc> {\n        let value_type = value.get_type();\n        if self.is_native_int_type_or_bool(value_type) {\n            return self.context.new_cast(None, value, dest_typ);\n        }\n\n        debug_assert!(value_type.dyncast_array().is_some());\n        let name_suffix = match self.type_kind(dest_typ) {\n            // cSpell:disable\n            TypeKind::Float => \"tisf\",\n            TypeKind::Double => \"tidf\",\n            TypeKind::FP128 => \"titf\",\n            // cSpell:enable\n            kind => panic!(\"cannot cast a non-native integer to type {:?}\", kind),\n        };\n        let sign = if signed { \"\" } else { \"un\" };\n        let func_name = format!(\"__float{}{}\", sign, name_suffix);\n        let param = self.context.new_parameter(None, value_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        self.context.new_call(None, func, &[value])\n    }\n\n    pub fn gcc_int_to_float_cast(&self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {\n        self.int_to_float_cast(true, value, dest_typ)\n    }","sourceCodeStart":896,"sourceCodeEnd":932,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_gcc/src/int.rs#L896-L932","documentation":"This panic fires inside int_to_float_cast when converting a non-native (array-backed, i128/u128) integer to a floating-point type whose TypeKind is neither Float (f32), Double (f64), nor FP128 (f128). For those three the backend emits a call to a compiler-rt/libgcc helper like __floatuntisf; any other kind (e.g. Half/f16, vectors, complex, or a misclassified type) hits the catch-all panic because no helper name is defined.","triggerScenarios":"Casting i128/u128 to a 16-bit float (f16 / TypeKind::Half) or to a float-like type that is not f32/f64/f128, on a target where the 128-bit integer is non-native so the helper-call path is taken. Also triggered if libgccjit reports the destination float with an unexpected TypeKind.","commonSituations":"Code casting u128 to f16 (half-precision) for ML/graphics workloads; crates using half::f16 with 128-bit integer sources on 32-bit targets; libgccjit version changes that alter float TypeKind enumeration.","solutions":["Avoid casting i128/u128 directly to f16/f128-or-other unsupported float; convert through f32 or f64 first.","Add the missing TypeKind arm to int_to_float_cast (e.g. TypeKind::Half => \"tihf\" or route via f32) if targeting a supported runtime helper.","Confirm the destination type is a scalar float and not a vector/complex type masquerading as a float.","Upgrade libgccjit; verify the float TypeKind reported matches Float/Double/FP128 for the destination."],"exampleFix":"// before\nlet f = (huge_u128 as f16).to_le_bits();\n// after (convert through f32, then narrow to f16)\nlet f = (huge_u128 as f32) as f16;","handlingStrategy":"validation","validationCode":"// Validate the destination is a supported float kind BEFORE casting a 128-bit int.\npub enum CastDest { F32, F64 }\npub fn int128_to_float(x: i128, dest: CastDest) -> f64 {\n    match dest {\n        CastDest::F32 => x as f32 as f64, // OK: Float kind\n        CastDest::F64 => x as f64,         // OK: Double kind\n        // No other branches -> cannot reach the panic at int.rs:914\n    }\n}","typeGuard":"// Only allow float destinations for 128-bit-int -> float conversion.\nmod float_dest {\n    pub trait FloatRepr: Copy + private::Sealed {}\n    mod private { pub trait Sealed {} }\n    impl Sealed for f32 {} impl FloatRepr for f32 {}\n    impl Sealed for f64 {} impl FloatRepr for f64 {}\n}\npub fn int_to_float<F: float_dest::FloatRepr>(x: i128) -> F { x as F } // F is f32 or f64 only","tryCatchPattern":null,"preventionTips":["Only ever cast i128/u128 to f32 or f64 (Float/Double kinds); the panic fires for any other TypeKind.","Never cast 128-bit ints to custom newtype/fixed-point numeric types expecting a non-float codegen kind.","Bound generic int->float helpers by a FloatRepr sealed trait so invalid destinations fail to compile.","Add a unit test asserting the cast target type kind is Float/Double before enabling the GCC backend."],"tags":["rust","codegen","gcc","libgccjit","i128","float-cast","panic"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}