@@ -337,7 +337,9 @@ pub trait RustGenerator<'a> {
337
337
// If the type recursively owns data and it's a
338
338
// variant/record/list, then we need to place the
339
339
// lifetime parameter on the type as well.
340
- if ( info. has_list || info. has_borrow_handle ) && needs_generics ( self . resolve ( ) , & ty. kind )
340
+ if ( info. has_list || info. has_borrow_handle )
341
+ && !info. has_own_handle
342
+ && needs_generics ( self . resolve ( ) , & ty. kind )
341
343
{
342
344
self . print_generics ( lt) ;
343
345
}
@@ -470,6 +472,11 @@ pub trait RustGenerator<'a> {
470
472
} else {
471
473
mode
472
474
} ;
475
+ // Lists with `own` handles must always be owned
476
+ let mode = match * ty {
477
+ Type :: Id ( id) if self . info ( id) . has_own_handle => TypeMode :: Owned ,
478
+ _ => mode,
479
+ } ;
473
480
match mode {
474
481
TypeMode :: AllBorrowed ( lt) => {
475
482
self . print_borrowed_slice ( false , ty, lt, next_mode) ;
@@ -529,21 +536,29 @@ pub trait RustGenerator<'a> {
529
536
530
537
fn modes_of ( & self , ty : TypeId ) -> Vec < ( String , TypeMode ) > {
531
538
let info = self . info ( ty) ;
539
+ // If this type isn't actually used, no need to generate it.
532
540
if !info. owned && !info. borrowed {
533
541
return Vec :: new ( ) ;
534
542
}
535
543
let mut result = Vec :: new ( ) ;
536
- let first_mode =
537
- if info. owned || !info. borrowed || matches ! ( self . ownership( ) , Ownership :: Owning ) {
538
- if info. has_borrow_handle {
539
- TypeMode :: HandlesBorrowed ( "'a" )
540
- } else {
541
- TypeMode :: Owned
542
- }
544
+
545
+ // Prioritize generating an "owned" type. This is done to simplify
546
+ // generated bindings by default. Borrowed handles always use a borrow,
547
+ // however.
548
+ let first_mode = if info. owned
549
+ || !info. borrowed
550
+ || matches ! ( self . ownership( ) , Ownership :: Owning )
551
+ || info. has_own_handle
552
+ {
553
+ if info. has_borrow_handle {
554
+ TypeMode :: HandlesBorrowed ( "'a" )
543
555
} else {
544
- assert ! ( !self . uses_two_names( & info) ) ;
545
- TypeMode :: AllBorrowed ( "'a" )
546
- } ;
556
+ TypeMode :: Owned
557
+ }
558
+ } else {
559
+ assert ! ( !self . uses_two_names( & info) ) ;
560
+ TypeMode :: AllBorrowed ( "'a" )
561
+ } ;
547
562
result. push ( ( self . result_name ( ty) , first_mode) ) ;
548
563
if self . uses_two_names ( & info) {
549
564
result. push ( ( self . param_name ( ty) , TypeMode :: AllBorrowed ( "'a" ) ) ) ;
@@ -1025,15 +1040,21 @@ pub trait RustGenerator<'a> {
1025
1040
}
1026
1041
1027
1042
fn uses_two_names ( & self , info : & TypeInfo ) -> bool {
1028
- info. has_list
1043
+ // Types are only duplicated if explicitly requested ...
1044
+ matches ! (
1045
+ self . ownership( ) ,
1046
+ Ownership :: Borrowing {
1047
+ duplicate_if_necessary: true
1048
+ }
1049
+ )
1050
+ // ... and if they're both used in a borrowed/owned context
1029
1051
&& info. borrowed
1030
1052
&& info. owned
1031
- && matches ! (
1032
- self . ownership( ) ,
1033
- Ownership :: Borrowing {
1034
- duplicate_if_necessary: true
1035
- }
1036
- )
1053
+ // ... and they have a list ...
1054
+ && info. has_list
1055
+ // ... and if there's NOT an `own` handle since those are always
1056
+ // done by ownership.
1057
+ && !info. has_own_handle
1037
1058
}
1038
1059
1039
1060
fn lifetime_for ( & self , info : & TypeInfo , mode : TypeMode ) -> Option < & ' static str > {
0 commit comments