(#36): Don't output "-> ()" for extern "C" functions with no return type

Fixes federico/gnome-class#36
parent f95a2e60
......@@ -68,8 +68,7 @@ pub fn instance_slot_trampolines<'this, 'ast: 'this>(
unsafe extern "C" fn #trampoline_name(
this: *mut #receiver_instance,
#inputs
)
-> #output
) #output
{
#callback_guard
......@@ -229,8 +228,7 @@ pub fn extern_methods<'ast>(names: &Names, slots: &[Slot<'ast>]) -> Vec<TokenStr
Some(quote! {
#[no_mangle]
pub unsafe extern "C" fn #ffi_name(this: *mut #InstanceNameFfi,
#inputs)
-> #output
#inputs) #output
{
#callback_guard
......@@ -249,8 +247,7 @@ pub fn extern_methods<'ast>(names: &Names, slots: &[Slot<'ast>]) -> Vec<TokenStr
Some(quote! {
#[no_mangle]
pub unsafe extern "C" fn #ffi_name(this: *mut #InstanceNameFfi,
#inputs)
-> #output
#inputs) #output
{
#callback_guard
......
......@@ -4,13 +4,26 @@ use quote::ToTokens;
use hir::{FnArg, FnSig, Ty};
impl<'ast> FnSig<'ast> {
/// Generates the Glib type name of the function's return value
/// Generates `-> GlibTypeName` for the function's return value
///
/// For example, if the `FnSig` represents a `fn foo(...) ->
/// bool`, then this function will generate something that
/// resolves to `glib_sys::gboolean`.
///
/// For functions that return nothing, i.e. the `FnSig` has an `output: Ty::Unit`,
/// then no `-> Foo` is generated at all. This is so that `extern "C"` functions will look like
///
/// ```rust,ignore
/// unsafe extern "C" fn foo(...);
/// ```
///
/// instead of
///
/// ```rust,ignore
/// unsafe extern fn "C" foo(...) -> (); // we don't want a unit type there
/// ```
pub fn output_glib_type<'a>(&'a self) -> impl ToTokens + 'a {
ToGlibType(&self.output, self)
ToGlibReturnType(&self.output, self)
}
/// Generates an argument list just with Rust types, suitable for `Fn` signatures, without
......@@ -108,6 +121,25 @@ impl<'ast> FnSig<'ast> {
}
}
struct ToGlibReturnType<'ast>(&'ast Ty<'ast>, &'ast FnSig<'ast>);
impl<'ast> ToTokens for ToGlibReturnType<'ast> {
fn to_tokens(&self, tokens: &mut TokenStream) {
// Only output the "->" for non-unit return types
match *self.0 {
Ty::Unit => (),
_ => {
(quote! {
->
})
.to_tokens(tokens);
ToGlibType(self.0, self.1).to_tokens(tokens)
}
}
}
}
struct ToGlibType<'ast>(&'ast Ty<'ast>, &'ast FnSig<'ast>);
impl<'ast> ToTokens for ToGlibType<'ast> {
......
......@@ -27,7 +27,7 @@ impl<'ast> ToTokens for SlotDeclaration<'ast> {
pub #name: Option<unsafe extern "C" fn(
this: *mut #InstanceNameFfi,
#inputs
) -> #output>,
) #output>,
})
.to_tokens(tokens);
}
......@@ -41,7 +41,7 @@ impl<'ast> ToTokens for SlotDeclaration<'ast> {
pub #signalname: Option<unsafe extern "C" fn(
this: *mut #InstanceNameFfi,
#inputs
) -> #output>,
) #output>,
})
.to_tokens(tokens);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment