Function vs closure argument lifetime inference

struct MutRef<'a, T: 'a> {
    inner: &'a mut T,

fn fix<F, T>(f: F) -> F
    where F: Fn(&mut T) -> MutRef<T>

fn main() {
    let x = |s: &mut String | -> MutRef<String> {
        MutRef { inner: s }

    let fx = fix(|s: &mut String | -> MutRef<String> {
        MutRef { inner: s }
    fn y(s: &mut String) -> MutRef<String> {
         MutRef { inner: s }
    // doesn't compile: E0495
    // let mut s = String::from("hi");
    // println!("{:?}", x(&mut s));
    // doesn't compile on stable: E0271
    let mut t = String::from("hello");
    println!("{:?}", fx(&mut t));
    let mut u = String::from("how are you");
    println!("{:?}", y(&mut u));


playground link:

I thought I knew most of how rust works at this point, but this has been stumping me. why do x and y seemingly have different inferred lifetimes? what changed recently to allow fix() to work in nightly and beta but not stable?


It looks like the reborrow issue:


There are known issues with how lifetimes are inferred/bound in closures - I think this is an example of that. Generally the workaround is to use functions, instead of closures, to bind lifetimes properly.

These issues are a particularly unfortunate papercut precisely because they don’t make sense and leave one with the “I thought I understood Rust but …” sentiment. Hopefully this will be resolved in the not too distant future.