Releases: rockorager/ziglint
v0.5.2
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:
-
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.
-
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 rootstd.zigfile.
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 analysisThese 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.2Or download pre-built binaries from the release assets.
v0.5.1
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 ofTagPayloadwith@field()std.enums.nameCast()- deprecated in favor of@enumFromInt(@intFromEnum())std.unicode.utf8Decode()- deprecated in favor ofutf8DecodeAssumeValid()- 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.trimLeftwithstd.mem.trimStart - Fixed Z007 violations: eliminated 20 duplicate
ModuleGraphimports across test functions - Added test cases for deprecated functions we don't yet detect (marked as skipped for future work)
Improvements
- Added
--verboseflag 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.1Or download pre-built binaries from the release assets.
v0.5.0
What's New
Three new naming convention rules based on the official Zig Style Guide:
- Z031: Avoid underscore prefix in identifiers - detects
_like_thisnaming pattern - Z032: Acronyms should use standard casing - detects
XMLParser(should beXmlParser) - 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/ziglintv0.4.1
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/ziglintv0.4.0
What's New
New Rules
- Z028: Inline
@importshould be assigned to a top-levelconst - Z030:
deinitfunctions should setself.* = 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/ziglintv0.3.0
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 returnpatterns - Z026: Suppressed-errors rule - flags error suppression patterns
- Z027: Flag instance access to container-level decls
- Z029: Detect redundant
@asin 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
--helpand--versionnow 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-linuxbuild target to CI and releases
Installation
mise use github:rockorager/ziglintv0.2.2
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/ziglintv0.2.1
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/ziglintv0.2.0
What's New
New Rules
- Z017: Flag redundant
tryin return statements (return try expr→return expr) - Z018: Flag redundant
@aswhen 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 beSelf
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/ziglintOr download binaries from the release assets.
v0.1.0
What's New
- Initial release of ziglint
- Zig linting and style checks
- Cross-platform support (macOS, Linux, Windows)
Installation
mise use github:rockorager/ziglintOr download binaries from the release assets.