Hello! I'm doing Scanning · Crafting Interpreters but with Rust
While implementing the Scanner
type, I got into this problem
pub struct Scanner<'a> {
chars: Peekable<Chars<'a>>,
tokens: Vec<Token>,
errors: Vec<usize>,
line: usize,
}
impl<'a> Scanner<'a> {
pub fn new(source: &str) -> Scanner {
Scanner {
chars: source.chars().peekable(),
tokens: vec![],
errors: vec![],
line: 1,
}
}
This does compile, but if I try this
pub struct Scanner<'a> {
chars: Peekable<Chars<'a>>,
tokens: Vec<Token>,
errors: Vec<usize>,
line: usize,
}
impl<'a> Scanner<'a> {
pub fn new(source: &str) -> Self {
Scanner {
chars: source.chars().peekable(),
tokens: vec![],
errors: vec![],
line: 1,
}
}
It does not. Can someone explain the difference to me? I thought that Self
and the name of the type were interchangeable.
chrisd
October 21, 2019, 12:36am
2
What does the error message say?
on the second case
error[E0621]: explicit lifetime required in the type of source
--> src/lox/scanner.rs:33:9
|
32 | pub fn new(source: &str) -> Self {
| ---- help: add explicit lifetime `'a` to the type of `source`: `&'a str`
33 | / Scanner {
34 | | chars: source.chars().peekable(),
35 | | tokens: vec![],
36 | | errors: vec![],
37 | | line: 1,
38 | | }
| |_________^ lifetime `'a` required
leudz
October 21, 2019, 12:44am
4
Hi, it's because in the first case, the compiler will infer the lifetime:
fn new<'s>(source: &'s str) -> Scanner<'s>
But Self
already has a lifetime named 'a
. The error message suggests you explicit the lifetime of source
.
fn new(source: &'a str) -> Self
1 Like
Ooh, that makes sense! Self is subtituing for Scanner<'a>
here, so I need to tell the compiler that source has that same lifetime. While with Scanner
, he infers that!
Thanks @leudz !
1 Like
Another way to solve this would be to follow the compiler's instructions and bind the input string to 'a
impl<'a> Scanner<'a> {
pub fn new(source: &'a str) -> Self {
Self {
chars: source.chars().peekable(),
tokens: vec![],
errors: vec![],
line: 1,
}
}
}
3 Likes
This is what I ended up going with, but I didn't understand the need to do so untill now
1 Like
Yandros
October 21, 2019, 12:08pm
8
You can add the #![deny(elided_lifetimes_in_paths)]
lint to your project to better catch the hidden lifetime in Scanner
-like structs
1 Like
system
Closed
January 19, 2020, 12:08pm
9
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.