Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rule: inferable-type-not-used #194

Open
paperclover opened this issue Jan 8, 2025 · 1 comment
Open

rule: inferable-type-not-used #194

paperclover opened this issue Jan 8, 2025 · 1 comment
Labels
A-linter Area - linter and lint rules C-rule Category - Lint rule suggestion

Comments

@paperclover
Copy link

paperclover commented Jan 8, 2025

Description

When a value is assigned, returned, or otherwise has a RLS with a static type, disallow re-specifying that type. This mostly means changing struct literals to anonymous struct literals, removing redundant @as, or using a decl literal over a namespace.

Motivating example:

 pub fn fstat(_: *NodeFS, args: Arguments.Fstat, _: Flavor) Maybe(Return.Fstat) {
     return switch (Syscall.fstat(args.fd)) {
         .result => |result| .{ .result = Stats.init(result, false) },
-        .err => |err| Maybe(Return.Fstat){ .err = err },
+        .err => |err|                   .{ .err = err },
     };
 }

Examples

Examples of incorrect code for this rule

const x: u32 = @as(u32, @intCast(y)); // remove as expression

pub fn f1(a: u64) u32 {
    return @as(u32, @intCast(a)); // remove as expression
}

const T = struct {
    field: u32,

    const x: T = .{ .field = 2 };
};

pub fn hello(a: T) void {
    _ = a;
}

const Enum = enum { a };
const z: Enum = z: {
    hello(T{ // remove `T`
		.field = @as(u32, @intCast(y)), // remove as expression
	});
    hello(T.x); // Remove `T`
    break :z Enum.z; // remove `Enum`
};

fn other(comptime hello: type, n: u64) SomeComplex(hello) {
    return SomeComplex(hello).init(n);
	// use decl literal `.init(n)`
	// can realize that the literal text `SomeComplex(hello)` is re-used
}

Examples that would not be flagged.

const x = @as(u32, @intCast(y)); // destination has no type

pub fn goodbye(a: anytype) void {
    _ = a;
}
comptime {
    goodbye(T{ // cannot remove T as argument is `anytype`
		.field = @as(u32, @intCast(y)), // `.field` has no type
	});
}

fn other(n: u64) u32 {
    // when the types are not the same, it should not apply.
    // the extra coercion does something
    return @as(u16, @truncate(n));
}
@paperclover paperclover added A-linter Area - linter and lint rules C-rule Category - Lint rule suggestion labels Jan 8, 2025
@DonIsaac
Copy link
Owner

DonIsaac commented Jan 11, 2025

Needs type checker, specifically getContextualTypeOfExpression

edit: I blame Grammarly's extension for making me misclick and accidentally close this issue

@DonIsaac DonIsaac reopened this Jan 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linter Area - linter and lint rules C-rule Category - Lint rule suggestion
Projects
None yet
Development

No branches or pull requests

2 participants