Borrow checker and function arguments in Rust, cor

2019-01-12 07:51发布

When a mutable argument is passed as a function argument, the borrow checker doesn't allow this to be used to construct other arguments, even when those arguments clone values without holding a reference.

While assigning variables outside the function is always an option1, logically this seems over zealous and something the borrow checker could take into account.

Is this working as intended or something that should be resolved?

#[derive(Debug)]
struct SomeTest {
    pub some_value: f64,
    pub some_other: i64,
}

fn some_fn(var: &mut SomeTest, other: i64) {
    println!("{:?}, {}", var, other);
}

fn main() {
    let mut v = SomeTest { some_value: 1.0, some_other: 2 };
    some_fn(&mut v, v.some_other + 1);

    // However this works!
/*
    {
        let x = v.some_other + 1;
        some_fn(&mut v, x);
    }
*/
}

Gives this error:

  --> src/main.rs:14:21
   |
14 |     some_fn(&mut v, v.some_other + 1);
   |                  -  ^^^^^^^^^^^^ use of borrowed `v`
   |                  |
   |                  borrow of `v` occurs here

See: playpen.


[1]: Even though one-off assignments do sometimes improve readability, being forced to use them for arguments encourages use of scopes to avoid single use variables polluting the name-space, causing function calls that would otherwise be one line - being enclosed in braces and defining variables... I'd like to avoid this if possible especially when the requirement seems like something the borrow checker could support.

1条回答
狗以群分
2楼-- · 2019-01-12 08:38

This is an artifact of the current implementation of the borrow checker. It is a well known limitation, dating back to at least 2013, and no one is overjoyed by it.

Is this working as intended

Yes.

something that should be resolved?

Yes.

The magic keywords are "non-lexical lifetimes". Right now, lifetimes are lexical - they correspond to the blocks of source that we type. Ideally, foo.method(foo.mutable_method()) would see that the borrow ends "inside the parenthesis", but for a myriad of reasons, it is tied to the entire statement.

For tons of further information see RFC issue 811 and everything linked from there.

查看更多
登录 后发表回答