Compiler swears again

How to solve this problem (if possible)? I want to create a function that reads json, parses the borrowed object, then converts it to owned using a higher order function. Looks like everything is legal here? I tried different ways but I can't compile this code.

use serde::Deserialize;

#[derive(Deserialize)]
struct Borrowed<'s> {
    s: &'s str,
}

struct Owned {
    s: String,
}

fn load<L, B>(to_owned: L) -> Owned
where
    L: FnOnce(B) -> Owned,
    B: Deserialize<'?>, // or DeserializeOwned?
{
    let buf = String::from(r#"{ "s": "a" }"#);
    let b = serde_json::from_str(buf.as_str()).unwrap();
    to_owned(b)
}

fn main() {
    let owned = load(|b: Borrowed| Owned { s: b.s.to_owned() });
    println!("{}", owned.s);
}

(Playground)

In the future please include the error message.

Especially in this case have you tried following the instructions that the compiler gave?

1 Like

This playground shows how you would do it, but unfortunately I encountered an ICE. There might be a way to work around it, I'm not sure. See this thread for an explanation of how it works.

1 Like

This compiles and runs properly: Rust Playground. Basically the idea is to separate out all the parts that require access to 'de into a trait, and then use for<'de> on that trait once.

edit: You can even hide the implementation details: Rust Playground

7 Likes

Can I abstract from the Borrower? I need to call an abstract function FnOnce(B) -> O where B is any borrower and O is any owned type. But only the borrower causes compilation problems, so in my example I abstracted from it. Implementation with concrete types has no problems.

I need an abstract type because I write many different loaders for different types. And to re-implement them all, I have to copy huge chunks of code.

Thanks, this is what I wanted :blush:
Only the internal error saddens me

Not until we get GATs, they are required to properly simulate lifetime parameters in generic types. For now, you could use a macro to generate the boilerplate

1 Like

What is GAT and where can I find out about them?

UPD: I found this rfcs/1598-generic_associated_types.md at master · rust-lang/rfcs · GitHub

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.