Skip to content

Attempt to implement support for self-referential union types - #3419

Open
erickt wants to merge 2 commits into
rust-lang:mainfrom
erickt:union2
Open

Attempt to implement support for self-referential union types#3419
erickt wants to merge 2 commits into
rust-lang:mainfrom
erickt:union2

Conversation

@erickt

@erickt erickt commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

In llvm/llvm-project#185449, LLVM's libc++ changed a header to use a recursive self-referential type, which looks approximately like:

template <class A0, class... As> union RUnion { A0 arg; RUnion<As...> u; };
template <class A> union RUnion<A> { A arg; };
struct Wrap { RUnion<int, float> u; };

This code caused bindgen to panic. The problem seems to be that bindgen can't handle the recursive self-referential union. Digging into the code, it seems that when this type is being parsed, with_loaned_item removes the type from the context. Later on, when parsing the CompKind::Union, CompInfo::layout would call resolve_type on an item that was loaned out, so it panics. This bug was filed in #3397.

I've attempted to fix this bug with the help of Gemini agent, and it seems that we might be able to swap out resolve_type with safe_resolve_type in a few locations to get it to stop erroring out. This seems to make sense as best as I understand this situation, although there may be a chance that returning None in these callsites might be incorrect. But I couldn't find a counter example that shows incorrect code.

Fixes #3397

Update safe_resolve_type to use .and_then(|t| t.kind().as_type())
and convert panicking resolve_type calls across ty.rs and enum_ty.rs
to safe_resolve_type.

This prevents compiler panics when item IDs are temporarily loaned
out during AST graph traversal (with_loaned_item) or when IDs point
to non-type items.

Test: cargo test -p bindgen-tests

TAG=agy
CONV=49e4437e-d358-4213-bb5a-8478173dda33
@rustbot rustbot added the A-C++ label Jul 30, 2026
Early return None in CompInfo::layout for uninstantiated C++
template definitions (!self.template_params.is_empty()), avoiding
infinite layout recursion on variadic template unions.

In CompInfo::is_rust_union, check ctx.uses_any_template_parameters
during codegen, emitting struct + __BindgenUnionField<T> wrappers for
unconstrained generic template union fields to prevent Rust compiler
E0740 errors.

Test: cargo test -p bindgen-tests

TAG=agy
CONV=49e4437e-d358-4213-bb5a-8478173dda33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bindgen panicked with message "Not an item: ItemId(...)" when parsing recursive union templates (breaks recent LLVM libc++ std::aligned_union)

2 participants