100-exercises-to-learn-rust icon indicating copy to clipboard operation
100-exercises-to-learn-rust copied to clipboard

More explanation about lifetime syntax

Open v-p-b opened this issue 11 months ago • 2 comments

First of all thanks for the exercises, it's great resources are available online!

I open this issue because I think some crucial explanation is missing when lifetimes are introduced, but I'm not sure if an explanation exists in the Rust ecosystem in general (I discussed this with our local Rust Evangelist, who couldn't point me to a reassuring answer either). I get that lifetimes are complex, but my concern is mainly about the syntax one should use to express lifetime constraints, assuming full understanding of the concept of lifetimes and program logic.

Say we want to solve exercise 6.16 - BTreeMap, where we are supposed to implement an IntoIterator. Let's say we also figured out the IntoIter type based on the official docs:

impl IntoIterator for &TicketStore {
    type Item = &Ticket;
    type IntoIter = std::collections::btree_map::Values<'a, TicketId, Ticket>;

    fn into_iter(self) -> Self::IntoIter {
        self.tickets.values()
    }
}

(The above code also assumes that one figures out that (despite IntoIter is specified with Ticket) Item should be &Ticket)

The compiler gives the following error:

error[E0261]: use of undeclared lifetime name 'a

... and suggests to introduce the lifetime in impl. (Note that the other compiler suggestion leads to a deep rabbit hole!)

impl<'a> syntax is mentioned here in the Rust Book, but nowhere in the Exercise Book:

  • https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-annotations-in-method-definitions

As I understand this notion is not relevant to actual lifetimes of memory structures, but is only a syntactic element that introduces the lifetime identifier. After introducing the lifetime the compiler gives the following error:

error[E0207]: the lifetime parameter 'a is not constrained by the impl trait, self type, or predicates

"Error example 4" in rustc --explain E0207 matches this exact case, but gives no resolution except pointing to the RFC, that has no mention of lifetimes at all!

The only "solution" I found is to get a hint from the "impl trait, self type or predicates" E0207 error and try to squeeze lifetime parameters around &TicketStore, but even the Rust Book doesn't have mention of the &'a TicketStore syntax that should be used here based on the provided solution.

I think it'd spare a lot of frustration if the expected syntax elements would be at least briefly described, preferably with links to further explanations about their roles.

v-p-b avatar Jan 09 '25 11:01 v-p-b

FYI, filed https://github.com/rust-lang/rust/issues/135589 to improve the error output from the compiler.

estebank avatar Jan 16 '25 17:01 estebank

I'd like to once again thank @estebank for picking this up! I believe https://github.com/rust-lang/rust/pull/135604 (now merged to master) is a major step forward to make the solution to the exercise problem discoverable.

v-p-b avatar Jan 17 '25 11:01 v-p-b