[PATCH v8 1/2] scripts: checkpatch: move Rust-specific lints to separate file

Jason Hall posted 2 patches 1 day, 5 hours ago
There is a newer version of this series
[PATCH v8 1/2] scripts: checkpatch: move Rust-specific lints to separate file
Posted by Jason Hall 1 day, 5 hours ago
Create scripts/rust_checkpatch.pl for Rust-specific linting logic.
Add a conditional loading hook in scripts/checkpatch.pl to call it.
This will allow Rust linting logic to be maintained independently.

Add a new entry to the MAINTAINERS file to track this new file.

Suggested-by: Joe Perches <joe@perches.com>
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Jason Hall <jason.kei.hall@gmail.com>
---
 MAINTAINERS                | 22 ++++++++++++++--------
 scripts/checkpatch.pl      | 14 ++++++++++++++
 scripts/rust_checkpatch.pl | 16 ++++++++++++++++
 3 files changed, 44 insertions(+), 8 deletions(-)
 create mode 100644 scripts/rust_checkpatch.pl

diff --git a/MAINTAINERS b/MAINTAINERS
index f6bc65de83c7..57831dc30e6b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4109,7 +4109,7 @@ F:	drivers/input/touchscreen/atmel_mxt_ts.c
 ATOMIC INFRASTRUCTURE
 M:	Will Deacon <will@kernel.org>
 M:	Peter Zijlstra <peterz@infradead.org>
-M:	Boqun Feng <boqun.feng@gmail.com>
+M:	Boqun Feng <boqun@kernel.org>
 R:	Mark Rutland <mark.rutland@arm.com>
 R:	Gary Guo <gary@garyguo.net>
 L:	linux-kernel@vger.kernel.org
@@ -4500,7 +4500,7 @@ F:	lib/sbitmap.c
 
 BLOCK LAYER DEVICE DRIVER API [RUST]
 M:	Andreas Hindborg <a.hindborg@kernel.org>
-R:	Boqun Feng <boqun.feng@gmail.com>
+R:	Boqun Feng <boqun@kernel.org>
 L:	linux-block@vger.kernel.org
 L:	rust-for-linux@vger.kernel.org
 S:	Supported
@@ -5880,6 +5880,12 @@ R:	Lukas Bulwahn <lukas.bulwahn@gmail.com>
 S:	Maintained
 F:	scripts/checkpatch.pl
 
+CHECKPATCH RUST LINTS
+M:	Jason Hall <jason.kei.hall@gmail.com>
+L:	rust-for-linux@vger.kernel.org
+S:	Maintained
+F:	scripts/rust_checkpatch.pl
+
 CHECKPATCH DOCUMENTATION
 M:	Dwaipayan Ray <dwaipayanray1@gmail.com>
 M:	Lukas Bulwahn <lukas.bulwahn@gmail.com>
@@ -11264,7 +11270,7 @@ F:	tools/testing/selftests/timers/
 
 DELAY, SLEEP, TIMEKEEPING, TIMERS [RUST]
 M:	Andreas Hindborg <a.hindborg@kernel.org>
-R:	Boqun Feng <boqun.feng@gmail.com>
+R:	Boqun Feng <boqun@kernel.org>
 R:	FUJITA Tomonori <fujita.tomonori@gmail.com>
 R:	Frederic Weisbecker <frederic@kernel.org>
 R:	Lyude Paul <lyude@redhat.com>
@@ -14559,7 +14565,7 @@ M:	Alan Stern <stern@rowland.harvard.edu>
 M:	Andrea Parri <parri.andrea@gmail.com>
 M:	Will Deacon <will@kernel.org>
 M:	Peter Zijlstra <peterz@infradead.org>
-M:	Boqun Feng <boqun.feng@gmail.com>
+M:	Boqun Feng <boqun@kernel.org>
 M:	Nicholas Piggin <npiggin@gmail.com>
 M:	David Howells <dhowells@redhat.com>
 M:	Jade Alglave <j.alglave@ucl.ac.uk>
@@ -14718,7 +14724,7 @@ LOCKING PRIMITIVES
 M:	Peter Zijlstra <peterz@infradead.org>
 M:	Ingo Molnar <mingo@redhat.com>
 M:	Will Deacon <will@kernel.org>
-M:	Boqun Feng <boqun.feng@gmail.com> (LOCKDEP & RUST)
+M:	Boqun Feng <boqun@kernel.org> (LOCKDEP & RUST)
 R:	Waiman Long <longman@redhat.com>
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
@@ -21912,7 +21918,7 @@ M:	Frederic Weisbecker <frederic@kernel.org> (kernel/rcu/tree_nocb.h)
 M:	Neeraj Upadhyay <neeraj.upadhyay@kernel.org> (kernel/rcu/tasks.h)
 M:	Joel Fernandes <joelagnelf@nvidia.com>
 M:	Josh Triplett <josh@joshtriplett.org>
-M:	Boqun Feng <boqun.feng@gmail.com>
+M:	Boqun Feng <boqun@kernel.org>
 M:	Uladzislau Rezki <urezki@gmail.com>
 R:	Steven Rostedt <rostedt@goodmis.org>
 R:	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
@@ -22362,7 +22368,7 @@ RESTARTABLE SEQUENCES SUPPORT
 M:	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
 M:	Peter Zijlstra <peterz@infradead.org>
 M:	"Paul E. McKenney" <paulmck@kernel.org>
-M:	Boqun Feng <boqun.feng@gmail.com>
+M:	Boqun Feng <boqun@kernel.org>
 L:	linux-kernel@vger.kernel.org
 S:	Supported
 F:	include/trace/events/rseq.h
@@ -22885,7 +22891,7 @@ F:	tools/verification/
 
 RUST
 M:	Miguel Ojeda <ojeda@kernel.org>
-R:	Boqun Feng <boqun.feng@gmail.com>
+R:	Boqun Feng <boqun@kernel.org>
 R:	Gary Guo <gary@garyguo.net>
 R:	Björn Roy Baron <bjorn3_gh@protonmail.com>
 R:	Benno Lossin <lossin@kernel.org>
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index c0250244cf7a..f75cb70ad0dd 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -20,6 +20,12 @@ my $D = dirname(abs_path($P));
 
 my $V = '0.32';
 
+my $rust_checkpatch_available = 0;
+if (-e "$D/rust_checkpatch.pl") {
+	require "$D/rust_checkpatch.pl";
+	$rust_checkpatch_available = 1;
+}
+
 use Getopt::Long qw(:config no_auto_abbrev);
 
 my $quiet = 0;
@@ -2947,6 +2953,14 @@ sub process {
 
 		$cnt_lines++ if ($realcnt != 0);
 
+# Check for Rust-specific lints
+		if ($rust_checkpatch_available && $realfile =~ /\.rs$/) {
+			my ($type, $msg) = process_rust($line, $rawline, $herecurr);
+			if ($type) {
+				WARN($type, $msg);
+			}
+		}
+
 # Verify the existence of a commit log if appropriate
 # 2 is used because a $signature is counted in $commit_log_lines
 		if ($in_commit_log) {
diff --git a/scripts/rust_checkpatch.pl b/scripts/rust_checkpatch.pl
new file mode 100644
index 000000000000..56c1bc29d3f2
--- /dev/null
+++ b/scripts/rust_checkpatch.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
+#
+# (c) 2026, Jason Hall <jason.kei.hall@gmail.com>
+
+use strict;
+use warnings;
+
+sub process_rust {
+    my ($line, $rawline, $herecurr) = @_;
+
+    # Reserve for future Rust-specific lints
+    return ();
+}
+
+1;
-- 
2.43.0

Re: [PATCH v8 1/2] scripts: checkpatch: move Rust-specific lints to separate file
Posted by Miguel Ojeda 1 day, 4 hours ago
On Sat, Feb 7, 2026 at 10:08 PM Jason Hall <jason.kei.hall@gmail.com> wrote:
>
> -M:     Boqun Feng <boqun.feng@gmail.com>
> +M:     Boqun Feng <boqun@kernel.org>

This is now a patch series, great!

But please review your patches before sending them -- this has a lot
of unrelated changes again.

I suspect you are copying files around, to re-create commits in
another base manually, instead of using `git` commands like `git
rebase`.

Cheers,
Miguel
[PATCH v9 0/2] modularize Rust lints and add RUST_UNWRAP check
Posted by Jason Hall 1 day, 3 hours ago
This series moves Rust-specific linting logic into a separate file to
prevent further growth of the main scripts/checkpatch.pl script and
introduces a new lint to enforce safety standards.

The first patch creates the infrastructure for scripts/rust_checkpatch.pl
and adds a conditional loading hook in the main checkpatch script. It
also updates the MAINTAINERS file to track this new file.

The second patch introduces the  RUST_UNWRAP lint, which warns against
the use of .unwrap() and .expect() unless they are accompanied by a 
'// PANIC:' justification comment.

Jason Hall (2):
  scripts: checkpatch: move Rust-specific lints to separate file
  scripts: checkpatch: add RUST_UNWRAP lint

 MAINTAINERS                |  6 ++++++
 scripts/checkpatch.pl      | 14 ++++++++++++++
 scripts/rust_checkpatch.pl | 30 ++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+)
 create mode 100644 scripts/rust_checkpatch.pl

-- 
2.43.0
Re: [PATCH v9 0/2] modularize Rust lints and add RUST_UNWRAP check
Posted by Greg KH 19 hours ago
On Sat, Feb 07, 2026 at 03:49:05PM -0700, Jason Hall wrote:
> This series moves Rust-specific linting logic into a separate file to
> prevent further growth of the main scripts/checkpatch.pl script and
> introduces a new lint to enforce safety standards.
> 
> The first patch creates the infrastructure for scripts/rust_checkpatch.pl
> and adds a conditional loading hook in the main checkpatch script. It
> also updates the MAINTAINERS file to track this new file.
> 
> The second patch introduces the  RUST_UNWRAP lint, which warns against
> the use of .unwrap() and .expect() unless they are accompanied by a 
> '// PANIC:' justification comment.
> 
> Jason Hall (2):
>   scripts: checkpatch: move Rust-specific lints to separate file
>   scripts: checkpatch: add RUST_UNWRAP lint
> 
>  MAINTAINERS                |  6 ++++++
>  scripts/checkpatch.pl      | 14 ++++++++++++++
>  scripts/rust_checkpatch.pl | 30 ++++++++++++++++++++++++++++++
>  3 files changed, 50 insertions(+)
>  create mode 100644 scripts/rust_checkpatch.pl
> 
> -- 
> 2.43.0
> 
> 

Hi,

This is the friendly patch-bot of Greg Kroah-Hartman.  You have sent him
a patch that has triggered this response.  He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created.  Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.

You are receiving this message because of the following common error(s)
as indicated below:

- This looks like a new version of a previously submitted patch, but you
  did not list below the --- line any changes from the previous version.
  Please read the section entitled "The canonical patch format" in the
  kernel file, Documentation/process/submitting-patches.rst for what
  needs to be done here to properly describe this.

If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.

thanks,

greg k-h's patch email bot
[PATCH v9 1/2] scripts: checkpatch: move Rust-specific lints to separate file
Posted by Jason Hall 1 day, 3 hours ago
Create scripts/rust_checkpatch.pl for Rust-specific linting logic.
Add a conditional loading hook in scripts/checkpatch.pl to call it.
This will allow Rust linting logic to be maintained independently.

Add a new entry to the MAINTAINERS file to track this new file.

Suggested-by: Joe Perches <joe@perches.com>
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Jason Hall <jason.kei.hall@gmail.com>
---
 MAINTAINERS                |  6 ++++++
 scripts/checkpatch.pl      | 14 ++++++++++++++
 scripts/rust_checkpatch.pl | 16 ++++++++++++++++
 3 files changed, 36 insertions(+)
 create mode 100644 scripts/rust_checkpatch.pl

diff --git a/MAINTAINERS b/MAINTAINERS
index 2c0bdd08b74c..57831dc30e6b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5880,6 +5880,12 @@ R:	Lukas Bulwahn <lukas.bulwahn@gmail.com>
 S:	Maintained
 F:	scripts/checkpatch.pl
 
+CHECKPATCH RUST LINTS
+M:	Jason Hall <jason.kei.hall@gmail.com>
+L:	rust-for-linux@vger.kernel.org
+S:	Maintained
+F:	scripts/rust_checkpatch.pl
+
 CHECKPATCH DOCUMENTATION
 M:	Dwaipayan Ray <dwaipayanray1@gmail.com>
 M:	Lukas Bulwahn <lukas.bulwahn@gmail.com>
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index c0250244cf7a..f75cb70ad0dd 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -20,6 +20,12 @@ my $D = dirname(abs_path($P));
 
 my $V = '0.32';
 
+my $rust_checkpatch_available = 0;
+if (-e "$D/rust_checkpatch.pl") {
+	require "$D/rust_checkpatch.pl";
+	$rust_checkpatch_available = 1;
+}
+
 use Getopt::Long qw(:config no_auto_abbrev);
 
 my $quiet = 0;
@@ -2947,6 +2953,14 @@ sub process {
 
 		$cnt_lines++ if ($realcnt != 0);
 
+# Check for Rust-specific lints
+		if ($rust_checkpatch_available && $realfile =~ /\.rs$/) {
+			my ($type, $msg) = process_rust($line, $rawline, $herecurr);
+			if ($type) {
+				WARN($type, $msg);
+			}
+		}
+
 # Verify the existence of a commit log if appropriate
 # 2 is used because a $signature is counted in $commit_log_lines
 		if ($in_commit_log) {
diff --git a/scripts/rust_checkpatch.pl b/scripts/rust_checkpatch.pl
new file mode 100644
index 000000000000..56c1bc29d3f2
--- /dev/null
+++ b/scripts/rust_checkpatch.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
+#
+# (c) 2026, Jason Hall <jason.kei.hall@gmail.com>
+
+use strict;
+use warnings;
+
+sub process_rust {
+    my ($line, $rawline, $herecurr) = @_;
+
+    # Reserve for future Rust-specific lints
+    return ();
+}
+
+1;
-- 
2.43.0
[PATCH v9 2/2] scripts: checkpatch: add RUST_UNWRAP lint
Posted by Jason Hall 1 day, 3 hours ago
Warn against the use of .unwrap() and .expect() unless accompanied by
a '// PANIC:' comment. This enforces safety standards in the Rust-
for-Linux project until upstream Clippy lints are integrated.

Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://github.com/Rust-for-linux/linux/issues/1191
Signed-off-by: Jason Hall <jason.kei.hall@gmail.com>
---
 scripts/rust_checkpatch.pl | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/scripts/rust_checkpatch.pl b/scripts/rust_checkpatch.pl
index 56c1bc29d3f2..fa7adaed264c 100644
--- a/scripts/rust_checkpatch.pl
+++ b/scripts/rust_checkpatch.pl
@@ -9,7 +9,21 @@ use warnings;
 sub process_rust {
     my ($line, $rawline, $herecurr) = @_;
 
-    # Reserve for future Rust-specific lints
+    # Check for Rust unwrap/expect usage.
+    # We skip lines that are already comments, assert macros (common in tests),
+    # or have a '// PANIC:' justification.
+    if ($line =~ /^\+/) {
+        if ($line =~ /(?:\.|::)(?:unwrap|expect)\s*\(/ &&
+            $rawline !~ /\/\/\s*PANIC:/ &&
+            $line !~ /^\+\s*\/\// &&
+            $line !~ /^\+\s*assert/) {
+            return ("RUST_UNWRAP",
+                    "unwrap() and expect() should generally be avoided in Rust kernel code.\n" .
+                   "If the use is intended, please justify it with a '// PANIC:' comment.\n" .
+                    "See: https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust\n" .
+                    $herecurr);
+        }
+    }
     return ();
 }
 
-- 
2.43.0
Re: [PATCH v9 2/2] scripts: checkpatch: add RUST_UNWRAP lint
Posted by Dirk Behme 18 hours ago
On 07.02.26 23:49, Jason Hall wrote:
> Warn against the use of .unwrap() and .expect() unless accompanied by
> a '// PANIC:' comment. This enforces safety standards in the Rust-
> for-Linux project until upstream Clippy lints are integrated.


I wonder if we could add some outcome from the mailing list discussion
to the commit message? E.g. what we consider to be false positives,
the handling of them and what we suppose to be fixed etc.


> Suggested-by: Miguel Ojeda <ojeda@kernel.org>
> Link: https://github.com/Rust-for-linux/linux/issues/1191
> Signed-off-by: Jason Hall <jason.kei.hall@gmail.com>
> ---
>  scripts/rust_checkpatch.pl | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/scripts/rust_checkpatch.pl b/scripts/rust_checkpatch.pl
> index 56c1bc29d3f2..fa7adaed264c 100644
> --- a/scripts/rust_checkpatch.pl
> +++ b/scripts/rust_checkpatch.pl
> @@ -9,7 +9,21 @@ use warnings;
>  sub process_rust {
>      my ($line, $rawline, $herecurr) = @_;
>  
> -    # Reserve for future Rust-specific lints
> +    # Check for Rust unwrap/expect usage.
> +    # We skip lines that are already comments, assert macros (common in tests),
> +    # or have a '// PANIC:' justification.
> +    if ($line =~ /^\+/) {
> +        if ($line =~ /(?:\.|::)(?:unwrap|expect)\s*\(/ &&


Whats about the `.expect()` topic discussed in

https://lore.kernel.org/rust-for-linux/a798e6a368639f7a1ce633a6dfecd088d6ed4123.camel@perches.com/T/#m00723ad673727036e5fcf96a35f2f231ec9de31f

https://lore.kernel.org/rust-for-linux/a798e6a368639f7a1ce633a6dfecd088d6ed4123.camel@perches.com/T/#m5604274a633ef33eb474f95b54f797843d0fe1dd

?

> +            $rawline !~ /\/\/\s*PANIC:/ &&
> +            $line !~ /^\+\s*\/\// &&
> +            $line !~ /^\+\s*assert/) {
> +            return ("RUST_UNWRAP",
> +                    "unwrap() and expect() should generally be avoided in Rust kernel code.\n" .
> +                   "If the use is intended, please justify it with a '// PANIC:' comment.\n" .
> +                    "See: https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust\n" .
> +                    $herecurr);
> +        }
> +    }
>      return ();
>  }

Just for the logs:

Running this on e.g.

https://lore.kernel.org/rust-for-linux/20260207-binder-shrink-vec-v3-v3-3-8ff388563427@cock.li/

gives


$ ./scripts/checkpatch.pl
0001-rust-alloc-add-KUnit-tests-for-Vec-shrink-operations.patch
WARNING: unwrap() and expect() should generally be avoided in Rust
kernel code.
If the use is intended, please justify it with a '// PANIC:' comment.
See:
https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust
#52: FILE: rust/kernel/alloc/kvec.rs:1524:
+        let mut v: VVec<u32> = VVec::with_capacity(initial_capacity,
GFP_KERNEL).unwrap();

...

total: 0 errors, 21 warnings, 189 lines checked

(note: all 21 warnings are from `unwrap()`)

I'm not sure if it makes me happy to ignore these 21 warnings as false
positives ;)

Best regards

Dirk
Re: [PATCH v9 2/2] scripts: checkpatch: add RUST_UNWRAP lint
Posted by Jason Hall 12 hours ago
Hi Dirk,

I have been playing around with the lint logic. It now identifies 
when we enter a test-related block (like mod tests, #[test], or KUnit 
macros) and suppresses the warning for that specific context. 

This handles the false positives you encountered in the Binder patch 
while still catching "lazy" unwraps in production logic.

I tested the scenarios laid out below.

Proposed Logic:

my $in_rust_test_context = 0;

sub process_rust {
    my ($line, $rawline, $herecurr) = @_;

    if ($rawline =~ /^(?:@@|diff --git)/) {
        $in_rust_test_context = 0;
    }

    if ($line =~ /^\+\s*(?:mod\s+tests|#\[.*(?:test|kunit))/) {
        $in_rust_test_context = 1;
    }

    if ($line =~ /^\+/ && !$in_rust_test_context) {
        if ($line =~ /(?:\.|::)(?:unwrap|expect)\s*\(/ &&
            $rawline !~ /\/\/\s*PANIC:/ &&
            $line !~ /^\+\s*\/\// &&
            $line !~ /^\+\s*assert/) {
            return ("RUST_UNWRAP", "...");
        }
    }
    return ();
}

Scenarios:

--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -42,6 +42,7 @@
     pub fn new_with_data() -> Self {
-        let x = Some(1);
+        // Scenario 1: Production code (SHOULD WARN)
+        let val = some_kernel_function().unwrap();
         Vec { ptr: NonNull::dangling(), len: 0 }
     }
 
@@ -150,6 +151,13 @@
+    // Scenario 2: Explicitly justified (SHOULD NOT WARN)
+    pub fn proof_of_concept() {
+        let x = core::ptr::NonNull::new(ptr).unwrap(); // PANIC: ptr is never null here
+    }
+
+    // Scenario 3: Already a comment (SHOULD NOT WARN)
+    // let x = something.unwrap();
+
@@ -200,10 +208,20 @@
+#[test]
+fn scenario_4_standalone_test() {
+    // SHOULD NOT WARN because of #[test] above
+    let v: KVec<u32> = KVec::with_capacity(1, GFP_KERNEL).unwrap();
+}
+
+#[macros::kunit_tests(rust_kvec)]
+mod tests {
+    use super::*;
+
+    fn test_internal_logic() {
+        // Scenario 5: Inside KUnit mod (SHOULD NOT WARN)
+        // Dirk's specific 21 warnings happened in a block like this.
+        let mut v = KVec::new();
+        v.push(1, GFP_KERNEL).unwrap();
+        assert_eq!(v.pop().unwrap(), 1);
+    }
+}

If this looks okay, I can resubmit the patch series with this.

Best regards,
Jason