I've just read this article in the Nomicon. In the example they copy for optimisation purposes the u32 value into a local variable, because it shall be - according to the Nomicon - available in a register.
I know that registers are much faster than stack or heap memory but how can I be certain that the compiler uses a register for a variable? Are there any rules or something which you could keep in mind here?
You technically can't be sure, as the language has no concept of registers. That section of the Nomicon is really only using rust syntax to talk about the lower-level impact of the language's aliasing rules, it's not explaining the semantics of the language itself when its talking about registers or loading things to them from memory. The language sees all memory as uniform and the distinction that matters is values and references - semantically even the only difference between the stack and heap is the lifetime of the values.
However, in practice, the compiler (and LLVM) is very good at optimisation, and it will put things in registers where possible, or even better, completely eliminate moves where that's possible. (Including by inlining function bodies into their callers) The only caveat that springs to mind where the author might lead it into suboptimal choices is passing very small values by reference, which clippy will flag for you.
Significantly, unlike in languages like C# or Java, struct values do not have an observable identity as a holistic "object" that forces the compiler to keep them together (and in memory) when they are passed as a parameter to a function. If you have a struct that has four
u32 fields and you pass it as a function parameter, the compiler has no issue with taking the struct apart, putting the fields seperately into registers, and generating the function body so accessing those fields use the registers directly, without any need to even "reassemble" them in memory.
Ok I understand. So they say that in this article just for for explanation purposes. Thanks for the clarification!