Skip to content

Feature: Detect mutable variable patterns in favor of functional style #2

@jssblck

Description

@jssblck

Use Case

Functional programming style in Rust is often clearer and safer than mutation. For example:

// ❌ Avoid: mutable accumulation
let mut results = Vec::new();
for item in items {
    if let Some(value) = process(item) {
        results.push(value);
    }
}

// ✅ Prefer: functional style
let results = items
    .into_iter()
    .filter_map(process)
    .collect::<Vec<_>>();

Challenge

Creating a reliable Nudge rule for this is extremely difficult because:

  1. Legitimate uses: I/O operations (std::io::copy), FFI, performance-critical code, complex builders
  2. Highly context-dependent: Needs to understand if mutation is necessary or just habitual
  3. Pattern complexity: Many different mutation patterns exist
  4. False positives: Would trigger on valid uses constantly

Patterns to Detect

Common anti-patterns that could benefit from functional style:

  • let mut vec = Vec::new(); for x in items { vec.push(...) }.map().collect()
  • let mut found = None; for x in items { if cond { found = Some(x); break; } }.find()
  • let mut result = init; for x in items { result = combine(result, x); }.fold()

Potential Solutions

To make this enforceable, Nudge would need:

  • Control flow analysis: Recognize accumulation patterns in loops
  • Semantic understanding: Know when mutation is necessary vs stylistic
  • Suggestion engine: Recommend the functional equivalent
  • Allowlist: Skip legitimate mutation contexts

Related Guidelines

From our project's style guide:

CRITICAL: Prefer functional/immutable patterns over mutation. Treat mut as essentially banned unless absolutely necessary.

Acceptable uses of mut:

  • Streaming I/O with readers/writers
  • Performance-critical code where mutation measurably improves performance
  • FFI or unsafe code where mutation is required
  • Building complex data structures where functional style is genuinely awkward

Request

This seems like it would require significant semantic analysis. Are there any approaches that could make simpler cases enforceable without too many false positives?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions