@@ -7,6 +7,7 @@ mod for_loops_over_fallibles;
7
7
mod iter_next_loop;
8
8
mod manual_flatten;
9
9
mod manual_memcpy;
10
+ mod missing_spin_loop;
10
11
mod mut_range_bound;
11
12
mod needless_collect;
12
13
mod needless_range_loop;
@@ -560,6 +561,42 @@ declare_clippy_lint! {
560
561
"for loops over `Option`s or `Result`s with a single expression can be simplified"
561
562
}
562
563
564
+ declare_clippy_lint ! {
565
+ /// ### What it does
566
+ /// Check for empty spin loops
567
+ ///
568
+ /// ### Why is this bad?
569
+ /// The loop body should have something like `thread::park()` or at least
570
+ /// `std::hint::spin_loop()` to avoid needlessly burning cycles and conserve
571
+ /// energy. Perhaps even better use an actual lock, if possible.
572
+ ///
573
+ /// ### Known problems
574
+ /// This lint doesn't currently trigger on `while let` or
575
+ /// `loop { match .. { .. } }` loops, which would be considered idiomatic in
576
+ /// combination with e.g. `AtomicBool::compare_exchange_weak`.
577
+ ///
578
+ /// ### Example
579
+ ///
580
+ /// ```ignore
581
+ /// use core::sync::atomic::{AtomicBool, Ordering};
582
+ /// let b = AtomicBool::new(true);
583
+ /// // give a ref to `b` to another thread,wait for it to become false
584
+ /// while b.load(Ordering::Acquire) {};
585
+ /// ```
586
+ /// Use instead:
587
+ /// ```rust,no_run
588
+ ///# use core::sync::atomic::{AtomicBool, Ordering};
589
+ ///# let b = AtomicBool::new(true);
590
+ /// while b.load(Ordering::Acquire) {
591
+ /// std::hint::spin_loop()
592
+ /// }
593
+ /// ```
594
+ #[ clippy:: version = "1.59.0" ]
595
+ pub MISSING_SPIN_LOOP ,
596
+ perf,
597
+ "An empty busy waiting loop"
598
+ }
599
+
563
600
declare_lint_pass ! ( Loops => [
564
601
MANUAL_MEMCPY ,
565
602
MANUAL_FLATTEN ,
@@ -579,6 +616,7 @@ declare_lint_pass!(Loops => [
579
616
WHILE_IMMUTABLE_CONDITION ,
580
617
SAME_ITEM_PUSH ,
581
618
SINGLE_ELEMENT_LOOP ,
619
+ MISSING_SPIN_LOOP ,
582
620
] ) ;
583
621
584
622
impl < ' tcx > LateLintPass < ' tcx > for Loops {
@@ -628,6 +666,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
628
666
629
667
if let Some ( higher:: While { condition, body } ) = higher:: While :: hir ( expr) {
630
668
while_immutable_condition:: check ( cx, condition, body) ;
669
+ missing_spin_loop:: check ( cx, condition, body) ;
631
670
}
632
671
633
672
needless_collect:: check ( expr, cx) ;
0 commit comments