| fn fn_val(i: i32) -> i32 { |
| unimplemented!() |
| } |
| fn fn_constref(i: &i32) -> i32 { |
| unimplemented!() |
| } |
| fn fn_mutref(i: &mut i32) { |
| unimplemented!() |
| } |
| fn fooi() -> i32 { |
| unimplemented!() |
| } |
| fn foob() -> bool { |
| unimplemented!() |
| } |
| |
| fn immutable_condition() { |
| // Should warn when all vars mentioned are immutable |
| let y = 0; |
| while y < 10 { |
| //~^ while_immutable_condition |
| |
| println!("KO - y is immutable"); |
| } |
| |
| let x = 0; |
| while y < 10 && x < 3 { |
| //~^ while_immutable_condition |
| |
| let mut k = 1; |
| k += 2; |
| println!("KO - x and y immutable"); |
| } |
| |
| let cond = false; |
| while !cond { |
| //~^ while_immutable_condition |
| |
| println!("KO - cond immutable"); |
| } |
| |
| let mut i = 0; |
| while y < 10 && i < 3 { |
| i += 1; |
| println!("OK - i is mutable"); |
| } |
| |
| let mut mut_cond = false; |
| while !mut_cond || cond { |
| mut_cond = true; |
| println!("OK - mut_cond is mutable"); |
| } |
| |
| while fooi() < x { |
| println!("OK - Fn call results may vary"); |
| } |
| |
| while foob() { |
| println!("OK - Fn call results may vary"); |
| } |
| |
| let mut a = 0; |
| let mut c = move || { |
| while a < 5 { |
| a += 1; |
| println!("OK - a is mutable"); |
| } |
| }; |
| c(); |
| |
| let mut tup = (0, 0); |
| while tup.0 < 5 { |
| tup.0 += 1; |
| println!("OK - tup.0 gets mutated") |
| } |
| } |
| |
| fn unused_var() { |
| // Should warn when a (mutable) var is not used in while body |
| let (mut i, mut j) = (0, 0); |
| |
| while i < 3 { |
| //~^ while_immutable_condition |
| |
| j = 3; |
| println!("KO - i not mentioned"); |
| } |
| |
| while i < 3 && j > 0 { |
| //~^ while_immutable_condition |
| |
| println!("KO - i and j not mentioned"); |
| } |
| |
| while i < 3 { |
| //~^ while_immutable_condition |
| |
| let mut i = 5; |
| fn_mutref(&mut i); |
| println!("KO - shadowed"); |
| } |
| |
| while i < 3 && j > 0 { |
| i = 5; |
| println!("OK - i in cond and mentioned"); |
| } |
| } |
| |
| fn used_immutable() { |
| let mut i = 0; |
| |
| while i < 3 { |
| //~^ while_immutable_condition |
| |
| fn_constref(&i); |
| println!("KO - const reference"); |
| } |
| |
| while i < 3 { |
| //~^ while_immutable_condition |
| |
| fn_val(i); |
| println!("KO - passed by value"); |
| } |
| |
| while i < 3 { |
| println!("OK - passed by mutable reference"); |
| fn_mutref(&mut i) |
| } |
| |
| while i < 3 { |
| fn_mutref(&mut i); |
| println!("OK - passed by mutable reference"); |
| } |
| } |
| |
| const N: i32 = 5; |
| const B: bool = false; |
| |
| fn consts() { |
| while false { |
| println!("Constants are not linted"); |
| } |
| |
| while B { |
| println!("Constants are not linted"); |
| } |
| |
| while N > 0 { |
| println!("Constants are not linted"); |
| } |
| } |
| |
| use std::cell::Cell; |
| |
| fn maybe_i_mutate(i: &Cell<bool>) { |
| unimplemented!() |
| } |
| |
| fn internally_mutable() { |
| let b = Cell::new(true); |
| |
| while b.get() { |
| // b cannot be silently coerced to `bool` |
| maybe_i_mutate(&b); |
| println!("OK - Method call within condition"); |
| } |
| } |
| |
| struct Counter { |
| count: usize, |
| } |
| |
| impl Counter { |
| fn inc(&mut self) { |
| self.count += 1; |
| } |
| |
| fn inc_n(&mut self, n: usize) { |
| while self.count < n { |
| self.inc(); |
| } |
| println!("OK - self borrowed mutably"); |
| } |
| |
| fn print_n(&self, n: usize) { |
| while self.count < n { |
| //~^ while_immutable_condition |
| |
| println!("KO - {} is not mutated", self.count); |
| } |
| } |
| } |
| |
| fn while_loop_with_break_and_return() { |
| let y = 0; |
| while y < 10 { |
| //~^ while_immutable_condition |
| |
| if y == 0 { |
| break; |
| } |
| println!("KO - loop contains break"); |
| } |
| |
| while y < 10 { |
| //~^ while_immutable_condition |
| |
| if y == 0 { |
| return; |
| } |
| println!("KO - loop contains return"); |
| } |
| } |
| |
| fn immutable_condition_false_positive(mut n: u64) -> u32 { |
| let mut count = 0; |
| while { |
| n >>= 1; |
| n != 0 |
| } { |
| count += 1; |
| } |
| count |
| } |
| |
| fn main() { |
| immutable_condition(); |
| unused_var(); |
| used_immutable(); |
| internally_mutable(); |
| immutable_condition_false_positive(5); |
| |
| let mut c = Counter { count: 0 }; |
| c.inc_n(5); |
| c.print_n(2); |
| |
| while_loop_with_break_and_return(); |
| } |