I regret to inform you that x86_64 (which is probably a “major architecture”) is segmented and has three address spaces. In practice, it has two. In user code, those address spaces are normal memory and TLS and, in kernel code, they are normal memory and percpu memory.
And the proposed scheme in this article is, on first read, amazing. It would make the epic hackery in the kernel percpu code safer (in Rust, anyway). The major caveat is that, for even slightly decent codegen, the address space of an x86_64 pointer should be part of its type, not its value. Even do, this scheme still works:
ptr.with_addr(usize) -> ptr
has a type! If the input pointer is TLS or percpu, so is the output.