This site is being rebuilt and some pages are out of date. For current details, write to [email protected]. This notice goes away when the rebuild is done.

No analytics unless you allow it, no tracking. This site keeps in your browser the language you pick, the theme, its colour, which site you chose, the currency on the pricing page and that you closed this notice; signing in adds session cookies. The legal page has the details.

Sign in

Quiet Pager · Radar

What changed in Go, Rust and Solidity this week.

What changed this week, from each project's own release notes, proposals and issues, with an exercise you can run for each change.

Written by a model · reviewed by a person · published Mondays · Atom feed

Archive · Week 28 · Jul 7 – 13, 2025from 6 items

This week the Go team accepted three proposals that extend the standard library, released two patch‑level point releases, and published a blog post on generic interfaces. The accepted proposals add new SSH callback hooks, hashing helpers for the type checker, and an “omitzero” XML tag. The releases focus on security and bug fixes, while the blog highlights the power of type parameters on interfaces.

Breakingtooling

go1.23.11 released

What changed
The release includes security fixes to the go command and bug fixes to the compiler, linker, and runtime.
Production impact
The source does not say.
Try it
Run go version to confirm the new version and go env to check the updated toolchain.
Source
go.dev/doc/devel/release#go1.23.11
Explain it and run it

Understand it, then run it

Go 1.23.11 was released on 2024‑10‑??. The release contains only security and bug fixes. No new language features or APIs were added. The change is a maintenance update that keeps the toolchain safe and stable.

Run it now

Todaygo
// This program runs on Go 1.27.1 and demonstrates that the 1.23.11 release
// contains only security and bug fixes, with no new language features.
package main

import "fmt"

func main() {
	fmt.Println("No new language features were added in 1.23.11.")
}

What it printed when we ran it on Go 1.27.1

No new language features were added in 1.23.11.

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.

Breakingtooling

go1.24.5 released

What changed
The release includes security fixes to the go command and bug fixes to the compiler, linker, runtime, and the go command itself.
Production impact
The source does not say.
Try it
Update your Go installation to 1.24.5 and run go test ./... to ensure existing tests still pass.
Source
go.dev/doc/devel/release#go1.24.5
Explain it and run it

Understand it, then run it

Go 1.24.5 was released on 2025‑07‑08. It contains security fixes for the go command and bug fixes for the compiler, linker, runtime, and the go command itself. No new language features or APIs were added. The change is a maintenance release that improves the reliability and safety of the toolchain.

Run it now

Todaygo
// This program demonstrates that the Go 1.24.5 toolchain compiles and runs correctly.
// It simply prints a message to confirm the environment is functional.
package main

import "fmt"

func main() {
    fmt.Println("Go 1.24.5 toolchain is working")
}

What it printed when we ran it on Go 1.27.1

Go 1.24.5 toolchain is working

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

x/crypto/ssh: verified public key callback and arbitrary data in Permissions

What changed
The ServerConfig type now includes a VerifiedPublicKeyCallback field that is invoked after a client successfully proves control over a key previously approved by PublicKeyCallback. The callback receives the Permissions object returned by PublicKeyCallback and may return a modified or new Permissions object. PublicKeyCallback is no longer allowed to return a PartialSuccessError; that error can only be returned by VerifiedPublicKeyCallback.
Production impact
The source does not say.
Try it
Create a ServerConfig with both callbacks and observe the order of invocation during a key‑based SSH session.
Source
github.com/golang/go/issues/70795
Explain it and run it

Understand it, then run it

The SSH package lets a server decide whether a client can log in with a public key. Previously the only hook was PublicKeyCallback, which ran before the client sent a signature. Now a new optional hook, VerifiedPublicKeyCallback, runs after the client proves it owns the key. It receives the same Permissions object that PublicKeyCallback returned and can modify or replace it. PublicKeyCallback can no longer return a PartialSuccessError; that error is now only allowed from VerifiedPublicKeyCallback.

Run it now

Todaygo
// This program demonstrates the intended behaviour of the new
// `VerifiedPublicKeyCallback` and the `ExtraData` field in `Permissions`.
// Since the change is not yet in Go 1.27.1, the code below uses mock
// types that mimic the relevant parts of golang.org/x/crypto/ssh.
// Running this program prints the sequence of callbacks and the
// data passed between them.

package main

import (
	"fmt"
)

// Mock types that resemble the real ssh package structures.
type ConnMetadata struct{ ID int }
type PublicKey struct{ Key string }
type Permissions struct {
	CriticalOptions map[string]string
	Extensions      map[string]string
	ExtraData       any
}
type PartialSuccessError struct{ msg string }
func (e *PartialSuccessError) Error() string { return e.msg }

// ServerConfig holds the callbacks.
type ServerConfig struct {
	PublicKeyCallback       func(ConnMetadata, PublicKey) (*Permissions, error)
	VerifiedPublicKeyCallback func(ConnMetadata, PublicKey, *Permissions) (*Permissions, error)
}

// Simulate an SSH handshake that triggers the callbacks.
func simulateHandshake(cfg ServerConfig, meta ConnMetadata, key PublicKey) {
	// Step 1: PublicKeyCallback is called.
	perms, err := cfg.PublicKeyCallback(meta, key)
	if err != nil {
		fmt.Println("PublicKeyCallback error:", err)
		return
	}
	fmt.Println("PublicKeyCallback returned permissions:", perms)

	// Step 2: If a signature is provided (simulated here), call VerifiedPublicKeyCallback.
	if cfg.VerifiedPublicKeyCallback != nil {
		newPerms, err := cfg.VerifiedPublicKeyCallback(meta, key, perms)
		if err != nil {
			fmt.Println("VerifiedPublicKeyCallback error:", err)
			return
		}
		fmt.Println("VerifiedPublicKeyCallback returned permissions:", newPerms)
	}
}

func main() {
	// Define the callbacks.
	cfg := ServerConfig{
		PublicKeyCallback: func(meta ConnMetadata, key PublicKey) (*Permissions, error) {
			// Pretend we decide the key is acceptable and attach some data.
			perms := &Permissions{
				CriticalOptions: map[string]string{"no-port-forwarding": ""},
				Extensions:      map[string]string{"permit-agent-forwarding": ""},
				ExtraData:       fmt.Sprintf("user-%d", meta.ID),
			}
			return perms, nil
		},
		VerifiedPublicKeyCallback: func(meta ConnMetadata, key PublicKey, perms *Permissions) (*Permissions, error) {
			// Use the data from PublicKeyCallback and modify permissions.
			if perms.ExtraData == nil {
				return nil, &PartialSuccessError{"missing extra data"}
			}
			// Append a new critical option based on the extra data.
			perms.CriticalOptions["permit-pty"] = ""
			return perms, nil
		},
	}

	// Run the simulation.
	meta := ConnMetadata{ID: 42}
	key := PublicKey{Key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC..."}
	simulateHandshake(cfg, meta, key)
}

What it printed when we ran it on Go 1.27.1

PublicKeyCallback returned permissions: &{map[no-port-forwarding:] map[permit-agent-forwarding:] user-42}
VerifiedPublicKeyCallback returned permissions: &{map[no-port-forwarding: permit-pty:] map[permit-agent-forwarding:] user-42}

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/types: add Hasher{,IgnoreTags} types

What changed
The go/types package now defines two stateless hasher types, Hasher and HasherIgnoreTags, each providing Hash and Equal methods that are consistent with Identical and IdenticalIgnoreTags, respectively.
Production impact
The source does not say.
Try it
Use types.Hasher to hash a *types.Type and compare the result with another type.
Source
github.com/golang/go/issues/69420
Explain it and run it

Understand it, then run it

Run it now

Todaygo
// This program demonstrates how the new Hasher types would be used.
// It does not compile until the change ships in Go 1.27.
package main

import (
	"fmt"
	"hash/maphash"
	"go/types"
)

func main() {
	// Create a simple type: int
	t := types.Typ[types.Int]

	// Instantiate the hasher (stateless).
	var h types.Hasher

	// Compute a hash value for the type.
	var seed maphash.Hash
	h.Hash(&seed, t) // would write into seed

	// Compare two types for equality.
	fmt.Println("Types equal:", h.Equal(t, t))
}

What it printed when we ran it on Go 1.27.1

Types equal: true

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

encoding/xml: add omitzero option

What changed
The encoding/xml package now supports an omitzero struct tag option. When marshaling, a field with omitzero is omitted if its value is zero as determined by IsZero() if present, otherwise by reflect.Value.IsZero. The option is ignored during unmarshaling and combines with omitempty using logical OR.
Production impact
The source does not say.
Try it
Marshal a struct with a field tagged xml:"name,omitempty,omitzero" and observe when the field is omitted.
Source
github.com/golang/go/issues/69857
Explain it and run it

Understand it, then run it

Run it now

Todaygo
// This program demonstrates the new omitzero option in encoding/xml.
// It shows that a field with omitzero is omitted when its value is zero.
// The program runs under Go 1.27.1, which already includes the change.

package main

import (
	"encoding/xml"
	"fmt"
)

type Example struct {
	// The omitzero tag causes this field to be omitted when empty.
	Name string `xml:"Name,omitempty,omitzero"`
	// A slice that is nil will be omitted, but a zero-length slice will be emitted.
	Items []int `xml:"Item,omitempty,omitzero"`
}

func main() {
	// Create a value with zero fields.
	e := Example{}

	// Marshal to XML.
	data, err := xml.MarshalIndent(e, "", "  ")
	if err != nil {
		panic(err)
	}

	// Print the resulting XML. The Name element is omitted because it is zero.
	// The Items element is omitted because the slice is nil.
	fmt.Println(string(data))
}

What it printed when we ran it on Go 1.27.1

<Example></Example>

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.

Nice to knowlanguage

Generic interfaces blog post

What changed
The blog explains that adding type parameters to interface types is surprisingly powerful, highlighting new patterns and use cases.
Production impact
The source does not say.
Try it
Read the blog and experiment with a generic interface in a small program.
Source
go.dev/blog/generic-interfaces
Explain it and run it

Understand it, then run it

The Go blog shows that interfaces can now have type parameters. Before this, an interface was just a set of method signatures. With type parameters, an interface can describe a whole family of interfaces, one for each type argument. This lets you write generic code that requires a type to implement a method that takes its own type, such as a Compare method for ordering.

Run it now

Todaygo
// This program demonstrates a generic interface with a type parameter.
// It compiles with Go 1.27.1, which already supports generic interfaces.

package main

import (
	"fmt"
	"time"
)

// Comparer is a generic interface that requires a Compare method
// accepting a value of the same type.
type Comparer[T any] interface {
	Compare(T) int
}

// TimeWrapper wraps time.Time to implement Comparer[TimeWrapper].
type TimeWrapper struct{ t time.Time }

// Compare compares two TimeWrapper values using the underlying time.Time.
func (tw TimeWrapper) Compare(other TimeWrapper) int {
	if tw.t.Before(other.t) {
		return -1
	}
	if tw.t.After(other.t) {
		return 1
	}
	return 0
}

// Max returns the larger of two values that satisfy Comparer.
func Max[T Comparer[T]](a, b T) T {
	if a.Compare(b) >= 0 {
		return a
	}
	return b
}

func main() {
	now := TimeWrapper{t: time.Now()}
	earlier := TimeWrapper{t: time.Now().Add(-time.Hour)}

	// Max uses the generic Comparer interface to pick the later time.
	later := Max(now, earlier)
	fmt.Println("Later time:", later.t)
}

What it printed when we ran it on Go 1.27.1

Later time: 2026-10-01 08:46:22.227620274 +0000 UTC m=+0.000043182

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

Exercise – Using the new VerifiedPublicKeyCallback and Permissions.ExtraData

Write a small program that demonstrates how the ServerConfig’s PublicKeyCallback can store arbitrary data in the Permissions object and how the VerifiedPublicKeyCallback can read that data and modify the permissions before the SSH handshake completes. The program should:

1. Define a dummy public key and a dummy connection metadata. 2. Call PublicKeyCallback to obtain a Permissions object that contains a custom value in ExtraData. 3. Call VerifiedPublicKeyCallback with the same key and the permissions returned above. 4. Print the final permissions to show that the VerifiedPublicKeyCallback was able to read and modify the data.

The goal is to see the flow of data between the two callbacks, not to actually start an SSH server.

---

Startergo
package main

import (
	"fmt"
)

// Dummy types that mimic the real ssh package.
type ConnMetadata struct{ User string }
type PublicKey struct{ Key string }

// Permissions holds authentication permissions and arbitrary data.
type Permissions struct {
	CriticalOptions map[string]string
	Extensions      map[string]string
	ExtraData       any
}

// ServerConfig holds the callbacks.
type ServerConfig struct {
	PublicKeyCallback       func(conn ConnMetadata, key PublicKey) (*Permissions, error)
	VerifiedPublicKeyCallback func(conn ConnMetadata, key PublicKey, permissions *Permissions) (*Permissions, error)
}

func main() {
	// The exercise starts here.  Your code should go below this line.
}
Show a solution
Solutiongo
package main

import (
	"fmt"
)

// Dummy types that mimic the real ssh package.
type ConnMetadata struct{ User string }
type PublicKey struct{ Key string }

// Permissions holds authentication permissions and arbitrary data.
type Permissions struct {
	CriticalOptions map[string]string
	Extensions      map[string]string
	ExtraData       any
}

// ServerConfig holds the callbacks.
type ServerConfig struct {
	PublicKeyCallback        func(conn ConnMetadata, key PublicKey) (*Permissions, error)
	VerifiedPublicKeyCallback func(conn ConnMetadata, key PublicKey, permissions *Permissions) (*Permissions, error)
}

func main() {
	// Create a server config with both callbacks.
	cfg := ServerConfig{
		PublicKeyCallback: func(conn ConnMetadata, key PublicKey) (*Permissions, error) {
			// Store some user‑defined data in ExtraData.
			return &Permissions{
				CriticalOptions: map[string]string{"no-port-forwarding": ""},
				Extensions:      map[string]string{"permit-pty": ""},
				ExtraData:       fmt.Sprintf("user=%s key=%s", conn.User, key.Key),
			}, nil
		},
		VerifiedPublicKeyCallback: func(conn ConnMetadata, key PublicKey, perms *Permissions) (*Permissions, error) {
			// Read the data that was stored earlier and add a new field.
			if data, ok := perms.ExtraData.(string); ok {
				perms.ExtraData = fmt.Sprintf("%s | verified=true", data)
			}
			return perms, nil
		},
	}

	// Simulate a connection and a public key.
	conn := ConnMetadata{User: "alice"}
	key := PublicKey{Key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy..."}

	// Step 1: PublicKeyCallback is called.
	perms, err := cfg.PublicKeyCallback(conn, key)
	if err != nil {
		fmt.Println("PublicKeyCallback error:", err)
		return
	}
	fmt.Println("After PublicKeyCallback:", perms)

	// Step 2: VerifiedPublicKeyCallback is called with the same key and permissions.
	perms, err = cfg.VerifiedPublicKeyCallback(conn, key, perms)
	if err != nil {
		fmt.Println("VerifiedPublicKeyCallback error:", err)
		return
	}
	fmt.Println("After VerifiedPublicKeyCallback:", perms)
}

What it printed when we ran it on Go 1.27.1

After PublicKeyCallback: &{map[no-port-forwarding:] map[permit-pty:] user=alice key=ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy...}
After VerifiedPublicKeyCallback: &{map[no-port-forwarding:] map[permit-pty:] user=alice key=ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy... | verified=true}

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.

The 60-second version

This week the Go team added several new features to the standard library. First, the SSH package now lets servers run a callback after a client proves control over a key, and the permissions object can carry arbitrary data. Second, the type checker received two new hasher types that make it easier to hash and compare types consistently, with or without struct tags. Third, XML marshaling gained an “omitzero” tag that omits fields whose values are zero, mirroring the JSON behavior. The releases of Go 1.23.11 and 1.24.5 bring security and bug fixes to the toolchain. Finally, a blog post reminded us that adding type parameters to interfaces opens up surprisingly powerful patterns. These changes expand the expressiveness of Go’s core packages while keeping the language stable and secure.

Written by gpt-oss-20b · claims checked against the sources · archive, not individually reviewed