Support matrix
Feature by feature and package by package, from the test results.
Generated from marmot's test results of 2026-11-12. Every test builds a program with marmot and with Go and compares the output and exit status.
Status words: works (every test passes), partial (some fail), missing (not implemented), untested.
Conformance numbers
Every test compares stdout, stderr (up to the first panic line) and exit status with the stock Go toolchain.
| Tier | Passing | Total | What it covers |
|---|---|---|---|
| run/core | 134 | 134 | language core, no imports, println only |
| run/gc | 13 | 13 | allocation heavy programs |
| run/sched | 15 | 15 | goroutines, channels, deadlock |
| run/std | 235 | 238 | standard library by package |
| run/opt | 21 | 22 | optimizer and specializer targets |
| run/mem | 50 | 50 | use after free and lifetime hunting (every way a slice stays reachable) |
| run/layout | 49 | 49 | struct layouts: every field mix, every access path |
| run/audit | 33 | 41 | counterexamples from the spec and verify audits |
| run/apps | 12 | 12 | 200 to 600 line real programs |
| goroot | 98 | 108 | single file programs from the Go project's own test suite |
| world | 29 | 32 | real open source modules (vendored, pinned) |
| total (dev build) | 689 | 714 |
Other build modes in the same run:
| Mode | Passing | Total |
|---|---|---|
| dev | 689 | 714 |
| gcstress | 50 | 50 |
| lifetime | 49 | 50 |
Language
| Feature | Status | Tests |
|---|---|---|
| Integers: wraparound, shifts, division, conversions | works | 13 of 13 |
| Floats: NaN, infinities, conversions, printing | works | 6 of 6 Fused multiply-add follows gc on arm64. |
| Complex numbers | works | 2 of 2 |
| Strings, runes, UTF-8 iteration and conversion | works | 7 of 7 |
| Slices: append, copy, aliasing, capacity | works | 10 of 10 Growth capacities may differ from gc. |
| Arrays and structs: copy, compare, embedding | works | 9 of 9 |
| Maps, all key kinds, iteration with deletion | works | 8 of 8 Iteration order is random, as in gc. |
| Methods, method values and expressions | works | 2 of 2 |
| Closures and Go 1.22 loop variables | works | 4 of 4 |
| Interfaces, assertions, type switches | works | 12 of 12 |
| Generics: functions, types, constraints | works | 5 of 5 |
| defer, panic, recover | works | 18 of 18 |
| Runtime panics: bounds, nil, divide, assertions | works | 8 of 8 Message text matches gc; the stack trace format differs. |
| Control flow: labels, goto, switch, range over int and func | works | 10 of 10 |
| Constants and iota | works | 2 of 2 |
| Initialization order and init functions | works | 2 of 2 |
| Evaluation order | works | 2 of 2 Variables are read after calls in the same expression, as gc does. |
| Goroutines, channels, select | works | 26 of 26 |
| Garbage collection (allocation heavy programs) | works | 13 of 13 |
| unsafe | works | 5 of 5 |
| Compiler optimizations preserve semantics | partial | 21 of 22 Loop, specialization and float tests; run at -O0, -O2, -Oz and -release. |
| Real programs (parsers, interpreters, simulations) | works | 12 of 12 |
| cgo | missing | non-goal for v1 |
| Race detector (-race) | missing | non-goal for v1 |
| plugin package | missing | non-goal for v1 |
| DWARF debug info | missing | non-goal for v1 |
| Windows | missing | non-goal for v1 |
Standard library
Each row is a directory under tests/run/std. Packages not listed have no test yet.
| Packages | Status | Tests |
|---|---|---|
| sync/atomic | works | 10 of 10 |
| bufio | works | 11 of 11 |
| bytes | works | 10 of 10 |
| compress/* | works | 1 of 1 |
| encoding/{base32,base64,hex,binary,csv,xml,gob,asn1,pem,ascii85} | works | 4 of 4 |
| errors | works | 10 of 10 |
| path, path/filepath | works | 5 of 5 |
| fmt | works | 14 of 14 |
| container/{heap,list,ring} | works | 3 of 3 |
| net/http, httptest, cookiejar, crypto/tls | works | 8 of 8 |
| io | works | 11 of 11 |
| encoding/json | works | 8 of 8 |
| log | partial | 1 of 2 |
| maps | works | 10 of 10 |
| math, math/bits, math/cmplx | works | 12 of 12 |
| net, net/netip | works | 6 of 6 |
| os, os/user | works | 12 of 12 |
| math/rand | works | 3 of 3 |
| reflect | partial | 7 of 8 |
| regexp | works | 6 of 6 |
| runtime, runtime/debug | missing | 0 of 1 |
| slices, cmp | works | 10 of 10 |
| log/slog | works | 1 of 1 |
| sort | works | 10 of 10 |
| database/sql | works | 1 of 1 |
| strconv | works | 10 of 10 |
| strings | works | 10 of 10 |
| sync | works | 12 of 12 |
| text/template | works | 5 of 5 |
| time, time/tzdata | works | 14 of 14 |
| unicode, unicode/utf8, unicode/utf16 | works | 10 of 10 |
Stock standard library tests under marmot test
Results of marmot test -short on stock packages (darwin/arm64 laptop, 2026-11-12, before the fixes). "alloc counts only" means every failure is a testing.AllocsPerRun count.
| package | result | pass | fail | rate |
|---|---|---|---|---|
| fmt | ok | 79 | 0 | 100% |
| strings | FAIL | 146 | 5 | 97% |
| bytes | FAIL | 175 | 3 | 98% |
| strconv | FAIL | 69 | 11 | 86% |
| sort | ok | 81 | 0 | 100% |
| slices | FAIL | 162 | 3 | 98% |
| maps | ok | 24 | 0 | 100% |
| math | ok | 111 | 0 | 100% |
| unicode | ok | 42 | 0 | 100% |
| unicode/utf8 | FAIL | 30 | 1 | 97% |
| time | FAIL | 46 | 2 | 96% |
| sync | build | 0 | 0 | - |
| sync/atomic | ok | 107 | 0 | 100% |
| context | FAIL | 68 | 1 | 99% |
| errors | ok | 92 | 0 | 100% |
| io | FAIL | 77 | 2 | 97% |
| bufio | FAIL | 88 | 1 | 99% |
| os | FAIL | 3525 | 11 | 100% |
| os/exec | FAIL | 23 | 57 | 29% |
| os/signal | FAIL | 5 | 1 | 83% |
| path | ok | 16 | 0 | 100% |
| path/filepath | FAIL | 59 | 1 | 98% |
| encoding/json | FAIL | 0 | 1 | 0% |
| encoding/binary | build | 0 | 0 | - |
| encoding/base64 | ok | 23 | 0 | 100% |
| encoding/hex | ok | 18 | 0 | 100% |
| encoding/csv | ok | 77 | 0 | 100% |
| encoding/xml | FAIL | 332 | 3 | 99% |
| encoding/pem | ok | 21 | 0 | 100% |
| regexp | ok | 75 | 0 | 100% |
| text/template | FAIL | 58 | 1 | 98% |
| html/template | FAIL | 0 | 0 | - |
| text/tabwriter | ok | 6 | 0 | 100% |
| text/scanner | ok | 22 | 0 | 100% |
| net/url | FAIL | 89 | 5 | 95% |
| net/http | build | 0 | 0 | - |
| net/http/httptest | FAIL | 51 | 3 | 94% |
| net | FAIL | 9 | 0 | 100% |
| mime | FAIL | 24 | 1 | 96% |
| mime/multipart | FAIL | 49 | 4 | 92% |
| crypto/sha256 | FAIL | 33 | 2 | 94% |
| crypto/md5 | FAIL | 17 | 1 | 94% |
| crypto/sha1 | FAIL | 17 | 1 | 94% |
| crypto/hmac | ok | 233 | 0 | 100% |
| crypto/rand | FAIL | 14 | 2 | 88% |
| crypto/aes | ok | 58 | 0 | 100% |
| crypto/tls | FAIL | 0 | 0 | - |
| crypto/x509 | FAIL | 0 | 0 | - |
| hash/crc32 | ok | 18 | 0 | 100% |
| hash/fnv | ok | 62 | 0 | 100% |
| container/heap | ok | 9 | 0 | 100% |
| container/list | ok | 11 | 0 | 100% |
| container/ring | ok | 15 | 0 | 100% |
| math/rand | FAIL | 25 | 2 | 93% |
| math/rand/v2 | ok | 25 | 0 | 100% |
| math/big | FAIL | 266 | 1 | 100% |
| math/bits | build | 0 | 0 | - |
| reflect | build | 0 | 0 | - |
| runtime | build | 0 | 0 | - |
| log | FAIL | 9 | 2 | 82% |
| log/slog | FAIL | 225 | 29 | 89% |
| flag | FAIL | 28 | 1 | 97% |
| embed | build | 0 | 0 | - |
| io/fs | FAIL | 5 | 0 | 100% |
| compress/gzip | ok | 23 | 0 | 100% |
| compress/flate | ok | 128 | 0 | 100% |
| archive/tar | FAIL | 1 | 2 | 33% |
| archive/zip | FAIL | 0 | 0 | - |
| html | ok | 6 | 0 | 100% |
| go/token | FAIL | 25 | 1 | 96% |
| go/scanner | ok | 25 | 0 | 100% |
| go/parser | FAIL | 42 | 0 | 100% |
| go/ast | FAIL | 23 | 1 | 96% |
| go/format | ok | 5 | 0 | 100% |
| go/types | FAIL | 70 | 1 | 99% |
| iter | FAIL | 10 | 10 | 50% |
| unique | build | 0 | 0 | - |
Real world modules
Vendored at a pinned version under tests/world (see tests/world/README.md), each with a small deterministic program checked against stock Go.
| Module test | Status |
|---|---|
| base58 | works |
| blackfriday | works |
| cobra | works |
| decimal | works |
| difflib | works |
| doublestar | works |
| embedfs | works |
| fuzzysearch | works |
| gjson | works |
| gocmp | works |
| godiff | works |
| goldmark | works |
| gotoml | works |
| govaluate | works |
| humanize | works |
| ini | works |
| levenshtein | works |
| lru | works |
| mapstructure | fails |
| pflag | works |
| pkgerrors | works |
| rate | works |
| semver | works |
| strcase | works |
| tablewriter | works |
| testify | fails |
| toml | works |
| ulid | fails |
| uuid | works |
| xtext | works |
| xxhash | works |
| yaml | works |
29 of 32 world programs pass.
Build modes
- dev (default,
-O2): the safe pipeline; every transform below that is marked off stays off. -release: whole program optimization,-O3, loop and library specializations.-O0-O1-O2-O3-Os-Oz: LLVM level; the conformance runner can run any program in-O0,-O2,-Ozand-release(-modes).- Opt-in lifetime and memory transforms, each behind an environment switch. A transform is on by default only after a proof review and a full conformance matrix plus fuzz round with it forced on; until then it is off.
| Transform | Switch | Default |
|---|---|---|
| In-place reuse (reuse.go) | MARMOT_REUSE | off |
| Capture by value (escape.go allocSettled) | MARMOT_BYVALUE | off |
| Region inference (region.go) | MARMOT_REGIONS | off |
| Frame regions (frameregion.go) | MARMOT_FRAME_REGIONS | off |
| Allocation sinking (allocsink.go) | MARMOT_ALLOCSINK | off |
| Escape summaries, cross package, extended rules | MARMOT_ESCAPE_SUMMARY, MARMOT_XPKG_ESCAPE, MARMOT_ESCAPE_EXT | off |
| Conversion and make frame buffers (stackconv.go) | MARMOT_STACKCONV | off |
| Intraprocedural escape (default path) | on | on |
| go-strings S3 no-copy (backend) | -no-strings-nocopy | on |
| Defer record elision (panics.go) | MARMOT_DEFERELIDE | off |
| Dead initializer removal (staticinit.go) | MARMOT_DEADINIT | off |
| Allocation without zeroing (rtcore rt_alloc_nozero, 569d095; poison fill c8e0a15) | callers only | on |
Stress modes used by the conformance runner: gcstress (MARMOT_GCSTRESS=1), poison (MARMOT_POISON=1), lifetime (MARMOT_LIFETIME=all).
Targets
| Target | Status | Tested |
|---|---|---|
| darwin/arm64 | primary | all tiers above |
| linux/amd64 | cross compiled on macOS, run on a Linux test host | 99 of 99 conformance tests pass (tree 2c645f1) |
| linux/arm64 | not tested |
Tools
marmot build [flags] [packages or files]:-o,-O {0,1,2,3,s,z}(default 2),-release(whole program,-O3, loop and library specializations),-emit {mlir,llvm,obj,exe},-dialect {llvm,go},-gc {precise,none},-target,-tags,-nocache,-v,-x,-work.marmot run [flags] file.go [args]: build and run.marmot test [-v] [-run RE] [-skip RE] [-bench RE] [-count N] [-timeout D] [packages]: builds thego list -testmain and runs it in the package directory.marmot version.
Known differences from gc
- Panic output prints the same message and exits with status 2; the traceback below
goroutine N [running]:is gc style but frames of inlined functions do not appear. - Floating point uses the same fused multiply-add rule as gc on arm64 (
x*y+zfuses, an explicit conversion does not). - Variables are read after calls in the same expression, as gc does (the spec leaves this unspecified).
runtime.Callerand friends work from a pc table; binaries built with-shave none.- NaN payloads. Where the Go specification only says the result is a NaN, marmot may return a different NaN (payload and sign bits) than gc: the builtin
minandmax(also over slices, soslices.Minandslices.Max),math.Max,math.Min, andmath.Floor,Ceil,Trunc,RoundandRoundToEvenof a signaling NaN (gc quiets it, marmot may return it unchanged). The value is a NaN in every case; onlymath.Float64bits,math.Float32bitsorunsafeshows the difference, and gc itself differs here across architectures. Values that are not NaN are bit identical to gc on the same architecture; a difference there is a bug. Programs:tests/run/audit/minmax_nan_payload,tests/run/audit/math_exp_log_bits. - Slice growth capacities and map iteration order are not guaranteed to equal gc's.
- Evaluation order: variables are read after the calls of the same expression; open cases are tracked in
tests/run/audit/evalorder_gaps. - Unexported methods of embedded types from different packages with the same name: see
world/audit_unexportedunder open failures. - cgo, the race detector, plugins, DWARF and Windows are not supported.
reflect: see the open failures below for the current gaps.
Open failures
Listed in tests/known_failures.txt; a test that passes is removed from the list.
goroot/genmeth1:goroot/range4:goroot/reflectmethod1:goroot/reflectmethod2:goroot/reflectmethod3:goroot/reflectmethod4:goroot/reflectmethod5:goroot/reflectmethod6:goroot/reflectmethod7:goroot/shift3:run/std/reflect/kinds_names:run/opt/fma_fusion_gc: gc fuses x*y+z on arm64, marmot does not (spec allows both)run/opt/panic_in_loop@Oz: recovered panic then nil deref panic is not recoverable at -Ozrun/std/runtime/goroutines_gc: runtime.Caller unsupported (no pc to file:line table yet)run/std/log/basic: runtime.Caller unsupported, log.Lshortfile prints ???:0world/ulid: return id, parse(&id): gc reads variables after calls (see core/eval_order_var_after_call)run/mem/regionstore@lifetime: MARMOT_LIFETIME=all: region store use-after-free, expected until fixedworld/audit_unexported: unexported methods of different packages are confused in itabsrun/audit/deadinit_bigmake: huge make: fatal "out of memory" instead of the makeslice panic (dead initializer removal)run/audit/defer_builtin_recover: recover() result lost for a deferred builtinrun/audit/evalorder_gaps: map index evaluation order differs from gcrun/audit/fma_complex_mul: complex multiply: fused multiply-add bits differ from gcrun/audit/make_huge_const: make with a huge constant length does not panic like gcrun/audit/math_exp_log_bits: math.Exp(-745.13) returns 0x1, gc 0x0 (value difference, not a NaN payload)run/audit/method_value_nil_iface: method value of a nil interface panics with the wrong messagerun/audit/tempstring_write: temporary string written through (no-copy conversion)