Unverified Commit cc4114f0 authored by Mark Hammond's avatar Mark Hammond Committed by GitHub
Browse files

Fixup lifetimes in Callable/ResultType (#2399)

Changing `return_type` and `throws_type` to be references is more
consistent and allows the trait to implement `iter_types`.
parent 22909572
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -581,7 +581,7 @@ fn can_render_callable(callable: &dyn Callable, ci: &ComponentInterface) -> bool
    // can't handle external errors.
    callable
        .throws_type()
        .map(|t| !ci.is_external(&t))
        .map(|t| !ci.is_external(t))
        .unwrap_or(true)
}

@@ -749,7 +749,7 @@ mod filters {
        let call = format!("UniffiLib.INSTANCE.{ffi_func}(future, continuation)");
        // May need to convert the RustBuffer from our package to the RustBuffer of the external package
        let call = match callable.return_type() {
            Some(return_type) if ci.is_external(&return_type) => {
            Some(return_type) if ci.is_external(return_type) => {
                let ffi_type = FfiType::from(return_type);
                match ffi_type {
                    FfiType::RustBuffer(Some(ExternalFfiMetadata { name, .. })) => {
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ use uniffi_meta::Checksum;

use super::ffi::{FfiArgument, FfiCallbackFunction, FfiField, FfiFunction, FfiStruct, FfiType};
use super::object::Method;
use super::{AsType, Type, TypeIterator};
use super::{AsType, Callable, Type, TypeIterator};

#[derive(Debug, Clone, Checksum)]
pub struct CallbackInterface {
+25 −24
Original line number Diff line number Diff line
@@ -128,16 +128,6 @@ impl Function {
        Ok(())
    }

    pub fn iter_types(&self) -> TypeIterator<'_> {
        Box::new(
            self.arguments
                .iter()
                .flat_map(Argument::iter_types)
                .chain(self.return_type.iter().flat_map(Type::iter_types))
                .chain(self.throws.iter().flat_map(Type::iter_types)),
        )
    }

    pub fn docstring(&self) -> Option<&str> {
        self.docstring.as_deref()
    }
@@ -239,15 +229,15 @@ impl From<&Argument> for FfiArgument {

/// Combines the return and throws type of a function/method
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct ResultType {
    pub return_type: Option<Type>,
    pub throws_type: Option<Type>,
pub struct ResultType<'a> {
    pub return_type: Option<&'a Type>,
    pub throws_type: Option<&'a Type>,
}

impl ResultType {
impl<'a> ResultType<'a> {
    /// Get the `T` parameters for the `FutureCallback<T>` for this ResultType
    pub fn future_callback_param(&self) -> FfiType {
        match &self.return_type {
        match self.return_type {
            Some(t) => t.into(),
            None => FfiType::UInt8,
        }
@@ -257,20 +247,31 @@ impl ResultType {
/// Implemented by function-like types (Function, Method, Constructor)
pub trait Callable {
    fn arguments(&self) -> Vec<&Argument>;
    fn return_type(&self) -> Option<Type>;
    fn throws_type(&self) -> Option<Type>;
    fn return_type(&self) -> Option<&Type>;
    fn throws_type(&self) -> Option<&Type>;
    fn is_async(&self) -> bool;
    fn docstring(&self) -> Option<&str>;
    fn takes_self(&self) -> bool {
        false
    }
    fn result_type(&self) -> ResultType {
    fn result_type(&self) -> ResultType<'_> {
        ResultType {
            return_type: self.return_type(),
            throws_type: self.throws_type(),
        }
    }

    fn iter_types(&self) -> TypeIterator<'_> {
        let types: Vec<&Type> = self
            .arguments()
            .iter()
            .flat_map(|a| a.iter_types())
            .chain(self.return_type().iter().flat_map(|t| t.iter_types()))
            .chain(self.throws_type().iter().flat_map(|t| t.iter_types()))
            .collect();
        Box::new(types.into_iter())
    }

    // Scaffolding function
    fn ffi_func(&self) -> &FfiFunction;

@@ -306,12 +307,12 @@ impl Callable for Function {
        self.arguments()
    }

    fn return_type(&self) -> Option<Type> {
        self.return_type().cloned()
    fn return_type(&self) -> Option<&Type> {
        self.return_type()
    }

    fn throws_type(&self) -> Option<Type> {
        self.throws_type().cloned()
    fn throws_type(&self) -> Option<&Type> {
        self.throws_type()
    }

    fn docstring(&self) -> Option<&str> {
@@ -333,11 +334,11 @@ impl<T: Callable> Callable for &T {
        (*self).arguments()
    }

    fn return_type(&self) -> Option<Type> {
    fn return_type(&self) -> Option<&Type> {
        (*self).return_type()
    }

    fn throws_type(&self) -> Option<Type> {
    fn throws_type(&self) -> Option<&Type> {
        (*self).throws_type()
    }

+1 −1
Original line number Diff line number Diff line
@@ -603,7 +603,7 @@ impl ComponentInterface {
    }

    /// Iterate over return/throws types for async functions
    pub fn iter_async_result_types(&self) -> impl Iterator<Item = ResultType> {
    pub fn iter_async_result_types(&self) -> impl Iterator<Item = ResultType<'_>> {
        let unique_results = self
            .iter_callables()
            .map(|c| c.result_type())
+16 −31
Original line number Diff line number Diff line
@@ -395,6 +395,8 @@ pub struct Constructor {
    // Force a checksum value, or we'll fallback to the trait.
    #[checksum_ignore]
    pub(super) checksum: Option<u16>,
    // to help with lifetimes elsewhere...
    pub(super) self_type: Type,
}

impl Constructor {
@@ -461,15 +463,6 @@ impl Constructor {
            self.arguments.iter().map(Into::into),
        );
    }

    pub fn iter_types(&self) -> TypeIterator<'_> {
        Box::new(
            self.arguments
                .iter()
                .flat_map(Argument::iter_types)
                .chain(self.throws.iter().flat_map(Type::iter_types)),
        )
    }
}

impl From<uniffi_meta::ConstructorMetadata> for Constructor {
@@ -483,6 +476,11 @@ impl From<uniffi_meta::ConstructorMetadata> for Constructor {
            is_async: meta.is_async,
            ..FfiFunction::default()
        };
        let self_type = Type::Object {
            module_path: meta.module_path.clone(),
            name: meta.self_name.clone(),
            imp: ObjectImpl::Struct,
        };
        Self {
            name: meta.name,
            object_name: meta.self_name,
@@ -494,6 +492,7 @@ impl From<uniffi_meta::ConstructorMetadata> for Constructor {
            throws: meta.throws.map(Into::into),
            checksum_fn_name,
            checksum: meta.checksum,
            self_type,
        }
    }
}
@@ -616,16 +615,6 @@ impl Method {
        Ok(())
    }

    pub fn iter_types(&self) -> TypeIterator<'_> {
        Box::new(
            self.arguments
                .iter()
                .flat_map(Argument::iter_types)
                .chain(self.return_type.iter().flat_map(Type::iter_types))
                .chain(self.throws.iter().flat_map(Type::iter_types)),
        )
    }

    /// For async callback interface methods, the FFI struct to pass to the completion function.
    pub fn foreign_future_ffi_result_struct(&self) -> FfiStruct {
        callbacks::foreign_future_ffi_result_struct(self.return_type.as_ref().map(FfiType::from))
@@ -738,16 +727,12 @@ impl Callable for Constructor {
        self.arguments()
    }

    fn return_type(&self) -> Option<Type> {
        Some(Type::Object {
            name: self.object_name.clone(),
            module_path: self.object_module_path.clone(),
            imp: ObjectImpl::Struct,
        })
    fn return_type(&self) -> Option<&Type> {
        Some(&self.self_type)
    }

    fn throws_type(&self) -> Option<Type> {
        self.throws_type().cloned()
    fn throws_type(&self) -> Option<&Type> {
        self.throws_type()
    }

    fn docstring(&self) -> Option<&str> {
@@ -768,12 +753,12 @@ impl Callable for Method {
        self.arguments()
    }

    fn return_type(&self) -> Option<Type> {
        self.return_type().cloned()
    fn return_type(&self) -> Option<&Type> {
        self.return_type()
    }

    fn throws_type(&self) -> Option<Type> {
        self.throws_type().cloned()
    fn throws_type(&self) -> Option<&Type> {
        self.throws_type()
    }

    fn docstring(&self) -> Option<&str> {