rust-lang / rust-lang/rust-clippy

while_immutable_condition false positive with mut pointers

Open
#3,548 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-false-positive
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Code like the following triggers clippy::while_immutable_condition:

static mut GLOBAL: *mut i8 = 0 as *mut _;

fn main() {
    let mut x = 0;
    let p: *mut i8 = &mut x;
    unsafe {
        GLOBAL = p;
        while *p == 0 {
            *GLOBAL += 1;
        }
    }
}

The exact error message is:

error: Variable in the condition are not mutated in the loop body. This either leads to an infinite or to a never
running loop.
 --> src/main.rs:8:15
  |
8 |         while *p > 0 {
  |               ^^^^^^
  |
  = note: #[deny(clippy::while_immutable_condition)] on by default
  = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/master/index.html#while_immutable_condition

There are clearly two mut pointers involved above, but it's also possible for this to happen with e.g. external functions:

extern {
    fn stash_the_pointer(x: *mut i8);
    fn use_the_pointer();
}

fn main() {
    let mut x = 0;
    let p: *mut i8 = &mut x;
    unsafe {
        stash_the_pointer(p);
        while *p == 0 {
            use_the_pointer();
        }
    }
}

Clippy complains also about the above, although in reality, stash_the_pointer could've saved the pointer somewhere, allowing use_the_pointer to update it.

$ cargo clippy --version
clippy 0.0.212 (2e26fdc 2018-11-22)

Having the lint disregard mut pointers entirely would be a simple way of papering over this, but a more accurate fix might be something along the lines of:

  • If the while condition is based on a mut pointer;
  • And the pointer has been assigned to a static global or passed to a function;
  • And there is a use of a static global or a function call in the loop;
  • Then the lint shouldn't fire.

But maybe it's not that simple, I didn't really think about it very hard.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the implementation and tests for clippy::while_immutable_condition, then reproduce the report with the supplied Rust examples using cargo clippy. Done means the lint no longer emits a false positive for the demonstrated mutable-pointer, global, or external-function cases, with regression coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.