DRAFT RELEASE NOTES — Introduction to Go 1.16

Go 1.16 is not yet released. These are work-in-progress release notes. Go 1.16 is expected to be released in February 2021.

Changes to the language

TODO

Ports

Darwin

Go 1.16 adds support of 64-bit ARM architecture on macOS (also known as Apple Silicon) with GOOS=darwin, GOARCH=arm64. Like the darwin/amd64 port, the darwin/arm64 port supports cgo, internal and external linking, c-archive, c-shared, and pie build modes, and the race detector.

The iOS port, which was previously darwin/arm64, is now moved to ios/arm64. GOOS=ios implies the darwin build tag, just as GOOS=android implies the linux build tag.

The ios/amd64 port is added, targetting the iOS simulator running on AMD64-based macOS.

NetBSD

Go now supports the 64-bit ARM architecture on NetBSD (the netbsd/arm64 port).

386

As announced in the Go 1.15 release notes, Go 1.16 drops support for x87 mode compilation (GO386=387). Support for non-SSE2 processors is now available using soft float mode (GO386=softfloat). Users running on non-SSE2 processors should replace GO386=387 with GO386=softfloat.

Tools

TODO

Go command

TODO

Modules

Build commands like go build and go test no longer modify go.mod and go.sum by default. Instead, they report an error if a module requirement or checksum needs to be added or updated (as if the -mod=readonly flag were used). Module requirements and sums may be adjusted with go mod tidy or go get.

go install now accepts arguments with version suffixes (for example, go install example.com/cmd@v1.0.0). This causes go install to build and install packages in module-aware mode, ignoring the go.mod file in the current directory or any parent directory, if there is one. This is useful for installing executables without affecting the dependencies of the main module.
TODO: write and link to section in golang.org/ref/mod
TODO: write and link to blog post

go install, with or without a version suffix (as described above), is now the recommended way to build and install packages in module mode. go get should be used with the -d flag to adjust the current module's dependencies without building packages, and use of go get to build and install packages is deprecated. In a future release, the -d flag will always be enabled.

retract directives may now be used in a go.mod file to indicate that certain published versions of the module should not be used by other modules. A module author may retract a version after a severe problem is discovered or if the version was published unintentionally.
TODO: write and link to section in golang.org/ref/mod
TODO: write and link to tutorial or blog post

The go mod vendor and go mod tidy subcommands now accept the -e flag, which instructs them to proceed despite errors in resolving missing packages.

go test

When using go test, a test that calls os.Exit(0) during execution of a test function will now be considered to fail. This will help catch cases in which a test calls code that calls os.Exit(0) and thereby stops running all future tests. If a TestMain function calls os.Exit(0) that is still considered to be a passing test.

The go get -insecure flag is deprecated and will be removed in a future version. This flag permits fetching from repositories and resolving custom domains using insecure schemes such as HTTP, and also bypassess module sum validation using the checksum database. To permit the use of insecure schemes, use the GOINSECURE environment variable instead. To bypass module sum validation, use GOPRIVATE or GONOSUMDB. See go help environment for details.

go get

go get example.com/mod@patch now requires that some version of example.com/mod already be required by the main module. (However, go get -u=patch continues to patch even newly-added dependencies.)

The all pattern

When the main module's go.mod file declares go 1.16 or higher, the all package pattern now matches only those packages that are transitively imported by a package or test found in the main module. (Packages imported by tests of packages imported by the main module are no longer included.) This is the same set of packages retained by go mod vendor since Go 1.11.

The -toolexec build flag

When the -toolexec build flag is specified to use a program when invoking toolchain programs like compile or asm, the environment variable TOOLEXEC_IMPORTPATH is now set to the import path of the package being built.

The -i build flag

The -i flag accepted by go build, go install, and go test is now deprecated. The -i flag instructs the go command to install packages imported by packages named on the command line. Since the build cache was introduced in Go 1.10, the -i flag no longer has a significant effect on build times, and it causes errors when the install directory is not writable.

The list command

When the -export flag is specified, the BuildID field is now set to the build ID of the compiled package. This is equivalent to running go tool buildid on go list -exported -f {{.Export}, but without the extra step.

Cgo

The cgo tool will no longer try to translate C struct bitfields into Go struct fields, even if their size can be represented in Go. The order in which C bitfields appear in memory is implementation dependent, so in some cases the cgo tool produced results that were silently incorrect.

Vet

TODO

Runtime

TODO

On Linux, the runtime now defaults to releasing memory to the operating system promptly (using MADV_DONTNEED), rather than lazily when the operating system is under memory pressure (using MADV_FREE). This means process-level memory statistics like RSS will more accurately reflect the amount of physical memory being used by Go processes. Systems that are currently using GODEBUG=madvdontneed=1 to improve memory monitoring behavior no longer need to set this environment variable.

Compiler

TODO

Linker

This release includes additional improvements to the Go linker, reducing linker resource usage (both time and memory) and improving code robustness/maintainability. These changes form the second half of a two-release project to modernize the Go linker.

The linker changes in 1.16 extend the 1.15 improvements to all supported architecture/OS combinations (the 1.15 performance improvements were primarily focused on ELF-based OSes and amd64 architectures). For a representative set of large Go programs, linking is 20-35% faster than 1.15 and requires 5-15% less memory on average for linux/amd64, with larger improvements for other architectures and OSes.

TODO: update with final numbers later in the release.

On Windows, go build -buildmode=c-shared now generates Windows ASLR DLLs by default. ASLR can be disabled with --ldflags=-aslr=false.

Core library

TODO

crypto/hmac

New will now panic if separate calls to the hash generation function fail to return new values. Previously, the behavior was undefined and invalid outputs were sometimes generated.

crypto/tls

I/O operations on closing or closed TLS connections can now be detected using the new ErrClosed error. A typical use would be errors.Is(err, net.ErrClosed). In earlier releases the only way to reliably detect this case was to match the string returned by the Error method with "tls: use of closed connection".

A default deadline is set in Close before sending the close notify alert, in order to prevent blocking indefinitely.

(*Conn).HandshakeContext was added to allow the user to control cancellation of an in-progress TLS Handshake. The context provided is propagated into the ClientHelloInfo and CertificateRequestInfo structs and accessible through the new (*ClientHelloInfo).Context and (*CertificateRequestInfo).Context methods respectively. Canceling the context after the handshake has finished has no effect.

Clients now ensure that the server selects an ALPN protocol from the list advertised by the client.

TLS servers will now prefer other AEAD cipher suites (such as ChaCha20Poly1305) over AES-GCM cipher suites if either the client or server doesn't have AES hardware support, unless the application set both Config.PreferServerCipherSuites and Config.CipherSuites or there are no other AEAD cipher suites supported. The client is assumed not to have AES hardware support if it does not signal a preference for AES-GCM cipher suites.

crypto/x509

ParseCertificate and CreateCertificate both now enforce string encoding restrictions for the fields DNSNames, EmailAddresses, and URIs. These fields can only contain strings with characters within the ASCII range.

CreateCertificate now verifies the generated certificate's signature using the signer's public key. If the signature is invalid, an error is returned, instead of a malformed certificate.

A number of additional fields have been added to the CertificateRequest type. These fields are now parsed in ParseCertificateRequest and marshalled in CreateCertificateRequest.

encoding/json

The error message for SyntaxError now begins with "json: ", matching the other errors in the package.

net

The case of I/O on a closed network connection, or I/O on a network connection that is closed before any of the I/O completes, can now be detected using the new ErrClosed error. A typical use would be errors.Is(err, net.ErrClosed). In earlier releases the only way to reliably detect this case was to match the string returned by the Error method with "use of closed network connection".

In previous Go releases the default TCP listener backlog size on Linux systems, set by /proc/sys/net/core/somaxconn, was limited to a maximum of 65535. On Linux kernel version 4.1 and above, the maximum is now 4294967295.

text/template/parse

A new CommentNode was added to the parse tree. The Mode field in the parse.Tree enables access to it.

unicode

The unicode package and associated support throughout the system has been upgraded from Unicode 12.0.0 to Unicode 13.0.0, which adds 5,930 new characters, including four new scripts, and 55 new emoji. Unicode 13.0.0 also designates plane 3 (U+30000-U+3FFFF) as the tertiary ideographic plane.

Minor changes to the library

As always, there are various minor changes and updates to the library, made with the Go 1 promise of compatibility in mind.

TODO

crypto/dsa

The crypto/dsa package is now deprecated. See issue #40337.

crypto/tls

TODO: https://golang.org/cl/246637: make config.Clone return nil if the source is nil

crypto/x509

DSA signature verification is no longer supported. Note that DSA signature generation was never supported. See issue #40337.

TODO: https://golang.org/cl/257257: return additional chains from Verify on Windows

TODO: https://golang.org/cl/262343: add Unwrap to SystemRootsError

encoding/json

TODO: https://golang.org/cl/234818: allow semicolon in field key / struct tag

encoding/xml

The encoder has always taken care to avoid using namespace prefixes beginning with xml, which are reserved by the XML specification. Now, following the specification more closely, that check is case-insensitive, so that prefixes beginning with XML, XmL, and so on are also avoided.

flag

TODO: https://golang.org/cl/240014: add Func

io

TODO: https://golang.org/cl/261577: add a new ReadSeekCloser interface

log

TODO: https://golang.org/cl/264460: expose std via new Default function

log/syslog

TODO: https://golang.org/cl/264297: set local to true if network is any of "unix", or "unixgram"

mime/multipart

TODO: https://golang.org/cl/247477: return overflow errors in Reader.ReadForm

net

TODO: https://golang.org/cl/238629: prefer /etc/hosts over DNS when no /etc/nsswitch.conf is present

net/http

In the net/http package, the behavior of StripPrefix has been changed to strip the prefix from the request URL's RawPath field in addition to its Path field. In past releases, only the Path field was trimmed, and so if the request URL contained any escaped characters the URL would be modified to have mismatched Path and RawPath fields. In Go 1.16, StripPrefix trims both fields. If there are escaped characters in the prefix part of the request URL the handler serves a 404 instead of its previous behavior of invoking the underlying handler with a mismatched Path/RawPath pair.

The net/http package now rejects HTTP range requests of the form "Range": "bytes=--N" where "-N" is a negative suffix length, for example "Range": "bytes=--2". It now replies with a 416 "Range Not Satisfiable" response.

Cookies set with SameSiteDefaultMode now behave according to the current spec (no attribute is set) instead of generating a SameSite key without a value.

The net/http package now uses the new (*tls.Conn).HandshakeContext with the Request context when performing TLS handshakes in the client or server.

TODO: https://golang.org/cl/250039: set Content-Length:0 for empty PATCH requests as with POST, PATCH

TODO: https://golang.org/cl/249440: match http scheme when selecting http_proxy

net/http/httputil

TODO: https://golang.org/cl/260637: flush ReverseProxy immediately if Content-Length is -1

net/smtp

TODO: https://golang.org/cl/247257: adds support for the SMTPUTF8 extension

os

TODO: https://golang.org/cl/242998: export errFinished as ErrProcessDone

os/signal

TODO: https://golang.org/cl/219640: add NotifyContext to cancel context using system signals

path

TODO: https://golang.org/cl/264397: validate patterns in Match, Glob

path/filepath

TODO: https://golang.org/cl/264397: validate patterns in Match, Glob

reflect

TODO: https://golang.org/cl/248341: support multiple keys in struct tags

runtime

TODO: https://golang.org/cl/37222: make stack traces of endless recursion print only top and bottom 50

TODO: https://golang.org/cl/242258: add 24 byte allocation size class

TODO: https://golang.org/cl/254659: implement GODEBUG=inittrace=1 support

runtime/debug

TODO: https://golang.org/cl/249677: provide Addr method for errors from SetPanicOnFault

syscall

SysProcAttr on Windows has a new NoInheritHandles field that disables inheriting handles when creating a new process.

DLLError on Windows now has an Unwrap function for unwrapping its underlying error.

TODO: https://golang.org/cl/210639: support POSIX semantics for Linux syscalls

strconv

ParseFloat now uses the Eisel-Lemire algorithm, improving performance by up to a factor of 2. This can also speed up decoding textual formats like encoding/json.

text/template

TODO: https://golang.org/cl/254257: allow newlines inside action delimiters

time/tzdata

TODO: https://golang.org/cl/261877: use slim tz data format