我的借用检查器是不是出了问题?

4

引用必须对50:74处的块有效... ...但是借用值仅对50:74处的块有效

好的,那么问题出在哪里呢?

涉及到的块为:

pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
    let c = format!("git-upload-pack {}\0host={}\0", self.repo.path, self.repo.domain);

    let mut out = String::new();
    let data = try!(self.command(c.as_slice()));

    for line in data.iter() {
        out.push_str(from_utf8(line.as_slice()).unwrap());
    }

    Ok(out)
}

self.command:

fn command(self: &mut GitConnect, command: &str) -> Result<Vec<Vec<u8>>, &str> {

完整的错误信息如下:
src/protocol/git_connect.rs:54:38: 54:39 error: `c` does not live long enough
src/protocol/git_connect.rs:54         let data = try!(self.command(c.as_slice()));
                                                                    ^
<std macros>:1:1: 6:60 note: in expansion of try!
src/protocol/git_connect.rs:54:20: 54:53 note: expansion site
src/protocol/git_connect.rs:50:75: 61:6 note: reference must be valid for the anonymous lifetime #1 defined on the block at 50:74...
src/protocol/git_connect.rs:50     pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
src/protocol/git_connect.rs:51         let c = format!("git-upload-pack {}\0host={}\0", self.repo.path, self.repo.domain);
src/protocol/git_connect.rs:52 
src/protocol/git_connect.rs:53         let mut out = String::new();
src/protocol/git_connect.rs:54         let data = try!(self.command(c.as_slice()));
src/protocol/git_connect.rs:55 
                               ...
src/protocol/git_connect.rs:50:75: 61:6 note: ...but borrowed value is only valid for the block at 50:74
src/protocol/git_connect.rs:50     pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
src/protocol/git_connect.rs:51         let c = format!("git-upload-pack {}\0host={}\0", self.repo.path, self.repo.domain);
src/protocol/git_connect.rs:52 
src/protocol/git_connect.rs:53         let mut out = String::new();
src/protocol/git_connect.rs:54         let data = try!(self.command(c.as_slice()));

self.command 的签名是什么? - Vladimir Matveev
另外,您能否提供您的函数完整代码,包括其签名?这可能很重要。 - Vladimir Matveev
1个回答

3

在我看来,这似乎是一个bug。

这个签名:

fn command(self: &mut GitConnect, command: &str) -> Result<Vec<Vec<u8>>, &str>

根据生命周期省略规则,应该等同于以下内容:
fn command<'a, 'b>(self: &'a mut GitConnect, command: &'b str) -> Result<Vec<Vec<u8>>, &'a str>

实际上,如果你重写你的command()函数来使用这个扩展形式,它应该可以编译通过。同时,如果你使用了缩写的self参数定义:

fn command(&mut self, command: &str) -> Result<Vec<Vec<u8>>, &str>

然后它也进行编译。

目前似乎

fn command(self: &mut GitConnect, command: &str) -> Result<Vec<Vec<u8>>, &str>

等同于

fn command<'a>(self: &'a mut GitConnect, command: &'a str) -> Result<Vec<Vec<u8>>, &'a str>

由于存在生命周期错误,因此对于正确的原因,会为command参数提供完全相同的错误:断言command参数的生命周期与self相同,因此它将无法与生命周期较短的局部变量一起使用,其寿命将短于self


我在你发帖之前就想通了 - 你几乎是对的,除了 Result &str 的生命周期与输入无关。具体来说,它是 &'static str。看起来是将 Result &str 赋予了与 command 参数相同的生命周期。 - J V
根据您的签名和省略规则,它确实与输入相关。 - Vladimir Matveev
顺便说一句,我已经在这里提交了一个问题(https://github.com/rust-lang/rust/issues/21400)。 - Vladimir Matveev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接