-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;
/// 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 {
})
}
+ 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, ..) => {
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;
+ }
+}
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;
+ }
+}
--- /dev/null
+// 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() {}
--- /dev/null
+// 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() {}
--- /dev/null
+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
+