Skip to content

Commit ef95be5

Browse files
committed
Auto merge of rust-lang#11609 - y21:get_first_non_primitives, r=giraffate
[`get_first`]: lint on non-primitive slices Fixes rust-lang#11594 I left the issue open for a couple days before making the PR to see if anyone has something to say, but it looks like there aren't any objections to removing this check that prevented linting on non-primitive slices, so here's the PR now. There's a couple of instances in clippy itself where we now emit the lint. The actual relevant change is in the first commit and fixing the `.get(0)` instances in clippy itself is in the 2nd commit. changelog: [`get_first`]: lint on non-primitive slices
2 parents c40359d + e6f29f1 commit ef95be5

14 files changed

+45
-27
lines changed

clippy_lints/src/loops/same_item_push.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ fn get_vec_push<'tcx>(
185185
if let StmtKind::Semi(semi_stmt) = &stmt.kind;
186186
if let ExprKind::MethodCall(path, self_expr, args, _) = &semi_stmt.kind;
187187
// Figure out the parameters for the method call
188-
if let Some(pushed_item) = args.get(0);
188+
if let Some(pushed_item) = args.first();
189189
// Check that the method being called is push() on a Vec
190190
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr), sym::Vec);
191191
if path.ident.name.as_str() == "push";

clippy_lints/src/manual_bits.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<
103103
if let ExprKind::Path(ref count_func_qpath) = count_func.kind;
104104

105105
if let QPath::Resolved(_, count_func_path) = count_func_qpath;
106-
if let Some(segment_zero) = count_func_path.segments.get(0);
106+
if let Some(segment_zero) = count_func_path.segments.first();
107107
if let Some(args) = segment_zero.args;
108-
if let Some(GenericArg::Type(real_ty)) = args.args.get(0);
108+
if let Some(GenericArg::Type(real_ty)) = args.args.first();
109109

110110
if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id();
111111
if cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id);

clippy_lints/src/methods/get_first.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2-
use clippy_utils::is_slice_of_primitives;
32
use clippy_utils::source::snippet_with_applicability;
43
use if_chain::if_chain;
54
use rustc_ast::LitKind;
@@ -20,7 +19,6 @@ pub(super) fn check<'tcx>(
2019
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
2120
if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
2221
if cx.tcx.type_of(impl_id).instantiate_identity().is_slice();
23-
if let Some(_) = is_slice_of_primitives(cx, recv);
2422
if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = arg.kind;
2523
then {
2624
let mut app = Applicability::MachineApplicable;

clippy_lints/src/methods/search_is_some.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub(super) fn check<'tcx>(
3939
if search_method == "find";
4040
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind;
4141
let closure_body = cx.tcx.hir().body(body);
42-
if let Some(closure_arg) = closure_body.params.get(0);
42+
if let Some(closure_arg) = closure_body.params.first();
4343
then {
4444
if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
4545
Some(search_snippet.replacen('&', "", 1))

clippy_lints/src/missing_doc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl MissingDoc {
6767
if_chain! {
6868
if let Some(meta) = meta;
6969
if let MetaItemKind::List(list) = meta.kind;
70-
if let Some(meta) = list.get(0);
70+
if let Some(meta) = list.first();
7171
if let Some(name) = meta.ident();
7272
then {
7373
name.name == sym::include

clippy_lints/src/needless_continue.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ fn needless_continue_in_else(else_expr: &ast::Expr, label: Option<&ast::Label>)
189189
}
190190

191191
fn is_first_block_stmt_continue(block: &ast::Block, label: Option<&ast::Label>) -> bool {
192-
block.stmts.get(0).map_or(false, |stmt| match stmt.kind {
192+
block.stmts.first().map_or(false, |stmt| match stmt.kind {
193193
ast::StmtKind::Semi(ref e) | ast::StmtKind::Expr(ref e) => {
194194
if let ast::ExprKind::Continue(ref l) = e.kind {
195195
compare_labels(label, l.as_ref())
@@ -434,7 +434,7 @@ fn erode_from_back(s: &str) -> String {
434434
}
435435

436436
fn span_of_first_expr_in_block(block: &ast::Block) -> Option<Span> {
437-
block.stmts.get(0).map(|stmt| stmt.span)
437+
block.stmts.first().map(|stmt| stmt.span)
438438
}
439439

440440
#[cfg(test)]

clippy_lints/src/slow_vector_initialization.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VectorInitializationVisitor<'a, 'tcx> {
335335

336336
fn visit_block(&mut self, block: &'tcx Block<'_>) {
337337
if self.initialization_found {
338-
if let Some(s) = block.stmts.get(0) {
338+
if let Some(s) = block.stmts.first() {
339339
self.visit_stmt(s);
340340
}
341341

clippy_lints/src/uninit_vec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ fn extract_set_len_self<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Opt
201201
let expr = peel_hir_expr_while(expr, |e| {
202202
if let ExprKind::Block(block, _) = e.kind {
203203
// Extract the first statement/expression
204-
match (block.stmts.get(0).map(|stmt| &stmt.kind), block.expr) {
204+
match (block.stmts.first().map(|stmt| &stmt.kind), block.expr) {
205205
(None, Some(expr)) => Some(expr),
206206
(Some(StmtKind::Expr(expr) | StmtKind::Semi(expr)), _) => Some(expr),
207207
_ => None,

clippy_lints/src/unnecessary_map_on_constructor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
4040
let (constructor_path, constructor_item) =
4141
if let hir::ExprKind::Call(constructor, constructor_args) = recv.kind
4242
&& let hir::ExprKind::Path(constructor_path) = constructor.kind
43-
&& let Some(arg) = constructor_args.get(0)
43+
&& let Some(arg) = constructor_args.first()
4444
{
4545
if constructor.span.from_expansion() || arg.span.from_expansion() {
4646
return;
@@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
6666
_ => return,
6767
}
6868

69-
if let Some(map_arg) = args.get(0)
69+
if let Some(map_arg) = args.first()
7070
&& let hir::ExprKind::Path(fun) = map_arg.kind
7171
{
7272
if map_arg.span.from_expansion() {

clippy_utils/src/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
504504
},
505505
(Some(Constant::Vec(vec)), _) => {
506506
if !vec.is_empty() && vec.iter().all(|x| *x == vec[0]) {
507-
match vec.get(0) {
507+
match vec.first() {
508508
Some(Constant::F32(x)) => Some(Constant::F32(*x)),
509509
Some(Constant::F64(x)) => Some(Constant::F64(*x)),
510510
_ => None,

clippy_utils/src/higher.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -
449449
} else if name.ident.name == symbol::kw::Default {
450450
return Some(VecInitKind::Default);
451451
} else if name.ident.name.as_str() == "with_capacity" {
452-
let arg = args.get(0)?;
452+
let arg = args.first()?;
453453
return match constant_simple(cx, cx.typeck_results(), arg) {
454454
Some(Constant::Int(num)) => Some(VecInitKind::WithConstCapacity(num)),
455455
_ => Some(VecInitKind::WithExprCapacity(arg.hir_id)),

tests/ui/get_first.fixed

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,20 @@ impl Bar {
1414

1515
fn main() {
1616
let x = vec![2, 3, 5];
17-
let _ = x.first(); // Use x.first()
17+
let _ = x.first();
18+
//~^ ERROR: accessing first element with `x.get(0)`
1819
let _ = x.get(1);
1920
let _ = x[0];
2021

2122
let y = [2, 3, 5];
22-
let _ = y.first(); // Use y.first()
23+
let _ = y.first();
24+
//~^ ERROR: accessing first element with `y.get(0)`
2325
let _ = y.get(1);
2426
let _ = y[0];
2527

2628
let z = &[2, 3, 5];
27-
let _ = z.first(); // Use z.first()
29+
let _ = z.first();
30+
//~^ ERROR: accessing first element with `z.get(0)`
2831
let _ = z.get(1);
2932
let _ = z[0];
3033

@@ -37,4 +40,8 @@ fn main() {
3740

3841
let bar = Bar { arr: [0, 1, 2] };
3942
let _ = bar.get(0); // Do not lint, because Bar is struct.
43+
44+
let non_primitives = [vec![1, 2], vec![3, 4]];
45+
let _ = non_primitives.first();
46+
//~^ ERROR: accessing first element with `non_primitives.get(0)`
4047
}

tests/ui/get_first.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,20 @@ impl Bar {
1414

1515
fn main() {
1616
let x = vec![2, 3, 5];
17-
let _ = x.get(0); // Use x.first()
17+
let _ = x.get(0);
18+
//~^ ERROR: accessing first element with `x.get(0)`
1819
let _ = x.get(1);
1920
let _ = x[0];
2021

2122
let y = [2, 3, 5];
22-
let _ = y.get(0); // Use y.first()
23+
let _ = y.get(0);
24+
//~^ ERROR: accessing first element with `y.get(0)`
2325
let _ = y.get(1);
2426
let _ = y[0];
2527

2628
let z = &[2, 3, 5];
27-
let _ = z.get(0); // Use z.first()
29+
let _ = z.get(0);
30+
//~^ ERROR: accessing first element with `z.get(0)`
2831
let _ = z.get(1);
2932
let _ = z[0];
3033

@@ -37,4 +40,8 @@ fn main() {
3740

3841
let bar = Bar { arr: [0, 1, 2] };
3942
let _ = bar.get(0); // Do not lint, because Bar is struct.
43+
44+
let non_primitives = [vec![1, 2], vec![3, 4]];
45+
let _ = non_primitives.get(0);
46+
//~^ ERROR: accessing first element with `non_primitives.get(0)`
4047
}

tests/ui/get_first.stderr

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
error: accessing first element with `x.get(0)`
22
--> $DIR/get_first.rs:17:13
33
|
4-
LL | let _ = x.get(0); // Use x.first()
4+
LL | let _ = x.get(0);
55
| ^^^^^^^^ help: try: `x.first()`
66
|
77
= note: `-D clippy::get-first` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::get_first)]`
99

1010
error: accessing first element with `y.get(0)`
11-
--> $DIR/get_first.rs:22:13
11+
--> $DIR/get_first.rs:23:13
1212
|
13-
LL | let _ = y.get(0); // Use y.first()
13+
LL | let _ = y.get(0);
1414
| ^^^^^^^^ help: try: `y.first()`
1515

1616
error: accessing first element with `z.get(0)`
17-
--> $DIR/get_first.rs:27:13
17+
--> $DIR/get_first.rs:29:13
1818
|
19-
LL | let _ = z.get(0); // Use z.first()
19+
LL | let _ = z.get(0);
2020
| ^^^^^^^^ help: try: `z.first()`
2121

22-
error: aborting due to 3 previous errors
22+
error: accessing first element with `non_primitives.get(0)`
23+
--> $DIR/get_first.rs:45:13
24+
|
25+
LL | let _ = non_primitives.get(0);
26+
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `non_primitives.first()`
27+
28+
error: aborting due to 4 previous errors
2329

0 commit comments

Comments
 (0)