Rust uses the C++20 memory ordering semantics.
If one evaluation modifies a memory location, and the other reads
or modifies the same memory location, and if at least one of the
evaluations is not an atomic operation, the behavior of the program
is undefined (the program has a data race) unless there exists a
happens-before relationship between these two evaluations.
So, is there then a happens-before relationship between the store of 92 and the read?
Happens-before
Regardless of threads, evaluation A happens-before evaluation
B if any of the following is true:
1) A is sequenced-before B
2) A inter-thread happens before B
which directs us to the definition of sequenced-before:
Sequenced-before
Within the same thread, evaluation A may be sequenced-before
evaluation B, as described in evaluation order.
which brings us to Order of evaluation
which says:
A sequence point is a point in the execution sequence where all
side effects from the previous evaluations in the sequence are
complete, and no side effects of the subsequent evaluations started.
Rules
1) There is a sequence point at the end of each full
expression (typically, at the semicolon).
My reading of this is then that there is no race or UB as far as Thread 1 is concerned with itself, as the Relaxed ordering only concerns how the compiler and hardware will constrain the flushing of modified store buffers to cache. They will still enforce a sequenced-before (and therefore happens-before) relation within the same thread of execution.
An unsynchronized write to a value that is read is a race, so Thread 2's write races Thread 1's read. There is no happens-before relation here, so it is technically UB. Probably benign, but technically yolo.
(here's where I stir up the hornet's nest...)
races are good, actually.