Fix while_let_on_iterator

Reborrow mutable references rather then take a reference to them.
This commit is contained in:
Jason Newcomb
2021-07-30 22:59:20 -04:00
parent f6a5889ffa
commit fe75faa6ee
4 changed files with 71 additions and 4 deletions

View File

@@ -7,7 +7,7 @@ use clippy_utils::{
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, ErasedMap, NestedVisitorMap, Visitor};
use rustc_hir::{def::Res, Expr, ExprKind, HirId, Local, MatchSource, Node, PatKind, QPath, UnOp};
use rustc_hir::{def::Res, Expr, ExprKind, HirId, Local, MatchSource, Mutability, Node, PatKind, QPath, UnOp};
use rustc_lint::LateContext;
use rustc_span::{symbol::sym, Span, Symbol};
@@ -48,7 +48,12 @@ pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// borrowed mutably. TODO: If the struct can be partially moved from and the struct isn't used
// afterwards a mutable borrow of a field isn't necessary.
let ref_mut = if !iter_expr.fields.is_empty() || needs_mutable_borrow(cx, &iter_expr, loop_expr) {
"&mut "
if cx.typeck_results().node_type(iter_expr.hir_id).ref_mutability() == Some(Mutability::Mut) {
// Reborrow for mutable references. It may not be possible to get a mutable reference here.
"&mut *"
} else {
"&mut "
}
} else {
""
};
@@ -69,6 +74,8 @@ pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
struct IterExpr {
/// The span of the whole expression, not just the path and fields stored here.
span: Span,
/// The HIR id of the whole expression, not just the path and fields stored here.
hir_id: HirId,
/// The fields used, in order of child to parent.
fields: Vec<Symbol>,
/// The path being used.
@@ -78,12 +85,14 @@ struct IterExpr {
/// the expression might have side effects.
fn try_parse_iter_expr(cx: &LateContext<'_>, mut e: &Expr<'_>) -> Option<IterExpr> {
let span = e.span;
let hir_id = e.hir_id;
let mut fields = Vec::new();
loop {
match e.kind {
ExprKind::Path(ref path) => {
break Some(IterExpr {
span,
hir_id,
fields,
path: cx.qpath_res(path, e.hir_id),
});