For this particular case they thought ahead and require implementations to work with a GC that might move pointers. You run into it with cgo, which, as a result, has quite arcane rules for passing data between the two: https://golang.org/cmd/cgo/#hdr-Passing_pointers
Like with randomizing hashmap keys, they randomly enforce the rule to make sure that no one relies on it just happening to work since Go's GC doesn't currently move pointers.
I don't understand - as you say, cgo requires extra rules. Are you suggesting that extra rules will apply every time you cross a particular Go version boundary? This proposal doesn't seem to suggest that.
Sorry for the confusion. The rules were put in place to leave open the possibility of GC which could move pointers. Its not really related to this proposal directly, but its an example of how you can define a feature in such a way as to allow future changes.
Re:Proposal: Go 2 transition
by ianlancetaylor on Saturday October 27, 2018 @05:38PM
(#18317811)
Go could introduce a moving GC without requiring that map keys not be interface types. The simplest approach would be to use read barriers as we already use write barriers, and forward pointers during the moving phase of the GC.
(Efficiency costs might prohibit that, but it could be done.)
Another approach would be to use two different map implementations, and use a less efficient one for older code that used an interface type as a map key.
It's an interesting example, though. You're right: if there is an old language feature that can not be supported by a newer runtime, then there needs to be some sort of shim to let the older code keep working. That necessity may prevent us from making certain sorts of language changes.
Go doesn't have a stable ABI, AFAIK, so what (probably) actually going to happen is that the same Go 2 compiler will compile both Go 1 and Go 2 packages using the same runtime.
For instance, say Go wanted to introduce a moving GC, and say that required removing interfaces as map keys. How could a function that returned a map[interface{}]int in one module be called from another that was compiled with a later version of Go?
Would the whole program would have to be compiled with the non-moving GC?
Perhaps the answer is that Go would never introduce such a change.