about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduardo Broto <ebroto@tutanota.com>2020-05-28 00:36:15 +0200
committerEduardo Broto <ebroto@tutanota.com>2020-05-28 00:58:48 +0200
commit64a05f56c33d4754808ef85e634f72a9053c56fd (patch)
treed08e62253c067ea294ee183e78800f2ba8309c1c
parent7ea7cd165ad6705603852771bf82cc2fd6560db5 (diff)
downloadrust-64a05f56c33d4754808ef85e634f72a9053c56fd.tar.gz
rust-64a05f56c33d4754808ef85e634f72a9053c56fd.zip
len_zero: skip ranges if feature `range_is_empty` is not enabled
-rw-r--r--clippy_lints/src/len_zero.rs17
-rw-r--r--tests/ui/len_zero.fixed8
-rw-r--r--tests/ui/len_zero.rs8
-rw-r--r--tests/ui/len_zero_ranges.fixed14
-rw-r--r--tests/ui/len_zero_ranges.rs14
-rw-r--r--tests/ui/len_zero_ranges.stderr10
6 files changed, 70 insertions, 1 deletions
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index 2ec0b5a8d6f..f5bfede75a7 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -1,4 +1,4 @@
-use crate::utils::{get_item_name, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty};
+use crate::utils::{get_item_name, higher, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty};
 use rustc_ast::ast::LitKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
@@ -259,6 +259,17 @@ fn check_len(
 
 /// Checks if this type has an `is_empty` method.
 fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
+    /// Special case ranges until `range_is_empty` is stabilized. See issue 3807.
+    fn should_skip_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
+        higher::range(cx, expr).map_or(false, |_| {
+            !cx.tcx
+                .features()
+                .declared_lib_features
+                .iter()
+                .any(|(name, _)| name.as_str() == "range_is_empty")
+        })
+    }
+
     /// Gets an `AssocItem` and return true if it matches `is_empty(self)`.
     fn is_is_empty(cx: &LateContext<'_, '_>, item: &ty::AssocItem) -> bool {
         if let ty::AssocKind::Fn = item.kind {
@@ -284,6 +295,10 @@ fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
         })
     }
 
+    if should_skip_range(cx, expr) {
+        return false;
+    }
+
     let ty = &walk_ptrs_ty(cx.tables.expr_ty(expr));
     match ty.kind {
         ty::Dynamic(ref tt, ..) => {
diff --git a/tests/ui/len_zero.fixed b/tests/ui/len_zero.fixed
index 624e5ef8fcf..a29b832eb60 100644
--- a/tests/ui/len_zero.fixed
+++ b/tests/ui/len_zero.fixed
@@ -141,3 +141,11 @@ fn main() {
 fn test_slice(b: &[u8]) {
     if !b.is_empty() {}
 }
+
+mod issue_3807 {
+    // Avoid suggesting changes to ranges if the user did not enable `range_is_empty`.
+    // See https://github.com/rust-lang/rust/issues/48111#issuecomment-445132965
+    fn no_suggestion() {
+        let _ = (0..42).len() == 0;
+    }
+}
diff --git a/tests/ui/len_zero.rs b/tests/ui/len_zero.rs
index 7fba971cfd8..8fd0093f4fd 100644
--- a/tests/ui/len_zero.rs
+++ b/tests/ui/len_zero.rs
@@ -141,3 +141,11 @@ fn main() {
 fn test_slice(b: &[u8]) {
     if b.len() != 0 {}
 }
+
+mod issue_3807 {
+    // Avoid suggesting changes to ranges if the user did not enable `range_is_empty`.
+    // See https://github.com/rust-lang/rust/issues/48111#issuecomment-445132965
+    fn no_suggestion() {
+        let _ = (0..42).len() == 0;
+    }
+}
diff --git a/tests/ui/len_zero_ranges.fixed b/tests/ui/len_zero_ranges.fixed
new file mode 100644
index 00000000000..7da26f8ff4d
--- /dev/null
+++ b/tests/ui/len_zero_ranges.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+#![feature(range_is_empty)]
+#![warn(clippy::len_zero)]
+#![allow(unused)]
+
+mod issue_3807 {
+    // With the feature enabled, `is_empty` should be suggested
+    fn suggestion_is_fine() {
+        let _ = (0..42).is_empty();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/len_zero_ranges.rs b/tests/ui/len_zero_ranges.rs
new file mode 100644
index 00000000000..be7b4244bc0
--- /dev/null
+++ b/tests/ui/len_zero_ranges.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+
+#![feature(range_is_empty)]
+#![warn(clippy::len_zero)]
+#![allow(unused)]
+
+mod issue_3807 {
+    // With the feature enabled, `is_empty` should be suggested
+    fn suggestion_is_fine() {
+        let _ = (0..42).len() == 0;
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/len_zero_ranges.stderr b/tests/ui/len_zero_ranges.stderr
new file mode 100644
index 00000000000..6e5fa41fb08
--- /dev/null
+++ b/tests/ui/len_zero_ranges.stderr
@@ -0,0 +1,10 @@
+error: length comparison to zero
+  --> $DIR/len_zero_ranges.rs:10:17
+   |
+LL |         let _ = (0..42).len() == 0;
+   |                 ^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(0..42).is_empty()`
+   |
+   = note: `-D clippy::len-zero` implied by `-D warnings`
+
+error: aborting due to previous error
+