1 min read

Distinguishing abstract lifetimes from concrete lifetimes in Rust

Rust sometimes requires you to parameterize functions and structs to specify lifetimes. Confusingly, these work like type variables rather than types. They are abstract. In fact the concrete lifetime of a value is never explicitly designated.

Here's an illustrating example from the Rust book, the function longest() that returns the longest of the two strings passed. The return value must have a lifetime that is the same as the shorter of the two lifetimes. You might think you would have to explicitly say it has the shorter of the two, but no. Instead, you specify the two reference parameters have the same abstract lifetime. This doesn't require them to have the same concrete lifetime. Instead it means that the 'a lifetime will resolve to the shorter of their concrete lifetimes.

This is kind of like how a function, say, foo<T>(x: T, y: T) -> T can be called with two values of different concrete types (say i16 and i32) as long as they share some common supertype that we can substitute for T (say Into<i64>). This doesn't apply in Rust itself, I think, because the only "supertypes" that exist are traits and it would be invalid for foo() to return an unboxed trait object, but it makes sense in other languages.