Skip to content

Releases: rockorager/ziglint

v0.5.3

Choose a tag to compare

@github-actions github-actions released this 20 Jul 11:53
v0.5.3
80d2b08

Safer, More Accurate Lint Fixes

This release focuses on making ziglint diagnostics safe to follow. Suggested
changes now better preserve Zig semantics, avoid false positives, and provide
enough context to produce compiling fixes.

Highlights

  • Z017 now consistently flags return try expression and recommends hoisting
    try into a local. This preserves payload coercions such as !Thing to
    !?Thing that can break when try is simply removed.
  • Z002 now recommends valid discard assignments (_ = expression;) or a
    normally named binding instead of misleading underscore declarations.
  • Z003 includes the parser's actual error and precise source offset.
  • Z004 uses the declaration's real type and tells users to preserve declaration
    kind, modifiers, and initializer fields.
  • Z010 only removes explicit struct initializer types when a resolved concrete
    parameter expects that same type. Generic and unresolved calls are left
    unchanged.
  • Z016 only rewrites verified std.debug.assert calls, avoiding duplicated side
    effects in project-defined assert functions.
  • Z020 recommends the enclosing type name in named structs and Self in
    anonymous structs.
  • Z023 consistently places all comptime parameters before Allocator, Io, and
    ordinary runtime parameters.
  • Z028 allows _ = @import(...) only in test blocks.
  • Z030 uses the actual deinit receiver name and accepts early-return branches
    that explicitly invalidate it.
  • Z033 now applies its vague-name policy only to type names, not ordinary
    functions such as processData.

Additional corrections clarify deprecation markers, private error-set API
impact, accepted @This() aliases, and Z024's byte-based line-length limit.

Test Coverage

Documentation examples can now include compiler probes. Important suggested
rewrites are checked with zig test as well as ziglint, including the nullable
error-union coercion that motivated the Z017 change.

Installation

mise use github:rockorager/ziglint@v0.5.3

Or download a pre-built binary from the GitHub release assets.

v0.5.2

Choose a tag to compare

@github-actions github-actions released this 08 Feb 11:00
v0.5.2
74db04d

Performance Improvements

Module graph construction is now 3000x faster! 🚀

Dramatically improved module graph build performance through two key optimizations:

Before: ~1850ms to analyze build.zig (loading 308 modules from std with ZIR)
After: ~0.6ms to analyze build.zig (loading 2 modules without ZIR)

What changed:

  1. Disabled ZIR generation - ZIR was added proactively in v0.4.0 for future control flow analysis (issue #18), but no rules currently use it. Generating ZIR took 10-50ms per module.

  2. Skip recursing into std library - When linting user code like build.zig, we don't need to parse all 300+ modules from the standard library. Now we only load the root std.zig file.

Impact on real-world usage:

# Linting a single file that imports std
Before: ~2 seconds
After:  ~0.4 seconds (5x faster)

# Linting entire src/ directory
Before: Previously slow on large projects
After:  Dramatically faster startup and analysis

These optimizations can be easily reverted if control flow analysis is implemented in the future (see well-documented code comments in src/ModuleGraph.zig).

Technical Details

  • ZIR generation infrastructure remains in place and can be re-enabled by uncommenting documented code sections
  • Module graph now loads only user code + top-level std.zig instead of recursively parsing the entire standard library
  • All tests pass; linter functionality unchanged
  • Verified against GitHub history: ZIR added in commit 14bbe87 but never used by any rules

Installation

mise use github:rockorager/ziglint@v0.5.2

Or download pre-built binaries from the release assets.

v0.5.1

Choose a tag to compare

@github-actions github-actions released this 08 Feb 10:47
v0.5.1
1e4b8d9

Bug Fixes

Z011: Fixed deprecation detection in nested contexts

Previously, ziglint failed to detect deprecated function calls inside try expressions, catch blocks, and other nested AST contexts. This was due to incomplete AST traversal in the linter.

Fixed detection for:

  • std.meta.intToEnum() - deprecated in favor of @enumFromInt()
  • std.meta.TagPayloadByName() - deprecated in favor of TagPayload with @field()
  • std.enums.nameCast() - deprecated in favor of @enumFromInt(@intFromEnum())
  • std.unicode.utf8Decode() - deprecated in favor of utf8DecodeAssumeValid()
  • And many other deprecated functions that were previously missed

Technical details:

  • Fixed visitChildren() to recursively visit all child nodes for unhandled AST node types
  • Now catches deprecations in try expressions, catch blocks, and other complex contexts
  • Added test corpus to prevent regressions

Example - now detects:

pub fn main() !void {
    // Previously missed, now detected:
    _ = try std.meta.intToEnum(MyEnum, 1);
}

Code Quality

  • Fixed Z011 violation in ziglint's own codebase: replaced deprecated std.mem.trimLeft with std.mem.trimStart
  • Fixed Z007 violations: eliminated 20 duplicate ModuleGraph imports across test functions
  • Added test cases for deprecated functions we don't yet detect (marked as skipped for future work)

Improvements

  • Added --verbose flag with timing information for performance analysis
  • Added per-rule timing breakdown to verbose output
  • Improved verbose output with colors and rule summary
  • Better directory linting with verbose logging

Known Limitations

Detection still requires improvement for:

  • Deprecated methods on local variables (requires flow analysis)
  • Deprecated const values that aren't function calls

Installation

mise use github:rockorager/ziglint@v0.5.1

Or download pre-built binaries from the release assets.

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 01 Feb 22:09
v0.5.0
3e1c909

What's New

Three new naming convention rules based on the official Zig Style Guide:

  • Z031: Avoid underscore prefix in identifiers - detects _like_this naming pattern
  • Z032: Acronyms should use standard casing - detects XMLParser (should be XmlParser)
  • Z033: Avoid redundant words in identifiers - detects "Value", "Data", "Context", "Manager", "State", "utils", "misc" (disabled by default)

Configuration

Z033 is disabled by default as it can be controversial. Enable it in .ziglint.zon:

.{
    .rules = .{
        .Z033 = .{ .enabled = true },
    },
}

Installation

mise use github:rockorager/ziglint

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 31 Jan 20:37
v0.4.1
2f8246f

What's New

Bug Fixes

  • Z020: No longer flags @This() when passed as a function argument (e.g., testing.refAllDecls(@This()))

Installation

mise use github:rockorager/ziglint

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 31 Jan 20:16
v0.4.0
978e2d3

What's New

New Rules

  • Z028: Inline @import should be assigned to a top-level const
  • Z030: deinit functions should set self.* = undefined

Bug Fixes

  • Z012: No longer flags pub types within the same enclosing struct as private
  • Z006: Allows camelCase function aliases (e.g., const foo = @import("std").debug.print)
  • Fixed directory traversal on Windows

Installation

mise use github:rockorager/ziglint

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 30 Jan 20:11
v0.3.0
a0ca75e

What's New

New Lint Rules

  • Z023: Argument order lint rule - flags comptime value params that should come before runtime params
  • Z024: Line length lint rule with config file support (zlint.json)
  • Z025: No-catch-return rule - detects catch return patterns
  • Z026: Suppressed-errors rule - flags error suppression patterns
  • Z027: Flag instance access to container-level decls
  • Z029: Detect redundant @as in result-location contexts

Improvements

  • Z006: Recognize more type expressions as type aliases including primitive types and PascalCase labeled blocks
  • Z011: Improved deprecated stdlib function detection
  • TypeResolver: Add type-vs-instance resolution and function call return type resolution
  • --help and --version now exit with code 0

Documentation

  • Added comprehensive documentation for all linter rules in docs/rules/
  • Added executable documentation tests for linter rules
  • Added nix devShell for development

Build

  • Added aarch64-linux build target to CI and releases

Installation

mise use github:rockorager/ziglint

v0.2.2

Choose a tag to compare

@github-actions github-actions released this 25 Jan 11:29
69211ea

What's New

  • Z006: recognize primitive types as valid type aliases
  • Fix Z019 false positive for local structs in large functions
  • Fix Z019 false positive for structs in if/while/for bodies

Installation

mise use github:rockorager/ziglint

v0.2.1

Choose a tag to compare

@github-actions github-actions released this 25 Jan 03:06
f405db2

What's New

  • Build system now caches the lint step properly, skipping re-runs when source files are unchanged
  • Diagnostics output to stderr for proper build system integration

Installation

mise use github:rockorager/ziglint

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 24 Jan 15:14
abd2898

What's New

New Rules

  • Z017: Flag redundant try in return statements (return try exprreturn expr)
  • Z018: Flag redundant @as when type is already known from context
  • Z019: @This() in named struct; use the type name instead
  • Z020: Inline @This(); assign to a constant first
  • Z021: File-struct @This() alias should match filename
  • Z022: @This() alias in anonymous/local struct should be Self

Improvements

  • Z006: Treat error set merges as type aliases
  • TypeResolver: Support aliased std imports
  • Fix Z017 message dim color leak
  • Fix addLint caching by using LazyPath

Removed Rules

  • Z008: Comment divider line rule (removed)

Installation

mise use github:rockorager/ziglint

Or download binaries from the release assets.