Skip to content

Commit 2308856

Browse files
committed
Move some cases from redundant_slicing to deref_by_slicing
1 parent e43e4c7 commit 2308856

7 files changed

+81
-52
lines changed

clippy_lints/src/redundant_slicing.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use if_chain::if_chain;
66
use rustc_ast::util::parser::PREC_PREFIX;
77
use rustc_errors::Applicability;
88
use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
9-
use rustc_lint::{LateContext, LateLintPass};
9+
use rustc_lint::{LateContext, LateLintPass, Lint};
1010
use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability};
1111
use rustc_middle::ty::{subst::GenericArg, TyS};
1212
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -44,7 +44,7 @@ declare_clippy_lint! {
4444

4545
declare_clippy_lint! {
4646
/// ### What it does
47-
/// Checks for slicing expression which are equivalent to dereferencing the
47+
/// Checks for slicing expressions which are equivalent to dereferencing the
4848
/// value.
4949
///
5050
/// ### Why is this bad?
@@ -68,6 +68,9 @@ declare_clippy_lint! {
6868

6969
declare_lint_pass!(RedundantSlicing => [REDUNDANT_SLICING, DEREF_BY_SLICING]);
7070

71+
static REDUNDANT_SLICING_LINT: (&Lint, &str) = (REDUNDANT_SLICING, "redundant slicing of the whole range");
72+
static DEREF_BY_SLICING_LINT: (&Lint, &str) = (DEREF_BY_SLICING, "slicing when dereferencing would work");
73+
7174
impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
7275
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
7376
if expr.span.from_expansion() {
@@ -89,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
8992
});
9093
let mut app = Applicability::MachineApplicable;
9194

92-
let (lint, msg, help, sugg) = if TyS::same_type(expr_ty, indexed_ty) {
95+
let ((lint, msg), help, sugg) = if TyS::same_type(expr_ty, indexed_ty) {
9396
if expr_ref_count > indexed_ref_count {
9497
// Indexing takes self by reference and can't return a reference to that
9598
// reference as it's a local variable. The only way this could happen is if
@@ -100,9 +103,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
100103
}
101104
let deref_count = indexed_ref_count - expr_ref_count;
102105

103-
let (reborrow_str, help_str) = if mutability == Mutability::Mut {
106+
let (lint, reborrow_str, help_str) = if mutability == Mutability::Mut {
104107
// The slice was used to reborrow the mutable reference.
105-
("&mut *", "reborrow the original value instead")
108+
(DEREF_BY_SLICING_LINT, "&mut *", "reborrow the original value instead")
106109
} else if matches!(
107110
parent_expr,
108111
Some(Expr {
@@ -113,11 +116,11 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
113116
matches!(a.kind, Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })))
114117
}) {
115118
// The slice was used to make a temporary reference.
116-
("&*", "reborrow the original value instead")
119+
(DEREF_BY_SLICING_LINT, "&*", "reborrow the original value instead")
117120
} else if deref_count != 0 {
118-
("", "dereference the original value instead")
121+
(DEREF_BY_SLICING_LINT, "", "dereference the original value instead")
119122
} else {
120-
("", "use the original value instead")
123+
(REDUNDANT_SLICING_LINT, "", "use the original value instead")
121124
};
122125

123126
let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;
@@ -127,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
127130
format!("{}{}{}", reborrow_str, "*".repeat(deref_count), snip)
128131
};
129132

130-
(REDUNDANT_SLICING, "redundant slicing of the whole range", help_str, sugg)
133+
(lint, help_str, sugg)
131134
} else if let Some(target_id) = cx.tcx.lang_items().deref_target() {
132135
if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(
133136
cx.param_env,
@@ -140,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
140143
} else {
141144
format!("&{}{}*{}", mutability.prefix_str(), "*".repeat(indexed_ref_count), snip)
142145
};
143-
(DEREF_BY_SLICING, "slicing when dereferencing would work", "dereference the original value instead", sugg)
146+
(DEREF_BY_SLICING_LINT, "dereference the original value instead", sugg)
144147
} else {
145148
return;
146149
}

tests/ui/deref_by_slicing.fixed

+14-1
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,28 @@
22

33
#![warn(clippy::deref_by_slicing)]
44

5+
use std::io::Read;
6+
57
fn main() {
68
let mut vec = vec![0];
79
let _ = &*vec;
810
let _ = &mut *vec;
911

1012
let ref_vec = &mut vec;
1113
let _ = &**ref_vec;
12-
let _ = &mut **ref_vec;
14+
let mut_slice = &mut **ref_vec;
15+
let _ = &mut *mut_slice; // Err, re-borrows slice
1316

1417
let s = String::new();
1518
let _ = &*s;
19+
20+
static S: &[u8] = &[0, 1, 2];
21+
let _ = &mut &*S; // Err, re-borrows slice
22+
23+
let slice: &[u32] = &[0u32, 1u32];
24+
let slice_ref = &slice;
25+
let _ = *slice_ref; // Err, derefs slice
26+
27+
let bytes: &[u8] = &[];
28+
let _ = (&*bytes).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice
1629
}

tests/ui/deref_by_slicing.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,28 @@
22

33
#![warn(clippy::deref_by_slicing)]
44

5+
use std::io::Read;
6+
57
fn main() {
68
let mut vec = vec![0];
79
let _ = &vec[..];
810
let _ = &mut vec[..];
911

1012
let ref_vec = &mut vec;
1113
let _ = &ref_vec[..];
12-
let _ = &mut ref_vec[..];
14+
let mut_slice = &mut ref_vec[..];
15+
let _ = &mut mut_slice[..]; // Err, re-borrows slice
1316

1417
let s = String::new();
1518
let _ = &s[..];
19+
20+
static S: &[u8] = &[0, 1, 2];
21+
let _ = &mut &S[..]; // Err, re-borrows slice
22+
23+
let slice: &[u32] = &[0u32, 1u32];
24+
let slice_ref = &slice;
25+
let _ = &slice_ref[..]; // Err, derefs slice
26+
27+
let bytes: &[u8] = &[];
28+
let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice
1629
}

tests/ui/deref_by_slicing.stderr

+31-7
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,58 @@
11
error: slicing when dereferencing would work
2-
--> $DIR/deref_by_slicing.rs:7:13
2+
--> $DIR/deref_by_slicing.rs:9:13
33
|
44
LL | let _ = &vec[..];
55
| ^^^^^^^^ help: dereference the original value instead: `&*vec`
66
|
77
= note: `-D clippy::deref-by-slicing` implied by `-D warnings`
88

99
error: slicing when dereferencing would work
10-
--> $DIR/deref_by_slicing.rs:8:13
10+
--> $DIR/deref_by_slicing.rs:10:13
1111
|
1212
LL | let _ = &mut vec[..];
1313
| ^^^^^^^^^^^^ help: dereference the original value instead: `&mut *vec`
1414

1515
error: slicing when dereferencing would work
16-
--> $DIR/deref_by_slicing.rs:11:13
16+
--> $DIR/deref_by_slicing.rs:13:13
1717
|
1818
LL | let _ = &ref_vec[..];
1919
| ^^^^^^^^^^^^ help: dereference the original value instead: `&**ref_vec`
2020

2121
error: slicing when dereferencing would work
22-
--> $DIR/deref_by_slicing.rs:12:13
22+
--> $DIR/deref_by_slicing.rs:14:21
2323
|
24-
LL | let _ = &mut ref_vec[..];
25-
| ^^^^^^^^^^^^^^^^ help: dereference the original value instead: `&mut **ref_vec`
24+
LL | let mut_slice = &mut ref_vec[..];
25+
| ^^^^^^^^^^^^^^^^ help: dereference the original value instead: `&mut **ref_vec`
2626

2727
error: slicing when dereferencing would work
2828
--> $DIR/deref_by_slicing.rs:15:13
2929
|
30+
LL | let _ = &mut mut_slice[..]; // Err, re-borrows slice
31+
| ^^^^^^^^^^^^^^^^^^ help: reborrow the original value instead: `&mut *mut_slice`
32+
33+
error: slicing when dereferencing would work
34+
--> $DIR/deref_by_slicing.rs:18:13
35+
|
3036
LL | let _ = &s[..];
3137
| ^^^^^^ help: dereference the original value instead: `&*s`
3238

33-
error: aborting due to 5 previous errors
39+
error: slicing when dereferencing would work
40+
--> $DIR/deref_by_slicing.rs:21:18
41+
|
42+
LL | let _ = &mut &S[..]; // Err, re-borrows slice
43+
| ^^^^^^ help: reborrow the original value instead: `&*S`
44+
45+
error: slicing when dereferencing would work
46+
--> $DIR/deref_by_slicing.rs:25:13
47+
|
48+
LL | let _ = &slice_ref[..]; // Err, derefs slice
49+
| ^^^^^^^^^^^^^^ help: dereference the original value instead: `*slice_ref`
50+
51+
error: slicing when dereferencing would work
52+
--> $DIR/deref_by_slicing.rs:28:13
53+
|
54+
LL | let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice
55+
| ^^^^^^^^^^^^ help: reborrow the original value instead: `(&*bytes)`
56+
57+
error: aborting due to 9 previous errors
3458

tests/ui/redundant_slicing.fixed

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ fn main() {
1414
let _ = (&*v); // Outer borrow is redundant
1515

1616
static S: &[u8] = &[0, 1, 2];
17-
let err = &mut &*S; // Should reborrow instead of slice
17+
let _ = &mut &S[..]; // Ok, re-borrows slice
1818

1919
let mut vec = vec![0];
2020
let mut_slice = &mut vec[..]; // Ok, results in `&mut [_]`
21-
let _ = &mut *mut_slice; // Should reborrow instead of slice
21+
let _ = &mut mut_slice[..]; // Ok, re-borrows slice
2222

2323
let ref_vec = &vec;
2424
let _ = &ref_vec[..]; // Ok, results in `&[_]`
@@ -38,9 +38,9 @@ fn main() {
3838
let _ = m2!(slice); // Don't lint in a macro
3939

4040
let slice_ref = &slice;
41-
let _ = *slice_ref; // Deref instead of slice
41+
let _ = &slice_ref[..]; // Ok, derefs slice
4242

4343
// Issue #7972
4444
let bytes: &[u8] = &[];
45-
let _ = (&*bytes).read_to_end(&mut vec![]).unwrap();
45+
let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Ok, re-borrows slice
4646
}

tests/ui/redundant_slicing.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ fn main() {
1414
let _ = &(&*v)[..]; // Outer borrow is redundant
1515

1616
static S: &[u8] = &[0, 1, 2];
17-
let err = &mut &S[..]; // Should reborrow instead of slice
17+
let _ = &mut &S[..]; // Ok, re-borrows slice
1818

1919
let mut vec = vec![0];
2020
let mut_slice = &mut vec[..]; // Ok, results in `&mut [_]`
21-
let _ = &mut mut_slice[..]; // Should reborrow instead of slice
21+
let _ = &mut mut_slice[..]; // Ok, re-borrows slice
2222

2323
let ref_vec = &vec;
2424
let _ = &ref_vec[..]; // Ok, results in `&[_]`
@@ -38,9 +38,9 @@ fn main() {
3838
let _ = m2!(slice); // Don't lint in a macro
3939

4040
let slice_ref = &slice;
41-
let _ = &slice_ref[..]; // Deref instead of slice
41+
let _ = &slice_ref[..]; // Ok, derefs slice
4242

4343
// Issue #7972
4444
let bytes: &[u8] = &[];
45-
let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap();
45+
let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Ok, re-borrows slice
4646
}

tests/ui/redundant_slicing.stderr

+1-25
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,11 @@ error: redundant slicing of the whole range
1212
LL | let _ = &(&*v)[..]; // Outer borrow is redundant
1313
| ^^^^^^^^^^ help: use the original value instead: `(&*v)`
1414

15-
error: redundant slicing of the whole range
16-
--> $DIR/redundant_slicing.rs:17:20
17-
|
18-
LL | let err = &mut &S[..]; // Should reborrow instead of slice
19-
| ^^^^^^ help: reborrow the original value instead: `&*S`
20-
21-
error: redundant slicing of the whole range
22-
--> $DIR/redundant_slicing.rs:21:13
23-
|
24-
LL | let _ = &mut mut_slice[..]; // Should reborrow instead of slice
25-
| ^^^^^^^^^^^^^^^^^^ help: reborrow the original value instead: `&mut *mut_slice`
26-
2715
error: redundant slicing of the whole range
2816
--> $DIR/redundant_slicing.rs:31:13
2917
|
3018
LL | let _ = &m!(slice)[..];
3119
| ^^^^^^^^^^^^^^ help: use the original value instead: `slice`
3220

33-
error: redundant slicing of the whole range
34-
--> $DIR/redundant_slicing.rs:41:13
35-
|
36-
LL | let _ = &slice_ref[..]; // Deref instead of slice
37-
| ^^^^^^^^^^^^^^ help: dereference the original value instead: `*slice_ref`
38-
39-
error: redundant slicing of the whole range
40-
--> $DIR/redundant_slicing.rs:45:13
41-
|
42-
LL | let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap();
43-
| ^^^^^^^^^^^^ help: reborrow the original value instead: `(&*bytes)`
44-
45-
error: aborting due to 7 previous errors
21+
error: aborting due to 3 previous errors
4622

0 commit comments

Comments
 (0)