Merge remote-tracking branch 'upstream/master' into rustup

This commit is contained in:
Philipp Krones 2022-07-15 09:49:15 +02:00
commit f074034590
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
170 changed files with 3143 additions and 980 deletions

View file

@ -34,7 +34,8 @@ pub(super) fn check<'tcx>(
if let Some((name, ty, initializer)) = initialize_visitor.get_result();
if is_integer_const(cx, initializer, 0);
then {
let mut applicability = Applicability::MachineApplicable;
let mut applicability = Applicability::MaybeIncorrect;
let span = expr.span.with_hi(arg.span.hi());
let int_name = match ty.map(Ty::kind) {
// usize or inferred
@ -42,7 +43,7 @@ pub(super) fn check<'tcx>(
span_lint_and_sugg(
cx,
EXPLICIT_COUNTER_LOOP,
expr.span.with_hi(arg.span.hi()),
span,
&format!("the variable `{}` is used as a loop counter", name),
"consider using",
format!(
@ -63,11 +64,11 @@ pub(super) fn check<'tcx>(
span_lint_and_then(
cx,
EXPLICIT_COUNTER_LOOP,
expr.span.with_hi(arg.span.hi()),
span,
&format!("the variable `{}` is used as a loop counter", name),
|diag| {
diag.span_suggestion(
expr.span.with_hi(arg.span.hi()),
span,
"consider using",
format!(
"for ({}, {}) in (0_{}..).zip({})",

View file

@ -139,7 +139,7 @@ fn last_stmt_and_ret<'tcx>(
if_chain! {
// This should be the loop
if let Some((node_hir, Node::Stmt(..))) = parent_iter.next();
// This should be the funciton body
// This should be the function body
if let Some((_, Node::Block(block))) = parent_iter.next();
if let Some((last_stmt, last_ret)) = extract(block);
if last_stmt.hir_id == node_hir;

View file

@ -51,22 +51,32 @@ pub(super) fn check<'tcx>(
_ => ""
};
let sugg = format!("{arg_snippet}{copied}.flatten()");
// If suggestion is not a one-liner, it won't be shown inline within the error message. In that case,
// it will be shown in the extra `help` message at the end, which is why the first `help_msg` needs
// to refer to the correct relative position of the suggestion.
let help_msg = if sugg.contains('\n') {
"remove the `if let` statement in the for loop and then..."
} else {
"...and remove the `if let` statement in the for loop"
};
span_lint_and_then(
cx,
MANUAL_FLATTEN,
span,
&msg,
|diag| {
let sugg = format!("{}{}.flatten()", arg_snippet, copied);
diag.span_suggestion(
arg.span,
"try",
sugg,
Applicability::MaybeIncorrect,
applicability,
);
diag.span_help(
inner_expr.span,
"...and remove the `if let` statement in the for loop",
help_msg,
);
}
);

View file

@ -11,7 +11,7 @@ use rustc_lint::LateContext;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) {
let (init, has_trailing_exprs) = match (loop_block.stmts, loop_block.expr) {
([stmt, stmts @ ..], expr) => {
if let StmtKind::Local(&Local { init: Some(e), els: None, .. }) | StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind {
if let StmtKind::Local(&Local { init: Some(e), .. }) | StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind {
(e, !stmts.is_empty() || expr.is_some())
} else {
return;

View file

@ -3,13 +3,15 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::higher;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{
get_enclosing_loop_or_closure, is_refutable, is_trait_method, match_def_path, paths, visitors::is_res_used,
get_enclosing_loop_or_multi_call_closure, is_refutable, is_trait_method, match_def_path, paths,
visitors::is_res_used,
};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Closure, def::Res, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, UnOp};
use rustc_hir::{def::Res, Closure, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, UnOp};
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::ty::adjustment::Adjust;
use rustc_span::{symbol::sym, Symbol};
@ -249,6 +251,11 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
used_iter: bool,
}
impl<'tcx> Visitor<'tcx> for AfterLoopVisitor<'_, '_, 'tcx> {
type NestedFilter = OnlyBodies;
fn nested_visit_map(&mut self) -> Self::Map {
self.cx.tcx.hir()
}
fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
if self.used_iter {
return;
@ -283,6 +290,11 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
used_after: bool,
}
impl<'a, 'b, 'tcx> Visitor<'tcx> for NestedLoopVisitor<'a, 'b, 'tcx> {
type NestedFilter = OnlyBodies;
fn nested_visit_map(&mut self) -> Self::Map {
self.cx.tcx.hir()
}
fn visit_local(&mut self, l: &'tcx Local<'_>) {
if !self.after_loop {
l.pat.each_binding_or_first(&mut |_, id, _, _| {
@ -320,10 +332,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
}
}
if let Some(e) = get_enclosing_loop_or_closure(cx.tcx, loop_expr) {
// The iterator expression will be used on the next iteration (for loops), or on the next call (for
// closures) unless it is declared within the enclosing expression. TODO: Check for closures
// used where an `FnOnce` type is expected.
if let Some(e) = get_enclosing_loop_or_multi_call_closure(cx, loop_expr) {
let local_id = match iter_expr.path {
Res::Local(id) => id,
_ => return true,