#![deny(clippy::trait_duplication_in_bounds)] use std::collections::BTreeMap; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; fn bad_foo(arg0: T, arg1: Z) //~^ ERROR: this trait bound is already specified in the where clause //~| ERROR: this trait bound is already specified in the where clause where T: Clone, T: Default, { unimplemented!(); } fn good_bar(arg: T) { unimplemented!(); } fn good_foo(arg: T) where T: Clone + Default, { unimplemented!(); } fn good_foobar(arg: T) where T: Clone, { unimplemented!(); } trait T: Default { fn f() where Self: Default; //~^ ERROR: this trait bound is already specified in trait declaration } trait U: Default { fn f() where Self: Clone; } trait ZZ: Default { fn g(); fn h(); fn f() where Self: Default + Clone; //~^ ERROR: this trait bound is already specified in trait declaration } trait BadTrait: Default + Clone { fn f() where Self: Default + Clone; //~^ ERROR: this trait bound is already specified in trait declaration //~| ERROR: this trait bound is already specified in trait declaration fn g() where Self: Default; //~^ ERROR: this trait bound is already specified in trait declaration fn h() where Self: Copy; } #[derive(Default, Clone)] struct Life; impl T for Life { // this should not warn fn f() {} } impl U for Life { // this should not warn fn f() {} } // should not warn trait Iter: Iterator { fn into_group_btreemap(self) -> BTreeMap> where Self: Iterator + Sized, K: Ord + Eq, { unimplemented!(); } } struct Foo; trait FooIter: Iterator { fn bar() where Self: Iterator, //~^ ERROR: this trait bound is already specified in trait declaration { } } // The below should not lint and exist to guard against false positives fn impl_trait(_: impl AsRef, _: impl AsRef) {} pub mod one { #[derive(Clone, Debug)] struct MultiProductIter where I: Iterator + Clone, I::Item: Clone, { _marker: I, } pub struct MultiProduct(Vec>) where I: Iterator + Clone, I::Item: Clone; pub fn multi_cartesian_product(_: H) -> MultiProduct<::IntoIter> where H: Iterator, H::Item: IntoIterator, ::IntoIter: Clone, ::Item: Clone, { todo!() } } pub mod two { use std::iter::Peekable; pub struct MergeBy where I: Iterator, J: Iterator, { _i: Peekable, _j: Peekable, _f: F, } impl Clone for MergeBy where I: Iterator, J: Iterator, std::iter::Peekable: Clone, std::iter::Peekable: Clone, F: Clone, { fn clone(&self) -> Self { Self { _i: self._i.clone(), _j: self._j.clone(), _f: self._f.clone(), } } } } pub trait Trait {} pub fn f(_a: impl Trait, _b: impl Trait) {} pub trait ImplTrait {} impl ImplTrait<(A, B)> for Foo where Foo: ImplTrait + ImplTrait {} fn main() {}