Are all Rust attributes Macros? - rust

Are all attributes in Rust implemented as Macros? Or some native attributes are created specially by the compiler/language and does not use the Macros mechanism?
If there are attributes not created via Macros, how do I identify them?

There are many attributes that are not macros and are treated specifically by the compiler. Examples: #[cfg] (although this one can be considered as a macro, even if not implemented as one), #[repr], #[doc], #[allow(...)]/#[warn(...)]/#[deny(...)]/#[forbid(...)], and many more.
I don't know a way to identify such attributes except to look at the list of builtin macro attributes and see if they're there.

Related

Is it necessary to use macros while developing substrate runtime in rust?

I am so surprised when I look into the substrate-relevant project code. It's so hard to understand, runtime macros everywhere.
Now, It's easier for you to develop your own blockchain base on the Substrate framework. The most difficult section might be how to make rustc accept your code.
It is not necessary to use the macros to develop on Substrate. As you may know, the macros ultimately expand to be real rust code, so if you understand the inner working of Substrate at that level, then of course you can write that code yourself, but this will certainly not be as easy as using the macros.
I believe the macros expand to about 3x the lines of code as you write, and contains logic that we try to keep opaque from the average runtime developer.
It is a fair criticism that the runtime macros can be hard to debug or work with, but we are looking to solve this issue by using Rust attribute macros and staying closer to traditional Rust syntax.
See the tracking issue here: https://github.com/paritytech/substrate/issues/5678

How can I implement complicated macros like `format_args!` in user space?

I like that Rust comes with a lot of macros which moves computation to compile-time instead of repeatably to run-time.
print! and all its variants using format_args! See source code are great examples.
Unfortunately, in the source code you see the comment /* compiler built-in */ instead of a implementation direct in the source file.
Does Rust have the capability to let the user write such complex logic as a macro as well? If so, how can I do so?
Complex macros are usually implemented as procedural macros, which you can learn more about in The Rust Programming Language or in The Rust Reference books.
You can also achieve very complex things with the so called declarative macros, look at the excellent The Little Book of Rust Macros.
There are several talks about these on YouTube, but you may find the following in particular very interesting, which was given at the RustConf 2018, My Little Procedural Macro by Chris Wong:

Can I use the Rust lexer or parser to retrieve a list of functions within a Rust file?

The lexer/parser file located here is quite large and I'm not sure if it is suitable for just retrieving a list of Rust functions. Perhaps writing my own/using another library would be a better route to take?
The end objective would be to create a kind of execution manager. To contextualise, it would be able to read a list of function calls wrapped in a function. The function calls that are within the function will then be able to be re/ordered from some web interface. Thought it might be nice to manage larger applications this way.
No. I mean, not really. Whether you write your own parser or re-use syntex, you're going to hit a fundamental limitation: macros.
So let's say you go all-out and expand macro_rules!-based macros, including the ones defined in external crates (which means you'll also need to extract rustc's crate metadata loading... which isn't stable). What about procedural macros and custom derive attributes? Those are defined in code and depend on compiler-internal interfaces to function.
The only way this is likely to ever work correctly is if you build on top of the compiler, or duplicate a huge amount of work (which also involves unstable binary interfaces).
You could use syntex to parse the Rust code in a build script.

How to embed resources in Rust executable?

This is the cousin of this question over here asking the same thing for C.
Basically, is there a better way than to just turn it into a giant byte array and putting it in a source file?
Alternatively, does a macro have the ability to do this? (Rust Macros... are a dense looking and their exact capabilities are not known to me.)
You probably want include_bytes!.
If you are in older versions of Rust, use include_bin! instead.
You could alternatively use this tool https://github.com/pyros2097/rust-embed Which was created by me which generates rust code for your resources.

template instantiation statistics from compilers

Is there a way to get a summary of the instantiated templates (with what types and how many times - like a histogram) within a translation unit or for the whole project (shared object/executable)?
If I have a large codebase and I want to take advantage of the C++11 extern keyword I would like to know which templates are most used within my project (or from the internals of stl - like std::less<MyString> for example).
Also is it possible to have a weight assigned to each template instantiation (time spent by the compiler)?
Even if only one (c++11 enabled) compiler gives me such statistics I would be happy.
How difficult would it be to implement such a thing with Clang's LibTooling?
And is this even reasonable? Many people told me that I can reason which template instantiations I should extern without the use of a tool...
There are several ways to attack this problem.
If you are working with an open-source compiler, it's not hard to make a simple change to the source code that will trace all template substantiations.
If that sounds like too much hassle, you can also try to force the compiler to produce a warning on each template instantiation for a given symbol. Steven Watanabe has written a set of tools that can help you with that.
Finally, possibly the best options is to use the debugging symbols (or map files), generated by the compiler, to track down how many times each function appears in the final image and more importantly how much does it add to the weight in bytes. The best example for such a tool is Andrian Stone's SymbolSort, which is based on the Microsoft's toolset. Another similar tool is the Map File Browser.

Resources