Skip to content

Commit 425ed88

Browse files
committed
[bindings] Push generic resolution into resolve_path
Like the previous commit pushing into maybe_resolve_path, this makes generic resolution a part of type resolution everywhere.
1 parent fe6b239 commit 425ed88

File tree

2 files changed

+33
-62
lines changed

2 files changed

+33
-62
lines changed

c-bindings-gen/src/main.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ macro_rules! walk_supertraits { ($t: expr, $types: expr, ($( $pat: pat => $e: ex
9797
$( $pat => $e, )*
9898
}
9999
} else {
100-
let path = $types.resolve_path(&supertrait.path);
100+
let path = $types.resolve_path(&supertrait.path, None);
101101
match (&path as &str, &supertrait.path.segments.iter().last().unwrap().ident) {
102102
$( $pat => $e, )*
103103
}
@@ -357,7 +357,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
357357
let mut bounds_iter = t.bounds.iter();
358358
match bounds_iter.next().unwrap() {
359359
syn::TypeParamBound::Trait(tr) => {
360-
writeln!(w, "\ttype {} = crate::{};", t.ident, types.resolve_path(&tr.path)).unwrap();
360+
writeln!(w, "\ttype {} = crate::{};", t.ident, types.resolve_path(&tr.path, None)).unwrap();
361361
},
362362
_ => unimplemented!(),
363363
}
@@ -579,7 +579,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
579579
if let Some(trait_path) = i.trait_.as_ref() {
580580
if trait_path.0.is_some() { unimplemented!(); }
581581
if types.understood_c_path(&trait_path.1) {
582-
let full_trait_path = types.resolve_path(&trait_path.1);
582+
let full_trait_path = types.resolve_path(&trait_path.1, None);
583583
let trait_obj = *types.crate_types.traits.get(&full_trait_path).unwrap();
584584
// We learn the associated types maping from the original trait object.
585585
// That's great, except that they are unresolved idents, so if we learn
@@ -1125,7 +1125,7 @@ fn convert_file<'a, 'b>(libast: &'a FullLibraryAST, crate_types: &mut CrateTypes
11251125
// Re-export any primitive-type constants.
11261126
if let syn::Visibility::Public(_) = c.vis {
11271127
if let syn::Type::Path(p) = &*c.ty {
1128-
let resolved_path = type_resolver.resolve_path(&p.path);
1128+
let resolved_path = type_resolver.resolve_path(&p.path, None);
11291129
if type_resolver.is_primitive(&resolved_path) {
11301130
writeln!(out, "\n#[no_mangle]").unwrap();
11311131
writeln!(out, "pub static {}: {} = {}::{}::{};", c.ident, resolved_path, orig_crate, module, c.ident).unwrap();

c-bindings-gen/src/types.rs

Lines changed: 29 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl<'a> GenericTypes<'a> {
177177
if non_lifetimes_processed { return false; }
178178
non_lifetimes_processed = true;
179179
assert_simple_bound(&trait_bound);
180-
*gen = ("crate::".to_string() + &types.resolve_path(&trait_bound.path),
180+
*gen = ("crate::".to_string() + &types.resolve_path(&trait_bound.path, None),
181181
Some(&trait_bound.path));
182182
}
183183
}
@@ -700,7 +700,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
700700
},
701701
"Option" => {
702702
if let Some(syn::Type::Path(p)) = single_contained {
703-
if self.c_type_has_inner_from_path(&self.resolve_path(&p.path)) {
703+
if self.c_type_has_inner_from_path(&self.resolve_path(&p.path, None)) {
704704
if is_ref {
705705
return Some(("if ", vec![
706706
(".is_none() { std::ptr::null() } else { ".to_owned(), format!("({}.as_ref().unwrap())", var_access))
@@ -746,7 +746,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
746746
},
747747
"Option" => {
748748
if let Some(syn::Type::Path(p)) = single_contained {
749-
if self.c_type_has_inner_from_path(&self.resolve_path(&p.path)) {
749+
if self.c_type_has_inner_from_path(&self.resolve_path(&p.path, None)) {
750750
if is_ref {
751751
return Some(("if ", vec![(".inner.is_null() { None } else { Some((*".to_string(), format!("{}", var_name))], ").clone()) }"))
752752
} else {
@@ -903,8 +903,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
903903
} else { None }
904904
}
905905
}
906-
pub fn resolve_path(&self, p: &syn::Path) -> String {
907-
self.maybe_resolve_path(p, None).unwrap()
906+
pub fn resolve_path(&self, p: &syn::Path, generics: Option<&GenericTypes>) -> String {
907+
self.maybe_resolve_path(p, generics).unwrap()
908908
}
909909

910910
// ***********************************
@@ -1026,7 +1026,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
10261026
pub fn write_empty_rust_val<W: std::io::Write>(&self, w: &mut W, t: &syn::Type) {
10271027
match t {
10281028
syn::Type::Path(p) => {
1029-
let resolved = self.resolve_path(&p.path);
1029+
let resolved = self.resolve_path(&p.path, None);
10301030
if self.crate_types.opaques.get(&resolved).is_some() {
10311031
write!(w, "crate::{} {{ inner: std::ptr::null_mut(), is_owned: true }}", resolved).unwrap();
10321032
} else {
@@ -1059,7 +1059,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
10591059
pub fn write_empty_rust_val_check_suffix<W: std::io::Write>(&self, w: &mut W, t: &syn::Type) -> bool {
10601060
match t {
10611061
syn::Type::Path(p) => {
1062-
let resolved = self.resolve_path(&p.path);
1062+
let resolved = self.resolve_path(&p.path, None);
10631063
if self.crate_types.opaques.get(&resolved).is_some() {
10641064
write!(w, ".inner.is_null()").unwrap();
10651065
false
@@ -1164,38 +1164,18 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
11641164
unimplemented!();
11651165
}
11661166

1167-
if let Some(gen_types) = generics {
1168-
if let Some((_, synpath)) = gen_types.maybe_resolve_path(&p.path) {
1169-
let genpath = self.resolve_path(&synpath);
1170-
assert!(!self.is_known_container(&genpath, is_ref) && !self.is_transparent_container(&genpath, is_ref));
1171-
if let Some(c_type) = path_lookup(&genpath, is_ref, ptr_for_ref) {
1172-
write!(w, "{}", c_type).unwrap();
1173-
return;
1174-
} else {
1175-
let synident = single_ident_generic_path_to_ident(synpath).unwrap();
1176-
if let Some(t) = self.crate_types.traits.get(&genpath) {
1177-
decl_lookup(w, &DeclType::Trait(t), &genpath, is_ref, is_mut);
1178-
return;
1179-
} else if let Some(_) = self.imports.get(synident) {
1180-
// crate_types lookup has to have succeeded:
1181-
panic!("Failed to print inline conversion for {}", synident);
1182-
} else if let Some(decl_type) = self.declared.get(synident) {
1183-
decl_lookup(w, decl_type, &self.maybe_resolve_path(synpath, None).unwrap(), is_ref, is_mut);
1184-
return;
1185-
} else { unimplemented!(); }
1186-
}
1187-
}
1188-
}
1189-
1190-
let resolved_path = self.resolve_path(&p.path);
1167+
let resolved_path = self.resolve_path(&p.path, generics);
11911168
if let Some(c_type) = path_lookup(&resolved_path, is_ref, ptr_for_ref) {
11921169
write!(w, "{}", c_type).unwrap();
11931170
} else if self.crate_types.opaques.get(&resolved_path).is_some() {
11941171
decl_lookup(w, &DeclType::StructImported, &resolved_path, is_ref, is_mut);
11951172
} else if self.crate_types.mirrored_enums.get(&resolved_path).is_some() {
11961173
decl_lookup(w, &DeclType::MirroredEnum, &resolved_path, is_ref, is_mut);
11971174
} else if let Some(ident) = single_ident_generic_path_to_ident(&p.path) {
1198-
if let Some(_) = self.imports.get(ident) {
1175+
if let Some(t) = self.crate_types.traits.get(&resolved_path) {
1176+
decl_lookup(w, &DeclType::Trait(t), &resolved_path, is_ref, is_mut);
1177+
return;
1178+
} else if let Some(_) = self.imports.get(ident) {
11991179
// crate_types lookup has to have succeeded:
12001180
panic!("Failed to print inline conversion for {}", ident);
12011181
} else if let Some(decl_type) = self.declared.get(ident) {
@@ -1216,12 +1196,12 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
12161196
// We assume all slices contain only literals or references.
12171197
// This may result in some outputs not compiling.
12181198
if let syn::Type::Path(p) = &*s.elem {
1219-
let resolved = self.resolve_path(&p.path);
1199+
let resolved = self.resolve_path(&p.path, generics);
12201200
assert!(self.is_primitive(&resolved));
12211201
write!(w, "{}", path_lookup("[u8]", is_ref, ptr_for_ref).unwrap()).unwrap();
12221202
} else if let syn::Type::Reference(r) = &*s.elem {
12231203
if let syn::Type::Path(p) = &*r.elem {
1224-
write!(w, "{}", sliceconv(self.c_type_has_inner_from_path(&self.resolve_path(&p.path)))).unwrap();
1204+
write!(w, "{}", sliceconv(self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics)))).unwrap();
12251205
} else { unimplemented!(); }
12261206
} else { unimplemented!(); }
12271207
},
@@ -1374,10 +1354,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
13741354
}
13751355
if let syn::Type::Reference(t) = ty {
13761356
if let syn::Type::Path(p) = &*t.elem {
1377-
self.c_type_has_inner_from_path(&self.resolve_path(&p.path))
1357+
self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics))
13781358
} else { false }
13791359
} else if let syn::Type::Path(p) = ty {
1380-
self.c_type_has_inner_from_path(&self.resolve_path(&p.path))
1360+
self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics))
13811361
} else { false }
13821362
} else { true };
13831363

@@ -1469,16 +1449,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
14691449
if p.qself.is_some() || p.path.leading_colon.is_some() {
14701450
unimplemented!();
14711451
}
1472-
if let Some(gen_types) = generics {
1473-
if let Some(resolved) = gen_types.maybe_resolve_path(&p.path) {
1474-
assert!(!self.is_known_container(&resolved.0, is_ref) && !self.is_transparent_container(&resolved.0, is_ref));
1475-
if let Some((prefix, suffix)) = path_lookup(&resolved.0, is_ref) {
1476-
write!(w, "let mut local_{} = {}{}{};", ident, prefix, var, suffix).unwrap();
1477-
return true;
1478-
} else { return false; }
1479-
}
1480-
}
1481-
let resolved_path = self.resolve_path(&p.path);
1452+
let resolved_path = self.resolve_path(&p.path, generics);
14821453
if self.is_known_container(&resolved_path, is_ref) || self.is_transparent_container(&resolved_path, is_ref) {
14831454
if let syn::PathArguments::AngleBracketed(args) = &p.path.segments.iter().next().unwrap().arguments {
14841455
convert_container!(resolved_path, args.args.len(), || args.args.iter().map(|arg| {
@@ -1506,7 +1477,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
15061477
},
15071478
syn::Type::Slice(s) => {
15081479
if let syn::Type::Path(p) = &*s.elem {
1509-
let resolved = self.resolve_path(&p.path);
1480+
let resolved = self.resolve_path(&p.path, generics);
15101481
assert!(self.is_primitive(&resolved));
15111482
let slice_path = format!("[{}]", resolved);
15121483
if let Some((prefix, suffix)) = path_lookup(&slice_path, true) {
@@ -1543,7 +1514,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
15431514
// Opaque types with inner pointers shouldn't ever create new stack
15441515
// variables, so we don't handle it and just assert that it doesn't
15451516
// here.
1546-
assert!(!self.c_type_has_inner_from_path(&self.resolve_path(&p.path)));
1517+
assert!(!self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics)));
15471518
}
15481519
}
15491520
}
@@ -1558,10 +1529,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
15581529
}
15591530
if let syn::Type::Reference(t) = elem {
15601531
if let syn::Type::Path(p) = &*t.elem {
1561-
self.c_type_has_inner_from_path(&self.resolve_path(&p.path))
1532+
self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics))
15621533
} else { false }
15631534
} else if let syn::Type::Path(p) = elem {
1564-
self.c_type_has_inner_from_path(&self.resolve_path(&p.path))
1535+
self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics))
15651536
} else { false }
15661537
};
15671538
if idx != 0 { write!(w, ", ").unwrap(); }
@@ -1624,7 +1595,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
16241595
($call: expr, $item: expr) => { {
16251596
write!(w, "#[no_mangle]\npub static {}_{}: extern \"C\" fn (", mangled_container, $call).unwrap();
16261597
if let syn::Type::Path(syn::TypePath { path, .. }) = $item {
1627-
let resolved = self.resolve_path(path);
1598+
let resolved = self.resolve_path(path, generics);
16281599
if self.is_known_container(&resolved, is_ref) || self.is_transparent_container(&resolved, is_ref) {
16291600
self.write_c_mangled_container_path_intern(generics, w, Self::path_to_generic_args(path),
16301601
&format!("{}", single_ident_generic_path_to_ident(path).unwrap()), is_ref, false, false, false);
@@ -1679,7 +1650,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
16791650
write!(w, ">").unwrap();
16801651
}
16811652
} else if let syn::Type::Path(p_arg) = t {
1682-
let resolved_generic = self.resolve_path(&p_arg.path);
1653+
let resolved_generic = self.resolve_path(&p_arg.path, None);
16831654
if self.is_primitive(&resolved_generic) {
16841655
write!(w, "{}", resolved_generic).unwrap();
16851656
} else if let Some(c_type) = self.c_type_from_path(&resolved_generic, is_ref, false) {
@@ -1721,7 +1692,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
17211692
}
17221693
} else if let syn::Type::Reference(r_arg) = t {
17231694
if let syn::Type::Path(p_arg) = &*r_arg.elem {
1724-
let resolved = self.resolve_path(&p_arg.path);
1695+
let resolved = self.resolve_path(&p_arg.path, None);
17251696
if single_ident_generic_path_to_ident(&p_arg.path).is_some() {
17261697
if self.crate_types.opaques.get(&resolved).is_some() {
17271698
write!(w, "crate::{}", resolved).unwrap();
@@ -1730,7 +1701,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
17301701
} else { unimplemented!(); }
17311702
} else if let syn::Type::Array(a_arg) = t {
17321703
if let syn::Type::Path(p_arg) = &*a_arg.elem {
1733-
let resolved = self.resolve_path(&p_arg.path);
1704+
let resolved = self.resolve_path(&p_arg.path, None);
17341705
assert!(self.is_primitive(&resolved));
17351706
if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(len), .. }) = &a_arg.len {
17361707
write!(w, "{}",
@@ -1775,7 +1746,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
17751746
for arg in args.iter() {
17761747
macro_rules! write_path {
17771748
($p_arg: expr, $extra_write: expr) => {
1778-
let subtype = self.resolve_path(&$p_arg.path);
1749+
let subtype = self.resolve_path(&$p_arg.path, generics);
17791750
if self.is_transparent_container(ident, is_ref) {
17801751
// We dont (yet) support primitives or containers inside transparent
17811752
// containers, so check for that first:
@@ -1855,7 +1826,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
18551826
} else { return false; }
18561827
} else if let syn::Type::Array(a) = arg {
18571828
if let syn::Type::Path(p_arg) = &*a.elem {
1858-
let resolved = self.resolve_path(&p_arg.path);
1829+
let resolved = self.resolve_path(&p_arg.path, generics);
18591830
if !self.is_primitive(&resolved) { return false; }
18601831
if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(len), .. }) = &a.len {
18611832
if self.c_type_from_path(&format!("[{}; {}]", resolved, len.base10_digits()), is_ref, ptr_for_ref).is_none() { return false; }
@@ -1966,15 +1937,15 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
19661937
syn::Type::Slice(s) => {
19671938
if !is_ref || is_mut { return false; }
19681939
if let syn::Type::Path(p) = &*s.elem {
1969-
let resolved = self.resolve_path(&p.path);
1940+
let resolved = self.resolve_path(&p.path, generics);
19701941
if self.is_primitive(&resolved) {
19711942
write!(w, "{}::{}slice", Self::container_templ_path(), resolved).unwrap();
19721943
true
19731944
} else { false }
19741945
} else if let syn::Type::Reference(r) = &*s.elem {
19751946
if let syn::Type::Path(p) = &*r.elem {
19761947
// Slices with "real types" inside are mapped as the equivalent non-ref Vec
1977-
let resolved = self.resolve_path(&p.path);
1948+
let resolved = self.resolve_path(&p.path, generics);
19781949
let mangled_container = if let Some(ident) = self.crate_types.opaques.get(&resolved) {
19791950
format!("CVec_{}Z", ident)
19801951
} else if let Some(en) = self.crate_types.mirrored_enums.get(&resolved) {

0 commit comments

Comments
 (0)