@@ -84,6 +84,9 @@ struct CodegenResult<'a> {
84
84
/// Whether an union has been generated at least once.
85
85
saw_union : bool ,
86
86
87
+ /// Whether an incomplete array has been generated at least once.
88
+ saw_incomplete_array : bool ,
89
+
87
90
items_seen : HashSet < ItemId > ,
88
91
/// The set of generated function/var names, needed because in C/C++ is
89
92
/// legal to do something like:
@@ -115,6 +118,7 @@ impl<'a> CodegenResult<'a> {
115
118
CodegenResult {
116
119
items : vec ! [ ] ,
117
120
saw_union : false ,
121
+ saw_incomplete_array : false ,
118
122
codegen_id : codegen_id,
119
123
items_seen : Default :: default ( ) ,
120
124
functions_seen : Default :: default ( ) ,
@@ -132,6 +136,10 @@ impl<'a> CodegenResult<'a> {
132
136
self . saw_union = true ;
133
137
}
134
138
139
+ fn saw_incomplete_array ( & mut self ) {
140
+ self . saw_incomplete_array = true ;
141
+ }
142
+
135
143
fn seen ( & self , item : ItemId ) -> bool {
136
144
self . items_seen . contains ( & item)
137
145
}
@@ -175,6 +183,7 @@ impl<'a> CodegenResult<'a> {
175
183
cb ( & mut new) ;
176
184
177
185
self . saw_union |= new. saw_union ;
186
+ self . saw_incomplete_array |= new. saw_incomplete_array ;
178
187
179
188
new. items
180
189
}
@@ -344,6 +353,10 @@ impl CodeGenerator for Module {
344
353
if saw_union && !ctx. options ( ) . unstable_rust {
345
354
utils:: prepend_union_types ( ctx, & mut * result) ;
346
355
}
356
+ let saw_incomplete_array = result. saw_incomplete_array ;
357
+ if saw_incomplete_array && !ctx. options ( ) . unstable_rust {
358
+ utils:: prepend_incomplete_array_types ( ctx, & mut * result) ;
359
+ }
347
360
if ctx. need_bindegen_complex_type ( ) {
348
361
utils:: prepend_complex_type ( ctx, & mut * result) ;
349
362
}
@@ -1013,6 +1026,16 @@ impl CodeGenerator for CompInfo {
1013
1026
} else {
1014
1027
quote_ty ! ( ctx. ext_cx( ) , __BindgenUnionField<$ty>)
1015
1028
}
1029
+ } else if let Some ( item) = field_ty. is_incomplete_array ( ctx) {
1030
+ result. saw_incomplete_array ( ) ;
1031
+
1032
+ let inner = item. to_rust_ty ( ctx) ;
1033
+
1034
+ if ctx. options ( ) . enable_cxx_namespaces {
1035
+ quote_ty ! ( ctx. ext_cx( ) , root:: __IncompleteArrayField<$inner>)
1036
+ } else {
1037
+ quote_ty ! ( ctx. ext_cx( ) , __IncompleteArrayField<$inner>)
1038
+ }
1016
1039
} else {
1017
1040
ty
1018
1041
} ;
@@ -2333,6 +2356,59 @@ mod utils {
2333
2356
result. extend ( old_items. into_iter ( ) ) ;
2334
2357
}
2335
2358
2359
+ pub fn prepend_incomplete_array_types ( ctx : & BindgenContext ,
2360
+ result : & mut Vec < P < ast:: Item > > ) {
2361
+ let prefix = ctx. trait_prefix ( ) ;
2362
+
2363
+ // TODO(emilio): The fmt::Debug impl could be way nicer with
2364
+ // std::intrinsics::type_name, but...
2365
+ let incomplete_array_decl = quote_item ! ( ctx. ext_cx( ) ,
2366
+ #[ repr( C ) ]
2367
+ pub struct __IncompleteArrayField<T >(
2368
+ :: $prefix:: marker:: PhantomData <T >) ;
2369
+ )
2370
+ . unwrap ( ) ;
2371
+
2372
+ let incomplete_array_impl = quote_item ! ( & ctx. ext_cx( ) ,
2373
+ impl <T > __IncompleteArrayField<T > {
2374
+ #[ inline]
2375
+ pub fn new( ) -> Self {
2376
+ __IncompleteArrayField( :: $prefix:: marker:: PhantomData )
2377
+ }
2378
+
2379
+ #[ inline]
2380
+ pub unsafe fn as_slice( & self , len: usize ) -> & [ T ] {
2381
+ :: std:: slice:: from_raw_parts( :: std:: mem:: transmute( self ) , len)
2382
+ }
2383
+
2384
+ #[ inline]
2385
+ pub unsafe fn as_mut_slice( & mut self , len: usize ) -> & mut [ T ] {
2386
+ :: std:: slice:: from_raw_parts_mut( :: std:: mem:: transmute( self ) , len)
2387
+ }
2388
+ }
2389
+ )
2390
+ . unwrap ( ) ;
2391
+
2392
+ let incomplete_array_debug_impl = quote_item ! ( ctx. ext_cx( ) ,
2393
+ impl <T > :: std:: fmt:: Debug for __IncompleteArrayField<T > {
2394
+ fn fmt( & self , fmt: & mut :: std:: fmt:: Formatter )
2395
+ -> :: std:: fmt:: Result {
2396
+ fmt. write_str( "__IncompleteArrayField" )
2397
+ }
2398
+ }
2399
+ )
2400
+ . unwrap ( ) ;
2401
+
2402
+ let items = vec ! [
2403
+ incomplete_array_decl,
2404
+ incomplete_array_impl,
2405
+ incomplete_array_debug_impl,
2406
+ ] ;
2407
+
2408
+ let old_items = mem:: replace ( result, items) ;
2409
+ result. extend ( old_items. into_iter ( ) ) ;
2410
+ }
2411
+
2336
2412
pub fn prepend_complex_type ( ctx : & BindgenContext ,
2337
2413
result : & mut Vec < P < ast:: Item > > ) {
2338
2414
let complex_type = quote_item ! ( ctx. ext_cx( ) ,
0 commit comments