Why the code can't be compiled, another question

I can't understand:

#[test]
fn a() {
    fn t<'a>(_f: fn(&'a String) -> &'a String) {
        let s = "1".to_owned();
        _f(&s);
    }
}

fails, saying s still borrowd after drop.

It even fails when I manually drop the returned reference.

#[test]
fn a() {
    fn t<'a>(_f: fn(&'a String) -> &'a String) {
        let s = "1".to_owned();
        let k = _f(&s);
        drop(k);
    }
}

Well, for example if you were to call t<'static>, then the method requires you to pass in a &'static String, but your string does not live forever. The syntax you are looking for is:

#[test]
fn a() {
    fn t(_f: for<'a> fn(&'a String) -> &'a String) {
        let s = "1".to_owned();
        _f(&s);
    }
}
2 Likes

Ok, I accept this.

Another question:
Docuement says, fn(T) -> U, T is contra-variant and U is covariant. And, if T == U, e.g. fn(T) -> T, It is invariant, because it is the only choice to satisfy contra-variant and covariant at the same time.

But, the following code, T == &'a String. then _f should be invariant, right?
So t should not accept x1, and compiling should fail.
However, it is compiled. Why?

#[test]
fn a() {
    fn t(_f: for <'a> fn(&'a String) -> &'a String) {
        let _s = "1".to_owned();
        println!("accept _f");
        _f(&_s);
    }

    fn x1<'a>(_s: &'a String) -> &'static String {
        println!("in _f");
        let b = Box::new(String::from("111"));
        unsafe { &*Box::into_raw(b) }
    }
    t(x1);
}

You are going from T = &'a String, U = &'static String to T = U = &'a String, and there's no issue with that.

1 Like

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.