11use clippy_utils:: consts:: { constant, Constant } ;
22use clippy_utils:: diagnostics:: span_lint_and_sugg;
3- use clippy_utils:: is_trait_method;
43use clippy_utils:: source:: snippet_with_applicability;
5- use if_chain:: if_chain;
4+ use clippy_utils:: { is_lang_item_or_ctor, is_trait_method} ;
5+ use hir:: { LangItem , OwnerNode } ;
66use rustc_errors:: Applicability ;
77use rustc_hir as hir;
88use rustc_lint:: LateContext ;
@@ -11,20 +11,21 @@ use rustc_span::sym;
1111use super :: ITER_NTH_ZERO ;
1212
1313pub ( super ) fn check ( cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > , recv : & hir:: Expr < ' _ > , arg : & hir:: Expr < ' _ > ) {
14- if_chain ! {
15- if is_trait_method( cx, expr, sym:: Iterator ) ;
16- if let Some ( Constant :: Int ( 0 ) ) = constant( cx, cx. typeck_results( ) , arg) ;
17- then {
18- let mut applicability = Applicability :: MachineApplicable ;
19- span_lint_and_sugg(
20- cx,
21- ITER_NTH_ZERO ,
22- expr. span,
23- "called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent" ,
24- "try calling `.next()` instead of `.nth(0)`" ,
25- format!( "{}.next()" , snippet_with_applicability( cx, recv. span, ".." , & mut applicability) ) ,
26- applicability,
27- ) ;
28- }
14+ if let OwnerNode :: Item ( item) = cx. tcx . hir ( ) . owner ( cx. tcx . hir ( ) . get_parent_item ( expr. hir_id ) )
15+ && let def_id = item. owner_id . to_def_id ( )
16+ && is_trait_method ( cx, expr, sym:: Iterator )
17+ && let Some ( Constant :: Int ( 0 ) ) = constant ( cx, cx. typeck_results ( ) , arg)
18+ && !is_lang_item_or_ctor ( cx, def_id, LangItem :: IteratorNext )
19+ {
20+ let mut app = Applicability :: MachineApplicable ;
21+ span_lint_and_sugg (
22+ cx,
23+ ITER_NTH_ZERO ,
24+ expr. span ,
25+ "called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent" ,
26+ "try calling `.next()` instead of `.nth(0)`" ,
27+ format ! ( "{}.next()" , snippet_with_applicability( cx, recv. span, ".." , & mut app) ) ,
28+ app,
29+ ) ;
2930 }
3031}
0 commit comments