Archive · Week 46 · Nov 10 – 16, 2025from 5 items
The Go team accepted several proposals that add small conveniences and safety checks to the language and its tooling. The week also celebrated Go’s 16th birthday with a blog post.
Worth knowingstdlib
go/token: add File.End method
- What changed
- The
Filetype in thego/tokenpackage now has anEnd()method that returns the position of the end of the file. - Production impact
- The source does not say.
- Try it
- Import
go/tokenand callf.End()on atoken.File. - Source
- github.com/golang/go/issues/75849
Explain it and run it
Understand it, then run it
The go/token package keeps track of where text appears in a source file. A File value knows its start position (Base) and its length (Size). Before this change you had to compute the end of the file by adding those two numbers every time. The new End() method does that for you, returning the position just after the last byte of the file. It saves a few keystrokes and makes the intent clearer.
Run it now
// This program demonstrates the current state of the go/token File type in Go 1.27.1.
// The proposed End() method is not yet available, so we compute the end position
// manually using Base() and Size() and print the result.
package main
import (
"fmt"
"go/token"
)
func main() {
// Create a new FileSet and add a file named "example.go" with 20 bytes of content.
fset := token.NewFileSet()
f := fset.AddFile("example.go", -1, 20)
// Base() returns the starting position of the file (usually 1).
base := f.Base()
// Size() returns the number of bytes in the file.
size := f.Size()
// Compute the end position as Base() + Size().
end := token.Pos(base + size)
fmt.Printf("Base: %d\n", base)
fmt.Printf("Size: %d\n", size)
fmt.Printf("End: %d\n", end)
}
What it printed when we ran it on Go 1.27.1
Base: 1 Size: 20 End: 21
After the change ships
go · the proposal's code; it does not compile until the change ships
// This does not compile until the change ships in Go 1.27.1.
package main
import (
"fmt"
"go/token"
)
func main() {
fset := token.NewFileSet()
f := fset.AddFile("example.go", -1, 20)
fmt.Println("End:", f.End())
}
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Worth knowingstdlib
go/ast: add BasicLit.ValueEnd field
- What changed
ast.BasicLitnow has aValueEndfield that records the actual end position of a literal, andBasicLit.End()returns this value when it is set.- Production impact
- The source does not say.
- Try it
- Parse a multiline raw string literal with
go/parserand inspect theValueEndof the resultingBasicLit. - Source
- github.com/golang/go/issues/76031
Explain it and run it
Understand it, then run it
ast.BasicLit represents a literal value in Go source code. Its End() method used to compute the literal’s end position by adding the literal’s start position to the length of the literal string stored in Value. For multiline raw string literals the scanner removes carriage‑return characters, so the string in Value is shorter than the actual text in the source file. The new ValueEnd field records the real end position of the literal, and BasicLit.End() now returns that value when it is set.
Run it now
// This program demonstrates the incorrect End position for a multiline raw
// string literal in Go 1.27.1. The change that adds BasicLit.ValueEnd is not
// yet available, so we show the problem that the proposal fixes.
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
)
func main() {
src := `package main
func main() {
s := ` + "`Hello\nWorld`" + `
}`
fset := token.NewFileSet()
// Parse the source code.
f, err := parser.ParseFile(fset, "example.go", src, 0)
if err != nil {
panic(err)
}
// Find the first BasicLit node (the raw string literal).
var lit *ast.BasicLit
ast.Inspect(f, func(n ast.Node) bool {
if bl, ok := n.(*ast.BasicLit); ok && bl.Kind == token.STRING {
lit = bl
return false
}
return true
})
if lit == nil {
panic("no string literal found")
}
// Print the literal value and its start position.
fmt.Printf("Literal value: %q\n", lit.Value)
fmt.Printf("Start position: %s\n", fset.Position(lit.Pos()))
// End() uses ValuePos + len(Value), which is incorrect for multiline raw strings.
fmt.Printf("End() position: %s\n", fset.Position(lit.End()))
// Compute the correct end position by looking at the file content.
// The file's content ends at the position of the closing backtick.
// We find the index of the closing backtick in the source string.
endIdx := len(src) - 1 // last character is the closing backtick
endPos := fset.File(lit.Pos()).Pos(endIdx)
fmt.Printf("Manual end position: %s\n", fset.Position(endPos))
}
What it printed when we ran it on Go 1.27.1
Literal value: "`Hello\nWorld`" Start position: example.go:3:7 End() position: example.go:4:7 Manual end position: example.go:5:1
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Worth knowingstdlib
crypto/fips140: add Version
- What changed
- The
crypto/fips140package now exposes aVersion()function that returns the FIPS 140‑3 Go Cryptographic Module version or"latest". - Production impact
- The source does not say.
- Try it
- Call
crypto/fips140.Version()in a program and print the result. - Source
- github.com/golang/go/issues/75301
Explain it and run it
Understand it, then run it
The crypto/fips140 package has a new function called Version. It tells you which version of the FIPS 140‑3 Go Cryptographic Module your program was built with. If the build used a frozen module that has a GOFIPS140 setting, Version returns that module’s version string, like "v1.0.0". If no frozen module was used, or the build is still in progress, it simply returns "latest".
Run it now
// This program demonstrates the new fips140.Version function.
// Since Go 1.27.1 does not yet include the change, the call will compile
// but return "latest" unless the build is done with GOFIPS140 set.
package main
import (
"fmt"
"crypto/fips140"
)
func main() {
// Retrieve the FIPS 140-3 module version.
ver := fips140.Version()
// Print the result; it will be "latest" in this environment.
fmt.Println("FIPS 140-3 module version:", ver)
}
What it printed when we ran it on Go 1.27.1
FIPS 140-3 module version: latest
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Worth knowingtooling
cmd/vet: add check for using %q with non‑{rune,byte} integer types
- What changed
go vetnow warns when the%qverb is used with an integer type that is notruneorbyte.- Production impact
- The source does not say.
- Try it
- Run
go veton a file that containsfmt.Printf("%q", 123)and observe the new warning. - Source
- github.com/golang/go/issues/72850
Explain it and run it
Understand it, then run it
go vet now checks the %q verb in fmt.Printf. If you write fmt.Printf("%q", 123) the program prints the character whose Unicode code point is 123, which is {. The new check warns when the value you pass to %q is an integer that is not a rune or a byte. This helps you spot accidental misuse of %q that might lead to confusing output.
Run it now
// This program demonstrates the behavior that go vet now warns about: using
// the %q verb with an integer that is not a rune or byte. The output shows
// that fmt.Printf("%q", 123) prints the character with code 123, which is
// '{'.
package main
import "fmt"
func main() {
// Print the result of formatting an integer with %q.
fmt.Printf("%q\n", 123)
}
What it printed when we ran it on Go 1.27.1
'{'
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Exercise
Write a small program that parses a Go source file containing a multiline raw string literal and prints the ValueEnd position of that literal.
The 60-second version
Hello, everyone. This week the Go team added a few handy features. In the token package, a new `End()` method on `File` gives you the position of the file’s end, making file boundary calculations a bit cleaner. The abstract syntax tree now records the true end position of string literals, which helps tools that need accurate source ranges, especially for multiline raw strings. In the crypto package, a `Version()` function tells you which FIPS 140‑3 module you’re running against, or “latest” if you’re not using a frozen module. Finally, the vet tool now warns when you use the `%q` format verb with an integer that isn’t a rune or byte, catching a subtle source of bugs. Those are the highlights from this week’s Go updates.
Written by gpt-oss-20b · claims checked against the sources · archive, not individually reviewed