The Go compiler treats import "unsafe" as special - even if there is a vendor/unsafe directory, or a compiled unsafe.a package file, it doesn't use any of those - import "unsafe" always means the real unsafe, no matter what.
go/types appears not to follow this rule. I accidentally created a $GOROOT/pkg/darwin_amd64/unsafe.a, and that causes go/types to fail to typecheck just about any code using unsafe, because it no longer uses the real unsafe.
Obviously I will fix my problem and stop generating unsafe.a, but go/types should still refuse to treat import "unsafe" as anything other than the real unsafe.
touch $(go env GOROOT)/pkg/$(go env GOOS)_$(go env GOARCH)/unsafe.a
go test -short go/types
It fails quite loudly. The first few lines of output are:
--- FAIL: TestBuiltinSignatures (0.00s)
builtins_test.go:141: var s int; _ = append(s): 1:19: could not import unsafe (/Users/rsc/go/pkg/darwin_amd64/unsafe.a: can't find export data (EOF))
builtins_test.go:141: var s int; _ = append(s, 0): 1:19: could not import unsafe (/Users/rsc/go/pkg/darwin_amd64/unsafe.a: can't find export data (EOF))
Sigh. Obviously my memory is going. OK. Well, the importer is going to get rewritten as part of package management and workspace abstraction issues, so that will probably fix this anyway. So I guess nothing to do now.
FWIW, it doesn't make a lot of sense to me to vendor package unsafe - I'd be fine to disallow this and perhaps even state it in the spec that importing unsafe means only one thing and cannot be changed.