@@ -561,7 +561,19 @@ impl CodeGenerator for Type {
561
561
let layout = self . layout ( ctx) . unwrap_or_else ( Layout :: zero) ;
562
562
BlobTyBuilder :: new ( layout) . build ( )
563
563
} else {
564
- inner_item. to_rust_ty ( ctx)
564
+ let inner_rust_ty = inner_item. to_rust_ty ( ctx) ;
565
+
566
+ // We get a unit if the inner type is a template definition
567
+ // that is opaque or has non-type template parameters and
568
+ // doesn't know its layout. Its possible that we have better
569
+ // information about the layout, and in the worst case, just
570
+ // make sure we don't return a zero-sized type.
571
+ if inner_rust_ty == aster:: AstBuilder :: new ( ) . ty ( ) . unit ( ) {
572
+ let layout = self . layout ( ctx) . unwrap_or_else ( || Layout :: for_size ( 1 ) ) ;
573
+ BlobTyBuilder :: new ( layout) . build ( )
574
+ } else {
575
+ inner_rust_ty
576
+ }
565
577
} ;
566
578
567
579
{
@@ -2265,67 +2277,7 @@ impl ToRustTy for Type {
2265
2277
aster:: AstBuilder :: new ( ) . ty ( ) . path ( ) . ids ( path) . build ( )
2266
2278
}
2267
2279
TypeKind :: TemplateInstantiation ( ref inst) => {
2268
- let decl = inst. template_definition ( ) ;
2269
- let mut ty = decl. to_rust_ty ( ctx) . unwrap ( ) ;
2270
-
2271
- // If we gave up when making a type for the template definition,
2272
- // check if maybe we can make a better opaque blob for the
2273
- // instantiation.
2274
- if ty == aster:: AstBuilder :: new ( ) . ty ( ) . unit ( ) . unwrap ( ) {
2275
- if let Some ( layout) = self . layout ( ctx) {
2276
- ty = BlobTyBuilder :: new ( layout) . build ( ) . unwrap ( )
2277
- }
2278
- }
2279
-
2280
- let decl_params = if let Some ( params) =
2281
- decl. self_template_params ( ctx) {
2282
- params
2283
- } else {
2284
- // This can happen if we generated an opaque type for a
2285
- // partial template specialization, in which case we just
2286
- // use the opaque type's layout. If we don't have a layout,
2287
- // we cross our fingers and hope for the best :-/
2288
- debug_assert ! ( ctx. resolve_type_through_type_refs( decl)
2289
- . is_opaque( ) ) ;
2290
- let layout = self . layout ( ctx) . unwrap_or ( Layout :: zero ( ) ) ;
2291
- ty = BlobTyBuilder :: new ( layout) . build ( ) . unwrap ( ) ;
2292
-
2293
- vec ! [ ]
2294
- } ;
2295
-
2296
- // TODO: If the decl type is a template class/struct
2297
- // declaration's member template declaration, it could rely on
2298
- // generic template parameters from its outer template
2299
- // class/struct. When we emit bindings for it, it could require
2300
- // *more* type arguments than we have here, and we will need to
2301
- // reconstruct them somehow. We don't have any means of doing
2302
- // that reconstruction at this time.
2303
-
2304
- if let ast:: TyKind :: Path ( _, ref mut path) = ty. node {
2305
- let template_args = inst. template_arguments ( )
2306
- . iter ( )
2307
- . zip ( decl_params. iter ( ) )
2308
- // Only pass type arguments for the type parameters that
2309
- // the decl uses.
2310
- . filter ( |& ( _, param) | ctx. uses_template_parameter ( decl, * param) )
2311
- . map ( |( arg, _) | arg. to_rust_ty ( ctx) )
2312
- . collect :: < Vec < _ > > ( ) ;
2313
-
2314
- path. segments . last_mut ( ) . unwrap ( ) . parameters = if
2315
- template_args. is_empty ( ) {
2316
- None
2317
- } else {
2318
- Some ( P ( ast:: PathParameters :: AngleBracketed (
2319
- ast:: AngleBracketedParameterData {
2320
- lifetimes : vec ! [ ] ,
2321
- types : P :: from_vec ( template_args) ,
2322
- bindings : P :: from_vec ( vec ! [ ] ) ,
2323
- }
2324
- ) ) )
2325
- }
2326
- }
2327
-
2328
- P ( ty)
2280
+ inst. to_rust_ty ( ctx, self )
2329
2281
}
2330
2282
TypeKind :: ResolvedTypeRef ( inner) => inner. to_rust_ty ( ctx) ,
2331
2283
TypeKind :: TemplateAlias ( inner, _) |
@@ -2409,6 +2361,74 @@ impl ToRustTy for Type {
2409
2361
}
2410
2362
}
2411
2363
2364
+ impl ToRustTy for TemplateInstantiation {
2365
+ type Extra = Type ;
2366
+
2367
+ fn to_rust_ty ( & self , ctx : & BindgenContext , self_ty : & Type ) -> P < ast:: Ty > {
2368
+ let decl = self . template_definition ( ) ;
2369
+ let mut ty = decl. to_rust_ty ( ctx) . unwrap ( ) ;
2370
+
2371
+ if ty == aster:: AstBuilder :: new ( ) . ty ( ) . unit ( ) . unwrap ( ) {
2372
+ // If we gave up when making a type for the template definition,
2373
+ // check if maybe we can make a better opaque blob for the
2374
+ // instantiation. If not, at least don't use a zero-sized type.
2375
+ if let Some ( layout) = self_ty. layout ( ctx) {
2376
+ return BlobTyBuilder :: new ( layout) . build ( ) ;
2377
+ } else {
2378
+ return quote_ty ! ( ctx. ext_cx( ) , u8 ) ;
2379
+ }
2380
+ }
2381
+
2382
+ let decl_params = match decl. self_template_params ( ctx) {
2383
+ Some ( params) => params,
2384
+ None => {
2385
+ // This can happen if we generated an opaque type for a
2386
+ // partial template specialization, in which case we just
2387
+ // use the opaque type's layout. If we don't have a layout,
2388
+ // we cross our fingers and hope for the best :-/
2389
+ debug_assert ! ( ctx. resolve_type_through_type_refs( decl)
2390
+ . is_opaque( ) ) ;
2391
+ let layout = self_ty. layout ( ctx) . unwrap_or ( Layout :: zero ( ) ) ;
2392
+ return BlobTyBuilder :: new ( layout) . build ( ) ;
2393
+ }
2394
+ } ;
2395
+
2396
+ // TODO: If the decl type is a template class/struct
2397
+ // declaration's member template declaration, it could rely on
2398
+ // generic template parameters from its outer template
2399
+ // class/struct. When we emit bindings for it, it could require
2400
+ // *more* type arguments than we have here, and we will need to
2401
+ // reconstruct them somehow. We don't have any means of doing
2402
+ // that reconstruction at this time.
2403
+
2404
+ if let ast:: TyKind :: Path ( _, ref mut path) = ty. node {
2405
+ let template_args = self . template_arguments ( )
2406
+ . iter ( )
2407
+ . zip ( decl_params. iter ( ) )
2408
+ // Only pass type arguments for the type parameters that
2409
+ // the decl uses.
2410
+ . filter ( |& ( _, param) | ctx. uses_template_parameter ( decl, * param) )
2411
+ . map ( |( arg, _) | arg. to_rust_ty ( ctx) )
2412
+ . collect :: < Vec < _ > > ( ) ;
2413
+
2414
+ path. segments . last_mut ( ) . unwrap ( ) . parameters = if
2415
+ template_args. is_empty ( ) {
2416
+ None
2417
+ } else {
2418
+ Some ( P ( ast:: PathParameters :: AngleBracketed (
2419
+ ast:: AngleBracketedParameterData {
2420
+ lifetimes : vec ! [ ] ,
2421
+ types : P :: from_vec ( template_args) ,
2422
+ bindings : P :: from_vec ( vec ! [ ] ) ,
2423
+ }
2424
+ ) ) )
2425
+ }
2426
+ }
2427
+
2428
+ P ( ty)
2429
+ }
2430
+ }
2431
+
2412
2432
impl ToRustTy for FunctionSig {
2413
2433
type Extra = Item ;
2414
2434
0 commit comments