gir icon indicating copy to clipboard operation
gir copied to clipboard

Regression after the switch to impl in arguments

Open bilelmoussaoui opened this issue 3 years ago • 8 comments

after the switch to having impl in the arguments, a regression was introduced where such code is generated

Before:

fn uninstall<P: IsA<gio::Cancellable>>(
    &self,
    kind: RefKind,
    name: &str,
    arch: Option<&str>,
    branch: Option<&str>,
    progress: Option<&mut dyn (FnMut(&str, u32, bool))>,
    cancellable: Option<&P>,
) -> Result<(), glib::Error> {
    let progress_data: Option<&mut dyn (FnMut(&str, u32, bool))> = progress;
    unsafe extern "C" fn progress_func<P: IsA<gio::Cancellable>>(
        status: *const libc::c_char,
        progress: libc::c_uint,
        estimating: glib::ffi::gboolean,
        user_data: glib::ffi::gpointer,
    ) {
        let status: Borrowed<glib::GString> = from_glib_borrow(status);
        let estimating = from_glib(estimating);
        let callback: *mut Option<&mut dyn (FnMut(&str, u32, bool))> =
            user_data as *const _ as usize as *mut Option<&mut dyn (FnMut(&str, u32, bool))>;
        if let Some(ref mut callback) = *callback {
            callback(status.as_str(), progress, estimating)
        } else {
            panic!("cannot get closure...")
        };
    }
    let progress = if progress_data.is_some() {
        Some(progress_func::<P> as _)
    } else {
        None
    };
    let super_callback0: &Option<&mut dyn (FnMut(&str, u32, bool))> = &progress_data;
    unsafe {
        let mut error = ptr::null_mut();
        let _ = ffi::flatpak_installation_uninstall(
            self.as_ref().to_glib_none().0,
            kind.into_glib(),
            name.to_glib_none().0,
            arch.to_glib_none().0,
            branch.to_glib_none().0,
            progress,
            super_callback0 as *const _ as usize as *mut _,
            cancellable.map(|p| p.as_ref()).to_glib_none().0,
            &mut error,
        );
        if error.is_null() {
            Ok(())
        } else {
            Err(from_glib_full(error))
        }
    }
}

After

fn uninstall(
    &self,
    kind: RefKind,
    name: &str,
    arch: Option<&str>,
    branch: Option<&str>,
    progress: Option<&mut dyn (FnMut(&str, u32, bool))>,
    cancellable: Option<&impl IsA<gio::Cancellable>>,
) -> Result<(), glib::Error> {
    let progress_data: Option<&mut dyn (FnMut(&str, u32, bool))> = progress;
    unsafe extern "C" fn progress_func(
        status: *const libc::c_char,
        progress: libc::c_uint,
        estimating: glib::ffi::gboolean,
        user_data: glib::ffi::gpointer,
    ) {
        let status: Borrowed<glib::GString> = from_glib_borrow(status);
        let estimating = from_glib(estimating);
        let callback: *mut Option<&mut dyn (FnMut(&str, u32, bool))> =
            user_data as *const _ as usize as *mut Option<&mut dyn (FnMut(&str, u32, bool))>;
        if let Some(ref mut callback) = *callback {
            callback(status.as_str(), progress, estimating)
        } else {
            panic!("cannot get closure...")
        };
    }
    let progress = if progress_data.is_some() {
        Some(progress_func as _)
    } else {
        None
    };
    let super_callback0: &Option<&mut dyn (FnMut(&str, u32, bool))> = &progress_data;
    unsafe {
        let mut error = ptr::null_mut();
        let _ = ffi::flatpak_installation_uninstall(
            self.as_ref().to_glib_none().0,
            kind.into_glib(),
            name.to_glib_none().0,
            arch.to_glib_none().0,
            branch.to_glib_none().0,
            progress,
            super_callback0 as *const _ as usize as *mut _,
            cancellable.to_glib_none().0,
            &mut error,
        );
        if error.is_null() {
            Ok(())
        } else {
            Err(from_glib_full(error))
        }
    }
}

The cancellable.to_glib_none().0 should be cancellable.map(|p| p.as_ref()).to_glib_none().0, instead

The GIR definition

<method name="uninstall" c:identifier="flatpak_installation_uninstall" deprecated="1" deprecated-version="1.7.0" throws="1">
    <doc xml:space="preserve" filename="flatpak-installation.c" line="2124">This is an old deprecated function, you should use
#FlatpakTransaction and flatpak_transaction_add_uninstall()
instead. It has a lot more interesting features.

Uninstall an application or runtime.</doc>
    <doc-deprecated xml:space="preserve">Use flatpak_transaction_add_uninstall() instead.</doc-deprecated>
    <source-position filename="flatpak-installation.h" line="369"/>
    <return-value transfer-ownership="none">
        <doc xml:space="preserve" filename="flatpak-installation.c" line="2144">%TRUE on success</doc>
        <type name="gboolean" c:type="gboolean"/>
    </return-value>
    <parameters>
        <instance-parameter name="self" transfer-ownership="none">
            <doc xml:space="preserve" filename="flatpak-installation.c" line="2126">a #FlatpakInstallation</doc>
            <type name="Installation" c:type="FlatpakInstallation*"/>
        </instance-parameter>
        <parameter name="kind" transfer-ownership="none">
            <doc xml:space="preserve" filename="flatpak-installation.c" line="2127">what this ref contains (an #FlatpakRefKind)</doc>
            <type name="RefKind" c:type="FlatpakRefKind"/>
        </parameter>
        <parameter name="name" transfer-ownership="none">
            <doc xml:space="preserve" filename="flatpak-installation.c" line="2128">name of the app or runtime to uninstall</doc>
            <type name="utf8" c:type="const char*"/>
        </parameter>
        <parameter name="arch" transfer-ownership="none" nullable="1" allow-none="1">
            <doc xml:space="preserve" filename="flatpak-installation.c" line="2129">architecture of the app or runtime to uninstall; if
%NULL, flatpak_get_default_arch() is assumed</doc>
            <type name="utf8" c:type="const char*"/>
        </parameter>
        <parameter name="branch" transfer-ownership="none" nullable="1" allow-none="1">
            <doc xml:space="preserve" filename="flatpak-installation.c" line="2131">name of the branch of the app or runtime to uninstall;
if %NULL, `master` is assumed</doc>
            <type name="utf8" c:type="const char*"/>
        </parameter>
        <parameter name="progress" transfer-ownership="none" nullable="1" allow-none="1" scope="call" closure="5">
            <doc xml:space="preserve" filename="flatpak-installation.c" line="2133">the callback</doc>
            <type name="ProgressCallback" c:type="FlatpakProgressCallback"/>
        </parameter>
        <parameter name="progress_data" transfer-ownership="none" nullable="1" allow-none="1" closure="4">
            <doc xml:space="preserve" filename="flatpak-installation.c" line="2134">user data passed to @progress</doc>
            <type name="gpointer" c:type="gpointer"/>
        </parameter>
        <parameter name="cancellable" transfer-ownership="none" nullable="1" allow-none="1">
            <doc xml:space="preserve" filename="flatpak-installation.c" line="2135">a #GCancellable</doc>
            <type name="Gio.Cancellable" c:type="GCancellable*"/>
        </parameter>
    </parameters>
</method>

bilelmoussaoui avatar Nov 12 '21 16:11 bilelmoussaoui

Adding it to the blockers for next release.

GuillaumeGomez avatar Nov 12 '21 17:11 GuillaumeGomez

Maybe @MarijnS95 might have an idea about?

bilelmoussaoui avatar Nov 12 '21 17:11 bilelmoussaoui

@sdroege Pinged me about code containing exactly that map in https://github.com/gtk-rs/gir/pull/1245#issuecomment-954856146 - don't know if anything was resolved around it?

MarijnS95 avatar Nov 12 '21 17:11 MarijnS95

The strange thing being that this is an Option<&P> which holds a borrow already - ~why do you need to call as_ref() on P: IsA?~ EDIT: What is it converting into?

MarijnS95 avatar Nov 12 '21 17:11 MarijnS95

What is it converting into? to the parent type; a gio::Cancellable. That's how all the subclassable type works right now

bilelmoussaoui avatar Nov 12 '21 17:11 bilelmoussaoui

Why does it generate the correct code for all the same pattern in gio? :) That was one of the testcases when doing my changes recently.

sdroege avatar Nov 12 '21 17:11 sdroege

No idea at all, if you can give me some tips where I should look at I can give it a try

bilelmoussaoui avatar Nov 12 '21 17:11 bilelmoussaoui

The MR that broke it should be https://github.com/gtk-rs/gir/pull/1245.

sdroege avatar Nov 12 '21 18:11 sdroege