Repository navigation
Closed
Labels
Description
I have found these related issues/pull requests
When an enum has repr(C) the sqlx macro uses C in its _ as C casting.
Description
Given a enum like this:
#[derive(Debug, sqlx::Type)]
#[repr(C)]
enum MyEnum {
VariantA,
VariantB,
}the macro expands to:
// Recursive expansion of sqlx::Type macro
// ========================================
#[automatically_derived]
impl<'q, DB: ::sqlx::Database> ::sqlx::encode::Encode<'q, DB> for MyEnum
where
C: ::sqlx::encode::Encode<'q, DB>,
{
fn encode_by_ref(
&self,
buf: &mut <DB as ::sqlx::database::Database>::ArgumentBuffer,
) -> ::std::result::Result<::sqlx::encode::IsNull, ::sqlx::error::BoxDynError> {
let value = match self {
MyEnum::VariantA => (MyEnum::VariantA as C),
MyEnum::VariantB => (MyEnum::VariantB as C),
};
<C as ::sqlx::encode::Encode<DB>>::encode_by_ref(&value, buf)
}
fn size_hint(&self) -> usize {
<C as ::sqlx::encode::Encode<DB>>::size_hint(&Default::default())
}
}
#[automatically_derived]
impl<'r, DB: ::sqlx::Database> ::sqlx::decode::Decode<'r, DB> for MyEnum
where
C: ::sqlx::decode::Decode<'r, DB>,
{
fn decode(
value: <DB as ::sqlx::database::Database>::ValueRef<'r>,
) -> ::std::result::Result<
Self,
::std::boxed::Box<
dyn ::std::error::Error + 'static + ::std::marker::Send + ::std::marker::Sync,
>,
> {
let value = <C as ::sqlx::decode::Decode<'r, DB>>::decode(value)?;
match value {
_ if (MyEnum::VariantA as C) == value => ::std::result::Result::Ok(MyEnum::VariantA),
_ if (MyEnum::VariantB as C) == value => ::std::result::Result::Ok(MyEnum::VariantB),
_ => ::std::result::Result::Err(::std::boxed::Box::new(::sqlx::Error::Decode(
::std::format!("invalid value {:?} for enum {}", value, "MyEnum").into(),
))),
}
}
}
#[automatically_derived]
impl<DB: ::sqlx::Database> ::sqlx::Type<DB> for MyEnum
where
C: ::sqlx::Type<DB>,
{
fn type_info() -> DB::TypeInfo {
<C as ::sqlx::Type<DB>>::type_info()
}
fn compatible(ty: &DB::TypeInfo) -> bool {
<C as ::sqlx::Type<DB>>::compatible(ty)
}
}
#[automatically_derived]
impl ::sqlx::postgres::PgHasArrayType for MyEnum {
fn array_type_info() -> ::sqlx::postgres::PgTypeInfo {
<C as ::sqlx::postgres::PgHasArrayType>::array_type_info()
}
}For repr(usize) and friends this behaviour makes sense but not for repr(C)
Reproduction steps
#[derive(Debug, sqlx::Type)]
#[repr(C)]
enum MyEnum {
VariantA,
VariantB,
}SQLx version
0.9
Enabled SQLx features
"runtime-tokio","tls-rustls-ring-native-roots","postgres","uuid","chrono","json","derive","migrate",
Database server and version
PostgresQL 18
Operating system
Windows
Rust version
rustc 1.98.0-nightly (f20a92ec0 2026-06-07)
Activity
Erik1000 commentedon Aug 7, 2026
Discovered because
facetrequires enum to have an explictreprthelastbackspace commentedon Nov 5, 2026
I'd like to pick this up. The derive takes the first bare word in
#[repr(..)]as the integer type, sorepr(C)becomesas C. My fix only accepts integer reprs and treats anything else like an enum without a repr (a string enum). Opening a PR with a sqlite test, happy to change the approach if you'd prefer something else.