Skip to content

Rule: prefer explicit type annotation with anonymous method calls #21

@mattrobenolt

Description

@mattrobenolt

Overview

Add a rule that encourages using explicit type annotations with anonymous method syntax (Result Location Semantics) instead of calling methods directly on type names.

Examples

Bad

var allocator = std.heap.ArenaAllocator.init(backing);
var list = std.ArrayList(u8).init(allocator);
var map = std.StringHashMap(u32).init(allocator);
var f = Foo.init();
var parser = Parser.create(input);

Good

var allocator: std.heap.ArenaAllocator = .init(backing);
var list: std.ArrayList(u8) = .init(allocator);
var map: std.StringHashMap(u32) = .init(allocator);
var f: Foo = .init();
var parser: Parser = .create(input);

Rationale

  • Explicit type annotations improve readability - the type is visible at the declaration site
  • Consistent with Zig's Result Location Semantics design
  • Follows the same philosophy as Z004 (prefer const x: T = .{} over const x = T{})
  • The anonymous .method() syntax is idiomatic Zig

Detection

Flag when:

  1. A variable declaration has no type annotation (var_decl.ast.type_node == .none)
  2. The initializer is a function call
  3. The callee is a field access where the LHS is a type (PascalCase identifier or field access chain ending in PascalCase)

Limitations

Without full type resolution, we can't verify that Type.method() actually returns Type. The suggestion may not be valid if the method returns a different type. However:

  • The compiler will catch invalid cases
  • This pattern is overwhelmingly used for constructors that return Self/@This()

A heuristic-based implementation could ship now, with improved accuracy once #22 (type resolution infrastructure) lands.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions