After some more digging into #83, the issue was actually lack of HOME.
We need to specify GOPATH and GOCACHE because we haven't specified a
HOME.
Given the setup,
```
cd $(mktemp -d)
echo "module example.com/demo" > go.mod
echo "package demo" > demo.go
eval $(gimme 1.16rc1)
GO=$(which go)
```
If we run `go build` with an empty environment, it fails as expected.
```
$ env -i $GO build
missing $GOPATH
```
Setting HOME gives it a good default place for GOPATH, GOCACHE, and
friends.
```
$ env -i HOME=$(pwd)/home $GO build # succeeds
```
The nocmp integration test creates a temporary directory with a copy of
nocmp.go and a Go file that should not compile if our implementation of
nocmp is correct.
This worked fine without a GOPATH set previously, but with Go 1.16, it
seems that we need to have the GOPATH environment variable set (ref
https://github.com/golang/go/commit/cdbd4d49d8b).
Change the nocmp integration test to rely on Go modules for the test.
We can point GOPATH to an arbitrary temporary directory because we don't
rely on anything in it.
Fixes#82
The embedded `nocmp` field and other similar fields are unused in tests
and the rest of our code.
We can get the effect of `nocmp` without embedding the fields by using
`_ nocmp` as a field.
`staticcheck` caught the following issue.
nocmp_test.go:84:7: type y is unused (U1000)
Test was intended to evaluate the size of the new `type y` but due to a
typo, we were testing with `x`.
It is currently possible to make non-atomic comparisons of atomic
values:
x := atomic.NewInt32(1)
y := atomic.NewInt32(1)
fmt.Println(*x == *y)
This is undesirable because it loads the value in a non-atomic way. The
correct method is,
x := atomic.NewInt32(1)
y := atomic.NewInt32(1)
fmt.Println(x.Load() == y.Load())
To prevent this, disallow comparison of atomic values by embedding an
uncomparable array into atomics. The empty array adds no runtime cost,
and does not increase the in-memory size of the structs. Inspired by
[go4.org/mem#RO][1].
[1]: 3dbcd07079/mem.go (L42)
Note that the Value struct, which embeds `"sync/atomic".Value` was also
changed. This will break usages in the following form, but that's
acceptable because unkeyed struct literals are among the exceptions
stated in the [Go 1 compatibility expectations][2].
import (
syncatomic "sync/atomic"
"go.uber.org/atomic"
)
atomic.Value{syncatomic.Value{..}}
[2]: https://golang.org/doc/go1compat#expectationsResolves#72