Skip to content

Upgrade for current Go releases - #88

Merged
dave merged 8 commits into
masterfrom
upgrade-go
Sep 10, 2026
Merged

dave merged 8 commits into
masterfrom
upgrade-go

Conversation

@dave

@dave dave commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Brings the library up to date with current Go releases.

Adapted from #86 by @SamuelMarks — the dependency upgrade, the GitHub Actions migration, the gofmt pass, the go vet example renames and the fix for #81 are his work, and those commits keep his authorship. They have been modified: the dependency rationale differs, and the blank-line fix gained a regression test.

Not taken from #86: the TypeSpec Assign decoration point (adds public API and silently moves comment attachment for type aliases — worth doing, but separately), and ~125 generated docstrings.

Changes

  • x/tools v0.1.12 → v0.50.0. The old version panics reading export data from any modern toolchain, which broke the gotypes and gopackages resolvers. Requires go 1.26.0, matching the golang.org/x repos and the oldest supported Go release.
  • Fixes Fprint can eat empty lines. #81 — a run of two blank lines was collapsed to none. A newline fragment now only ever raises a node's spacing, so an EmptyLine can't be downgraded by a following NewLine.
  • Fixes a latent bug in gendst that could corrupt or panic when regenerating decorations-types-generated.go. It sliced the formatted source of positions.go using token.Pos values, which are relative to the file's base in the FileSet, and the loader parses a package's files concurrently.
  • Adds File.GoVersion, which go/ast gained in Go 1.21. It was being dropped, so a restored file lost its version constraint as far as go/types was concerned.
  • Travis → GitHub Actions, testing 1.26 and 1.27.
  • Stdlib round-trip test gains the files that have since hit Fails to correctly handle multi-alias imports. #45, skipped individually rather than by package.

Verification

  • Full suite green on Go 1.26.8 and 1.27.1, including the byte-exact standard library round-trip
  • go run ./gendst leaves a clean tree, so every generated file matches the generator
  • gofmt clean; go vet clean apart from pre-existing warnings in gendst/data/positions.go
  • Only public API change is the added File.GoVersion field

SamuelMarks and others added 8 commits September 10, 2026 14:33
Travis CI has been shut down, so CI moves to GitHub Actions, testing
against the two currently supported Go releases (1.26 and 1.27).

golang.org/x/tools v0.1.12 could not read export data produced by
modern toolchains, panicking in the gotypes and gopackages resolvers.
v0.50.0 is the current release: it reads the version 4 export data
emitted by Go 1.27 (as do v0.44.0 and later) and adds version 5 support
for whatever emits it next.

v0.50.0 requires go 1.26.0. That is also the go directive used by the
golang.org/x repositories, and the oldest Go release still supported, so
it costs nothing to anyone on a supported toolchain. The go directive is
a minimum for every module that depends on us, so it is deliberately not
set to the latest release.
Applies the doc comment reformatting introduced by gofmt in Go 1.19.
generateDstDecs slices the formatted source of positions.go using
token.Pos values, which are relative to the base of the file in the
FileSet rather than to the start of the file. This is only correct when
positions.go happens to be the first file added to the FileSet.

The loader parses the files of a package concurrently, so the base
depends on which file wins the race. When positions.go loses, the slices
are offset and we either write corrupted comments into
decorations-types-generated.go (each example missing its leading
characters) or panic with a slice bounds error.

Normalise the positions to a base of 1, which is what the slicing
expects.
go vet now rejects an ExampleXxx function where Xxx is not an identifier
in the package under test, which broke the build of the dst test
package. Rename the affected examples to the Example_xxx form, which vet
accepts for package level examples.

Examples that do name a real identifier (ExampleClone, ExampleDecorations,
ExampleInspect) are left alone so they stay attached to that identifier
in the documentation.
A run of two blank lines produces an empty-line fragment followed by a
new-line fragment, and both resolve to the same node. The second
overwrote the spacing set by the first, downgrading EmptyLine to
NewLine, and where the node was found in both directions the spacing was
lost altogether - two blank lines restored as none.

Only ever increase the spacing when attaching a newline fragment to a
node. gofmt collapses a run of blank lines to a single blank line, so
EmptyLine is the correct result.

Fixes #81
The standard library has grown more files that import the same path
twice with different aliases (e.g. "unsafe" alongside `_ "unsafe"` for
go:linkname), which we can't restore yet - see #45. Collect the affected
files into a map instead of a growing boolean expression, and add the
files that have appeared since this list was last updated.

Also skip packages that have nothing for us to restore, rather than
failing: those with no non-test source, and those where every source
file is preprocessed by cgo (Load only decorates the files in GoFiles).
Also commit the generated import block as gendst writes it, rather than
the goimports-grouped version that was committed previously, so that
running the generator leaves a clean tree. That makes it possible to
check the generated files are up to date with:

    go run ./gendst && git diff --exit-code
go/ast gained File.GoVersion in Go 1.21, recording the minimum Go
version required by the //go:build directives in the file. We were
dropping it, so a restored file lost its version constraint as far as
go/types was concerned.
@dave
dave merged commit a42bf06 into master Sep 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fprint can eat empty lines.

2 participants