From e63c8846af0e37b6573dd3dde03a2954e1ca3eee Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 29 Oct 2021 18:59:25 +0000 Subject: [PATCH] Support traits and structs with lifetime bounds (which are ignored) --- c-bindings-gen/src/main.rs | 17 +++++++++++------ c-bindings-gen/src/types.rs | 35 ++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index 4d5b070..280f94e 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -491,13 +491,18 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty &syn::TraitItem::Type(ref t) => { if t.default.is_some() || t.generics.lt_token.is_some() { unimplemented!(); } let mut bounds_iter = t.bounds.iter(); - match bounds_iter.next().unwrap() { - syn::TypeParamBound::Trait(tr) => { - writeln!(w, "\ttype {} = crate::{};", t.ident, $type_resolver.resolve_path(&tr.path, Some(&gen_types))).unwrap(); - }, - _ => unimplemented!(), + loop { + match bounds_iter.next().unwrap() { + syn::TypeParamBound::Trait(tr) => { + writeln!(w, "\ttype {} = crate::{};", t.ident, $type_resolver.resolve_path(&tr.path, Some(&gen_types))).unwrap(); + for bound in bounds_iter { + if let syn::TypeParamBound::Trait(_) = bound { unimplemented!(); } + } + break; + }, + syn::TypeParamBound::Lifetime(_) => {}, + } } - if bounds_iter.next().is_some() { unimplemented!(); } }, _ => unimplemented!(), } diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index 498bdf5..357fe4c 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -294,23 +294,28 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { &syn::TraitItem::Type(ref t) => { if t.default.is_some() || t.generics.lt_token.is_some() { unimplemented!(); } let mut bounds_iter = t.bounds.iter(); - match bounds_iter.next().unwrap() { - syn::TypeParamBound::Trait(tr) => { - assert_simple_bound(&tr); - if let Some(path) = types.maybe_resolve_path(&tr.path, None) { - if types.skip_path(&path) { continue; } - // In general we handle Deref as if it were just X (and - // implement Deref for relevant types). We don't - // bother to implement it for associated types, however, so we just - // ignore such bounds. - if path != "std::ops::Deref" && path != "core::ops::Deref" { - self.typed_generics.insert(&t.ident, path); + loop { + match bounds_iter.next().unwrap() { + syn::TypeParamBound::Trait(tr) => { + assert_simple_bound(&tr); + if let Some(path) = types.maybe_resolve_path(&tr.path, None) { + if types.skip_path(&path) { continue; } + // In general we handle Deref as if it were just X (and + // implement Deref for relevant types). We don't + // bother to implement it for associated types, however, so we just + // ignore such bounds. + if path != "std::ops::Deref" && path != "core::ops::Deref" { + self.typed_generics.insert(&t.ident, path); + } + } else { unimplemented!(); } + for bound in bounds_iter { + if let syn::TypeParamBound::Trait(_) = bound { unimplemented!(); } } - } else { unimplemented!(); } - }, - _ => unimplemented!(), + break; + }, + syn::TypeParamBound::Lifetime(_) => {}, + } } - if bounds_iter.next().is_some() { unimplemented!(); } }, _ => {}, } -- 2.30.2