From 87347d82d2c799fd8a073d54a72006906a532658 Mon Sep 17 00:00:00 2001 From: Rua Date: Tue, 5 May 2026 19:23:28 +0200 Subject: [PATCH 1/3] transpile: Split off `make_enum_constant_init` --- c2rust-transpile/src/translator/enums.rs | 27 ++++++++++++++++++------ c2rust-transpile/src/translator/mod.rs | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/c2rust-transpile/src/translator/enums.rs b/c2rust-transpile/src/translator/enums.rs index f682242bb7..e5892b111d 100644 --- a/c2rust-transpile/src/translator/enums.rs +++ b/c2rust-transpile/src/translator/enums.rs @@ -2,6 +2,7 @@ use c2rust_ast_builder::mk; use proc_macro2::Span; use syn::Expr; +use crate::c_ast::iterators::SomeId; use crate::{ diagnostics::TranslationResult, translator::{signed_int_expr, ConvertedDecl, ExprContext, Translation}, @@ -36,8 +37,6 @@ impl<'c> Translation<'c> { pub fn convert_enum_constant( &self, enum_constant_id: CEnumConstantId, - span: Span, - value: ConstIntExpr, ) -> TranslationResult { let name = self .renamer @@ -52,17 +51,31 @@ impl<'c> Translation<'c> { .expect("Enums should already be renamed"); let ty = mk().ident_ty(enum_name); - let val = match value { - ConstIntExpr::I(value) => signed_int_expr(value), - ConstIntExpr::U(value) => mk().lit_expr(mk().int_unsuffixed_lit(value as u128)), - }; - let init = self.enum_constructor_expr(enum_id, val); + let (span, init) = self.make_enum_constant_init(enum_constant_id); Ok(ConvertedDecl::Item( mk().span(span).pub_().const_item(name, ty, init), )) } + fn make_enum_constant_init(&self, enum_constant_id: CEnumConstantId) -> (Span, Box) { + let value = match self.ast_context[enum_constant_id].kind { + CDeclKind::EnumConstant { value, .. } => value, + _ => panic!("{:?} does not point to an enum variant", enum_constant_id), + }; + let value_rs = match value { + ConstIntExpr::I(value) => signed_int_expr(value), + ConstIntExpr::U(value) => mk().lit_expr(mk().int_unsuffixed_lit(value as u128)), + }; + let enum_id = self.ast_context.parents[&enum_constant_id]; + let init = self.enum_constructor_expr(enum_id, value_rs); + let span = self + .get_span(SomeId::Decl(enum_constant_id)) + .unwrap_or_else(Span::call_site); + + (span, init) + } + pub fn convert_enum_zero_initializer(&self, enum_id: CEnumId) -> WithStmts> { WithStmts::new_val(self.enum_for_i64(enum_id, 0)) } diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index 680d0685e5..009d6420dc 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -2094,7 +2094,7 @@ impl<'c> Translation<'c> { .. } => self.convert_enum(decl_id, span, integral_type), - EnumConstant { value, .. } => self.convert_enum_constant(decl_id, span, value), + EnumConstant { .. } => self.convert_enum_constant(decl_id), // We can allow non top level function declarations (i.e. extern // declarations) without any problem. Clang doesn't support nested From 4bee3c913f8ed9749c4ee8a707eab8a7b5cc3d77 Mon Sep 17 00:00:00 2001 From: Rua Date: Tue, 5 May 2026 19:23:44 +0200 Subject: [PATCH 2/3] transpile: Handle `EnumConstant` as part of `Enum` --- c2rust-transpile/src/translator/enums.rs | 45 +++++++++++------------- c2rust-transpile/src/translator/mod.rs | 6 ++-- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/c2rust-transpile/src/translator/enums.rs b/c2rust-transpile/src/translator/enums.rs index e5892b111d..8eaaaa14db 100644 --- a/c2rust-transpile/src/translator/enums.rs +++ b/c2rust-transpile/src/translator/enums.rs @@ -16,6 +16,7 @@ impl<'c> Translation<'c> { enum_id: CEnumId, span: Span, integral_type: CQualTypeId, + variants: &[CEnumConstantId], ) -> TranslationResult { let enum_name = &self .type_converter @@ -24,38 +25,32 @@ impl<'c> Translation<'c> { .expect("Enums should already be renamed"); let integral_type_rs = self.convert_type(integral_type.ctype)?; let field = mk().pub_().enum_field(integral_type_rs); - let item = mk() + let enum_item = mk() .span(span) .call_attr("derive", vec!["Clone", "Copy"]) .call_attr("repr", vec!["transparent"]) .pub_() .struct_item(enum_name, vec![field], true); - Ok(ConvertedDecl::Item(item)) - } - - pub fn convert_enum_constant( - &self, - enum_constant_id: CEnumConstantId, - ) -> TranslationResult { - let name = self - .renamer - .borrow_mut() - .get(&enum_constant_id) - .expect("Enum constant not named"); - let enum_id = self.ast_context.parents[&enum_constant_id]; - let enum_name = self - .type_converter - .borrow() - .resolve_decl_name(enum_id) - .expect("Enums should already be renamed"); - - let ty = mk().ident_ty(enum_name); - let (span, init) = self.make_enum_constant_init(enum_constant_id); + if variants.is_empty() { + return Ok(ConvertedDecl::Item(enum_item)); + } - Ok(ConvertedDecl::Item( - mk().span(span).pub_().const_item(name, ty, init), - )) + let enum_type = mk().ident_ty(enum_name); + let constants_iter = variants.iter().map(|&enum_constant_id| { + let name = self + .renamer + .borrow_mut() + .get(&enum_constant_id) + .expect("Enum constant not named"); + let (span, init) = self.make_enum_constant_init(enum_constant_id); + mk().span(span) + .pub_() + .const_item(name, enum_type.clone(), init) + }); + + let items = std::iter::once(enum_item).chain(constants_iter).collect(); + Ok(ConvertedDecl::Items(items)) } fn make_enum_constant_init(&self, enum_constant_id: CEnumConstantId) -> (Span, Box) { diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index 009d6420dc..4f0d97fca1 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -2090,11 +2090,13 @@ impl<'c> Translation<'c> { )), Enum { + ref variants, integral_type: Some(integral_type), .. - } => self.convert_enum(decl_id, span, integral_type), + } => self.convert_enum(decl_id, span, integral_type, variants), - EnumConstant { .. } => self.convert_enum_constant(decl_id), + // EnumConstant is translated as part of Enum. + EnumConstant { .. } => Ok(ConvertedDecl::NoItem), // We can allow non top level function declarations (i.e. extern // declarations) without any problem. Clang doesn't support nested From 937303a6be9422ceeb6a35e31a680b0fb770884d Mon Sep 17 00:00:00 2001 From: Rua Date: Fri, 7 Aug 2026 09:35:15 +0200 Subject: [PATCH 3/3] transpile: Translate `EnumConstant` with associated constants --- c2rust-ast-builder/src/builder.rs | 20 +++++ c2rust-transpile/src/translator/enums.rs | 80 +++++++++++++------ c2rust-transpile/src/translator/mod.rs | 6 +- ...shots__transpile@enums.c.2021.clang15.snap | 40 +++++----- ...shots__transpile@enums.c.2024.clang15.snap | 40 +++++----- ...shots__transpile@exprs.c.2021.clang15.snap | 14 ++-- ...shots__transpile@exprs.c.2024.clang15.snap | 14 ++-- ...s__transpile@macrocase.c.2021.clang15.snap | 6 +- ...s__transpile@macrocase.c.2024.clang15.snap | 6 +- ...transpile@raw_keywords.c.2021.clang15.snap | 8 +- ...transpile@raw_keywords.c.2024.clang15.snap | 8 +- ...ots__transpile@records.c.2021.clang15.snap | 16 ++-- ...ots__transpile@records.c.2024.clang15.snap | 16 ++-- ..._transpile@scalar_init.c.2021.clang15.snap | 6 +- ..._transpile@scalar_init.c.2024.clang15.snap | 6 +- tests/unit/enums/src/test_enums.rs | 10 +-- tests/unit/misc/src/test_uninitialized.rs | 8 +- 17 files changed, 193 insertions(+), 111 deletions(-) diff --git a/c2rust-ast-builder/src/builder.rs b/c2rust-ast-builder/src/builder.rs index 526bbd45ad..5a856b6297 100644 --- a/c2rust-ast-builder/src/builder.rs +++ b/c2rust-ast-builder/src/builder.rs @@ -1421,6 +1421,26 @@ impl Builder { })) } + pub fn const_impl_item(self, name: I, ty: Box, init: Box) -> ImplItem + where + I: Make, + { + let name = name.make(&self); + ImplItem::Const(ImplItemConst { + attrs: self.attrs, + vis: self.vis, + defaultness: None, + const_token: Token![const](self.span), + ident: name, + generics: self.generics, + colon_token: Token![:](self.span), + ty: *ty, + eq_token: Token![=](self.span), + expr: *init, + semi_token: Token![;](self.span), + }) + } + pub fn fn_item(self, sig: S, mut block: Block) -> Box where S: Make, diff --git a/c2rust-transpile/src/translator/enums.rs b/c2rust-transpile/src/translator/enums.rs index 8eaaaa14db..fd69a8960c 100644 --- a/c2rust-transpile/src/translator/enums.rs +++ b/c2rust-transpile/src/translator/enums.rs @@ -36,21 +36,30 @@ impl<'c> Translation<'c> { return Ok(ConvertedDecl::Item(enum_item)); } - let enum_type = mk().ident_ty(enum_name); - let constants_iter = variants.iter().map(|&enum_constant_id| { - let name = self - .renamer - .borrow_mut() - .get(&enum_constant_id) - .expect("Enum constant not named"); - let (span, init) = self.make_enum_constant_init(enum_constant_id); - mk().span(span) - .pub_() - .const_item(name, enum_type.clone(), init) - }); - - let items = std::iter::once(enum_item).chain(constants_iter).collect(); - Ok(ConvertedDecl::Items(items)) + let enum_type = mk().ident_ty("Self"); + let constants = variants + .iter() + .map(|&enum_constant_id| { + let name = match self.ast_context[enum_constant_id].kind { + CDeclKind::EnumConstant { ref name, .. } => name, + _ => panic!("{:?} does not point to an enum variant", enum_constant_id), + }; + let name_rs = self.type_converter.borrow_mut().declare_field_name( + enum_id, + enum_constant_id, + name, + ); + let (span, init) = self.make_enum_constant_init(enum_constant_id); + mk().span(span) + .pub_() + .const_impl_item(name_rs, enum_type.clone(), init) + }) + .collect(); + + let impl_block = mk() + .span(span) + .impl_item(mk().ident_ty(enum_name), constants); + Ok(ConvertedDecl::Items(vec![enum_item, impl_block])) } fn make_enum_constant_init(&self, enum_constant_id: CEnumConstantId) -> (Span, Box) { @@ -63,7 +72,7 @@ impl<'c> Translation<'c> { ConstIntExpr::U(value) => mk().lit_expr(mk().int_unsuffixed_lit(value as u128)), }; let enum_id = self.ast_context.parents[&enum_constant_id]; - let init = self.enum_constructor_expr(enum_id, value_rs); + let init = self.enum_constructor_expr(enum_id, value_rs, true); let span = self .get_span(SomeId::Decl(enum_constant_id)) .unwrap_or_else(Span::call_site); @@ -139,7 +148,7 @@ impl<'c> Translation<'c> { let enum_integral_type = self.enum_integral_type(enum_id); let mut val = WithStmts::new_val(val); val = self.make_cast(ctx, source_cty, enum_integral_type, val)?; - val = val.map(|val| self.enum_constructor_expr(enum_id, val)); + val = val.map(|val| self.enum_constructor_expr(enum_id, val, false)); Ok(val) } @@ -158,7 +167,7 @@ impl<'c> Translation<'c> { _ => signed_int_expr(value), }; - self.enum_constructor_expr(enum_id, value) + self.enum_constructor_expr(enum_id, value, false) } /// Returns the id of the variant of `enum_id` whose value matches `value`, if any. @@ -180,20 +189,41 @@ impl<'c> Translation<'c> { } fn enum_constant_expr(&self, enum_constant_id: CEnumConstantId) -> Box { - let name = self.renamer.borrow().get(&enum_constant_id).unwrap(); - self.add_import(enum_constant_id, &name); - mk().ident_expr(name) - } - - fn enum_constructor_expr(&self, enum_id: CEnumId, value: Box) -> Box { + let enum_id = self.ast_context.parents[&enum_constant_id]; let enum_name = self .type_converter .borrow() .resolve_decl_name(enum_id) .unwrap(); + let enum_constant_name = self + .type_converter + .borrow() + .resolve_field_name(Some(enum_id), enum_constant_id) + .unwrap(); + self.add_import(enum_id, &enum_name); + mk().path_expr(vec![enum_name, enum_constant_name]) + } + + fn enum_constructor_expr( + &self, + enum_id: CEnumId, + value: Box, + use_self_type: bool, + ) -> Box { + let func = if use_self_type { + mk().ident_expr("Self") + } else { + let enum_name = self + .type_converter + .borrow() + .resolve_decl_name(enum_id) + .unwrap(); + self.add_import(enum_id, &enum_name); + mk().ident_expr(enum_name) + }; - mk().call_expr(mk().ident_expr(enum_name), vec![value]) + mk().call_expr(func, vec![value]) } pub(crate) fn enum_constant_matches_type( diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index 4f0d97fca1..22c473c519 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -899,9 +899,7 @@ pub fn translate( // Tuple structs are in both namespaces. Enum { .. } => Namespaces::types() | Namespaces::values(), Struct { .. } | Union { .. } | Typedef { .. } => Namespaces::types(), - Function { .. } | EnumConstant { .. } | Variable { .. } | MacroObject { .. } => { - Namespaces::values() - } + Function { .. } | Variable { .. } | MacroObject { .. } => Namespaces::values(), _ => Namespaces::none(), } } @@ -997,7 +995,6 @@ pub fn translate( let needs_export = match decl.kind { Struct { .. } => true, Enum { .. } => true, - EnumConstant { .. } => true, Union { .. } => true, Typedef { .. } => { // Only check the key as opposed to `contains` @@ -3605,6 +3602,7 @@ impl<'c> Translation<'c> { } let varname = decl.get_name().expect("expected variable name").to_owned(); + let rustname = self .renamer .borrow_mut() diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2021.clang15.snap index ccd13b8fbe..9c6b49d203 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2021.clang15.snap @@ -14,28 +14,32 @@ expression: cat tests/snapshots/enums.2021.clang15.rs #[derive(Clone, Copy)] #[repr(transparent)] pub struct Foo(pub ::core::ffi::c_uint); -pub const Foo3: Foo = Foo(3); -pub const Foo2: Foo = Foo(2); -pub const Foo1: Foo = Foo(1); -pub const Foo0: Foo = Foo(0); +impl Foo { + pub const Foo0: Self = Self(0); + pub const Foo1: Self = Self(1); + pub const Foo2: Self = Self(2); + pub const Foo3: Self = Self(3); +} #[derive(Clone, Copy)] #[repr(transparent)] pub struct Bar(pub ::core::ffi::c_int); -pub const Bar3: Bar = Bar(3); -pub const Bar2: Bar = Bar(2); -pub const Bar1: Bar = Bar(1); -pub const Bar0: Bar = Bar(0); -pub const BarN1: Bar = Bar(-1); +impl Bar { + pub const BarN1: Self = Self(-1); + pub const Bar0: Self = Self(0); + pub const Bar1: Self = Self(1); + pub const Bar2: Self = Self(2); + pub const Bar3: Self = Self(3); +} pub const FOO1_MACRO: ::core::ffi::c_uint = 1 as ::core::ffi::c_uint; pub const BAR1_MACRO: ::core::ffi::c_int = 1; #[no_mangle] pub unsafe extern "C" fn test_enums() { - let mut foo: Foo = Foo0; - let mut bar: Bar = Bar0; - foo = Foo1; - bar = BarN1; - foo = Foo(Bar0.0 as ::core::ffi::c_uint); - bar = Bar(Foo0.0 as ::core::ffi::c_int); + let mut foo: Foo = Foo::Foo0; + let mut bar: Bar = Bar::Bar0; + foo = Foo::Foo1; + bar = Bar::BarN1; + foo = Foo(Bar::Bar0.0 as ::core::ffi::c_uint); + bar = Bar(Foo::Foo0.0 as ::core::ffi::c_int); foo = Foo(1 as ::core::ffi::c_int as ::core::ffi::c_uint); bar = Bar(1 as ::core::ffi::c_int); foo = Foo(3 as ::core::ffi::c_int as ::core::ffi::c_uint); @@ -50,13 +54,13 @@ pub unsafe extern "C" fn test_enums() { let c2rust_fresh1 = bar; bar = Bar(bar.0 + 1); foo = Foo(c2rust_fresh1.0 as ::core::ffi::c_uint); - let mut e: Foo = Foo1; + let mut e: Foo = Foo::Foo1; let mut enum_enum: ::core::ffi::c_int = (e.0 == foo.0) as ::core::ffi::c_int; - let mut enum_constant: ::core::ffi::c_int = (e.0 == Foo0.0) as ::core::ffi::c_int; + let mut enum_constant: ::core::ffi::c_int = (e.0 == Foo::Foo0.0) as ::core::ffi::c_int; let mut wrong_enum_enum: ::core::ffi::c_int = (e.0 == bar.0 as ::core::ffi::c_uint) as ::core::ffi::c_int; let mut wrong_enum_constant: ::core::ffi::c_int = - (e.0 == Bar0.0 as ::core::ffi::c_uint) as ::core::ffi::c_int; + (e.0 == Bar::Bar0.0 as ::core::ffi::c_uint) as ::core::ffi::c_int; match foo.0 { 0 | 1 | 2 | 3 | 42 | 4294967254 | _ => {} } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2024.clang15.snap index 5bd9839bc9..49dbe0066e 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2024.clang15.snap @@ -15,28 +15,32 @@ expression: cat tests/snapshots/enums.2024.clang15.rs #[derive(Clone, Copy)] #[repr(transparent)] pub struct Foo(pub ::core::ffi::c_uint); -pub const Foo3: Foo = Foo(3); -pub const Foo2: Foo = Foo(2); -pub const Foo1: Foo = Foo(1); -pub const Foo0: Foo = Foo(0); +impl Foo { + pub const Foo0: Self = Self(0); + pub const Foo1: Self = Self(1); + pub const Foo2: Self = Self(2); + pub const Foo3: Self = Self(3); +} #[derive(Clone, Copy)] #[repr(transparent)] pub struct Bar(pub ::core::ffi::c_int); -pub const Bar3: Bar = Bar(3); -pub const Bar2: Bar = Bar(2); -pub const Bar1: Bar = Bar(1); -pub const Bar0: Bar = Bar(0); -pub const BarN1: Bar = Bar(-1); +impl Bar { + pub const BarN1: Self = Self(-1); + pub const Bar0: Self = Self(0); + pub const Bar1: Self = Self(1); + pub const Bar2: Self = Self(2); + pub const Bar3: Self = Self(3); +} pub const FOO1_MACRO: ::core::ffi::c_uint = 1 as ::core::ffi::c_uint; pub const BAR1_MACRO: ::core::ffi::c_int = 1; #[unsafe(no_mangle)] pub unsafe extern "C" fn test_enums() { - let mut foo: Foo = Foo0; - let mut bar: Bar = Bar0; - foo = Foo1; - bar = BarN1; - foo = Foo(Bar0.0 as ::core::ffi::c_uint); - bar = Bar(Foo0.0 as ::core::ffi::c_int); + let mut foo: Foo = Foo::Foo0; + let mut bar: Bar = Bar::Bar0; + foo = Foo::Foo1; + bar = Bar::BarN1; + foo = Foo(Bar::Bar0.0 as ::core::ffi::c_uint); + bar = Bar(Foo::Foo0.0 as ::core::ffi::c_int); foo = Foo(1 as ::core::ffi::c_int as ::core::ffi::c_uint); bar = Bar(1 as ::core::ffi::c_int); foo = Foo(3 as ::core::ffi::c_int as ::core::ffi::c_uint); @@ -51,13 +55,13 @@ pub unsafe extern "C" fn test_enums() { let c2rust_fresh1 = bar; bar = Bar(bar.0 + 1); foo = Foo(c2rust_fresh1.0 as ::core::ffi::c_uint); - let mut e: Foo = Foo1; + let mut e: Foo = Foo::Foo1; let mut enum_enum: ::core::ffi::c_int = (e.0 == foo.0) as ::core::ffi::c_int; - let mut enum_constant: ::core::ffi::c_int = (e.0 == Foo0.0) as ::core::ffi::c_int; + let mut enum_constant: ::core::ffi::c_int = (e.0 == Foo::Foo0.0) as ::core::ffi::c_int; let mut wrong_enum_enum: ::core::ffi::c_int = (e.0 == bar.0 as ::core::ffi::c_uint) as ::core::ffi::c_int; let mut wrong_enum_constant: ::core::ffi::c_int = - (e.0 == Bar0.0 as ::core::ffi::c_uint) as ::core::ffi::c_int; + (e.0 == Bar::Bar0.0 as ::core::ffi::c_uint) as ::core::ffi::c_int; match foo.0 { 0 | 1 | 2 | 3 | 42 | 4294967254 | _ => {} } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap index c537891706..6d309c97ab 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap @@ -20,14 +20,18 @@ pub type size_t = usize; #[derive(Clone, Copy)] #[repr(transparent)] pub struct E(pub ::core::ffi::c_uint); -pub const EA: E = E(0); +impl E { + pub const EA: Self = Self(0); +} pub type int_t = ::core::ffi::c_int; #[derive(Clone, Copy)] #[repr(transparent)] pub struct C2Rust_Unnamed(pub ::core::ffi::c_uint); -pub const C: C2Rust_Unnamed = C2Rust_Unnamed(2); -pub const B: C2Rust_Unnamed = C2Rust_Unnamed(1); -pub const A: C2Rust_Unnamed = C2Rust_Unnamed(0); +impl C2Rust_Unnamed { + pub const A: Self = Self(0); + pub const B: Self = Self(1); + pub const C: Self = Self(2); +} unsafe extern "C" fn side_effect() -> ::core::ffi::c_int { puts(b"the return of side effect\0".as_ptr() as *const ::core::ffi::c_char); return 0 as ::core::ffi::c_int; @@ -107,7 +111,7 @@ pub unsafe extern "C" fn inc_decl_with_lvalue_side_effect() { pub unsafe extern "C" fn unsigned_compound_desugaring() { let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; let mut u: ::core::ffi::c_uint = 0 as ::core::ffi::c_uint; - let mut e: E = EA; + let mut e: E = E::EA; e = E(e.0.wrapping_add(u)); i = (i as ::core::ffi::c_uint).wrapping_add(u) as ::core::ffi::c_int; } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap index 1f8554c64c..b9428e8394 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap @@ -20,14 +20,18 @@ pub type size_t = usize; #[derive(Clone, Copy)] #[repr(transparent)] pub struct E(pub ::core::ffi::c_uint); -pub const EA: E = E(0); +impl E { + pub const EA: Self = Self(0); +} pub type int_t = ::core::ffi::c_int; #[derive(Clone, Copy)] #[repr(transparent)] pub struct C2Rust_Unnamed(pub ::core::ffi::c_uint); -pub const C: C2Rust_Unnamed = C2Rust_Unnamed(2); -pub const B: C2Rust_Unnamed = C2Rust_Unnamed(1); -pub const A: C2Rust_Unnamed = C2Rust_Unnamed(0); +impl C2Rust_Unnamed { + pub const A: Self = Self(0); + pub const B: Self = Self(1); + pub const C: Self = Self(2); +} unsafe extern "C" fn side_effect() -> ::core::ffi::c_int { puts(b"the return of side effect\0".as_ptr() as *const ::core::ffi::c_char); return 0 as ::core::ffi::c_int; @@ -107,7 +111,7 @@ pub unsafe extern "C" fn inc_decl_with_lvalue_side_effect() { pub unsafe extern "C" fn unsigned_compound_desugaring() { let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; let mut u: ::core::ffi::c_uint = 0 as ::core::ffi::c_uint; - let mut e: E = EA; + let mut e: E = E::EA; e = E(e.0.wrapping_add(u)); i = (i as ::core::ffi::c_uint).wrapping_add(u) as ::core::ffi::c_int; } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macrocase.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macrocase.c.2021.clang15.snap index c41d837292..c85ec0c48d 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macrocase.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macrocase.c.2021.clang15.snap @@ -14,8 +14,10 @@ expression: cat tests/snapshots/macrocase.2021.clang15.rs #[derive(Clone, Copy)] #[repr(transparent)] pub struct ZSTD_dParameter(pub ::core::ffi::c_uint); -pub const ZSTD_d_experimentalParam1: ZSTD_dParameter = ZSTD_dParameter(1000); -pub const ZSTD_d_windowLogMax: ZSTD_dParameter = ZSTD_dParameter(100); +impl ZSTD_dParameter { + pub const ZSTD_d_windowLogMax: Self = Self(100); + pub const ZSTD_d_experimentalParam1: Self = Self(1000); +} pub const ZSTD_d_format: ::core::ffi::c_uint = 1000 as ::core::ffi::c_uint; #[no_mangle] pub unsafe extern "C" fn ZSTD_dParam_getBounds(mut dParam: ZSTD_dParameter) -> ::core::ffi::c_int { diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macrocase.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macrocase.c.2024.clang15.snap index e4cc4f1de0..d5f510cb5e 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macrocase.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macrocase.c.2024.clang15.snap @@ -15,8 +15,10 @@ expression: cat tests/snapshots/macrocase.2024.clang15.rs #[derive(Clone, Copy)] #[repr(transparent)] pub struct ZSTD_dParameter(pub ::core::ffi::c_uint); -pub const ZSTD_d_experimentalParam1: ZSTD_dParameter = ZSTD_dParameter(1000); -pub const ZSTD_d_windowLogMax: ZSTD_dParameter = ZSTD_dParameter(100); +impl ZSTD_dParameter { + pub const ZSTD_d_windowLogMax: Self = Self(100); + pub const ZSTD_d_experimentalParam1: Self = Self(1000); +} pub const ZSTD_d_format: ::core::ffi::c_uint = 1000 as ::core::ffi::c_uint; #[unsafe(no_mangle)] pub unsafe extern "C" fn ZSTD_dParam_getBounds(mut dParam: ZSTD_dParameter) -> ::core::ffi::c_int { diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@raw_keywords.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@raw_keywords.c.2021.clang15.snap index dc4e380e78..dcbd9b9543 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@raw_keywords.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@raw_keywords.c.2021.clang15.snap @@ -15,8 +15,10 @@ pub type r#type = ::core::ffi::c_int; #[derive(Clone, Copy)] #[repr(transparent)] pub struct r#as(pub ::core::ffi::c_uint); -pub const r#await: r#as = r#as(1); -pub const r#async: r#as = r#as(0); +impl r#as { + pub const r#async: Self = Self(0); + pub const r#await: Self = Self(1); +} #[derive(Copy, Clone)] #[repr(C)] pub struct r#dyn { @@ -35,7 +37,7 @@ pub unsafe extern "C" fn r#pub(mut r#ref: r#type) {} #[export_name = "impl"] pub unsafe extern "C" fn r#impl(mut r#in: r#type) { let mut r#trait: r#type = super_0; - let mut r#let: r#as = r#async; + let mut r#let: r#as = r#as::r#async; let mut r#mod: r#dyn = r#dyn { r#false: 0 }; r#mod.r#false = 0 as ::core::ffi::c_int as r#type; let mut r#mut: r#fn = r#fn { r#where: 0 }; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@raw_keywords.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@raw_keywords.c.2024.clang15.snap index e73cb9436b..64a790fa54 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@raw_keywords.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@raw_keywords.c.2024.clang15.snap @@ -16,8 +16,10 @@ pub type r#type = ::core::ffi::c_int; #[derive(Clone, Copy)] #[repr(transparent)] pub struct r#as(pub ::core::ffi::c_uint); -pub const r#await: r#as = r#as(1); -pub const r#async: r#as = r#as(0); +impl r#as { + pub const r#async: Self = Self(0); + pub const r#await: Self = Self(1); +} #[derive(Copy, Clone)] #[repr(C)] pub struct r#dyn { @@ -36,7 +38,7 @@ pub unsafe extern "C" fn r#pub(mut r#ref: r#type) {} #[unsafe(export_name = "impl")] pub unsafe extern "C" fn r#impl(mut r#in: r#type) { let mut r#trait: r#type = super_0; - let mut r#let: r#as = r#async; + let mut r#let: r#as = r#as::r#async; let mut r#mod: r#dyn = r#dyn { r#false: 0 }; r#mod.r#false = 0 as ::core::ffi::c_int as r#type; let mut r#mut: r#fn = r#fn { r#where: 0 }; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@records.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@records.c.2021.clang15.snap index 8cfbb62b5d..9ea67c6739 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@records.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@records.c.2021.clang15.snap @@ -17,8 +17,10 @@ pub struct AnonEnumInStruct {} #[derive(Clone, Copy)] #[repr(transparent)] pub struct C2Rust_Unnamed(pub ::core::ffi::c_uint); -pub const VALUE2: C2Rust_Unnamed = C2Rust_Unnamed(1); -pub const VALUE1: C2Rust_Unnamed = C2Rust_Unnamed(0); +impl C2Rust_Unnamed { + pub const VALUE1: Self = Self(0); + pub const VALUE2: Self = Self(1); +} #[derive(Copy, Clone)] #[repr(C)] pub struct AnonStructInStruct { @@ -45,8 +47,10 @@ pub union AnonEnumInUnion { #[derive(Clone, Copy)] #[repr(transparent)] pub struct C2Rust_Unnamed_1(pub ::core::ffi::c_uint); -pub const VALUE4: C2Rust_Unnamed_1 = C2Rust_Unnamed_1(1); -pub const VALUE3: C2Rust_Unnamed_1 = C2Rust_Unnamed_1(0); +impl C2Rust_Unnamed_1 { + pub const VALUE3: Self = Self(0); + pub const VALUE4: Self = Self(1); +} #[derive(Copy, Clone)] #[repr(C)] pub union AnonStructInUnion { @@ -70,7 +74,7 @@ pub struct InsideUnion { } #[no_mangle] pub unsafe extern "C" fn struct_declaration() { - let mut value: ::core::ffi::c_int = VALUE2.0 as ::core::ffi::c_int; + let mut value: ::core::ffi::c_int = C2Rust_Unnamed::VALUE2.0 as ::core::ffi::c_int; let mut a: AnonEnumInStruct = AnonEnumInStruct {}; let mut b: AnonStructInStruct = AnonStructInStruct { c2rust_unnamed: C2Rust_Unnamed_0 { some_number: 0 }, @@ -81,7 +85,7 @@ pub unsafe extern "C" fn struct_declaration() { } #[no_mangle] pub unsafe extern "C" fn union_declaration() { - let mut value: ::core::ffi::c_int = VALUE4.0 as ::core::ffi::c_int; + let mut value: ::core::ffi::c_int = C2Rust_Unnamed_1::VALUE4.0 as ::core::ffi::c_int; let mut a: AnonEnumInUnion = AnonEnumInUnion { a: 0 }; let mut b: AnonStructInUnion = AnonStructInUnion { c2rust_unnamed: C2Rust_Unnamed_2 { some_number: 0 }, diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@records.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@records.c.2024.clang15.snap index 46cf4abce5..d3d8f29afc 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@records.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@records.c.2024.clang15.snap @@ -18,8 +18,10 @@ pub struct AnonEnumInStruct {} #[derive(Clone, Copy)] #[repr(transparent)] pub struct C2Rust_Unnamed(pub ::core::ffi::c_uint); -pub const VALUE2: C2Rust_Unnamed = C2Rust_Unnamed(1); -pub const VALUE1: C2Rust_Unnamed = C2Rust_Unnamed(0); +impl C2Rust_Unnamed { + pub const VALUE1: Self = Self(0); + pub const VALUE2: Self = Self(1); +} #[derive(Copy, Clone)] #[repr(C)] pub struct AnonStructInStruct { @@ -46,8 +48,10 @@ pub union AnonEnumInUnion { #[derive(Clone, Copy)] #[repr(transparent)] pub struct C2Rust_Unnamed_1(pub ::core::ffi::c_uint); -pub const VALUE4: C2Rust_Unnamed_1 = C2Rust_Unnamed_1(1); -pub const VALUE3: C2Rust_Unnamed_1 = C2Rust_Unnamed_1(0); +impl C2Rust_Unnamed_1 { + pub const VALUE3: Self = Self(0); + pub const VALUE4: Self = Self(1); +} #[derive(Copy, Clone)] #[repr(C)] pub union AnonStructInUnion { @@ -71,7 +75,7 @@ pub struct InsideUnion { } #[unsafe(no_mangle)] pub unsafe extern "C" fn struct_declaration() { - let mut value: ::core::ffi::c_int = VALUE2.0 as ::core::ffi::c_int; + let mut value: ::core::ffi::c_int = C2Rust_Unnamed::VALUE2.0 as ::core::ffi::c_int; let mut a: AnonEnumInStruct = AnonEnumInStruct {}; let mut b: AnonStructInStruct = AnonStructInStruct { c2rust_unnamed: C2Rust_Unnamed_0 { some_number: 0 }, @@ -82,7 +86,7 @@ pub unsafe extern "C" fn struct_declaration() { } #[unsafe(no_mangle)] pub unsafe extern "C" fn union_declaration() { - let mut value: ::core::ffi::c_int = VALUE4.0 as ::core::ffi::c_int; + let mut value: ::core::ffi::c_int = C2Rust_Unnamed_1::VALUE4.0 as ::core::ffi::c_int; let mut a: AnonEnumInUnion = AnonEnumInUnion { a: 0 }; let mut b: AnonStructInUnion = AnonStructInUnion { c2rust_unnamed: C2Rust_Unnamed_2 { some_number: 0 }, diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@scalar_init.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@scalar_init.c.2021.clang15.snap index a8ac5f228d..c62eabf5b9 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@scalar_init.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@scalar_init.c.2021.clang15.snap @@ -15,7 +15,9 @@ expression: cat tests/snapshots/scalar_init.2021.clang15.rs #[derive(Clone, Copy)] #[repr(transparent)] pub struct E(pub ::core::ffi::c_uint); -pub const A: E = E(0); +impl E { + pub const A: Self = Self(0); +} pub const r#true: ::core::ffi::c_int = 1 as ::core::ffi::c_int; #[no_mangle] pub unsafe extern "C" fn scalar_init() { @@ -26,7 +28,7 @@ pub unsafe extern "C" fn scalar_init() { let mut f: ::core::ffi::c_float = 42.0f32; let mut d: ::core::ffi::c_double = 42.0f64; let mut ld: ::f128::f128 = ::f128::f128::new(42.0); - let mut e: E = A; + let mut e: E = E::A; let mut p: *mut ::core::ffi::c_int = &raw mut i; let mut eb: bool = false; let mut ec: ::core::ffi::c_char = 0; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@scalar_init.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@scalar_init.c.2024.clang15.snap index 60ed10f771..91572d244f 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@scalar_init.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@scalar_init.c.2024.clang15.snap @@ -15,7 +15,9 @@ expression: cat tests/snapshots/scalar_init.2024.clang15.rs #[derive(Clone, Copy)] #[repr(transparent)] pub struct E(pub ::core::ffi::c_uint); -pub const A: E = E(0); +impl E { + pub const A: Self = Self(0); +} pub const r#true: ::core::ffi::c_int = 1 as ::core::ffi::c_int; #[unsafe(no_mangle)] pub unsafe extern "C" fn scalar_init() { @@ -26,7 +28,7 @@ pub unsafe extern "C" fn scalar_init() { let mut f: ::core::ffi::c_float = 42.0f32; let mut d: ::core::ffi::c_double = 42.0f64; let mut ld: ::f128::f128 = ::f128::f128::new(42.0); - let mut e: E = A; + let mut e: E = E::A; let mut p: *mut ::core::ffi::c_int = &raw mut i; let mut eb: bool = false; let mut ec: ::core::ffi::c_char = 0; diff --git a/tests/unit/enums/src/test_enums.rs b/tests/unit/enums/src/test_enums.rs index c100fd91cc..17224cd324 100644 --- a/tests/unit/enums/src/test_enums.rs +++ b/tests/unit/enums/src/test_enums.rs @@ -1,12 +1,10 @@ use crate::big_enum::{rust_entry5, E1, E2, E3}; -use crate::enum_as_int::{rust_entry, A, B, E}; +use crate::enum_as_int::{rust_entry, E}; use crate::enum_compound::rust_entry6; use crate::enum_duplicate::{e, rust_entry3}; use crate::enum_fwd_decl::rust_foo; use crate::enum_ret::{rust_entry2, Color}; -use crate::non_canonical_enum_def::{ - hrtimer_restart, rust_abc, HRTIMER_NORESTART, HRTIMER_RESTART, -}; +use crate::non_canonical_enum_def::{hrtimer_restart, rust_abc}; use crate::top_enum::{rust_entry4, E as otherE}; use std::ffi::{c_int, c_uint}; @@ -35,8 +33,8 @@ const BUFFER_SIZE6: usize = 1; #[test] pub fn test_variants() { - assert_eq!(A.0 as u32, 0); - assert_eq!(B.0 as u32, 1); + assert_eq!(E::A.0 as u32, 0); + assert_eq!(E::B.0 as u32, 1); } #[test] diff --git a/tests/unit/misc/src/test_uninitialized.rs b/tests/unit/misc/src/test_uninitialized.rs index 505aee8937..111b1d0b7f 100644 --- a/tests/unit/misc/src/test_uninitialized.rs +++ b/tests/unit/misc/src/test_uninitialized.rs @@ -1,6 +1,6 @@ //! feature_raw_ref_op -use crate::uninitialized::{bar, baz, e, foo, rust_entry2, s, /*myint, myintp,*/ u}; +use crate::uninitialized::{e, rust_entry2, s, /*myint, myintp,*/ u}; use std::ffi::{c_int, c_uint}; unsafe extern "C" { @@ -26,9 +26,9 @@ pub fn test_buffer() { #[test] pub fn test_types() { - assert_eq!(foo.0 as u32, 1); - assert_eq!(bar.0 as u32, 2); - assert_eq!(baz.0 as u32, 3); + assert_eq!(e::foo.0 as u32, 1); + assert_eq!(e::bar.0 as u32, 2); + assert_eq!(e::baz.0 as u32, 3); // FIXME: union fields are private // let my_union = u { x: 32 };