-
Notifications
You must be signed in to change notification settings - Fork 1.8k
unnecessary_fold improvements
#13475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
705ba03
882e37c
19f11b6
895a0f9
966dadc
b474275
1c2870f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ use rustc_hir as hir; | |
| use rustc_hir::PatKind; | ||
| use rustc_lint::LateContext; | ||
| use rustc_middle::ty; | ||
| use rustc_span::{Span, sym}; | ||
| use rustc_span::{Span, Symbol, sym}; | ||
|
|
||
| use super::UNNECESSARY_FOLD; | ||
|
|
||
|
|
@@ -40,6 +40,19 @@ fn needs_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { | |
| return false; | ||
| } | ||
|
|
||
| // - the final expression in the body of a function with a simple return type | ||
| if let hir::Node::Block(block) = parent | ||
| && let grandparent = cx.tcx.parent_hir_node(block.hir_id) | ||
| && let hir::Node::Expr(grandparent_expr) = grandparent | ||
| && let ggparent = cx.tcx.parent_hir_node(grandparent_expr.hir_id) | ||
| && let hir::Node::Item(enclosing_item) = ggparent | ||
| && let hir::ItemKind::Fn(fn_sig, _, _) = enclosing_item.kind | ||
| && let hir::FnRetTy::Return(fn_return_ty) = fn_sig.decl.output | ||
| && matches!(fn_return_ty.kind, hir::TyKind::Path(..)) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| // if it's neither of those, stay on the safe side and suggest turbofish, | ||
| // even if it could work! | ||
| true | ||
|
|
@@ -80,7 +93,7 @@ fn check_fold_with_op( | |
| let mut applicability = Applicability::MachineApplicable; | ||
|
|
||
| let turbofish = if replacement.has_generic_return { | ||
| format!("::<{}>", cx.typeck_results().expr_ty_adjusted(right_expr).peel_refs()) | ||
| format!("::<{}>", cx.typeck_results().expr_ty(expr)) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this change make any difference? More specifically was the original code unnecessary There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I did it to be consistent with the new function I made, where there is no |
||
| } else { | ||
| String::new() | ||
| }; | ||
|
|
@@ -107,6 +120,40 @@ fn check_fold_with_op( | |
| } | ||
| } | ||
|
|
||
| fn check_fold_with_fn( | ||
| cx: &LateContext<'_>, | ||
| expr: &hir::Expr<'_>, | ||
| acc: &hir::Expr<'_>, | ||
| fold_span: Span, | ||
| op: Symbol, | ||
| replacement: Replacement, | ||
| ) { | ||
| if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = acc.kind | ||
| // Extract the name of the function passed to fold | ||
| && let hir::def::Res::Def(hir::def::DefKind::AssocFn, fn_did) = p.res | ||
| // Check if the function belongs to the operator | ||
| && cx.tcx.is_diagnostic_item(op, fn_did) | ||
| { | ||
| let applicability = Applicability::MachineApplicable; | ||
|
|
||
| let turbofish = if replacement.has_generic_return { | ||
| format!("::<{}>", cx.typeck_results().expr_ty(expr)) | ||
| } else { | ||
| String::new() | ||
| }; | ||
|
|
||
| span_lint_and_sugg( | ||
| cx, | ||
| UNNECESSARY_FOLD, | ||
| fold_span.with_hi(expr.span.hi()), | ||
| "this `.fold` can be written more succinctly using another method", | ||
| "try", | ||
| format!("{method}{turbofish}()", method = replacement.method_name,), | ||
viliml marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| applicability, | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| pub(super) fn check( | ||
| cx: &LateContext<'_>, | ||
| expr: &hir::Expr<'_>, | ||
|
|
@@ -142,13 +189,23 @@ pub(super) fn check( | |
| has_generic_return: needs_turbofish(cx, expr), | ||
| method_name: "sum", | ||
| }); | ||
| check_fold_with_fn(cx, expr, acc, fold_span, sym::add, Replacement { | ||
| has_args: false, | ||
| has_generic_return: needs_turbofish(cx, expr), | ||
| method_name: "sum", | ||
| }); | ||
| }, | ||
| ast::LitKind::Int(Pu128(1), _) => { | ||
| check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, Replacement { | ||
| has_args: false, | ||
| has_generic_return: needs_turbofish(cx, expr), | ||
| method_name: "product", | ||
| }); | ||
| check_fold_with_fn(cx, expr, acc, fold_span, sym::mul, Replacement { | ||
| has_args: false, | ||
| has_generic_return: needs_turbofish(cx, expr), | ||
| method_name: "product", | ||
| }); | ||
| }, | ||
| _ => (), | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably better to iterate over the parents? is there any reason simply getting the containing item doesn't work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know, I don't understand this infrastructure so well so my first try was probably not the best way to do it.