> "Allows more operations" seems like a straightforward meaning for "different semantics" to me. In Safe Rust, you can't access union members. In Unsafe Rust you can
The semantics are the same. The meaning of the operation is same. In both safe and unsafe accessing union members is the same operation with the same meaning. The only difference is that in unsafe Rust you are allowed do this. This is a difference in permission, not meaning
The meaning of the operation is not the same, because it is not an operation in Safe Rust.
"Allows more operations" seems like a straightforward meaning for "different semantics" to me. In Safe Rust, you can't access union members. In Unsafe Rust you can.
I agree that it's a little fanciful, but I also don't think it's really wrong.
> To suggest that this means that the language itself has infinite sublanguages obscures its actual sublanguages, such as the built-in macro-rules DSL.
In many languages, the macro language is either homoiconic or nearly homoiconic. In Crystal, for example, the macro DSL looks like normal Crystal, but with a few extra sigils. You can't invent new syntax in it.
When we talk about understanding C we generally take that to include the C preprocessor, despite the latter being a conceptually separate macro language. I think the same standard (except much, much better) applies to procedural macros in Rust: you need to understand a separate set of token production and consumption rules that interact but do not align with Rust's core syntax.
> This is a misunderstanding of the reference manual
I wasn't referring to the production rules themselves; I'm aware they're on most pages. I was referring to the fact that the attribute language is explicitly taken directly from a separate language (C#).