diff --git a/gen/build/Cargo.toml b/gen/build/Cargo.toml index 286e00c0a..20aafca3f 100644 --- a/gen/build/Cargo.toml +++ b/gen/build/Cargo.toml @@ -14,6 +14,8 @@ categories = ["development-tools::ffi"] [features] parallel = ["cc/parallel"] +# incomplete features that are not covered by a compatibility guarantee: +experimental-async-fn = [] [dependencies] cc = "1.0.49" diff --git a/gen/cmd/Cargo.toml b/gen/cmd/Cargo.toml index 5ba1e8d7d..7d94b2dc9 100644 --- a/gen/cmd/Cargo.toml +++ b/gen/cmd/Cargo.toml @@ -16,6 +16,10 @@ categories = ["development-tools::ffi"] name = "cxxbridge" path = "src/main.rs" +[features] +# incomplete features that are not covered by a compatibility guarantee: +experimental-async-fn = [] + [dependencies] clap = { version = "3.0", default-features = false, features = ["std", "suggestions"] } codespan-reporting = "0.11" diff --git a/macro/Cargo.toml b/macro/Cargo.toml index ce643358d..d565f6b03 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -16,6 +16,8 @@ categories = ["development-tools::ffi"] proc-macro = true [features] +# incomplete features that are not covered by a compatibility guarantee: +experimental-async-fn = [] experimental-enum-variants-from-header = ["clang-ast", "flate2", "memmap", "serde", "serde_json"] [dependencies] @@ -23,7 +25,7 @@ proc-macro2 = "1.0" quote = "1.0.4" syn = { version = "1.0.70", features = ["full"] } -# optional dependencies +# optional dependencies: clang-ast = { version = "0.1", optional = true } flate2 = { version = "1.0", optional = true } memmap = { version = "0.7", optional = true } diff --git a/syntax/impls.rs b/syntax/impls.rs index 22c5441b5..36e1f322a 100644 --- a/syntax/impls.rs +++ b/syntax/impls.rs @@ -309,6 +309,7 @@ impl Eq for Signature {} impl PartialEq for Signature { fn eq(&self, other: &Self) -> bool { let Signature { + asyncness, unsafety, fn_token: _, generics: _, @@ -320,6 +321,7 @@ impl PartialEq for Signature { throws_tokens: _, } = self; let Signature { + asyncness: asyncness2, unsafety: unsafety2, fn_token: _, generics: _, @@ -330,7 +332,8 @@ impl PartialEq for Signature { paren_token: _, throws_tokens: _, } = other; - unsafety.is_some() == unsafety2.is_some() + asyncness.is_some() == asyncness2.is_some() + && unsafety.is_some() == unsafety2.is_some() && receiver == receiver2 && ret == ret2 && throws == throws2 @@ -362,6 +365,7 @@ impl PartialEq for Signature { impl Hash for Signature { fn hash(&self, state: &mut H) { let Signature { + asyncness, unsafety, fn_token: _, generics: _, @@ -372,6 +376,7 @@ impl Hash for Signature { paren_token: _, throws_tokens: _, } = self; + asyncness.is_some().hash(state); unsafety.is_some().hash(state); receiver.hash(state); for arg in args { diff --git a/syntax/mod.rs b/syntax/mod.rs index da49dc3cb..4f19d9641 100644 --- a/syntax/mod.rs +++ b/syntax/mod.rs @@ -179,6 +179,7 @@ pub struct Lifetimes { } pub struct Signature { + pub asyncness: Option, pub unsafety: Option, pub fn_token: Token![fn], pub generics: Generics, diff --git a/syntax/parse.rs b/syntax/parse.rs index 8e7272f80..dee24c2fa 100644 --- a/syntax/parse.rs +++ b/syntax/parse.rs @@ -562,7 +562,7 @@ fn parse_extern_fn( )); } - if foreign_fn.sig.asyncness.is_some() { + if foreign_fn.sig.asyncness.is_some() && !cfg!(feature = "experimental-async-fn") { return Err(Error::new_spanned( foreign_fn, "async function is not directly supported yet, but see https://cxx.rs/async.html \ @@ -664,6 +664,7 @@ fn parse_extern_fn( let mut throws_tokens = None; let ret = parse_return_type(&foreign_fn.sig.output, &mut throws_tokens)?; let throws = throws_tokens.is_some(); + let asyncness = foreign_fn.sig.asyncness; let unsafety = foreign_fn.sig.unsafety; let fn_token = foreign_fn.sig.fn_token; let inherited_span = unsafety.map_or(fn_token.span, |unsafety| unsafety.span); @@ -684,6 +685,7 @@ fn parse_extern_fn( visibility, name, sig: Signature { + asyncness, unsafety, fn_token, generics, @@ -1400,6 +1402,7 @@ fn parse_type_fn(ty: &TypeBareFn) -> Result { let ret = parse_return_type(&ty.output, &mut throws_tokens)?; let throws = throws_tokens.is_some(); + let asyncness = None; let unsafety = ty.unsafety; let fn_token = ty.fn_token; let generics = Generics::default(); @@ -1407,6 +1410,7 @@ fn parse_type_fn(ty: &TypeBareFn) -> Result { let paren_token = ty.paren_token; Ok(Type::Fn(Box::new(Signature { + asyncness, unsafety, fn_token, generics, diff --git a/syntax/tokens.rs b/syntax/tokens.rs index b8eb234c6..62d37c23d 100644 --- a/syntax/tokens.rs +++ b/syntax/tokens.rs @@ -248,6 +248,7 @@ impl ToTokens for Lifetimes { impl ToTokens for Signature { fn to_tokens(&self, tokens: &mut TokenStream) { let Signature { + asyncness: _, unsafety: _, fn_token, generics: _,