@@ -823,8 +823,7 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
823
823
write_type ( out, & arg. ty ) ;
824
824
write ! ( out, "::from_raw({})" , arg. name. cxx) ;
825
825
} else if let Type :: UniquePtr ( _) = & arg. ty {
826
- write_type ( out, & arg. ty ) ;
827
- write ! ( out, "({})" , arg. name. cxx) ;
826
+ write ! ( out, "::std::move(*{})" , arg. name. cxx) ;
828
827
} else if arg. ty == RustString {
829
828
out. builtin . unsafe_bitcopy = true ;
830
829
write ! (
@@ -846,7 +845,6 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
846
845
write ! ( out, ")" ) ;
847
846
match & efn. ret {
848
847
Some ( Type :: RustBox ( _) ) => write ! ( out, ".into_raw()" ) ,
849
- Some ( Type :: UniquePtr ( _) ) => write ! ( out, ".release()" ) ,
850
848
Some ( Type :: Str ( _) | Type :: SliceRef ( _) ) if !indirect_return => write ! ( out, ")" ) ,
851
849
_ => { }
852
850
}
@@ -1092,7 +1090,6 @@ fn write_rust_function_shim_impl(
1092
1090
write ! ( out, "{}" , arg. name. cxx) ;
1093
1091
match & arg. ty {
1094
1092
Type :: RustBox ( _) => write ! ( out, ".into_raw()" ) ,
1095
- Type :: UniquePtr ( _) => write ! ( out, ".release()" ) ,
1096
1093
ty if ty != RustString && out. types . needs_indirect_abi ( ty) => write ! ( out, "$.value" ) ,
1097
1094
_ => { }
1098
1095
}
@@ -1155,10 +1152,19 @@ fn indirect_return(sig: &Signature, types: &Types) -> bool {
1155
1152
1156
1153
fn write_indirect_return_type ( out : & mut OutFile , ty : & Type ) {
1157
1154
match ty {
1158
- Type :: RustBox ( ty) | Type :: UniquePtr ( ty ) => {
1155
+ Type :: RustBox ( ty) => {
1159
1156
write_type_space ( out, & ty. inner ) ;
1160
1157
write ! ( out, "*" ) ;
1161
1158
}
1159
+ Type :: UniquePtr ( ty) => {
1160
+ write ! ( out, "::std::unique_ptr<" ) ;
1161
+ write_type ( out, & ty. first ) ;
1162
+ if let Some ( deleter) = & ty. second {
1163
+ write ! ( out, ", " ) ;
1164
+ write_type ( out, deleter) ;
1165
+ }
1166
+ write ! ( out, "> " ) ;
1167
+ }
1162
1168
Type :: Ref ( ty) => {
1163
1169
write_type_space ( out, & ty. inner ) ;
1164
1170
if !ty. mutable {
@@ -1181,7 +1187,7 @@ fn write_indirect_return_type_space(out: &mut OutFile, ty: &Type) {
1181
1187
1182
1188
fn write_extern_return_type_space ( out : & mut OutFile , ty : & Option < Type > ) {
1183
1189
match ty {
1184
- Some ( Type :: RustBox ( ty) | Type :: UniquePtr ( ty ) ) => {
1190
+ Some ( Type :: RustBox ( ty) ) => {
1185
1191
write_type_space ( out, & ty. inner ) ;
1186
1192
write ! ( out, "*" ) ;
1187
1193
}
@@ -1203,7 +1209,7 @@ fn write_extern_return_type_space(out: &mut OutFile, ty: &Option<Type>) {
1203
1209
1204
1210
fn write_extern_arg ( out : & mut OutFile , arg : & Var ) {
1205
1211
match & arg. ty {
1206
- Type :: RustBox ( ty) | Type :: UniquePtr ( ty ) | Type :: CxxVector ( ty) => {
1212
+ Type :: RustBox ( ty) | Type :: CxxVector ( ty) => {
1207
1213
write_type_space ( out, & ty. inner ) ;
1208
1214
write ! ( out, "*" ) ;
1209
1215
}
@@ -1237,7 +1243,11 @@ fn write_type(out: &mut OutFile, ty: &Type) {
1237
1243
}
1238
1244
Type :: UniquePtr ( ptr) => {
1239
1245
write ! ( out, "::std::unique_ptr<" ) ;
1240
- write_type ( out, & ptr. inner ) ;
1246
+ write_type ( out, & ptr. first ) ;
1247
+ if let Some ( deleter) = & ptr. second {
1248
+ write ! ( out, ", " ) ;
1249
+ write_type ( out, deleter) ;
1250
+ }
1241
1251
write ! ( out, ">" ) ;
1242
1252
}
1243
1253
Type :: SharedPtr ( ptr) => {
@@ -1350,7 +1360,7 @@ fn write_space_after_type(out: &mut OutFile, ty: &Type) {
1350
1360
1351
1361
#[ derive( Copy , Clone ) ]
1352
1362
enum UniquePtr < ' a > {
1353
- Ident ( & ' a Ident ) ,
1363
+ Ident ( & ' a Ident , Option < & ' a Ident > ) ,
1354
1364
CxxVector ( & ' a Ident ) ,
1355
1365
}
1356
1366
@@ -1367,7 +1377,7 @@ impl ToTypename for Ident {
1367
1377
impl < ' a > ToTypename for UniquePtr < ' a > {
1368
1378
fn to_typename ( & self , types : & Types ) -> String {
1369
1379
match self {
1370
- UniquePtr :: Ident ( ident) => ident. to_typename ( types) ,
1380
+ UniquePtr :: Ident ( ident, _ ) => ident. to_typename ( types) ,
1371
1381
UniquePtr :: CxxVector ( element) => {
1372
1382
format ! ( "::std::vector<{}>" , element. to_typename( types) )
1373
1383
}
@@ -1388,7 +1398,7 @@ impl ToMangled for Ident {
1388
1398
impl < ' a > ToMangled for UniquePtr < ' a > {
1389
1399
fn to_mangled ( & self , types : & Types ) -> Symbol {
1390
1400
match self {
1391
- UniquePtr :: Ident ( ident) => ident. to_mangled ( types) ,
1401
+ UniquePtr :: Ident ( ident, _ ) => ident. to_mangled ( types) ,
1392
1402
UniquePtr :: CxxVector ( element) => {
1393
1403
symbol:: join ( & [ & "std" , & "vector" , & element. to_mangled ( types) ] )
1394
1404
}
@@ -1409,7 +1419,7 @@ fn write_generic_instantiations(out: &mut OutFile) {
1409
1419
match * impl_key {
1410
1420
ImplKey :: RustBox ( ident) => write_rust_box_extern ( out, ident) ,
1411
1421
ImplKey :: RustVec ( ident) => write_rust_vec_extern ( out, ident) ,
1412
- ImplKey :: UniquePtr ( ident) => write_unique_ptr ( out, ident) ,
1422
+ ImplKey :: UniquePtr ( ident, deleter ) => write_unique_ptr ( out, ident, deleter ) ,
1413
1423
ImplKey :: SharedPtr ( ident) => write_shared_ptr ( out, ident) ,
1414
1424
ImplKey :: WeakPtr ( ident) => write_weak_ptr ( out, ident) ,
1415
1425
ImplKey :: CxxVector ( ident) => write_cxx_vector ( out, ident) ,
@@ -1621,8 +1631,8 @@ fn write_rust_vec_impl(out: &mut OutFile, key: NamedImplKey) {
1621
1631
writeln ! ( out, "}}" ) ;
1622
1632
}
1623
1633
1624
- fn write_unique_ptr ( out : & mut OutFile , key : NamedImplKey ) {
1625
- let ty = UniquePtr :: Ident ( key. rust ) ;
1634
+ fn write_unique_ptr ( out : & mut OutFile , key : NamedImplKey , deleter : Option < & Ident > ) {
1635
+ let ty = UniquePtr :: Ident ( key. rust , deleter ) ;
1626
1636
write_unique_ptr_common ( out, ty) ;
1627
1637
}
1628
1638
@@ -1632,18 +1642,34 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
1632
1642
out. include . utility = true ;
1633
1643
let inner = ty. to_typename ( out. types ) ;
1634
1644
let instance = ty. to_mangled ( out. types ) ;
1645
+ let ( cxx_type_string, mangled_prefix, deleter_name) =
1646
+ if let UniquePtr :: Ident ( _, Some ( deleter) ) = & ty {
1647
+ let deleter_instance = deleter. to_mangled ( out. types ) ;
1648
+ let deleter_inner = deleter. to_typename ( out. types ) ;
1649
+ (
1650
+ format ! ( "::std::unique_ptr<{}, {}>" , inner, & deleter_inner) ,
1651
+ format ! ( "cxxbridge1$unique_ptr${}${}$" , instance, deleter_instance) ,
1652
+ Some ( deleter_inner) ,
1653
+ )
1654
+ } else {
1655
+ (
1656
+ format ! ( "::std::unique_ptr<{}>" , inner) ,
1657
+ format ! ( "cxxbridge1$unique_ptr${}$" , instance) ,
1658
+ None ,
1659
+ )
1660
+ } ;
1635
1661
1636
1662
let can_construct_from_value = match ty {
1637
1663
// Some aliases are to opaque types; some are to trivial types. We can't
1638
1664
// know at code generation time, so we generate both C++ and Rust side
1639
1665
// bindings for a "new" method anyway. But the Rust code can't be called
1640
1666
// for Opaque types because the 'new' method is not implemented.
1641
- UniquePtr :: Ident ( ident) => out. types . is_maybe_trivial ( ident) ,
1667
+ UniquePtr :: Ident ( ident, _ ) => out. types . is_maybe_trivial ( ident) ,
1642
1668
UniquePtr :: CxxVector ( _) => false ,
1643
1669
} ;
1644
1670
1645
1671
let conditional_delete = match ty {
1646
- UniquePtr :: Ident ( ident) => {
1672
+ UniquePtr :: Ident ( ident, _ ) => {
1647
1673
!out. types . structs . contains_key ( ident) && !out. types . enums . contains_key ( ident)
1648
1674
}
1649
1675
UniquePtr :: CxxVector ( _) => false ,
@@ -1652,7 +1678,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
1652
1678
if conditional_delete {
1653
1679
out. builtin . is_complete = true ;
1654
1680
let definition = match ty {
1655
- UniquePtr :: Ident ( ty) => & out. types . resolve ( ty) . name . cxx ,
1681
+ UniquePtr :: Ident ( ty, _ ) => & out. types . resolve ( ty) . name . cxx ,
1656
1682
UniquePtr :: CxxVector ( _) => unreachable ! ( ) ,
1657
1683
} ;
1658
1684
writeln ! (
@@ -1661,22 +1687,36 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
1661
1687
inner, definition,
1662
1688
) ;
1663
1689
}
1664
- writeln ! (
1665
- out,
1666
- "static_assert(sizeof(::std::unique_ptr<{}>) == sizeof(void *), \" \" );" ,
1667
- inner,
1668
- ) ;
1669
- writeln ! (
1670
- out,
1671
- "static_assert(alignof(::std::unique_ptr<{}>) == alignof(void *), \" \" );" ,
1672
- inner,
1673
- ) ;
1690
+ if let Some ( deleter_name) = & deleter_name {
1691
+ writeln ! (
1692
+ out,
1693
+ "static_assert(sizeof(::std::unique_ptr<{inner}, {deleter_name}>) >= (sizeof(void *) + \
1694
+ sizeof({deleter_name})), \" Implausible size of unique_ptr with deleter {deleter_name}\" );",
1695
+ ) ;
1696
+ out. include . type_traits = true ;
1697
+ writeln ! (
1698
+ out,
1699
+ "static_assert(std::is_trivially_move_constructible<{deleter_name}>::value && std::is_trivially_destructible<{deleter_name}>::value, \
1700
+ \" Only trivial types are supported as deleter for unique_ptr\" );",
1701
+ )
1702
+ } else {
1703
+ writeln ! (
1704
+ out,
1705
+ "static_assert(sizeof(::std::unique_ptr<{}>) == sizeof(void *), \" \" );" ,
1706
+ inner,
1707
+ ) ;
1708
+ writeln ! (
1709
+ out,
1710
+ "static_assert(alignof(::std::unique_ptr<{}>) == alignof(void *), \" \" );" ,
1711
+ inner,
1712
+ ) ;
1713
+ }
1674
1714
1675
1715
begin_function_definition ( out) ;
1676
1716
writeln ! (
1677
1717
out,
1678
- "void cxxbridge1$unique_ptr${}$ null(::std::unique_ptr<{}> *ptr) noexcept {{" ,
1679
- instance , inner,
1718
+ "void {} null(::std::unique_ptr<{}> *ptr) noexcept {{" ,
1719
+ mangled_prefix , inner,
1680
1720
) ;
1681
1721
writeln ! ( out, " ::new (ptr) ::std::unique_ptr<{}>();" , inner) ;
1682
1722
writeln ! ( out, "}}" ) ;
@@ -1686,8 +1726,8 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
1686
1726
begin_function_definition ( out) ;
1687
1727
writeln ! (
1688
1728
out,
1689
- "{} *cxxbridge1$unique_ptr${}$ uninit(::std::unique_ptr<{}> *ptr) noexcept {{" ,
1690
- inner, instance , inner,
1729
+ "{} *{} uninit(::std::unique_ptr<{}> *ptr) noexcept {{" ,
1730
+ inner, mangled_prefix , inner,
1691
1731
) ;
1692
1732
writeln ! (
1693
1733
out,
@@ -1702,36 +1742,41 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
1702
1742
begin_function_definition ( out) ;
1703
1743
writeln ! (
1704
1744
out,
1705
- "void cxxbridge1$unique_ptr${}$ raw(::std::unique_ptr<{}> *ptr, {} *raw) noexcept {{" ,
1706
- instance , inner, inner,
1745
+ "void {} raw(::std::unique_ptr<{}> *ptr, {} *raw) noexcept {{" ,
1746
+ mangled_prefix , inner, inner,
1707
1747
) ;
1708
1748
writeln ! ( out, " ::new (ptr) ::std::unique_ptr<{}>(raw);" , inner) ;
1709
1749
writeln ! ( out, "}}" ) ;
1710
1750
1711
1751
begin_function_definition ( out) ;
1712
1752
writeln ! (
1713
1753
out,
1714
- "{} const *cxxbridge1$unique_ptr${}$ get(::std::unique_ptr<{}> const &ptr) noexcept {{" ,
1715
- inner, instance , inner,
1754
+ "{} const *{} get(::std::unique_ptr<{}> const &ptr) noexcept {{" ,
1755
+ inner, mangled_prefix , inner,
1716
1756
) ;
1717
1757
writeln ! ( out, " return ptr.get();" ) ;
1718
1758
writeln ! ( out, "}}" ) ;
1719
1759
1720
1760
begin_function_definition ( out) ;
1721
1761
writeln ! (
1722
1762
out,
1723
- "{} *cxxbridge1$unique_ptr${}$ release(::std::unique_ptr<{}> &ptr) noexcept {{" ,
1724
- inner, instance , inner,
1763
+ "{} *{} release(::std::unique_ptr<{}> &ptr) noexcept {{" ,
1764
+ inner, mangled_prefix , inner,
1725
1765
) ;
1726
1766
writeln ! ( out, " return ptr.release();" ) ;
1727
1767
writeln ! ( out, "}}" ) ;
1728
1768
1729
1769
begin_function_definition ( out) ;
1730
1770
writeln ! (
1731
1771
out,
1732
- "void cxxbridge1$unique_ptr${}$ drop(::std::unique_ptr<{}> *ptr) noexcept {{" ,
1733
- instance , inner ,
1772
+ "void {} drop({} *ptr) noexcept {{" ,
1773
+ mangled_prefix , & cxx_type_string ,
1734
1774
) ;
1775
+ if deleter_name. is_some ( ) {
1776
+ // Check whether the deleter is really the first member as expected by the Rust type
1777
+ out. include . cassert = true ;
1778
+ writeln ! ( out, " assert(reinterpret_cast<void*>(&ptr->get_deleter()) == reinterpret_cast<void*>(ptr));" ) ;
1779
+ }
1735
1780
if conditional_delete {
1736
1781
out. builtin . deleter_if = true ;
1737
1782
writeln ! (
0 commit comments