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 Idea Board #3

Open
DonIsaac opened this issue Nov 1, 2024 · 13 comments
Open

Rule Idea Board #3

DonIsaac opened this issue Nov 1, 2024 · 13 comments
Labels
A-linter Area - linter and lint rules C-rule Category - Lint rule suggestion

Comments

@DonIsaac
Copy link
Owner

DonIsaac commented Nov 1, 2024

This is a mega-issue tracking the list of rules we want to implement. Rule requests are welcome.

  1. no-undefined - ban undefined in assignments and initializations
  • Allow when a // SAFETY: comment is present
  • Allow self.* = undefined in deinit() functions
  1. unsafe-optional-unwrap: bad optional unwrapping without a prior null check
  2. use-after-deinit: ban references to foo after foo.deinit() calls (or other free-like calls)
  3. no-const-reassign: do not reassign const-declared variables. Yes the compiler checks this, no they don't check it for tree-shaken code.
  4. no-private-access: ban external references to _private container fields.
@DonIsaac DonIsaac added the C-enhancement Category - New feature or request label Nov 1, 2024
@DonIsaac DonIsaac pinned this issue Nov 1, 2024
@DonIsaac
Copy link
Owner Author

DonIsaac commented Nov 2, 2024

I don't know what to call this, but @paperdave proposed it here
image

@DonIsaac
Copy link
Owner Author

DonIsaac commented Nov 2, 2024

Here's his full list (it needs triage)
image

@paperdave
Copy link

paperdave commented Nov 2, 2024

I don't know what to call this

"declaration can be accessed with a shorter path" / shorter_decl_path

@DonIsaac
Copy link
Owner Author

DonIsaac commented Nov 2, 2024

@paperdave decl-alias?

@DonIsaac
Copy link
Owner Author

DonIsaac commented Nov 3, 2024

unused-array-side-effects: Accidental mutation on a copied array

fn addEntry(self: *Foo, id: u32, item: u32) !void {
  // this creates a copy. It's dropped when the function returns
  var foos = self.foo[id]; // should be &self.foo[id];
  try foos.append(item);   // has no lasting side effects b/c foos is dropped
}

@MichaelBelousov
Copy link

MichaelBelousov commented Nov 3, 2024

unsafe-union-unwrap/check-union-payload-refs:

like unsafe-option-unwrap but enforces that a direct union variant access occurs in a scope where the union tag was checked and matches.

var a: union(enum) { int: i32, float: f32 } = .X;

if (a == .float) {
  std.debug.print("float: {}", .{a.float}); // legal
} else {
  std.debug.print("int: {}", .{a.float}); // illegal!
}

switch (a) {
  .int => std.debug.print("int: {}", .{a.float}), // illegal
}

@paperdave
Copy link

naming-convention: enforce standard library naming conventions declarations

@paperdave
Copy link

paperdave commented Nov 4, 2024

but enforces that a direct union variant access occurs in a scope where the union tag was checked and matches.

it's better to avoid this pattern entirely, if possible. these rules should encourage switch and captures:

var a: union(enum) { int: i32, float: f32 } = .X;

if (a == .float) {
  std.debug.print("float: {}", .{a.float}); // illegal
} else {
  std.debug.print("int: {}", .{a.float}); // illegal
}

// rewrite into
switch (a) {
  .float => |float| std.debug.print("float: {}", .{a.float}),
  .int => |int| std.debug.print("int: {}", .{a.int}),
}

@MichaelBelousov
Copy link

MichaelBelousov commented Nov 4, 2024

it's better to avoid this pattern entirely, if possible. these rules should encourage switch and captures

I agree in general, but it's the same reason to have unsafe-option-unwrap even when if (optional) |capture| exists.

There is code when you're checking multiple conditions and only one union variant where a switch may be cumbersome:

if (condition and a == .float) {
  std.debug.print("{}", .{a.float});
}

// versus

if (condition) switch (a) {
  .float => |v| {
    std.debug.print("{}", .{v});
  },
  else => {},
}

probably both unsafe-*-unwrap rules should mention the capture equivalents since those will also fix the rule (as opposed to making sure you access in a scope that checks the tag)

@DonIsaac
Copy link
Owner Author

DonIsaac commented Nov 5, 2024

but enforces that a direct union variant access occurs in a scope where the union tag was checked and matches.

it's better to avoid this pattern entirely, if possible. these rules should encourage switch and captures:

var a: union(enum) { int: i32, float: f32 } = .X;



if (a == .float) {

  std.debug.print("float: {}", .{a.float}); // illegal

} else {

  std.debug.print("int: {}", .{a.float}); // illegal

}



// rewrite into

switch (a) {

  .float => |float| std.debug.print("float: {}", .{a.float}),

  .int => |int| std.debug.print("int: {}", .{a.int}),

}

Should we add a rule banning it entirely?

@MichaelBelousov
Copy link

Should we add a rule banning it entirely?

Sure but I'd recommend allowing it with checks as the default.

It comes up often enough imo. A better example that I should have shown earlier is try checking that two separate variables have specific tags. You'd need a nested double switch if you don't allow tags checking in a single if statement

try rewriting this as a switch:

if (a == .float and b == .int) {
}

@paperdave
Copy link

i think we should split these into separate issues. this thread is getting very long. one issue per lint rule, or for related ones they can share one.

@nektro
Copy link

nektro commented Nov 17, 2024

https://github.com/nektro/ziglint/issues has a bunch i havent implemented

@DonIsaac DonIsaac added A-linter Area - linter and lint rules C-rule Category - Lint rule suggestion and removed C-enhancement Category - New feature or request labels Nov 17, 2024
DonIsaac added a commit that referenced this issue Nov 22, 2024
`homeless-try` looks for `try` used outside of error union-returning
functions.

Part of #3
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

4 participants