1 use crate::utils::{is_copy, span_lint_and_note};
2 use rustc_hir::{Impl, Item, ItemKind};
3 use rustc_lint::{LateContext, LateLintPass};
4 use rustc_session::{declare_lint_pass, declare_tool_lint};
7 use if_chain::if_chain;
10 /// **What it does:** Checks for types that implement `Copy` as well as
13 /// **Why is this bad?** Implicit copies can be confusing when working with
14 /// iterator combinators.
16 /// **Known problems:** None.
20 /// #[derive(Copy, Clone)]
21 /// struct Countdown(u8);
23 /// impl Iterator for Countdown {
27 /// let a: Vec<_> = my_iterator.take(1).collect();
28 /// let b: Vec<_> = my_iterator.collect();
32 "implementing `Iterator` on a `Copy` type"
35 declare_lint_pass!(CopyIterator => [COPY_ITERATOR]);
37 impl<'tcx> LateLintPass<'tcx> for CopyIterator {
38 fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
40 if let ItemKind::Impl(Impl {
41 of_trait: Some(ref trait_ref),
44 let ty = cx.tcx.type_of(item.def_id);
46 if let Some(trait_id) = trait_ref.trait_def_id();
47 if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id);
53 "you are implementing `Iterator` on a `Copy` type",
55 "consider implementing `IntoIterator` instead",