由于需求冲突,无法推断autoref的适当生命周期

时间:2017-09-15 18:37:50

标签: parsing rust lifetime

我正在Rust中编写HTTP解析器。所有输入都是ASCII,所以我只使用&[u8]来迭代字节。

#[derive(Debug)]
pub enum ParseError {
    Method,
    OutOfBound,
}

struct Bytes<'src> {
    source: &'src [u8],
    i: usize, //current position in the source
}

impl<'src> Bytes<'src> {
    fn next(&mut self) -> Option<u8> {
        if self.source.len() > self.i + 1 {
            self.i += 1;
            Some(self.source[self.i - 1])
        } else {
            None
        }
    }

    fn until(&mut self, stop: u8) -> Result<&[u8], ParseError> {
        let start = self.i;
        while let Some(ch) = self.next() {
            if ch == stop {
                return Ok(&self.source[start..self.i - 1]);
            }
        }

        Err(ParseError::OutOfBound)
    }
}

此功能:

use std::str;

fn uri<'str>(bytes: &mut Bytes<'str>) -> Result<&'str str, ParseError> {
    let until = try!(bytes.until(b' '));
    unsafe { Ok(str::from_utf8_unchecked(until)) }
}

产生错误:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/main.rs:37:28
   |
37 |     let until = try!(bytes.until(b' '));
   |                            ^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 36:1...
  --> src/main.rs:36:1
   |
36 | / fn uri<'str>(bytes: &mut Bytes<'str>) -> Result<&'str str, ParseError> {
37 | |     let until = try!(bytes.until(b' '));
38 | |     unsafe { Ok(str::from_utf8_unchecked(until)) }
39 | | }
   | |_^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:37:22
   |
37 |     let until = try!(bytes.until(b' '));
   |                      ^^^^^
note: but, the lifetime must be valid for the lifetime 'str as defined on the function body at 36:1...
  --> src/main.rs:36:1
   |
36 | / fn uri<'str>(bytes: &mut Bytes<'str>) -> Result<&'str str, ParseError> {
37 | |     let until = try!(bytes.until(b' '));
38 | |     unsafe { Ok(str::from_utf8_unchecked(until)) }
39 | | }
   | |_^
note: ...so that expression is assignable (expected std::result::Result<&'str str, _>, found std::result::Result<&str, _>)
  --> src/main.rs:38:14
   |
38 |     unsafe { Ok(str::from_utf8_unchecked(until)) }
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

这很奇怪,因为'until'引用了一个函数参数,所以我认为这不应该是一个问题。

更奇怪的是,当我直接索引字节时,它会编译。

fn uri<'str>(bytes: &mut Bytes<'str>) -> Result<&'str str, ParseError> {
    unsafe { Ok(str::from_utf8_unchecked(&bytes.source[20..30])) }
}

为什么?

0 个答案:

没有答案