@@ -11,7 +11,7 @@ use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
1111use crate :: bindgen:: dependencies:: Dependencies ;
1212use crate :: bindgen:: ir:: {
1313 AnnotationSet , Cfg , Constant , Documentation , Field , GenericArgument , GenericParams , Item ,
14- ItemContainer , Path , Repr , ReprAlign , ReprStyle , Type ,
14+ ItemContainer , Path , Repr , ReprAlign , ReprStyle , Type , Typedef ,
1515} ;
1616use crate :: bindgen:: library:: Library ;
1717use crate :: bindgen:: mangle;
@@ -122,11 +122,27 @@ impl Struct {
122122 has_tag_field : bool ,
123123 is_enum_variant_body : bool ,
124124 alignment : Option < ReprAlign > ,
125- is_transparent : bool ,
125+ mut is_transparent : bool ,
126126 cfg : Option < Cfg > ,
127127 annotations : AnnotationSet ,
128128 documentation : Documentation ,
129129 ) -> Self {
130+ // WARNING: Zero-sized transparent structs are legal rust [1], but zero-sized types of any
131+ // repr are "best avoided entirely" [2] because they "will be nonsensical or problematic if
132+ // passed through the FFI boundary" [3]. Further, because no well-defined underlying native
133+ // type exists for a ZST, we cannot emit a typedef and must define an empty struct instead.
134+ //
135+ // [1] https://github.com/rust-lang/rust/issues/77841#issuecomment-716575747
136+ // [2] https://github.com/rust-lang/rust/issues/77841#issuecomment-716796313
137+ // [3] https://doc.rust-lang.org/nomicon/other-reprs.html
138+ if fields. is_empty ( ) {
139+ warn ! (
140+ "Passing zero-sized struct {} across the FFI boundary is undefined behavior" ,
141+ & path
142+ ) ;
143+ is_transparent = false ;
144+ }
145+
130146 let export_name = path. name ( ) . to_owned ( ) ;
131147 Self {
132148 path,
@@ -150,6 +166,14 @@ impl Struct {
150166 }
151167 }
152168
169+ /// Attempts to convert this struct to a typedef (only works for transparent structs).
170+ pub fn as_typedef ( & self ) -> Option < Typedef > {
171+ match self . fields . first ( ) {
172+ Some ( field) if self . is_transparent => Some ( Typedef :: new_from_struct_field ( self , field) ) ,
173+ _ => None ,
174+ }
175+ }
176+
153177 pub fn add_monomorphs ( & self , library : & Library , out : & mut Monomorphs ) {
154178 // Generic structs can instantiate monomorphs only once they've been
155179 // instantiated. See `instantiate_monomorph` for more details.
0 commit comments