manual_try_fold: check that fold is really Iterator::fold

This commit is contained in:
Samuel Tardieu 2023-11-26 22:46:13 +01:00
parent 7af811b6c4
commit 0d09cb0a6b
2 changed files with 33 additions and 2 deletions

View file

@ -1,14 +1,14 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_from_proc_macro;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::implements_trait;
use clippy_utils::{is_from_proc_macro, is_trait_method};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::Span;
use rustc_span::{sym, Span};
use super::MANUAL_TRY_FOLD;
@ -22,6 +22,7 @@ pub(super) fn check<'tcx>(
) {
if !in_external_macro(cx.sess(), fold_span)
&& msrv.meets(msrvs::ITERATOR_TRY_FOLD)
&& is_trait_method(cx, expr, sym::Iterator)
&& let init_ty = cx.typeck_results().expr_ty(init)
&& let Some(try_trait) = cx.tcx.lang_items().try_trait()
&& implements_trait(cx, init_ty, try_trait, &[])

View file

@ -96,3 +96,33 @@ fn msrv_juust_right() {
.fold(Some(0i32), |sum, i| sum?.checked_add(*i))
.unwrap();
}
mod issue11876 {
struct Foo;
impl Bar for Foo {
type Output = u32;
}
trait Bar: Sized {
type Output;
fn fold<A, F>(self, init: A, func: F) -> Fold<Self, A, F>
where
A: Clone,
F: Fn(A, Self::Output) -> A,
{
Fold { this: self, init, func }
}
}
#[allow(dead_code)]
struct Fold<S, A, F> {
this: S,
init: A,
func: F,
}
fn main() {
Foo.fold(Some(0), |acc, entry| Some(acc? + entry));
}
}