DRAFT RELEASE NOTES - Introduction to Go 1.12

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

The latest Go release, version 1.12, arrives six months after Go 1.11. Most of its changes are in TODO. As always, the release maintains the Go 1 promise of compatibility. We expect almost all Go programs to continue to compile and run as before.

Changes to the language

There are no changes to the language specification.

Ports

FreeBSD

Go 1.12 is the last release that is supported on FreeBSD 10.x, which has already reached end-of-life. Go 1.13 will require FreeBSD 11.2+ or FreeBSD 12.0+.

Darwin

Go 1.12 is the last release that will run on macOS 10.10 Yosemite. Go 1.13 will require macOS 10.11 El Capitan or later.

Windows

TODO: status of ARM32 port?

AIX

TODO: status of AIX port?

Hurd

hurd is now a recognized value for GOOS, reserved for the GNU/Hurd system for use with gccgo.

Tools

go tool vet no longer supported

The go vet command has been rewritten to serve as the base for a range of different source code analysis tools. See the golang.org/x/tools/go/analysis package for details. A side-effect is that go tool vet is no longer supported. External tools that use go tool vet must be changed to use go vet. Using go vet instead of go tool vet should work with all supported versions of Go.

Build cache requirement

The build cache is now required as a step toward eliminating $GOPATH/pkg. Setting the environment variable GOCACHE=off to disable the build cache has no effect in Go 1.12.

Binary-only packages

Go 1.12 is the last release that will support binary-only packages.

Modules

When GO111MODULE is set to on, the go command now supports module-aware operations outside of a module directory, provided that those operations do not need to resolve import paths relative to the current directory or explicitly edit the go.mod file. Commands such as go get, go list, and go mod download behave as if in a module with initially-empty requirements. In this mode, go env GOMOD reports the system's null device (/dev/null or NUL).

go commands that download and extract modules are now safe to invoke concurrently. The module cache (GOPATH/pkg/mod) must reside in a filesystem that supports file locking.

The go directive in a go.mod file now indicates the version of the language used by the files within that module, and go mod tidy sets it to the current release (go 1.12) if no existing version is present. If the go directive for a module specifies a version newer than the toolchain in use, the go command will attempt to build the packages regardless, and will note the mismatch only if that build fails.

When an import cannot be resolved using the active modules, the go command will now try to use the modules mentioned in the main module's replace directives before consulting the module cache and the usual network sources. If a matching replacement is found but the replace directive does not specify a version, the go command uses a pseudo-version derived from the zero time.Time (such as v0.0.0-00010101000000-000000000000).

Compiler toolchain

The compiler's live variable analysis has improved. This may mean that finalizers will be executed sooner in this release than in previous releases. If that is a problem, consider the appropriate addition of a runtime.KeepAlive call.

More functions are now eligible for inlining by default, including functions that do nothing but call another function. This extra inlining makes it additionally important to use runtime.CallersFrames instead of iterating over the result of runtime.Callers directly.

// Old code which no longer works correctly (it will miss inlined call frames).
var pcs [10]uintptr
n := runtime.Callers(1, pcs[:])
for _, pc := range pcs[:n] {
	f := runtime.FuncForPC(pc)
	if f != nil {
		fmt.Println(f.Name())
	}
}
// New code which will work correctly.
var pcs [10]uintptr
n := runtime.Callers(1, pcs[:])
frames := runtime.CallersFrames(pcs[:n])
for {
	frame, more := frames.Next()
	fmt.Println(frame.Function)
	if !more {
		break
	}
}

The compiler now accepts a -lang flag to set the Go language version to use. For example, -lang=go1.8 causes the compiler to emit an error if the program uses type aliases, which were added in Go 1.9. Language changes made before Go 1.12 are not consistently enforced.

Godoc

In Go 1.12, godoc no longer has a command-line interface and is only a web server. Users should use go doc for command-line help output instead.

Core library

All of the changes to the standard library are minor.

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.

bufio

TODO: https://golang.org/cl/149297: make Reader.Peek invalidate Unreads

build

TODO: https://golang.org/cl/61511: support frame-pointer for arm64

bytes

The new function ReplaceAll returns a copy of a byte slice with all non-overlapping instances of a value replaced by another.

A pointer to a zero-value Reader is now functionally equivalent to NewReader(nil). Prior to Go 1.12, the former could not be used as a substitute for the latter in all cases.

cmd,runtime

TODO: https://golang.org/cl/138675: enable race detector on arm64

crypto/rand

TODO: https://golang.org/cl/120055: use the new getrandom syscall on FreeBSD

TODO: https://golang.org/cl/139419: warn to stderr if blocked 60+ sec on first Reader.Read call

crypto/rc4

TODO: https://golang.org/cl/130397: remove assembler implementations

database/sql

A query cursor can now be obtained by passing a *Rows value to the Row.Scan method.

expvar

The new Delete method allows for deletion of key/value pairs from a Map.

fmt

Maps are now printed in key-sorted order to ease testing. The ordering rules are:

When printing maps, non-reflexive key values like NaN were previously displayed as <nil>. As of this release, the correct values are printed.

go/doc

To address some outstanding issues in cmd/doc, this package has a new Mode bit, PreserveAST, which controls whether AST data is cleared.

go/token

The File type has a new LineStart field, which returns the position of the start of a given line. This is especially useful in programs that occassionally handle non-Go files, such as assembly, but wish to use the token.Pos mechanism to identify file positions.

image

The RegisterFormat function is now safe for concurrent use.

image/png

Paletted images with fewer than 16 colors now encode to smaller outputs.

internal/cpu

TODO: https://golang.org/cl/149578: move GODEBUGCPU options into GODEBUG

internal/poll

TODO: https://golang.org/cl/130676: use F_FULLFSYNC fcntl for FD.Fsync on OS X

io

The new StringWriter interface wraps the WriteString function.

lib/time

The time zone database in $GOROOT/lib/time/zoneinfo.zip has been updated to version 2018g. Note that this ZIP file is only used if a time zone database is not provided by the operating system.

math/bits

TODO: https://golang.org/cl/123157: add extended precision Add, Sub, Mul, Div

net

The Dialer.DualStack setting is now ignored and deprecated; RFC 6555 Fast Fallback ("Happy Eyeballs") is now enabled by default. To disable, set Dialer.FallbackDelay to a negative value.

Similarly, TCP keep-alives are now enabled by default if Dialer.KeepAlive is zero. To disable, set it to a negative value.

On Linux, the splice system call is now used when copying from a UnixConn to a TCPConn.

net/http

The HTTP server now rejects misdirected HTTP requests to HTTPS servers with a plaintext "400 Bad Request" response.

The new Client.CloseIdleConnections method calls the Client's underlying Transport's CloseIdleConnections if it has one.

The Transport no longer rejects HTTP responses which declare HTTP Trailers but don't use chunked encoding. Instead, the declared trailers are now just ignored.

The Transport no longer handles MAX_CONCURRENT_STREAMS values advertised from HTTP/2 servers as strictly as it did during Go 1.10 and Go 1.11. The default behavior is now back to how it was in Go 1.9: each connection to a server can have up to MAX_CONCURRENT_STREAMS requests active and then new TCP connections are created as needed. In Go 1.10 and Go 1.11 the http2 package would block and wait for requests to finish instead of creating new connections. To get the stricter behavior back, import the golang.org/x/net/http2 package directly and set Transport.StrictMaxConcurrentStreams to true.

net/http/httputil

The ReverseProxy now automatically proxies WebSocket requests.

os

The new ProcessState.ExitCode method returns the process's exit code.

ModeCharDevice has been added to the ModeType bitmask, allowing for ModeDevice | ModeCharDevice to be recovered when masking a FileMode with ModeType.

The new function UserHomeDir returns the current user's home directory.

RemoveAll now supports paths longer than 4096 characters on most Unix systems.

path/filepath

The IsAbs function now returns true when passed a reserved filename on Windows such as NUL. List of reserved names.

reflect

A new MapIter type is an iterator for ranging over a map. This type is exposed through the Value type's new MapRange method. This follows the same iteration semantics as a range statment, with Next to advance the iterator, and Key/Value to access each entry.

regexp

TODO: https://golang.org/cl/139783: add DeepEqual test

TODO: https://golang.org/cl/139784: add partial Deprecation comment to Copy

runtime

TODO: https://golang.org/cl/135395: use MADV_FREE on Linux if available

runtime/debug

TODO: https://golang.org/cl/144220: add API to read module info in binary

strings

The new function ReplaceAll returns a copy of a string with all non-overlapping instances of a value replaced by another.

A pointer to a zero-value Reader is now functionally equivalent to NewReader(nil). Prior to Go 1.12, the former could not be used as a substitute for the latter in all cases.

The new Builder.Cap method returns the capacity of the builder's underlying byte slice.

The character mapping functions Map, Title, ToLower, ToLowerSpecial, ToTitle, ToTitleSpecial, ToUpper, and ToUpperSpecial now always guarantee to return valid UTF-8. In earlier releases, if the input was invalid UTF-8 but no character replacements needed to be applied, these routines incorrectly returned the invalid UTF-8 unmodified.

syscall

TODO: https://golang.org/cl/125456: implement Unix Socket for Windows

TODO: https://golang.org/cl/138595: FreeBSD 12 ino64 support

TODO: https://golang.org/cl/141639: implement syscalls on Darwin using libSystem

TODO: https://golang.org/cl/147117: add Syscall18 on Windows

syscall/js

TODO: https://golang.org/cl/141644: add Wrapper interface to support external Value wrapper types

TODO: https://golang.org/cl/143137: make zero js.Value represent "undefined"

TODO: https://golang.org/cl/144384: add the Value.Truthy method

testing

TODO: https://golang.org/cl/121936: exit with error if testing.Short is called before flag.Parse

TODO: https://golang.org/cl/139258: implement -benchtime=100x

text/template

When executing a template, long context values are no longer truncated in errors.

executing "tmpl" at <.very.deep.context.v...>: map has no entry for key "notpresent"

is now

executing "tmpl" at <.very.deep.context.value.notpresent>: map has no entry for key "notpresent"