Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/rust/rules/no-dbg-macro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ note: |
- Line: add `// ast-grep-ignore: no-dbg-macro` on the line before
rule:
pattern: dbg!($$$ARGS)
fix: $$$ARGS
fix: ($$$ARGS)
5 changes: 5 additions & 0 deletions src/rust/rules/no-mem-transmute.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@ note: |
rule:
any:
- pattern: std::mem::transmute($$$ARGS)
- pattern: std::mem::transmute::<$$$T>($$$ARGS)
- pattern: core::mem::transmute($$$ARGS)
- pattern: core::mem::transmute::<$$$T>($$$ARGS)
- pattern: mem::transmute($$$ARGS)
- pattern: mem::transmute::<$$$T>($$$ARGS)
- pattern: transmute($$$ARGS)
- pattern: transmute::<$$$T>($$$ARGS)
24 changes: 24 additions & 0 deletions src/rust/rules/tracing-no-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ note: |
Bad:
```rust
tracing::info!("User {} logged in", format!("{:?}", user));
tracing::info!(user = format!("{:?}", user), "logged in");
```

Good:
Expand All @@ -21,6 +22,7 @@ note: |
- Line: add `// ast-grep-ignore: tracing-no-format` on the line before
rule:
any:
# format!() as last argument
- pattern: tracing::info!($$$ARGS, format!($$$FMT))
- pattern: tracing::debug!($$$ARGS, format!($$$FMT))
- pattern: tracing::warn!($$$ARGS, format!($$$FMT))
Expand All @@ -31,3 +33,25 @@ rule:
- pattern: warn!($$$ARGS, format!($$$FMT))
- pattern: error!($$$ARGS, format!($$$FMT))
- pattern: trace!($$$ARGS, format!($$$FMT))
# format!() as first/only argument
- pattern: tracing::info!(format!($$$FMT))
- pattern: tracing::debug!(format!($$$FMT))
- pattern: tracing::warn!(format!($$$FMT))
- pattern: tracing::error!(format!($$$FMT))
- pattern: tracing::trace!(format!($$$FMT))
- pattern: info!(format!($$$FMT))
- pattern: debug!(format!($$$FMT))
- pattern: warn!(format!($$$FMT))
- pattern: error!(format!($$$FMT))
- pattern: trace!(format!($$$FMT))
# format!() as first argument with trailing args
- pattern: tracing::info!(format!($$$FMT), $$$ARGS)
- pattern: tracing::debug!(format!($$$FMT), $$$ARGS)
- pattern: tracing::warn!(format!($$$FMT), $$$ARGS)
- pattern: tracing::error!(format!($$$FMT), $$$ARGS)
- pattern: tracing::trace!(format!($$$FMT), $$$ARGS)
- pattern: info!(format!($$$FMT), $$$ARGS)
- pattern: debug!(format!($$$FMT), $$$ARGS)
- pattern: warn!(format!($$$FMT), $$$ARGS)
- pattern: error!(format!($$$FMT), $$$ARGS)
- pattern: trace!(format!($$$FMT), $$$ARGS)
45 changes: 42 additions & 3 deletions src/rust/rules/unsafe-needs-safety-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,52 @@ note: |
```rust
// SAFETY: We have verified the pointer is valid and aligned
unsafe { *ptr }

// SAFETY: caller guarantees ptr is valid
let x = unsafe { *ptr };
```

This is a reminder rule - review each unsafe block to ensure it has
proper documentation. Some may already have SAFETY comments that
ast-grep cannot detect due to formatting.
The SAFETY comment must immediately precede the unsafe block or its
enclosing statement (no intervening statements).

To disable this rule:
- Line: add `// ast-grep-ignore: unsafe-needs-safety-comment` on the line before
rule:
kind: unsafe_block
not:
any:
# SAFETY comment immediately before the unsafe block itself
- follows:
stopBy: neighbor
kind: line_comment
regex: 'SAFETY:'
- follows:
stopBy: neighbor
kind: block_comment
regex: 'SAFETY:'
# SAFETY comment before enclosing let_declaration
- inside:
kind: let_declaration
follows:
stopBy: neighbor
kind: line_comment
regex: 'SAFETY:'
- inside:
kind: let_declaration
follows:
stopBy: neighbor
kind: block_comment
regex: 'SAFETY:'
# SAFETY comment before enclosing expression_statement
- inside:
kind: expression_statement
follows:
stopBy: neighbor
kind: line_comment
regex: 'SAFETY:'
- inside:
kind: expression_statement
follows:
stopBy: neighbor
kind: block_comment
regex: 'SAFETY:'
31 changes: 29 additions & 2 deletions src/rust/tests/__snapshots__/no-dbg-macro-snapshot.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
id: no-dbg-macro
snapshots:
? |
dbg!();
: fixed: |
();
labels:
- source: dbg!()
style: primary
start: 0
end: 6
? |
dbg!(x);
: fixed: |
x;
(x);
labels:
- source: dbg!(x)
style: primary
Expand All @@ -12,9 +21,27 @@ snapshots:
? |
dbg!(x, y, z);
: fixed: |
x, y, z;
(x, y, z);
labels:
- source: dbg!(x, y, z)
style: primary
start: 0
end: 13
? |
foo(dbg!(x));
: fixed: |
foo((x));
labels:
- source: dbg!(x)
style: primary
start: 4
end: 11
? |
let result = dbg!(compute());
: fixed: |
let result = (compute());
labels:
- source: dbg!(compute())
style: primary
start: 13
end: 28
35 changes: 35 additions & 0 deletions src/rust/tests/__snapshots__/no-mem-transmute-snapshot.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
id: no-mem-transmute
snapshots:
? |
let a = std::mem::transmute::<u32, i32>(value);
: labels:
- source: std::mem::transmute::<u32, i32>(value)
style: primary
start: 8
end: 46
? |
let b = mem::transmute::<[u8; 4], u32>(bytes);
: labels:
- source: mem::transmute::<[u8; 4], u32>(bytes)
style: primary
start: 8
end: 45
? |
let c = core::mem::transmute(value);
: labels:
- source: core::mem::transmute(value)
style: primary
start: 8
end: 35
? |
let d = core::mem::transmute::<u8, i8>(byte);
: labels:
- source: core::mem::transmute::<u8, i8>(byte)
style: primary
start: 8
end: 44
? |
let x = std::mem::transmute(value);
: labels:
Expand All @@ -14,3 +42,10 @@ snapshots:
style: primary
start: 8
end: 29
? |
let z = transmute(value);
: labels:
- source: transmute(value)
style: primary
start: 8
end: 24
21 changes: 21 additions & 0 deletions src/rust/tests/__snapshots__/tracing-no-format-snapshot.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
id: tracing-no-format
snapshots:
? |
debug!(format!("{}", value));
: labels:
- source: debug!(format!("{}", value))
style: primary
start: 0
end: 28
? |
info!("Value: {}", format!("{:?}", x));
: labels:
Expand All @@ -14,13 +21,27 @@ snapshots:
style: primary
start: 0
end: 50
? |
tracing::error!(format!("Error: {}"), err, "context");
: labels:
- source: 'tracing::error!(format!("Error: {}"), err, "context")'
style: primary
start: 0
end: 53
? |
tracing::info!("User {}", format!("{:?}", user));
: labels:
- source: tracing::info!("User {}", format!("{:?}", user))
style: primary
start: 0
end: 48
? |
tracing::info!(format!("User: {:?}", user));
: labels:
- source: 'tracing::info!(format!("User: {:?}", user))'
style: primary
start: 0
end: 43
? |
warn!("Warning: {}", format!("{}", msg));
: labels:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ snapshots:
style: primary
start: 15
end: 30
? |
fn foo(ptr: *const i32) -> i32 {
// SAFETY: ptr is valid
let x = 1;
unsafe { *ptr }
}
: labels:
- source: unsafe { *ptr }
style: primary
start: 80
end: 95
? |
fn foo(ptr: *const i32) -> i32 {
// This is probably fine
unsafe { *ptr }
}
: labels:
- source: unsafe { *ptr }
style: primary
start: 66
end: 81
? |
unsafe { *ptr }
: labels:
Expand Down
8 changes: 8 additions & 0 deletions src/rust/tests/no-dbg-macro-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ valid:
tracing::debug!(value = ?x, "debugging");
- |
println!("{:?}", x);
- |
log::debug!("value: {:?}", x);

invalid:
- |
dbg!(x);
- |
dbg!(x, y, z);
- |
dbg!();
- |
let result = dbg!(compute());
- |
foo(dbg!(x));
12 changes: 12 additions & 0 deletions src/rust/tests/no-mem-transmute-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,21 @@ valid:
let x = u32::from_ne_bytes(bytes);
- |
let y = value as i32;
- |
let z = bytemuck::cast(value);

invalid:
- |
let x = std::mem::transmute(value);
- |
let y = mem::transmute(bytes);
- |
let z = transmute(value);
- |
let a = std::mem::transmute::<u32, i32>(value);
- |
let b = mem::transmute::<[u8; 4], u32>(bytes);
- |
let c = core::mem::transmute(value);
- |
let d = core::mem::transmute::<u8, i8>(byte);
11 changes: 11 additions & 0 deletions src/rust/tests/tracing-no-format-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ valid:
tracing::debug!(count = count, "Processing items");
- |
info!("Simple message");
- |
tracing::warn!("Plain warning");

invalid:
# format!() as last argument
- |
tracing::info!("User {}", format!("{:?}", user));
- |
Expand All @@ -16,3 +19,11 @@ invalid:
info!("Value: {}", format!("{:?}", x));
- |
warn!("Warning: {}", format!("{}", msg));
# format!() as first/only argument
- |
tracing::info!(format!("User: {:?}", user));
- |
debug!(format!("{}", value));
# format!() as first argument with trailing args
- |
tracing::error!(format!("Error: {}"), err, "context");
41 changes: 41 additions & 0 deletions src/rust/tests/unsafe-needs-safety-comment-test.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,55 @@
id: unsafe-needs-safety-comment
valid:
# No unsafe at all
- |
fn foo() {
let x = 1;
}

# Line comment with SAFETY before unsafe block
- |
fn foo(ptr: *const i32) -> i32 {
// SAFETY: ptr is valid and aligned
unsafe { *ptr }
}

# Block comment with SAFETY
- |
fn foo(ptr: *const i32) -> i32 {
/* SAFETY: ptr is valid */
unsafe { *ptr }
}

# SAFETY comment before let statement containing unsafe
- |
fn foo(ptr: *const i32) -> i32 {
// SAFETY: ptr is valid
let x = unsafe { *ptr };
x
}

invalid:
# No comment at all
- |
fn foo() {
unsafe { *ptr }
}

# Top-level unsafe without comment
- |
unsafe { std::ptr::read(ptr) }

# Wrong comment (not SAFETY)
- |
fn foo(ptr: *const i32) -> i32 {
// This is probably fine
unsafe { *ptr }
}

# SAFETY comment for wrong block (intervening statement)
- |
fn foo(ptr: *const i32) -> i32 {
// SAFETY: ptr is valid
let x = 1;
unsafe { *ptr }
}