Skip to content

Commit 754717c

Browse files
authored
feat: struct initializer lint (#11892)
1 parent 740fae2 commit 754717c

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

crates/lint/src/sol/info/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use screaming_snake_case::{SCREAMING_SNAKE_CASE_CONSTANT, SCREAMING_SNAKE_CASE_I
1212
mod imports;
1313
use imports::{UNALIASED_PLAIN_IMPORT, UNUSED_IMPORT};
1414

15+
mod named_struct_fields;
16+
use named_struct_fields::NAMED_STRUCT_FIELDS;
17+
1518
mod unsafe_cheatcodes;
1619
use unsafe_cheatcodes::UNSAFE_CHEATCODE_USAGE;
1720

@@ -21,5 +24,6 @@ register_lints!(
2124
(MixedCaseFunction, early, (MIXED_CASE_FUNCTION)),
2225
(ScreamingSnakeCase, early, (SCREAMING_SNAKE_CASE_CONSTANT, SCREAMING_SNAKE_CASE_IMMUTABLE)),
2326
(Imports, early, (UNALIASED_PLAIN_IMPORT, UNUSED_IMPORT)),
27+
(NamedStructFields, late, (NAMED_STRUCT_FIELDS)),
2428
(UnsafeCheatcodes, early, (UNSAFE_CHEATCODE_USAGE))
2529
);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use solar::sema::hir::{CallArgs, CallArgsKind, Expr, ExprKind, ItemId, Res};
2+
3+
use crate::{
4+
linter::{LateLintPass, LintContext},
5+
sol::{Severity, SolLint, info::NamedStructFields},
6+
};
7+
8+
declare_forge_lint!(
9+
NAMED_STRUCT_FIELDS,
10+
Severity::Info,
11+
"named-struct-fields",
12+
"prefer initializing structs with named fields"
13+
);
14+
15+
impl<'hir> LateLintPass<'hir> for NamedStructFields {
16+
fn check_expr(
17+
&mut self,
18+
ctx: &LintContext,
19+
_hir: &'hir solar::sema::hir::Hir<'hir>,
20+
expr: &'hir solar::sema::hir::Expr<'hir>,
21+
) {
22+
if let ExprKind::Call(
23+
Expr { kind: ExprKind::Ident([Res::Item(ItemId::Struct(_struct_id))]), .. },
24+
CallArgs { kind: CallArgsKind::Unnamed(_args), .. },
25+
_,
26+
) = &expr.kind
27+
{
28+
ctx.emit(&NAMED_STRUCT_FIELDS, expr.span);
29+
}
30+
}
31+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.18;
3+
4+
contract NamedStructFields {
5+
struct Person {
6+
string name;
7+
uint256 age;
8+
address wallet;
9+
}
10+
11+
function namedArgs() public {
12+
Person memory person = Person({
13+
name: "Alice",
14+
age: 25,
15+
wallet: address(0)
16+
});
17+
}
18+
19+
function positionalArgs() public {
20+
Person memory person = Person("Alice", 25, address(0)); //~NOTE: prefer initializing structs with named fields
21+
}
22+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
note[named-struct-fields]: prefer initializing structs with named fields
2+
--> ROOT/testdata/NamedStructFields.sol:LL:CC
3+
|
4+
LL | Person memory person = Person("Alice", 25, address(0));
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= help: https://book.getfoundry.sh/reference/forge/forge-lint#named-struct-fields
8+

0 commit comments

Comments
 (0)