if let ExprKind::Index(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::Array(_, s) = ty.sty {
let size: u128 = s.assert_usize(cx.tcx).unwrap().into();
- match to_const_range(cx, range, size) {
- (None, None) => {},
- (Some(start), None) => {
- if start > size {
- utils::span_lint(
- cx,
- OUT_OF_BOUNDS_INDEXING,
- expr.span,
- "range is out of bounds",
- );
- return;
- }
- },
- (None, Some(end)) => {
- if end > size {
- utils::span_lint(
- cx,
- OUT_OF_BOUNDS_INDEXING,
- expr.span,
- "range is out of bounds",
- );
- return;
- }
- },
- (Some(start), Some(end)) => {
- if start > size || end > size {
- utils::span_lint(
- cx,
- OUT_OF_BOUNDS_INDEXING,
- expr.span,
- "range is out of bounds",
- );
- }
- // early return because both start and end are constant
+ let const_range = to_const_range(cx, range, size);
+
+ if let (Some(start), _) = const_range {
+ if start > size {
+ utils::span_lint(
+ cx,
+ OUT_OF_BOUNDS_INDEXING,
+ expr.span,
+ "range is out of bounds",
+ );
+ return;
+ }
+ }
+
+ if let (_, Some(end)) = const_range {
+ if end > size {
+ utils::span_lint(
+ cx,
+ OUT_OF_BOUNDS_INDEXING,
+ expr.span,
+ "range is out of bounds",
+ );
return;
- },
+ }
+ }
+
+ if let (Some(_), Some(_)) = const_range {
+ // early return because both start and end are constants
+ // and we have proven above that they are in bounds
+ return;
}
}