Skip to content

Identify unintended assignment in condition #294

Description

@straight-shoota

This is an idea for a rule that targets the same error type as #163, an unintended assignment in a condition (instead of equality comparison).

I think the only valid use case for an assignment in a condition is for eliminating a Nil type from an expression. For that purpose, it's assigned to a local variable and the type restriction excluding Nil applies inside the block.

So we could use a couple of indicators which identify this use case:

  1. The assignment target is a fresh local variable.
  2. The assignment target is used in the block or subsequent parts of the condition.
  3. The assigned value is not a constant or literal.
  4. The assigned value should not be a local variable (you don't need to assign it again, the type restriction would apply on the original already).
  5. The conditional expression is not a trailing one (because there's no body with a type restriction; I suppose it could be valid if another part of the condition uses the restricted variable, but that's pretty certainly not a good style for a trailing conditional).

There might be more indicators.

The original example from #163 would already violate 1), 2), 3) and 5) 😎

var = 1

puts "foo" if var = 1

I think this approach would be far superior to using Yoda conditionals for this use case.

Activity

  1. self-assigned this
    on Nov 14, 2022
  2. added this to the 1.3.1 milestone on Nov 14, 2022
  3. straight-shoota commented on Nov 15, 2022

    @straight-shoota
    ContributorAuthor
    1. The assigned value is not a constant or literal.

    Technically, there are some valid use cases for constants whose value is determined at runtime (and are nilable).

    An example for that would be Process::INITIAL_PWD.

    if pwd = Process::INITIAL_PWD
      # do something only if INITIAL_PWD exists
    end

    Example use case: https://github.com/crystal-lang/crystal/blob/ed211835f35e354a9047a36aa634a32c01844864/src/process/executable_path.cr#L178

    I think this is pretty rare, though. Most constants have static values an non-nilable types. Not sure if there are any considerable examples besides INITIAL_PWD, pretty sure there are none in stdlib.

  4. modified the milestones: 1.3.1, v1.4.0 on Nov 15, 2022
  5. removed their assignment
    on Jan 3, 2023
  6. added theissue type on Dec 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions