diff --git a/clippy_lints/src/methods/manual_try_fold.rs b/clippy_lints/src/methods/manual_try_fold.rs index 51145afda7f..f93edded729 100644 --- a/clippy_lints/src/methods/manual_try_fold.rs +++ b/clippy_lints/src/methods/manual_try_fold.rs @@ -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, &[]) diff --git a/tests/ui/manual_try_fold.rs b/tests/ui/manual_try_fold.rs index bddf03ac3f1..7299d7cf986 100644 --- a/tests/ui/manual_try_fold.rs +++ b/tests/ui/manual_try_fold.rs @@ -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(self, init: A, func: F) -> Fold + where + A: Clone, + F: Fn(A, Self::Output) -> A, + { + Fold { this: self, init, func } + } + } + + #[allow(dead_code)] + struct Fold { + this: S, + init: A, + func: F, + } + + fn main() { + Foo.fold(Some(0), |acc, entry| Some(acc? + entry)); + } +}