about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/indexing_slicing.rs45
-rw-r--r--clippy_lints/src/lib.rs8
-rw-r--r--clippy_lints/src/utils/conf.rs8
-rw-r--r--tests/ui-toml/suppress_lint_in_const/clippy.toml2
-rw-r--r--tests/ui-toml/suppress_lint_in_const/test.stderr3
-rw-r--r--tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr2
-rw-r--r--tests/ui/indexing_slicing_index.stderr23
-rw-r--r--tests/ui/indexing_slicing_slice.stderr47
8 files changed, 63 insertions, 75 deletions
diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs
index 92facbbf034..dfea0bf18d1 100644
--- a/clippy_lints/src/indexing_slicing.rs
+++ b/clippy_lints/src/indexing_slicing.rs
@@ -1,9 +1,10 @@
 //! lint on indexing and slicing operations
 
 use clippy_utils::consts::{constant, Constant};
-use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
+use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::higher;
 use rustc_ast::ast::RangeLimits;
+use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
@@ -86,18 +87,20 @@ impl_lint_pass!(IndexingSlicing => [INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING]);
 
 #[derive(Copy, Clone)]
 pub struct IndexingSlicing {
-    suppress_lint_in_const: bool,
+    suppress_restriction_lint_in_const: bool,
 }
 
 impl IndexingSlicing {
-    pub fn new(suppress_lint_in_const: bool) -> Self {
-        Self { suppress_lint_in_const }
+    pub fn new(suppress_restriction_lint_in_const: bool) -> Self {
+        Self {
+            suppress_restriction_lint_in_const,
+        }
     }
 }
 
 impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if self.suppress_lint_in_const && cx.tcx.hir().is_inside_const_context(expr.hir_id) {
+        if self.suppress_restriction_lint_in_const && cx.tcx.hir().is_inside_const_context(expr.hir_id) {
             return;
         }
 
@@ -152,12 +155,19 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
                     (None, None) => return, // [..] is ok.
                 };
 
-                span_lint_and_help(cx, INDEXING_SLICING, expr.span, "slicing may panic", None, help_msg);
+                span_lint_and_then(cx, INDEXING_SLICING, expr.span, "slicing may panic", |diag| {
+                    let note = if cx.tcx.hir().is_inside_const_context(expr.hir_id) {
+                        "the suggestion might not be applicable in constant blocks"
+                    } else {
+                        ""
+                    };
+                    diag.span_suggestion(expr.span, help_msg, note, Applicability::MachineApplicable);
+                });
             } else {
                 // Catchall non-range index, i.e., [n] or [n << m]
                 if let ty::Array(..) = ty.kind() {
                     // Index is a const block.
-                    if self.suppress_lint_in_const && let ExprKind::ConstBlock(..) = index.kind {
+                    if self.suppress_restriction_lint_in_const && let ExprKind::ConstBlock(..) = index.kind {
                         return;
                     }
                     // Index is a constant uint.
@@ -167,14 +177,19 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
                     }
                 }
 
-                span_lint_and_help(
-                    cx,
-                    INDEXING_SLICING,
-                    expr.span,
-                    "indexing may panic",
-                    None,
-                    "consider using `.get(n)` or `.get_mut(n)` instead",
-                );
+                span_lint_and_then(cx, INDEXING_SLICING, expr.span, "indexing may panic", |diag| {
+                    let note = if cx.tcx.hir().is_inside_const_context(expr.hir_id) {
+                        "the suggestion might not be applicable in constant blocks"
+                    } else {
+                        ""
+                    };
+                    diag.span_suggestion(
+                        expr.span,
+                        "consider using `.get(n)` or `.get_mut(n)` instead",
+                        note,
+                        Applicability::MachineApplicable,
+                    );
+                });
             }
         }
     }
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 3b5bac644ef..2dc3a082277 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -562,7 +562,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
     let allow_expect_in_tests = conf.allow_expect_in_tests;
     let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
-    let suppress_lint_in_const = conf.suppress_lint_in_const;
+    let suppress_restriction_lint_in_const = conf.suppress_restriction_lint_in_const;
     store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv())));
     store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv)));
     store.register_late_pass(move |_| {
@@ -685,7 +685,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|_| Box::new(inherent_impl::MultipleInherentImpl));
     store.register_late_pass(|_| Box::new(neg_cmp_op_on_partial_ord::NoNegCompOpForPartialOrd));
     store.register_late_pass(|_| Box::new(unwrap::Unwrap));
-    store.register_late_pass(move |_| Box::new(indexing_slicing::IndexingSlicing::new(suppress_lint_in_const)));
+    store.register_late_pass(move |_| {
+        Box::new(indexing_slicing::IndexingSlicing::new(
+            suppress_restriction_lint_in_const,
+        ))
+    });
     store.register_late_pass(|_| Box::new(non_copy_const::NonCopyConst));
     store.register_late_pass(|_| Box::new(ptr_offset_with_cast::PtrOffsetWithCast));
     store.register_late_pass(|_| Box::new(redundant_clone::RedundantClone));
diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs
index 4a0e135db83..0022044ea41 100644
--- a/clippy_lints/src/utils/conf.rs
+++ b/clippy_lints/src/utils/conf.rs
@@ -408,8 +408,12 @@ define_Conf! {
     (allow_mixed_uninlined_format_args: bool = true),
     /// Lint: INDEXING_SLICING
     ///
-    /// Whether to suppress lint in const function
-    (suppress_lint_in_const: bool = true),
+    /// Whether to suppress a restriction lint in constant code. In same
+    /// cases the restructured operation might not be unavoidable, as the
+    /// suggested counterparts are unavailable in constant code. This
+    /// configuration will cause restriction lints to trigger even
+    /// if no suggestion can be made.
+    (suppress_restriction_lint_in_const: bool = true),
 }
 
 /// Search for the configuration file.
diff --git a/tests/ui-toml/suppress_lint_in_const/clippy.toml b/tests/ui-toml/suppress_lint_in_const/clippy.toml
index fd459ff5ac5..d458f53a73d 100644
--- a/tests/ui-toml/suppress_lint_in_const/clippy.toml
+++ b/tests/ui-toml/suppress_lint_in_const/clippy.toml
@@ -1 +1 @@
-suppress-lint-in-const = false
\ No newline at end of file
+suppress-restriction-lint-in-const = false
\ No newline at end of file
diff --git a/tests/ui-toml/suppress_lint_in_const/test.stderr b/tests/ui-toml/suppress_lint_in_const/test.stderr
index b4f6fe0c024..4e4583ab33c 100644
--- a/tests/ui-toml/suppress_lint_in_const/test.stderr
+++ b/tests/ui-toml/suppress_lint_in_const/test.stderr
@@ -2,9 +2,8 @@ error: indexing may panic
   --> $DIR/test.rs:11:9
    |
 LL |         self.value[0] & 0b1000_0000 != 0
-   |         ^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^ help: consider using `.get(n)` or `.get_mut(n)` instead: `the suggestion might not be applicable in constant blocks`
    |
-   = help: consider using `.get(n)` or `.get_mut(n)` instead
    = note: `-D clippy::indexing-slicing` implied by `-D warnings`
 
 error: aborting due to previous error
diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index 521af13fe03..6ef2abb15b2 100644
--- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -35,7 +35,7 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie
            pass-by-value-size-limit
            single-char-binding-names-threshold
            standard-macro-braces
-           suppress-lint-in-const
+           suppress-restriction-lint-in-const
            third-party
            too-large-for-stack
            too-many-arguments-threshold
diff --git a/tests/ui/indexing_slicing_index.stderr b/tests/ui/indexing_slicing_index.stderr
index d8b6e3f1262..30fb6990795 100644
--- a/tests/ui/indexing_slicing_index.stderr
+++ b/tests/ui/indexing_slicing_index.stderr
@@ -14,50 +14,39 @@ error: indexing may panic
   --> $DIR/indexing_slicing_index.rs:22:5
    |
 LL |     x[index];
-   |     ^^^^^^^^
+   |     ^^^^^^^^ help: consider using `.get(n)` or `.get_mut(n)` instead
    |
-   = help: consider using `.get(n)` or `.get_mut(n)` instead
    = note: `-D clippy::indexing-slicing` implied by `-D warnings`
 
 error: indexing may panic
   --> $DIR/indexing_slicing_index.rs:38:5
    |
 LL |     v[0];
-   |     ^^^^
-   |
-   = help: consider using `.get(n)` or `.get_mut(n)` instead
+   |     ^^^^ help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
   --> $DIR/indexing_slicing_index.rs:39:5
    |
 LL |     v[10];
-   |     ^^^^^
-   |
-   = help: consider using `.get(n)` or `.get_mut(n)` instead
+   |     ^^^^^ help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
   --> $DIR/indexing_slicing_index.rs:40:5
    |
 LL |     v[1 << 3];
-   |     ^^^^^^^^^
-   |
-   = help: consider using `.get(n)` or `.get_mut(n)` instead
+   |     ^^^^^^^^^ help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
   --> $DIR/indexing_slicing_index.rs:46:5
    |
 LL |     v[N];
-   |     ^^^^
-   |
-   = help: consider using `.get(n)` or `.get_mut(n)` instead
+   |     ^^^^ help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
   --> $DIR/indexing_slicing_index.rs:47:5
    |
 LL |     v[M];
-   |     ^^^^
-   |
-   = help: consider using `.get(n)` or `.get_mut(n)` instead
+   |     ^^^^ help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/indexing_slicing_index.rs:10:24
diff --git a/tests/ui/indexing_slicing_slice.stderr b/tests/ui/indexing_slicing_slice.stderr
index dc54bd41365..ac2cc009a22 100644
--- a/tests/ui/indexing_slicing_slice.stderr
+++ b/tests/ui/indexing_slicing_slice.stderr
@@ -2,50 +2,39 @@ error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:12:6
    |
 LL |     &x[index..];
-   |      ^^^^^^^^^^
+   |      ^^^^^^^^^^ help: consider using `.get(n..)` or .get_mut(n..)` instead
    |
-   = help: consider using `.get(n..)` or .get_mut(n..)` instead
    = note: `-D clippy::indexing-slicing` implied by `-D warnings`
 
 error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:13:6
    |
 LL |     &x[..index];
-   |      ^^^^^^^^^^
-   |
-   = help: consider using `.get(..n)`or `.get_mut(..n)` instead
+   |      ^^^^^^^^^^ help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:14:6
    |
 LL |     &x[index_from..index_to];
-   |      ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
+   |      ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
 
 error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:15:6
    |
 LL |     &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to].
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider using `.get(..n)`or `.get_mut(..n)` instead
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:15:6
    |
 LL |     &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to].
-   |      ^^^^^^^^^^^^^^^
-   |
-   = help: consider using `.get(n..)` or .get_mut(n..)` instead
+   |      ^^^^^^^^^^^^^^^ help: consider using `.get(n..)` or .get_mut(n..)` instead
 
 error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:16:6
    |
 LL |     &x[5..][..10]; // Two lint reports, one for out of bounds [5..] and another for slicing [..10].
-   |      ^^^^^^^^^^^^
-   |
-   = help: consider using `.get(..n)`or `.get_mut(..n)` instead
+   |      ^^^^^^^^^^^^ help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: range is out of bounds
   --> $DIR/indexing_slicing_slice.rs:16:8
@@ -59,17 +48,13 @@ error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:17:6
    |
 LL |     &x[0..][..3];
-   |      ^^^^^^^^^^^
-   |
-   = help: consider using `.get(..n)`or `.get_mut(..n)` instead
+   |      ^^^^^^^^^^^ help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:18:6
    |
 LL |     &x[1..][..5];
-   |      ^^^^^^^^^^^
-   |
-   = help: consider using `.get(..n)`or `.get_mut(..n)` instead
+   |      ^^^^^^^^^^^ help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: range is out of bounds
   --> $DIR/indexing_slicing_slice.rs:25:12
@@ -87,17 +72,13 @@ error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:31:6
    |
 LL |     &v[10..100];
-   |      ^^^^^^^^^^
-   |
-   = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
+   |      ^^^^^^^^^^ help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
 
 error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:32:6
    |
 LL |     &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100].
-   |      ^^^^^^^^^^^^^^
-   |
-   = help: consider using `.get(..n)`or `.get_mut(..n)` instead
+   |      ^^^^^^^^^^^^^^ help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: range is out of bounds
   --> $DIR/indexing_slicing_slice.rs:32:8
@@ -109,17 +90,13 @@ error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:33:6
    |
 LL |     &v[10..];
-   |      ^^^^^^^
-   |
-   = help: consider using `.get(n..)` or .get_mut(n..)` instead
+   |      ^^^^^^^ help: consider using `.get(n..)` or .get_mut(n..)` instead
 
 error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:34:6
    |
 LL |     &v[..100];
-   |      ^^^^^^^^
-   |
-   = help: consider using `.get(..n)`or `.get_mut(..n)` instead
+   |      ^^^^^^^^ help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: aborting due to 16 previous errors