EDITORS: THIS HAS BEEN PRODUCED BY SOFTWARE UNDER DEVELOPMENT - THE CONTENT MAY REQUIRE EXTENSIVE EDITING
https://vincent.bernat.ch/en/blog/2026-go-netip-addrto6 [bernat.ch]
netip.Addr features an Unmap() method returning the unwrapped IPv4 contained in an IPv4-mapped IPv6 address: from ::ffff:203.0.113.10 or ::ffff:cb00:710a, it returns 203.0.113.10. There is no Map() or To6() method for the reverse direction. Such a method is trivial to implement, but Go maintainers have rejected it on the grounds that users should write netip.AddrFrom16(ip.As16()) and let the compiler optimize it. Today, this pattern is eight times slower than a native method. How can we teach the compiler to optimize this sequence?
Let's explore three ways to implement the map semantics for netip.Addr. My favorite is to add it to the Go standard library. Go maintainers prefer a small external helper chaining netip.AddrFrom16() and netip.Addr.As16(), hoping the compiler eventually optimizes it. The unsafe package opens a third path, with the same performance as the first solution.
[...]
The Go compiler has several phases:
- Parsing: The compiler tokenizes and parses the source code. It builds a syntax tree for each source file.
- Type checking: The compiler maps each identifier to the object it denotes, folds constants, and infers the type of every expression.
- IR construction: The compiler converts the syntax tree and its types into its own intermediate representation (IR). This process, called "noding," goes through a serialization format named unified IR.
- Middle end: The compiler performs several optimization passes on the IR, such as devirtualization, function call inlining, and escape analysis.
- Walk: This phase runs two steps: order of evaluation decomposes complex statements into simpler ones, and desugaring transforms higher-level Go constructs, like switch or channels, into more primitive instructions or calls to the runtime.
- Generic SSA: The compiler converts the IR into Static Single Assignment (SSA) form, a lower-level intermediate representation suited for machine-independent optimizations and rewrite rules.
- Machine code generation: The compiler rewrites the SSA form into machine-specific variants, allocates registers, and applies more optimization passes. At the end, the assembler turns the generated instructions into machine code.