Cannot infer type, but all types are known

In the below, specifically in call to from_glib_full, all types to the best of my knowledge are known:
The arg to the call is *mut gtk::Socket and the return type is *mut GtkSocket. Yet, I'm getting error.

 let gtk_socket: *mut gtk::Socket = pointer as *mut _ as *mut gtk::Socket;
 let gtksocket: *mut GtkSocket = from_glib_full(gtk_socket).unwrap();

Error:

let gtk_socket: *mut GtkSocket = from_glib_full(gtk_socket).unwrap();
| ^^^^^^^^^^^^^^ cannot infer type for type parameter T declared on the function from_glib_full

What's the definition of from_glib_full?

unsafe fn from_glib_full(ptr: P) -> Self;

What's the context, then? It is in some impl block, because of Self, - how is this block defined?

The context is provided in OP. the pointer var is of gpointer type. It happens inside of fn body.

I mean the context where the fn item is defined. It can't be a top-level item, since it would be a syntax error.

It is inside a trait FromGlibPtr

And what's the definition of FromGlibPtr, then?

Sorry, the intellisense must have navigate to incorrect def. This is the definition of fn from_glib_full:

#[inline]
pub unsafe fn from_glib_full<P: Ptr, T: FromGlibPtrFull<P>>(ptr: P) -> T {
    FromGlibPtrFull::from_glib_full(ptr)
}

And this is the trait:

pub trait FromGlibPtrFull<P: Ptr>: Sized {
    // rustdoc-stripper-ignore-next
    /// # Safety
    ///
    /// See trait level [notes on safety](#safety_points)
    unsafe fn from_glib_full(ptr: P) -> Self;
}

Okay, then - what is FromGlibPtrFull implemented for? You're unwrapping the result of from_glib_full call, that hints on something like Result, but since we don't know the trait, we don't know for sure what kind of Result (or probably Option) it is.

I actually do not agree with what you've said. We do provide all types, both return type and the fn call arg.

The code in the OP is equivalent (modulo lifetime of temporaries) to this:

let gtk_socket: *mut gtk::Socket = pointer as *mut _ as *mut gtk::Socket;
let tmp: T = from_glib_full(gtk_socket);
let gtksocket: *mut GtkSocket = tmp.unwrap();

In this case, what's T?

I do provide specific type. GtkSocket.

Look at the code at my previous post again. You're providing type for gtksocket, but not for tmp.

1 Like

To me this doesn't make sense. Unwrap knows what type I'm expecting it to unwrap to.

unwrap knows, of course, but from_glib_full doesn't. All that it knows is that the target type implements FromGlibPtrFull<*mut gtk::Socket> - that's not enough.

1 Like

Fair enough. Could you please give an example how to properly structure that call so it compiles?

Without knowing the available implementations for FromGlibPtrFull<*mut gtk::Socket> (or at lease the crate where it's from, if it's in the dependency) - I'm afraid not. The obvious way is to just drop unwrap(), since by your code it looks like from_glib_full would already return what you need, but I guess that there's something we don't know that makes this impossible.

You could try

let gtksocket: *mut GtkSocket = Option::unwrap(from_glib_full(gtk_socket));

or

let gtksocket: *mut GtkSocket = from_glib_full::<_, Option<_>>(gtk_socket).unwrap();

or

use glib::translate::FromGlibPtrFull;

// ……
let gtksocket: *mut GtkSocket = Option::from_glib_full(gtk_socket).unwrap();

and those approaches might work.

3 Likes

Hi, thanks.
I never saw Option being used that way. Very interesting.
Thanks