Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add tagged union support to the C backend? #28

Open
Gankra opened this issue Jun 30, 2024 · 1 comment
Open

add tagged union support to the C backend? #28

Gankra opened this issue Jun 30, 2024 · 1 comment
Labels
enhancement New feature or request help wanted Extra attention is needed question Further information is requested

Comments

@Gankra
Copy link
Owner

Gankra commented Jun 30, 2024

Currently the C backend bails out everywhere it finds a rust-like tagged union:

Ty::Tagged(_tagged_ty) => {
return Err(UnsupportedError::Other(
"c doesn't have tagged unions impled yet".to_owned(),
))?;
/*
// Emit an actual enum decl
self.generate_repr_attr(f, &tagged_ty.attrs, "tagged")?;
writeln!(f, "typedef struct {} {{", tagged_ty.name)?;
f.add_indent(1);

This is fair since C doesn't have any such notion, but, RFC#2195 "really tagged unions" exists precisely to define the layouts of tagged unions when you slap repr(C), repr(u8) or repr(C, u8) on a rust tagged union.

This is implemented by cbindgen and used by firefox's webrender bindings.

I am a bit on the fence as to whether it is in scope for abi-cafe to provide this feature. If you did provide it you'd have to do some careful and tedious analysis of the attributes on the tagged union since repr(u8) and repr(C) have substantially different layouts.

@Gankra Gankra added enhancement New feature or request help wanted Extra attention is needed question Further information is requested labels Jun 30, 2024
@Gankra
Copy link
Owner Author

Gankra commented Jul 1, 2024

A quick TL;DR of the RFC:

The repr(C) layout is the most obvious lowering to a struct containing a c-style enum and a union. The enum says which case of the union is currently valid.

The repr(u8) layout (also repr(u32), etc.) is similar but the enum specifically has that integer type, and instead of being stored in a wrapper struct it's stored as the first field of every variant of the union. This is a more compact layout because space doesn't need to be wasted for padding between the enum and the union. Also it's more reliable because C refuses to specify what the backing integer of a normal enum is so rustc just guesses based on the platform.

repr(C, u8) says to use the tag size of repr(u8) but the layout of repr(C).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant