`'r#static` is not a valid lifetime

Some fun trivia.

TIL that some raw identifiers are not allowed when thinking of some edge-case inputs to feed to macros. (My initial reaction was confusion, since I thought the whole point was to allow any keyword to be valid as a raw identifier). Naturally, I then explored more of the possibilities. In particular, when it comes to lifetime identifiers, as far as I'm aware, 'r#static, 'r#crate, 'r#self, 'r#Self, 'r#super, and 'r#_ are the only invalid raw lifetime parameters.

This does not match the list of RESERVED_RAW_LIFETIMEs in the Rust Reference, which does not include 'r#static.

The precise wording of the reference is that "Unlike a normal lifetime, a raw lifetime may be any strict or reserved keyword except the ones listed above for RAW_LIFETIME". ("The ones listed above" are the ones in RESERVED_RAW_LIFETIME.) Since static is a weak keyword which is restricted for lifetimes (not a strict or reserved keyword), static then cannot be used for raw lifetime parameters either.

Sort of cool.

I also now know that derive(yoke::Yokeable) does not handle raw identifiers very well. This makes me somewhat worried about whether derive macros for unsafe traits, likely using syn to parse input without meticulously using Ident::unraw everywhere, manage to handle everything soundly, especially since you can introduce a lifetime as 'r#a and use it as 'a... that is, a lifetime can refer to a lifetime parameter even if they are not equal (as Idents). Also, even quote doesn't support raw lifetimes (though it does support raw identifiers in most places).

I'm very glad that 'r#static is not a valid lifetime parameter; it places a limit on how unsuspecting derive macros for unsafe traits can be tricked.

(Note: I previously forgot to add the word “parameter”. 'r#static is still valid and acts like 'static.)

4 Likes

ROFL, David Tolnay fixed and closed an issue I opened on quote within ten minutes of me opening it.

So.... I take it back, quote does support raw lifetimes.

I'm actually dying of laughter.

12 Likes

I read the original post and then saw the PR get merged in my feed and was thinking to myself, "wow, that was fast".

Based on my testing, it seems that 'r#static is a valid lifetime, but behaves exactly like 'static.

I tried everything, but I couldn't get rust to parse a 'r#$crate lifetime lol

Oops, you’re right, I meant that it’s not a valid lifetime variable / generic lifetime parameter.