What does pub struct CrateId { ENCODABLE = custom } mean?

On Rust's compiler I found this: rust/def_id.rs at 5065144d6db9b116ad67d37d081e0c13f7ee29d5 · rust-lang/rust · GitHub

rustc_index::newtype_index! {
    pub struct CrateId {
        ENCODABLE = custom
    }
}

What does this ENCODABLE = custom mean?

I have no idea and haven't seen such thing in ordinary rust code.

This code is being provided to a macro defined here.

It's inside a macro call; it's matched on by the macro. This is maybe the place.

I didn't new rust macros could match against things inside a struct

what are the things in @?

(@attrs        [$(#[$attrs:meta])*]
     @type         [$type:ident]
     @max          [$max:expr]
     @vis          [$v:vis]
     @debug_format [$debug_format:tt]

If you look higher up in the macro definition, it's making recursive calls to itself and inserting those @whatevers as markers which it again matches against.

A macro can match any syntax that is a sequence of valid Rust tokens and has balanced ()[]{} brackets. You can freely invent new syntax in your macros within those constraints, as long as the macro expands to valid Rust code.

2 Likes

but I'm confused. These markers are pure text then just to be matched? Or do they matter? It's Rust code or simple text?

They're tokens, like @jdahlstrom said. They don't have to be anything that's valid rust outside of a macro invocation. In this case the markers are just matched like text. Here's a section on them in the reference, including a grammar.

I've never found a great guide to these and just sort of reasoned them out and cargo-cult when I need to, so I'm afraid I don't have a better references. Perhaps someone else can suggest a good guide.

Or just play around and try to see what's possible. Macro-related errors aren't the best though (largely due to their flexibility no doubt), so this can be a slow or frustrating process.

It's not valid Rust code. In fact, that's the whole point of using macros. They provide syntax extensions to the language, without actually needing to change the language itself.

You can think up any kind of crazy-moon syntax you please, and as long as it has balanced parentheses, you can write a macro for parsing it, and you can then transform it to something that will in fact be valid Rust code.

1 Like