Code Review in Rust: What to Check and How to Give Feedback in Practice

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Code Review in Rust Is Not Just a Formality

\n\n

Code review is one of the key processes in developing any high-quality software. But when it comes to Rust, this process takes on special significance. Rust is a language with a unique system of ownership and borrowing, which the compiler checks at compile time. However, even if the code compiles, it doesn't mean it is written well, safely, and efficiently.

\n\n

In this article, we will break down exactly what to pay attention to during code review of Rust projects, how to give constructive feedback without offending a colleague, and how to avoid common mistakes that the compiler doesn't catch. The article is aimed at developers who are already familiar with the basics of Rust but want to deepen their review skills.

\n\n

1. Memory Safety and Resource Management

\n\n

Rust guarantees memory safety without a garbage collector. But this does not negate the need to check how the developer uses unsafe blocks, raw pointers, and external FFI calls.

\n\n

What to check:

\n
    \n
  • Use of unsafe: every unsafe block should be justified and accompanied by a comment explaining why it is safe. If you can do without unsafe, it is better to do so.
  • \n
  • Resource leaks: check that all Box, Rc, Arc, and other smart pointers are correctly freed. For example, cyclic references via Rc without Weak are a common problem.
  • \n
  • Drop order: if a struct contains fields with a custom Drop implementation, ensure that the destruction order does not lead to errors.
  • \n
\n\n
// Example of bad code: unsafe without comments\nunsafe {\n    let ptr = ...;\n    // No explanation of why this is safe\n    *ptr = 42;\n}\n\n// Good code: comment and safe alternative\n// Use unsafe only to call a C function that guarantees pointer validity\nunsafe {\n    // The pointer was obtained from a C API that guarantees its validity for the lifetime of the call\n    some_c_function(ptr);\n}\n
\n\n

2. Code Idiomaticity and Style

\n\n

Rust has its own idioms that differ from C++ or Python. Code review should check how well the code aligns with the spirit of the language.

\n\n

What to check:

\n
    \n
  • Use of Option and Result: avoid unwrap() and expect() without an explicit reason. In production code, use error handling via match, the ? operator, or unwrap_or_else.
  • \n
  • Pattern matching: prefer if let and match over chains of is_some()/is_ok().
  • \n
  • Use of traits: check that traits are implemented meaningfully. For example, the Display implementation should provide readable output, not just Debug.
  • \n
  • Naming: in Rust, it is conventional to use snake_case for variables and functions, CamelCase for types and traits. Constants use SCREAMING_SNAKE_CASE.
  • \n
\n\n
// Bad: excessive use of unwrap\nlet value = some_option.unwrap();\n\n// Good: error handling\nlet value = match some_option {\n    Some(v) => v,\n    None => return Err("Value not found".into()),\n};\n\n// Even better: with the ? operator\nlet value = some_option.ok_or("Value not found")?;\n
\n\n

3. Performance and Allocations

\n\n

Rust provides low-level control over memory, but this doesn't mean the code is automatically fast. During review, it is important to check for potential bottlenecks.

\n\n

What to check:

\n
    \n
  • Unnecessary allocations: check whether String or Vec are being created

Blogs

Book Recommendations