Skip to content

Commit b3a7c05

Browse files
committed
changelog: Add as_slice_instead_of_reference_full_range lint
1 parent 40bead0 commit b3a7c05

8 files changed

+149
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5620,6 +5620,7 @@ Released 2018-09-13
56205620
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
56215621
[`as_pointer_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_pointer_underscore
56225622
[`as_ptr_cast_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_ptr_cast_mut
5623+
[`as_slice_instead_of_reference_full_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_slice_instead_of_reference_full_range
56235624
[`as_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore
56245625
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
56255626
[`assertions_on_result_states`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_result_states
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::source::snippet_with_applicability;
3+
use rustc_errors::Applicability;
4+
use rustc_hir::*;
5+
use rustc_lint::{LateContext, LateLintPass};
6+
use rustc_session::declare_lint_pass;
7+
8+
declare_clippy_lint! {
9+
/// ### What it does
10+
///
11+
/// Detects if a full range slice reference is used instead of using the `.as_slice()` method.
12+
///
13+
/// ### Why is this bad?
14+
///
15+
/// Using the `some_value.as_slice()` method is more explicit then using `&some_value[..]`
16+
///
17+
/// ### Example
18+
/// ```no_run
19+
/// let array = [u8; 4];
20+
/// let slice = &array[..];
21+
/// ```
22+
/// Use instead:
23+
/// ```no_run
24+
/// let array = [u8; 4];
25+
/// let slice = array.as_slice;
26+
/// ```
27+
#[clippy::version = "1.88.0"]
28+
pub AS_SLICE_INSTEAD_OF_REFERENCE_FULL_RANGE,
29+
nursery,
30+
"Use as slice instead of borrow full range."
31+
}
32+
declare_lint_pass!(AsSliceInsteadOfReferenceFullRange => [AS_SLICE_INSTEAD_OF_REFERENCE_FULL_RANGE]);
33+
34+
impl LateLintPass<'_> for AsSliceInsteadOfReferenceFullRange {
35+
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
36+
if let ExprKind::AddrOf(_, mutability, borrow) = expr.kind
37+
&& let ExprKind::Index(name, indexing, _) = borrow.kind
38+
&& let ExprKind::Struct(qpath, _, _) = indexing.kind
39+
&& let QPath::LangItem(LangItem::RangeFull, _) = qpath
40+
{
41+
let snippet = snippet_with_applicability(cx, name.span, "..", &mut Applicability::Unspecified);
42+
43+
match mutability {
44+
Mutability::Not => {
45+
span_lint_and_sugg(
46+
cx,
47+
AS_SLICE_INSTEAD_OF_REFERENCE_FULL_RANGE,
48+
expr.span,
49+
format!("Use `.as_slice()` instead of full range slice"),
50+
"try",
51+
format!("{snippet}.as_slice()"),
52+
Applicability::Unspecified,
53+
);
54+
},
55+
Mutability::Mut => {
56+
span_lint_and_sugg(
57+
cx,
58+
AS_SLICE_INSTEAD_OF_REFERENCE_FULL_RANGE,
59+
expr.span,
60+
format!("Use `.as_mut_slice()` instead of full range slice"),
61+
"try",
62+
format!("{snippet}.as_mut_slice()"),
63+
Applicability::Unspecified,
64+
);
65+
},
66+
}
67+
}
68+
}
69+
}

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
99
crate::arbitrary_source_item_ordering::ARBITRARY_SOURCE_ITEM_ORDERING_INFO,
1010
crate::arc_with_non_send_sync::ARC_WITH_NON_SEND_SYNC_INFO,
1111
crate::as_conversions::AS_CONVERSIONS_INFO,
12+
crate::as_slice_instead_of_reference_full_range::AS_SLICE_INSTEAD_OF_REFERENCE_FULL_RANGE_INFO,
1213
crate::asm_syntax::INLINE_ASM_X86_ATT_SYNTAX_INFO,
1314
crate::asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX_INFO,
1415
crate::assertions_on_constants::ASSERTIONS_ON_CONSTANTS_INFO,

clippy_lints/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ mod approx_const;
7676
mod arbitrary_source_item_ordering;
7777
mod arc_with_non_send_sync;
7878
mod as_conversions;
79+
mod as_slice_instead_of_reference_full_range;
7980
mod asm_syntax;
8081
mod assertions_on_constants;
8182
mod assertions_on_result_states;
@@ -944,5 +945,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
944945
store.register_late_pass(|_| Box::new(single_option_map::SingleOptionMap));
945946
store.register_late_pass(move |_| Box::new(redundant_test_prefix::RedundantTestPrefix));
946947
store.register_late_pass(|_| Box::new(cloned_ref_to_slice_refs::ClonedRefToSliceRefs::new(conf)));
948+
store
949+
.register_late_pass(|_| Box::new(as_slice_instead_of_reference_full_range::AsSliceInsteadOfReferenceFullRange));
947950
// add lints here, do not remove this comment, it's used in `new_lint`
948951
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error: Oh noooo
2+
--> tests/ui/array_as_slice_instead_of_unbounded_slice.rs:5:25
3+
|
4+
LL | let slice: &[u8] = &array[..];
5+
| ^^^^^^^^^
6+
|
7+
= help: .as_slice()
8+
= note: `-D clippy::array-as-slice-instead-of-unbounded-slice` implied by `-D warnings`
9+
= help: to override `-D warnings` add `#[allow(clippy::array_as_slice_instead_of_unbounded_slice)]`
10+
11+
error: aborting due to 1 previous error
12+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![warn(clippy::as_slice_instead_of_reference_full_range)]
2+
3+
mod nested_1 {
4+
pub(crate) mod nested_2 {
5+
pub(crate) const SOME_VALUE: [u8; 4] = [1, 2, 3, 4];
6+
}
7+
}
8+
9+
fn main() {
10+
let array: [u8; 4] = [0; 4];
11+
let slice: &[u8] = array.as_slice();
12+
//~^ as_slice_instead_of_reference_full_range
13+
14+
let mut array: [u8; 4] = [0; 4];
15+
let mut slice: &[u8] = array.as_mut_slice();
16+
//~^ as_slice_instead_of_reference_full_range
17+
18+
let slice: &[u8] = nested_1::nested_2::SOME_VALUE.as_slice();
19+
//~^ as_slice_instead_of_reference_full_range
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![warn(clippy::as_slice_instead_of_reference_full_range)]
2+
3+
mod nested_1 {
4+
pub(crate) mod nested_2 {
5+
pub(crate) const SOME_VALUE: [u8; 4] = [1, 2, 3, 4];
6+
}
7+
}
8+
9+
fn main() {
10+
let array: [u8; 4] = [0; 4];
11+
let slice: &[u8] = &array[..];
12+
//~^ as_slice_instead_of_reference_full_range
13+
14+
let mut array: [u8; 4] = [0; 4];
15+
let mut slice: &[u8] = &mut array[..];
16+
//~^ as_slice_instead_of_reference_full_range
17+
18+
let slice: &[u8] = &nested_1::nested_2::SOME_VALUE[..];
19+
//~^ as_slice_instead_of_reference_full_range
20+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error: Use `.as_slice()` instead of full range slice
2+
--> tests/ui/as_slice_instead_of_reference_full_range.rs:11:24
3+
|
4+
LL | let slice: &[u8] = &array[..];
5+
| ^^^^^^^^^^ help: try: `array.as_slice()`
6+
|
7+
= note: `-D clippy::as-slice-instead-of-reference-full-range` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::as_slice_instead_of_reference_full_range)]`
9+
10+
error: Use `.as_mut_slice()` instead of full range slice
11+
--> tests/ui/as_slice_instead_of_reference_full_range.rs:15:28
12+
|
13+
LL | let mut slice: &[u8] = &mut array[..];
14+
| ^^^^^^^^^^^^^^ help: try: `array.as_mut_slice()`
15+
16+
error: Use `.as_slice()` instead of full range slice
17+
--> tests/ui/as_slice_instead_of_reference_full_range.rs:18:24
18+
|
19+
LL | let slice: &[u8] = &nested_1::nested_2::SOME_VALUE[..];
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `nested_1::nested_2::SOME_VALUE.as_slice()`
21+
22+
error: aborting due to 3 previous errors
23+

0 commit comments

Comments
 (0)