diff --git a/clippy_lints/src/array_indexing.rs b/clippy_lints/src/array_indexing.rs deleted file mode 100644 index 77aa5e834..000000000 --- a/clippy_lints/src/array_indexing.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::consts::{constant, Constant}; -use crate::utils::higher::Range; -use crate::utils::{self, higher}; -use rustc::hir; -use rustc::lint::*; -use rustc::ty; -use syntax::ast::RangeLimits; - -/// **What it does:** Checks for out of bounds array indexing with a constant -/// index. -/// -/// **Why is this bad?** This will always panic at runtime. -/// -/// **Known problems:** Hopefully none. -/// -/// **Example:** -/// ```rust -/// let x = [1,2,3,4]; -/// ... -/// x[9]; -/// &x[2..9]; -/// ``` -declare_clippy_lint! { - pub OUT_OF_BOUNDS_INDEXING, - correctness, - "out of bounds constant indexing" -} - -/// **What it does:** Checks for usage of indexing or slicing. -/// -/// **Why is this bad?** Usually, this can be safely allowed. However, in some -/// domains such as kernel development, a panic can cause the whole operating -/// system to crash. -/// -/// **Known problems:** Hopefully none. -/// -/// **Example:** -/// ```rust -/// ... -/// x[2]; -/// &x[0..2]; -/// ``` -declare_clippy_lint! { - pub INDEXING_SLICING, - restriction, - "indexing/slicing usage" -} - -#[derive(Copy, Clone)] -pub struct ArrayIndexing; - -impl LintPass for ArrayIndexing { - fn get_lints(&self) -> LintArray { - lint_array!(INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING) - } -} - -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIndexing { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) { - if let hir::ExprIndex(ref array, ref index) = e.node { - // Array with known size can be checked statically - let ty = cx.tables.expr_ty(array); - if let ty::TyArray(_, size) = ty.sty { - let size = size.assert_usize(cx.tcx).unwrap().into(); - - // Index is a constant uint - if let Some((Constant::Int(const_index), _)) = constant(cx, cx.tables, index) { - if size <= const_index { - utils::span_lint(cx, OUT_OF_BOUNDS_INDEXING, e.span, "const index is out of bounds"); - } - - return; - } - - // Index is a constant range - if let Some(range) = higher::range(cx, index) { - if let Some((start, end)) = to_const_range(cx, range, size) { - if start > size || end > size { - utils::span_lint(cx, OUT_OF_BOUNDS_INDEXING, e.span, "range is out of bounds"); - } - return; - } - } - } - - if let Some(range) = higher::range(cx, index) { - // Full ranges are always valid - if range.start.is_none() && range.end.is_none() { - return; - } - - // Impossible to know if indexing or slicing is correct - utils::span_lint(cx, INDEXING_SLICING, e.span, "slicing may panic"); - } else { - utils::span_lint(cx, INDEXING_SLICING, e.span, "indexing may panic"); - } - } - } -} - -/// Returns an option containing a tuple with the start and end (exclusive) of -/// the range. -fn to_const_range<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, range: Range, array_size: u128) -> Option<(u128, u128)> { - let s = range.start.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c)); - let start = match s { - Some(Some(Constant::Int(x))) => x, - Some(_) => return None, - None => 0, - }; - - let e = range.end.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c)); - let end = match e { - Some(Some(Constant::Int(x))) => if range.limits == RangeLimits::Closed { - x + 1 - } else { - x - }, - Some(_) => return None, - None => array_size, - }; - - Some((start, end)) -} diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs new file mode 100644 index 000000000..7dd72a538 --- /dev/null +++ b/clippy_lints/src/indexing_slicing.rs @@ -0,0 +1,183 @@ +//! lint on indexing and slicing operations + +use crate::consts::{constant, Constant}; +use crate::utils; +use crate::utils::higher; +use crate::utils::higher::Range; +use rustc::hir::*; +use rustc::lint::*; +use rustc::ty; +use syntax::ast::RangeLimits; + +/// **What it does:** Checks for out of bounds array indexing with a constant +/// index. +/// +/// **Why is this bad?** This will always panic at runtime. +/// +/// **Known problems:** Hopefully none. +/// +/// **Example:** +/// ```rust +/// let x = [1,2,3,4]; +/// +/// // Bad +/// x[9]; +/// &x[2..9]; +/// +/// // Good +/// x[0]; +/// x[3]; +/// ``` +declare_clippy_lint! { + pub OUT_OF_BOUNDS_INDEXING, + correctness, + "out of bounds constant indexing" +} + +/// **What it does:** Checks for usage of indexing or slicing. Arrays are special cased, this lint +/// does report on arrays if we can tell that slicing operations are in bounds and does not +/// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint. +/// +/// **Why is this bad?** Indexing and slicing can panic at runtime and there are +/// safe alternatives. +/// +/// **Known problems:** Hopefully none. +/// +/// **Example:** +/// ```rust +/// // Vector +/// let x = vec![0; 5]; +/// +/// // Bad +/// x[2]; +/// &x[2..100]; +/// &x[2..]; +/// &x[..100]; +/// +/// // Good +/// x.get(2); +/// x.get(2..100); +/// x.get(2..); +/// x.get(..100); +/// +/// // Array +/// let y = [0, 1, 2, 3]; +/// +/// // Bad +/// &y[10..100]; +/// &y[10..]; +/// &y[..100]; +/// +/// // Good +/// &y[2..]; +/// &y[..2]; +/// &y[0..3]; +/// y.get(10); +/// y.get(10..100); +/// y.get(10..); +/// y.get(..100); +/// ``` +declare_clippy_lint! { + pub INDEXING_SLICING, + pedantic, + "indexing/slicing usage" +} + +#[derive(Copy, Clone)] +pub struct IndexingSlicing; + +impl LintPass for IndexingSlicing { + fn get_lints(&self) -> LintArray { + lint_array!(INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING) + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing { + fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { + if let ExprIndex(ref array, ref index) = &expr.node { + let ty = cx.tables.expr_ty(array); + if let Some(range) = higher::range(cx, index) { + // Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..] + if let ty::TyArray(_, s) = ty.sty { + let size: u128 = s.assert_usize(cx.tcx).unwrap().into(); + // Index is a constant range. + if let Some((start, end)) = to_const_range(cx, range, size) { + if start > size || end > size { + utils::span_lint( + cx, + OUT_OF_BOUNDS_INDEXING, + expr.span, + "range is out of bounds", + ); + } + return; + } + } + + let help_msg = match (range.start, range.end) { + (None, Some(_)) => "Consider using `.get(..n)`or `.get_mut(..n)` instead", + (Some(_), None) => "Consider using `.get(n..)` or .get_mut(n..)` instead", + (Some(_), Some(_)) => "Consider using `.get(n..m)` or `.get_mut(n..m)` instead", + (None, None) => return, // [..] is ok. + }; + + utils::span_help_and_lint( + cx, + INDEXING_SLICING, + expr.span, + "slicing may panic.", + help_msg, + ); + } else { + // Catchall non-range index, i.e. [n] or [n << m] + if let ty::TyArray(..) = ty.sty { + // Index is a constant uint. + if let Some(..) = constant(cx, cx.tables, index) { + // Let rustc's `const_err` lint handle constant `usize` indexing on arrays. + return; + } + } + + utils::span_help_and_lint( + cx, + INDEXING_SLICING, + expr.span, + "indexing may panic.", + "Consider using `.get(n)` or `.get_mut(n)` instead", + ); + } + } + } +} + +/// Returns an option containing a tuple with the start and end (exclusive) of +/// the range. +fn to_const_range<'a, 'tcx>( + cx: &LateContext<'a, 'tcx>, + range: Range, + array_size: u128, +) -> Option<(u128, u128)> { + let s = range + .start + .map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c)); + let start = match s { + Some(Some(Constant::Int(x))) => x, + Some(_) => return None, + None => 0, + }; + + let e = range + .end + .map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c)); + let end = match e { + Some(Some(Constant::Int(x))) => if range.limits == RangeLimits::Closed { + x + 1 + } else { + x + }, + Some(_) => return None, + None => array_size, + }; + + Some((start, end)) +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index a2f2ae8ab..621b21429 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -6,7 +6,7 @@ #![feature(stmt_expr_attributes)] #![feature(range_contains)] #![feature(macro_vis_matcher)] -#![allow(unknown_lints, indexing_slicing, shadow_reuse, missing_docs_in_private_items)] +#![allow(unknown_lints, shadow_reuse, missing_docs_in_private_items)] #![recursion_limit = "256"] #![allow(stable_features)] #![feature(iterator_find_map)] @@ -99,7 +99,6 @@ pub mod utils; // begin lints modules, do not remove this comment, it’s used in `update_lints` pub mod approx_const; pub mod arithmetic; -pub mod array_indexing; pub mod assign_ops; pub mod attrs; pub mod bit_mask; @@ -139,6 +138,7 @@ pub mod identity_conversion; pub mod identity_op; pub mod if_let_redundant_pattern_matching; pub mod if_not_else; +pub mod indexing_slicing; pub mod infallible_destructuring_match; pub mod infinite_iter; pub mod inherent_impl; @@ -355,7 +355,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { ); reg.register_late_lint_pass(box escape::Pass{too_large_for_stack: conf.too_large_for_stack}); reg.register_early_lint_pass(box misc_early::MiscEarly); - reg.register_late_lint_pass(box array_indexing::ArrayIndexing); reg.register_late_lint_pass(box panic_unimplemented::Pass); reg.register_late_lint_pass(box strings::StringLitAsBytes); reg.register_late_lint_pass(box derive::Derive); @@ -432,12 +431,11 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_late_lint_pass(box unwrap::Pass); reg.register_late_lint_pass(box duration_subsec::DurationSubsec); reg.register_late_lint_pass(box default_trait_access::DefaultTraitAccess); - + reg.register_late_lint_pass(box indexing_slicing::IndexingSlicing); reg.register_lint_group("clippy_restriction", vec![ arithmetic::FLOAT_ARITHMETIC, arithmetic::INTEGER_ARITHMETIC, - array_indexing::INDEXING_SLICING, assign_ops::ASSIGN_OPS, else_if_without_else::ELSE_IF_WITHOUT_ELSE, inherent_impl::MULTIPLE_INHERENT_IMPL, @@ -468,6 +466,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { enum_variants::PUB_ENUM_VARIANT_NAMES, enum_variants::STUTTER, if_not_else::IF_NOT_ELSE, + indexing_slicing::INDEXING_SLICING, infinite_iter::MAYBE_INFINITE_ITER, items_after_statements::ITEMS_AFTER_STATEMENTS, matches::SINGLE_MATCH_ELSE, @@ -500,7 +499,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_lint_group("clippy", vec![ approx_const::APPROX_CONSTANT, - array_indexing::OUT_OF_BOUNDS_INDEXING, + indexing_slicing::OUT_OF_BOUNDS_INDEXING, assign_ops::ASSIGN_OP_PATTERN, assign_ops::MISREFACTORED_ASSIGN_OP, attrs::DEPRECATED_SEMVER, @@ -863,7 +862,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_lint_group("clippy_correctness", vec![ approx_const::APPROX_CONSTANT, - array_indexing::OUT_OF_BOUNDS_INDEXING, + indexing_slicing::OUT_OF_BOUNDS_INDEXING, attrs::DEPRECATED_SEMVER, attrs::USELESS_ATTRIBUTE, bit_mask::BAD_BIT_MASK, diff --git a/tests/ui/array_indexing.rs b/tests/ui/array_indexing.rs deleted file mode 100644 index a01600eda..000000000 --- a/tests/ui/array_indexing.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![feature(plugin)] - - -#![warn(indexing_slicing)] -#![warn(out_of_bounds_indexing)] -#![allow(no_effect, unnecessary_operation)] - -fn main() { - let x = [1,2,3,4]; - x[0]; - x[3]; - x[4]; - x[1 << 3]; - &x[1..5]; - &x[0..3]; - &x[0..=4]; - &x[..=4]; - &x[..]; - &x[1..]; - &x[4..]; - &x[5..]; - &x[..4]; - &x[..5]; - - let y = &x; - y[0]; - &y[1..2]; - &y[..]; - &y[0..=4]; - &y[..=4]; - - let empty: [i8; 0] = []; - empty[0]; - &empty[1..5]; - &empty[0..=4]; - &empty[..=4]; - &empty[..]; - &empty[0..]; - &empty[0..0]; - &empty[0..=0]; - &empty[..=0]; - &empty[..0]; - &empty[1..]; - &empty[..4]; -} diff --git a/tests/ui/array_indexing.stderr b/tests/ui/array_indexing.stderr deleted file mode 100644 index d730b0129..000000000 --- a/tests/ui/array_indexing.stderr +++ /dev/null @@ -1,120 +0,0 @@ -error: const index is out of bounds - --> $DIR/array_indexing.rs:12:5 - | -12 | x[4]; - | ^^^^ - | - = note: `-D out-of-bounds-indexing` implied by `-D warnings` - -error: const index is out of bounds - --> $DIR/array_indexing.rs:13:5 - | -13 | x[1 << 3]; - | ^^^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:14:6 - | -14 | &x[1..5]; - | ^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:16:6 - | -16 | &x[0..=4]; - | ^^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:17:6 - | -17 | &x[..=4]; - | ^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:21:6 - | -21 | &x[5..]; - | ^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:23:6 - | -23 | &x[..5]; - | ^^^^^^ - -error: indexing may panic - --> $DIR/array_indexing.rs:26:5 - | -26 | y[0]; - | ^^^^ - | - = note: `-D indexing-slicing` implied by `-D warnings` - -error: slicing may panic - --> $DIR/array_indexing.rs:27:6 - | -27 | &y[1..2]; - | ^^^^^^^ - -error: slicing may panic - --> $DIR/array_indexing.rs:29:6 - | -29 | &y[0..=4]; - | ^^^^^^^^ - -error: slicing may panic - --> $DIR/array_indexing.rs:30:6 - | -30 | &y[..=4]; - | ^^^^^^^ - -error: const index is out of bounds - --> $DIR/array_indexing.rs:33:5 - | -33 | empty[0]; - | ^^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:34:6 - | -34 | &empty[1..5]; - | ^^^^^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:35:6 - | -35 | &empty[0..=4]; - | ^^^^^^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:36:6 - | -36 | &empty[..=4]; - | ^^^^^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:40:6 - | -40 | &empty[0..=0]; - | ^^^^^^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:41:6 - | -41 | &empty[..=0]; - | ^^^^^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:43:6 - | -43 | &empty[1..]; - | ^^^^^^^^^^ - -error: range is out of bounds - --> $DIR/array_indexing.rs:44:6 - | -44 | &empty[..4]; - | ^^^^^^^^^^ - -error: aborting due to 19 previous errors - diff --git a/tests/ui/indexing_slicing.rs b/tests/ui/indexing_slicing.rs new file mode 100644 index 000000000..e39dc9236 --- /dev/null +++ b/tests/ui/indexing_slicing.rs @@ -0,0 +1,82 @@ +#![feature(plugin)] +#![warn(indexing_slicing)] +#![warn(out_of_bounds_indexing)] +#![allow(no_effect, unnecessary_operation)] + +fn main() { + let x = [1, 2, 3, 4]; + let index: usize = 1; + let index_from: usize = 2; + let index_to: usize = 3; + x[index]; + &x[index..]; + &x[..index]; + &x[index_from..index_to]; + &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to]. + x[4]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays. + x[1 << 3]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays. + &x[..=4]; + &x[1..5]; + &x[5..][..10]; // Two lint reports, one for [5..] and another for [..10]. + &x[5..]; + &x[..5]; + &x[5..].iter().map(|x| 2 * x).collect::>(); + &x[0..=4]; + &x[0..][..3]; + &x[1..][..5]; + + &x[4..]; // Ok, should not produce stderr. + &x[..4]; // Ok, should not produce stderr. + &x[..]; // Ok, should not produce stderr. + &x[1..]; // Ok, should not produce stderr. + &x[2..].iter().map(|x| 2 * x).collect::>(); // Ok, should not produce stderr. + &x[0..].get(..3); // Ok, should not produce stderr. + x[0]; // Ok, should not produce stderr. + x[3]; // Ok, should not produce stderr. + &x[0..3]; // Ok, should not produce stderr. + + let y = &x; + y[0]; + &y[1..2]; + &y[0..=4]; + &y[..=4]; + + &y[..]; // Ok, should not produce stderr. + + let empty: [i8; 0] = []; + empty[0]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays. + &empty[1..5]; + &empty[0..=4]; + &empty[..=4]; + &empty[1..]; + &empty[..4]; + &empty[0..=0]; + &empty[..=0]; + + &empty[0..]; // Ok, should not produce stderr. + &empty[0..0]; // Ok, should not produce stderr. + &empty[..0]; // Ok, should not produce stderr. + &empty[..]; // Ok, should not produce stderr. + + let v = vec![0; 5]; + v[0]; + v[10]; + v[1 << 3]; + &v[10..100]; + &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100]. + &v[10..]; + &v[..100]; + + &v[..]; // Ok, should not produce stderr. + + // + // Continue tests at end function to minimize the changes to this file's corresponding stderr. + // + + const N: usize = 15; // Out of bounds + const M: usize = 3; // In bounds + x[N]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays. + x[M]; // Ok, should not produce stderr. + v[N]; + v[M]; +} diff --git a/tests/ui/indexing_slicing.stderr b/tests/ui/indexing_slicing.stderr new file mode 100644 index 000000000..ee11dce6d --- /dev/null +++ b/tests/ui/indexing_slicing.stderr @@ -0,0 +1,271 @@ +error: indexing may panic. + --> $DIR/indexing_slicing.rs:11:5 + | +11 | x[index]; + | ^^^^^^^^ + | + = note: `-D indexing-slicing` implied by `-D warnings` + = help: Consider using `.get(n)` or `.get_mut(n)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:12:6 + | +12 | &x[index..]; + | ^^^^^^^^^^ + | + = help: Consider using `.get(n..)` or .get_mut(n..)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:13:6 + | +13 | &x[..index]; + | ^^^^^^^^^^ + | + = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:14:6 + | +14 | &x[index_from..index_to]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: Consider using `.get(n..m)` or `.get_mut(n..m)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:15:6 + | +15 | &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 + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:15:6 + | +15 | &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 + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:18:6 + | +18 | &x[..=4]; + | ^^^^^^^ + | + = note: `-D out-of-bounds-indexing` implied by `-D warnings` + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:19:6 + | +19 | &x[1..5]; + | ^^^^^^^ + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:20:6 + | +20 | &x[5..][..10]; // Two lint reports, one for [5..] and another for [..10]. + | ^^^^^^^^^^^^ + | + = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:20:6 + | +20 | &x[5..][..10]; // Two lint reports, one for [5..] and another for [..10]. + | ^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:21:6 + | +21 | &x[5..]; + | ^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:22:6 + | +22 | &x[..5]; + | ^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:23:6 + | +23 | &x[5..].iter().map(|x| 2 * x).collect::>(); + | ^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:24:6 + | +24 | &x[0..=4]; + | ^^^^^^^^ + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:25:6 + | +25 | &x[0..][..3]; + | ^^^^^^^^^^^ + | + = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:26:6 + | +26 | &x[1..][..5]; + | ^^^^^^^^^^^ + | + = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + +error: indexing may panic. + --> $DIR/indexing_slicing.rs:39:5 + | +39 | y[0]; + | ^^^^ + | + = help: Consider using `.get(n)` or `.get_mut(n)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:40:6 + | +40 | &y[1..2]; + | ^^^^^^^ + | + = help: Consider using `.get(n..m)` or `.get_mut(n..m)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:41:6 + | +41 | &y[0..=4]; + | ^^^^^^^^ + | + = help: Consider using `.get(n..m)` or `.get_mut(n..m)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:42:6 + | +42 | &y[..=4]; + | ^^^^^^^ + | + = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:48:6 + | +48 | &empty[1..5]; + | ^^^^^^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:49:6 + | +49 | &empty[0..=4]; + | ^^^^^^^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:50:6 + | +50 | &empty[..=4]; + | ^^^^^^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:51:6 + | +51 | &empty[1..]; + | ^^^^^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:52:6 + | +52 | &empty[..4]; + | ^^^^^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:53:6 + | +53 | &empty[0..=0]; + | ^^^^^^^^^^^^ + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:54:6 + | +54 | &empty[..=0]; + | ^^^^^^^^^^^ + +error: indexing may panic. + --> $DIR/indexing_slicing.rs:62:5 + | +62 | v[0]; + | ^^^^ + | + = help: Consider using `.get(n)` or `.get_mut(n)` instead + +error: indexing may panic. + --> $DIR/indexing_slicing.rs:63:5 + | +63 | v[10]; + | ^^^^^ + | + = help: Consider using `.get(n)` or `.get_mut(n)` instead + +error: indexing may panic. + --> $DIR/indexing_slicing.rs:64:5 + | +64 | v[1 << 3]; + | ^^^^^^^^^ + | + = help: Consider using `.get(n)` or `.get_mut(n)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:65:6 + | +65 | &v[10..100]; + | ^^^^^^^^^^ + | + = help: Consider using `.get(n..m)` or `.get_mut(n..m)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:66:6 + | +66 | &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100]. + | ^^^^^^^^^^^^^^ + | + = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + +error: range is out of bounds + --> $DIR/indexing_slicing.rs:66:6 + | +66 | &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100]. + | ^^^^^^^ + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:67:6 + | +67 | &v[10..]; + | ^^^^^^^ + | + = help: Consider using `.get(n..)` or .get_mut(n..)` instead + +error: slicing may panic. + --> $DIR/indexing_slicing.rs:68:6 + | +68 | &v[..100]; + | ^^^^^^^^ + | + = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + +error: indexing may panic. + --> $DIR/indexing_slicing.rs:80:5 + | +80 | v[N]; + | ^^^^ + | + = help: Consider using `.get(n)` or `.get_mut(n)` instead + +error: indexing may panic. + --> $DIR/indexing_slicing.rs:81:5 + | +81 | v[M]; + | ^^^^ + | + = help: Consider using `.get(n)` or `.get_mut(n)` instead + +error: aborting due to 37 previous errors +