@@ -43,6 +43,14 @@ use crate::c_types::*;
43
43
use alloc::{vec::Vec, boxed::Box};
44
44
" ;
45
45
46
+
47
+ /// str.rsplit_once but with an older MSRV
48
+ fn rsplit_once < ' a > ( inp : & ' a str , pattern : & str ) -> Option < ( & ' a str , & ' a str ) > {
49
+ let mut iter = inp. rsplitn ( 2 , pattern) ;
50
+ let second_entry = iter. next ( ) . unwrap ( ) ;
51
+ Some ( ( iter. next ( ) . unwrap ( ) , second_entry) )
52
+ }
53
+
46
54
// *************************************
47
55
// *** Manually-expanded conversions ***
48
56
// *************************************
@@ -54,11 +62,10 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
54
62
let full_obj_path;
55
63
let mut has_inner = false ;
56
64
if let syn:: Type :: Path ( ref p) = for_ty {
57
- if let Some ( ident) = single_ident_generic_path_to_ident ( & p. path ) {
58
- for_obj = format ! ( "{}" , ident) ;
59
- full_obj_path = for_obj. clone ( ) ;
60
- has_inner = types. c_type_has_inner_from_path ( & types. resolve_path ( & p. path , Some ( generics) ) ) ;
61
- } else { return ; }
65
+ let resolved_path = types. resolve_path ( & p. path , Some ( generics) ) ;
66
+ for_obj = format ! ( "{}" , p. path. segments. last( ) . unwrap( ) . ident) ;
67
+ full_obj_path = format ! ( "crate::{}" , resolved_path) ;
68
+ has_inner = types. c_type_has_inner_from_path ( & resolved_path) ;
62
69
} else {
63
70
// We assume that anything that isn't a Path is somehow a generic that ends up in our
64
71
// derived-types module.
@@ -872,8 +879,12 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
872
879
}
873
880
if let & syn:: Type :: Path ( ref p) = & * i. self_ty {
874
881
if p. qself . is_some ( ) { unimplemented ! ( ) ; }
875
- if let Some ( ident) = single_ident_generic_path_to_ident ( & p. path ) {
876
- if let Some ( resolved_path) = types. maybe_resolve_non_ignored_ident ( & ident) {
882
+ let ident = & p. path . segments . last ( ) . unwrap ( ) . ident ;
883
+ if let Some ( resolved_path) = types. maybe_resolve_path ( & p. path , None ) {
884
+ if types. crate_types . opaques . contains_key ( & resolved_path) || types. crate_types . mirrored_enums . contains_key ( & resolved_path) ||
885
+ // At least for core::infallible::Infallible we need to support mapping an
886
+ // out-of-crate trait implementation.
887
+ ( types. understood_c_path ( & p. path ) && first_seg_is_stdlib ( resolved_path. split ( "::" ) . next ( ) . unwrap ( ) ) ) {
877
888
if !types. understood_c_path ( & p. path ) {
878
889
eprintln ! ( "Not implementing anything for impl {} as the type is not understood (probably C-not exported)" , ident) ;
879
890
return ;
@@ -1300,7 +1311,8 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
1300
1311
maybe_convert_trait_impl ( w, & trait_path. 1 , & * i. self_ty , types, & gen_types) ;
1301
1312
}
1302
1313
} else {
1303
- let declared_type = ( * types. get_declared_type ( & ident) . unwrap ( ) ) . clone ( ) ;
1314
+ let is_opaque = types. crate_types . opaques . contains_key ( & resolved_path) ;
1315
+ let is_mirrored_enum = types. crate_types . mirrored_enums . contains_key ( & resolved_path) ;
1304
1316
for item in i. items . iter ( ) {
1305
1317
match item {
1306
1318
syn:: ImplItem :: Method ( m) => {
@@ -1318,11 +1330,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
1318
1330
writeln ! ( w, "#[must_use]" ) . unwrap ( ) ;
1319
1331
}
1320
1332
write ! ( w, "#[no_mangle]\n pub extern \" C\" fn {}_{}(" , ident, m. sig. ident) . unwrap ( ) ;
1321
- let ret_type = match & declared_type {
1322
- DeclType :: MirroredEnum => format ! ( "{}" , ident) ,
1323
- DeclType :: StructImported { ..} => format ! ( "{}" , ident) ,
1324
- _ => unimplemented ! ( ) ,
1325
- } ;
1333
+ let ret_type = format ! ( "crate::{}" , resolved_path) ;
1326
1334
write_method_params ( w, & m. sig , & ret_type, types, Some ( & meth_gen_types) , false , true ) ;
1327
1335
write ! ( w, " {{\n \t " ) . unwrap ( ) ;
1328
1336
write_method_var_decl_body ( w, & m. sig , "" , types, Some ( & meth_gen_types) , false ) ;
@@ -1339,18 +1347,18 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
1339
1347
if !takes_mut_self && !takes_self {
1340
1348
write ! ( w, "{}::{}(" , resolved_path, m. sig. ident) . unwrap ( ) ;
1341
1349
} else {
1342
- match & declared_type {
1343
- DeclType :: MirroredEnum => write ! ( w, "this_arg.to_native().{}(" , m. sig. ident) . unwrap ( ) ,
1344
- DeclType :: StructImported { .. } => {
1345
- if takes_owned_self {
1346
- write ! ( w, "(*unsafe {{ Box::from_raw(this_arg.take_inner()) }}).{}(" , m. sig. ident) . unwrap ( ) ;
1347
- } else if takes_mut_self {
1348
- write ! ( w, "unsafe {{ &mut (*ObjOps::untweak_ptr(this_arg.inner as *mut native{})) }}.{}(" , ident, m. sig. ident) . unwrap ( ) ;
1349
- } else {
1350
- write ! ( w, "unsafe {{ &*ObjOps::untweak_ptr(this_arg.inner) }}.{}(" , m. sig. ident) . unwrap ( ) ;
1351
- }
1352
- } ,
1353
- _ => unimplemented ! ( ) ,
1350
+ if is_mirrored_enum {
1351
+ write ! ( w, "this_arg.to_native().{}(" , m. sig. ident) . unwrap ( ) ;
1352
+ } else if is_opaque {
1353
+ if takes_owned_self {
1354
+ write ! ( w, "(*unsafe {{ Box::from_raw(this_arg.take_inner()) }}).{}(" , m. sig. ident) . unwrap ( ) ;
1355
+ } else if takes_mut_self {
1356
+ write ! ( w, "unsafe {{ &mut (*ObjOps::untweak_ptr(this_arg.inner as *mut crate::{}:: native{})) }}.{}(" , rsplit_once ( & resolved_path , "::" ) . unwrap ( ) . 0 , ident, m. sig. ident) . unwrap ( ) ;
1357
+ } else {
1358
+ write ! ( w, "unsafe {{ &*ObjOps::untweak_ptr(this_arg.inner) }}.{}(" , m. sig. ident) . unwrap ( ) ;
1359
+ }
1360
+ } else {
1361
+ unimplemented ! ( ) ;
1354
1362
}
1355
1363
}
1356
1364
write_method_call_params ( w, & m. sig , "" , types, Some ( & meth_gen_types) , & ret_type, false ) ;
@@ -1367,11 +1375,18 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
1367
1375
if !gen_types. as_mut ( ) . unwrap ( ) . learn_generics ( & i. generics , types) {
1368
1376
gen_types = None ;
1369
1377
}
1370
- ' alias_impls: for ( alias, arguments) in aliases {
1378
+ let alias_module = rsplit_once ( & resolved_path, "::" ) . unwrap ( ) . 0 ;
1379
+
1380
+ ' alias_impls: for ( alias_resolved, arguments) in aliases {
1371
1381
let mut new_ty_generics = Vec :: new ( ) ;
1372
1382
let mut need_generics = false ;
1373
1383
1374
- let alias_resolved = types. resolve_path ( & alias, None ) ;
1384
+ let alias_resolver_override;
1385
+ let alias_resolver = if alias_module != types. module_path {
1386
+ alias_resolver_override = ImportResolver :: new ( types. types . crate_name , & types. crate_types . lib_ast . dependencies ,
1387
+ alias_module, & types. crate_types . lib_ast . modules . get ( alias_module) . unwrap ( ) . items ) ;
1388
+ & alias_resolver_override
1389
+ } else { & types. types } ; /*.maybe_resolve_path(&alias, None).unwrap();*/
1375
1390
for ( idx, gen) in i. generics . params . iter ( ) . enumerate ( ) {
1376
1391
match gen {
1377
1392
syn:: GenericParam :: Type ( type_param) => {
@@ -1380,10 +1395,11 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
1380
1395
if let syn:: PathArguments :: AngleBracketed ( ref t) = & arguments {
1381
1396
assert ! ( idx < t. args. len( ) ) ;
1382
1397
if let syn:: GenericArgument :: Type ( syn:: Type :: Path ( p) ) = & t. args [ idx] {
1383
- if let Some ( generic_arg) = types . maybe_resolve_path ( & p. path , None ) {
1398
+ if let Some ( generic_arg) = alias_resolver . maybe_resolve_path ( & p. path , None ) {
1384
1399
1385
1400
new_ty_generics. push ( ( type_param. ident . clone ( ) , syn:: Type :: Path ( p. clone ( ) ) ) ) ;
1386
- let generic_bound = types. resolve_path ( & trait_bound. path , None ) ;
1401
+ let generic_bound = types. maybe_resolve_path ( & trait_bound. path , None )
1402
+ . unwrap_or_else ( || format ! ( "{}::{}" , types. module_path, single_ident_generic_path_to_ident( & trait_bound. path) . unwrap( ) ) ) ;
1387
1403
if let Some ( traits_impld) = types. crate_types . trait_impls . get ( & generic_arg) {
1388
1404
for trait_impld in traits_impld {
1389
1405
if * trait_impld == generic_bound { continue ' bounds_check; }
@@ -1411,6 +1427,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
1411
1427
}
1412
1428
}
1413
1429
let mut params = syn:: punctuated:: Punctuated :: new ( ) ;
1430
+ let alias = string_path_to_syn_path ( & alias_resolved) ;
1414
1431
let real_aliased =
1415
1432
if need_generics {
1416
1433
let alias_generics = types. crate_types . opaques . get ( & alias_resolved) . unwrap ( ) . 1 ;
@@ -1776,11 +1793,7 @@ fn convert_priv_mod<'a, 'b: 'a, W: std::io::Write>(w: &mut W, libast: &'b FullLi
1776
1793
match item {
1777
1794
syn:: Item :: Mod ( m) => convert_priv_mod ( w, libast, crate_types, out_dir, & format ! ( "{}::{}" , mod_path, module. ident) , m) ,
1778
1795
syn:: Item :: Impl ( i) => {
1779
- if let & syn:: Type :: Path ( ref p) = & * i. self_ty {
1780
- if p. path . get_ident ( ) . is_some ( ) {
1781
- writeln_impl ( w, i, & mut types) ;
1782
- }
1783
- }
1796
+ writeln_impl ( w, i, & mut types) ;
1784
1797
} ,
1785
1798
_ => { } ,
1786
1799
}
@@ -2022,17 +2035,14 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a
2022
2035
let type_path = format ! ( "{}::{}" , module, t. ident) ;
2023
2036
match & * t. ty {
2024
2037
syn:: Type :: Path ( p) => {
2025
- let t_ident = & t. ident ;
2026
-
2027
2038
// If its a path with no generics, assume we don't map the aliased type and map it opaque
2028
- let path_obj = parse_quote ! ( #t_ident) ;
2029
2039
let args_obj = p. path . segments . last ( ) . unwrap ( ) . arguments . clone ( ) ;
2030
2040
match crate_types. reverse_alias_map . entry ( import_resolver. maybe_resolve_path ( & p. path , None ) . unwrap ( ) ) {
2031
- hash_map:: Entry :: Occupied ( mut e) => { e. get_mut ( ) . push ( ( path_obj , args_obj) ) ; } ,
2032
- hash_map:: Entry :: Vacant ( e) => { e. insert ( vec ! [ ( path_obj , args_obj) ] ) ; } ,
2041
+ hash_map:: Entry :: Occupied ( mut e) => { e. get_mut ( ) . push ( ( type_path . clone ( ) , args_obj) ) ; } ,
2042
+ hash_map:: Entry :: Vacant ( e) => { e. insert ( vec ! [ ( type_path . clone ( ) , args_obj) ] ) ; } ,
2033
2043
}
2034
2044
2035
- crate_types. opaques . insert ( type_path, ( t_ident , & t. generics ) ) ;
2045
+ crate_types. opaques . insert ( type_path, ( & t . ident , & t. generics ) ) ;
2036
2046
} ,
2037
2047
_ => {
2038
2048
crate_types. type_aliases . insert ( type_path, import_resolver. resolve_imported_refs ( ( * t. ty ) . clone ( ) ) ) ;
0 commit comments