Why `self` and `super` are not keywords in rustc parser?


#1

In rustc parser self and super are not keywords, but instead just special identifiers. There are several consequences of this. For example, foo :: bar is a valid path, but self :: bar is not :wink:

The more interesting effect is that parser admits bogus paths like foo::super::self::baz, but they are ruled out during resolve. Actually, they are not even forbidden, but just fail to resolve because you cannot name an item “self” or “super”. If, self and super are proper keywords, this constraint could be easily enforced during syntax analysis.

So my question is what are the benefits of treating self and super as identifiers?


#2

First of all, it makes Rust a language with less magic. Magic that makes a language less understandable and complicated.
If you look at languages like Java it is often unclear why something works or what it does in the background. For example this. Where is it stored and why does it work? Rust doesn’t have that problem at all. self is just a convenient method of writing self: Self. To be exact, it is just a parameter to a function. As opposed to Java where all this is hidden in the language itself and you have to look for it to find the answer.

Second, you don’t need to use self.
Theoretically if you write a function that gets passed to instances of the struct, you can just reuse that function and call it with two parameters or in the form instance.function(&other). That is called Universal Function Call Syntax.

And lastly, I prefer the rusty style. Rust is a systems language and therefore must be understandable in a way so that the developer can, at any time, tell what the program is doing exactly, how the memory layout looks and why they can or cannot do something.
If a function is declared:

// "&self" is shorthand syntax for "self: &Self"
fn do_something(self: &Self) {
    // do something with self
}

I know that the variable is passed as a immutable reference and that the function gets it as an argument.
In Java:

void do_something() {
    // do something with this
}

I cannot possibly know if the function is attached to the object and therefore where it lives in memory and what side-effects this can have.

Also it’s magic and I don’t like magic. It makes everything complicated.

Edit:

You might also want to read that.


#3

Hm, I must have formulated my question in a somewhat obscure way.

I am not asking about the language itself, I’m asking about a concrete implementation of the language, namely rustc. In particular I wonder why self and super inside the compiler are treated as special identifiers, and not as keywords.

And regarding the language, I do think that Rust’s self is really super :slight_smile:


#4

Oh, okay, so then I cannot help you I’m afraid.

But I think that might be somewhat more suitable for
internals.rust-lang.org.


#5

They are keywords, they are just treated as identifiers… sometimes.
I suppose most of these strange things in their behavior are idiosyncrasies of rustc_resolve and parser, not deliberate design choices.