Skip to content

chore(deps): update module dev.gaijin.team/go/exhaustruct/v5 to v5.2.0 - #8928

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/dev.gaijin.team-go-exhaustruct-v5-5.x
Open

chore(deps): update module dev.gaijin.team/go/exhaustruct/v5 to v5.2.0#8928
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/dev.gaijin.team-go-exhaustruct-v5-5.x

Conversation

@renovate

@renovate renovate Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
dev.gaijin.team/go/exhaustruct/v5 v5.0.3v5.2.0 age confidence

Release Notes

GaijinEntertainment/go-exhaustruct (dev.gaijin.team/go/exhaustruct/v5)

v5.2.0

Compare Source

A minor release adding one option. -allow-empty-blank-assignments exempts an empty struct literal the blank identifier receives, so a compile-time interface check such as var _ Iface = T{} is no longer asked to fill fields nothing reads. The option is off by default; with it off, nothing changes.

Added
  • -allow-empty-blank-assignments (#​153). var _ Iface = T{} exists to prove that T implements Iface, and the analyzer required every field of a value that is discarded on the spot. The only allowance that reached the shape, -allow-empty-declarations, let every declared literal through with it. The new option keys on what receives the value: the blank identifier reads no field, so no field is required. It covers var _ Iface = T{}, var _ = T{} and _ = T{}, with &T{} and parentheses on either side, at package or function level.

    type Handler interface{ Serve() }
    
    type Server struct {
        Addr string
        Port int
    }
    
    func (Server) Serve() {}
    
    var _ Handler = Server{}       // OK
    var _ Handler = &Server{}      // OK
    var _, s = Server{}, Server{}  // Server is missing fields Addr, Port

    A value is matched to its name by position, so in the last line the literal bound to s is still reported. A literal nested in the value (_ = []Server{{}}), a converted one (_ = Handler(Server{})) and a partial one stay reported: the blank identifier receives the slice, the conversion result, or a value with fields already named.

    The programmatic name is Config.AllowEmptyBlankAssignments.

Upgrading
go install dev.gaijin.team/go/exhaustruct/v5/cmd/exhaustruct@latest

CLI users reinstall and add the flag where they want it. Existing configuration is unchanged and no finding moves until the option is turned on.

golangci-lint users need a matching allow-empty-blank-assignments key under exhaustruct_v5 settings before they can turn it on. That key lives in the golangci-lint repository and is not part of this release.

v5.1.0

Compare Source

A release for Go 1.27 code. Literals that name promoted fields no longer crash the analyzer or get reported as incomplete, -fix writes source that compiles and keeps every field's optionality, and a set of resolution gaps that predate Go 1.27 are closed. The module now requires Go 1.26.

Breaking changes
  • Go 1.26 or newer is required. x/tools v0.40.0 cannot read the export data Go 1.27 writes, so every run on that toolchain failed with internal error: package "sync/atomic" without types. The v0.49.0 release that reads it needs go1.25; the floor goes to 1.26, which golangci-lint v2.13 already requires for this analyzer. Consumers on Go 1.24 or 1.25 cannot build this version.
Fixes
  • makeslice: cap out of range on promoted keys (#​168). Go 1.27 lets a composite literal name a promoted field in place of the embedded field carrying it (golang/go#77245). A literal naming more promoted fields than the struct has direct ones drove a capacity estimate negative and took golangci-lint down with it.

  • Complete literals reported as incomplete (#​161). Every promoted key counted as a key the struct did not have, so A{b: "foo", a: 1, c: "f"} was reported as missing the embedded field it filled through. Promoted keys now resolve through the embedded field tree: a literal that names nothing under an embedded field is missing that field, one that fills it partly is missing the fields under it, each nameable from the same literal.

    type Base struct{ ID, Name string }
    type Server struct {
        Base
        Port int
    }
    
    _ = Server{ID: "1", Name: "a", Port: 8080} // OK
    _ = Server{ID: "1", Port: 8080}            // Server is missing field Name
    _ = Server{Port: 8080}                     // Server is missing field Base

    The Go version of the file holding the literal decides whether promoted keys are possible, not the version the module declares, so a //go:build go1.26 file in a go1.27 module is read as the older one.

  • Struct metadata cached by position. Export data drops the column and clamps lines past 64Ki to 1, so two types declared in one dependency file collapsed onto one cache entry and a literal was checked against another type's fields. The cache is keyed by the go/types objects, which are unique per declaration, and each key is filled once across concurrently analysed packages.

  • Pattern alternations that matched nothing. Go's regexp is leftmost-first, so .*\.(Config|ConfigOption) committed to Config against pkg.ConfigOption, stopped short of the end, and the pattern was silently ignored. Patterns now match leftmost-longest, compiled exactly as written.

  • -fix output that did not compile or changed what is required. Migrating an exhaustruct:"optional" tag could comment out a single-line struct's closing brace, write a directive over one the author had already placed, or turn an enforced field optional. Tags are read and removed by the grammar reflect.StructTag reads, other entries in the tag survive, an interpreted-string tag migrates like a raw one, and the directive lands where the directive scanner resolves it to the field. Every deprecated tag is migrated, including one on a type the configuration excludes from checking.

  • Directives in block comments and with trailing prose. /*exhaustruct:optional*/ now applies, which is the one form that annotates a field name inline, and prose after a directive is no longer reported as an unknown directive named "". A directive is matched to code by every line its comment covers, so a block comment reaches the code beside either end of it.

  • Literal types that fell through. Map keys resolve against the key type rather than the value type, []PtrAlias{{...}} and []PtrDefined{{...}} are checked, a literal of a type parameter is checked against the struct its constraint's terms share, and an alias to an anonymous struct carries its own directives.

  • Directives above a statement reach the literals inside it, as they did in v4. A //exhaustruct:ignore above a slice, map, call or return covers the literals nested in it, and redundant parentheses no longer end the walk.

  • Diagnostics for a dependency's directives reach the package that owns the file, not the first importer to resolve a type from it.

  • Blank fields (_) are never reported for a keyed literal, since no key can name them.

Changed behaviour
  • A field no literal can write is required by nothing, whatever a directive or a pattern says about it: an unexported field of another package's struct, a promoted field a shallower one shadows, and a name two embedded fields promote at one depth.

  • A field marked //exhaustruct:enforce under an embedded field that the enclosing type left unrequired is still required. From Go 1.27 the enforced field itself is reported; below it the embedded field is, since that is the one key that reaches it.

  • type P = *Config and type Q *Config carry their own type-level directives and patterns, and a literal eliding &Config under one of them is reported as that type. A plain *Config still answers as Config.

  • A field pattern (Type#Field) is a rule for that field even when another pattern names the type holding it. Only a single pattern broad enough to match both names no field in particular.

  • In either comment form the directive opens the comment, as //go:build does: /* exhaustruct:optional */ with a space is prose. A directive name written after a separator and a space, as in //exhaustruct:optional, enforce, is reported instead of being dropped in silence.

Performance

Resolving a type opens each embedded struct once, at the depth it is first reached, where the walk previously cost one subtree per path through the embedding graph and twenty shared layers took 2.8 GB. A literal's keys are arranged once for the whole descent, instantiations of a generic type share their declaration's metadata, a constraint's interfaces are resolved once per walk, filled cache keys are answered under the read lock, and a file's directive scan builds only the lines a directive comment can share with code.

Internal
  • CI lints again: the lint job passed an empty Go version and --issues-exit-code 0, so it could not fail. Lint now gates the build against a pinned golangci-lint, the suite runs under the race detector, and a dogfood job runs the analyzer built from the checkout over the checkout.
  • The type-origin scanner, whose IsAlias/IsDerived results nothing read, is gone.
  • The README documents promoted fields, blank fields, both comment forms, type-parameter literals, pointer type names, and how field patterns and type patterns interact.
Upgrading
go install dev.gaijin.team/go/exhaustruct/v5/cmd/exhaustruct@latest

Toolchain 1.26 or newer, then reinstall. Configuration is unchanged. Findings move only where the analyzer was wrong before: promoted keys, blank fields, the newly resolved literal types, pattern alternations, use-site directive scope, and the enforced-under-optional case above.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the dependencies Pull requests that update a dependency file label Sep 4, 2026
@renovate
renovate Bot requested a review from dmathieu as a code owner September 4, 2026 16:47
@renovate renovate Bot added the Skip Changelog PRs that do not require a CHANGELOG.md entry label Sep 4, 2026
@renovate
renovate Bot requested a review from flc1125 as a code owner September 4, 2026 16:47
@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.5%. Comparing base (b42f111) to head (5d2e9f9).

Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff          @@
##            main   #8928   +/-   ##
=====================================
  Coverage   88.5%   88.5%           
=====================================
  Files        333     333           
  Lines      21100   21100           
=====================================
+ Hits       18682   18684    +2     
+ Misses      2418    2416    -2     

see 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@renovate
renovate Bot force-pushed the renovate/dev.gaijin.team-go-exhaustruct-v5-5.x branch from 2835bb9 to ec9f3a7 Compare September 4, 2026 20:38
@renovate renovate Bot changed the title chore(deps): update module dev.gaijin.team/go/exhaustruct/v5 to v5.1.0 chore(deps): update module dev.gaijin.team/go/exhaustruct/v5 to v5.2.0 Sep 4, 2026
@renovate
renovate Bot force-pushed the renovate/dev.gaijin.team-go-exhaustruct-v5-5.x branch from ec9f3a7 to 8315bd0 Compare September 6, 2026 18:27
@renovate
renovate Bot force-pushed the renovate/dev.gaijin.team-go-exhaustruct-v5-5.x branch from 8315bd0 to 5d2e9f9 Compare September 7, 2026 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file Skip Changelog PRs that do not require a CHANGELOG.md entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants