1
votes

I need to create NewType wrappers for interfacing with FFI. I want to create an interface similar to Rust's String and str types, so I can have a wrapper for an owned type, and a wrapper for a reference. Because some times I'm dealing with references that came from raw pointers that the FFI library will free, and other times I need to take ownership so that rust will free the memory. I want to be able to easily use the methods on the reference type by implementing AsRef on the owned type, but I'm having an issue with lifetimes.

playground

pub struct MyInt(i64);

pub struct MyIntRef<'a>(&'a i64);

impl AsRef<MyIntRef<'_>> for MyInt {
    fn as_ref(&self) -> &MyIntRef<'_> {
        todo!()
    }
}

This code fails to compile with the following error:

= note: expected `fn(&MyInt) -> &MyIntRef<'_>`
           found `fn(&MyInt) -> &MyIntRef<'_>`

The error seems to indicate that I do have the correct signature. Why is this failing?

1
The immediate problem is that '_ means two different lifetimes in the two places you have it, but beyond that, how exactly do you intend to fill in that todo!()? You can't create a MyIntRef inside the function and return a reference to it. Take another look at the relationship between str and String -- note that neither of them has a lifetime parameter.trentcl
Also, you can look at the implementation of CString and CStr, (str is a primitive type, but CStr is pure Rust).rodrigo
It would help if you showed how is the C API you are trying to wrap. I'm guessing that the i64 in your snippets is a placeholder.rodrigo

1 Answers

0
votes

I think you've just got your trait parameter type mixed up.

pub struct MyInt(i64);

pub struct MyIntRef<'a>(&'a i64);

impl AsRef<i64> for MyInt {
    fn as_ref(&self) -> &i64 {
        &self.0
    }
}

impl<'a> AsRef<i64> for MyIntRef<'a> {
    fn as_ref(&self) -> &i64 {
        self.0
    }
}