Skip to content

Commit 4c4673e

Browse files
committed
[bindings] Push generic resolution into maybe_resolve_path
This pushes down the logic to check if a given Path is, in fact, a reference to a generic into the common maybe_resolve_path instead of doing it redundantly in a few different places. Net loss of LoC.
1 parent 44f804b commit 4c4673e

File tree

2 files changed

+45
-58
lines changed

2 files changed

+45
-58
lines changed

c-bindings-gen/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ fn convert_macro<W: std::io::Write>(w: &mut W, macro_path: &syn::Path, stream: &
5656

5757
/// Convert "impl trait_path for for_obj { .. }" for manually-mapped types (ie (de)serialization)
5858
fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path, for_obj: &syn::Ident, types: &TypeResolver) {
59-
if let Some(t) = types.maybe_resolve_path(&trait_path) {
59+
if let Some(t) = types.maybe_resolve_path(&trait_path, None) {
6060
let s = types.maybe_resolve_ident(for_obj).unwrap();
6161
if !types.crate_types.opaques.get(&s).is_some() { return; }
6262
match &t as &str {

c-bindings-gen/src/types.rs

Lines changed: 44 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl<'a> GenericTypes<'a> {
144144
}
145145

146146
assert_simple_bound(&trait_bound);
147-
if let Some(mut path) = types.maybe_resolve_path(&trait_bound.path) {
147+
if let Some(mut path) = types.maybe_resolve_path(&trait_bound.path, None) {
148148
if types.skip_path(&path) { continue; }
149149
if non_lifetimes_processed { return false; }
150150
non_lifetimes_processed = true;
@@ -868,7 +868,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
868868
} else { None }
869869
}
870870

871-
pub fn maybe_resolve_path(&self, p: &syn::Path) -> Option<String> {
871+
pub fn maybe_resolve_path(&self, p_arg: &syn::Path, generics: Option<&GenericTypes>) -> Option<String> {
872+
let p = if let Some(gen_types) = generics {
873+
if let Some((_, synpath)) = gen_types.maybe_resolve_path(p_arg) {
874+
synpath
875+
} else { p_arg }
876+
} else { p_arg };
877+
872878
if p.leading_colon.is_some() {
873879
// At some point we may need this, but for now, its unused, so just fail.
874880
return None;
@@ -898,15 +904,15 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
898904
}
899905
}
900906
pub fn resolve_path(&self, p: &syn::Path) -> String {
901-
self.maybe_resolve_path(p).unwrap()
907+
self.maybe_resolve_path(p, None).unwrap()
902908
}
903909

904910
// ***********************************
905911
// *** Original Rust Type Printing ***
906912
// ***********************************
907913

908914
fn write_rust_path<W: std::io::Write>(&self, w: &mut W, path: &syn::Path) {
909-
if let Some(resolved) = self.maybe_resolve_path(&path) {
915+
if let Some(resolved) = self.maybe_resolve_path(&path, None) {
910916
if self.is_primitive(&resolved) {
911917
write!(w, "{}", path.get_ident().unwrap()).unwrap();
912918
} else {
@@ -1119,12 +1125,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
11191125
match t {
11201126
syn::Type::Path(p) => {
11211127
if p.qself.is_some() { unimplemented!(); }
1122-
if let Some(gen_types) = generics {
1123-
if let Some(resolved) = gen_types.maybe_resolve_path(&p.path) {
1124-
return self.skip_path(resolved.0);
1125-
}
1126-
}
1127-
if let Some(full_path) = self.maybe_resolve_path(&p.path) {
1128+
if let Some(full_path) = self.maybe_resolve_path(&p.path, generics) {
11281129
self.skip_path(&full_path)
11291130
} else { false }
11301131
},
@@ -1138,13 +1139,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
11381139
match t {
11391140
syn::Type::Path(p) => {
11401141
if p.qself.is_some() { unimplemented!(); }
1141-
if let Some(gen_types) = generics {
1142-
if let Some(resolved) = gen_types.maybe_resolve_path(&p.path) {
1143-
write!(w, "{}", self.no_arg_path_to_rust(resolved.0)).unwrap();
1144-
return;
1145-
}
1146-
}
1147-
if let Some(full_path) = self.maybe_resolve_path(&p.path) {
1142+
if let Some(full_path) = self.maybe_resolve_path(&p.path, generics) {
11481143
write!(w, "{}", self.no_arg_path_to_rust(&full_path)).unwrap();
11491144
}
11501145
},
@@ -1185,7 +1180,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
11851180
// crate_types lookup has to have succeeded:
11861181
panic!("Failed to print inline conversion for {}", synident);
11871182
} else if let Some(decl_type) = self.declared.get(synident) {
1188-
decl_lookup(w, decl_type, &self.maybe_resolve_path(synpath).unwrap(), is_ref, is_mut);
1183+
decl_lookup(w, decl_type, &self.maybe_resolve_path(synpath, None).unwrap(), is_ref, is_mut);
11891184
return;
11901185
} else { unimplemented!(); }
11911186
}
@@ -1616,7 +1611,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
16161611
// *** C Container Type Equivalent and alias Printing ***
16171612
// ******************************************************
16181613

1619-
fn write_template_constructor<W: std::io::Write>(&mut self, w: &mut W, container_type: &str, mangled_container: &str, args: &Vec<&syn::Type>, is_ref: bool) {
1614+
fn write_template_constructor<W: std::io::Write>(&mut self, w: &mut W, container_type: &str, mangled_container: &str, args: &Vec<&syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) {
16201615
if container_type == "Result" {
16211616
assert_eq!(args.len(), 2);
16221617
macro_rules! write_fn {
@@ -1631,13 +1626,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
16311626
if let syn::Type::Path(syn::TypePath { path, .. }) = $item {
16321627
let resolved = self.resolve_path(path);
16331628
if self.is_known_container(&resolved, is_ref) || self.is_transparent_container(&resolved, is_ref) {
1634-
self.write_c_mangled_container_path_intern(w, Self::path_to_generic_args(path),
1629+
self.write_c_mangled_container_path_intern(w, Self::path_to_generic_args(path), generics,
16351630
&format!("{}", single_ident_generic_path_to_ident(path).unwrap()), is_ref, false, false, false);
16361631
} else {
16371632
self.write_template_generics(w, &mut [$item].iter().map(|t| *t), is_ref, true);
16381633
}
16391634
} else if let syn::Type::Tuple(syn::TypeTuple { elems, .. }) = $item {
1640-
self.write_c_mangled_container_path_intern(w, elems.iter().collect(),
1635+
self.write_c_mangled_container_path_intern(w, elems.iter().collect(), generics,
16411636
&format!("{}Tuple", elems.len()), is_ref, false, false, false);
16421637
} else { unimplemented!(); }
16431638
write!(w, ") -> {} =\n\t{}::CResultTempl::<", mangled_container, Self::container_templ_path()).unwrap();
@@ -1657,7 +1652,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
16571652
write!(w, "#[no_mangle]\npub extern \"C\" fn {}_new(", mangled_container).unwrap();
16581653
for (idx, gen) in args.iter().enumerate() {
16591654
write!(w, "{}{}: ", if idx != 0 { ", " } else { "" }, ('a' as u8 + idx as u8) as char).unwrap();
1660-
self.write_c_type_intern(None, w, gen, false, false, false);
1655+
self.write_c_type_intern(w, gen, None, false, false, false);
16611656
}
16621657
writeln!(w, ") -> {} {{", mangled_container).unwrap();
16631658
writeln!(w, "\t{} {{", mangled_container).unwrap();
@@ -1745,7 +1740,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
17451740
}
17461741
}
17471742
}
1748-
fn check_create_container(&mut self, mangled_container: String, container_type: &str, args: Vec<&syn::Type>, is_ref: bool) {
1743+
fn check_create_container(&mut self, mangled_container: String, container_type: &str, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) {
17491744
if !self.crate_types.templates_defined.get(&mangled_container).is_some() {
17501745
self.crate_types.templates_defined.insert(mangled_container.clone(), true);
17511746
let mut created_container: Vec<u8> = Vec::new();
@@ -1760,7 +1755,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
17601755
self.write_template_generics(&mut created_container, &mut args.iter().map(|t| *t), is_ref, true);
17611756
writeln!(&mut created_container, ">;").unwrap();
17621757

1763-
self.write_template_constructor(&mut created_container, container_type, &mangled_container, &args, is_ref);
1758+
self.write_template_constructor(&mut created_container, container_type, &mangled_container, &args, generics, is_ref);
17641759

17651760
self.crate_types.template_file.write(&created_container).unwrap();
17661761
}
@@ -1771,7 +1766,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
17711766
} else { unimplemented!(); }
17721767
}
17731768
fn write_c_mangled_container_path_intern<W: std::io::Write>
1774-
(&mut self, w: &mut W, args: Vec<&syn::Type>, ident: &str, is_ref: bool, is_mut: bool, ptr_for_ref: bool, in_type: bool) -> bool {
1769+
(&mut self, w: &mut W, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, ident: &str, is_ref: bool, is_mut: bool, ptr_for_ref: bool, in_type: bool) -> bool {
17751770
let mut mangled_type: Vec<u8> = Vec::new();
17761771
if !self.is_transparent_container(ident, is_ref) {
17771772
write!(w, "C{}_", ident).unwrap();
@@ -1788,9 +1783,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
17881783
if self.is_known_container(&subtype, is_ref) { return false; }
17891784
if !in_type {
17901785
if self.c_type_has_inner_from_path(&subtype) {
1791-
if !self.write_c_path_intern(w, &$p_arg.path, is_ref, is_mut, ptr_for_ref) { return false; }
1786+
if !self.write_c_path_intern(w, &$p_arg.path, generics, is_ref, is_mut, ptr_for_ref) { return false; }
17921787
} else {
1793-
if !self.write_c_path_intern(w, &$p_arg.path, true, is_mut, true) { return false; }
1788+
if !self.write_c_path_intern(w, &$p_arg.path, generics, true, is_mut, true) { return false; }
17941789
}
17951790
} else {
17961791
if $p_arg.path.segments.len() == 1 {
@@ -1800,15 +1795,15 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
18001795
}
18011796
}
18021797
} else if self.is_known_container(&subtype, is_ref) || self.is_transparent_container(&subtype, is_ref) {
1803-
if !self.write_c_mangled_container_path_intern(w, Self::path_to_generic_args(&$p_arg.path),
1798+
if !self.write_c_mangled_container_path_intern(w, Self::path_to_generic_args(&$p_arg.path), generics,
18041799
&subtype, is_ref, is_mut, ptr_for_ref, true) {
18051800
return false;
18061801
}
18071802
self.write_c_mangled_container_path_intern(&mut mangled_type, Self::path_to_generic_args(&$p_arg.path),
1808-
&subtype, is_ref, is_mut, ptr_for_ref, true);
1803+
generics, &subtype, is_ref, is_mut, ptr_for_ref, true);
18091804
if let Some(w2) = $extra_write as Option<&mut Vec<u8>> {
18101805
self.write_c_mangled_container_path_intern(w2, Self::path_to_generic_args(&$p_arg.path),
1811-
&subtype, is_ref, is_mut, ptr_for_ref, true);
1806+
generics, &subtype, is_ref, is_mut, ptr_for_ref, true);
18121807
}
18131808
} else if let Some(id) = single_ident_generic_path_to_ident(&$p_arg.path) {
18141809
write!(w, "{}", id).unwrap();
@@ -1842,7 +1837,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
18421837
write!(mangled_type, "Z").unwrap();
18431838
write!(mangled_tuple_type, "Z").unwrap();
18441839
self.check_create_container(String::from_utf8(mangled_tuple_type).unwrap(),
1845-
&format!("{}Tuple", tuple.elems.len()), tuple.elems.iter().collect(), is_ref);
1840+
&format!("{}Tuple", tuple.elems.len()), tuple.elems.iter().collect(), generics, is_ref);
18461841
}
18471842
} else if let syn::Type::Path(p_arg) = arg {
18481843
write_path!(p_arg, None);
@@ -1876,23 +1871,22 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
18761871
write!(mangled_type, "Z").unwrap();
18771872

18781873
// Make sure the type is actually defined:
1879-
self.check_create_container(String::from_utf8(mangled_type).unwrap(), ident, args, is_ref);
1874+
self.check_create_container(String::from_utf8(mangled_type).unwrap(), ident, args, generics, is_ref);
18801875
true
18811876
}
1882-
fn write_c_mangled_container_path<W: std::io::Write>(&mut self, w: &mut W, args: Vec<&syn::Type>, ident: &str, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
1877+
fn write_c_mangled_container_path<W: std::io::Write>(&mut self, w: &mut W, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, ident: &str, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
18831878
if !self.is_transparent_container(ident, is_ref) {
18841879
write!(w, "{}::", Self::generated_container_path()).unwrap();
18851880
}
1886-
self.write_c_mangled_container_path_intern(w, args, ident, is_ref, is_mut, ptr_for_ref, false)
1881+
self.write_c_mangled_container_path_intern(w, args, generics, ident, is_ref, is_mut, ptr_for_ref, false)
18871882
}
18881883

18891884
// **********************************
18901885
// *** C Type Equivalent Printing ***
18911886
// **********************************
18921887

1893-
fn write_c_path_intern<W: std::io::Write>(&self, w: &mut W, path: &syn::Path, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
1894-
//eprintln!("pcpi ({} {} {}): {:?}", is_ref, is_mut, ptr_for_ref, path);
1895-
let full_path = match self.maybe_resolve_path(&path) {
1888+
fn write_c_path_intern<W: std::io::Write>(&self, w: &mut W, path: &syn::Path, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
1889+
let full_path = match self.maybe_resolve_path(&path, generics) {
18961890
Some(path) => path, None => return false };
18971891
if let Some(c_type) = self.c_type_from_path(&full_path, is_ref, ptr_for_ref) {
18981892
write!(w, "{}", c_type).unwrap();
@@ -1923,43 +1917,36 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
19231917
false
19241918
}
19251919
}
1926-
fn write_c_type_intern<W: std::io::Write>(&mut self, generics: Option<&GenericTypes>, w: &mut W, t: &syn::Type, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
1920+
fn write_c_type_intern<W: std::io::Write>(&mut self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
19271921
match t {
19281922
syn::Type::Path(p) => {
19291923
if p.qself.is_some() || p.path.leading_colon.is_some() {
19301924
return false;
19311925
}
1932-
if let Some(gen_types) = generics {
1933-
if let Some(resolved) = gen_types.maybe_resolve_path(&p.path) {
1934-
if self.is_known_container(&resolved.0, is_ref) { return false; }
1935-
if self.is_transparent_container(&resolved.0, is_ref) { return false; }
1936-
return self.write_c_path_intern(w, &resolved.1, is_ref, is_mut, ptr_for_ref);
1937-
}
1938-
}
1939-
if let Some(full_path) = self.maybe_resolve_path(&p.path) {
1926+
if let Some(full_path) = self.maybe_resolve_path(&p.path, generics) {
19401927
if self.is_known_container(&full_path, is_ref) || self.is_transparent_container(&full_path, is_ref) {
1941-
return self.write_c_mangled_container_path(w, Self::path_to_generic_args(&p.path), &full_path, is_ref, is_mut, ptr_for_ref);
1928+
return self.write_c_mangled_container_path(w, Self::path_to_generic_args(&p.path), generics, &full_path, is_ref, is_mut, ptr_for_ref);
19421929
}
19431930
}
19441931
if p.path.leading_colon.is_some() { return false; }
1945-
self.write_c_path_intern(w, &p.path, is_ref, is_mut, ptr_for_ref)
1932+
self.write_c_path_intern(w, &p.path, generics, is_ref, is_mut, ptr_for_ref)
19461933
},
19471934
syn::Type::Reference(r) => {
19481935
if let Some(lft) = &r.lifetime {
19491936
if format!("{}", lft.ident) != "static" { return false; }
19501937
}
1951-
self.write_c_type_intern(generics, w, &*r.elem, true, r.mutability.is_some(), ptr_for_ref)
1938+
self.write_c_type_intern(w, &*r.elem, generics, true, r.mutability.is_some(), ptr_for_ref)
19521939
},
19531940
syn::Type::Array(a) => {
19541941
if is_ref && is_mut {
19551942
write!(w, "*mut [").unwrap();
1956-
if !self.write_c_type_intern(generics, w, &a.elem, false, false, ptr_for_ref) { return false; }
1943+
if !self.write_c_type_intern(w, &a.elem, generics, false, false, ptr_for_ref) { return false; }
19571944
} else if is_ref {
19581945
write!(w, "*const [").unwrap();
1959-
if !self.write_c_type_intern(generics, w, &a.elem, false, false, ptr_for_ref) { return false; }
1946+
if !self.write_c_type_intern(w, &a.elem, generics, false, false, ptr_for_ref) { return false; }
19601947
} else {
19611948
let mut typecheck = Vec::new();
1962-
if !self.write_c_type_intern(generics, &mut typecheck, &a.elem, false, false, ptr_for_ref) { return false; }
1949+
if !self.write_c_type_intern(&mut typecheck, &a.elem, generics, false, false, ptr_for_ref) { return false; }
19631950
if typecheck[..] != ['u' as u8, '8' as u8] { return false; }
19641951
}
19651952
if let syn::Expr::Lit(l) = &a.len {
@@ -1996,7 +1983,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
19961983
format!("CVec_{}Z", id)
19971984
} else { return false; };
19981985
write!(w, "{}::{}", Self::generated_container_path(), mangled_container).unwrap();
1999-
self.check_create_container(mangled_container, "Vec", vec![&*r.elem], false);
1986+
self.check_create_container(mangled_container, "Vec", vec![&*r.elem], generics, false);
20001987
true
20011988
} else { false }
20021989
} else { false }
@@ -2005,21 +1992,21 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
20051992
if t.elems.len() == 0 {
20061993
true
20071994
} else {
2008-
self.write_c_mangled_container_path(w, t.elems.iter().collect(),
1995+
self.write_c_mangled_container_path(w, t.elems.iter().collect(), generics,
20091996
&format!("{}Tuple", t.elems.len()), is_ref, is_mut, ptr_for_ref)
20101997
}
20111998
},
20121999
_ => false,
20132000
}
20142001
}
20152002
pub fn write_c_type<W: std::io::Write>(&mut self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, ptr_for_ref: bool) {
2016-
assert!(self.write_c_type_intern(generics, w, t, false, false, ptr_for_ref));
2003+
assert!(self.write_c_type_intern(w, t, generics, false, false, ptr_for_ref));
20172004
}
20182005
pub fn understood_c_path(&mut self, p: &syn::Path) -> bool {
20192006
if p.leading_colon.is_some() { return false; }
2020-
self.write_c_path_intern(&mut std::io::sink(), p, false, false, false)
2007+
self.write_c_path_intern(&mut std::io::sink(), p, None, false, false, false)
20212008
}
20222009
pub fn understood_c_type(&mut self, t: &syn::Type, generics: Option<&GenericTypes>) -> bool {
2023-
self.write_c_type_intern(generics, &mut std::io::sink(), t, false, false, false)
2010+
self.write_c_type_intern(&mut std::io::sink(), t, generics, false, false, false)
20242011
}
20252012
}

0 commit comments

Comments
 (0)