> What can Rust macros do that C++ TMP (and macros even though that's a last resort IMHO...) can't do?

Rust has two kinds of macro with very different properties, so lets talk about that briefly (reader: if you are here to learn about this C++ Proposal paper then er, bye?)

1. The macro_rules! "By example" macros. These are a bit like the simpler C macros you might have used, except that they really care about syntax and aren't just gluing text together without understanding it. These macros are hygienic (if a macro uses its own variable named "count" and your function has a variable named "count" Rust knows those are different variables and everything works fine whereas with a C or C++ macro that will cause trouble) and they're fairly powerful for solving those annoying "Don't Repeat Yourself" problems in programming when you can't quite factor out the repetition in the Rust code per se.

These macros are very safe, I would trust a novice to write and use them, worst case maybe you need to show the novice how to ask Rust to apply the macro and show the results so they can see what they screwed up, because e.g. "suck it and see" doesn't work very well to figure out what you did wrong writing a macro.

2. Procedural ("proc") macros. There are several specific flavours of proc macro but they're all Rust code, which you wrote, running inside the compiler during the build, taking bits of the program syntax tree as input parameters.

This can do anything. For example Mara wrote whichever_compiles! a proc macro which forks the compiler, attempting each of the options you supplied, once one of them compiles the other compilers die and the survivor presses on compiling the rest of your program. It's deeply regrettable that this is possible, but it is. Only experts should touch proc macros, and they should obviously not do anything crazy unless (like Mara) they are doing so as a joke.

So, proc macros can do a lot more than C++. Perhaps more than they should do, but more.

> I feel like "interfaces" as in pure abstract virtual classes can achieve the same effect as Rust traits

C++ traits are roughly in the same space as C++ 0x Concepts. You might think aha, we have C++ 20 Concepts. Unfortunately C++ 20 Concepts is a pale shadow.

Traits does a few important things (possible to some extent in C++ 0x Concepts) which C++ 20 Concepts can't do. In particular, it has semantic weight because the concepts must be explicitly implemented. In C++ two concepts with the same syntactic requirement are functionally identical. The ISO document says using a concept which is not correctly "modelled" means your program is ill-defined (might do anything) but in practice the code compiles and everything seems OK. In Rust even though there's no syntactic difference between PartialEq and Eq, the types which don't explicitly implement Eq are not Eq. That is, you can programmatically ask, "Is a == b an equivalence relation?" whereas in C++ all you can actually ask is "Can I write a == b ?"

More directly practically, Rust actually checks Traits whereas in C++ there is no checking.

e.g. if you try to sum() a Vec of u32s that will work, but if you try to do that to a Vec of Strings there is no such function, the Sum Trait isn't implemented for Strings.

You could do this in C++ but it's much easier not to, and so most software doesn't and then your users are fed a lot of SFINAE compiler errors which choke them to death. In Rust it's mandatory to spell out the required Traits.