Auto merge of #11609 - y21:get_first_non_primitives, r=giraffate
[`get_first`]: lint on non-primitive slices Fixes #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
This commit is contained in:
commit
ef95be517c
@ -185,7 +185,7 @@ fn get_vec_push<'tcx>(
|
||||
if let StmtKind::Semi(semi_stmt) = &stmt.kind;
|
||||
if let ExprKind::MethodCall(path, self_expr, args, _) = &semi_stmt.kind;
|
||||
// Figure out the parameters for the method call
|
||||
if let Some(pushed_item) = args.get(0);
|
||||
if let Some(pushed_item) = args.first();
|
||||
// Check that the method being called is push() on a Vec
|
||||
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr), sym::Vec);
|
||||
if path.ident.name.as_str() == "push";
|
||||
|
@ -103,9 +103,9 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<
|
||||
if let ExprKind::Path(ref count_func_qpath) = count_func.kind;
|
||||
|
||||
if let QPath::Resolved(_, count_func_path) = count_func_qpath;
|
||||
if let Some(segment_zero) = count_func_path.segments.get(0);
|
||||
if let Some(segment_zero) = count_func_path.segments.first();
|
||||
if let Some(args) = segment_zero.args;
|
||||
if let Some(GenericArg::Type(real_ty)) = args.args.get(0);
|
||||
if let Some(GenericArg::Type(real_ty)) = args.args.first();
|
||||
|
||||
if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id();
|
||||
if cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id);
|
||||
|
@ -1,5 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_slice_of_primitives;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::LitKind;
|
||||
@ -20,7 +19,6 @@ pub(super) fn check<'tcx>(
|
||||
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
|
||||
if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
|
||||
if cx.tcx.type_of(impl_id).instantiate_identity().is_slice();
|
||||
if let Some(_) = is_slice_of_primitives(cx, recv);
|
||||
if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = arg.kind;
|
||||
then {
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
|
@ -39,7 +39,7 @@ pub(super) fn check<'tcx>(
|
||||
if search_method == "find";
|
||||
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind;
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
if let Some(closure_arg) = closure_body.params.get(0);
|
||||
if let Some(closure_arg) = closure_body.params.first();
|
||||
then {
|
||||
if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
|
||||
Some(search_snippet.replacen('&', "", 1))
|
||||
|
@ -67,7 +67,7 @@ fn has_include(meta: Option<MetaItem>) -> bool {
|
||||
if_chain! {
|
||||
if let Some(meta) = meta;
|
||||
if let MetaItemKind::List(list) = meta.kind;
|
||||
if let Some(meta) = list.get(0);
|
||||
if let Some(meta) = list.first();
|
||||
if let Some(name) = meta.ident();
|
||||
then {
|
||||
name.name == sym::include
|
||||
|
@ -189,7 +189,7 @@ fn needless_continue_in_else(else_expr: &ast::Expr, label: Option<&ast::Label>)
|
||||
}
|
||||
|
||||
fn is_first_block_stmt_continue(block: &ast::Block, label: Option<&ast::Label>) -> bool {
|
||||
block.stmts.get(0).map_or(false, |stmt| match stmt.kind {
|
||||
block.stmts.first().map_or(false, |stmt| match stmt.kind {
|
||||
ast::StmtKind::Semi(ref e) | ast::StmtKind::Expr(ref e) => {
|
||||
if let ast::ExprKind::Continue(ref l) = e.kind {
|
||||
compare_labels(label, l.as_ref())
|
||||
@ -434,7 +434,7 @@ fn erode_from_back(s: &str) -> String {
|
||||
}
|
||||
|
||||
fn span_of_first_expr_in_block(block: &ast::Block) -> Option<Span> {
|
||||
block.stmts.get(0).map(|stmt| stmt.span)
|
||||
block.stmts.first().map(|stmt| stmt.span)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -335,7 +335,7 @@ fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {
|
||||
|
||||
fn visit_block(&mut self, block: &'tcx Block<'_>) {
|
||||
if self.initialization_found {
|
||||
if let Some(s) = block.stmts.get(0) {
|
||||
if let Some(s) = block.stmts.first() {
|
||||
self.visit_stmt(s);
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ fn extract_set_len_self<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Opt
|
||||
let expr = peel_hir_expr_while(expr, |e| {
|
||||
if let ExprKind::Block(block, _) = e.kind {
|
||||
// Extract the first statement/expression
|
||||
match (block.stmts.get(0).map(|stmt| &stmt.kind), block.expr) {
|
||||
match (block.stmts.first().map(|stmt| &stmt.kind), block.expr) {
|
||||
(None, Some(expr)) => Some(expr),
|
||||
(Some(StmtKind::Expr(expr) | StmtKind::Semi(expr)), _) => Some(expr),
|
||||
_ => None,
|
||||
|
@ -40,7 +40,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tc
|
||||
let (constructor_path, constructor_item) =
|
||||
if let hir::ExprKind::Call(constructor, constructor_args) = recv.kind
|
||||
&& let hir::ExprKind::Path(constructor_path) = constructor.kind
|
||||
&& let Some(arg) = constructor_args.get(0)
|
||||
&& let Some(arg) = constructor_args.first()
|
||||
{
|
||||
if constructor.span.from_expansion() || arg.span.from_expansion() {
|
||||
return;
|
||||
@ -66,7 +66,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tc
|
||||
_ => return,
|
||||
}
|
||||
|
||||
if let Some(map_arg) = args.get(0)
|
||||
if let Some(map_arg) = args.first()
|
||||
&& let hir::ExprKind::Path(fun) = map_arg.kind
|
||||
{
|
||||
if map_arg.span.from_expansion() {
|
||||
|
@ -504,7 +504,7 @@ fn index(&mut self, lhs: &'_ Expr<'_>, index: &'_ Expr<'_>) -> Option<Constant<'
|
||||
},
|
||||
(Some(Constant::Vec(vec)), _) => {
|
||||
if !vec.is_empty() && vec.iter().all(|x| *x == vec[0]) {
|
||||
match vec.get(0) {
|
||||
match vec.first() {
|
||||
Some(Constant::F32(x)) => Some(Constant::F32(*x)),
|
||||
Some(Constant::F64(x)) => Some(Constant::F64(*x)),
|
||||
_ => None,
|
||||
|
@ -449,7 +449,7 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -
|
||||
} else if name.ident.name == symbol::kw::Default {
|
||||
return Some(VecInitKind::Default);
|
||||
} else if name.ident.name.as_str() == "with_capacity" {
|
||||
let arg = args.get(0)?;
|
||||
let arg = args.first()?;
|
||||
return match constant_simple(cx, cx.typeck_results(), arg) {
|
||||
Some(Constant::Int(num)) => Some(VecInitKind::WithConstCapacity(num)),
|
||||
_ => Some(VecInitKind::WithExprCapacity(arg.hir_id)),
|
||||
|
@ -14,17 +14,20 @@ impl Bar {
|
||||
|
||||
fn main() {
|
||||
let x = vec![2, 3, 5];
|
||||
let _ = x.first(); // Use x.first()
|
||||
let _ = x.first();
|
||||
//~^ ERROR: accessing first element with `x.get(0)`
|
||||
let _ = x.get(1);
|
||||
let _ = x[0];
|
||||
|
||||
let y = [2, 3, 5];
|
||||
let _ = y.first(); // Use y.first()
|
||||
let _ = y.first();
|
||||
//~^ ERROR: accessing first element with `y.get(0)`
|
||||
let _ = y.get(1);
|
||||
let _ = y[0];
|
||||
|
||||
let z = &[2, 3, 5];
|
||||
let _ = z.first(); // Use z.first()
|
||||
let _ = z.first();
|
||||
//~^ ERROR: accessing first element with `z.get(0)`
|
||||
let _ = z.get(1);
|
||||
let _ = z[0];
|
||||
|
||||
@ -37,4 +40,8 @@ fn main() {
|
||||
|
||||
let bar = Bar { arr: [0, 1, 2] };
|
||||
let _ = bar.get(0); // Do not lint, because Bar is struct.
|
||||
|
||||
let non_primitives = [vec![1, 2], vec![3, 4]];
|
||||
let _ = non_primitives.first();
|
||||
//~^ ERROR: accessing first element with `non_primitives.get(0)`
|
||||
}
|
||||
|
@ -14,17 +14,20 @@ fn get(&self, pos: usize) -> Option<&u32> {
|
||||
|
||||
fn main() {
|
||||
let x = vec![2, 3, 5];
|
||||
let _ = x.get(0); // Use x.first()
|
||||
let _ = x.get(0);
|
||||
//~^ ERROR: accessing first element with `x.get(0)`
|
||||
let _ = x.get(1);
|
||||
let _ = x[0];
|
||||
|
||||
let y = [2, 3, 5];
|
||||
let _ = y.get(0); // Use y.first()
|
||||
let _ = y.get(0);
|
||||
//~^ ERROR: accessing first element with `y.get(0)`
|
||||
let _ = y.get(1);
|
||||
let _ = y[0];
|
||||
|
||||
let z = &[2, 3, 5];
|
||||
let _ = z.get(0); // Use z.first()
|
||||
let _ = z.get(0);
|
||||
//~^ ERROR: accessing first element with `z.get(0)`
|
||||
let _ = z.get(1);
|
||||
let _ = z[0];
|
||||
|
||||
@ -37,4 +40,8 @@ fn main() {
|
||||
|
||||
let bar = Bar { arr: [0, 1, 2] };
|
||||
let _ = bar.get(0); // Do not lint, because Bar is struct.
|
||||
|
||||
let non_primitives = [vec![1, 2], vec![3, 4]];
|
||||
let _ = non_primitives.get(0);
|
||||
//~^ ERROR: accessing first element with `non_primitives.get(0)`
|
||||
}
|
||||
|
@ -1,23 +1,29 @@
|
||||
error: accessing first element with `x.get(0)`
|
||||
--> $DIR/get_first.rs:17:13
|
||||
|
|
||||
LL | let _ = x.get(0); // Use x.first()
|
||||
LL | let _ = x.get(0);
|
||||
| ^^^^^^^^ help: try: `x.first()`
|
||||
|
|
||||
= note: `-D clippy::get-first` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::get_first)]`
|
||||
|
||||
error: accessing first element with `y.get(0)`
|
||||
--> $DIR/get_first.rs:22:13
|
||||
--> $DIR/get_first.rs:23:13
|
||||
|
|
||||
LL | let _ = y.get(0); // Use y.first()
|
||||
LL | let _ = y.get(0);
|
||||
| ^^^^^^^^ help: try: `y.first()`
|
||||
|
||||
error: accessing first element with `z.get(0)`
|
||||
--> $DIR/get_first.rs:27:13
|
||||
--> $DIR/get_first.rs:29:13
|
||||
|
|
||||
LL | let _ = z.get(0); // Use z.first()
|
||||
LL | let _ = z.get(0);
|
||||
| ^^^^^^^^ help: try: `z.first()`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: accessing first element with `non_primitives.get(0)`
|
||||
--> $DIR/get_first.rs:45:13
|
||||
|
|
||||
LL | let _ = non_primitives.get(0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `non_primitives.first()`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user