1 use clippy_utils::diagnostics::span_lint_and_note;
2 use clippy_utils::ty::is_copy;
3 use rustc_hir::{Impl, Item, ItemKind};
4 use rustc_lint::{LateContext, LateLintPass};
5 use rustc_session::{declare_lint_pass, declare_tool_lint};
8 use if_chain::if_chain;
10 declare_clippy_lint! {
12 /// Checks for types that implement `Copy` as well as
15 /// ### Why is this bad?
16 /// Implicit copies can be confusing when working with
17 /// iterator combinators.
21 /// #[derive(Copy, Clone)]
22 /// struct Countdown(u8);
24 /// impl Iterator for Countdown {
28 /// let a: Vec<_> = my_iterator.take(1).collect();
29 /// let b: Vec<_> = my_iterator.collect();
31 #[clippy::version = "1.30.0"]
34 "implementing `Iterator` on a `Copy` type"
37 declare_lint_pass!(CopyIterator => [COPY_ITERATOR]);
39 impl<'tcx> LateLintPass<'tcx> for CopyIterator {
40 fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
42 if let ItemKind::Impl(Impl {
43 of_trait: Some(ref trait_ref),
46 let ty = cx.tcx.type_of(item.def_id);
48 if let Some(trait_id) = trait_ref.trait_def_id();
49 if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id);
55 "you are implementing `Iterator` on a `Copy` type",
57 "consider implementing `IntoIterator` instead",